feat: 🎸 add grant_scope_ids to role model (#2308)

* feat: 🎸 add grant_scope_ids to role model

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12709

* refactor: 💡 remove removeGrantScopes method

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12709

* style: 💄 add braces around if statement

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12709
This commit is contained in:
Cameron Perera authored and Lisbet Alvarez committed 2024-07-15 17:23:00 -07:00
1 parent c0cecda312
commit f9e85aa9aa
5 files changed
+123 -6

No files matched your search

@@ -28,6 +28,12 @@ export default class GeneratedRoleModel extends BaseModel {
})
grant_scope_id;
@attr('array', {
description:
"The scopes to which this role applies. Defaults to the role's scope.",
})
grant_scope_ids;
@attr('date', {
description: 'The time this resource was created\nOutput only.',
readOnly: true,
+14
View File
@@ -74,6 +74,20 @@ export default class RoleModel extends GeneratedRoleModel {
// =methods
/**
* Saves grant scope ids on the role via the `set-grant-scopes` method.
* @param {[string]} grantScopeIDs
* @return {Promise}
*/
setGrantScopes(grantScopeIDs) {
return this.save({
adapterOptions: {
method: 'set-grant-scopes',
grantScopeIDs,
},
});
}
/**
* Saves grant strings on the role via the `set-grants` method.
* See serializer and adapter for more information.
+31 -6
View File
@@ -15,23 +15,35 @@ export default class RoleSerializer extends ApplicationSerializer {
* serialized.
* If `adapterOptions.principalIDs` is set (to an array of user and
* group IDs), then the payload is serialized via `serializeWithPrincipals`.
* If `adapterOptions.grantScopeIDs` is set (to an array of scope IDs or
* keywords), then the payload is serialized via `serializeWithGrantScopeIDs`.
* @override
* @param {Snapshot} snapshot
* @return {object}
*/
serialize(snapshot) {
const grantStrings = get(snapshot, 'adapterOptions.grantStrings');
let serialized = super.serialize(...arguments);
if (grantStrings)
const grantStrings = get(snapshot, 'adapterOptions.grantStrings');
if (grantStrings) {
serialized = this.serializeWithGrantStrings(snapshot, grantStrings);
}
const principalIDs = snapshot?.adapterOptions?.principalIDs;
if (principalIDs)
if (principalIDs) {
serialized = this.serializeWithPrincipals(snapshot, principalIDs);
}
const grantScopeIDs = snapshot?.adapterOptions?.grantScopeIDs;
if (grantScopeIDs) {
serialized = this.serializeWithGrantScopeIDs(snapshot, grantScopeIDs);
}
return serialized;
}
/**
* Returns a payload containing only the grants array.
* Returns a payload containing only the grants array and version.
* @param {Snapshot} snapshot
* @param {[string]} grantStrings
* @return {object}
@@ -44,8 +56,8 @@ export default class RoleSerializer extends ApplicationSerializer {
}
/**
* Returns a payload containing only the principal_ids array using IDs
* passed into the function (rather than existing principals on the model).
* Returns a payload containing only the principal_ids array using IDs passed
* into the function (rather than existing principals on the model) and version.
* @param {Snapshot} snapshot
* @param {[string]} principalIDs
* @return {object}
@@ -56,4 +68,17 @@ export default class RoleSerializer extends ApplicationSerializer {
principal_ids: principalIDs,
};
}
/**
* Returns a payload containing only the grant_scope_ids array and version.
* @param {Snapshot} snapshot
* @param {[string]} grantScopeIDs
* @return {object}
*/
serializeWithGrantScopeIDs(snapshot, grantScopeIDs) {
return {
version: snapshot.attr('version'),
grant_scope_ids: grantScopeIDs,
};
}
}
+31
View File
@@ -17,6 +17,37 @@ module('Unit | Model | role', function (hooks) {
assert.ok(model);
});
test('it has a `setGrantScopes` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post('/roles/r_123:set-grant-scopes', (schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
grant_scope_ids: ['this', 'children'],
version: 1,
});
return { id: 'r_123' };
});
const store = this.owner.lookup('service:store');
store.push({
data: {
id: 'r_123',
type: 'role',
attributes: {
name: 'Role',
description: 'Description',
grant_scope_ids: ['this'],
version: 1,
scope: {
scope_id: 'o_1',
type: 'scope',
},
},
},
});
const model = store.peekRecord('role', 'r_123');
await model.setGrantScopes(['this', 'children']);
});
test('it has a `saveGrantStrings` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post('/roles/123abc:set-grants', (schema, request) => {
@@ -26,6 +26,7 @@ module('Unit | Serializer | role', function (hooks) {
description: 'Description',
version: 1,
grant_scope_id: null,
grant_scope_ids: [],
});
});
@@ -49,6 +50,46 @@ module('Unit | Serializer | role', function (hooks) {
});
});
test('it serializes only principals when `adapterOptions.principalIDs` is set', function (assert) {
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('role');
const record = store.createRecord('role', {
name: 'User',
description: 'Description',
principal_ids: [],
version: 1,
});
const snapshot = record._createSnapshot();
snapshot.adapterOptions = {
principalIDs: ['u_123'],
};
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
principal_ids: ['u_123'],
version: 1,
});
});
test('it serializes only grant scope IDs when `adapterOptions.grantScopeIDs` is set', function (assert) {
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('role');
const record = store.createRecord('role', {
name: 'User',
description: 'Description',
grant_scope_ids: ['this'],
version: 1,
});
const snapshot = record._createSnapshot();
snapshot.adapterOptions = {
grantScopeIDs: ['this', 'children'],
};
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
grant_scope_ids: ['this', 'children'],
version: 1,
});
});
test('it normalizes records with array fields', function (assert) {
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('role');