Skip to content

Commit

Permalink
ui: Integrate new roles and policies
Browse files Browse the repository at this point in the history
  • Loading branch information
John Cowen committed Aug 23, 2019
1 parent a6ade42 commit 2200072
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 179 deletions.
93 changes: 30 additions & 63 deletions ui-v2/app/adapters/role.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,39 @@
import Adapter, {
REQUEST_CREATE,
REQUEST_UPDATE,
DATACENTER_QUERY_PARAM as API_DATACENTER_KEY,
} from './application';
import Adapter, { DATACENTER_QUERY_PARAM as API_DATACENTER_KEY } from './application';

import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/role';
import { SLUG_KEY } from 'consul-ui/models/role';
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
import { OK as HTTP_OK } from 'consul-ui/utils/http/status';
import { PUT as HTTP_PUT } from 'consul-ui/utils/http/method';

import WithPolicies from 'consul-ui/mixins/policy/as-many';
export default Adapter.extend({
requestForQuery: function(request, { dc, index, id }) {
return request`
GET /v1/acl/roles?${{ dc }}
export default Adapter.extend(WithPolicies, {
urlForQuery: function(query, modelName) {
return this.appendURL('acl/roles', [], this.cleanQuery(query));
${{ index }}
`;
},
urlForQueryRecord: function(query, modelName) {
if (typeof query.id === 'undefined') {
requestForQueryRecord: function(request, { dc, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
return this.appendURL('acl/role', [query.id], this.cleanQuery(query));
},
urlForCreateRecord: function(modelName, snapshot) {
return this.appendURL('acl/role', [], {
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY),
});
},
urlForUpdateRecord: function(id, modelName, snapshot) {
return this.appendURL('acl/role', [snapshot.attr(SLUG_KEY)], {
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY),
});
},
urlForDeleteRecord: function(id, modelName, snapshot) {
return this.appendURL('acl/role', [snapshot.attr(SLUG_KEY)], {
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY),
});
},
handleResponse: function(status, headers, payload, requestData) {
let response = payload;
if (status === HTTP_OK) {
const url = this.parseURL(requestData.url);
switch (true) {
case response === true:
response = this.handleBooleanResponse(url, response, PRIMARY_KEY, SLUG_KEY);
break;
case Array.isArray(response):
response = this.handleBatchResponse(url, response, PRIMARY_KEY, SLUG_KEY);
break;
default:
response = this.handleSingleResponse(url, response, PRIMARY_KEY, SLUG_KEY);
}
}
return this._super(status, headers, response, requestData);
},
methodForRequest: function(params) {
switch (params.requestType) {
case REQUEST_CREATE:
return HTTP_PUT;
}
return this._super(...arguments);
},
dataForRequest: function(params) {
const data = this._super(...arguments);
switch (params.requestType) {
case REQUEST_UPDATE:
case REQUEST_CREATE:
return data.role;
}
return data;
return request`
GET /v1/acl/role/${id}?${{ dc }}
${{ index }}
`;
},
requestForCreateRecord: function(request, data) {
return request`
PUT /v1/acl/role?${{ [API_DATACENTER_KEY]: data[DATACENTER_KEY] }}
`;
},
requestForUpdateRecord: function(request, data) {
return request`
PUT /v1/acl/role/${data[SLUG_KEY]}?${{ [API_DATACENTER_KEY]: data[DATACENTER_KEY] }}
`;
},
requestForDeleteRecord: function(request, data) {
return request`
DELETE /v1/acl/role/${data[SLUG_KEY]}?${{ [API_DATACENTER_KEY]: data[DATACENTER_KEY] }}
`;
},
});
4 changes: 0 additions & 4 deletions ui-v2/app/adapters/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,4 @@ export default Adapter.extend({
PUT /v1/session/destroy/${data[SLUG_KEY]}?${{ [API_DATACENTER_KEY]: data[DATACENTER_KEY] }}
`;
},
//
respondForQueryRecord: function(respond, query) {
return this._super(cb => respond((headers, body) => cb(headers, body[0])), query);
},
});
11 changes: 3 additions & 8 deletions ui-v2/app/adapters/token.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import Adapter, { DATACENTER_QUERY_PARAM as API_DATACENTER_KEY } from './application';
import { inject as service } from '@ember/service';
import { get } from '@ember/object';
import { SLUG_KEY } from 'consul-ui/models/token';
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';

import WithPolicies from 'consul-ui/mixins/policy/as-many';
import WithRoles from 'consul-ui/mixins/role/as-many';

import { get } from '@ember/object';


export default Adapter.extend(WithRoles, WithPolicies, {
export default Adapter.extend({
store: service('store'),

requestForQuery: function(request, { dc, index, policy }) {
Expand All @@ -35,7 +30,7 @@ export default Adapter.extend(WithRoles, WithPolicies, {
`;
},
requestForUpdateRecord: function(request, data) {
// TODO: Serializer
// TODO: Serializer - Pretty sure this can go now
// If a token has Rules, use the old API
if (typeof data['Rules'] !== 'undefined') {
// TODO: need to clean up vars sent
Expand Down
48 changes: 30 additions & 18 deletions ui-v2/app/mixins/policy/as-many.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { REQUEST_CREATE, REQUEST_UPDATE } from 'consul-ui/adapters/application';

import Mixin from '@ember/object/mixin';
import { get } from '@ember/object';

Expand All @@ -17,6 +15,8 @@ const normalizeServiceIdentities = function(items) {
return policy;
});
};
// Sometimes we get `Policies: null`, make null equal an empty array
// and add an empty template
const normalizePolicies = function(items) {
return (items || []).map(function(item) {
return {
Expand Down Expand Up @@ -47,24 +47,36 @@ const serializePolicies = function(items) {
};

export default Mixin.create({
handleSingleResponse: function(url, response, primary, slug) {
response.Policies = normalizePolicies(response.Policies).concat(
normalizeServiceIdentities(response.ServiceIdentities)
);
return this._super(url, response, primary, slug);
//TODO: what about update and create?
respondForQueryRecord: function(respond, query) {
return this._super(function(cb) {
return respond((headers, body) => {
body.Policies = normalizePolicies(body.Policies).concat(
normalizeServiceIdentities(body.ServiceIdentities)
);
return cb(headers, body);
});
}, query);
},
respondForQuery: function(respond, query) {
return this._super(function(cb) {
return respond(function(headers, body) {
return cb(
headers,
body.map(function(item) {
item.Policies = normalizePolicies(item.Policies).concat(
normalizeServiceIdentities(item.ServiceIdentities)
);
return item;
})
);
});
}, query);
},
dataForRequest: function(params) {
serialize: function(snapshot, options) {
const data = this._super(...arguments);
const name = params.type.modelName;
switch (params.requestType) {
case REQUEST_UPDATE:
// falls through
case REQUEST_CREATE:
// ServiceIdentities serialization must happen first, or a copy taken
data[name].ServiceIdentities = serializeServiceIdentities(data[name].Policies);
data[name].Policies = minimizeModel(serializePolicies(data[name].Policies));
break;
}
data.ServiceIdentities = serializeServiceIdentities(data.Policies);
data.Policies = minimizeModel(serializePolicies(data.Policies));
return data;
},
});
41 changes: 23 additions & 18 deletions ui-v2/app/mixins/role/as-many.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
import { REQUEST_CREATE, REQUEST_UPDATE } from 'consul-ui/adapters/application';

import Mixin from '@ember/object/mixin';

import minimizeModel from 'consul-ui/utils/minimizeModel';

export default Mixin.create({
handleSingleResponse: function(url, response, primary, slug) {
['Roles'].forEach(function(prop) {
if (typeof response[prop] === 'undefined' || response[prop] === null) {
response[prop] = [];
}
});
return this._super(url, response, primary, slug);
// TODO: what about update and create?
respondForQueryRecord: function(respond, query) {
return this._super(function(cb) {
return respond((headers, body) => {
body.Roles = typeof body.Roles === 'undefined' || body.Roles === null ? [] : body.Roles;
return cb(headers, body);
});
}, query);
},
respondForQuery: function(respond, query) {
return this._super(function(cb) {
return respond(function(headers, body) {
return cb(
headers,
body.map(function(item) {
item.Roles = typeof item.Roles === 'undefined' || item.Roles === null ? [] : item.Roles;
return item;
})
);
});
}, query);
},
dataForRequest: function(params) {
const name = params.type.modelName;
serialize: function(snapshot, options) {
const data = this._super(...arguments);
switch (params.requestType) {
case REQUEST_UPDATE:
// falls through
case REQUEST_CREATE:
data[name].Roles = minimizeModel(data[name].Roles);
break;
}
data.Roles = minimizeModel(data.Roles);
return data;
},
});
6 changes: 4 additions & 2 deletions ui-v2/app/serializers/role.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Serializer from './application';
import { PRIMARY_KEY } from 'consul-ui/models/role';
export default Serializer.extend({
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/role';
import WithPolicies from 'consul-ui/mixins/policy/as-many';
export default Serializer.extend(WithPolicies, {
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
});
32 changes: 4 additions & 28 deletions ui-v2/app/serializers/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import Serializer from './application';
import { get } from '@ember/object';
import { PRIMARY_KEY, SLUG_KEY, ATTRS } from 'consul-ui/models/token';

export default Serializer.extend({
import WithPolicies from 'consul-ui/mixins/policy/as-many';
import WithRoles from 'consul-ui/mixins/role/as-many';

export default Serializer.extend(WithPolicies, WithRoles, {
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
attrs: ATTRS,
Expand All @@ -15,20 +18,6 @@ export default Serializer.extend({
data['ID'] = data['SecretID'];
data['Name'] = data['Description'];
}

if (Array.isArray(data.Policies)) {
data.Policies = data.Policies.filter(function(item) {
// Just incase, don't save any policies that aren't saved
return !get(item, 'isNew');
}).map(function(item) {
return {
ID: get(item, 'ID'),
Name: get(item, 'Name'),
};
});
} else {
delete data.Policies;
}
// make sure we never send the SecretID
if (data && typeof data['SecretID'] !== 'undefined') {
delete data['SecretID'];
Expand Down Expand Up @@ -58,17 +47,4 @@ export default Serializer.extend({
query
);
},
respondForQueryRecord: function(respond, query) {
return this._super(
cb =>
respond((headers, body) => {
// Sometimes we get `Policies: null`, make null equal an empty array
if (typeof body.Policies === 'undefined' || body.Policies === null) {
body.Policies = [];
}
return cb(headers, body);
}),
query
);
},
});
1 change: 0 additions & 1 deletion ui-v2/tests/acceptance/deleting.feature
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ Feature: deleting: Deleting items with confirmations, success and error notifica
| kv | DELETE | /v1/kv/key-name?dc=datacenter | kv: key-name |
| intention | DELETE | /v1/connect/intentions/ee52203d-989f-4f7a-ab5a-2bef004164ca?dc=datacenter | intention: ee52203d-989f-4f7a-ab5a-2bef004164ca |
| token | DELETE | /v1/acl/token/001fda31-194e-4ff1-a5ec-589abf2cafd0?dc=datacenter | token: 001fda31-194e-4ff1-a5ec-589abf2cafd0 |
| policy | DELETE | /v1/acl/policy/1981f51d-301a-497b-89a0-05112ef02b4b?dc=datacenter | policy: 1981f51d-301a-497b-89a0-05112ef02b4b |
----------------------------------------------------------------------------------------------------------------------------------------------------
@ignore
Scenario: Sort out the wide tables ^
Expand Down
34 changes: 26 additions & 8 deletions ui-v2/tests/integration/adapters/role/response-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,54 @@ module('Integration | Adapter | role | response', function(hooks) {
setupTest(hooks);
const dc = 'dc-1';
const id = 'role-name';
test('handleResponse returns the correct data for list endpoint', function(assert) {
const adapter = this.owner.lookup('adapter:role');
test('respondForQuery returns the correct data for list endpoint', function(assert) {
const serializer = this.owner.lookup('serializer:role');
const request = {
url: `/v1/acl/roles?dc=${dc}`,
};
return get(request.url).then(function(payload) {
const expected = payload.map(item =>
Object.assign({}, item, {
Datacenter: dc,
uid: `["${dc}","${item.ID}"]`,
Policies: createPolicies(item),
uid: `["${dc}","${item.ID}"]`,
})
);
const actual = adapter.handleResponse(200, {}, payload, request);
const actual = serializer.respondForQuery(
function(cb) {
const headers = {};
const body = payload;
return cb(headers, body);
},
{
dc: dc,
}
);
assert.deepEqual(actual, expected);
});
});
test('handleResponse returns the correct data for item endpoint', function(assert) {
const adapter = this.owner.lookup('adapter:role');
test('respondForQueryRecord returns the correct data for item endpoint', function(assert) {
const serializer = this.owner.lookup('serializer:role');
const request = {
url: `/v1/acl/role/${id}?dc=${dc}`,
};
return get(request.url).then(function(payload) {
const expected = Object.assign({}, payload, {
Datacenter: dc,
Policies: createPolicies(payload),
[META]: {},
uid: `["${dc}","${id}"]`,
Policies: createPolicies(payload),
});
const actual = adapter.handleResponse(200, {}, payload, request);
const actual = serializer.respondForQueryRecord(
function(cb) {
const headers = {};
const body = payload;
return cb(headers, body);
},
{
dc: dc,
}
);
assert.deepEqual(actual, expected);
});
});
Expand Down
Loading

0 comments on commit 2200072

Please sign in to comment.