Icu 6794 refactor attributes using the newer is nested attribute annotation (#1481)
This commit is contained in:
1 parent
ff6e2bb4cf
commit
ff7a1fedea
15 files changed
+325
-259
No files matched your search
@@ -49,4 +49,26 @@ export default class GeneratedAuthMethodModel extends BaseModel {
|
||||
description: 'Current version number of this resource.',
|
||||
})
|
||||
version;
|
||||
|
||||
@attr('string', { readOnly: true, isNestedAttribute: true }) state;
|
||||
|
||||
@attr('string', { isNestedAttribute: true }) issuer;
|
||||
|
||||
@attr('string', { isNestedAttribute: true }) client_id;
|
||||
|
||||
@attr('string', { isNestedAttribute: true }) client_secret;
|
||||
|
||||
@attr('string', { readOnly: true, isNestedAttribute: true })
|
||||
client_secret_hmac;
|
||||
|
||||
@attr('number', { isNestedAttribute: true }) max_age;
|
||||
|
||||
@attr('string', { isNestedAttribute: true }) api_url_prefix;
|
||||
|
||||
@attr('string', { readOnly: true, isNestedAttribute: true }) callback_url;
|
||||
|
||||
@attr('boolean', { isNestedAttribute: true })
|
||||
disable_discovered_config_validation;
|
||||
|
||||
@attr('boolean', { isNestedAttribute: true }) dry_run;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import GeneratedAuthMethodModel from '../generated/models/auth-method';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
import { equal } from '@ember/object/computed';
|
||||
|
||||
/**
|
||||
@@ -28,33 +27,37 @@ export const options = {
|
||||
};
|
||||
|
||||
export default class AuthMethodModel extends GeneratedAuthMethodModel {
|
||||
// =error attributes
|
||||
// These attributes exist solely to capture errors on nested fields.
|
||||
// See the application adapter's error normalization method for
|
||||
// more information.
|
||||
|
||||
@attr('string', { readOnly: true }) attributes_state;
|
||||
@attr('string', { readOnly: true }) attributes_issuer;
|
||||
@attr('string', { readOnly: true }) attributes_client_id;
|
||||
@attr('string', { readOnly: true }) attributes_client_secret;
|
||||
@attr('string', { readOnly: true }) attributes_max_age;
|
||||
@attr('string', { readOnly: true }) attributes_api_url_prefix;
|
||||
@attr('string', { readOnly: true })
|
||||
attributes_disable_discovered_config_validation;
|
||||
@attr('string', { readOnly: true }) attributes_dry_run;
|
||||
@attr('string', { readOnly: true }) attributes_account_claim_maps;
|
||||
@attr('string', { readOnly: true }) attributes_claims_scopes;
|
||||
@attr('string', { readOnly: true }) attributes_signing_algorithms;
|
||||
@attr('string', { readOnly: true }) attributes_allowed_audiences;
|
||||
@attr('string', { readOnly: true }) attributes_idp_ca_certs;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||
* @type {FragmentAuthMethodAttributesModel}
|
||||
*/
|
||||
@fragment('fragment-auth-method-attributes', { defaultValue: {} }) attributes;
|
||||
@fragmentArray('fragment-auth-method-attributes-account-claim-map', {
|
||||
emptyArrayIfMissing: true,
|
||||
isNestedAttribute: true,
|
||||
})
|
||||
account_claim_maps;
|
||||
|
||||
@fragmentArray('fragment-string', {
|
||||
emptyArrayIfMissing: true,
|
||||
isNestedAttribute: true,
|
||||
})
|
||||
claims_scopes;
|
||||
|
||||
@fragmentArray('fragment-string', {
|
||||
emptyArrayIfMissing: true,
|
||||
isNestedAttribute: true,
|
||||
})
|
||||
signing_algorithms;
|
||||
|
||||
@fragmentArray('fragment-string', {
|
||||
emptyArrayIfMissing: true,
|
||||
isNestedAttribute: true,
|
||||
})
|
||||
allowed_audiences;
|
||||
|
||||
@fragmentArray('fragment-string', {
|
||||
emptyArrayIfMissing: true,
|
||||
isNestedAttribute: true,
|
||||
})
|
||||
idp_ca_certs;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
@@ -81,21 +84,21 @@ export default class AuthMethodModel extends GeneratedAuthMethodModel {
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isInactive() {
|
||||
return this.attributes.state === 'inactive';
|
||||
return this.state === 'inactive';
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isPrivate() {
|
||||
return this.attributes.state === 'active-private';
|
||||
return this.state === 'active-private';
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
get isPublic() {
|
||||
return this.attributes.state === 'active-public';
|
||||
return this.state === 'active-public';
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
|
||||
export default class FragmentAuthMethodAttributesModel extends Fragment {
|
||||
// =attributes (OIDC)
|
||||
|
||||
@attr('string', { readOnly: true }) state;
|
||||
@attr('string') issuer;
|
||||
@attr('string') client_id;
|
||||
@attr('string') client_secret;
|
||||
@attr('string', { readOnly: true }) client_secret_hmac;
|
||||
@attr('number') max_age;
|
||||
@attr('string') api_url_prefix;
|
||||
@attr('string', { readOnly: true }) callback_url;
|
||||
@attr('boolean') disable_discovered_config_validation;
|
||||
@attr('boolean') dry_run;
|
||||
|
||||
@fragmentArray('fragment-auth-method-attributes-account-claim-map', {
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
account_claim_maps;
|
||||
|
||||
@fragmentArray('fragment-string', {
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
claims_scopes;
|
||||
|
||||
@fragmentArray('fragment-string', {
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
signing_algorithms;
|
||||
|
||||
@fragmentArray('fragment-string', {
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
allowed_audiences;
|
||||
|
||||
@fragmentArray('fragment-string', { emptyArrayIfMissing: true }) idp_ca_certs;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import JSONSerializer from '@ember-data/serializer/json';
|
||||
|
||||
export default class FragmentAuthMethodAttributesSerializer extends JSONSerializer {
|
||||
/**
|
||||
* If an attribute is annotated as readOnly in the model, don't serialize it.
|
||||
* Otherwise delegate to default attribute serializer.
|
||||
*
|
||||
* @override
|
||||
* @method serializeAttribute
|
||||
* @param {Snapshot} snapshot
|
||||
* @param {Object} json
|
||||
* @param {String} key
|
||||
* @param {Object} attribute
|
||||
*/
|
||||
serializeAttribute(snapshot, json, key, attribute) {
|
||||
const { type, options } = attribute;
|
||||
let value = super.serializeAttribute(...arguments);
|
||||
// Convert empty strings to null.
|
||||
if (type === 'string' && json[key] === '') json[key] = null;
|
||||
// Do not serialize read-only attributes.
|
||||
if (options.readOnly) delete json[key];
|
||||
// Client secret cannot be unset. If it's falsy, it must be removed.
|
||||
if (key === 'client_secret' && !json[key]) delete json[key];
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'api/models/fragment-auth-method-attributes';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'api/serializers/fragment-auth-method-attributes';
|
||||
@@ -1,12 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Model | fragment auth method attributes', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('fragment-auth-method-attributes', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
@@ -33,27 +33,25 @@ module('Unit | Serializer | auth method', function (hooks) {
|
||||
let record = store.createRecord('auth-method', {
|
||||
type: 'oidc',
|
||||
name: 'OIDC Auth Method',
|
||||
attributes: {
|
||||
state: 'foo',
|
||||
account_claim_maps: [{ from: 'foo', to: 'bar' }],
|
||||
claims_scopes: [{ value: 'profile' }, { value: 'email' }],
|
||||
signing_algorithms: [{ value: 'RS256' }, { value: 'RS384' }],
|
||||
allowed_audiences: [
|
||||
{ value: 'www.alice.com' },
|
||||
{ value: 'www.alice.com/admin' },
|
||||
],
|
||||
idp_ca_certs: [
|
||||
{ value: 'certificate-1234' },
|
||||
{ value: 'certificate-5678' },
|
||||
],
|
||||
api_url_prefix: 'protocol://host:port/foo',
|
||||
client_id: 'id123',
|
||||
client_secret: 'secret456',
|
||||
disable_discovered_config_validation: true,
|
||||
dry_run: true,
|
||||
issuer: 'http://www.example.net',
|
||||
max_age: 500,
|
||||
},
|
||||
state: 'foo',
|
||||
account_claim_maps: [{ from: 'foo', to: 'bar' }],
|
||||
claims_scopes: [{ value: 'profile' }, { value: 'email' }],
|
||||
signing_algorithms: [{ value: 'RS256' }, { value: 'RS384' }],
|
||||
allowed_audiences: [
|
||||
{ value: 'www.alice.com' },
|
||||
{ value: 'www.alice.com/admin' },
|
||||
],
|
||||
idp_ca_certs: [
|
||||
{ value: 'certificate-1234' },
|
||||
{ value: 'certificate-5678' },
|
||||
],
|
||||
api_url_prefix: 'protocol://host:port/foo',
|
||||
client_id: 'id123',
|
||||
client_secret: 'secret456',
|
||||
disable_discovered_config_validation: true,
|
||||
dry_run: true,
|
||||
issuer: 'http://www.example.net',
|
||||
max_age: 500,
|
||||
});
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
@@ -148,19 +146,56 @@ module('Unit | Serializer | auth method', function (hooks) {
|
||||
|
||||
test('it normalizes OIDC records', async function (assert) {
|
||||
const store = this.owner.lookup('service:store');
|
||||
|
||||
const apiUrlPrefix = 'protocol://host:port/foo';
|
||||
const clientId = 'id123';
|
||||
const clientSecret = 'secret456';
|
||||
const disableDiscoveredConfigValidation = true;
|
||||
const dryRun = true;
|
||||
const issuer = 'http://www.example.net';
|
||||
const maxAge = 500;
|
||||
this.server.get('/v1/auth-methods/oidc123', () => ({
|
||||
attributes: {
|
||||
account_claim_maps: ['from=to', 'foo=bar'],
|
||||
claims_scopes: [{ value: 'profile' }, { value: 'email' }],
|
||||
signing_algorithms: [{ value: 'RS256' }, { value: 'RS384' }],
|
||||
allowed_audiences: [
|
||||
{ value: 'www.alice.com' },
|
||||
{ value: 'www.alice.com/admin' },
|
||||
],
|
||||
idp_ca_certs: [
|
||||
{ value: 'certificate-1234' },
|
||||
{ value: 'certificate-5678' },
|
||||
],
|
||||
api_url_prefix: apiUrlPrefix,
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
disable_discovered_config_validation: disableDiscoveredConfigValidation,
|
||||
dry_run: dryRun,
|
||||
issuer: issuer,
|
||||
max_age: maxAge,
|
||||
},
|
||||
version: 1,
|
||||
type: 'oidc',
|
||||
id: 'oidc123',
|
||||
}));
|
||||
|
||||
const record = await store.findRecord('auth-method', 'oidc123');
|
||||
const { account_claim_maps } = record.attributes;
|
||||
const { account_claim_maps } = record;
|
||||
|
||||
assert.strictEqual(account_claim_maps.firstObject.from, 'from');
|
||||
assert.strictEqual(account_claim_maps.firstObject.to, 'to');
|
||||
assert.strictEqual(account_claim_maps.lastObject.from, 'foo');
|
||||
assert.strictEqual(account_claim_maps.lastObject.to, 'bar');
|
||||
assert.strictEqual(record.api_url_prefix, apiUrlPrefix);
|
||||
assert.strictEqual(record.client_id, clientId);
|
||||
assert.strictEqual(record.client_secret, clientSecret);
|
||||
assert.strictEqual(
|
||||
record.disable_discovered_config_validation,
|
||||
disableDiscoveredConfigValidation
|
||||
);
|
||||
assert.strictEqual(record.dry_run, dryRun);
|
||||
assert.strictEqual(record.issuer, issuer);
|
||||
assert.strictEqual(record.max_age, maxAge);
|
||||
});
|
||||
});
|
||||
@@ -1,37 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Serializer | fragment auth method attributes', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it serializes empty strings to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('user', {
|
||||
name: '',
|
||||
description: '',
|
||||
version: null,
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
name: null,
|
||||
description: null,
|
||||
});
|
||||
});
|
||||
|
||||
test('it does not serialize client_secret if present but falsy', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('user', {
|
||||
name: '',
|
||||
description: '',
|
||||
version: null,
|
||||
client_secret: false,
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
name: null,
|
||||
description: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user