Skip to content

Commit a63d79d

Browse files
committed
D-12087 add support for implicit auth, i.e. let browser do its thing
parameters to createMeta are now specified via configuration object
1 parent 829a5c5 commit a63d79d

File tree

5 files changed

+110
-38
lines changed

5 files changed

+110
-38
lines changed

.eslintrc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,7 @@
4545
}
4646
],
4747
"no-use-before-define": 0,
48-
"comma-dangle": [
49-
2,
50-
"never"
51-
],
48+
"comma-dangle": 0,
5249
"no-cond-assign": [
5350
2,
5451
"always"

src/createMeta.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import transformDataToAsset from './transformDataToAsset';
33
import getV1Urls from './getV1Urls';
44
import Oid from './Oid';
55

6-
export default (hostname, instance, protocol, port, token, postFn, getFn, isBasic) => {
6+
export default ({hostname, instance, protocol, port, token, postFn, getFn, isBasic}) => {
77
const urls = getV1Urls(hostname, instance, protocol, port);
88
const headers = createHeaderObj(token, isBasic);
99

@@ -59,8 +59,22 @@ export default (hostname, instance, protocol, port, token, postFn, getFn, isBasi
5959
};
6060
};
6161

62-
const createHeaderObj = (token, isBasic) => ({
63-
Accept: 'application/json',
64-
'Content-Type': 'application/json',
65-
Authorization: `${isBasic ? 'Basic' : 'Bearer'} ${token}`
66-
});
62+
const createHeaderObj = (token, isBasic) => {
63+
const headers = {
64+
Accept: 'application/json',
65+
'Content-Type': 'application/json',
66+
};
67+
68+
69+
const hasToken = Boolean(token);
70+
const hasType = typeof isBasic !== 'undefined';
71+
72+
if (hasToken || hasType) {
73+
invariant(hasToken, `Error: there was no \`token\` provided to the SDK`);
74+
invariant(hasType, `Error: there was no \`isBasic\` provided to the SDK`);
75+
76+
headers['Authorization'] = `${isBasic ? 'Basic' : 'Bearer'} ${token}`; // eslint-disable-line dot-notation
77+
}
78+
79+
return headers;
80+
};

src/createMeta.specs.js

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('src/meta', function() {
1616
});
1717
describe('when creating a meta object', () => {
1818
beforeEach(() => {
19-
this.actual = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, false);
19+
this.actual = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: false });
2020
});
2121
it('it should return an object with a create asset function', () => {
2222
this.actual.create.should.be.a('function');
@@ -46,7 +46,7 @@ describe('src/meta.create', function() {
4646
});
4747
describe('given no asset type', () => {
4848
beforeEach(() => {
49-
this.meta = createMeta('h', 'i', 'http', 80, 'token', () => {
49+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80 }, () => {
5050
}, () => {
5151
}, false);
5252
});
@@ -92,7 +92,7 @@ describe('src/meta.create', function() {
9292
RewireApi.__Rewire__('transformDataToAsset', transformDataToAsset);
9393
this.postFn = sinon.stub();
9494

95-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, null);
95+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, isBasic: false });
9696
this.actual = this.meta.create('Actual', {Value: 5.5});
9797
});
9898
afterEach(() => {
@@ -127,7 +127,42 @@ describe('src/meta.create', function() {
127127
RewireApi.__Rewire__('transformDataToAsset', transformDataToAsset);
128128
this.postFn = sinon.stub();
129129

130-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, null, true);
130+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, isBasic: true });
131+
this.actual = this.meta.create('Actual', {Value: 5.5});
132+
});
133+
afterEach(() => {
134+
RewireApi.__ResetDependency__('getV1Urls');
135+
RewireApi.__ResetDependency__('transformDataToAsset');
136+
});
137+
it('it should post the asset creation to the REST URL endpoint with basic authentication headers', () => {
138+
this.postFn.calledWith('rest URL/Actual', this.assetData, this.headers).should.be.true;
139+
});
140+
});
141+
});
142+
});
143+
144+
describe('given implicit authentication', () => {
145+
describe('given an asset type and asset data', () => {
146+
describe('when creating an asset', () => {
147+
beforeEach(() => {
148+
this.assetData = {key: 'value'};
149+
this.headers = {
150+
Accept: 'application/json',
151+
'Content-Type': 'application/json',
152+
};
153+
const getV1Urls = sinon.mock()
154+
.withArgs('h', 'i', 'http', 80)
155+
.returns({
156+
rest: 'rest URL'
157+
});
158+
const transformDataToAsset = sinon.mock()
159+
.withArgs({Value: 5.5})
160+
.returns(this.assetData);
161+
RewireApi.__Rewire__('getV1Urls', getV1Urls);
162+
RewireApi.__Rewire__('transformDataToAsset', transformDataToAsset);
163+
this.postFn = sinon.stub();
164+
165+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, postFn: this.postFn });
131166
this.actual = this.meta.create('Actual', {Value: 5.5});
132167
});
133168
afterEach(() => {
@@ -146,7 +181,7 @@ describe('src/meta.create', function() {
146181
describe('src/meta.update', function() {
147182
beforeEach(() => {
148183
this.actual = undefined;
149-
this.meta = createMeta('h', 'i', 'http', 80, 'token', () => {
184+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80 }, () => {
150185
}, () => {
151186
});
152187
});
@@ -193,7 +228,7 @@ describe('src/meta.update', function() {
193228
RewireApi.__Rewire__('transformDataToAsset', transformDataToAsset);
194229
this.postFn = sinon.stub();
195230

196-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, false);
231+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: false });
197232
this.actual = this.meta.update('Actual:10011', {Value: 5.5});
198233
});
199234
afterEach(() => {
@@ -228,7 +263,7 @@ describe('src/meta.update', function() {
228263
RewireApi.__Rewire__('transformDataToAsset', transformDataToAsset);
229264
this.postFn = sinon.stub();
230265

231-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, true);
266+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: true });
232267
this.actual = this.meta.update('Actual:10011', {Value: 5.5});
233268
});
234269
afterEach(() => {
@@ -262,7 +297,7 @@ describe('src/meta.update', function() {
262297
RewireApi.__Rewire__('transformDataToAsset', transformDataToAsset);
263298
this.postFn = sinon.stub();
264299

265-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, true);
300+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: true });
266301
this.actual = this.meta.update('Actual:10011', {Value: 5.5}, 'change comment');
267302
});
268303
afterEach(() => {
@@ -279,7 +314,7 @@ describe('src/meta.update', function() {
279314
describe('src/meta.query', function() {
280315
beforeEach(() => {
281316
this.actual = undefined;
282-
this.meta = createMeta('h', 'i', 'http', 80, 'token', () => {
317+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80 }, () => {
283318
}, () => {
284319
});
285320
});
@@ -336,7 +371,7 @@ describe('src/meta.query', function() {
336371
RewireApi.__Rewire__('getV1Urls', getV1Urls);
337372
this.postFn = sinon.stub();
338373

339-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, false);
374+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: false });
340375
this.actual = this.meta.query(this.query);
341376
});
342377
afterEach(() => {
@@ -366,7 +401,7 @@ describe('src/meta.query', function() {
366401
RewireApi.__Rewire__('getV1Urls', getV1Urls);
367402
this.postFn = sinon.stub();
368403

369-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, true);
404+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: true });
370405
this.actual = this.meta.query(this.query);
371406
});
372407
afterEach(() => {
@@ -383,7 +418,7 @@ describe('src/meta.query', function() {
383418
describe('src/meta.executeOperation', function() {
384419
beforeEach(() => {
385420
this.actual = undefined;
386-
this.meta = createMeta('h', 'i', 'http', 80, 'token', () => {
421+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80 }, () => {
387422
}, () => {
388423
});
389424
});
@@ -419,7 +454,7 @@ describe('src/meta.executeOperation', function() {
419454
RewireApi.__Rewire__('getV1Urls', getV1Urls);
420455
this.postFn = sinon.stub();
421456

422-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, false);
457+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: false });
423458
this.actual = this.meta.executeOperation('Actual:10011', this.operationName);
424459
});
425460
afterEach(() => {
@@ -449,7 +484,7 @@ describe('src/meta.executeOperation', function() {
449484
RewireApi.__Rewire__('getV1Urls', getV1Urls);
450485
this.postFn = sinon.stub();
451486

452-
this.meta = createMeta('h', 'i', 'http', 80, 'token', this.postFn, this.getFn, true);
487+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', postFn: this.postFn, getFn: this.getFn, isBasic: true });
453488
this.actual = this.meta.executeOperation('Actual:10011', this.operationName);
454489
});
455490
afterEach(() => {
@@ -483,7 +518,7 @@ describe('src/meta.queryDefinition', function() {
483518
RewireApi.__Rewire__('getV1Urls', getV1Urls);
484519
this.getFn = sinon.stub();
485520

486-
this.meta = createMeta('h', 'i', 'http', 80, 'token', null, this.getFn, false);
521+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', getFn: this.getFn, isBasic: false });
487522
this.actual = this.meta.queryDefinition();
488523
});
489524
afterEach(() => {
@@ -510,7 +545,7 @@ describe('src/meta.queryDefinition', function() {
510545
RewireApi.__Rewire__('getV1Urls', getV1Urls);
511546
this.getFn = sinon.stub();
512547

513-
this.meta = createMeta('h', 'i', 'http', 80, 'token', null, this.getFn, false);
548+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', getFn: this.getFn, isBasic: false });
514549
this.actual = this.meta.queryDefinition('Actual');
515550
});
516551
afterEach(() => {
@@ -537,7 +572,7 @@ describe('src/meta.queryDefinition', function() {
537572
RewireApi.__Rewire__('getV1Urls', getV1Urls);
538573
this.getFn = sinon.stub();
539574

540-
this.meta = createMeta('h', 'i', 'http', 80, 'token', null, this.getFn, false);
575+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', getFn: this.getFn, isBasic: false });
541576
this.actual = this.meta.getActivityStream('Story:1234');
542577
});
543578
afterEach(() => {
@@ -564,7 +599,7 @@ describe('src/meta.queryDefinition', function() {
564599
RewireApi.__Rewire__('getV1Urls', getV1Urls);
565600
this.getFn = sinon.stub();
566601

567-
this.meta = createMeta('h', 'i', 'http', 80, 'token', null, this.getFn, false);
602+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', getFn: this.getFn, isBasic: false });
568603
this.actual = this.meta.queryDefinition();
569604
});
570605
afterEach(() => {
@@ -591,7 +626,7 @@ describe('src/meta.queryDefinition', function() {
591626
RewireApi.__Rewire__('getV1Urls', getV1Urls);
592627
this.getFn = sinon.stub();
593628

594-
this.meta = createMeta('h', 'i', 'http', 80, 'token', null, this.getFn, true);
629+
this.meta = createMeta({ hostname: 'h', instance: 'i', protocol: 'http', port: 80, token: 'token', getFn: this.getFn, isBasic: true });
595630
this.actual = this.meta.queryDefinition();
596631
});
597632
afterEach(() => {

src/index.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,33 @@ export {default as axiosConnector} from './connectors/axiosConnector';
77
export default (postFn, getFn) => (hostname, instance, port = 80, isHttps = false) => {
88
const protocol = isHttps ? 'https' : 'http';
99
return {
10-
withAccessToken: (token) => createMeta(
10+
withImplicitAuth: () => createMeta({
11+
hostname,
12+
instance,
13+
protocol,
14+
port,
15+
postFn,
16+
getFn,
17+
}),
18+
withAccessToken: (token) => createMeta({
1119
hostname,
1220
instance,
1321
protocol,
1422
port,
1523
token,
1624
postFn,
1725
getFn,
18-
false
19-
),
20-
withCreds: (username, password) => createMeta(
26+
isBasic: false,
27+
}),
28+
withCreds: (username, password) => createMeta({
2129
hostname,
2230
instance,
2331
protocol,
2432
port,
25-
btoa(`${username}:${password}`),
33+
token: btoa(`${username}:${password}`),
2634
postFn,
2735
getFn,
28-
true
29-
)
36+
isBasic: true,
37+
})
3038
};
3139
};

src/index.specs.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ describe('when loading the module', function() {
3434
it('it should return a meta object with function to authenticate via an access token', () => {
3535
this.setSecurity.withAccessToken.should.be.a('function');
3636
});
37+
it('it should return a meta object with function to authenticate implicitly', () => {
38+
this.setSecurity.withImplicitAuth.should.be.a('function');
39+
});
3740

3841
describe('given an access token', () => {
3942
beforeEach(() => {
@@ -42,7 +45,7 @@ describe('when loading the module', function() {
4245
describe('when creating the SDK', () => {
4346
beforeEach(() => {
4447
this.metaStub = sinon.mock()
45-
.withExactArgs('hostname', 'instance', 'https', 80, this.accessToken, this.postFn, this.getFn, false)
48+
.withExactArgs({ hostname: 'hostname', instance: 'instance', protocol: 'https', port: 80, token: this.accessToken, postFn: this.postFn, getFn: this.getFn, isBasic: false })
4649
.returns('meta');
4750
RewireApi.__Rewire__('createMeta', this.metaStub);
4851
this.meta = this.setSecurity.withAccessToken(this.accessToken);
@@ -62,7 +65,7 @@ describe('when loading the module', function() {
6265
beforeEach(() => {
6366
this.token = 'username token';
6467
this.metaStub = sinon.mock()
65-
.withExactArgs('hostname', 'instance', 'https', 80, this.token, this.postFn, this.getFn, true)
68+
.withExactArgs({ hostname: 'hostname', instance: 'instance', protocol: 'https', port: 80, token: this.token, postFn: this.postFn, getFn: this.getFn, isBasic: true })
6669
.returns('meta1');
6770
this.btoa = sinon.mock()
6871
.withArgs(`${this.username}:${this.password}`)
@@ -76,6 +79,21 @@ describe('when loading the module', function() {
7679
});
7780
});
7881
});
82+
83+
describe('given no explicit credentials', () => {
84+
describe('when creating the SDK', () => {
85+
beforeEach(() => {
86+
this.metaStub = sinon.mock()
87+
.withExactArgs({ hostname: 'hostname', instance: 'instance', protocol: 'https', port: 80, postFn: this.postFn, getFn: this.getFn })
88+
.returns('meta1');
89+
RewireApi.__Rewire__('createMeta', this.metaStub);
90+
this.meta = this.setSecurity.withImplicitAuth();
91+
});
92+
it('it should return a Meta object with hostname, instance, port, protocol, post and get functions', () => {
93+
this.meta.should.equal('meta1');
94+
});
95+
});
96+
});
7997
});
8098
});
8199
});

0 commit comments

Comments
 (0)