Skip to content

Commit

Permalink
Merge pull request #20 from franciscogouveia/16-wildcards
Browse files Browse the repository at this point in the history
16 wildcards
  • Loading branch information
franciscogouveia committed Mar 4, 2017
2 parents e05a238 + 4fdbbc2 commit 1082034
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 13 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ const context = {
dataRetrieverRouter.setContext(context);

const policy = {
target: [{ 'credentials:username': 'francisco' }, { 'credentials:group': 'admin' }], // if username is 'francisco' OR group is 'admin'
target: [{ 'credentials:username': 'francisco' }, { 'credentials:group': /^articles\:.*$/ }], // if username is 'francisco' OR group matches 'articles:*' (using native javascript RegExp)
apply: 'deny-overrides', // permit, unless one denies
rules: [
{
target: { 'credentials:group': 'admin', 'credentials:validated': false }, // if group is 'admin' AND is not validated
target: { 'credentials:group': 'articles:admin', 'credentials:validated': false }, // if group is 'articles:admin' AND is not validated
effect: 'deny' // then deny (deny access to users that are not validated)
},
{
Expand Down
30 changes: 19 additions & 11 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,27 +212,35 @@ internals.evaluateTargetElementKey = (dataRetriever, element, key) => {
/**
* If target has more than one value, all of them should match
**/
internals._targetApplies = (target, value) => {
internals._targetApplies = (targets, values) => {

if (target === value) {
return true;
if (!Array.isArray(targets)) {
targets = [targets];
}

if (!(value instanceof Array)) {
value = [value];
if (!Array.isArray(values)) {
values = [values];
}

if (!(target instanceof Array)) {
target = [target];
}
// Should match all
// So: continue looping unless one doesn't
for (const index in targets) {
const target = targets[index];
const matches = values.filter((value) => {

for (const index in target) {
if (value.indexOf(target[index]) === -1) {
// At least one doesn't match
if (target instanceof RegExp) {
return target.test(value);
}

return value === target;
});

if (matches.length === 0) {
return false;
}
}

// All targets are matched
return true;
};

Expand Down
85 changes: 85 additions & 0 deletions test/target.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,91 @@ experiment('Target unit tests (AND)', () => {

});

experiment('Target unit tests (AND with RegExp)', () => {

const target = { 'credentials:group': /^articles\:(writer|reader)$/, 'credentials:premium': true };

// Register mocked data retriever
const dataRetriever = new DataRetrievalRouter();
dataRetriever.register('credentials', (source, key, context) => {

return context[key];
}, { override: true });

test('should apply (full match: articles:writer)', (done) => {

const information = {
username: 'user00001',
group: ['articles:writer'],
premium: true
};

Rbac.evaluateTarget(target, dataRetriever.createChild(information), (err, applies) => {

expect(err).to.not.exist();

expect(applies).to.exist().and.to.equal(true);

done();
});
});

test('should apply (full match: articles:reader)', (done) => {

const information = {
username: 'user00002',
group: ['articles:reader'],
premium: true
};

Rbac.evaluateTarget(target, dataRetriever.createChild(information), (err, applies) => {

expect(err).to.not.exist();

expect(applies).to.exist().and.to.equal(true);

done();
});
});

test('should not apply (partial match)', (done) => {

const information = {
username: 'user00003',
group: ['articles:other'],
premium: true
};

Rbac.evaluateTarget(target, dataRetriever.createChild(information), (err, applies) => {

expect(err).to.not.exist();

expect(applies).to.exist().and.to.equal(false);

done();
});
});

test('should not apply (no match)', (done) => {

const information = {
username: 'user00004',
group: ['articles:other'],
premium: false
};

Rbac.evaluateTarget(target, dataRetriever.createChild(information), (err, applies) => {

expect(err).to.not.exist();

expect(applies).to.exist().and.to.equal(false);

done();
});
});

});

experiment('Target unit tests (OR)', () => {

const target = [
Expand Down

0 comments on commit 1082034

Please sign in to comment.