@api-client/core 0.19.31 → 0.19.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/modeling/ApiModel.d.ts.map +1 -1
- package/build/src/modeling/ApiModel.js +0 -8
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/RuntimeApiModel.d.ts +16 -0
- package/build/src/modeling/RuntimeApiModel.d.ts.map +1 -1
- package/build/src/modeling/RuntimeApiModel.js +31 -0
- package/build/src/modeling/RuntimeApiModel.js.map +1 -1
- package/build/src/modeling/types.d.ts +0 -15
- package/build/src/modeling/types.d.ts.map +1 -1
- package/build/src/modeling/types.js.map +1 -1
- package/build/src/modeling/validation/api_model_rules.d.ts.map +1 -1
- package/build/src/modeling/validation/api_model_rules.js +49 -46
- package/build/src/modeling/validation/api_model_rules.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/modeling/ApiModel.ts +0 -10
- package/src/modeling/RuntimeApiModel.ts +46 -0
- package/src/modeling/readme.md +2 -2
- package/src/modeling/types.ts +0 -15
- package/src/modeling/validation/api_model_rules.ts +50 -48
- package/src/modeling/validation/api_model_validation_rules.md +2 -2
- package/tests/unit/modeling/RuntimeApiModel.spec.ts +31 -0
- package/tests/unit/modeling/api_model.spec.ts +6 -6
- package/tests/unit/modeling/generators/OasGenerator.spec.ts +1 -3
- package/tests/unit/modeling/validation/api_model_rules.spec.ts +12 -12
package/package.json
CHANGED
package/src/modeling/ApiModel.ts
CHANGED
|
@@ -6,9 +6,7 @@ import type {
|
|
|
6
6
|
AuthenticationStrategy,
|
|
7
7
|
AuthorizationStrategy,
|
|
8
8
|
ExposedEntitySchema,
|
|
9
|
-
RolesBasedAccessControl,
|
|
10
9
|
SessionConfiguration,
|
|
11
|
-
UsernamePasswordConfiguration,
|
|
12
10
|
ExposeOptions,
|
|
13
11
|
OffsetPaginationStrategy,
|
|
14
12
|
CursorPaginationStrategy,
|
|
@@ -668,14 +666,6 @@ export class ApiModel extends DependentModel {
|
|
|
668
666
|
if (this.session) {
|
|
669
667
|
this.session.properties = []
|
|
670
668
|
}
|
|
671
|
-
if (this.authentication && this.authentication.strategy === 'UsernamePassword') {
|
|
672
|
-
const typed = this.authentication as UsernamePasswordConfiguration
|
|
673
|
-
typed.passwordKey = undefined
|
|
674
|
-
}
|
|
675
|
-
if (this.authorization && this.authorization.strategy == 'RBAC') {
|
|
676
|
-
const typed = this.authorization as RolesBasedAccessControl
|
|
677
|
-
typed.roleKey = ''
|
|
678
|
-
}
|
|
679
669
|
}
|
|
680
670
|
|
|
681
671
|
/**
|
|
@@ -4,6 +4,9 @@ import type { DataDomainSchema } from './DataDomain.js'
|
|
|
4
4
|
import type { ActionKind } from './actions/index.js'
|
|
5
5
|
import type { ExposedEntity } from './ExposedEntity.js'
|
|
6
6
|
import type { Action } from './actions/Action.js'
|
|
7
|
+
import { SemanticType } from './Semantics.js'
|
|
8
|
+
import type { DomainEntity } from './DomainEntity.js'
|
|
9
|
+
import type { DomainProperty } from './DomainProperty.js'
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* Identifies a specific exposed entity and its action kind.
|
|
@@ -55,12 +58,55 @@ export class RuntimeApiModel extends ApiModel {
|
|
|
55
58
|
*/
|
|
56
59
|
#definitions = new WeakMap<RouteToken[], RouteDefinition>()
|
|
57
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Cached references to commonly used entities for fast runtime lookup.
|
|
63
|
+
*/
|
|
64
|
+
cachedEntities: {
|
|
65
|
+
user?: DomainEntity
|
|
66
|
+
} = {}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Cached references to commonly used properties for fast runtime lookup.
|
|
70
|
+
*/
|
|
71
|
+
cachedProperties: {
|
|
72
|
+
username?: DomainProperty
|
|
73
|
+
password?: DomainProperty
|
|
74
|
+
role?: DomainProperty
|
|
75
|
+
} = {}
|
|
76
|
+
|
|
58
77
|
constructor(schema: RuntimeApiModelSchema, domainSchema: DataDomainSchema) {
|
|
59
78
|
super(schema, domainSchema)
|
|
60
79
|
|
|
61
80
|
if (schema.routingMap) {
|
|
62
81
|
this.#initializeRouter(schema.routingMap)
|
|
63
82
|
}
|
|
83
|
+
|
|
84
|
+
this.#cacheEntitiesAndProperties()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
#cacheEntitiesAndProperties() {
|
|
88
|
+
if (!this.user || !this.domain) {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const userEntity = this.domain.findEntity(this.user.key, this.user.domain)
|
|
93
|
+
if (!userEntity) {
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.cachedEntities.user = userEntity
|
|
98
|
+
|
|
99
|
+
for (const prop of userEntity.properties) {
|
|
100
|
+
if (prop.hasSemantic(SemanticType.Username)) {
|
|
101
|
+
this.cachedProperties.username = prop
|
|
102
|
+
}
|
|
103
|
+
if (prop.hasSemantic(SemanticType.Password)) {
|
|
104
|
+
this.cachedProperties.password = prop
|
|
105
|
+
}
|
|
106
|
+
if (prop.hasSemantic(SemanticType.UserRole)) {
|
|
107
|
+
this.cachedProperties.role = prop
|
|
108
|
+
}
|
|
109
|
+
}
|
|
64
110
|
}
|
|
65
111
|
|
|
66
112
|
#initializeRouter(routingMap: RoutingMap) {
|
package/src/modeling/readme.md
CHANGED
|
@@ -187,8 +187,8 @@ apiModel.attachDataDomain(domain)
|
|
|
187
187
|
|
|
188
188
|
// 4. Configure security
|
|
189
189
|
apiModel.user = { key: userEntity.key }
|
|
190
|
-
apiModel.authentication = { strategy: 'UsernamePassword'
|
|
191
|
-
apiModel.authorization = { strategy: 'RBAC'
|
|
190
|
+
apiModel.authentication = { strategy: 'UsernamePassword' }
|
|
191
|
+
apiModel.authorization = { strategy: 'RBAC' }
|
|
192
192
|
apiModel.session = {
|
|
193
193
|
secret: 'your-secure-secret',
|
|
194
194
|
properties: ['email', 'role'],
|
package/src/modeling/types.ts
CHANGED
|
@@ -393,14 +393,6 @@ export interface AuthorizationConfiguration {
|
|
|
393
393
|
|
|
394
394
|
export interface RolesBasedAccessControl extends AuthorizationConfiguration {
|
|
395
395
|
strategy: 'RBAC'
|
|
396
|
-
/**
|
|
397
|
-
* The property within the designated "User" entity that defines the user's role.
|
|
398
|
-
* This field is used in access rules to grant permissions.
|
|
399
|
-
*
|
|
400
|
-
* This property must be marked with the "Role" data semantic in the Data Modeler.
|
|
401
|
-
* It is required to publish the API.
|
|
402
|
-
*/
|
|
403
|
-
roleKey: string
|
|
404
396
|
}
|
|
405
397
|
|
|
406
398
|
export type AuthorizationStrategy = RolesBasedAccessControl
|
|
@@ -424,13 +416,6 @@ export interface AuthenticationConfiguration {
|
|
|
424
416
|
*/
|
|
425
417
|
export interface UsernamePasswordConfiguration extends AuthenticationConfiguration {
|
|
426
418
|
strategy: 'UsernamePassword'
|
|
427
|
-
/**
|
|
428
|
-
* The specific property within the User entity that holds the password.
|
|
429
|
-
* This property must be marked with the "Password" data semantic in the Data Modeler.
|
|
430
|
-
*
|
|
431
|
-
* This property is required to publish the API.
|
|
432
|
-
*/
|
|
433
|
-
passwordKey?: string
|
|
434
419
|
}
|
|
435
420
|
|
|
436
421
|
export type AuthenticationStrategy = UsernamePasswordConfiguration
|
|
@@ -5,10 +5,10 @@ import { ListAction } from '../actions/ListAction.js'
|
|
|
5
5
|
import { DeleteAction } from '../actions/DeleteAction.js'
|
|
6
6
|
import { UpdateAction } from '../actions/UpdateAction.js'
|
|
7
7
|
import { SearchAction } from '../actions/SearchAction.js'
|
|
8
|
-
import type { RolesBasedAccessControl, UsernamePasswordConfiguration } from '../types.js'
|
|
9
8
|
import type { ApiModelValidationItem, ApiModelValidationContext } from '../types.js'
|
|
10
9
|
import { ApiModelKind, ExposedEntityKind } from '../../models/kinds.js'
|
|
11
10
|
import { SemanticType } from '../Semantics.js'
|
|
11
|
+
import { DomainProperty } from '../DomainProperty.js'
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Creates a unique validation code.
|
|
@@ -127,35 +127,32 @@ export function validateApiModelSecurity(model: ApiModel): ApiModelValidationIte
|
|
|
127
127
|
context: { ...context, property: 'authentication' },
|
|
128
128
|
})
|
|
129
129
|
} else if (model.authentication.strategy === 'UsernamePassword') {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
context: { ...context, property: 'authentication.passwordKey' },
|
|
140
|
-
})
|
|
141
|
-
} else if (userEntity) {
|
|
142
|
-
const passwordProp = Array.from(userEntity.properties).find((p) => p.key === auth.passwordKey)
|
|
143
|
-
if (passwordProp && !passwordProp.hasSemantic(SemanticType.Password)) {
|
|
130
|
+
if (userEntity) {
|
|
131
|
+
let passwordProp: DomainProperty | undefined
|
|
132
|
+
for (const prop of userEntity.properties) {
|
|
133
|
+
if (prop.hasSemantic(SemanticType.Password)) {
|
|
134
|
+
passwordProp = prop
|
|
135
|
+
break
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!passwordProp) {
|
|
144
139
|
issues.push({
|
|
145
140
|
code: createCode('API', 'MISSING_PASSWORD_SEMANTIC'),
|
|
146
|
-
message: 'The selected
|
|
147
|
-
suggestion: 'Go to the Data Modeler and add the "Password" semantic to
|
|
141
|
+
message: 'The selected user model requires a property with the Password data semantic for authentication.',
|
|
142
|
+
suggestion: 'Go to the Data Modeler and add the "Password" semantic to the password property.',
|
|
148
143
|
severity: 'error',
|
|
149
|
-
context: { ...context, property: '
|
|
144
|
+
context: { ...context, property: 'user' },
|
|
150
145
|
})
|
|
151
146
|
}
|
|
152
|
-
}
|
|
153
147
|
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
148
|
+
let usernameProp: DomainProperty | undefined
|
|
149
|
+
for (const prop of userEntity.properties) {
|
|
150
|
+
if (prop.hasSemantic(SemanticType.Username)) {
|
|
151
|
+
usernameProp = prop
|
|
152
|
+
break
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (!usernameProp) {
|
|
159
156
|
issues.push({
|
|
160
157
|
code: createCode('API', 'MISSING_USERNAME_SEMANTIC'),
|
|
161
158
|
message: 'Username & Password authentication requires a field with the Username data semantic.',
|
|
@@ -177,24 +174,21 @@ export function validateApiModelSecurity(model: ApiModel): ApiModelValidationIte
|
|
|
177
174
|
context: { ...context, property: 'authorization' },
|
|
178
175
|
})
|
|
179
176
|
} else if (model.authorization.strategy === 'RBAC') {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
} else if (userEntity) {
|
|
190
|
-
const roleProp = Array.from(userEntity.properties).find((p) => p.key === rbac.roleKey)
|
|
191
|
-
if (roleProp && !roleProp.hasSemantic(SemanticType.UserRole)) {
|
|
177
|
+
if (userEntity) {
|
|
178
|
+
let roleProp: DomainProperty | undefined
|
|
179
|
+
for (const prop of userEntity.properties) {
|
|
180
|
+
if (prop.hasSemantic(SemanticType.UserRole)) {
|
|
181
|
+
roleProp = prop
|
|
182
|
+
break
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!roleProp) {
|
|
192
186
|
issues.push({
|
|
193
187
|
code: createCode('API', 'MISSING_ROLE_SEMANTIC'),
|
|
194
|
-
message: '
|
|
195
|
-
suggestion: 'Go to the Data Modeler and add the "User Role" semantic to
|
|
188
|
+
message: 'Role-based access control requires a property with the User Role data semantic on the user model.',
|
|
189
|
+
suggestion: 'Go to the Data Modeler and add the "User Role" semantic to the property used for roles.',
|
|
196
190
|
severity: 'error',
|
|
197
|
-
context: { ...context, property: '
|
|
191
|
+
context: { ...context, property: 'user' },
|
|
198
192
|
})
|
|
199
193
|
}
|
|
200
194
|
}
|
|
@@ -229,15 +223,23 @@ export function validateApiModelSecurity(model: ApiModel): ApiModelValidationIte
|
|
|
229
223
|
context: { ...context, property: 'session.properties' },
|
|
230
224
|
})
|
|
231
225
|
} else if (model.authorization && model.authorization.strategy === 'RBAC') {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
226
|
+
if (userEntity) {
|
|
227
|
+
let roleProp: DomainProperty | undefined
|
|
228
|
+
for (const prop of userEntity.properties) {
|
|
229
|
+
if (prop.hasSemantic(SemanticType.UserRole)) {
|
|
230
|
+
roleProp = prop
|
|
231
|
+
break
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (roleProp && !model.session.properties.includes(roleProp.key)) {
|
|
235
|
+
issues.push({
|
|
236
|
+
code: createCode('API', 'MISSING_RBAC_SESSION_PROPERTY'),
|
|
237
|
+
message: 'The user role must be included in the session data for permissions to work.',
|
|
238
|
+
suggestion: 'Make sure your selected role property is checked in the session settings.',
|
|
239
|
+
severity: 'error',
|
|
240
|
+
context: { ...context, property: 'session.properties' },
|
|
241
|
+
})
|
|
242
|
+
}
|
|
241
243
|
}
|
|
242
244
|
}
|
|
243
245
|
|
|
@@ -23,9 +23,9 @@ Validations are evaluated with one of three severity levels:
|
|
|
23
23
|
## 3. Security & Access Control
|
|
24
24
|
|
|
25
25
|
- **Authentication** [Error]: The `authentication` configuration is required.
|
|
26
|
-
- If the strategy is `UsernamePassword`, the
|
|
26
|
+
- If the strategy is `UsernamePassword`, the user entity must contain a property with the `Username` semantic.
|
|
27
27
|
- **Authorization** [Error]: The `authorization` configuration is required.
|
|
28
|
-
- If the strategy is `RBAC`, the
|
|
28
|
+
- If the strategy is `RBAC`, the user entity must contain a property with the `UserRole` semantic.
|
|
29
29
|
- **Session Configuration** [Error]: The `session` configuration is required and must meet the following criteria:
|
|
30
30
|
- **Secret**: A session encryption token (`secret`) is required.
|
|
31
31
|
- **Properties**: The `session.properties` array must have at least one property set (e.g. to identify the User ID).
|
|
@@ -2,6 +2,7 @@ import { test } from '@japa/runner'
|
|
|
2
2
|
import { ApiModel } from '../../../src/modeling/ApiModel.js'
|
|
3
3
|
import { RuntimeApiModel, type RuntimeApiModelSchema } from '../../../src/modeling/RuntimeApiModel.js'
|
|
4
4
|
import { DataDomain } from '../../../src/modeling/DataDomain.js'
|
|
5
|
+
import { SemanticType } from '../../../src/modeling/Semantics.js'
|
|
5
6
|
|
|
6
7
|
test.group('RuntimeApiModel', () => {
|
|
7
8
|
test('initializes from schema', ({ assert }) => {
|
|
@@ -119,4 +120,34 @@ test.group('RuntimeApiModel', () => {
|
|
|
119
120
|
const missingActionResult = runtimeModel.lookupAction('GET', '/missing-action')
|
|
120
121
|
assert.isUndefined(missingActionResult)
|
|
121
122
|
}).tags(['@modeling', '@runtime'])
|
|
123
|
+
|
|
124
|
+
test('caches user entity and properties based on semantics', ({ assert }) => {
|
|
125
|
+
const domain = new DataDomain({ info: { version: '1.0.0' } })
|
|
126
|
+
const modelNode = domain.addModel({ key: 'users' })
|
|
127
|
+
const userEntity = modelNode.addEntity({ info: { name: 'User' }, semantics: [{ id: SemanticType.User }] })
|
|
128
|
+
|
|
129
|
+
const passwordProp = userEntity.addProperty({
|
|
130
|
+
info: { name: 'Password' },
|
|
131
|
+
semantics: [{ id: SemanticType.Password }],
|
|
132
|
+
})
|
|
133
|
+
const roleProp = userEntity.addProperty({ info: { name: 'Role' }, semantics: [{ id: SemanticType.UserRole }] })
|
|
134
|
+
const usernameProp = userEntity.addProperty({
|
|
135
|
+
info: { name: 'Username' },
|
|
136
|
+
semantics: [{ id: SemanticType.Username }],
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
const schema = {
|
|
140
|
+
key: 'api-1',
|
|
141
|
+
info: { name: 'Test API' },
|
|
142
|
+
user: { key: userEntity.key, domain: domain.key },
|
|
143
|
+
routingMap: {},
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const runtimeModel = new RuntimeApiModel(schema as any, domain.toJSON())
|
|
147
|
+
|
|
148
|
+
assert.equal(runtimeModel.cachedEntities.user?.key, userEntity.key)
|
|
149
|
+
assert.equal(runtimeModel.cachedProperties.password?.key, passwordProp.key)
|
|
150
|
+
assert.equal(runtimeModel.cachedProperties.role?.key, roleProp.key)
|
|
151
|
+
assert.equal(runtimeModel.cachedProperties.username?.key, usernameProp.key)
|
|
152
|
+
}).tags(['@modeling', '@runtime'])
|
|
122
153
|
})
|
|
@@ -53,7 +53,7 @@ test.group('ApiModel.createSchema()', () => {
|
|
|
53
53
|
user: { key: 'user-entity' },
|
|
54
54
|
dependencyList: [{ key: 'domain1', version: '1.0.0' }],
|
|
55
55
|
authentication: { strategy: 'UsernamePassword' },
|
|
56
|
-
authorization: { strategy: 'RBAC'
|
|
56
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
57
57
|
session: { secret: 'secret', properties: ['email'] },
|
|
58
58
|
accessRule: [{ type: 'public' }],
|
|
59
59
|
rateLimiting: { rules: [] },
|
|
@@ -72,7 +72,7 @@ test.group('ApiModel.createSchema()', () => {
|
|
|
72
72
|
assert.deepEqual(schema.user, { key: 'user-entity' })
|
|
73
73
|
assert.deepEqual(schema.dependencyList, [{ key: 'domain1', version: '1.0.0' }])
|
|
74
74
|
assert.deepEqual(schema.authentication, { strategy: 'UsernamePassword' })
|
|
75
|
-
assert.deepEqual(schema.authorization, { strategy: 'RBAC'
|
|
75
|
+
assert.deepEqual(schema.authorization, { strategy: 'RBAC' })
|
|
76
76
|
assert.deepEqual(schema.session, { secret: 'secret', properties: ['email'] })
|
|
77
77
|
assert.deepEqual(schema.accessRule, [{ type: 'public' }])
|
|
78
78
|
assert.deepEqual(schema.rateLimiting, { rules: [] })
|
|
@@ -132,7 +132,7 @@ test.group('ApiModel.constructor()', () => {
|
|
|
132
132
|
user: { key: 'user-entity' },
|
|
133
133
|
dependencyList: [{ key: 'domain1', version: '1.0.0' }],
|
|
134
134
|
authentication: { strategy: 'UsernamePassword' },
|
|
135
|
-
authorization: { strategy: 'RBAC'
|
|
135
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
136
136
|
session: { secret: 'secret', properties: ['email'] },
|
|
137
137
|
accessRule: [{ type: 'allowPublic' }],
|
|
138
138
|
rateLimiting: { rules: [] },
|
|
@@ -150,7 +150,7 @@ test.group('ApiModel.constructor()', () => {
|
|
|
150
150
|
assert.deepEqual(model.user, { key: 'user-entity' })
|
|
151
151
|
assert.deepEqual(model.dependencyList, [{ key: 'domain1', version: '1.0.0' }])
|
|
152
152
|
assert.deepEqual(model.authentication, { strategy: 'UsernamePassword' })
|
|
153
|
-
assert.deepEqual(model.authorization, { strategy: 'RBAC'
|
|
153
|
+
assert.deepEqual(model.authorization, { strategy: 'RBAC' })
|
|
154
154
|
assert.deepEqual(model.session, { secret: 'secret', properties: ['email'] })
|
|
155
155
|
assert.deepEqual(model.accessRule, [new AllowPublicAccessRule(model)])
|
|
156
156
|
assert.deepEqual(model.rateLimiting, new RateLimitingConfiguration())
|
|
@@ -289,7 +289,7 @@ test.group('ApiModel.toJSON()', () => {
|
|
|
289
289
|
user: { key: 'user-entity' },
|
|
290
290
|
dependencyList: [{ key: 'domain1', version: '1.0.0' }],
|
|
291
291
|
authentication: { strategy: 'UsernamePassword' },
|
|
292
|
-
authorization: { strategy: 'RBAC'
|
|
292
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
293
293
|
session: { secret: 'secret', properties: ['email'] },
|
|
294
294
|
accessRule: [{ type: 'allowPublic' }],
|
|
295
295
|
rateLimiting: { rules: [] },
|
|
@@ -308,7 +308,7 @@ test.group('ApiModel.toJSON()', () => {
|
|
|
308
308
|
assert.deepEqual(json.user, { key: 'user-entity' })
|
|
309
309
|
assert.deepEqual(json.dependencyList, [{ key: 'domain1', version: '1.0.0' }])
|
|
310
310
|
assert.deepEqual(json.authentication, { strategy: 'UsernamePassword' })
|
|
311
|
-
assert.deepEqual(json.authorization, { strategy: 'RBAC'
|
|
311
|
+
assert.deepEqual(json.authorization, { strategy: 'RBAC' })
|
|
312
312
|
assert.deepEqual(json.session, { secret: 'secret', properties: ['email'] })
|
|
313
313
|
assert.deepEqual(json.accessRule, [{ type: 'allowPublic' }])
|
|
314
314
|
assert.deepEqual(json.rateLimiting, { rules: [] })
|
|
@@ -32,7 +32,7 @@ test.group('OasGenerator', (group) => {
|
|
|
32
32
|
info: { name: 'email' },
|
|
33
33
|
semantics: [{ id: SemanticType.Email }, { id: SemanticType.Username }],
|
|
34
34
|
})
|
|
35
|
-
|
|
35
|
+
user.addProperty({
|
|
36
36
|
type: 'string',
|
|
37
37
|
required: true,
|
|
38
38
|
info: { name: 'password' },
|
|
@@ -148,11 +148,9 @@ test.group('OasGenerator', (group) => {
|
|
|
148
148
|
}
|
|
149
149
|
api.authentication = {
|
|
150
150
|
strategy: 'UsernamePassword',
|
|
151
|
-
passwordKey: passwd.key,
|
|
152
151
|
}
|
|
153
152
|
api.authorization = {
|
|
154
153
|
strategy: 'RBAC',
|
|
155
|
-
roleKey: role.key,
|
|
156
154
|
}
|
|
157
155
|
api.pagination = { kind: 'cursor', defaultLimit: 50, maxLimit: 70 }
|
|
158
156
|
const userExposure = api.exposeEntity({ key: user.key })
|
|
@@ -63,8 +63,8 @@ test.group('ApiModel Validation', () => {
|
|
|
63
63
|
|
|
64
64
|
const model = new ApiModel(
|
|
65
65
|
{
|
|
66
|
-
authentication: { strategy: 'UsernamePassword'
|
|
67
|
-
authorization: { strategy: 'RBAC'
|
|
66
|
+
authentication: { strategy: 'UsernamePassword' } as UsernamePasswordConfiguration,
|
|
67
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
68
68
|
session: {
|
|
69
69
|
secret: 'super-secret',
|
|
70
70
|
properties: ['id', 'role'],
|
|
@@ -91,8 +91,8 @@ test.group('ApiModel Validation', () => {
|
|
|
91
91
|
const domain = new DataDomain({ info: { version: '1.0.0' } })
|
|
92
92
|
const model = new ApiModel(
|
|
93
93
|
{
|
|
94
|
-
authentication: { strategy: 'UsernamePassword'
|
|
95
|
-
authorization: { strategy: 'RBAC'
|
|
94
|
+
authentication: { strategy: 'UsernamePassword' } as UsernamePasswordConfiguration,
|
|
95
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
96
96
|
session: {
|
|
97
97
|
secret: 'super-secret',
|
|
98
98
|
properties: [],
|
|
@@ -126,8 +126,8 @@ test.group('ApiModel Validation', () => {
|
|
|
126
126
|
|
|
127
127
|
const model = new ApiModel(
|
|
128
128
|
{
|
|
129
|
-
authentication: { strategy: 'UsernamePassword'
|
|
130
|
-
authorization: { strategy: 'RBAC'
|
|
129
|
+
authentication: { strategy: 'UsernamePassword' } as UsernamePasswordConfiguration,
|
|
130
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
131
131
|
session: { secret: 'secret', properties: [] },
|
|
132
132
|
user: { key: userEntity.key, domain: domain.key },
|
|
133
133
|
},
|
|
@@ -148,8 +148,8 @@ test.group('ApiModel Validation', () => {
|
|
|
148
148
|
|
|
149
149
|
const model = new ApiModel(
|
|
150
150
|
{
|
|
151
|
-
authentication: { strategy: 'UsernamePassword'
|
|
152
|
-
authorization: { strategy: 'RBAC'
|
|
151
|
+
authentication: { strategy: 'UsernamePassword' } as UsernamePasswordConfiguration,
|
|
152
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
153
153
|
session: { secret: 'secret', properties: [] },
|
|
154
154
|
user: { key: userEntity.key, domain: domain.key },
|
|
155
155
|
},
|
|
@@ -170,8 +170,8 @@ test.group('ApiModel Validation', () => {
|
|
|
170
170
|
|
|
171
171
|
const model = new ApiModel(
|
|
172
172
|
{
|
|
173
|
-
authentication: { strategy: 'UsernamePassword'
|
|
174
|
-
authorization: { strategy: 'RBAC'
|
|
173
|
+
authentication: { strategy: 'UsernamePassword' } as UsernamePasswordConfiguration,
|
|
174
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
175
175
|
session: { secret: 'secret', properties: [] },
|
|
176
176
|
user: { key: userEntity.key, domain: domain.key },
|
|
177
177
|
},
|
|
@@ -397,8 +397,8 @@ test.group('ApiModel Validation', () => {
|
|
|
397
397
|
const model = new ApiModel(
|
|
398
398
|
{
|
|
399
399
|
info: { name: 'Valid API', description: 'A test definition' },
|
|
400
|
-
authentication: { strategy: 'UsernamePassword'
|
|
401
|
-
authorization: { strategy: 'RBAC'
|
|
400
|
+
authentication: { strategy: 'UsernamePassword' } as UsernamePasswordConfiguration,
|
|
401
|
+
authorization: { strategy: 'RBAC' } as RolesBasedAccessControl,
|
|
402
402
|
session: {
|
|
403
403
|
secret: 'super-secret',
|
|
404
404
|
properties: ['id', 'role'],
|