-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PP-12395: Create API key functionality #4394
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 4 additions & 1 deletion
5
app/controllers/simplified-account/settings/api-keys/api-keys.controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,17 @@ | ||
const { response } = require('@utils/response') | ||
const apiKeysService = require('@services/api-keys.service') | ||
const formatSimplifiedAccountPathsFor = require('@utils/simplified-account/format/format-simplified-account-paths-for') | ||
const paths = require('@root/paths') | ||
|
||
async function get (req, res) { | ||
const activeKeys = await apiKeysService.getActiveKeys(req.account.id) | ||
return response(req, res, 'simplified-account/settings/api-keys/index', { | ||
accountType: req.account.type, | ||
activeKeys, | ||
createApiKeyLink: '#', | ||
createApiKeyLink: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.create, req.service.externalId, req.account.type), | ||
showRevokedKeysLink: '#' | ||
}) | ||
} | ||
|
||
module.exports = { get } | ||
module.exports.createApiKey = require('./create/create-api-key.controller') |
22 changes: 22 additions & 0 deletions
22
app/controllers/simplified-account/settings/api-keys/create/create-api-key.controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const { response } = require('@utils/response') | ||
const formatSimplifiedAccountPathsFor = require('@utils/simplified-account/format/format-simplified-account-paths-for') | ||
const paths = require('@root/paths') | ||
const { TOKEN_SOURCE, createApiKey } = require('@services/api-keys.service') | ||
|
||
async function get (req, res) { | ||
return response(req, res, 'simplified-account/settings/api-keys/api-key-name', { | ||
backLink: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, req.service.externalId, req.account.type) | ||
}) | ||
} | ||
|
||
async function post (req, res) { | ||
const description = req.body.description // TODO validate length - deal with this in another PR | ||
const newApiKey = await createApiKey(req.account, description, req.user.email, TOKEN_SOURCE.API) | ||
response(req, res, 'simplified-account/settings/api-keys/new-api-key-details', { | ||
description, | ||
apiKey: newApiKey, | ||
backToApiKeysLink: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, req.service.externalId, req.account.type) | ||
}) | ||
} | ||
|
||
module.exports = { get, post } |
81 changes: 81 additions & 0 deletions
81
...controllers/simplified-account/settings/api-keys/create/create-api-key.controller.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
const ControllerTestBuilder = require('@test/test-helpers/simplified-account/controllers/ControllerTestBuilder.class') | ||
const sinon = require('sinon') | ||
const { expect } = require('chai') | ||
const formatSimplifiedAccountPathsFor = require('@utils/simplified-account/format/format-simplified-account-paths-for') | ||
const paths = require('@root/paths') | ||
const { TOKEN_SOURCE } = require('@services/api-keys.service') | ||
|
||
const ACCOUNT_TYPE = 'live' | ||
const SERVICE_ID = 'service-id-123abc' | ||
const mockResponse = sinon.spy() | ||
const newApiKey = 'api_test_123' // pragma: allowlist secret | ||
const apiKeysService = { | ||
createApiKey: sinon.stub().resolves(newApiKey), | ||
TOKEN_SOURCE | ||
} | ||
|
||
const { | ||
req, | ||
res, | ||
nextRequest, | ||
call | ||
} = new ControllerTestBuilder('@controllers/simplified-account/settings/api-keys/create/create-api-key.controller') | ||
.withServiceExternalId(SERVICE_ID) | ||
.withAccountType(ACCOUNT_TYPE) | ||
.withStubs({ | ||
'@utils/response': { response: mockResponse }, | ||
'@services/api-keys.service': apiKeysService | ||
}) | ||
.build() | ||
|
||
describe('Controller: settings/create-api-key', () => { | ||
describe('get', () => { | ||
before(() => { | ||
call('get') | ||
}) | ||
|
||
it('should call the response method', () => { | ||
expect(mockResponse).to.have.been.calledOnce // eslint-disable-line | ||
}) | ||
|
||
it('should pass req, res, template path and context to the response method', () => { | ||
expect(mockResponse).to.have.been.calledWith(req, res, 'simplified-account/settings/api-keys/api-key-name', | ||
{ backLink: formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, SERVICE_ID, ACCOUNT_TYPE) }) | ||
}) | ||
}) | ||
|
||
describe('post', () => { | ||
before(() => { | ||
nextRequest({ | ||
body: { | ||
description: 'a test api key' | ||
}, | ||
user: { | ||
email: '[email protected]' | ||
} | ||
}) | ||
call('post') | ||
}) | ||
|
||
it('should submit values to the api keys service', () => { | ||
expect(apiKeysService.createApiKey).to.have.been.calledWith( | ||
sinon.match.any, | ||
'a test api key', | ||
'[email protected]', | ||
TOKEN_SOURCE.API | ||
) | ||
}) | ||
|
||
it('should call the response method', () => { | ||
expect(mockResponse).to.have.been.calledOnce // eslint-disable-line | ||
}) | ||
|
||
it('should pass context data to the response method', () => { | ||
expect(mockResponse.args[0][2]).to.equal('simplified-account/settings/api-keys/new-api-key-details') | ||
expect(mockResponse.args[0][3]).to.have.property('backToApiKeysLink').to.equal( | ||
formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.apiKeys.index, SERVICE_ID, ACCOUNT_TYPE)) | ||
expect(mockResponse.args[0][3]).to.have.property('apiKey').to.equal(newApiKey) | ||
expect(mockResponse.args[0][3]).to.have.property('description').to.equal('a test api key') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
app/views/simplified-account/settings/api-keys/api-key-name.njk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{% extends "../settings-layout.njk" %} | ||
|
||
{% block settingsPageTitle %} | ||
API key name | ||
{% endblock %} | ||
|
||
{% block settingsContent %} | ||
|
||
<h1 class="govuk-heading-l page-title">API key name</h1> | ||
|
||
<form id="api-key-name" method="post" novalidate> | ||
<input id="csrf" name="csrfToken" type="hidden" value="{{ csrf }}"/> | ||
|
||
{{ govukInput({ | ||
id: "description", | ||
name: "description", | ||
type: "text", | ||
attributes: { | ||
maxlength: "100" | ||
}, | ||
classes: "govuk-input--width-40", | ||
label: { | ||
text: "Add a description for the key" | ||
}, | ||
hint: { | ||
text: "For example, “John Smith’s API key”" | ||
} | ||
}) }} | ||
|
||
{{ govukButton({ | ||
text: "Continue" | ||
}) }} | ||
</form> | ||
{% endblock %} |
69 changes: 69 additions & 0 deletions
69
app/views/simplified-account/settings/api-keys/new-api-key-details.njk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
{% extends "../settings-layout.njk" %} | ||
|
||
{% block settingsPageTitle %} | ||
New API key | ||
{% endblock %} | ||
|
||
{% block settingsContent %} | ||
|
||
{{ govukBackLink({ | ||
text: "Back to API keys", | ||
href: backToApiKeysLink | ||
}) }} | ||
|
||
<h1 class="govuk-heading-l page-title">New API key</h1> | ||
|
||
{% set html %} | ||
<p class="govuk-body"> | ||
Copy your key to somewhere safe.</br></br>You won’t be able to see it again once you leave this page. | ||
</p> | ||
{% endset %} | ||
|
||
{{ govukInsetText({ | ||
html: html | ||
}) }} | ||
|
||
<p class="govuk-body"> | ||
You must copy the whole key, including the <span class="key-prefix">api_test_</span> or <span class="key-prefix">api_live_</span> prefix. | ||
</p> | ||
|
||
{{ govukWarningText( | ||
{ | ||
text: 'API security', | ||
iconFallbackText: 'Warning' | ||
} | ||
) }} | ||
|
||
<ul class="govuk-list govuk-list--bullet"> | ||
<li>You must store your API keys securely.</li> | ||
<li>You must not share this key in publicly accessible documents or repositories.</li> | ||
<li>You must not share it with anyone who should not be using the GOV.UK Pay API directly.</li> | ||
</ul> | ||
|
||
<p class="govuk-body"> | ||
More about <a class="govuk-link" href="https://docs.payments.service.gov.uk/security/#securing-your-developer-keys"> | ||
securing your API keys</a>. | ||
</p> | ||
|
||
<h2 class="govuk-heading-m"> | ||
{{ description }} | ||
</h2> | ||
<div> | ||
<span id="apiKey" class="code copy-this-api-key govuk-!-margin-top-6">{{ apiKey }}</span> | ||
</div> | ||
|
||
{{ govukButton({ | ||
text: "Copy API key to clipboard", | ||
classes: "govuk-button--secondary govuk-!-margin-top-6", | ||
attributes: { | ||
id: "generate-button", | ||
"data-copy-text": true, | ||
"data-target": "copy-this-api-key", | ||
"data-success": "API key has been copied", | ||
"data-notification-target": "copy-this-api-key-notification" | ||
} | ||
}) }} | ||
|
||
<div class="copy-this-api-key-notification govuk-visually-hidden" aria-live="assertive"></div> | ||
|
||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it's better or worse to allow for customising the back link text, e.g. if a
backLinkText
variable is provided in the context then it will override the text. I'll leave that up to you, just a thoughtThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth doing if I encounter more back links that don't have the text "Back". Going to leave this for now.