Skip to content

Commit 24aecdc

Browse files
authored
Merge pull request #14 from marttinen/3.3.0-rc
Support hapi auth "modes"
2 parents 43c28b5 + 7b01e33 commit 24aecdc

11 files changed

+92
-29
lines changed

src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,15 @@ async function handleKeycloakValidation (tkn, h) {
139139
* @throws {Boom.unauthorized} If header is missing or has an invalid format
140140
*/
141141
async function validate (field, h = (data) => data) {
142+
if (!field) {
143+
throw raiseUnauthorized(errorMessages.missing)
144+
}
145+
142146
const tkn = token.create(field)
143147
const reply = fakeToolkit(h)
144148

145149
if (!tkn) {
146-
throw raiseUnauthorized(errorMessages.missing)
150+
throw raiseUnauthorized(errorMessages.invalid)
147151
}
148152

149153
const cached = await cache.get(store, tkn)

src/utils.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,15 @@ function verify (opts) {
117117
* @returns {Boom.unauthorized} The created `Boom` error
118118
*/
119119
function raiseUnauthorized (error, reason, scheme = 'Bearer') {
120-
return boom.unauthorized(null, scheme, {
121-
strategy: 'keycloak-jwt',
122-
...(error ? { error } : {}),
123-
...(reason && error !== reason ? { reason } : {})
124-
})
120+
return boom.unauthorized(
121+
error !== errorMessages.missing ? error : null,
122+
scheme,
123+
{
124+
strategy: 'keycloak-jwt',
125+
...(error === errorMessages.missing ? { error } : {}),
126+
...(reason && error !== reason ? { reason } : {})
127+
}
128+
)
125129
}
126130

127131
/**
@@ -132,7 +136,7 @@ function raiseUnauthorized (error, reason, scheme = 'Bearer') {
132136
*/
133137
const errorMessages = {
134138
invalid: 'Invalid credentials',
135-
missing: 'Missing or invalid authorization header',
139+
missing: 'Missing authorization header',
136140
rpt: 'Retrieving the RPT failed',
137141
apiKey: 'Retrieving the token with the api key failed'
138142
}

test/_helpers.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,32 @@ function registerRoutes (server) {
184184
}
185185
}
186186
}
187+
},
188+
{
189+
method: 'GET',
190+
path: '/mode-optional',
191+
options: {
192+
auth: { strategy: 'keycloak-jwt', mode: 'optional' },
193+
handler (req) {
194+
return {
195+
headers: req.headers,
196+
query: req.query
197+
}
198+
}
199+
}
200+
},
201+
{
202+
method: 'GET',
203+
path: '/mode-try',
204+
options: {
205+
auth: { strategy: 'keycloak-jwt', mode: 'try' },
206+
handler (req) {
207+
return {
208+
headers: req.headers,
209+
query: req.query
210+
}
211+
}
212+
}
187213
}
188214
])
189215
}

test/index.entitlement.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ test('authentication does fail – invalid token', async (t) => {
8484

8585
t.truthy(res)
8686
t.is(res.statusCode, 401)
87-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials", reason="Retrieving the RPT failed"')
87+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", reason="Retrieving the RPT failed", error="Invalid credentials"')
8888
})
8989

