Allow setting custom reason prompt for Access Requests#54642
Allow setting custom reason prompt for Access Requests#54642
Conversation
a4a0be8 to
1483d13
Compare
1483d13 to
b49f4a0
Compare
ef61f06 to
82e2540
Compare
82e2540 to
e2de975
Compare
b49f4a0 to
fff9027
Compare
e2de975 to
bd9d2a4
Compare
5c0cdd8 to
10422e5
Compare
| }) { | ||
| const { valid, message } = useRule(requireText(reason, requireReason)); | ||
| const { valid, message } = useRule( | ||
| requireText(reason, requireReason || reasonMode === 'required') |
There was a problem hiding this comment.
There's already a requireReason field https://github.com/gravitational/teleport.e/blob/b24b076f260ad5900f589a04cd7debc4f3059527/web/teleport/src/Workflow/NewRequest/useRequestCheckout.tsx#L226.
How does it differ from reasonMode? Could we only have requireReason?
There was a problem hiding this comment.
They come from different fields in the role.
requireReason comes from .spec.options.request_access and the reasonMode comes from .spec.allow.request.reason.mode. They have slightly different semantics:
There was a problem hiding this comment.
for RequestCheckout i don't think we need the distinction between reasonMode and requireReason (especially if my mental wiring was correct, reasonMode refers to both fields?).
all we need to know is is reason required so we can mark the textbox as required.
There was a problem hiding this comment.
I removed reasonMode from there. The handling is done in https://github.com/gravitational/teleport.e/pull/6502/files#diff-b64b7aa2754e33df83b39bcee2a857c345415c9a1c8de0f5138424c48a3a7acdR228
| // requireReasonForAllRoles indicates that non-empty reason is required for all access | ||
| // requests. This happens if any of the user roles has options.request_access "reason". |
There was a problem hiding this comment.
is the reason mode included in the flag?
access request isn't confusing at all 😭 (i just looked at the requiringReasonRoles)
i would mention in comment, not to be confused with spec.allow.request.reason.mode
can we also mention that this flag takes precedence over the reason mode?
There was a problem hiding this comment.
There is no precedence. If any of them matches then the reason is requred.
| return requestValidator{}, trace.Wrap(err) | ||
| } | ||
| } | ||
| slices.Sort(m.reasonPrompts) |
There was a problem hiding this comment.
hrm, what benefit do we get by sorting the prompts? i'd imagine a user would not expect that or what if prompts are built from previous prompts?
There was a problem hiding this comment.
There is no guaranteed order they will come from the backend. I'd like to avoid situation where the order is changed on every refresh. So by extension prompts can't be build from previous prompts.
| return nil, trace.Wrap(err) | ||
| } | ||
| if required { | ||
| enrichment.ReasonMode = types.RequestReasonModeRequired |
There was a problem hiding this comment.
i'm not sure enrichment.ReasonMode the ReasonMode is the right variable name to use b/c it makes it sound like that's the spec.allow.request.reason.mode value, but it's that or the options.request_access (which takes precedence).
I'd probably rename it to just enrichment.ReasonRequired or RequireReason
There was a problem hiding this comment.
options.request_access doesn't take precedence. It may look like that from the implementation because it's more efficient to check options.request_access first. I'd even say checking options.request_access for regular (not autologin) access requests was a bad decision.
I prefer to stick with the enum because in unlikely case this mode is extended we won't have to change the wire format.
| thresholdNames: ['default'], | ||
| resources: [], | ||
| assumeStartTime: null, | ||
| reasonMode: 'optional', |
There was a problem hiding this comment.
i just want to make sure, is this reasonMode referring specifically to field spec.allow.request.reason.mode
There was a problem hiding this comment.
It covers both spec.allow.request.reason.mode and spec.options.request_access
There was a problem hiding this comment.
I think I know why you may be confused. The information take from the user state may be already outdated. This reasonMode thing will calculated from the current backend state regardless of the roles in the cert.
| }) { | ||
| const { valid, message } = useRule(requireText(reason, requireReason)); | ||
| const { valid, message } = useRule( | ||
| requireText(reason, requireReason || reasonMode === 'required') |
There was a problem hiding this comment.
for RequestCheckout i don't think we need the distinction between reasonMode and requireReason (especially if my mental wiring was correct, reasonMode refers to both fields?).
all we need to know is is reason required so we can mark the textbox as required.
10422e5 to
c4293fa
Compare
|
@gzdunek @kimlisa @smallinsky PTALA |
147cf9a to
d1be7c2
Compare
| if m.opts.dryRun { | ||
| return enrichment, nil | ||
| } | ||
| return nil, nil |
There was a problem hiding this comment.
This is quite scary interface.
I would expect that the err == nil the object is valid
Can we just req.SetDryRunEnrichment(enrichment) ?
d1be7c2 to
f28149e
Compare
| onStartTimeChange={onStartTimeChange} | ||
| fetchKubeNamespaces={fetchKubeNamespaces} | ||
| updateNamespacesForKubeCluster={updateNamespacesForKubeCluster} | ||
| reasonPrompts={reasonPrompts} |
There was a problem hiding this comment.
In the line 272 we should also add:
requireReason={reasonMode === 'required'}Another thing is that these prompts work only in Web UI, not in Teleport Connect (teleterm).
To add them there too, we need to extend the below struct with these two new fields (reasonMode and reasonPrompts):
teleport/lib/teleterm/apiserver/handler/handler_access_requests.go
Lines 203 to 221 in f33bbbf
and make sure that they are passed here:
Unfortunately the type for an argument in makeAccessRequest is any so TypeScript doesn't show any errors about missing fields.
In case of any problems feel free to reach out to me.
There was a problem hiding this comment.
Would you be ok with adding Teleport Connect support in a subsequent PR?
f28149e to
81bd936
Compare
|
@gzdunek PTALA |
gzdunek
left a comment
There was a problem hiding this comment.
The frontend side looks good to me.
| const labelText = hasError ? message : 'Request Reason'; | ||
|
|
||
| const placeholderText = | ||
| reasonPrompts?.filter(s => s.length > 0).join('\n') || |
There was a problem hiding this comment.
Unnecessary optional chaining (optionality can also be removed in the line 739).
| onStartTimeChange={onStartTimeChange} | ||
| fetchKubeNamespaces={fetchKubeNamespaces} | ||
| updateNamespacesForKubeCluster={updateNamespacesForKubeCluster} | ||
| reasonPrompts={reasonPrompts} |
81bd936 to
983b77c
Compare
Issue: #29475
Requires #54660
E companion: https://github.com/gravitational/teleport.e/pull/6502
Changes:
Bonus changes:
After pressing "Submit Request", when 2 prompts are configured and the reason is required:

Note: Teleport Connect support is added in #55092
changelog: UI: Access Request reason prompts configured in Role.spec.options.request_prompt are now displayed in the reason text box, if such a role is assigned to the user.