Repository navigation
fix: keep sudo id when login(sudoId) also logs in the API user - #1777
Priyank-gouda678 wants to merge 1 commit into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request fixes an issue in both the Node and Swift SDKs where the requested sudo ID was being cleared immediately after assignment because the assignment occurred before the reset() call. To resolve this, the assignment of sudoId has been moved to execute after reset(). Additionally, a new unit test suite has been added for NodeSession to verify the sudo login behavior. The review feedback suggests normalizing newId in nodeSession.ts before comparison to prevent redundant assignments, and enhancing the new unit test to explicitly assert the exact sequence and number of API requests made during the login process.
| if (newId !== this.sudoId) { | ||
| // Assign new requested sudo id after reset() above, which clears it | ||
| this.sudoId = newId || ''; | ||
| } |
There was a problem hiding this comment.
Comparing newId (which can be undefined) directly with this.sudoId (which is initialized to '') results in a redundant assignment of '' to this.sudoId when no sudo ID is requested. We can avoid this by normalizing newId first and then performing the comparison.
| if (newId !== this.sudoId) { | |
| // Assign new requested sudo id after reset() above, which clears it | |
| this.sudoId = newId || ''; | |
| } | |
| const targetSudoId = newId || ''; | |
| if (targetSudoId !== this.sudoId) { | |
| // Assign new requested sudo id after reset() above, which clears it | |
| this.sudoId = targetSudoId; | |
| } |
| expect(request).toHaveBeenCalledWith( | ||
| 'POST', | ||
| '/api/4.0/login/5', | ||
| null, | ||
| null, | ||
| expect.any(Function), | ||
| settings | ||
| ); |
There was a problem hiding this comment.
To make the test more robust and explicitly verify the login sequence (first logging in the API user, then performing the sudo login), we should assert that request was called exactly twice and verify the second call specifically using toHaveBeenNthCalledWith.
| expect(request).toHaveBeenCalledWith( | |
| 'POST', | |
| '/api/4.0/login/5', | |
| null, | |
| null, | |
| expect.any(Function), | |
| settings | |
| ); | |
| expect(request).toHaveBeenCalledTimes(2); | |
| expect(request).toHaveBeenNthCalledWith( | |
| 2, | |
| 'POST', | |
| '/api/4.0/login/5', | |
| null, | |
| null, | |
| expect.any(Function), | |
| settings | |
| ); |
NodeSession._login()assigns the requested sudo id and then, when the API user's token is not active, callsreset()before logging the API user in.reset()clearssudoId, so theif (this.sudoId)check that follows is false,POST /login/{id}is never sent, andlogin(id)returns the API user's token. Every later call on that SDK then runs with the API3 credentials (normally an admin, since sudo needs that permission) whileisSudo()reports false. It happens on the firstlogin(id)of a fresh session and on anylogin(id)after the API user's token has expired, so a service that sudoes to scope calls to an end user's permissions gets admin-scoped results back. The SwiftAuthSession._login()has the same ordering. The Kotlin, C# and Python sessions are not affected: Kotlin doesn't callreset()there, C# checks thesudoIdargument, and Python keeps_sudo_idoutside the API login.The sudo id is now assigned after the API user login in both sessions. The new
nodeSession.spec.tscovers a freshlogin('5'): it fails before the change (onlyPOST /api/4.0/loginis sent) and passes after. The Swift change was checked with a mock transport: before,login("5")leavesisSudo() == falseholding the API token; after, it sendsPOST /login/5and holds the sudo token.Developer Checklist ℹ️