1515import { Helper , Model , FilteredAdapter } from 'casbin' ;
1616import { CasbinRule } from './casbinRule' ;
1717import {
18- Connection ,
19- ConnectionOptions ,
20- createConnection ,
21- getRepository ,
18+ DataSource ,
19+ DataSourceOptions ,
20+ FindOptionsWhere ,
21+ Repository ,
2222} from 'typeorm' ;
2323import { CasbinMongoRule } from './casbinMongoRule' ;
2424
2525type GenericCasbinRule = CasbinRule | CasbinMongoRule ;
2626type CasbinRuleConstructor = new ( ...args : any [ ] ) => GenericCasbinRule ;
2727
2828interface ExistentConnection {
29- connection : Connection ;
29+ connection : DataSource ;
30+ }
31+ export type TypeORMAdapterOptions = ExistentConnection | DataSourceOptions ;
32+
33+ export interface TypeORMAdapterConfig {
34+ customCasbinRuleEntity ?: CasbinRuleConstructor ;
3035}
31- export type TypeORMAdapterOptions = ExistentConnection | ConnectionOptions ;
3236
3337/**
3438 * TypeORMAdapter represents the TypeORM filtered adapter for policy storage.
3539 */
3640export default class TypeORMAdapter implements FilteredAdapter {
37- private option : ConnectionOptions ;
38- private typeorm : Connection ;
41+ private adapterConfig ?: TypeORMAdapterConfig ;
42+ private option : DataSourceOptions ;
43+ private typeorm : DataSource ;
3944 private filtered = false ;
4045
41- private constructor ( option : TypeORMAdapterOptions ) {
46+ private constructor (
47+ option : TypeORMAdapterOptions ,
48+ adapterConfig ?: TypeORMAdapterConfig ,
49+ ) {
50+ this . adapterConfig = adapterConfig ;
51+
4252 if ( ( option as ExistentConnection ) . connection ) {
4353 this . typeorm = ( option as ExistentConnection ) . connection ;
4454 this . option = this . typeorm . options ;
4555 } else {
46- this . option = option as ConnectionOptions ;
56+ this . option = option as DataSourceOptions ;
4757 }
4858 }
4959
@@ -54,47 +64,55 @@ export default class TypeORMAdapter implements FilteredAdapter {
5464 /**
5565 * newAdapter is the constructor.
5666 * @param option typeorm connection option
67+ * @param adapterConfig additional configuration options for the adapter
5768 */
58- public static async newAdapter ( option : TypeORMAdapterOptions ) {
69+ public static async newAdapter (
70+ option : TypeORMAdapterOptions ,
71+ adapterConfig ?: TypeORMAdapterConfig ,
72+ ) {
5973 let a : TypeORMAdapter ;
6074
6175 const defaults = {
6276 synchronize : true ,
6377 name : 'node-casbin-official' ,
6478 } ;
6579 if ( ( option as ExistentConnection ) . connection ) {
66- a = new TypeORMAdapter ( option ) ;
80+ a = new TypeORMAdapter ( option , adapterConfig ) ;
6781 } else {
68- const options = option as ConnectionOptions ;
69- const entities = { entities : [ this . getCasbinRuleType ( options . type ) ] } ;
82+ const options = option as DataSourceOptions ;
83+ const entities = {
84+ entities : [
85+ TypeORMAdapter . getCasbinRuleType ( options . type , adapterConfig ) ,
86+ ] ,
87+ } ;
7088 const configuration = Object . assign ( defaults , options ) ;
71- a = new TypeORMAdapter ( Object . assign ( configuration , entities ) ) ;
89+ a = new TypeORMAdapter (
90+ Object . assign ( configuration , entities ) ,
91+ adapterConfig ,
92+ ) ;
7293 }
7394 await a . open ( ) ;
7495 return a ;
7596 }
7697
7798 private async open ( ) {
7899 if ( ! this . typeorm ) {
79- this . typeorm = await createConnection ( this . option ) ;
100+ this . typeorm = new DataSource ( this . option ) ;
80101 }
81102
82- if ( ! this . typeorm . isConnected ) {
83- await this . typeorm . connect ( ) ;
103+ if ( ! this . typeorm . isInitialized ) {
104+ await this . typeorm . initialize ( ) ;
84105 }
85106 }
86107
87108 public async close ( ) {
88- if ( this . typeorm . isConnected ) {
89- await this . typeorm . close ( ) ;
109+ if ( this . typeorm . isInitialized ) {
110+ await this . typeorm . destroy ( ) ;
90111 }
91112 }
92113
93114 private async clearTable ( ) {
94- await getRepository (
95- this . getCasbinRuleConstructor ( ) ,
96- this . option . name ,
97- ) . clear ( ) ;
115+ await this . getRepository ( ) . clear ( ) ;
98116 }
99117
100118 private loadPolicyLine ( line : GenericCasbinRule , model : Model ) {
@@ -112,22 +130,19 @@ export default class TypeORMAdapter implements FilteredAdapter {
112130 * loadPolicy loads all policy rules from the storage.
113131 */
114132 public async loadPolicy ( model : Model ) {
115- const lines = await getRepository (
116- this . getCasbinRuleConstructor ( ) ,
117- this . option . name ,
118- ) . find ( ) ;
133+ const lines = await this . getRepository ( ) . find ( ) ;
119134
120135 for ( const line of lines ) {
121136 this . loadPolicyLine ( line , model ) ;
122137 }
123138 }
124139
125140 // Loading policies based on filter condition
126- public async loadFilteredPolicy ( model : Model , filter : object ) {
127- const filteredLines = await getRepository (
128- this . getCasbinRuleConstructor ( ) ,
129- this . option . name ,
130- ) . find ( filter ) ;
141+ public async loadFilteredPolicy (
142+ model : Model ,
143+ filter : FindOptionsWhere < GenericCasbinRule > ,
144+ ) {
145+ const filteredLines = await this . getRepository ( ) . find ( { where : filter } ) ;
131146 for ( const line of filteredLines ) {
132147 this . loadPolicyLine ( line , model ) ;
133148 }
@@ -211,9 +226,7 @@ export default class TypeORMAdapter implements FilteredAdapter {
211226 */
212227 public async addPolicy ( sec : string , ptype : string , rule : string [ ] ) {
213228 const line = this . savePolicyLine ( ptype , rule ) ;
214- await getRepository ( this . getCasbinRuleConstructor ( ) , this . option . name ) . save (
215- line ,
216- ) ;
229+ await this . getRepository ( ) . save ( line ) ;
217230 }
218231
219232 /**
@@ -247,10 +260,7 @@ export default class TypeORMAdapter implements FilteredAdapter {
247260 */
248261 public async removePolicy ( sec : string , ptype : string , rule : string [ ] ) {
249262 const line = this . savePolicyLine ( ptype , rule ) ;
250- await getRepository (
251- this . getCasbinRuleConstructor ( ) ,
252- this . option . name ,
253- ) . delete ( {
263+ await this . getRepository ( ) . delete ( {
254264 ...line ,
255265 } ) ;
256266 }
@@ -260,7 +270,10 @@ export default class TypeORMAdapter implements FilteredAdapter {
260270 */
261271 public async removePolicies ( sec : string , ptype : string , rules : string [ ] [ ] ) {
262272 const queryRunner = this . typeorm . createQueryRunner ( ) ;
263- const type = TypeORMAdapter . getCasbinRuleType ( this . option . type ) ;
273+ const type = TypeORMAdapter . getCasbinRuleType (
274+ this . option . type ,
275+ this . adapterConfig ,
276+ ) ;
264277
265278 await queryRunner . connect ( ) ;
266279 await queryRunner . startTransaction ( ) ;
@@ -313,27 +326,39 @@ export default class TypeORMAdapter implements FilteredAdapter {
313326 if ( fieldIndex <= 6 && 6 < fieldIndex + fieldValues . length ) {
314327 line . v6 = fieldValues [ 6 - fieldIndex ] ;
315328 }
316- await getRepository (
317- this . getCasbinRuleConstructor ( ) ,
318- this . option . name ,
319- ) . delete ( {
329+
330+ await this . getRepository ( ) . delete ( {
320331 ...line ,
321332 } ) ;
322333 }
323334
324335 private getCasbinRuleConstructor ( ) : CasbinRuleConstructor {
325- return TypeORMAdapter . getCasbinRuleType ( this . option . type ) ;
336+ return TypeORMAdapter . getCasbinRuleType (
337+ this . option . type ,
338+ this . adapterConfig ,
339+ ) ;
326340 }
327341
328342 /**
329- * Returns either a {@link CasbinRule} or a {@link CasbinMongoRule}, depending on the type. This switch is required as the normal
330- * {@link CasbinRule} does not work when using MongoDB as a backend (due to a missing ObjectID field).
343+ * Returns either a {@link CasbinRule} or a {@link CasbinMongoRule}, depending on the type. If passed a custom entity through the adapter config it will use that entity type.
344+ * This switch is required as the normal {@link CasbinRule} does not work when using MongoDB as a backend (due to a missing ObjectID field).
331345 * @param type
332346 */
333- private static getCasbinRuleType ( type : string ) : CasbinRuleConstructor {
347+ private static getCasbinRuleType (
348+ type : string ,
349+ adapterConfig ?: TypeORMAdapterConfig ,
350+ ) : CasbinRuleConstructor {
351+ if ( adapterConfig ?. customCasbinRuleEntity ) {
352+ return adapterConfig . customCasbinRuleEntity ;
353+ }
354+
334355 if ( type === 'mongodb' ) {
335356 return CasbinMongoRule ;
336357 }
337358 return CasbinRule ;
338359 }
360+
361+ private getRepository ( ) : Repository < GenericCasbinRule > {
362+ return this . typeorm . getRepository ( this . getCasbinRuleConstructor ( ) ) ;
363+ }
339364}
0 commit comments