-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sidebranch: MFA end user setup (#15273)
* initial setup of components and route * fix navbar * replace parent component with controller * use auth service to return entity id * adapter and some error handling: * clean up adapter and handle warning * wip * use library for qrCode generation * clear warning and QR code display fix * flow for restart setup * add documentation * clean up * fix warning issue * handle root user * remove comment * update copy * fix margin * address comment
- Loading branch information
1 parent
b8dbd68
commit 4c585c9
Showing
18 changed files
with
318 additions
and
14 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import ApplicationAdapter from './application'; | ||
|
||
export default class MfaSetupAdapter extends ApplicationAdapter { | ||
adminGenerate(data) { | ||
let url = `/v1/identity/mfa/method/totp/admin-generate`; | ||
return this.ajax(url, 'POST', { data }); | ||
} | ||
|
||
adminDestroy(data) { | ||
let url = `/v1/identity/mfa/method/totp/admin-destroy`; | ||
return this.ajax(url, 'POST', { data }); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import Component from '@glimmer/component'; | ||
import { inject as service } from '@ember/service'; | ||
import { action } from '@ember/object'; | ||
import { tracked } from '@glimmer/tracking'; | ||
|
||
/** | ||
* @module MfaSetupStepOne | ||
* MfaSetupStepOne component is a child component used in the end user setup for MFA. It records the UUID (aka method_id) and sends a admin-generate request. | ||
* | ||
* @param {string} entityId - the entityId of the user. This comes from the auth service which records it on loading of the cluster. A root user does not have an entityId. | ||
* @param {function} isUUIDVerified - a function that consumes a boolean. Is true if the admin-generate is successful and false if it throws a warning or error. | ||
* @param {boolean} restartFlow - a boolean that is true that is true if the user should proceed to step two or false if they should stay on step one. | ||
* @param {function} saveUUIDandQrCode - A function that sends the inputted UUID and return qrCode from step one to the parent. | ||
* @param {boolean} showWarning - whether a warning is returned from the admin-generate query. Needs to be passed to step two. | ||
*/ | ||
|
||
export default class MfaSetupStepOne extends Component { | ||
@service store; | ||
@tracked error = ''; | ||
@tracked warning = ''; | ||
@tracked qrCode = ''; | ||
@action | ||
redirectPreviousPage() { | ||
this.args.restartFlow(); | ||
window.history.back(); | ||
} | ||
@action | ||
async verifyUUID(evt) { | ||
evt.preventDefault(); | ||
let response = await this.postAdminGenerate(); | ||
if (response === 'stop_progress') { | ||
this.args.isUUIDVerified(false); | ||
} else if (response === 'reset_method') { | ||
this.args.showWarning(this.warning); | ||
} else { | ||
this.args.isUUIDVerified(true); | ||
} | ||
} | ||
async postAdminGenerate() { | ||
this.error = ''; | ||
this.warning = ''; | ||
let adapter = this.store.adapterFor('mfa-setup'); | ||
let response; | ||
try { | ||
response = await adapter.adminGenerate({ | ||
entity_id: this.args.entityId, | ||
method_id: this.UUID, // comes from value on the input | ||
}); | ||
this.args.saveUUIDandQrCode(this.UUID, response.data?.url); | ||
// if there was a warning it won't fail but needs to be handled here and the flow needs to be interrupted | ||
let warnings = response.warnings || []; | ||
if (warnings.length > 0) { | ||
this.UUID = ''; // clear UUID | ||
const alreadyGenerated = warnings.find((w) => | ||
w.includes('Entity already has a secret for MFA method') | ||
); | ||
if (alreadyGenerated) { | ||
this.warning = | ||
'A QR code has already been generated, scanned, and MFA set up for this entity. If a new code is required, contact your administrator.'; | ||
return 'reset_method'; | ||
} | ||
this.warning = warnings; // in case other kinds of warnings comes through. | ||
return 'reset_method'; | ||
} | ||
} catch (error) { | ||
this.UUID = ''; // clear the UUID | ||
this.error = error.errors; | ||
return 'stop_progress'; | ||
} | ||
return response; | ||
} | ||
} |
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,40 @@ | ||
import Component from '@glimmer/component'; | ||
import { inject as service } from '@ember/service'; | ||
import { action } from '@ember/object'; | ||
|
||
/** | ||
* @module MfaSetupStepTwo | ||
* MfaSetupStepTwo component is a child component used in the end user setup for MFA. It displays a qrCode or a warning and allows a user to reset the method. | ||
* | ||
* @param {string} entityId - the entityId of the user. This comes from the auth service which records it on loading of the cluster. A root user does not have an entityId. | ||
* @param {string} uuid - the UUID that is entered in the input on step one. | ||
* @param {string} qrCode - the returned url from the admin-generate post. Used to create the qrCode. | ||
* @param {boolean} restartFlow - a boolean that is true that is true if the user should proceed to step two or false if they should stay on step one. | ||
* @param {string} warning - if there is a warning returned from the admin-generate post then it's sent to the step two component in this param. | ||
*/ | ||
|
||
export default class MfaSetupStepTwo extends Component { | ||
@service store; | ||
|
||
@action | ||
redirectPreviousPage() { | ||
this.args.restartFlow(); | ||
window.history.back(); | ||
} | ||
|
||
@action | ||
async restartSetup() { | ||
this.error = null; | ||
let adapter = this.store.adapterFor('mfa-setup'); | ||
try { | ||
await adapter.adminDestroy({ | ||
entity_id: this.args.entityId, | ||
method_id: this.args.uuid, | ||
}); | ||
} catch (error) { | ||
this.error = error.errors; | ||
return 'stop_progress'; | ||
} | ||
this.args.restartFlow(); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import Controller from '@ember/controller'; | ||
import { inject as service } from '@ember/service'; | ||
import { action } from '@ember/object'; | ||
import { tracked } from '@glimmer/tracking'; | ||
|
||
export default class VaultClusterMfaSetupController extends Controller { | ||
@service auth; | ||
@tracked onStep = 1; | ||
@tracked warning = ''; | ||
@tracked uuid = ''; | ||
@tracked qrCode = ''; | ||
get entityId() { | ||
return this.auth.authData.entity_id; | ||
} | ||
@action isUUIDVerified(verified) { | ||
this.warning = ''; // clear the warning, otherwise it persists. | ||
if (verified) { | ||
this.onStep = 2; | ||
} else { | ||
this.restartFlow(); | ||
} | ||
} | ||
|
||
@action | ||
restartFlow() { | ||
this.onStep = 1; | ||
} | ||
|
||
@action | ||
saveUUIDandQrCode(uuid, qrCode) { | ||
// qrCode could be an empty string if the admin-generate was not successful | ||
this.uuid = uuid; | ||
this.qrCode = qrCode; | ||
} | ||
|
||
@action | ||
showWarning(warning) { | ||
this.warning = warning; | ||
this.onStep = 2; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import Route from '@ember/routing/route'; | ||
|
||
export default class MfaSetupRoute extends Route {} |
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
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,26 @@ | ||
<p> | ||
TOTP Multi-factor authentication (MFA) can be enabled here if it is required by your administrator. This will ensure that | ||
you are not prevented from logging into Vault in the future, once MFA is fully enforced. | ||
</p> | ||
<form id="mfa-setup-step-one" {{on "submit" this.verifyUUID}}> | ||
<MessageError @errorMessage={{this.error}} class="has-top-margin-s" /> | ||
<div class="field has-top-margin-l"> | ||
<label class="is-label"> | ||
Method ID | ||
</label> | ||
|
||
{{! template-lint-disable no-autofocus-attribute}} | ||
<p class="sub-text">Enter the UUID for your multi-factor authentication method. This can be provided to you by your | ||
administrator.</p> | ||
<Input id="uuid" name="uuid" class="input" autocomplete="off" spellcheck="false" autofocus="true" @value={{this.UUID}} /> | ||
</div> | ||
|
||
<div class="is-flex-start has-gap"> | ||
<button id="continue" type="submit" class="button is-primary" disabled={{(is-empty-value this.UUID)}}> | ||
Verify | ||
</button> | ||
<button id="cancel" type="button" {{on "click" this.redirectPreviousPage}} class="button"> | ||
Cancel | ||
</button> | ||
</div> | ||
</form> |
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,35 @@ | ||
<p> | ||
TOTP Multi-factor authentication (MFA) can be enabled here if it is required by your administrator. This will ensure that | ||
you are not prevented from logging into Vault in the future, once MFA is fully enforced. | ||
</p> | ||
<div class="field has-top-margin-l"> | ||
<MessageError @errorMessage={{this.error}} class="has-top-margin-s" /> | ||
{{#if @warning}} | ||
<AlertBanner @type="info" @title="MFA enabled" @message={{@warning}} class="has-top-margin-l" /> | ||
{{else}} | ||
<div class="list-item-row"> | ||
<div class="center-display"> | ||
{{! template-lint-disable no-curly-component-invocation }} | ||
{{qr-code text=@qrCode colorLight="#F7F7F7" width=155 height=155 correctLevel="L"}} | ||
</div> | ||
</div> | ||
<div class="has-top-margin-s"> | ||
<div class="info-table-row has-no-shadow"> | ||
<div class="column info-table-row-edit"><Icon @name="alert-triangle-fill" class="has-text-highlight" /></div> | ||
<p class="is-size-8"> | ||
After you leave this page, this QR code will be removed and | ||
<strong>cannot</strong> | ||
be regenerated. | ||
</p> | ||
</div> | ||
</div> | ||
{{/if}} | ||
<div class="is-flex-start has-gap has-top-margin-l"> | ||
<button id="restart" type="button" class="button has-text-danger" {{on "click" this.restartSetup}}> | ||
Restart setup | ||
</button> | ||
<button id="cancel" type="button" {{on "click" this.redirectPreviousPage}} class="button is-primary"> | ||
Done | ||
</button> | ||
</div> | ||
</div> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<SplashPage @showTruncatedNavBar={{false}} as |Page|> | ||
<Page.header> | ||
<h1 class="title is-4">MFA setup</h1> | ||
</Page.header> | ||
<Page.content> | ||
<div class="auth-form" data-test-mfa-form> | ||
<div class="box"> | ||
{{#if (eq this.onStep 1)}} | ||
<MfaSetupStepOne | ||
@entityId={{this.entityId}} | ||
@isUUIDVerified={{this.isUUIDVerified}} | ||
@restartFlow={{this.restartFlow}} | ||
@saveUUIDandQrCode={{this.saveUUIDandQrCode}} | ||
@showWarning={{this.showWarning}} | ||
/> | ||
{{/if}} | ||
{{#if (eq this.onStep 2)}} | ||
<MfaSetupStepTwo | ||
@entityId={{this.entityId}} | ||
@uuid={{this.uuid}} | ||
@qrCode={{this.qrCode}} | ||
@restartFlow={{this.restartFlow}} | ||
@warning={{this.warning}} | ||
/> | ||
{{/if}} | ||
</div> | ||
</div> | ||
</Page.content> | ||
</SplashPage> |
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.