Skip to content

Conversation

@scezen
Copy link
Member

@scezen scezen commented Dec 31, 2025

Ticket : DERCBOT-1772

Details

  • Fixed 500 error when switching namespace: we were casting RoutingContext to UserContextInternal, now using context.userContext() to update the user.
  • Persisted the updated TockUser in session (tockUser) during namespace switch so the new namespace is applied immediately (no refresh needed).
  • Added a small guard in CAS mapping: if tockUser already exists in session, we reuse it and avoid overwriting it during CAS upgrade.

Note :

  • We keep the current flow and only add session persistence + a guard to prevent CAS from resetting the namespace.
  • Some formatting fixes made by KTLint will make the review harder but it's mandatory for the CI to pass.

@scezen scezen marked this pull request as ready for review January 2, 2026 22:40
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a 500 error that occurred when switching namespaces in the application. The root cause was improper casting of RoutingContext directly to UserContextInternal. The fix properly uses context.userContext() before casting and persists the updated TockUser in the session.

Key Changes:

  • Fixed namespace switching to use context.userContext() instead of casting RoutingContext directly
  • Added session persistence for the updated TockUser during namespace switches
  • Implemented a guard in CAS authentication to reuse existing TockUser from session and prevent overwriting during CAS upgrade

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
shared/src/main/kotlin/security/auth/CASAuthProvider.kt Added session check logic to preserve TockUser during namespace switches and prevent CAS from overwriting it; includes KTLint formatting changes
nlp/admin/server/src/main/kotlin/AdminVerticle.kt Fixed namespace switching endpoint to properly update user context and persist to session; extensive KTLint formatting changes throughout the file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


if (sessionTockUser != null) {
// If a TockUser is already in session (ex: after a namespace switch), reuse it and don't overwrite it.
(rc.userContext() as UserContextInternal).setUser(sessionTockUser)
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cast to UserContextInternal is fragile and depends on Vert.x internal implementation details. The io.vertx.ext.web.impl package is internal and could change without notice. Consider checking if userContext() is an instance of UserContextInternal before casting, or document this as a known limitation that may break with future Vert.x versions.

Copilot uses AI. Check for mistakes.
val updated = context.user!!.copy(namespace = n)

// Update the user through userContext() and persist in session so next calls see the change.
(context.userContext() as UserContextInternal).setUser(updated)
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cast to UserContextInternal is fragile and depends on Vert.x internal implementation details. The io.vertx.ext.web.impl package is internal and could change without notice. Consider checking if userContext() is an instance of UserContextInternal before casting, or document this as a known limitation that may break with future Vert.x versions.

Suggested change
(context.userContext() as UserContextInternal).setUser(updated)
val userContext = context.userContext()
if (userContext is UserContextInternal) {
userContext.setUser(updated)
}

Copilot uses AI. Check for mistakes.
front.setCurrentNamespace(context.userLogin, n)
(context as UserContextInternal).setUser(context.user!!.copy(namespace = n))

val updated = context.user!!.copy(namespace = n)
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The copy() method on a data class creates a shallow copy. Since TockUser has a delegate field that is a mutable User object, and the authorizations are set in the init block, using copy(namespace = n) will copy the existing delegate and not reinitialize the authorizations. This could potentially lead to inconsistent state if the namespace change should affect authorizations. Verify that preserving the existing delegate and authorizations is the intended behavior.

Copilot uses AI. Check for mistakes.
val updated = context.user!!.copy(namespace = n)

// Update the user through userContext() and persist in session so next calls see the change.
(context.userContext() as UserContextInternal).setUser(updated)
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential null safety issue: context.session() returns a nullable session. If the session is null, the put() operation will be silently skipped, and the namespace change won't be persisted. Consider checking if the session is null and handling this case explicitly, or at minimum adding a comment acknowledging this limitation.

Suggested change
(context.userContext() as UserContextInternal).setUser(updated)
(context.userContext() as UserContextInternal).setUser(updated)
// Note: if session() is null, this call is skipped and the namespace change is not persisted across requests.

Copilot uses AI. Check for mistakes.
Comment on lines +201 to +204
if (sessionTockUser != null) {
// If a TockUser is already in session (ex: after a namespace switch), reuse it and don't overwrite it.
(rc.userContext() as UserContextInternal).setUser(sessionTockUser)
rc.next()
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential race condition: The check for sessionTockUser and setting it in userContext() is not atomic. If multiple requests are processed concurrently for the same user during a namespace switch, there could be inconsistent state. Consider whether this scenario is possible in your application architecture and if additional synchronization is needed.

Copilot uses AI. Check for mistakes.
@vsct-jburet
Copy link
Contributor

@scezen I add copilot review. You can close all useless comments ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants