Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
324 additions
and
56 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
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,51 +1,67 @@ | ||
import Model, { attr } from '@ember-data/model'; | ||
import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; | ||
import { withModelValidations } from 'vault/decorators/model-validations'; | ||
import PkiCertificateBaseModel from './certificate/base'; | ||
import { attr } from '@ember-data/model'; | ||
import { withFormFields } from 'vault/decorators/model-form-fields'; | ||
import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities'; | ||
|
||
const validations = { | ||
name: [ | ||
{ type: 'presence', message: 'Name is required.' }, | ||
{ | ||
type: 'containsWhiteSpace', | ||
message: 'Name cannot contain whitespace.', | ||
}, | ||
], | ||
}; | ||
@withFormFields(null, [ | ||
{ | ||
default: [ | ||
'certificate', | ||
'caChain', | ||
'commonName', | ||
'issuerName', | ||
'notValidBefore', | ||
'serialNumber', | ||
'keyId', | ||
'uriSans', | ||
'notValidAfter', | ||
], | ||
}, | ||
{ 'Issuer URLs': ['issuingCertificates', 'crlDistributionPoints', 'ocspServers', 'deltaCrlUrls'] }, | ||
]) | ||
export default class PkiIssuerModel extends PkiCertificateBaseModel { | ||
getHelpUrl(backend) { | ||
return `/v1/${backend}/issuer/example?help=1`; | ||
} | ||
|
||
@attr('string') issuerId; | ||
@attr('string', { displayType: 'masked' }) certificate; | ||
@attr('string', { displayType: 'masked', label: 'CA Chain' }) caChain; | ||
@attr('date', { | ||
label: 'Issue date', | ||
}) | ||
notValidBefore; | ||
|
||
@withModelValidations(validations) | ||
export default class PkiIssuerModel extends Model { | ||
@attr('string', { readOnly: true }) backend; | ||
@attr('string', { | ||
label: 'Issuer name', | ||
fieldValue: 'id', | ||
label: 'Default key ID', | ||
}) | ||
keyId; | ||
|
||
@attr({ | ||
label: 'Subject Alternative Names', | ||
}) | ||
name; | ||
uriSans; | ||
|
||
get useOpenAPI() { | ||
return true; | ||
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}`) issuerPath; | ||
@lazyCapabilities(apiPath`${'backend'}/root/rotate/exported`) rotateExported; | ||
@lazyCapabilities(apiPath`${'backend'}/root/rotate/internal`) rotateInternal; | ||
@lazyCapabilities(apiPath`${'backend'}/root/rotate/existing`) rotateExisting; | ||
@lazyCapabilities(apiPath`${'backend'}/intermediate/cross-sign`) crossSignPath; | ||
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}/sign-intermediate`) signIntermediate; | ||
get canRotateIssuer() { | ||
return ( | ||
this.rotateExported.get('canUpdate') !== false || | ||
this.rotateExisting.get('canUpdate') !== false || | ||
this.rotateInternal.get('canUpdate') !== false | ||
); | ||
} | ||
getHelpUrl(backend) { | ||
return `/v1/${backend}/issuer/example?help=1`; | ||
get canCrossSign() { | ||
return this.crossSignPath.get('canUpdate') !== false; | ||
} | ||
|
||
@attr('boolean') isDefault; | ||
@attr('string') issuerName; | ||
|
||
// Form Fields not hidden in toggle options | ||
_attributeMeta = null; | ||
get formFields() { | ||
if (!this._attributeMeta) { | ||
this._attributeMeta = expandAttributeMeta(this, [ | ||
'name', | ||
'leafNotAfterBehavior', | ||
'usage', | ||
'manualChain', | ||
'issuingCertifications', | ||
'crlDistributionPoints', | ||
'ocspServers', | ||
'deltaCrlUrls', // new endpoint, mentioned in RFC, but need to confirm it's there. | ||
]); | ||
} | ||
return this._attributeMeta; | ||
get canSignIntermediate() { | ||
return this.signIntermediate.get('canUpdate') !== false; | ||
} | ||
get canConfigure() { | ||
return this.issuerPath.get('canUpdate') !== false; | ||
} | ||
} |
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 @@ | ||
<Toolbar> | ||
<ToolbarActions> | ||
{{#if @canRotate}} | ||
<ToolbarLink @route="issuers.generate-root" @type="rotate-cw" @issuer={{@issuer.id}} data-test-pki-issuer-rotate-root> | ||
Rotate this root | ||
</ToolbarLink> | ||
{{/if}} | ||
{{#if @canCrossSign}} | ||
<ToolbarLink | ||
@route="issuers.issuer.cross-sign" | ||
@type="pen-tool" | ||
@issuer={{@issuer.id}} | ||
data-test-pki-issuer-cross-sign | ||
> | ||
Cross-sign Issuer | ||
</ToolbarLink> | ||
{{/if}} | ||
{{#if @canSignIntermediate}} | ||
<ToolbarLink @route="issuers.issuer.sign" @type="pen-tool" @issuer={{@issuer.id}} data-test-pki-issuer-sign-int> | ||
Sign Intermediate | ||
</ToolbarLink> | ||
{{/if}} | ||
<DownloadButton | ||
class="toolbar-link" | ||
@filename={{@issuer.id}} | ||
@data={{@issuer.certificate}} | ||
@extension="pem" | ||
data-test-issuer-download | ||
> | ||
Download | ||
<Chevron @direction="down" @isButton={{true}} /> | ||
</DownloadButton> | ||
{{#if @canConfigure}} | ||
<ToolbarLink @route="issuers.issuer.edit" @issuer={{@issuer.id}} data-test-pki-issuer-configure> | ||
Configure | ||
</ToolbarLink> | ||
{{/if}} | ||
</ToolbarActions> | ||
</Toolbar> | ||
|
||
<main data-test-issuer-details> | ||
{{#each @issuer.formFieldGroups as |fieldGroup|}} | ||
{{#each-in fieldGroup as |group fields|}} | ||
<div class="box is-sideless is-fullwidth is-shadowless" data-test-details-group={{group}}> | ||
{{#if (not-eq group "default")}} | ||
<h2 class="title is-5 has-margin-top" data-test-group-title> | ||
{{group}} | ||
</h2> | ||
{{/if}} | ||
{{#each fields as |attr|}} | ||
{{#if (eq attr.options.displayType "masked")}} | ||
<InfoTableRow @label={{or attr.options.label (humanize (dasherize attr.name))}} @value={{get @issuer attr.name}}> | ||
<MaskedInput | ||
@name={{or attr.options.label (humanize (dasherize attr.name))}} | ||
@value={{get @issuer attr.name}} | ||
@displayOnly={{true}} | ||
@allowCopy={{true}} | ||
/> | ||
</InfoTableRow> | ||
{{else if (eq attr.name "keyId")}} | ||
<InfoTableRow @label={{or attr.options.label (humanize (dasherize attr.name))}} @value={{get @issuer attr.name}}> | ||
<LinkTo @route="keys.key" @model={{get @issuer attr.name}}>{{get @issuer attr.name}}</LinkTo> | ||
</InfoTableRow> | ||
{{else}} | ||
<InfoTableRow | ||
@label={{or attr.options.label (humanize (dasherize attr.name))}} | ||
@value={{get @issuer attr.name}} | ||
@formatDate={{if (eq attr.type "date") "MMM d yyyy HH:mm:ss a zzzz"}} | ||
@alwaysRender={{true}} | ||
/> | ||
{{/if}} | ||
{{/each}} | ||
</div> | ||
{{/each-in}} | ||
{{/each}} | ||
|
||
</main> |
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 |
---|---|---|
@@ -1,3 +1,9 @@ | ||
import Route from '@ember/routing/route'; | ||
import PkiIssuerIndexRoute from './index'; | ||
|
||
export default class PkiIssuerDetailsRoute extends Route {} | ||
export default class PkiIssuerDetailsRoute extends PkiIssuerIndexRoute { | ||
// Details route gets issuer data from PkiIssuerIndexRoute | ||
setupController(controller, resolvedModel) { | ||
super.setupController(controller, resolvedModel); | ||
controller.breadcrumbs.push({ label: resolvedModel.id }); | ||
} | ||
} |
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 @@ | ||
import PkiIssuersListRoute from '../index'; | ||
|
||
// Single issuer index route extends issuers list route | ||
export default class PkiIssuerIndexRoute extends PkiIssuersListRoute { | ||
model() { | ||
const { issuer_ref } = this.paramsFor('issuers/issuer'); | ||
return this.store.queryRecord('pki/issuer', { | ||
backend: this.secretMountPath.currentPath, | ||
id: issuer_ref, | ||
}); | ||
} | ||
|
||
setupController(controller, resolvedModel) { | ||
super.setupController(controller, resolvedModel); | ||
const backend = this.secretMountPath.currentPath || 'pki'; | ||
controller.breadcrumbs = [ | ||
{ label: 'secrets', route: 'secrets', linkExternal: true }, | ||
{ label: backend, route: 'overview' }, | ||
{ label: 'issuers', route: 'issuers.index' }, | ||
]; | ||
} | ||
} |
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 |
---|---|---|
@@ -1 +1,18 @@ | ||
route: issuers.issuer.details | ||
<PageHeader as |p|> | ||
<p.top> | ||
<Page::Breadcrumbs @breadcrumbs={{this.breadcrumbs}} /> | ||
</p.top> | ||
<p.levelLeft> | ||
<h1 class="title is-3" data-test-pki-issuer-page-title> | ||
<Icon @name="file-text" @size="24" class="has-text-grey-light" /> | ||
View issuer certificate | ||
</h1> | ||
</p.levelLeft> | ||
</PageHeader> | ||
<Page::PkiIssuerDetails | ||
@issuer={{this.model}} | ||
@canRotate={{this.model.canRotateIssuer}} | ||
@canCrossSign={{this.model.canCrossSign}} | ||
@canSignIntermediate={{this.model.canSignIntermediate}} | ||
@canConfigure={{this.model.canConfigure}} | ||
/> |
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,11 @@ | ||
export const SELECTORS = { | ||
defaultGroup: '[data-test-details-group="default"]', | ||
urlsGroup: '[data-test-details-group="Issuer URLs"]', | ||
groupTitle: '[data-test-group-title]', | ||
row: '[data-test-component="info-table-row"]', | ||
rotateRoot: '[data-test-pki-issuer-rotate-root]', | ||
crossSign: '[data-test-pki-issuer-cross-sign]', | ||
signIntermediate: '[data-test-pki-issuer-sign-int]', | ||
download: '[data-test-issuer-download]', | ||
configure: '[data-test-pki-issuer-configure]', | ||
}; |
Oops, something went wrong.