@@ -164,23 +164,49 @@ function mapTuple(tuple: TupleKey): RelationReference {
164
164
} ;
165
165
}
166
166
167
+ function parseObjectString ( object : string ) : { type : string ; id : string } {
168
+ const result = object . split ( ":" ) ;
169
+ return { type : result [ 0 ] , id : result [ 1 ] } ;
170
+ }
171
+
172
+ function parseUserString ( user : string ) : {
173
+ type : string ;
174
+ id : string | undefined ;
175
+ relation : string | undefined ;
176
+ wildcard : boolean ;
177
+ } {
178
+ const result = user . split ( ":" ) ;
179
+ const type = result [ 0 ] ;
180
+
181
+ if ( result [ 1 ] === "*" ) {
182
+ return { type, id : undefined , relation : undefined , wildcard : true } ;
183
+ }
184
+
185
+ if ( result [ 1 ] . includes ( "#" ) ) {
186
+ const [ id , relation ] = result [ 1 ] . split ( "#" ) ;
187
+ return { type, id, relation, wildcard : false } ;
188
+ }
189
+
190
+ return { type, id : result [ 1 ] , relation : undefined , wildcard : false } ;
191
+ }
192
+
167
193
// Validation for Types
168
194
169
195
function validateTypes ( tuple : TupleKey , types : string [ ] , instancePath : string ) : boolean {
170
196
const errors = [ ] ;
171
197
172
- const user = tuple . user . split ( ":" ) [ 0 ] ;
198
+ const userType = parseUserString ( tuple . user ) . type ;
173
199
174
200
// Ensure valid type of user
175
- if ( ! types . includes ( user ) ) {
176
- errors . push ( invalidType ( user , types , instancePath + "/user" ) ) ;
201
+ if ( ! types . includes ( userType ) ) {
202
+ errors . push ( invalidType ( userType , types , instancePath + "/user" ) ) ;
177
203
}
178
204
179
- const object = tuple . object . split ( ":" ) [ 0 ] ;
205
+ const objectType = parseObjectString ( tuple . object ) . type ;
180
206
181
207
// Ensure valid type of object
182
- if ( ! types . includes ( object ) ) {
183
- errors . push ( invalidType ( object , types , instancePath + "/object" ) ) ;
208
+ if ( ! types . includes ( objectType ) ) {
209
+ errors . push ( invalidType ( objectType , types , instancePath + "/object" ) ) ;
184
210
}
185
211
186
212
// Report all errors
@@ -198,22 +224,26 @@ function validateRelation(tuple: TupleKey, typeDefs: TypeDefinition[], instanceP
198
224
// Check if relation exists on given type
199
225
let doesExistOnType = false ;
200
226
if ( tuple . user . includes ( "#" ) ) {
201
- const user = tuple . user . split ( ":" ) [ 0 ] ;
202
- const userRelation = tuple . user . split ( "#" ) [ 1 ] ;
227
+ const userResult = parseUserString ( tuple . user ) ;
203
228
for ( const typeDef of typeDefs ) {
204
- if ( typeDef && typeDef . type === user && typeDef . relations ?. [ userRelation ] ) {
229
+ if (
230
+ typeDef &&
231
+ typeDef . type === userResult . type &&
232
+ userResult . relation &&
233
+ typeDef . relations ?. [ userResult . relation ]
234
+ ) {
205
235
doesExistOnType = true ;
206
236
break ;
207
237
}
208
238
}
209
239
210
- if ( ! doesExistOnType ) {
211
- errors . push ( relationMustExistOnType ( userRelation , user , instancePath + "/user" ) ) ;
240
+ if ( ! doesExistOnType && userResult . relation ) {
241
+ errors . push ( relationMustExistOnType ( userResult . relation , userResult . type , instancePath + "/user" ) ) ;
212
242
}
213
243
}
214
244
215
245
// Check if relation exists on given object
216
- const objectType = tuple . object . split ( ":" ) [ 0 ] ;
246
+ const objectType = parseObjectString ( tuple . object ) . type ;
217
247
let doesExistOnObject = false ;
218
248
for ( const typeDef of typeDefs ) {
219
249
if ( typeDef && typeDef . type === objectType && typeDef . relations ?. [ tuple . relation ] ) {
@@ -256,7 +286,7 @@ function validateTypeRestrictions(
256
286
validateTuple . errors = validateTuple . errors || [ ] ;
257
287
258
288
const mappedTuple = mapTuple ( tuple ) ;
259
- const type = tuple . object . split ( ":" ) [ 0 ] ;
289
+ const type = parseObjectString ( tuple . object ) . type ;
260
290
const foundType = typeDefs . filter ( ( t ) => t . type === type ) [ 0 ] ;
261
291
const userTypes = foundType ?. metadata ?. relations ?. [ tuple . relation ] . directly_related_user_types ;
262
292
@@ -349,7 +379,7 @@ const validateTuple: SchemaValidateFunction = function (
349
379
// Validate the type field for check and list_objects
350
380
function validateUserField ( model : AuthorizationModel , types : string [ ] , userField : string , instancePath : string ) {
351
381
const errors = [ ] ;
352
- const foundType = userField . split ( ":" ) [ 0 ] ;
382
+ const foundType = parseUserString ( userField ) . type ;
353
383
354
384
// Ensure valid type
355
385
if ( ! types . includes ( foundType ) ) {
@@ -434,11 +464,11 @@ function validateCheck(
434
464
435
465
if ( checkTest . object && isStringValue ( checkTest . object ) ) {
436
466
const checkObject = checkTest . object ;
437
- const object = checkObject . split ( ":" ) [ 0 ] ;
467
+ const objectType = parseObjectString ( checkObject ) . type ;
438
468
439
469
// Ensure valid type of object
440
- if ( ! types . includes ( object ) ) {
441
- objectErrors . push ( invalidTypeUser ( object , types , instancePath + "/object" ) ) ;
470
+ if ( ! types . includes ( objectType ) ) {
471
+ objectErrors . push ( invalidTypeUser ( objectType , types , instancePath + "/object" ) ) ;
442
472
}
443
473
444
474
if ( ! objectErrors . length ) {
@@ -447,7 +477,7 @@ function validateCheck(
447
477
}
448
478
}
449
479
450
- objectErrors . push ( ...validateAssertionField ( model , object , checkTest . assertions , instancePath ) ) ;
480
+ objectErrors . push ( ...validateAssertionField ( model , objectType , checkTest . assertions , instancePath ) ) ;
451
481
}
452
482
453
483
const context = checkTest . context ;
@@ -520,11 +550,11 @@ function validateListUsers(
520
550
if ( listUsers && isStringValue ( listUsers . object ) ) {
521
551
const listUserObj = listUsers . object ;
522
552
523
- const object = listUserObj . split ( ":" ) [ 0 ] ;
553
+ const objectType = parseObjectString ( listUserObj ) . type ;
524
554
525
555
// Ensure valid type of object
526
- if ( ! types . includes ( object ) ) {
527
- errors . push ( invalidTypeUser ( object , types , instancePath + "/object" ) ) ;
556
+ if ( ! types . includes ( objectType ) ) {
557
+ errors . push ( invalidTypeUser ( objectType , types , instancePath + "/object" ) ) ;
528
558
}
529
559
530
560
if ( ! errors . length ) {
0 commit comments