|
@@ -188,15 +188,6 @@ class PermissionService extends BaseService {
|
|
|
return permission;
|
|
|
}
|
|
|
|
|
|
- async check () {
|
|
|
- const ld = (Context.get('logdent') ?? 0) + 1;
|
|
|
- return await Context.get().sub({ logdent: ld }).arun(async () => {
|
|
|
- const res = await this.check__(...arguments);
|
|
|
- // this.log.noticeme('RETURN ' + res);
|
|
|
- return res;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
async scan (actor, permission_options) {
|
|
|
const reading = [];
|
|
|
|
|
@@ -214,171 +205,6 @@ class PermissionService extends BaseService {
|
|
|
return reading;
|
|
|
}
|
|
|
|
|
|
- async check__ (actor, permission) {
|
|
|
- permission = await this._rewrite_permission(permission);
|
|
|
-
|
|
|
- this.log.info(`checking permission ${permission} for actor ${actor.uid}`, {
|
|
|
- actor: actor.uid,
|
|
|
- permission,
|
|
|
- });
|
|
|
-
|
|
|
- // for ( const implicator of this._permission_implicators ) {
|
|
|
- // if ( ! implicator.matches(permission) ) continue;
|
|
|
- // const implied = await implicator.check({
|
|
|
- // actor,
|
|
|
- // permission,
|
|
|
- // recurse: this.check.bind(this),
|
|
|
- // });
|
|
|
- // if ( implied ) return implied;
|
|
|
- // }
|
|
|
-
|
|
|
- // For now we're only checking driver permissions, and users have all of them
|
|
|
- if ( actor.type instanceof UserActorType ) {
|
|
|
- return await this.check_user_permission(actor, permission);
|
|
|
- }
|
|
|
-
|
|
|
- if ( actor.type instanceof AccessTokenActorType ) {
|
|
|
- // Authorizer must have permission
|
|
|
- const authorizer_permission = await this.check(actor.type.authorizer, permission);
|
|
|
- if ( ! authorizer_permission ) return false;
|
|
|
-
|
|
|
- return await this.check_access_token_permission(
|
|
|
- actor.type.authorizer, actor.type.token, permission
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- // Prevent undefined behaviour
|
|
|
- if ( actor.type instanceof AppUnderUserActorType ) {
|
|
|
- // NEXT:
|
|
|
- const app_uid = actor.type.app.uid;
|
|
|
- const user_actor = actor.get_related_actor(UserActorType);
|
|
|
- // const user_has_permission = await this.check_user_permission(user_actor, permission);
|
|
|
- const user_has_permission = await this.check__(
|
|
|
- user_actor, permission,
|
|
|
- );
|
|
|
- if ( ! user_has_permission ) return undefined;
|
|
|
-
|
|
|
- // This was a useful log so I'm keeping it here
|
|
|
- // console.log('\x1B[36;1m>=== THIS IS HERE ===<\x1B[0m',
|
|
|
- // app_uid,
|
|
|
- // permission,
|
|
|
- // )
|
|
|
-
|
|
|
- return await this.check_user_app_permission(actor, app_uid, permission);
|
|
|
- }
|
|
|
-
|
|
|
- if ( actor.type instanceof SiteActorType ) {
|
|
|
- return await this.check_site_permission(actor, permission);
|
|
|
- }
|
|
|
-
|
|
|
- console.log ('WHAT ACTOR TYPE THEN???', actor.type);
|
|
|
-
|
|
|
- throw new Error('unrecognized actor type');
|
|
|
- }
|
|
|
-
|
|
|
- // TODO: context meta for cycle detection
|
|
|
- async check_user_permission (actor, permission) {
|
|
|
- return await require('../../structured/sequence/check-user-permission')
|
|
|
- .call(this, {
|
|
|
- // passed
|
|
|
- actor,
|
|
|
- permission,
|
|
|
- // constants
|
|
|
- implicit_user_permissions,
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- async check_access_token_permission (authorizer, token, permission) {
|
|
|
- const rows = await this.db.read(
|
|
|
- 'SELECT * FROM `access_token_permissions` ' +
|
|
|
- 'WHERE `token_uid` = ? AND `permission` = ?',
|
|
|
- [
|
|
|
- token,
|
|
|
- permission,
|
|
|
- ]
|
|
|
- );
|
|
|
-
|
|
|
- // Token must have permission
|
|
|
- if ( ! rows[0] ) return undefined;
|
|
|
-
|
|
|
- return rows[0].extra;
|
|
|
- }
|
|
|
-
|
|
|
- async check_user_app_permission (actor, app_uid, permission) {
|
|
|
- permission = await this._rewrite_permission(permission);
|
|
|
-
|
|
|
- let app = await get_app({ uid: app_uid });
|
|
|
- if ( ! app ) app = await get_app({ name: app_uid });
|
|
|
- const app_id = app.id;
|
|
|
-
|
|
|
- // const parent_perms = this.get_parent_permissions(permission);
|
|
|
- const parent_perms = await this.get_higher_permissions(permission);
|
|
|
-
|
|
|
- for ( const permission of parent_perms ) {
|
|
|
- // Check hardcoded permissions
|
|
|
- if ( default_implicit_user_app_permissions[permission] ) {
|
|
|
- return default_implicit_user_app_permissions[permission];
|
|
|
- }
|
|
|
-
|
|
|
- // Check implicit permissions
|
|
|
- const implicit_permissions = {};
|
|
|
- for ( const implicit_permission of implicit_user_app_permissions ) {
|
|
|
- if ( implicit_permission.apps.includes(app_uid) ) {
|
|
|
- implicit_permissions[permission] = implicit_permission.permissions[permission];
|
|
|
- }
|
|
|
- }
|
|
|
- if ( implicit_permissions[permission] ) {
|
|
|
- return implicit_permissions[permission];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // My biggest gripe with SQL is doing string manipulation for queries.
|
|
|
- // If the grammar for SQL was simpler we could model it, write this as
|
|
|
- // data, and even implement macros for common patterns.
|
|
|
- let sql_perm = parent_perms.map((perm) =>
|
|
|
- `\`permission\` = ?`).join(' OR ');
|
|
|
- if ( parent_perms.length > 1 ) sql_perm = '(' + sql_perm + ')';
|
|
|
-
|
|
|
- // SELECT permission
|
|
|
- const rows = await this.db.read(
|
|
|
- 'SELECT * FROM `user_to_app_permissions` ' +
|
|
|
- 'WHERE `user_id` = ? AND `app_id` = ? AND ' +
|
|
|
- sql_perm,
|
|
|
- [
|
|
|
- actor.type.user.id,
|
|
|
- app_id,
|
|
|
- ...parent_perms,
|
|
|
- ]
|
|
|
- );
|
|
|
-
|
|
|
- if ( ! rows[0] ) return undefined;
|
|
|
-
|
|
|
- return rows[0].extra;
|
|
|
- }
|
|
|
-
|
|
|
- async check_site_permission (actor, permission) {
|
|
|
- permission = await this._rewrite_permission(permission);
|
|
|
- // const parent_perms = this.get_parent_permissions(permission);
|
|
|
- const parent_perms = await this.get_higher_permissions(permission);
|
|
|
-
|
|
|
- // Check implicit permissions
|
|
|
- for ( const parent_perm of parent_perms ) {
|
|
|
- if ( implicit_user_permissions[parent_perm] ) {
|
|
|
- return implicit_user_permissions[parent_perm];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for ( const implicator of this._permission_implicators ) {
|
|
|
- if ( ! implicator.matches(permission) ) continue;
|
|
|
- const implied = await implicator.check({
|
|
|
- actor,
|
|
|
- permission,
|
|
|
- recurse: this.check.bind(this),
|
|
|
- });
|
|
|
- if ( implied ) return implied;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
async grant_user_app_permission (actor, app_uid, permission, extra = {}, meta) {
|
|
|
permission = await this._rewrite_permission(permission);
|
|
|
|