-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
feat(redirectTo): added UI part of redirectTo logic for CLOUD users to redirectTo original links after logging in #18214
Conversation
…directTo as a queryParameter
…ed correctly on IDPE Co-authored-by: Greg Linton<greg@influxdata.com>
…ctices & feature flag Co-authored-by: Greg Linton<greg@influxdata.com>
flags.yml
Outdated
@@ -40,3 +40,11 @@ | |||
default: false | |||
contact: Lyon Hill | |||
expose: true | |||
|
|||
- name: RedirectTo Path After Login |
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 there a corresponding idpe PR that matches this one?
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.
no PR up yet. I'm glad you commented on this. When we talked to @gavincabbage about it on Friday it seemed like the UI yml file would generate the flag for the API too, is that right? Right now we want to write up some tests for the API to make sure everything is smooth before submitting a PR for cloud
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.
it will show up on api/v2/flags
if that's what you're referring to as the API (we need to figure out better words for all this), but only for people who are hosting this locally, which seems like the opposite of the intent of this PR? If you want the flag to only show up on a production deployment, it needs to be made on IDPE. You should probably even remove the flag from this repo, as local overrides would work for development and the flag isn't meant for OSS instances that handle their own auth.
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.
Gotcha. So I'll remove the local flag and set it in IDPE
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.
Some clarifying details: The flag only needs to be in one place, either influxdb/flags.yml
or idpe/flags.yml
. The former for flags used by OSS or both OSS and IDPE. The latter for flags used by only IDPE. Since the UI lives in OSS afaiu, most or all UI related flags will probably end up 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.
I made the above comment without refreshing this page, and missed @drdelambre's latest comment.
If the code is resilient to the flag only being present in IDPE's api/v2/flags
response and not in OSS's, then moving the flag to IDPE also works.
ui/src/Signin.tsx
Outdated
window.location.href | ||
}` | ||
) | ||
window.localStorage.setItem('redirectTo', window.location.href) |
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.
note to self: this is because sessions are handled weird on the backend and don't exist until a user is authenticated instead of elevating an anonymous session that is created on first touch. We can't follow a request chain from the unauthenticated user to an authenticated user. this'll become a problem when we start sharing dashboards as we'll introduce non-authenticated user state into the mix.
kit/feature/list.go
Outdated
@@ -58,16 +58,32 @@ func SessionService() BoolFlag { | |||
return sessionService | |||
} | |||
|
|||
var redirectto = MakeBoolFlag( |
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.
var redirectto = MakeBoolFlag( | |
var redirectTo = MakeBoolFlag( |
looks like the examples here are all camelCased. Best to stick with local conventions
ui/src/Signin.tsx
Outdated
@@ -74,13 +75,28 @@ export class Signin extends PureComponent<Props, State> { | |||
private checkForLogin = async () => { | |||
try { | |||
await client.users.me() | |||
const redirectIsSet = !!window.localStorage.getItem('redirectTo') |
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.
do we have a way to access storage without hitting localStorage
directly? maybe some kind of module that handles fallbacks in case localStorage isn't enabled?
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.
It seems like we're setting/getting state items here:
https://github.com/influxdata/influxdb/blob/master/ui/src/localStorage.ts#L41-L51
But they make use of the same underlying functionality. Is it beneficial to abstract some of the logic to a generalized setter in that file? I'm curious to know
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, we should use the abstractions that exist in the system, even if they're doing the same thing. if we needed to add an extra step (like let's say we have to add a timestamp to all writes to local storage), we'd only have to update the code to do that in one place, if everything made use of that function. it handles error messaging in a consistent way as well
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.
Sounds good. I'll go ahead and write up some utility functions and send up a commit for that
ui/src/Signin.tsx
Outdated
window.location.href | ||
}` | ||
) | ||
window.localStorage.setItem('redirectTo', window.location.href) |
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.
why set the redirectTo
to the current url instead of just removing it from localStorage since we're done with it?
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.
Great question - so this feature is actually handling redirectTo logic for three separate environments conditions:
- Social Sign On is not enabled (tools cluster), and the user logs in via the universal login page
- Social Sign On is enabled and the user is authenticated in Auth0 but not IDPE
- Social Sign On *is enabled and the user is NOT authenticated in Auth0
By setting the query parameter directly to the initial api/v2/signin
request, we handle the first two cases (where a user is being navigated - whether directly or silently - to the universal login page).
The reason we are setting the redirectTo
onto localStorage is due to the way that authentication occurs in cloud. Basically, by the time we get navigated to the /login
page, we will have no reference or session with the original redirectTo logic (and the browser will have been redirected about 4 times)
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.
and the browser will have been redirected about 4 times
😬 😱
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.
Tell me about it. Things are in need of a good unification
) | ||
window.localStorage.setItem('redirectTo', window.location.href) | ||
window.location.href = url.href | ||
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.
why throw
the error if we're redirecting away from this page?
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.
The original implementation set this so I went based off of that. I think the understanding is that if there's an issue with the redirect, we will not want the user to continue on (since that'll navigate them to /signin
which is reserved for OSS)
ui/src/authorizations/apis/index.ts
Outdated
export const getAuth0Config = async ( | ||
redirectTo: string | ||
): Promise<Auth0Config> => { | ||
try { | ||
const response = await fetch( | ||
`${getAPIBasepath()}/api/v2private/oauth/clientConfig` | ||
) | ||
let url = `${getAPIBasepath()}/api/v2private/oauth/clientConfig` | ||
if (isFlagEnabled('redirectto')) { | ||
url = `${getAPIBasepath()}/api/v2private/oauth/clientConfig?redirectTo=${redirectTo}` | ||
} | ||
const response = await fetch(url) |
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 think this flag checking logic makes more sense in the component. the authorizations api shouldn't really know about feature flags if it doesn't have to. it's just making a request to a url and getting some data back.
i think it would be clearer to have redirectTo
be an optional parameter that gets added as a query param if it exists. then you can move the isFlagEnabled
one layer up to the code that calls this, LoginPageContents
.
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 think I see what you're saying
@@ -61,7 +61,8 @@ class LoginPageContents extends PureComponent<DispatchProps> { | |||
|
|||
public async componentDidMount() { | |||
try { | |||
const config = await getAuth0Config() | |||
const redirectTo = window.localStorage.getItem('redirectTo') || '/' |
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.
the feature flag makes more sense here i think - here it can control what gets sent to getAuth0Config
so that that layer doesn't even need to be aware of the flag. something like:
let config
if (isFlagEnabled('redirectto')) {
const redirectTo = window.localStorage.getItem('redirectTo') || '/'
config = await getAuth0Config(redirectTo)
} else {
config = await getAuth0Config()
}
doing it this way (not sending an empty string will leave the url a little cleaner - it won't have ?redirectTo=
with no value in it - in other words, only append ?redirectTo=${actualURL}
if there's something to redirect to.
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 makes sense
) | ||
let url = `${getAPIBasepath()}/api/v2private/oauth/clientConfig` | ||
if (isFlagEnabled('redirectto')) { | ||
url = `${getAPIBasepath()}/api/v2private/oauth/clientConfig?redirectTo=${redirectTo}` |
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.
why not just url += ?redirectTo=
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.
No reason not to. Thought about it but figured this was a bit more explicit and would require less manipulation once the feature flag is removed
kit/feature/list.go
Outdated
@@ -58,16 +58,32 @@ func SessionService() BoolFlag { | |||
return sessionService | |||
} | |||
|
|||
var redirectto = MakeBoolFlag( |
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 this autogenerated code from make flags
that you forgot to remove?
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.
it is autogenerated code that I didn't realize was autogenerated ;)
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.
remove the autogenerated code changes, but the rest looks great given the weird session setup we have in the system.
Problem
Users navigating to CLOUD would lose the original URL reference once they completed logging in.
Solution
This is part one of a dual-change that will address the issue described above. Namely, the UI will set the redirectTo as the query parameter for the API. In this PR, we have: