Skip to content

Conversation

lane-wetmore
Copy link
Contributor

@lane-wetmore lane-wetmore commented Feb 27, 2025

Description

This is a culmination of PRs into this sidebranch which have been individually reviewed. These changes include enabling the TOTP secrets engine according to current design specs + tests.

TOTP.secrets.engine.mov

enterprise tests ✅

TODO only if you're a HashiCorp employee

  • Backport Labels: If this fix needs to be backported, use the appropriate backport/ label that matches the desired release branch. Note that in the CE repo, the latest release branch will look like backport/x.x.x, but older release branches will be backport/ent/x.x.x+ent.
    • LTS: If this fixes a critical security vulnerability or severity 1 bug, it will also need to be backported to the current LTS versions of Vault. To ensure this, use all available enterprise labels.
  • ENT Breakage: If this PR either 1) removes a public function OR 2) changes the signature
    of a public function, even if that change is in a CE file, double check that
    applying the patch for this PR to the ENT repo and running tests doesn't
    break any tests. Sometimes ENT only tests rely on public functions in CE
    files.
  • Jira: If this change has an associated Jira, it's referenced either
    in the PR description, commit message, or branch name.
  • RFC: If this change has an associated RFC, please link it in the description.
  • ENT PR: If this change has an associated ENT PR, please link it in the
    description. Also, make sure the changelog is in this PR, not in your ENT PR.

mpflanzer and others added 2 commits February 13, 2025 12:50
* TOTP secrets in the web UI

* Use credentials route to show TOTP code

* Refactor create and edit of TOTP keys

* TOTP model validation

* Add TOTP provider mode

* Use withExpandedAttributes in TOTP model

* Simplify attributes

* Make TOTP period optional

* Better TOTP editor labels

* Fix disabled attribute for select and checkbox
@github-actions github-actions bot added the hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed label Feb 27, 2025
Copy link

github-actions bot commented Feb 27, 2025

CI Results:
All Go tests succeeded! ✅

import ApplicationAdapter from './application';
import { encodePath } from 'vault/utils/path-encoding-helpers';

