@@ -135,6 +135,32 @@ class PermissionImplicator {
135
135
}
136
136
}
137
137
138
+ class PermissionExploder {
139
+ static create ( { id, matcher, exploder } ) {
140
+ return new PermissionExploder ( { id, matcher, exploder } ) ;
141
+ }
142
+
143
+ constructor ( { id, matcher, exploder } ) {
144
+ this . id = id ;
145
+ this . matcher = matcher ;
146
+ this . exploder = exploder ;
147
+ }
148
+
149
+ matches ( permission ) {
150
+ return this . matcher ( permission ) ;
151
+ }
152
+
153
+ /**
154
+ * Check if the permission is implied by this implicator
155
+ * @param {Actor } actor
156
+ * @param {string } permission
157
+ * @returns
158
+ */
159
+ async explode ( { actor, permission } ) {
160
+ return await this . exploder ( { actor, permission } ) ;
161
+ }
162
+ }
163
+
138
164
class PermissionUtil {
139
165
static unescape_permission_component ( component ) {
140
166
let unescaped_str = '' ;
@@ -194,6 +220,7 @@ class PermissionService extends BaseService {
194
220
195
221
this . _permission_rewriters = [ ] ;
196
222
this . _permission_implicators = [ ] ;
223
+ this . _permission_exploders = [ ] ;
197
224
}
198
225
199
226
async _rewrite_permission ( permission ) {
@@ -220,6 +247,17 @@ class PermissionService extends BaseService {
220
247
actor : actor . uid ,
221
248
permission,
222
249
} ) ;
250
+
251
+ // for ( const implicator of this._permission_implicators ) {
252
+ // if ( ! implicator.matches(permission) ) continue;
253
+ // const implied = await implicator.check({
254
+ // actor,
255
+ // permission,
256
+ // recurse: this.check.bind(this),
257
+ // });
258
+ // if ( implied ) return implied;
259
+ // }
260
+
223
261
// For now we're only checking driver permissions, and users have all of them
224
262
if ( actor . type instanceof UserActorType ) {
225
263
return await this . check_user_permission ( actor , permission ) ;
@@ -240,8 +278,17 @@ class PermissionService extends BaseService {
240
278
// NEXT:
241
279
const app_uid = actor . type . app . uid ;
242
280
const user_actor = actor . get_related_actor ( UserActorType ) ;
243
- const user_has_permission = await this . check_user_permission ( user_actor , permission ) ;
281
+ // const user_has_permission = await this.check_user_permission(user_actor, permission);
282
+ const user_has_permission = await this . check__ (
283
+ user_actor , permission ,
284
+ ) ;
244
285
if ( ! user_has_permission ) return undefined ;
286
+
287
+ // This was a useful log so I'm keeping it here
288
+ // console.log('\x1B[36;1m>=== THIS IS HERE ===<\x1B[0m',
289
+ // app_uid,
290
+ // permission,
291
+ // )
245
292
246
293
return await this . check_user_app_permission ( actor , app_uid , permission ) ;
247
294
}
@@ -252,7 +299,8 @@ class PermissionService extends BaseService {
252
299
// TODO: context meta for cycle detection
253
300
async check_user_permission ( actor , permission ) {
254
301
permission = await this . _rewrite_permission ( permission ) ;
255
- const parent_perms = this . get_parent_permissions ( permission ) ;
302
+ // const parent_perms = this.get_parent_permissions(permission);
303
+ const parent_perms = await this . get_higher_permissions ( permission ) ;
256
304
257
305
// Check implicit permissions
258
306
for ( const parent_perm of parent_perms ) {
@@ -329,7 +377,8 @@ class PermissionService extends BaseService {
329
377
if ( ! app ) app = await get_app ( { name : app_uid } ) ;
330
378
const app_id = app . id ;
331
379
332
- const parent_perms = this . get_parent_permissions ( permission ) ;
380
+ // const parent_perms = this.get_parent_permissions(permission);
381
+ const parent_perms = await this . get_higher_permissions ( permission ) ;
333
382
334
383
for ( const permission of parent_perms ) {
335
384
// Check hardcoded permissions
@@ -348,7 +397,7 @@ class PermissionService extends BaseService {
348
397
return implicit_permissions [ permission ] ;
349
398
}
350
399
}
351
-
400
+
352
401
// My biggest gripe with SQL is doing string manipulation for queries.
353
402
// If the grammar for SQL was simpler we could model it, write this as
354
403
// data, and even implement macros for common patterns.
@@ -665,6 +714,21 @@ class PermissionService extends BaseService {
665
714
666
715
return retval ;
667
716
}
717
+
718
+ async get_higher_permissions ( permission ) {
719
+ const higher_perms = [ ] ;
720
+ const parent_perms = this . get_parent_permissions ( permission ) ;
721
+ for ( const parent_perm of parent_perms ) {
722
+ for ( const exploder of this . _permission_exploders ) {
723
+ if ( ! exploder . matches ( parent_perm ) ) continue ;
724
+ const perms = await exploder . explode ( {
725
+ permission : parent_perm ,
726
+ } ) ;
727
+ higher_perms . push ( ...perms ) ;
728
+ }
729
+ }
730
+ return higher_perms ;
731
+ }
668
732
669
733
get_parent_permissions ( permission ) {
670
734
const parent_perms = [ ] ;
@@ -699,6 +763,14 @@ class PermissionService extends BaseService {
699
763
this . _permission_implicators . push ( implicator ) ;
700
764
}
701
765
766
+ register_exploder ( exploder ) {
767
+ if ( ! ( exploder instanceof PermissionExploder ) ) {
768
+ throw new Error ( 'exploder must be a PermissionExploder' ) ;
769
+ }
770
+
771
+ this . _permission_exploders . push ( exploder ) ;
772
+ }
773
+
702
774
_register_commands ( commands ) {
703
775
commands . registerCommands ( 'perms' , [
704
776
{
@@ -723,6 +795,7 @@ class PermissionService extends BaseService {
723
795
module . exports = {
724
796
PermissionRewriter,
725
797
PermissionImplicator,
798
+ PermissionExploder,
726
799
PermissionUtil,
727
800
PermissionService,
728
801
} ;
0 commit comments