-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
UI/update auth form to fetchRoles after a namespace is inputted, prior to OIDC auth #19541
UI/update auth form to fetchRoles after a namespace is inputted, prior to OIDC auth #19541
Conversation
Thanks for going after this. I know we're waiting for an AD FS environment, but a reminder to add the backport labels. |
This is a different bug actually, so no need to wait for AD FS to reproduce. There aren't release milestone tags made for the next patch version yet - so holding off on adding PR tags until they've been created. Should have mentioned this! |
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.
🚀
try { | ||
await this.fetchRole.perform(this.roleName, { debounce: false }); | ||
} catch (error) { | ||
// this task could be cancelled if the instances in didReceiveAttrs resolve after this was started | ||
if (error?.name !== 'TaskCancelation') { | ||
throw error; | ||
} | ||
} |
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 can't see an issue with moving this above the conditional. If anything, since a role is required it should have come before in the first place to ensure we have the necessary data.
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.
That's my understanding? I'm guessing it wasn't above before because firing it off in didReceiveAttrs
seems like it'd be sufficient. Unfortunately the conditionals that wrap fetchRole
in that function don't account for the namespace updating
@@ -32,18 +32,16 @@ | |||
</li> | |||
{{/let}} | |||
{{/each}} | |||
{{#if this.hasMethodsWithPath}} |
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.
This condition is already wrapped higher up correct? It looks like removing it is the only change here.
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.
Yeah - meant to comment. It looked like this was redundant? So removed to clean it up - but want to make sure I'm not misreading...
@@ -88,4 +89,90 @@ module('Acceptance | Enterprise | namespaces', function (hooks) { | |||
'Does not prepend root to namespace' | |||
); | |||
}); | |||
|
|||
module('auth form', function (hooks) { |
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 don't think I've seen modules nested in other modules before. Neat idea!
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 copied @hashishaw 's idea from the pki tests, thought it was a neat way to organize. (And make the setup reusable if/when we add more namespace tests?) : https://github.com/hashicorp/vault/blob/main/ui/tests/acceptance/pki/pki-engine-workflow-test.js#L154
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.
🎉
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.
A couple smol comments. Great test coverage and comments!
|
||
module('auth form', function (hooks) { | ||
setupMirage(hooks); | ||
const SELECTORS = { |
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.
Usually these live outside of the module, not sure if it's necessary but this here caught me off guard
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.
Yeah I didn't know what to do with the module in a module situation? Should I move them just outside this module? or outside the "parent" module?
}); | ||
await visit('/vault/auth?with=oidc%2F'); | ||
assert.dom(SELECTORS.authTab(this.rootOidc)).exists('renders oidc method tab for root'); | ||
await authPage.namespaceInput(this.namespace); |
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.
Is it worth using the typeIn
method here rather than the page object's fillable
(which I think uses fillin
under the hood)?
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 actually used fillIn
on purpose because that's what caused the bug in the first place
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.
Played around with this locally too, I think this is a reasonable approach for the fix! But I hope the next time we touch this file it's to rewrite it 🙃 Thank you for the very thorough bug description/breakdown!
…r to OIDC auth (#19541) * re-fetch roles if there is a namespace * remove redundant conditional * reorder oidc auth operations * add test * test cleanup * add changelog
…is inputted, prior to OIDC auth #19541 (#19661) * UI/update auth form to fetchRoles after a namespace is inputted, prior to OIDC auth (#19541) * re-fetch roles if there is a namespace * remove redundant conditional * reorder oidc auth operations * add test * test cleanup * add changelog * UI: fix enterprise test failures (#19671) * move oidc tests into new file * remove module from namespace test * remove entered line * add logout to afterEach hook * remove ns test * move test setup to within test * use logout.visit() instead * updates oidc auth namespaces test * reverts to authPage logout --------- Co-authored-by: Jordan Reimer <zofskeez@gmail.com> --------- Co-authored-by: Jordan Reimer <zofskeez@gmail.com>
So this was tricky to reproduce and due to the whack-a-mole nature of these bugs, here is a very thorough breakdown:
The auth form component updates as the namespace changes to show the correct associated login methods (and corresponding button styles, if applicable). This means the form often reverts to the dropdown menu because by default auth methods are not listed as tabs when unauthenticated (this is a separate config option)
Notice in the gif below, there is an
oidc
tab because in/Root
oidc has been configured solisting_visibility='unauth'
(docs). However, as another namespace is typed, the default form changes becausetestns
has no unuath'd methods.the bug 🐛
For both OIDC and JWT, the
role
is updated when the method is selected and theAuthJwt
component fires off itsdidReceiveAttrs
lifecycle hook which runs the taskfetchRole
with whatever namespace has been set by the url params.If a user very quickly types in a namespace (
admin
) that has the same method (oidc
), mounted at the same path (alsooidc
) but only one of them have a default role configured (stick with me!) then the UI remains on theoidc
tab, but the task to fetch for a role is not re-fired with the new namespace value. This is because thefetchRole
only fires if the auth path has changed. You can see in the gif when we go from root to theadmin
namespace, we get theInvalid role
error because root does not have a default role. However, after refreshing, the namespace stays in the url params and thus the role is set properly.fix 🔧
Because the component is often torn down when the namespace changes it doesn't make sense to check if the namespace has changed (like we do for the auth path by
this.oldSelectedAuthPath !== this.selectedAuthPath
).Instead, opted to reorder the methods in
startOIDCAuth
and tested with the following situations to insure the bug fixes introduced by #17661 were preserved.incorrect-uris-oidc/
with missing URI datamissing-role-oidc
with no role configuredproper-config-oidc
with a default role setup, properly