export default ApplicationAdapter.extend({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modernize this adapter to match current Ember patterns, confirm each method is actually necessary (and not just copy pasta)


.code-validity {
padding-left: $spacing-12;
cursor: unset;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure unset is necessary here? We can double check, but ideally it'd be nice to remove this component file and use generic css spacing helpers for the padding

import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

export default class SecretListItemComponent extends Component {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

component names should match the file

Suggested change
export default class SecretListItemComponent extends Component {
export default class TotpListItem extends Component {

Comment on lines 19 to 31
persist(method, successCallback) {
const model = this.model;
return model[method]().then(() => {
if (!model.isError) {
if (model.backend === 'totp' && model.generate) {
this.hasGenerated = true;
this.successCallback = successCallback;
} else {
successCallback(model);
}
}
});
}
Copy link
Contributor

@hellobontempo hellobontempo Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing a delete method specific for this item should remove the need for some conditionals here. But I'd still like to confirm what the intended functionality is here. Is this called when clicking "Delete" from the popup menu?

Also - why is hasGenerated something that needs to be tracked here?

})
backend;

@alias('account_name') name;
Copy link
Contributor

@hellobontempo hellobontempo Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the original intention here was to use account_name as name, but reviewing the docs they're separate parameters and some users may not want to use the same value for both.


@withModelValidations(validations)
@withExpandedAttributes()
export default class TotpModel extends Model {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to audit the params here and make sure they match the docs: https://developer.hashicorp.com/vault/api-docs/secret/totp

fieldValue: 'name',
editDisabled: true,
})
account_name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're inconsistent but typically use camel case syntax for model params accountName

Comment on lines 139 to 167
@computed('generate', function () {
const defaultFields = ['generate'];
const options = ['algorithm', 'digits', 'period'];
const providerOptions = [];

if (this.generate) {
providerOptions.push('key_size', 'skew', 'exported', 'qr_size');
} else {
defaultFields.push('url', 'key');
}

defaultFields.push('account_name', 'issuer');

const groups = [
{ default: defaultFields },
{
Options: [...options],
},
];

if (this.generate) {
groups.push({
'Provider options': [...providerOptions],
});
}

return this._expandGroups(groups);
})
fieldGroups;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newer pattern is to keep models "thin" and any form logic should be handled by the form component, not the model. Instead, we can use the @withFormFields decorator which will "expand" all of the model attributes into the form structure we want (with the options object that houses editType and all of that info).

The decorator can be called with args, like this: https://github.com/hashicorp/vault/blob/main/ui/app/models/pki/issuer.js#L27

@@ -335,7 +336,7 @@
{{else if (or (eq @attr.type "boolean") (eq @attr.options.editType "boolean"))}}
<div class="b-checkbox">
<input
disabled={{this.disabled}}
disabled={{and @attr.options.editDisabled (not @model.isNew)}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at the disabled getter in the component file shows that a @disabled arg can be passed in. we still need to account for that case and this logic should be added to the getter

We could then call this.disabled here and above. It might be worth updating the other areas of and @attr.options.editDisabled (not @model.isNew) so we're consistent (though as it is, not all inputs are even setup to accept a disabled arg...so the consistency is somewhat moot) This component file is always a challenge to balance keeping scope down without breaking backwards compatibility for an arg.

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { later, cancel } from '@ember/runloop';
Copy link
Contributor

@hellobontempo hellobontempo Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use ember-concurrency here instead as we want to move away from ember/runloop (docs)

there are some examples in the codebase but here are the docs

Copy link
Contributor

@hellobontempo hellobontempo Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file should be co-located and moved beside the generate-credentials-totp.js file. (the separate file trees was necessary pre ember-octane)

Copy link
Contributor

@hellobontempo hellobontempo Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file should be co-located and live beside totp-list-item.js (we'll want to double check that doesn't message with the rendering expectations for the generic <Component> helper the file path will be the same (secret-list/totp-list-item), so it should be fine

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be co-located as well (we'll want to double check that doesn't mess with the generator pattern and how these are rendered)

Comment on lines 29 to 30
{{did-insert this.startTimer}}
{{will-destroy this.cancelTimer}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with ember concurrency we shouldn't need these. the task can be initiated in the constructor() for the component and are automatically canceled when the component is torn down.

Comment on lines 61 to 62
algorithm;
@attr('number', {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: line break between each @attr

Suggested change
algorithm;
@attr('number', {
algorithm;
@attr('number', {

Comment on lines 68 to 71
@attr('string', {
editDisabled: true,
})
issuer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small attr options blocks can be on a single line

Suggested change
@attr('string', {
editDisabled: true,
})
issuer;
@attr('string', { editDisabled: true })
issuer;

@attr('number', {
possibleValues: SKEW,
//defaultValue: 1,
editDisabled: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like edit is disabled for all of these? we just hide disable edit higher up

lane-wetmore and others added 2 commits March 7, 2025 15:38
* a few changes to use newer extends pattern

* refactor totp adapter

* refactor generate-credentials-totp

* update component name

* refactor totp-edit

* update naming from totp to totp-key for clarity and convention

* update to use totp-key instead of totp

* break totp actions into separate components

* remove support for editing totp key

* move new totp code logic into generate credentials totp (fixes delay in new code)

* move hbs files to be alongside their js counterparts

* refactor totp model and update form fields decorator to handle combined groups

* Update ui/app/components/generate-credentials-totp.hbs

Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>

* remove unnecessary update method and improve method separation of concerns

* Update ui/app/components/generate-credentials-totp.js

Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>

* pass only relevant model data into component

* update totp credentials

* url improvement

* remove unnecessary cleanup method and move totp code generation

* add todo

* remove old totp code refresh

* update directory location and name

* combine conditionals

* remove unused code

* add todos

* update model id assignment

* move field display logic out of model

* combine display conditional blocks

* remove TOTP from unsupported engines list

---------

Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>
* update getter to return non generated or generated form fields

* update field text and labels to match design

* only show exported for generate and fix toggle

* add model validations and invalid form alert

* update validations to match doc specifications

* fix key validation

* fix validations

* add totp list item test

* add tests for creating vault provided key, navigating to details, and deleting key

* add jsdoc for totp-edit

* remove todo

* update jsdoc and convert create method to task

* fix stying

* make delete method async and remove persist

* make method names more clear

* remove extra div

* remove unneeded test selector

* update validators and messages

* use existing toggle button type

* add withExpandedAttributes back in

* move common logic into before each hook

* add test for non vault generated key

* use general selectors

* test improvements

* test improvements

* add success messages

* update assertion message

* update mountBackend to navigate to relevant page if not already there

* update doc

* fix model inconsistencies and update serializer

* remove extra css and reverse progress bar for totp code

* update naming

* pass group fields to serializer as well

* update tests

* remove mode and update naming for clarity

* remove comment

* remove unneeded css file

* remove unneeded mode getter, update docs, update delete fn and message

* update reset to be more resilient and rename arg

* update field naming for clarity and add back in  namespace reminder

* remove unneeded div, update test selector,  clean up

* clean up strings, remove unneeded labels,

* remove aliases for capabilities

* update and fix tests

* remove unneeded test file
lane-wetmore and others added 2 commits April 15, 2025 12:30
* match read key and generate code flow to design

* add qr code view to acceptance tests

* add component tests

* remove unneeded variables

* add backend and id

* updated tests

* flash error message in delete key

* move test selector

* add generate code link from details view

* update back button to be dynamic

* Update ui/tests/acceptance/secrets/backend/totp/key-test.js

Co-authored-by: Shannon Roberts (Beagin) <beagins@users.noreply.github.com>

* save id for success message and update routing for back button

---------

Co-authored-by: Shannon Roberts (Beagin) <beagins@users.noreply.github.com>
@lane-wetmore lane-wetmore marked this pull request as ready for review April 15, 2025 17:34
@lane-wetmore lane-wetmore requested a review from a team as a code owner April 15, 2025 17:34
Copy link

Build Results:
All builds succeeded! ✅

@lane-wetmore lane-wetmore requested a review from a team as a code owner April 16, 2025 16:21
@lane-wetmore lane-wetmore requested review from anurag925 and removed request for anurag925 April 16, 2025 16:21
const { totpCodePeriod } = this.args;

if (!totpCodePeriod) {
return 0; // TODO improve this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this TODO need to be addressed before we merge?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so. I think that code block shouldn't be possible to reach anymore as we should always have a totpCodePeriod, but I left it in to be safe for now.

Copy link
Contributor

@Monkeychip Monkeychip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not been too involved in this sidebranch process. There are a couple of small changes I was considering recommending, but I understand the background context to this sidebranch and know at this point it's about getting this functionality out to users. Nice work on this!

@lane-wetmore lane-wetmore merged commit 55674dd into main Apr 17, 2025
33 checks passed
@lane-wetmore lane-wetmore deleted the ui-totp-sidebranch branch April 17, 2025 17:59
@hellobontempo hellobontempo mentioned this pull request Jun 30, 2025
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hashicorp-contributed-pr If the PR is HashiCorp (i.e. not-community) contributed ui
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants