Skip to content
This repository has been archived by the owner on Jan 7, 2020. It is now read-only.

Commit

Permalink
feat/Adapt to changes in safe_client_libs for containers permissions …
Browse files Browse the repository at this point in the history
…format (#131)
  • Loading branch information
bochaco authored and Viv Rajkumar committed Aug 22, 2017
1 parent 97c97b1 commit 832d4bf
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 51 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
},
"safe_app": {
"mirror": "https://s3.eu-west-2.amazonaws.com/safe-client-libs",
"version": "f576719",
"version": "96a73c3",
"targetDir": "src/native",
"filename": "safe_app",
"filePattern": "^.*\\.(dll|so|dylib)$",
Expand Down
22 changes: 15 additions & 7 deletions src/api/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,17 +205,18 @@ class AuthInterface {
}

/**
* Get the names of all containers found.
* @return {Promise<[String]>}
* Get the names of all containers found and the app's granted
* permissions for each of them.
* @return {Promise<[ContainersPerms]>}
*/
getContainersNames() {
return lib.access_container_get_names(this.app.connection);
getContainersPermissions() {
return lib.access_container_fetch(this.app.connection);
}

/**
* Get the MutableData for the app's own container generated by Authenticator.
* When run in tests, this falls back to the randomly generated version
* @return {Promise<[String]}
* @return {Promise<MutableData>}
*/
getOwnContainer() {
const appInfo = this.app.appInfo;
Expand All @@ -229,7 +230,8 @@ class AuthInterface {
prms = prms.catch((err) => {
// Error code -1002 corresponds to 'Container not found' case
if (err.code !== -1002) return Promise.reject(err);
return this.getContainersNames().then((names) => {
return this.getContainersPermissions().then((contPerms) => {
const names = Object.keys(contPerms);
const ctrnName = names.find((x) => x.match(/^apps\//));
if (!ctrnName) return Promise.reject(err);
return this.getContainer(ctrnName);
Expand All @@ -254,7 +256,13 @@ class AuthInterface {
perms = permissions;
}
}
return lib.access_container_is_permitted(this.app.connection, name, perms);

return this.getContainersPermissions()
.then((containersPerms) => {
const contPerms = containersPerms[name];
const result = perms.every((perm) => contPerms[perm]);
return Promise.resolve(result);
});
}

/**
Expand Down
63 changes: 31 additions & 32 deletions src/native/_auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ const AppExchangeInfo = Struct({
vendor: 'string'
});

const ContainerNames = new ArrayType('char *');

const PermissionSet = Struct({
Read: t.bool,
Insert: t.bool,
Expand Down Expand Up @@ -192,49 +190,50 @@ module.exports = {
encode_share_mdata_req: [t.Void, [ref.refType(ShareMDataReq), 'pointer', 'pointer'] ],
encode_unregistered_req: [t.Void, ['pointer', 'pointer'] ],
decode_ipc_msg: [t.Void, [
"string", // (msg: *const c_char,
'string', // (msg: *const c_char,
t.VoidPtr, // user_data: *mut c_void,
"pointer", // o_auth: extern "C" fn(*mut c_void, u32, FfiAuthGranted),
"pointer", // o_unregistered: extern "C" fn(*mut c_void, u32, *const u8, usize),
"pointer", // o_containers: extern "C" fn(*mut c_void, u32),
"pointer", // o_share_mdata: extern "C" fn(*mut c_void, u32),
"pointer", // o_revoked: extern "C" fn(*mut c_void),
"pointer" // o_err: extern "C" fn(*mut c_void, i32, u32)
'pointer', // o_auth: extern "C" fn(*mut c_void, u32, FfiAuthGranted),
'pointer', // o_unregistered: extern "C" fn(*mut c_void, u32, *const u8, usize),
'pointer', // o_containers: extern "C" fn(*mut c_void, u32),
'pointer', // o_share_mdata: extern "C" fn(*mut c_void, u32),
'pointer', // o_revoked: extern "C" fn(*mut c_void),
'pointer' // o_err: extern "C" fn(*mut c_void, i32, u32)
] ],
// access container:
// app: *const App, user_data: *mut c_void, o_cb: extern "C" fn(*mut c_void, i32, *const *const c_char, u32))
access_container_get_names: [t.Void, [AppPtr, "pointer", "pointer"]],
// app: *const App, user_data: *mut c_void, o_cb: extern "C" fn(*mut c_void, i32, *const ContainerPermissions, usize))
access_container_fetch: [t.Void, [AppPtr, 'pointer', 'pointer']],
// app: *const App, user_data: *mut c_void, o_cb: extern "C" fn(*mut c_void, i32)
access_container_refresh_access_info: [t.Void, [AppPtr, "pointer", "pointer"]],
access_container_refresh_access_info: [t.Void, [AppPtr, 'pointer', 'pointer']],
// app: *const App, name: FfiString, user_data: *mut c_void, o_cb: extern "C" fn(*mut c_void, i32, MDataInfoHandle)
access_container_get_container_mdata_info: [t.Void, [AppPtr, 'string', "pointer", "pointer"]],
// (app: *const App, name: FfiString, permission: Permission, user_data: *mut c_void, o_cb: extern "C" fn(*mut c_void, i32, bool)) {
access_container_is_permitted: [t.Void, [AppPtr, 'string', ContainerPermissionsArray, "pointer", "pointer"]],
access_container_get_container_mdata_info: [t.Void, [AppPtr, 'string', 'pointer', 'pointer']],
},
helpers: {
makeAppInfo,
makePermissions,
makeShareMDataPermissions,
},
api: {
access_container_get_names: helpers.Promisified(null, ["pointer", 'uint32'], (args) => {
access_container_fetch: helpers.Promisified(null, [ref.refType(ContainerPermissions), t.usize], (args) => {
const ptr = args[0];
const len = args[1];
const names = [];
const PTR_SIZE = ptr.ref().length;
for (let i = 0; i < len; i++) {
let name = ref.readCString(ref.readPointer(ptr, i* PTR_SIZE , (i + 1) * PTR_SIZE));
names.push(name);
let arrPtr = ref.reinterpret(ptr, ContainerPermissions.size * len);
let arr = ContainerPermissionsArray(arrPtr)
const contsPerms = {};
for (let i = 0; i < len ; i++) {
let cont = arr[i];
contsPerms[cont.cont_name] = {
Read: cont.access.Read,
Insert: cont.access.Insert,
Update: cont.access.Update,
Delete: cont.access.Delete,
ManagePermissions: cont.access.ManagePermissions
}
}
return names;
return contsPerms;
}),
access_container_refresh_access_info: helpers.Promisified(),
access_container_get_container_mdata_info: helpers.Promisified((app, str) =>
[app, str], 'pointer'),
access_container_is_permitted: helpers.Promisified((app, str, perms) => {
const permArray = makePermissionsSet(perms);
return [app, str, permArray]
}, t.bool),
encode_containers_req: helpers.Promisified(null, ['uint32', 'char *'], remapEncodeValues),
encode_auth_req: helpers.Promisified(null, ['uint32', 'char *'], remapEncodeValues),
encode_share_mdata_req: helpers.Promisified(null, ['uint32', 'char *'], remapEncodeValues),
Expand All @@ -244,22 +243,22 @@ module.exports = {
return new Promise(function(resolve, reject) {
fn.async(str,
ref.NULL,
ffi.Callback("void", [t.VoidPtr, "uint32", ref.refType(AuthGranted)], function(user_data, req_id, authGranted) {
ffi.Callback('void', [t.VoidPtr, 'uint32', ref.refType(AuthGranted)], function(user_data, req_id, authGranted) {
resolve(["granted", authGranted])
}),
ffi.Callback("void", [t.VoidPtr, "uint32", t.u8Pointer, t.usize], function(user_data, req_id, connUri, connUriLen) {
ffi.Callback('void', [t.VoidPtr, 'uint32', t.u8Pointer, t.usize], function(user_data, req_id, connUri, connUriLen) {
resolve(["unregistered", new Buffer(ref.reinterpret(connUri, connUriLen, 0))])
}),
ffi.Callback("void", [t.VoidPtr, "uint32"], function(user_data, req_id) {
ffi.Callback('void', [t.VoidPtr, 'uint32'], function(user_data, req_id) {
resolve(["containers", req_id])
}),
ffi.Callback("void", [t.VoidPtr, "uint32"], function(user_data, req_id) {
ffi.Callback('void', [t.VoidPtr, 'uint32'], function(user_data, req_id) {
resolve(["share_mdata", req_id])
}),
ffi.Callback("void", [t.VoidPtr], function(user_data) {
ffi.Callback('void', [t.VoidPtr], function(user_data) {
resolve(["revoked"])
}),
ffi.Callback("void", [t.VoidPtr, t.FfiResult, "uint32"], function(user_data, result, req_id) {
ffi.Callback('void', [t.VoidPtr, t.FfiResult, 'uint32'], function(user_data, result, req_id) {
reject(makeFfiError(result.error_code, result.error_description))
}),
function () {}
Expand Down
34 changes: 24 additions & 10 deletions test/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const h = require('./helpers');
const createAuthenticatedTestApp = h.createAuthenticatedTestApp;

describe('Access Container', () => {
const app = createAuthenticatedTestApp('_test_scope', { _public: ['Read'], _publicNames: ['Read', 'Insert'] });
const containersPermissions = { _public: ['Read'], _publicNames: ['Read', 'Insert', 'ManagePermissions'] };
const app = createAuthenticatedTestApp('_test_scope', containersPermissions);

it('should have a connection object after completing app authentication', () => {
should.exist(app.connection);
Expand All @@ -14,11 +15,25 @@ describe('Access Container', () => {
should(app.auth.registered).be.true();
});

/* eslint-disable dot-notation */
it('get container names', () => app.auth.refreshContainersPermissions().then(() =>
app.auth.getContainersNames().then((names) => {
// we always get a our own sandboxed container in tests")
should(names.length).be.equal(3);
should(names).containEql('_public');
app.auth.getContainersPermissions().then((contsPerms) => {
// we always get a our own sandboxed container in tests
should(Object.keys(contsPerms).length).be.equal(3);
should(contsPerms['_public']).be.eql({
Read: true,
Insert: false,
Delete: false,
Update: false,
ManagePermissions: false
});
should(contsPerms['_publicNames']).be.eql({
Read: true,
Insert: true,
Delete: false,
Update: false,
ManagePermissions: true
});
})));

it('get own container', () => app.auth.refreshContainersPermissions().then(() =>
Expand All @@ -31,14 +46,13 @@ describe('Access Container', () => {
should(hasAccess).be.true();
})));

// This is blocked by issue MAID-2265
it.skip('has read access to `_public` for `Read` and Insert`', () => app.auth.refreshContainersPermissions().then(() =>
it('has read access to `_public` for `Read` and Insert`', () => app.auth.refreshContainersPermissions().then(() =>
app.auth.canAccessContainer('_public', ['Read', 'Insert']).then((hasAccess) => {
should(hasAccess).be.false();
})));

it('has read access to `_publicNames` for `Read` and Insert`', () => app.auth.refreshContainersPermissions().then(() =>
app.auth.canAccessContainer('_publicNames', ['Read', 'Insert']).then((hasAccess) => {
it('has read access to `_publicNames` for `Read` and ManagePermissions`', () => app.auth.refreshContainersPermissions().then(() =>
app.auth.canAccessContainer('_publicNames', ['Read', 'ManagePermissions']).then((hasAccess) => {
should(hasAccess).be.true();
})));

Expand All @@ -52,7 +66,7 @@ describe('Access Container', () => {
should(resp.tag).equal(15000);
})));

it('mutate info of `_public` container', () => app.auth.refreshContainersPermissions().then(() =>
it('mutate info of `_publicNames` container', () => app.auth.refreshContainersPermissions().then(() =>
app.auth.getContainer('_publicNames')
.then((md) => md.getEntries()
.then((entries) => entries.mutate()
Expand Down
2 changes: 1 addition & 1 deletion test/mutable.js
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ describe('Mutable Data', () => {
)
);

it.skip('nfs creation and modification date for read', () => {
it('nfs creation and modification date for read', () => {
let creationDate;
return app.mutableData.newRandomPrivate(TAG_TYPE)
.then((m) => m.quickSetup({}).then(() => m.emulateAs('NFS')))
Expand Down

0 comments on commit 832d4bf

Please sign in to comment.