Skip to content

Commit 1a387f4

Browse files
test example
1 parent 5f2b0bb commit 1a387f4

File tree

3 files changed

+282
-0
lines changed

3 files changed

+282
-0
lines changed

test/integration/flows/db.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
class DB {
2+
3+
constructor () {
4+
this.users = new Map();
5+
this.clients = [];
6+
this.accessTokens = new Map();
7+
this.refreshTokens= new Map();
8+
}
9+
10+
saveUser (user) {
11+
this.users.set(user.id, user);
12+
13+
return user;
14+
}
15+
16+
findUser (username, password) {
17+
return Array.from(this.users.values()).find(user => {
18+
return user.username === username && user.password === password;
19+
});
20+
}
21+
22+
findUserById (id) {
23+
return this.users.get(id);
24+
}
25+
26+
saveClient (client) {
27+
this.clients.push(client);
28+
29+
return client;
30+
}
31+
32+
findClient (clientId, clientSecret) {
33+
return this.clients.find(client => {
34+
if (clientSecret) {
35+
return client.id === clientId && client.secret === clientSecret;
36+
} else {
37+
return client.id === clientId;
38+
}
39+
});
40+
}
41+
42+
findClientById (id) {
43+
return this.clients.find(client => client.id === id);
44+
}
45+
46+
saveAccessToken (accessToken, meta) {
47+
this.accessTokens.set(accessToken, meta);
48+
}
49+
50+
findAccessToken (accessToken) {
51+
return this.accessTokens.get(accessToken);
52+
}
53+
54+
saveRefreshToken (refreshToken, meta) {
55+
this.refreshTokens.set(refreshToken, meta);
56+
}
57+
58+
findRefreshToken (refreshToken) {
59+
return this.refreshTokens.get(refreshToken);
60+
}
61+
}
62+
63+
const db = new DB();
64+
65+
module.exports = db;

