From 3328fc5ee75c1c3bb84872bca47879372ce2ae4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomek=20=C5=81aziuk?= Date: Tue, 5 Dec 2017 11:09:57 +0100 Subject: [PATCH] rbac-a --- types/rbac-a/index.d.ts | 101 +++++++++++++++++++++++ types/rbac-a/lib/attributes-manager.d.ts | 2 + types/rbac-a/lib/provider.d.ts | 2 + types/rbac-a/lib/rbac.d.ts | 2 + types/rbac-a/rbac-a-tests.ts | 40 +++++++++ types/rbac-a/tsconfig.json | 25 ++++++ types/rbac-a/tslint.json | 1 + 7 files changed, 173 insertions(+) create mode 100644 types/rbac-a/index.d.ts create mode 100644 types/rbac-a/lib/attributes-manager.d.ts create mode 100644 types/rbac-a/lib/provider.d.ts create mode 100644 types/rbac-a/lib/rbac.d.ts create mode 100644 types/rbac-a/rbac-a-tests.ts create mode 100644 types/rbac-a/tsconfig.json create mode 100644 types/rbac-a/tslint.json diff --git a/types/rbac-a/index.d.ts b/types/rbac-a/index.d.ts new file mode 100644 index 0000000000..0d034b16e4 --- /dev/null +++ b/types/rbac-a/index.d.ts @@ -0,0 +1,101 @@ +// Type definitions for rbac-a 0.2 +// Project: https://github.com/yanickrochon/rbac-a#readme +// Definitions by: Tomek Łaziuk +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/// + +import { + EventEmitter, +} from "events"; + +export interface Roles { + [_: string]: number | Roles; +} + +export class Provider { + /** + * Return all the roles available for the given user. The return value + * must be an object, recursively defining the associated roles for the + * specified user. Return an empty object if user has no roles. + * Ex: { + * "role1": { + * "role1.1": null, + * "role1.2": { ... }, + * ... + * }, + * "secondary": ..., + * ... + * } + * The method mey return a promise resolving with the + * expected return value. + */ + getRoles(use: any): Roles | Promise; + /** + * Return all permissions for the specified role. The return value + * must be an array. Return an empty array if role is missing or + * no permission for the specified role. + * Ex: ['permission1', 'permission2', ... ] + * The method mey return a promise resolving with the + * expected return value. + */ + getPermission(role: any): string[] | Promise; + /** + * Return all attributes for the specified role. The return value must + * be an array. Return an empty array if role is missing or if no + * attributes for the specified role. + * Ex: ['attribute1', 'attribute2', ... ] + * The method mey return a promise resolving with the + * expected return value. + */ + getAttributes(role: any): string[] | Promise; +} + +export type AttributeFunction = (user: any, role: string, params: object) => any; + +/** + * Attributes Manager + * This class encapsulate attributes definition and validation. + * Usage + * var roleValid = attributesManager.validate(attribute, user, role, params); + */ +export class AttributesManager { + protected _attributes: { [_: string]: AttributeFunction }; + /** Define an attribute. The returned value is self for chaining. */ + set(attribute: AttributeFunction): this; + /** + * Undefine an attribute, by name or function and return removed + * attribute function if one was found. + */ + remove(attribute: string | AttributeFunction): AttributeFunction; + /** + * Validate the attribute with the specified user, role and parameters. + * The method will return a truthy value if the attribute valid, or a + * falsy otherwise. + * The method may also return a promise resolivng to the expected returne + * value, or reject. A rejected promise should be considered falsy. + * If the specified attribute does not exist, false is returned. + */ + validate(attribute: string, user: any, role: string, params: object): any; +} + +export class RBAC

extends EventEmitter { + readonly provider: P; + readonly attributes: AM; + constructor(opts: { provider: P, attributes?: AM }); + /** + * Check the user for the given permissions. The method will return + * a Promise resolving with a number. If the user has sufficient + * access to the specified permissions, the promise should resolve + * with a positive, non-zero value, or with NaN otherwise. If the + * Promise is rejected, it should be considered as if the user has + * insufficient access to the specified ressources. + */ + check(user: any, permission: string | string[], params?: object): Promise; +} + +export const Providers: { + /** Basic JSON permissions provider */ + JsonProvider: { new(roles: object): Provider }; +}; diff --git a/types/rbac-a/lib/attributes-manager.d.ts b/types/rbac-a/lib/attributes-manager.d.ts new file mode 100644 index 0000000000..619370c6a1 --- /dev/null +++ b/types/rbac-a/lib/attributes-manager.d.ts @@ -0,0 +1,2 @@ +import { AttributesManager } from ".."; +export = AttributesManager; diff --git a/types/rbac-a/lib/provider.d.ts b/types/rbac-a/lib/provider.d.ts new file mode 100644 index 0000000000..9c94f32f1d --- /dev/null +++ b/types/rbac-a/lib/provider.d.ts @@ -0,0 +1,2 @@ +import { Provider } from ".."; +export = Provider; diff --git a/types/rbac-a/lib/rbac.d.ts b/types/rbac-a/lib/rbac.d.ts new file mode 100644 index 0000000000..fae3c7321b --- /dev/null +++ b/types/rbac-a/lib/rbac.d.ts @@ -0,0 +1,2 @@ +import { RBAC } from ".."; +export = RBAC; diff --git a/types/rbac-a/rbac-a-tests.ts b/types/rbac-a/rbac-a-tests.ts new file mode 100644 index 0000000000..da783a2617 --- /dev/null +++ b/types/rbac-a/rbac-a-tests.ts @@ -0,0 +1,40 @@ +import { + Provider, + RBAC, +} from "rbac-a"; + +class CustomProvider extends Provider { } + +const rbac = new RBAC({ + provider: new CustomProvider() +}); + +const user = "ExampleUser"; + +rbac.on('error', (err) => { + console.error('Error while checking $s/%s', err.role, err.user); + console.error(err.stack); +}); + +rbac.check(user, 'create').then((allowed) => { + if (allowed) { + console.log('User can create!'); + } else { + console.log('User cannot create.'); + console.info('Please contact your system admin for more information'); + } +}).catch((err) => { + console.error(err && err.stack || err || 'ERROR'); +}); + +// specify attributes arguments +rbac.check(user, 'edit', { time: Date.now() }).then((allowed) => { + if (allowed) { + console.log('User can edit!'); + } else { + console.log('User cannot edit.'); + console.info('Please contact your system admin for more information'); + } +}).catch((err) => { + console.error(err && err.stack || err || 'ERROR'); +}); diff --git a/types/rbac-a/tsconfig.json b/types/rbac-a/tsconfig.json new file mode 100644 index 0000000000..214434a838 --- /dev/null +++ b/types/rbac-a/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "lib/attributes-manager.d.ts", + "lib/provider.d.ts", + "lib/rbac.d.ts", + "rbac-a-tests.ts" + ] +} diff --git a/types/rbac-a/tslint.json b/types/rbac-a/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/rbac-a/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }