-
Notifications
You must be signed in to change notification settings - Fork 44
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
Centralize WTS refresh token initialization #1095
Centralize WTS refresh token initialization #1095
Conversation
Also Mingfei is back. I've added him. 👍 |
I'm not sure I agree with the concept here. WTS should not be a hard dependency of portal. We have data commons that need portal but don't need WTS |
The assumption that WTS is configured and used everywhere is not a safe assumption |
@Avantol13 thanks for the review! You bring up a good point, and I thought about this as well when making this PR. One reason I added it here is because I see other workspace related items in |
Honestly I don't think workspace things should necessarily be there either, but adding more coupling (for example to WTS) is just making things worse in my opinion. I don't have a ton of portal experience so ultimately I need to defer to @mfshao imo portal should support commons that don't have workspaces at all, commons that only have workspaces for themselves (e.g. no need to WTS), and it should support ecosystems where we want workspaces and WTS. We have running, production examples of all of those things, and it seems like this PR presumes that we want everything to be an ecosystem with workspaces and WTS, and that just isn't the case. |
thanks @Avantol13, that makes sense. I agree that in this case probably the other references to workspaces should also be removed. @mfshao what do you think? |
I agree, WTS token initialization shouldn't happen as a part of portal app init process. It should be triggered only if a WTS related feature is enabled: workspace, GWASApp or AggAuthMapping I think we have the flags in config file to determine whther the later 2 feature has been enabled, for workspace, that is part of an old logic. We should probably also use a feature flag to explicitly to turn it on. |
cf6dab7
to
1456267
Compare
@mfshao thanks for your comment. I added this commit 1456267 which will trigger the initialization/refresh based on a very specific feature flag (I called 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.
I don't think we support "workspace without WTS" a long while ago...
But this PR has some linting issues that needs to be fixed
src/Workspace/index.jsx
Outdated
} | ||
}, | ||
); | ||
initWorkspaceRefreshToken(this.connected); |
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.
so, if this new feature is enabled, when user navigates from a page to workspace, another wts call will be dispatched? seems like a bit redundant
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.
Good point... But I think that if we want to do this with a feature flag that is false
by default, then we will need to keep some of this redundancy for backwards compatibility purposes. Also, an extra refresh is not so bad...it is better than no refresh (which happens if users use the portal but don't go into the workspace for a long period - a scenario we have in our project).
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.
Please note that this diff is technically not really a code/behaviour change: I basically moved the code on the left into a generic function that can be used in different places.
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.
Another option is to make a breaking change and make a feature flag for workspaces as a whole, and make this flag true
by default. This would simplify the code, but would require some special attention from teams that have a deployment that does not use workspace/ WTS. Please let me know what you think.
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 check if workspaceTokenServiceRefreshTokenAtLogin
is enabled, and only make the call if it's not?
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 could work, but IMO it is an unnecessary optimisation. But if you prefer this, I can easily add it. Let me 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.
it makes sense to me... depending on the flag, the call is made either globally, or when the workspace page loads, and not both. But we can defer to @mfshao who brought this up 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.
That is the point I bring this up: we should be able to add a check so this didn't get called repeatly
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.
Ok, I'll add a condition.
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.
Fixed here: 882043f
src/index.jsx
Outdated
@@ -67,6 +67,12 @@ import ErrorWorkspacePlaceholder from './Workspace/ErrorWorkspacePlaceholder'; | |||
import { ReduxStudyViewer, ReduxSingleStudyViewer } from './StudyViewer/reduxer'; | |||
import NotFound from './components/NotFound'; | |||
import ErrorPage403 from './components/ErrorPage403'; | |||
import { initWorkspaceRefreshToken } from './Workspace/WorkspaceRefreshToken'; | |||
|
|||
if (isEnabled('workspaceTokenServiceRefreshTokenAtLogin')) { |
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.
other index pages (which are being used by other portal bundles) also needs this change?
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.
not sure. Is this one not used by all?
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, some Data Commons have their own landing page, so they have their own index page (covid19Index.jsx
, nctIndex.jsx
, etc)
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.
so do we need to add this change there as well @paulineribeyre?
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 logic needs to happen for every Commons, not just the ones that use the default landing 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.
Ok, I'll add that
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.
Or not... This change has been reverted in favor of the one in src/Login/ProtectedContent.jsx
😅
42436aa
to
a0ce7ed
Compare
src/Login/ProtectedContent.jsx
Outdated
@@ -70,6 +72,10 @@ class ProtectedContent extends React.Component { | |||
const latestState = { ...newState }; | |||
latestState.dataLoaded = true; | |||
this.setState(latestState); | |||
if (newState.authenticated && isEnabled('workspaceTokenServiceRefreshTokenAtLogin')) { | |||
// initialize WTS: | |||
initWorkspaceRefreshToken(); |
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.
because this is in ProtectedContent.componentDidMount
, is the call to WTS going to be triggered for each ProtectedContent component in the index 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.
@paulineribeyre would that be a problem? I think it is a really light call.
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.
Yes i think that's a problem, from a quick search i see 26 ProtectedContents
in src/index.jsx
, we should not make so many API calls every time someone loads the page. Can we make a single call to WTS when the portal is loaded?
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.
Thanks for checking @paulineribeyre !
It is an interesting finding, since the same could be said regarding the call to checkLoginStatus
just a few lines up:
.then(
() => this.checkLoginStatus(store, this.state)
Maybe that is why checkLoginStatus
has the code below to avoid repeated calls? Should we do something similar here? Or should we try to find another location for our init code?
checkLoginStatus = (store, initialState) => {
const newState = { ...initialState };
const nowMs = Date.now();
newState.authenticated = true;
newState.redirectTo = null;
newState.user = store.getState().user;
if (nowMs - lastAuthMs < 60000) {
// assume we're still logged in after 1 minute ...
return Promise.resolve(newState);
}
...
@mfshao what would you suggest for 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.
you can do something similar like this
or change in your wts init code so that if a user is not logged in, don't force them to do an OIDC dance with WTS
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 am curious why you chose to add it to ProtectedContent
instead of index.jsx
like in your initial code?
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.
@paulineribeyre I was asked by @mfshao to do this...I now realise this was in slack and is not here in the PR comments.
@mfshao do you mind replying to this here?
In a nutshell: the code here is "guaranteed to be called after login", and having it in index.jsx
will break any parts that are public because it would force a redirect to a login 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.
@paulineribeyre @mfshao I added a proposal here in this last commit: f3e37c7. Please let me know what you think. It is based on the current solution for checkLoginStatus
in ProtectedContent.jsx
82b7b20
to
f3e37c7
Compare
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.
lgtm, deferring to @mfshao
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 we should test this features more. At least we should configure the portal to have some public/protected pages and try to login with user who already has WTS connected and who doesn't have WTS connected. To see if there will be any unexpected behaviors
.then( | ||
({ status }) => { | ||
if (status !== 200) { | ||
window.location.href = `${wtsPath}/authorization_url?redirect=${window.location.pathname}`; |
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.
Notice that the redirect here only contains window.location.pathname
, so if the page that the user is at contains some query params in its URL, they will be lost
This was not a problem before because WTS login redirect only happens in certian pages that don't need query params. But if you are moving this redirect so it can happen virtually from any portal pages, you need to accomodate accordingly, because this will have a product-wise impact
Also there are some location and history based redirect/state restore happens in other pages of portal. We should make sure this change doens't breaks them
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.
Also the tests need to get fixed before it can be merged |
b91eccb
to
ad4ec40
Compare
Jira Ticket: VADC-154
Improvements
Dependency updates
workspaceTokenServiceRefreshTokenAtLogin
. If this is set totrue
it will refresh the WTS token directly at portal login (recommended mode). If not set, this refresh happens only when the user enters the workspace section of the portal (default/old/previous mode).Deployment changes