test/integration/flows/model.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const db = require('./db');
2+
const scopes = ['read', 'write'];
3+
4+
async function getUser (username, password) {
5+
return db.findUser(username, password);
6+
}
7+
8+
async function getClient (clientId, clientSecret) {
9+
return db.findClient(clientId, clientSecret);
10+
}
11+
12+
async function saveToken (token, client, user) {
13+
const meta = {
14+
clientId: client.id,
15+
userId: user.id,
16+
scope: token.scope
17+
};
18+
19+
token.client = client;
20+
token.user = user;
21+
22+
if (token.accessToken) {
23+
db.saveAccessToken(token.accessToken, meta);
24+
}
25+
26+
if (token.refreshToken) {
27+
db.saveRefreshToken(token.refreshToken, meta);
28+
}
29+
30+
return token;
31+
}
32+
33+
async function getAccessToken (accessToken) {
34+
const meta = db.findAccessToken(accessToken);
35+
36+
return {
37+
accessToken,
38+
user: db.findUserById(meta.userId),
39+
client: db.findClientById(meta.clientId),
40+
scope: meta.scope
41+
};
42+
}
43+
44+
async function verifyScope (token, scope) {
45+
if (typeof scope === 'string') {
46+
return scopes.includes(scope);
47+
} else {
48+
return scope.every(s => scopes.includes(s));
49+
}
50+
}
51+
52+
const model = {
53+
getUser,
54+
getClient,
55+
saveToken,
56+
getAccessToken,
57+
verifyScope
58+
};
59+
60+
module.exports = model;
61+
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
const OAuth2Server = require('../../../');
2+
const db = require('./db');
3+
const model = require('./model');
4+
const Request = require('../../../lib/request');
5+
const Response = require('../../../lib/response');
6+
7+
require('chai').should();
8+
9+
const auth = new OAuth2Server({
10+
model: model
11+
});
12+
13+
const user = db.saveUser({ id: 1, username: 'test', password: 'test'});
14+
const client = db.saveClient({ id: 'a', secret: 'b', grants: ['password'] });
15+
const scope = 'read write';
16+
17+
function createDefaultRequest () {
18+
const request = new Request({
19+
body: {
20+
grant_type: 'password',
21+
client_id: client.id,
22+
client_secret: client.secret,
23+
username: user.username,
24+
password: user.password,
25+
scope
26+
},
27+
headers: {
28+
'content-type': 'application/x-www-form-urlencoded'
29+
},
30+
method: 'POST',
31+
query: {}
32+
});
33+
34+
request.is = function (header) {
35+
return this.headers['content-type'] === header;
36+
};
37+
38+
return request;
39+
}
40+
41+
describe('PasswordGrantType Integration Flow', function () {
42+
describe('Authenticate', function () {
43+
44+
it ('Succesfull authentication', async function () {
45+
const request = createDefaultRequest();
46+
const response = new Response({});
47+
48+
const token = await auth.token(request, response, {});
49+
response.body.token_type.should.equal('Bearer');
50+
response.body.access_token.should.equal(token.accessToken);
51+
response.body.refresh_token.should.equal(token.refreshToken);
52+
response.body.expires_in.should.be.a('number');
53+
response.body.scope.should.equal(scope);
54+
55+
token.accessToken.should.be.a('string');
56+
token.refreshToken.should.be.a('string');
57+
token.accessTokenExpiresAt.should.be.a('date');
58+
token.refreshTokenExpiresAt.should.be.a('date');
59+
token.scope.should.equal(scope);
60+
61+
db.accessTokens.has(token.accessToken).should.equal(true);
62+
db.refreshTokens.has(token.refreshToken).should.equal(true);
63+
});
64+
65+
it ('Username missing', async function () {
66+
const request = createDefaultRequest();
67+
const response = new Response({});
68+
69+
delete request.body.username;
70+
71+
await auth.token(request, response, {})
72+
.catch(err => {
73+
err.name.should.equal('invalid_request');
74+
});
75+
});
76+
77+
it ('Password missing', async function () {
78+
const request = createDefaultRequest();
79+
const response = new Response({});
80+
81+
delete request.body.password;
82+
83+
await auth.token(request, response, {})
84+
.catch(err => {
85+
err.name.should.equal('invalid_request');
86+
});
87+
});
88+
89+
it ('Wrong username', async function () {
90+
const request = createDefaultRequest();
91+
const response = new Response({});
92+
93+
request.body.username = 'wrong';
94+
95+
await auth.token(request, response, {})
96+
.catch(err => {
97+
err.name.should.equal('invalid_grant');
98+
});
99+
});
100+
101+
it ('Wrong password', async function () {
102+
const request = createDefaultRequest();
103+
const response = new Response({});
104+
105+
request.body.password = 'wrong';
106+
107+
await auth.token(request, response, {})
108+
.catch(err => {
109+
err.name.should.equal('invalid_grant');
110+
});
111+
});
112+
113+
it ('Client not found', async function () {
114+
const request = createDefaultRequest();
115+
const response = new Response({});
116+
117+
request.body.client_id = 'wrong';
118+
119+
await auth.token(request, response, {})
120+
.catch(err => {
121+
err.name.should.equal('invalid_client');
122+
});
123+
});
124+
125+
it ('Client secret not required', async function () {
126+
const request = createDefaultRequest();
127+
const response = new Response({});
128+
129+
delete request.body.client_secret;
130+
131+
const token = await auth.token(request, response, {
132+
requireClientAuthentication: {
133+
password: false
134+
}
135+
});
136+
137+
token.accessToken.should.be.a('string');
138+
});
139+
140+
it ('Client secret required', async function () {
141+
const request = createDefaultRequest();
142+
const response = new Response({});
143+
144+
delete request.body.client_secret;
145+
146+
await auth.token(request, response, {
147+
requireClientAuthentication: {
148+
password: false
149+
}
150+
})
151+
.catch(err => {
152+
err.name.should.equal('invalid_client');
153+
});
154+
});
155+
});
156+
});

0 commit comments

Comments
 (0)