@@ -7,12 +7,25 @@ export interface IPublicTablePermission {
77 readableColumns ?: Array < string > ;
88}
99
10+ function escapeCedarString ( value : string ) : string {
11+ return value
12+ . replace ( / \\ / g, '\\\\' )
13+ . replace ( / " / g, '\\"' )
14+ . replace ( / \n / g, '\\n' )
15+ . replace ( / \r / g, '\\r' )
16+ . replace ( / \t / g, '\\t' ) ;
17+ }
18+
19+ function cedarEntityRef ( entityType : string , id : string ) : string {
20+ return `${ entityType } ::"${ escapeCedarString ( id ) } "` ;
21+ }
22+
1023export function generatePublicCedarPolicy ( connectionId : string , tables : Array < IPublicTablePermission > ) : string {
1124 const policies : Array < string > = [ ] ;
1225
1326 for ( const table of tables ) {
1427 if ( ! table . tableName ) continue ;
15- const tableRef = ` RocketAdmin::Table::" ${ connectionId } /${ table . tableName } "` ;
28+ const tableRef = cedarEntityRef ( ' RocketAdmin::Table' , ` ${ connectionId } /${ table . tableName } ` ) ;
1629
1730 policies . push (
1831 `permit(\n principal,\n action == RocketAdmin::Action::"table:query",\n resource == ${ tableRef } \n);` ,
@@ -21,7 +34,7 @@ export function generatePublicCedarPolicy(connectionId: string, tables: Array<IP
2134 const readableColumns = table . readableColumns ;
2235 if ( readableColumns && readableColumns . length > 0 ) {
2336 for ( const columnName of readableColumns ) {
24- const columnRef = ` RocketAdmin::Column::" ${ connectionId } /${ table . tableName } /${ columnName } "` ;
37+ const columnRef = cedarEntityRef ( ' RocketAdmin::Column' , ` ${ connectionId } /${ table . tableName } /${ columnName } ` ) ;
2538 policies . push (
2639 `permit(\n principal,\n action == RocketAdmin::Action::"column:read",\n resource == ${ columnRef } \n);` ,
2740 ) ;
@@ -42,7 +55,7 @@ export function generateCedarPolicyForGroup(
4255 permissions : IComplexPermission ,
4356) : string {
4457 const policies : Array < string > = [ ] ;
45- const connectionRef = ` RocketAdmin::Connection::" ${ connectionId } "` ;
58+ const connectionRef = cedarEntityRef ( ' RocketAdmin::Connection' , connectionId ) ;
4659
4760 if ( isMain ) {
4861 policies . push ( `permit(\n principal,\n action,\n resource\n);` ) ;
@@ -69,7 +82,7 @@ export function generateCedarPolicyForGroup(
6982
7083 // Group permissions
7184 const groupAccess = permissions . group . accessLevel ;
72- const groupResourceRef = ` RocketAdmin::Group::" ${ permissions . group . groupId } "` ;
85+ const groupResourceRef = cedarEntityRef ( ' RocketAdmin::Group' , permissions . group . groupId ) ;
7386 if ( groupAccess === AccessLevelEnum . edit ) {
7487 policies . push (
7588 `permit(\n principal,\n action == RocketAdmin::Action::"group:read",\n resource == ${ groupResourceRef } \n);` ,
@@ -87,7 +100,7 @@ export function generateCedarPolicyForGroup(
87100 let hasCreatePermission = false ;
88101 let hasReadPermission = false ;
89102 for ( const dashboard of permissions . dashboards ) {
90- const dashboardRef = ` RocketAdmin::Dashboard::" ${ connectionId } /${ dashboard . dashboardId } "` ;
103+ const dashboardRef = cedarEntityRef ( ' RocketAdmin::Dashboard' , ` ${ connectionId } /${ dashboard . dashboardId } ` ) ;
91104 const access = dashboard . accessLevel ;
92105
93106 if ( access . read ) {
@@ -110,7 +123,7 @@ export function generateCedarPolicyForGroup(
110123 ) ;
111124 }
112125 }
113- const newDashboardRef = ` RocketAdmin::Dashboard::" ${ connectionId } /__new__"` ;
126+ const newDashboardRef = cedarEntityRef ( ' RocketAdmin::Dashboard' , ` ${ connectionId } /__new__` ) ;
114127 if ( hasReadPermission ) {
115128 policies . push (
116129 `permit(\n principal,\n action == RocketAdmin::Action::"dashboard:read",\n resource == ${ newDashboardRef } \n);` ,
@@ -127,7 +140,7 @@ export function generateCedarPolicyForGroup(
127140 let hasPanelCreatePermission = false ;
128141 let hasPanelReadPermission = false ;
129142 for ( const panel of permissions . panels ) {
130- const panelRef = ` RocketAdmin::Panel::" ${ connectionId } /${ panel . panelId } "` ;
143+ const panelRef = cedarEntityRef ( ' RocketAdmin::Panel' , ` ${ connectionId } /${ panel . panelId } ` ) ;
131144 const access = panel . accessLevel ;
132145
133146 if ( access . read ) {
@@ -150,7 +163,7 @@ export function generateCedarPolicyForGroup(
150163 ) ;
151164 }
152165 }
153- const newPanelRef = ` RocketAdmin::Panel::" ${ connectionId } /__new__"` ;
166+ const newPanelRef = cedarEntityRef ( ' RocketAdmin::Panel' , ` ${ connectionId } /__new__` ) ;
154167 if ( hasPanelReadPermission ) {
155168 policies . push (
156169 `permit(\n principal,\n action == RocketAdmin::Action::"panel:read",\n resource == ${ newPanelRef } \n);` ,
@@ -164,7 +177,7 @@ export function generateCedarPolicyForGroup(
164177 }
165178
166179 for ( const table of permissions . tables ) {
167- const tableRef = ` RocketAdmin::Table::" ${ connectionId } /${ table . tableName } "` ;
180+ const tableRef = cedarEntityRef ( ' RocketAdmin::Table' , ` ${ connectionId } /${ table . tableName } ` ) ;
168181 const access = table . accessLevel ;
169182
170183 // triggerCustomAction is intentionally excluded from hasAnyAccess: triggering custom
@@ -181,7 +194,7 @@ export function generateCedarPolicyForGroup(
181194 const readableColumns = table . readableColumns ;
182195 if ( readableColumns && readableColumns . length > 0 ) {
183196 for ( const columnName of readableColumns ) {
184- const columnRef = ` RocketAdmin::Column::" ${ connectionId } /${ table . tableName } /${ columnName } "` ;
197+ const columnRef = cedarEntityRef ( ' RocketAdmin::Column' , ` ${ connectionId } /${ table . tableName } /${ columnName } ` ) ;
185198 policies . push (
186199 `permit(\n principal,\n action == RocketAdmin::Action::"column:read",\n resource == ${ columnRef } \n);` ,
187200 ) ;
@@ -223,7 +236,10 @@ export function generateCedarPolicyForGroup(
223236 if ( permissions . actionEvents ) {
224237 for ( const event of permissions . actionEvents ) {
225238 if ( ! event . accessLevel ?. trigger ) continue ;
226- const eventRef = `RocketAdmin::ActionEvent::"${ connectionId } /${ event . tableName } /${ event . eventId } "` ;
239+ const eventRef = cedarEntityRef (
240+ 'RocketAdmin::ActionEvent' ,
241+ `${ connectionId } /${ event . tableName } /${ event . eventId } ` ,
242+ ) ;
227243 policies . push (
228244 `permit(\n principal,\n action == RocketAdmin::Action::"actionEvent:trigger",\n resource == ${ eventRef } \n);` ,
229245 ) ;
0 commit comments