-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Enforcement view at MFA method level #15485
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import Controller from '@ember/controller'; | ||
import { inject as service } from '@ember/service'; | ||
import { action } from '@ember/object'; | ||
|
||
export default class MfaMethodController extends Controller { | ||
@service router; | ||
@service flashMessages; | ||
|
||
queryParams = ['tab']; | ||
tab = 'config'; | ||
|
||
@action | ||
async deleteMethod() { | ||
try { | ||
await this.model.method.destroyRecord(); | ||
this.flashMessages.success('MFA method deleted successfully deleted.'); | ||
this.router.transitionTo('vault.cluster.access.mfa.methods'); | ||
} catch (error) { | ||
this.flashMessages.danger(`There was an error deleting this MFA method.`); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,22 @@ | ||
import Route from '@ember/routing/route'; | ||
|
||
import { hash } from 'rsvp'; | ||
export default class MfaMethodRoute extends Route { | ||
model({ id }) { | ||
return this.store.findRecord('mfa-method', id); | ||
return hash({ | ||
method: this.store.findRecord('mfa-method', id).then((data) => data), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what if no record can be found? could that situation happen? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After looking into the documentation for With that said, I think a method can exist on it's own which makes the result of the promise to fetch enforcements not required to load the route. Since you are swallowing the error it shouldn't be a problem here but just wanted to provide a bit of background on this pattern. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup hash acts similar to Promise all. But yeah since error is being swallowed, even if enforcements are not present, it will work fine. |
||
enforcements: this.store | ||
.query('mfa-login-enforcement', {}) | ||
.then((data) => { | ||
let filteredEnforcements = data.filter((item) => { | ||
let results = item.hasMany('mfa_methods').ids(); | ||
return results.includes(id); | ||
}); | ||
return filteredEnforcements; | ||
}) | ||
.catch(() => { | ||
// Do nothing | ||
}), | ||
}); | ||
} | ||
setupController(controller, model) { | ||
controller.set('model', model); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<LinkedBlock class="list-item-row" @params={{array "vault.cluster.access.mfa.enforcements.enforcement" @model.id}}> | ||
<div class="level is-mobile"> | ||
<div class="level-left"> | ||
<div> | ||
<Icon @name="lock" /> | ||
<span class="has-text-weight-semibold has-text-black"> | ||
{{@model.name}} | ||
</span> | ||
</div> | ||
</div> | ||
<div class="level-right is-flex is-paddingless is-marginless"> | ||
<div class="level-item"> | ||
<PopupMenu> | ||
<nav class="menu"> | ||
<ul class="menu-list"> | ||
<li> | ||
<LinkTo @route="vault.cluster.access.mfa.enforcements.enforcement" @model={{@model.name}}> | ||
Details | ||
</LinkTo> | ||
</li> | ||
<li> | ||
<LinkTo @route="vault.cluster.access.mfa.enforcements.enforcement.edit" @model={{@model.name}}> | ||
Edit | ||
</LinkTo> | ||
</li> | ||
</ul> | ||
</nav> | ||
</PopupMenu> | ||
</div> | ||
</div> | ||
</div> | ||
</LinkedBlock> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,78 @@ | ||
<PageHeader as |p|> | ||
<p.levelLeft> | ||
<h1 class="title is-3"> | ||
<Icon @size="24" @name={{this.model.type}} /> | ||
{{this.model.name}} | ||
<Icon @size="24" @name={{this.model.method.type}} /> | ||
{{this.model.method.name}} | ||
</h1> | ||
</p.levelLeft> | ||
</PageHeader> | ||
|
||
<Toolbar> | ||
<ToolbarActions> | ||
<ToolbarLink @params={{array "vault.cluster.access.mfa.methods.method.edit" this.model.id}}> | ||
Edit | ||
</ToolbarLink> | ||
</ToolbarActions> | ||
</Toolbar> | ||
<div class="tabs-container box is-sideless is-fullwidth is-paddingless is-marginless"> | ||
<nav class="tabs"> | ||
<ul> | ||
<LinkTo @route="vault.cluster.access.mfa.methods.method" @query={{hash tab="config"}}> | ||
Configuration | ||
</LinkTo> | ||
<LinkTo @route="vault.cluster.access.mfa.methods.method" @query={{hash tab="enforcements"}}> | ||
Enforcements | ||
</LinkTo> | ||
</ul> | ||
</nav> | ||
</div> | ||
|
||
<div class="box is-fullwidth is-sideless is-paddingless is-marginless"> | ||
{{#each this.model.attrs as |attr|}} | ||
{{#if (eq attr.type "object")}} | ||
<InfoTableRow | ||
@alwaysRender={{not (is-empty-value (get @model attr.name))}} | ||
@label={{or attr.options.label (to-label attr.name)}} | ||
@value={{stringify (get @model attr.name)}} | ||
{{#if (eq this.tab "config")}} | ||
<Toolbar> | ||
<ToolbarActions> | ||
<ConfirmAction | ||
@buttonClasses="toolbar-link" | ||
@disabled={{not (is-empty this.model.enforcements)}} | ||
@onConfirmAction={{this.deleteMethod}} | ||
@confirmTitle="Are you sure?" | ||
@confirmMessage="Deleting this MFA configuration is permanent, and it will no longer be available." | ||
@confirmButtonText="Delete" | ||
> | ||
Delete | ||
</ConfirmAction> | ||
<ToolbarLink @params={{array "vault.cluster.access.mfa.methods.method.edit" this.model.method.id}}> | ||
Edit | ||
</ToolbarLink> | ||
</ToolbarActions> | ||
</Toolbar> | ||
<div class="box is-fullwidth is-sideless is-paddingless is-marginless"> | ||
{{#each this.model.method.attrs as |attr|}} | ||
{{#if (eq attr.type "object")}} | ||
<InfoTableRow | ||
@alwaysRender={{not (is-empty-value (get this.model.method attr.name))}} | ||
@label={{or attr.options.label (to-label attr.name)}} | ||
@value={{stringify (get this.model.method attr.name)}} | ||
/> | ||
{{else}} | ||
<InfoTableRow | ||
@alwaysRender={{not (is-empty-value (get this.model.method attr.name))}} | ||
@label={{or attr.options.label (to-label attr.name)}} | ||
@value={{get this.model.method attr.name}} | ||
/> | ||
{{/if}} | ||
{{/each}} | ||
</div> | ||
{{else if (eq this.tab "enforcements")}} | ||
<Toolbar> | ||
<ToolbarActions> | ||
<ToolbarLink @type="add" @params={{array "vault.cluster.access.mfa.enforcements.create"}}> | ||
New enforcement | ||
</ToolbarLink> | ||
</ToolbarActions> | ||
</Toolbar> | ||
<div class="box is-fullwidth is-sideless is-paddingless is-marginless"> | ||
{{#if (is-empty this.model.enforcements)}} | ||
<EmptyState | ||
@title="No enforcements found." | ||
@message="No enforcements are applied to this MFA method. Edit an existing enforcement or add a new one to get started." | ||
/> | ||
{{else}} | ||
<InfoTableRow | ||
@alwaysRender={{not (is-empty-value (get @model attr.name))}} | ||
@label={{or attr.options.label (to-label attr.name)}} | ||
@value={{get @model attr.name}} | ||
/> | ||
{{#each this.model.enforcements as |item|}} | ||
<Mfa::LoginEnforcementListItem @model={{item}} /> | ||
{{/each}} | ||
{{/if}} | ||
{{/each}} | ||
</div> | ||
</div> | ||
{{/if}} |
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.
Jordan might have some thoughts on Hash. I think there's a work around he mentioned, but I know we're under a time crunch so this is more of a if you're interested reach out to him about it.