-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[server] update OIDC users on sign-in (email) – WEB-370 #17633
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
Conversation
expect(newEmail, "update was not called").not.to.be.undefined; | ||
expect(newEmail).to.equal(payload.claims.email); |
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 first check seems redundant, given we also do the second comparison, no?
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.
First is checking if the update is actually called, second is checking if the new value is as expected.
@test public async testSessionRequest_updates_existing_user() { | ||
const payload: OIDCCreateSessionPayload = { ...this.payload }; | ||
payload.claims.sub = this.knownSubjectID; // `userServiceMock.findUserForLogin` will match this value | ||
|
||
this.knownUser.identities = [ | ||
{ | ||
authId: payload.claims.sub, | ||
authProviderId: payload.claims.aud, | ||
authName: "Test User", | ||
primaryEmail: "[email protected]", | ||
}, | ||
]; | ||
|
||
let newEmail: string | undefined; | ||
this.userServiceMock.updateUserIdentity = async (user, updatedIdentity) => { | ||
newEmail = updatedIdentity.primaryEmail; | ||
}; | ||
|
||
const result = await request(this.app.create()) | ||
.post("/session") | ||
.set("Content-Type", "application/json") | ||
.send(JSON.stringify(payload)); | ||
|
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 feels this whole test is quite brittle. We're mostly testing that once you hit /session
with some payload, the handler invokes the userServiceMock.updateUserIdentity
method which is in fact a stub. So here, we're just checking that it invokes our stub, rather than it actually performs the behaviour we want.
Is it possible to instead use the real service and verify the record got updated in the DB?
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, if we make it a db-test.
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, this way it makes assumptions about the internal paths of the 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.
Up to you. I'd personally favour it as a db test as it gives us stronger guarantees but if you think it's pointless then I can live with that.
protected async updateOIDCUserOnSign(user: User, payload: OIDCCreateSessionPayload) { | ||
const recent = this.mapOIDCProfileToIdentity(payload); | ||
const existing = user.identities.find((identity) => identity.authId === recent.authId); | ||
|
||
// Update email | ||
if (existing && !!recent.primaryEmail && existing.primaryEmail !== recent.primaryEmail) { | ||
existing.primaryEmail = recent.primaryEmail; | ||
await this.userService.updateUserIdentity(user, existing); | ||
} | ||
} |
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.
Could this whole method be moved into the userService
such that it can be more easily re-used in other places? This would be particularly useful as we try to align with the service oriented architecture.
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.
Thought about that, but opted to not push the mapping in there.
See, userService.updateUserIdentity
does the actual update. On top, here is the mapping of the profiles, which very well could be pulled out to be reusable.
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.
Tests run, code LGTM: ✔️
/unhold |
Updates email address of SSO users on each sign-in.
Related Issue(s)
Fixes WEB-370
How to test
Documentation
Preview status
gitpod:summary
Build Options:
Run the build with werft instead of GHA
Run Leeway with
--dont-test
Publish Options
Installer Options
Add desired feature flags to the end of the line above, space separated
Preview Environment Options:
If enabled this will build
install/preview
If enabled this will create the environment on GCE infra
Valid options are
all
,workspace
,webapp
,ide
,jetbrains
,vscode
,ssh
/hold