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

Custom declarative condition Fns #45

Open
myovchev opened this issue Feb 28, 2020 · 6 comments
Open

Custom declarative condition Fns #45

myovchev opened this issue Feb 28, 2020 · 6 comments

Comments

@myovchev
Copy link
Contributor

myovchev commented Feb 28, 2020

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,
  },
};
@koladilip
Copy link
Contributor

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

@myovchev
Copy link
Contributor Author

myovchev commented Apr 9, 2020

I'll look into it asap.

@koladilip
Copy link
Contributor

#49
I have added this feature but not exactly this way, please look into it and see if this still requires?

@koladilip
Copy link
Contributor

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

@myovchev
Copy link
Contributor Author

@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.

@koladilip
Copy link
Contributor

@myovchev I have added test cases for validations: e62f534
Please document this, it will definitely help us.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants