Skip to content

Commit 834d97b

Browse files
committed
add protocol claim filtering logic
1 parent e45e363 commit 834d97b

4 files changed

Lines changed: 125 additions & 8 deletions

File tree

src/UserInfoService.js

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import JsonService from './JsonService';
22
import MetadataService from './MetadataService';
33
import Log from './Log';
44

5-
export default class UserInfoService{
5+
const ProtocolClaims = ["nonce", "at_hash", "iat", "nbf", "exp", "aud", "iss"];
6+
7+
export default class UserInfoService {
68
constructor(settings, JsonServiceCtor = JsonService, MetadataServiceCtor = MetadataService) {
79
if (!settings) {
810
Log.error("No settings passed to UserInfoService");
@@ -13,8 +15,34 @@ export default class UserInfoService{
1315
this._jsonService = new JsonServiceCtor();
1416
this._metadataService = new MetadataServiceCtor(this._settings);
1517
}
16-
17-
getUserInfo(){
18-
return Promise.resolve();
18+
19+
getClaims(token) {
20+
Log.info("UserInfoService.getClaims");
21+
22+
if (!token) {
23+
Log.error("No token passed");
24+
return Promise.reject(new Error("A token is required"));
25+
}
26+
27+
return this._metadataService.getUserInfoUrl().then(url => {
28+
Log.info("received userinfo url", url);
29+
30+
return this._jsonService.getJson(url, token).then(claims => {
31+
Log.info("claims received", claims);
32+
33+
if (claims && this._settings.filterProtocolClaims) {
34+
ProtocolClaims.forEach(type => {
35+
delete claims[type];
36+
});
37+
38+
Log.info("protocol claims filtered", claims);
39+
}
40+
41+
return claims;
42+
});
43+
}, err => {
44+
Log.error("Failed to get claims", err);
45+
throw new Error("Failed to get claims");
46+
});
1947
}
2048
}

test/StubJsonService.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export default class StubJsonService {
2-
getJson(url) {
2+
getJson(url, token) {
33
this.url = url;
4+
this.token = token;
45
return this.result;
56
}
67
}

test/StubMetadataService.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default class StubMetadataService{
2+
getUserInfoUrl(){
3+
return this.userInfoUrlResult;
4+
}
5+
}

test/UserInfoService.spec.js

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Log from '../src/Log';
22
import UserInfoService from '../src/UserInfoService';
33

44
import StubJsonService from './StubJsonService';
5+
import StubMetadataService from './StubMetadataService';
56

67
import chai from 'chai';
78
chai.should();
@@ -11,11 +12,13 @@ describe("UserInfoService", function() {
1112
let subject;
1213
let settings;
1314
let stubJsonService;
15+
let stubMetadataService;
1416

1517
beforeEach(function() {
1618
settings = {};
1719
stubJsonService = new StubJsonService();
18-
subject = new UserInfoService(settings, ()=>stubJsonService);
20+
stubMetadataService = new StubMetadataService();
21+
subject = new UserInfoService(settings, () => stubJsonService, () => stubMetadataService);
1922
});
2023

2124
describe("constructor", function() {
@@ -32,10 +35,90 @@ describe("UserInfoService", function() {
3235

3336
});
3437

35-
describe("getUserInfo", function() {
38+
describe("getClaims", function() {
3639

3740
it("should return a promise", function() {
38-
subject.getUserInfo().should.be.instanceof(Promise);
41+
subject.getClaims().should.be.instanceof(Promise);
42+
});
43+
44+
it("should require a token", function(done) {
45+
subject.getClaims().then(null,
46+
err => {
47+
err.message.should.contain("token");
48+
done();
49+
});
50+
});
51+
52+
it("should call userinfo url and pass token", function(done) {
53+
stubMetadataService.userInfoUrlResult = Promise.resolve("http://sts/userinfo");
54+
stubJsonService.result = Promise.resolve("test");
55+
56+
subject.getClaims("token").then(claims => {
57+
stubJsonService.url.should.equal("http://sts/userinfo");
58+
stubJsonService.token.should.equal("token");
59+
done();
60+
});
61+
62+
});
63+
64+
it("should fail when dependencies fail", function(done) {
65+
stubMetadataService.userInfoUrlResult = Promise.reject("test");
66+
67+
subject.getClaims("token").then(null,
68+
err => {
69+
err.message.should.contain('claims');
70+
done();
71+
}
72+
);
73+
74+
});
75+
76+
it("should return claims", function(done) {
77+
stubMetadataService.userInfoUrlResult = Promise.resolve("http://sts/userinfo");
78+
stubJsonService.result = Promise.resolve({
79+
foo: 1, bar: 'test',
80+
aud:'some_aud', iss:'issuer',
81+
sub:'123', email:'foo@gmail.com',
82+
role:['admin', 'dev'],
83+
nonce:'nonce', at_hash:"athash",
84+
iat:5, nbf:10, exp:20
85+
});
86+
87+
subject.getClaims("token").then(claims => {
88+
claims.should.deep.equal({
89+
foo: 1, bar: 'test',
90+
aud:'some_aud', iss:'issuer',
91+
sub:'123', email:'foo@gmail.com',
92+
role:['admin', 'dev'],
93+
nonce:'nonce', at_hash:"athash",
94+
iat:5, nbf:10, exp:20
95+
});
96+
done();
97+
});
98+
99+
});
100+
101+
it("should filter protocol claims", function(done) {
102+
stubMetadataService.userInfoUrlResult = Promise.resolve("http://sts/userinfo");
103+
stubJsonService.result = Promise.resolve({
104+
foo: 1, bar: 'test',
105+
aud:'some_aud', iss:'issuer',
106+
sub:'123', email:'foo@gmail.com',
107+
role:['admin', 'dev'],
108+
nonce:'nonce', at_hash:"athash",
109+
iat:5, nbf:10, exp:20
110+
});
111+
settings.filterProtocolClaims = true;
112+
113+
subject.getClaims("token").then(claims => {
114+
claims.should.deep.equal({
115+
foo: 1, bar: 'test',
116+
sub:'123', email:'foo@gmail.com',
117+
role:['admin', 'dev']
118+
});
119+
done();
120+
});
121+
39122
});
40123

41124
});

0 commit comments

Comments
 (0)