Skip to content

Issue167449 otp auto google auth - #133

Open
dk1991 wants to merge 5 commits into
masterfrom
issue167449_otp_auto_google_auth
Open

Issue167449 otp auto google auth#133
dk1991 wants to merge 5 commits into
masterfrom
issue167449_otp_auto_google_auth

Conversation

@dk1991

@dk1991 dk1991 commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Dmitriy Kanaev and others added 5 commits September 4, 2026 11:52
…tory

Mandatory OTP (is_otp_optional='N') with otp_type=none was silently
ignored at SSO login, so the flag alone did not enforce OTP. Now the
invariant "OTP mandatory => type is not none" is maintained at write
time in the service layer, covering both the admin UI and the Remote
API without touching the authentication code:

- UserServiceImpl.createUser/updateUser: assign google_auth when OTP
  is mandatory and the type is none/null, with an AUTO_SET_OTP_TYPE
  audit event
- UserServiceImpl.updateUserIsOtpOptionalValue: same normalization
  after making OTP mandatory
- UserServiceImpl.updateUserOtpType: reject unknown type codes
  (previously they silently reset the type) and reject 'none' for a
  user whose OTP is mandatory (SsoConflictException)
- Create/EditUserPage: when the "Is OTP optional" checkbox is cleared
  and no type is chosen, the OTP type dropdown switches to Google Auth
  with an info message

Existing DB records are intentionally not migrated: they get
normalized as they are saved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ser form

UIUser.isOtpOptional defaults to false, so an untouched create form used
to produce a user with mandatory OTP - and now that would also auto-set
the google_auth type, sending every new user to Google Authenticator
binding. Default the form to "optional", matching the DB column default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Renders CreateUserPage/EditUserPage with mocked Spring beans (no DB) and
drives the "Is OTP optional" checkbox via an Ajax change event:

- EditUserPage: clearing the flag auto-sets google_auth when the type is
  none, keeps an already-chosen type, and leaves the type alone when the
  flag stays optional
- CreateUserPage: the flag is checked (OTP optional) by default, and
  clearing it auto-sets google_auth

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remote API contract:
- register SsoConflictException and SsoBadRequestException in
  ExceptionSerializationHelper. The server answers a thrown service
  exception with HTTP 202 + ExceptionWrapper, so the client rebuilt an
  unregistered class as an anonymous SsoException and a
  `catch (SsoConflictException)` never matched, contradicting the
  javadoc added for updateUserOtpType.
- normalize OTP type codes in one place: an absent or blank code means
  "no OTP" (it used to clear the type before this branch), an unknown
  code is rejected with SsoBadRequestException instead of a raw
  IllegalStateException, and createUser/updateUser now use the same
  parsing as updateUserOtpType instead of the lenient fromCode.

Audit trail:
- log AUTO_SET_OTP_TYPE after the DAO call with its actual result, as
  every other event in the class does. It was logged as a success
  before the insert/update ran, so a duplicate username left an audit
  line claiming an OTP type was set on a user that was never created.

Admin UI:
- extract the auto-set rule into OtpTypeAutoSetBehavior and attach it
  to the OTP type drop down as well. An ajax request submits only the
  component it originates from, so the check box behavior decided on a
  stale OTP type: picking "None" and then clearing "Is OTP optional"
  showed None + mandatory, and the service silently rewrote it to
  google_auth on save.
- clear the drop down input before repainting it, otherwise the value
  the component received (a previous failed submit, or the choice just
  overridden) wins over the model and the select keeps showing None.
- add the missing Russian translation for user.otpTypeAutoSet.

Tests: AUTO_SET_OTP_TYPE is now pinned by strict-mock logging tests
(including the failed-DAO case), and the page tests assert the ajax
repaint and the info message, not only the model - verified by
removing each of them and watching the tests fail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ser default

The default OTP type and the "mandatory OTP without a type" condition were
spelled out separately in the service layer and in both admin pages, so
changing the rule in one place would silently leave the other previewing
something else. Move both into OtpTypeDefaults next to UIUser and reference
it from the service and from the ajax behavior.

UIUser.isOtpOptional defaulted to false while the DB column defaults to 'Y'.
The previous commits worked around that in CreateUserPage and in four
logging-test fixtures instead of fixing the field, which left the trap armed
for the next object built in code: it would get mandatory OTP and, since this
branch, a forced google_auth type as well. Default the field to true and drop
both workarounds - the four logging tests now fail if the default is flipped
back, which the workarounds used to hide.

Verified by mutation: restoring the false default breaks exactly those four
tests; the full reactor build stays green (156 service, 30 web).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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