Skip to content

Commit

Permalink
completed tests for authorize route
Browse files Browse the repository at this point in the history
  • Loading branch information
sohamkamani committed May 9, 2020
1 parent ee788c9 commit 529cd27
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 10 deletions.
2 changes: 1 addition & 1 deletion assets/authorization-server/login.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<title>Login Page</title>
</head>
<body>
<p>
Expand Down
2 changes: 1 addition & 1 deletion authorization-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,4 @@ const server = app.listen(config.port, "localhost", function () {

// for testing purposes

module.exports = { app }
module.exports = { app, requests }
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "",
"main": "client.js",
"scripts": {
"test": "mocha ./test/**/*"
"test": "mocha ./test/**/*",
"test-dev": "mocha --watch ./test/**/*"
},
"repository": {
"type": "git",
Expand Down
3 changes: 3 additions & 0 deletions tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@

1. **Creating the authorization route** - In `authorization-server.js` create a new empty server route that accepts `GET` requests to the `/authorize` endpoint using the `app.get` method. The empty route should return a `200` status by default, using the `res.end()` method.
2. **Verifying the client ID** - Next, get the `client_id` param from the `req.query` object and verify if the client ID exists by checking the `clients` object in the same file. If the client ID does not exist, respond with a `401` status code using the `res.status` method. If the
3. **Validating the scopes requested** - After the client ID is validated, we need to ensure that the requested scopes are a subset of the allowed scopes for the client. For example, the client with ID `"my-client"` is allowed to request for the `"permission:name"`, and the `"permission:date_of_birth"` scopes. The requested scopes are available in the `req.query.scopes` parameter as a space separated string. We can split this string into it's individual scopes by using the `req.query.scope.split(" ")` method. You can use the `containsAll(arg1, arg2)` function imported from the `utils.js` file to check if the array `arg1` contains all the elements of the array `arg2`. If requested scopes are not a subset of the allowed scopes, return a `401` status code.
4. **Storing the request** - Now that we have verified all the client credentials and scope, we need to create a request ID and temporarily store the request object to use in the next section. You can see an empty `requests` object already declared in the file. We need to create a random string as the request ID, which will be the key stored in the `requests` object, with the value being the `request.query` object. To help you generate a random string, you can use the `randomString()` function in the `utils.js` file.
5. **Rendering the login page** - We now need to render the login page for the user to login to our system. You can render the login page using the `res.render(page, params)`. The `page` argument can be set to `"login"` which will render the `assets/authorization-server/login.ejs` template file. The `params` argument is needed to supply parameters to the template file.
5 changes: 0 additions & 5 deletions test/module1/create-authorization-route.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,5 @@ it("serves an empty authorize route @authorization-server-create-authorize-route
.get("/authorize")
.then((res) => {
assert.notEqual(res.status, 404, "The `/authorize` route doesn't exist")
assert.equal(
res.status,
200,
"The `/authorize` route should return a 200 status by default"
)
})
})
30 changes: 30 additions & 0 deletions test/module1/render-login-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const assert = require("assert")
const request = require("supertest")

const { app, requests } = require("../../authorization-server")
const { deleteAllKeys } = require("../../utils")

it("renders login page on successful request @authorization-server-render-login", () => {
deleteAllKeys(requests)
return request(app)
.get("/authorize?client_id=my-client&scope=permission:name")
.then((res) => {
assert.equal(
res.header["content-type"],
"text/html; charset=utf-8",
"The response doesn't seem to be an HTML page"
)
assert.equal(
res.text.indexOf(`<title>Login Page</title>`) >= 0,
true,
"The returned page doesn't seem to be the login page"
)
assert.equal(
res.text.indexOf(
`Hi! You are logged in. Would you like to approve Sample Client`
) >= 0,
true,
"Looks like the client parameter wasn't passed as a template variable"
)
})
})
30 changes: 30 additions & 0 deletions test/module1/store-request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const assert = require("assert")
const request = require("supertest")

const { app, requests } = require("../../authorization-server")
const { deleteAllKeys } = require("../../utils")

it("stores the request in local memory @authorization-server-store-request", () => {
deleteAllKeys(requests)
return request(app)
.get("/authorize?client_id=my-client&scope=permission:name")
.then((res) => {
const keys = Object.keys(requests)
assert.equal(
keys.length,
1,
"Only a single request object should be stored in the `requests` variable for each request made"
)
const storedRequest = requests[keys[0]]
assert.equal(
storedRequest.client_id,
"my-client",
"the stored request object should contain the client ID"
)
assert.equal(
storedRequest.scope,
"permission:name",
"the stored request object should contain the client scope"
)
})
})
28 changes: 28 additions & 0 deletions test/module1/validate-scope.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const assert = require("assert")
const request = require("supertest")

const { app } = require("../../authorization-server")

it("returns a 200 for a valid scope @authorization-server-validate-scope", () => {
return request(app)
.get("/authorize?client_id=my-client&scope=permission:name")
.then((res) => {
assert.notEqual(res.status, 404, "The `/authorize` route doesn't exist")
assert.equal(
res.status,
200,
"The `/authorize` route should return a 200 status if the client ID is valid"
)

return request(app).get(
"/authorize?client_id=my-client&scope=permission:password"
)
})
.then((res) => {
assert.equal(
res.status,
401,
"The `/authorize` route should return a 401 status if the requested scope isn't allowed for the given client ID"
)
})
})
4 changes: 2 additions & 2 deletions test/module1/verify-client-id.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ const request = require("supertest")

const { app } = require("../../authorization-server")

it("serves an empty authorize route @authorization-server-verify-client-id", () => {
it("returns a 200 for a valid client ID @authorization-server-verify-client-id", () => {
return request(app)
.get("/authorize?client_id=my-client")
.get("/authorize?client_id=my-client&scope=permission:name")
.then((res) => {
assert.notEqual(res.status, 404, "The `/authorize` route doesn't exist")
assert.equal(
Expand Down
7 changes: 7 additions & 0 deletions utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ function decodeAuthCredentials(auth) {
return { clientId, clientSecret }
}

function deleteAllKeys(obj) {
Object.keys(obj).forEach((k) => {
delete obj[k]
})
}

module.exports = {
randomString,
containsAll,
decodeAuthCredentials,
deleteAllKeys,
}

0 comments on commit 529cd27

Please sign in to comment.