role-acl icon indicating copy to clipboard operation
role-acl copied to clipboard

Custom declarative condition Fns

Open myovchev opened this issue 4 years ago • 6 comments

I'm exploring the possibility to implement the role-acl lib in a project. I'm injecting it in my own ACL abstraction and everything looks good so far.

However, what I'm missing is an option to declare and register a custom condition Fn as a string and map it to a function. This way I'd be able to wrap more complex business logic and still to serialize and store the grant object.

I see there is custom functions support, which is an option to pre-process the definition and replace a custom condition string with JS function so that library process it, but a native library support would be much better. Not to mention it would open contribution possibilities (I can imagine a MONGODB_QUERY condition...)

Here is sample API of what I have on my mind:

Signature

interface CustomConditionFns {
  [name: string]: (ctx?: Record<string, unknown>, args?: unknown) => boolean;
}

condition.gte.ts

import { get } from 'lodash';

export type ARGS = { field: string; value: number };

export const conditionGte = (ctx: Record<string, any>, args: ARGS) => {
  return +get(ctx, args.field) > args.value;
};

acl.ts

import { AccessControl } from 'role-acl';
import { conditionLte } from 'condition.lte'

const grantObj = fetchOrImportGrant();
const customFns = { 'GTE': conditionGte };

// We'd need to register custom conditions together with grant 
// or before the grant to allow a type checking (unknown condition Fn)

// Register them together with the grant
const acl = new AccessControl(grantObj, customFns);
// OR first conditions, then the grant
const acl = new AccessControl();
acl.useConditions(customFns);
acl.setGrants(grantObj);

Usage (grant definition)

import { ARGS } from 'condition.lte'
const condition: { Fn: 'GTE'; args: ARGS } = {
  Fn: 'GTE',
  args: {
    field: 'user.visits',
    value: 1,
  },
};

myovchev avatar Feb 28 '20 20:02 myovchev

Looks Good to me, can you please send the pull request for the same?

koladilip avatar Mar 02 '20 03:03 koladilip

I'll look into it asap.

myovchev avatar Apr 09 '20 10:04 myovchev

https://github.com/tensult/role-acl/issues/49 I have added this feature but not exactly this way, please look into it and see if this still requires?

koladilip avatar Apr 19 '20 11:04 koladilip

https://github.com/tensult/role-acl/blob/develop/test/acl.spec.ts#L886 This feature is implemented. Please check.

koladilip avatar Apr 20 '20 10:04 koladilip

@koladilip I was about to inform you that I'm done with my urgent work and can finally take a look at the feature implementation. You were quicker though :)

I went through test cases and I had a very quick look on the implementation. The only difference I see is that your interface is more forgiving (not that strict) and you've implemented the registration as a fluent interface instead as batch which I think is perfectly OK :)

What I don't see as test cases is what happens if a custom condition is missing registration but used in the grants - handled/unhandled error, deny or grant (I don't believe you've went with that one).

Thanks for the implementation, it really brings the library to the next level. Let me know if I can be of any help (add this feature to the docs maybe?)

P.S. I don't understand the request in #49 neither. I'm dynamically building the context, so I can think of 1000s ways of building and validating the desired context. It's a matter of implementation and not a library feature.

myovchev avatar Apr 28 '20 20:04 myovchev

@myovchev I have added test cases for validations: https://github.com/tensult/role-acl/commit/e62f53407de2943ff1391664d6515e384257c40d Please document this, it will definitely help us.

koladilip avatar Apr 29 '20 05:04 koladilip