Skip to content

Auth Refactor split responsibilities#53

Merged
kainovaii merged 1 commit intomainfrom
dev
Mar 19, 2026
Merged

Auth Refactor split responsibilities#53
kainovaii merged 1 commit intomainfrom
dev

Conversation

@kainovaii
Copy link
Member

Pull Request: Auth Refactor split responsibilities

Summary

Breaks the monolithic Auth class into three focused classes and centralizes the duplicated instantiate() helper into Container.


Changes

1. AuthPassword — password utilities extracted

Added: security/auth/AuthPassword.java

  • hash(String password) — BCrypt hashing
  • check(String password, String hash) — BCrypt verification
  • Pure utility class, no state, no dependencies

2. TokenAuth — Bearer token authentication extracted

Added: security/auth/TokenAuth.java

  • userFromToken(Request) — resolves user from Authorization: Bearer header with request-level caching
  • isAuthenticated(Request) — checks token validity
  • requireToken(Request, Response) — halts 401 if no valid token
  • requireTokenRole(Request, Response, String) — halts 403 if missing role
  • getTokenResolver() — lazy-loads TokenResolver via Container or auto-detection

3. Auth — slimmed down to session auth only

Modified: security/auth/Auth.java

  • Removed all token methods (now in TokenAuth)
  • login() now uses AuthPassword.check() internally instead of BCrypt directly
  • hashPassword() / checkPassword() kept as @Deprecated wrappers delegating to AuthPassword for backward compatibility
  • Removed autoDetectTokenResolver() side-effect from autoDetectUserDetailsService()
  • Removed private instantiate() method (now uses Container.instantiate())
  • Cleaned up imports (no more java.lang.reflect)

4. Container.instantiate() — centralized reflection helper

Modified: di/Container.java

  • Added instantiate(Class<?> implClass, Class<T> targetType) — creates an instance via no-arg or DI-resolved constructor + field injection
  • Unlike resolve(), does not require @Service/@Repository annotations and does not register as singleton
  • Eliminates the duplicated instantiate() that existed in both Auth and TokenAuth

5. RoleChecker — updated to use TokenAuth

Modified: security/role/RoleChecker.java

  • Auth.requireToken()TokenAuth.requireToken()
  • Auth.requireTokenRole()TokenAuth.requireTokenRole()

6. BaseController — updated to use AuthPassword

Modified: http/controller/BaseController.java

  • Auth.hashPassword()AuthPassword.hash()
  • Auth.checkPassword()AuthPassword.check()

7. Tests updated

Modified: AuthPasswordTest.java

  • Migrated from Auth.hashPassword() / Auth.checkPassword() to AuthPassword.hash() / AuthPassword.check()

Modified: AuthTest.java

  • Removed tokenResolver reset from setUp() (field no longer exists in Auth)
  • Removed token auth tests (moved to TokenAuthTest)
  • fakeUser() uses AuthPassword.hash() instead of Auth.hashPassword()

Added: TokenAuthTest.java

  • Injects a mock TokenResolver to avoid Reflections auto-detect in test context
  • 8 tests covering: userFromToken (no header, invalid prefix, empty bearer, valid token, caching), isAuthenticated (no token, invalid, valid)

Breaking Changes

  • Auth.requireToken(Request, Response) → use TokenAuth.requireToken(Request, Response)
  • Auth.requireTokenRole(Request, Response, String) → use TokenAuth.requireTokenRole(Request, Response, String)
  • Auth.userFromToken(Request) → use TokenAuth.userFromToken(Request)
  • Auth.isTokenAuthenticated(Request) → use TokenAuth.isAuthenticated(Request)
  • Auth.getTokenResolver() → use TokenAuth.getTokenResolver()
  • Auth.hashPassword(String) and Auth.checkPassword(String, String) still work but are @Deprecated — migrate to AuthPassword.hash() / AuthPassword.check()

@kainovaii kainovaii merged commit 3d2ca8c into main Mar 19, 2026
2 checks passed
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.

1 participant