9090
test('authentication does fail – invalid header', async (t) => {
@@ -95,5 +95,5 @@ test('authentication does fail – invalid header', async (t) => {
9595

9696
t.truthy(res)
9797
t.is(res.statusCode, 401)
98-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Missing or invalid authorization header"')
98+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials"')
9999
})

test/index.hapi-modes.spec.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const nock = require('nock')
2+
const test = require('ava')
3+
const helpers = require('./_helpers')
4+
const fixtures = require('./fixtures')
5+
6+
const cfg = helpers.getOptions({ secret: fixtures.common.secret })
7+
8+
test.afterEach.always('reset instances and prototypes', () => {
9+
nock.cleanAll()
10+
})
11+
12+
test('server method – authentication supports mode: "optional" - will succeed without auth', async (t) => {
13+
const server = await helpers.getServer(cfg)
14+
const res = await server.inject({
15+
method: 'GET',
16+
url: '/mode-optional'
17+
})
18+
19+
t.truthy(res)
20+
t.is(res.statusCode, 200)
21+
})
22+
23+
test('server method – authentication supports mode: "optional" - will fail with invalid auth', async (t) => {
24+
const mockReq = helpers.mockRequest(fixtures.common.token, '/mode-optional')
25+
const server = await helpers.getServer(cfg)
26+
const res = await server.inject(mockReq)
27+
28+
t.truthy(res)
29+
t.is(res.statusCode, 401)
30+
})
31+
32+
test('server method – authentication supports mode: "try" - will succeed with invalid auth', async (t) => {
33+
const mockReq = helpers.mockRequest(fixtures.common.token, '/mode-try')
34+
const server = await helpers.getServer(cfg)
35+
const res = await server.inject(mockReq)
36+
37+
t.truthy(res)
38+
t.is(res.statusCode, 200)
39+
})

test/index.introspect.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,5 @@ test('authentication does fail – invalid header', async (t) => {
7777

7878
t.truthy(res)
7979
t.is(res.statusCode, 401)
80-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Missing or invalid authorization header"')
80+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials"')
8181
})

test/index.server.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ test('server method – authentication does fail – invalid header', async (t)
5252
t.truthy(err)
5353
t.truthy(err.isBoom)
5454
t.is(err.output.statusCode, 401)
55-
t.is(err.output.headers['WWW-Authenticate'], 'Bearer strategy="keycloak-jwt", error="Missing or invalid authorization header"')
55+
t.is(err.output.headers['WWW-Authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials"')
5656
})
5757

5858
test('server method – authentication does fail – error', async (t) => {

test/index.verify.buffer.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ test('authentication does fail – expired token', async (t) => {
4949

5050
t.truthy(res)
5151
t.is(res.statusCode, 401)
52-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials", reason="invalid token (expired)"')
52+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", reason="invalid token (expired)", error="Invalid credentials"')
5353
})
5454

5555
test('authentication does fail – invalid header', async (t) => {
@@ -59,5 +59,5 @@ test('authentication does fail – invalid header', async (t) => {
5959

6060
t.truthy(res)
6161
t.is(res.statusCode, 401)
62-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Missing or invalid authorization header"')
62+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials"')
6363
})

test/index.verify.jwk.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ test('authentication does fail – expired token', async (t) => {
5353

5454
t.truthy(res)
5555
t.is(res.statusCode, 401)
56-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials", reason="invalid token (expired)"')
56+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", reason="invalid token (expired)", error="Invalid credentials"')
5757
})
5858

5959
test('authentication does fail – invalid header', async (t) => {
@@ -63,5 +63,5 @@ test('authentication does fail – invalid header', async (t) => {
6363

6464
t.truthy(res)
6565
t.is(res.statusCode, 401)
66-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Missing or invalid authorization header"')
66+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials"')
6767
})

test/index.verify.pem.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ test('authentication does fail – expired token', async (t) => {
4949

5050
t.truthy(res)
5151
t.is(res.statusCode, 401)
52-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials", reason="invalid token (expired)"')
52+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", reason="invalid token (expired)", error="Invalid credentials"')
5353
})
5454

5555
test('authentication does fail – invalid header', async (t) => {
@@ -59,5 +59,5 @@ test('authentication does fail – invalid header', async (t) => {
5959

6060
t.truthy(res)
6161
t.is(res.statusCode, 401)
62-
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Missing or invalid authorization header"')
62+
t.is(res.headers['www-authenticate'], 'Bearer strategy="keycloak-jwt", error="Invalid credentials"')
6363
})

0 commit comments

Comments
 (0)