77
88interface ParsedPermitStatement {
99 action : string | null ;
10+ actions : string [ ] | null ;
1011 resourceType : string | null ;
1112 resourceId : string | null ;
1213 isWildcard : boolean ;
@@ -55,21 +56,41 @@ export function parseCedarPolicyToClassicalPermissions(
5556 case 'group:edit' :
5657 result . group . accessLevel = AccessLevelEnum . edit ;
5758 break ;
59+ case 'table:*' : {
60+ const wildcardTableName = permit . resourceId ? extractTableName ( permit . resourceId , connectionId ) : '*' ;
61+ if ( ! wildcardTableName ) break ;
62+ const wildcardTableEntry = getOrCreateTableEntry ( tableMap , wildcardTableName ) ;
63+ applyTableAction ( wildcardTableEntry , 'table:read' ) ;
64+ applyTableAction ( wildcardTableEntry , 'table:add' ) ;
65+ applyTableAction ( wildcardTableEntry , 'table:edit' ) ;
66+ applyTableAction ( wildcardTableEntry , 'table:delete' ) ;
67+ break ;
68+ }
5869 case 'table:read' :
5970 case 'table:add' :
6071 case 'table:edit' :
6172 case 'table:delete' : {
62- const tableName = extractTableName ( permit . resourceId , connectionId ) ;
73+ const tableName = permit . resourceId ? extractTableName ( permit . resourceId , connectionId ) : '*' ;
6374 if ( ! tableName ) break ;
6475 const tableEntry = getOrCreateTableEntry ( tableMap , tableName ) ;
6576 applyTableAction ( tableEntry , permit . action ) ;
6677 break ;
6778 }
79+ case 'dashboard:*' : {
80+ const wildcardDashboardId = permit . resourceId ? extractDashboardId ( permit . resourceId , connectionId ) : '*' ;
81+ if ( ! wildcardDashboardId ) break ;
82+ const wildcardDashboardEntry = getOrCreateDashboardEntry ( dashboardMap , wildcardDashboardId ) ;
83+ applyDashboardAction ( wildcardDashboardEntry , 'dashboard:read' ) ;
84+ applyDashboardAction ( wildcardDashboardEntry , 'dashboard:create' ) ;
85+ applyDashboardAction ( wildcardDashboardEntry , 'dashboard:edit' ) ;
86+ applyDashboardAction ( wildcardDashboardEntry , 'dashboard:delete' ) ;
87+ break ;
88+ }
6889 case 'dashboard:read' :
6990 case 'dashboard:create' :
7091 case 'dashboard:edit' :
7192 case 'dashboard:delete' : {
72- const dashboardId = extractDashboardId ( permit . resourceId , connectionId ) ;
93+ const dashboardId = permit . resourceId ? extractDashboardId ( permit . resourceId , connectionId ) : '*' ;
7394 if ( ! dashboardId ) break ;
7495 const dashboardEntry = getOrCreateDashboardEntry ( dashboardMap , dashboardId ) ;
7596 applyDashboardAction ( dashboardEntry , permit . action ) ;
@@ -95,7 +116,10 @@ function extractPermitStatements(policyText: string): ParsedPermitStatement[] {
95116
96117 let i = permitIndex + permitKeyword . length ;
97118 // Skip whitespace after "permit"
98- while ( i < policyText . length && ( policyText [ i ] === ' ' || policyText [ i ] === '\t' || policyText [ i ] === '\n' || policyText [ i ] === '\r' ) ) {
119+ while (
120+ i < policyText . length &&
121+ ( policyText [ i ] === ' ' || policyText [ i ] === '\t' || policyText [ i ] === '\n' || policyText [ i ] === '\r' )
122+ ) {
99123 i ++ ;
100124 }
101125
@@ -122,7 +146,10 @@ function extractPermitStatements(policyText: string): ParsedPermitStatement[] {
122146 const body = policyText . slice ( bodyStart , i ) ;
123147 // Skip past ')' and optional whitespace, expect ';'
124148 let j = i + 1 ;
125- while ( j < policyText . length && ( policyText [ j ] === ' ' || policyText [ j ] === '\t' || policyText [ j ] === '\n' || policyText [ j ] === '\r' ) ) {
149+ while (
150+ j < policyText . length &&
151+ ( policyText [ j ] === ' ' || policyText [ j ] === '\t' || policyText [ j ] === '\n' || policyText [ j ] === '\r' )
152+ ) {
126153 j ++ ;
127154 }
128155
@@ -134,28 +161,39 @@ function extractPermitStatements(policyText: string): ParsedPermitStatement[] {
134161 }
135162 }
136163
137- return results ;
164+ return results . flatMap ( expandActionIn ) ;
165+ }
166+
167+ function expandActionIn ( stmt : ParsedPermitStatement ) : ParsedPermitStatement [ ] {
168+ if ( ! stmt . actions || stmt . actions . length === 0 ) return [ stmt ] ;
169+ return stmt . actions . map ( ( action ) => ( { ...stmt , action, actions : null } ) ) ;
138170}
139171
140172function parsePermitBody ( body : string ) : ParsedPermitStatement {
141173 const result : ParsedPermitStatement = {
142174 action : null ,
175+ actions : null ,
143176 resourceType : null ,
144177 resourceId : null ,
145178 isWildcard : false ,
146179 } ;
147180
148- const actionMatch = body . match ( / a c t i o n \s * = = \s * R o c k e t A d m i n : : A c t i o n : : " ( [ ^ " ] + ) " / ) ;
181+ const actionMatch = body . match ( / a c t i o n \s * (?: = = | l i k e ) \s * R o c k e t A d m i n : : A c t i o n : : " ( [ ^ " ] + ) " / ) ;
149182 if ( actionMatch ) {
150183 result . action = actionMatch [ 1 ] ;
151184 } else {
152- const actionClause = body . match ( / , \s * ( a c t i o n ) \s * , / ) ;
153- if ( actionClause ) {
154- result . isWildcard = true ;
185+ const actionInMatch = body . match ( / a c t i o n \s + i n \s * \[ ( [ ^ \] ] + ) \] / ) ;
186+ if ( actionInMatch ) {
187+ result . actions = [ ...actionInMatch [ 1 ] . matchAll ( / R o c k e t A d m i n : : A c t i o n : : " ( [ ^ " ] + ) " / g) ] . map ( ( m ) => m [ 1 ] ) ;
188+ } else {
189+ const actionClause = body . match ( / , \s * ( a c t i o n ) \s * , / ) ;
190+ if ( actionClause ) {
191+ result . isWildcard = true ;
192+ }
155193 }
156194 }
157195
158- const resourceMatch = body . match ( / r e s o u r c e \s * = = \s * ( R o c k e t A d m i n : : \w + ) : : " ( [ ^ " ] + ) " / ) ;
196+ const resourceMatch = body . match ( / r e s o u r c e \s * (?: = = | l i k e ) \s * ( R o c k e t A d m i n : : \w + ) : : " ( [ ^ " ] + ) " / ) ;
159197 if ( resourceMatch ) {
160198 result . resourceType = resourceMatch [ 1 ] ;
161199 result . resourceId = resourceMatch [ 2 ] ;
0 commit comments