Merge pull request #4251 from hashicorp/bugfix/ui-null-tokens
Ensure a blank/empty token is sent if the localStorage kv doesn't exist
This commit is contained in:
commit
4db6f80de6
|
@ -7,19 +7,27 @@ export default Service.extend({
|
|||
storage: window.localStorage,
|
||||
findHeaders: function() {
|
||||
// TODO: if possible this should be a promise
|
||||
const token = get(this, 'storage').getItem('token');
|
||||
// TODO: The old UI always sent ?token=
|
||||
// replicate the old functionality here
|
||||
// but remove this to be cleaner if its not necessary
|
||||
return {
|
||||
'X-Consul-Token': get(this, 'storage').getItem('token'),
|
||||
'X-Consul-Token': token === null ? '' : token,
|
||||
};
|
||||
},
|
||||
findAll: function(key) {
|
||||
return Promise.resolve({ token: get(this, 'storage').getItem('token') });
|
||||
const token = get(this, 'storage').getItem('token');
|
||||
return Promise.resolve({ token: token === null ? '' : token });
|
||||
},
|
||||
findBySlug: function(slug) {
|
||||
// TODO: Force localStorage to always be strings...
|
||||
// const value = get(this, 'storage').getItem(slug);
|
||||
return Promise.resolve(get(this, 'storage').getItem(slug));
|
||||
},
|
||||
persist: function(obj) {
|
||||
const storage = get(this, 'storage');
|
||||
Object.keys(obj).forEach((item, i) => {
|
||||
// TODO: ...everywhere
|
||||
storage.setItem(item, obj[item]);
|
||||
});
|
||||
return Promise.resolve(obj);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<fieldset>
|
||||
<label class="type-text">
|
||||
<span>ACL Token</span>
|
||||
{{ input type='password' value=item.token }}
|
||||
{{ input type='password' value=item.token name="token" }}
|
||||
<em>The token is sent with requests as the <code>X-Consul-Token</code> HTTP header parameter. This is used to control the ACL for the web UI.</em>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
@setupApplicationTest
|
||||
Feature: settings / update: Update Settings
|
||||
In order to authenticate with an ACL token
|
||||
As a user
|
||||
I need to be able to add my token via the UI
|
||||
Scenario: I click Save without actually typing anything
|
||||
Given 1 datacenter model with the value "datacenter"
|
||||
When I visit the settings page
|
||||
Then the url should be /settings
|
||||
And I submit
|
||||
Then I have settings like yaml
|
||||
---
|
||||
token: ''
|
||||
---
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import steps from '../steps';
|
||||
|
||||
// step definitions that are shared between features should be moved to the
|
||||
// tests/acceptance/steps/steps.js file
|
||||
|
||||
export default function(assert) {
|
||||
return steps(assert).then('I should find a file', function() {
|
||||
assert.ok(true, this.step);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import steps from './steps';
|
||||
|
||||
// step definitions that are shared between features should be moved to the
|
||||
// tests/acceptance/steps/steps.js file
|
||||
|
||||
export default function(assert) {
|
||||
return steps(assert).then('I should find a file', function() {
|
||||
assert.ok(true, this.step);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
@setupApplicationTest
|
||||
Feature: token headers
|
||||
In order to authenticate with tokens
|
||||
As a user
|
||||
I need to be able to specify a ACL token AND/OR leave it blank to authenticate with the API
|
||||
Scenario: Arriving at the index page having not set a token previously
|
||||
Given 1 datacenter model with the value "datacenter"
|
||||
When I visit the index page
|
||||
Then the url should be /datacenter/services
|
||||
And a GET request is made to "/v1/catalog/datacenters" from yaml
|
||||
---
|
||||
headers:
|
||||
X-Consul-Token: ''
|
||||
---
|
||||
Scenario: Set the token to [Token] and then navigate to the index page
|
||||
Given 1 datacenter model with the value "datacenter"
|
||||
When I visit the settings page
|
||||
Then the url should be /settings
|
||||
Then I type with yaml
|
||||
---
|
||||
token: [Token]
|
||||
---
|
||||
And I submit
|
||||
When I visit the index page
|
||||
Then the url should be /datacenter/services
|
||||
And a GET request is made to "/v1/catalog/datacenters" from yaml
|
||||
---
|
||||
headers:
|
||||
X-Consul-Token: [Token]
|
||||
---
|
||||
Where:
|
||||
---------
|
||||
| Token |
|
||||
| token |
|
||||
| '' |
|
||||
---------
|
|
@ -64,6 +64,7 @@ function setupScenario(featureAnnotations, scenarioAnnotations) {
|
|||
}
|
||||
return function(model) {
|
||||
model.afterEach(function() {
|
||||
window.localStorage.clear();
|
||||
api.server.reset();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import index from 'consul-ui/tests/pages/index';
|
||||
import dcs from 'consul-ui/tests/pages/dc';
|
||||
import settings from 'consul-ui/tests/pages/settings';
|
||||
import services from 'consul-ui/tests/pages/dc/services/index';
|
||||
import service from 'consul-ui/tests/pages/dc/services/show';
|
||||
import nodes from 'consul-ui/tests/pages/dc/nodes/index';
|
||||
|
@ -12,6 +13,7 @@ import acl from 'consul-ui/tests/pages/dc/acls/edit';
|
|||
export default {
|
||||
index,
|
||||
dcs,
|
||||
settings,
|
||||
services,
|
||||
service,
|
||||
nodes,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { create, visitable, clickable } from 'ember-cli-page-object';
|
||||
|
||||
export default create({
|
||||
visit: visitable('/settings'),
|
||||
submit: clickable('[type=submit]'),
|
||||
});
|
|
@ -153,6 +153,37 @@ export default function(assert) {
|
|||
);
|
||||
});
|
||||
})
|
||||
// TODO: This one can replace the above one, it covers more use cases
|
||||
// also DRY it out a bit
|
||||
.then('a $method request is made to "$url" from yaml\n$yaml', function(method, url, yaml) {
|
||||
const request = api.server.history[api.server.history.length - 2];
|
||||
assert.equal(
|
||||
request.method,
|
||||
method,
|
||||
`Expected the request method to be ${method}, was ${request.method}`
|
||||
);
|
||||
assert.equal(request.url, url, `Expected the request url to be ${url}, was ${request.url}`);
|
||||
let data = yaml.body || {};
|
||||
const body = JSON.parse(request.requestBody);
|
||||
Object.keys(data).forEach(function(key, i, arr) {
|
||||
assert.equal(
|
||||
body[key],
|
||||
data[key],
|
||||
`Expected the payload to contain ${key} to equal ${body[key]}, ${key} was ${data[key]}`
|
||||
);
|
||||
});
|
||||
data = yaml.headers || {};
|
||||
const headers = request.requestHeaders;
|
||||
Object.keys(data).forEach(function(key, i, arr) {
|
||||
assert.equal(
|
||||
headers[key],
|
||||
data[key],
|
||||
`Expected the payload to contain ${key} to equal ${headers[key]}, ${key} was ${
|
||||
data[key]
|
||||
}`
|
||||
);
|
||||
});
|
||||
})
|
||||
.then('a $method request is made to "$url" with the body "$body"', function(
|
||||
method,
|
||||
url,
|
||||
|
@ -214,6 +245,15 @@ export default function(assert) {
|
|||
`Expected ${num} ${model}s with ${property} set to "${value}", saw ${len}`
|
||||
);
|
||||
})
|
||||
.then('I have settings like yaml\n$yaml', function(data) {
|
||||
// TODO: Inject this
|
||||
const settings = window.localStorage;
|
||||
Object.keys(data).forEach(function(prop) {
|
||||
const actual = settings.getItem(prop);
|
||||
const expected = data[prop];
|
||||
assert.strictEqual(actual, expected, `Expected settings to be ${expected} was ${actual}`);
|
||||
});
|
||||
})
|
||||
.then('I see $property on the $component like yaml\n$yaml', function(
|
||||
property,
|
||||
component,
|
||||
|
|
Loading…
Reference in New Issue