Skip to content

feat: allow organization owners to disable and re-enable managed users (SSO users)#3759

Open
Anty0 wants to merge 3 commits into
mainfrom
jirikuchynka/reenable-managed-users
Open

feat: allow organization owners to disable and re-enable managed users (SSO users)#3759
Anty0 wants to merge 3 commits into
mainfrom
jirikuchynka/reenable-managed-users

Conversation

@Anty0

@Anty0 Anty0 commented Jun 17, 2026

Copy link
Copy Markdown
Member

Closes #3275.

TLDR: This allows owners of SSO-enabled organizations to enable or disable their users. Because SSO accounts can't leave the organization that manages them, this is the only way to "get rid" of existing users.

The current implementation disables the managed account when the organization owner attempts to remove it from the organization. This behavior wasn't transparent to users, and it didn't allow the organization owner to re-enable accounts disabled this way.

Design

Remove user (existing option):
Screenshot 2026-06-17 at 16 07 50

Disable user:
Screenshot 2026-06-17 at 18 42 01

Re-enable user:
Screenshot 2026-06-17 at 16 51 54

Summary

  • Add owner-only, super-auth PUT /v2/organizations/{organizationId}/users/{userId}/disable and /enable endpoints to disable and re-enable accounts of users managed by the organization.
  • Revert the fix: allow disabling accounts of managed users when user cannot be removed - allows owners of organizations with sso to remove users #3263 hotfix that overloaded the remove-user DELETE endpoint: removing a managed user is rejected again (USER_IS_MANAGED_BY_ORGANIZATION); disabling/enabling is now done via the dedicated endpoints.
  • Keep disabled managed users visible in the organization member list, grayed out and labelled, with enable/disable toggle controls (non-managed members keep the remove action; managed members no longer show a non-functional leave button). The member-list query scopes disabled-visibility to managed users (disabledAt is null or managed), so admin-disabled non-managed accounts stay hidden as before.
  • Expose managed / disabled flags on the organization member model.
  • Make UserAccountService.disable/enable idempotent (no duplicate OnUserCountChanged event or state change on a no-op, clean NotFound for a missing user). This also changes the existing admin disable/enable endpoints from erroring to a no-op on repeat calls.
  • Per the existing model, an org owner may re-enable any user the org manages, including one disabled by a platform admin (no disabled-by provenance tracked).
  • Tests: org-owner disable/enable (scope, self-guard, kill-switch for JWT + PAT, re-enable restored access, idempotency, cross-org rejection, managed-user cannot leave/be removed, listing visibility, project-listing divergence), service-level seat-event assertions, admin idempotency, and updated e2e.

Summary by CodeRabbit

Summary

  • New Features

    • Organization owners can disable and re-enable managed users via new disable/enable action controls.
    • Organization member listings now display managed/disabled status, including a disabled label for managed users.
  • Behavior Changes

    • Disable/enable is idempotent (repeated actions don’t cause extra changes).
    • Self-disable is blocked, and only authorized users can manage managed-user state.
    • Disabled managed users are hidden from project listings while staying visible in organization listings.
  • Tests

    • Added/updated backend, UI, and end-to-end tests covering state transitions, listing behavior, and token/access effects.

- Add owner-only PUT endpoints to disable/enable accounts of users managed by the organization
- Revert the #3263 hotfix that overloaded the remove-user DELETE endpoint to disable managed users
- Keep disabled managed users visible in the org member list (grayed out) with enable/disable controls
- Make UserAccountService.disable/enable idempotent (no event/state change on a no-op; admin endpoints inherit this)
- Add backend, service-event, and e2e tests
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds organization-owner-scoped PUT endpoints to disable and re-enable managed users, replacing the prior remove-or-deactivate flow. The UserAccountService gains idempotency guards for disable/enable operations. The member listing query is updated to surface managed-disabled users. Frontend DisableUserButton and EnableUserButton components are added, MemberItem is refactored, and the full stack is covered by new backend and Cypress tests.

Changes

Managed User Disable/Enable Feature

Layer / File(s) Summary
Data contracts: view, model, error code
backend/data/src/main/kotlin/io/tolgee/constants/Message.kt, backend/data/src/main/kotlin/io/tolgee/model/views/UserAccountWithOrganizationRoleView.kt, backend/api/src/main/kotlin/io/tolgee/hateoas/organization/UserAccountWithOrganizationRoleModel.kt, backend/api/src/main/kotlin/io/tolgee/hateoas/organization/UserAccountWithOrganizationRoleModelAssembler.kt
Adds USER_IS_NOT_MANAGED_BY_ORGANIZATION enum value, extends UserAccountWithOrganizationRoleView with managed/disabledAt, adds corresponding managed/disabled booleans to the HATEOAS model, and populates them in the assembler.
Repository query and UserAccountService idempotency
backend/data/src/main/kotlin/io/tolgee/repository/UserAccountRepository.kt, backend/data/src/main/kotlin/io/tolgee/service/security/UserAccountService.kt
Adds findActiveOrDisabled(id) overload, removes findDisabled, updates getAllInOrganization JPQL to include managed-disabled users, and adds early-return no-op guards to disable/enable to prevent duplicate OnUserCountChanged events.
OrganizationRoleService refactor
backend/data/src/main/kotlin/io/tolgee/service/organization/OrganizationRoleService.kt
Replaces removeOrDeactivateUser with an explicit managed-by check in removeUser (throws ValidationException for managed users), adds disableUser and enableUser transactional methods with isManagedBy guard.
OrganizationController endpoints
backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/organization/OrganizationController.kt
Updates removeUser to call the refactored service, adds owner-only PUT endpoints disableUser (with self-disable guard) and enableUser.
Test data fixture
backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/DisableManagedUserTestData.kt
Seeds organizations, a managed member, a non-managed member, a disabled non-managed member, a project-only member, a multi-project member, and an other-org-managed user for use across multiple test suites.
Backend tests
backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerManagedUsersTest.kt, backend/app/src/test/kotlin/io/tolgee/service/UserAccountDisableEnableEventTest.kt, backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/administration/AdministrationControllerTest.kt, backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt, test assertion helper refactors
Adds full controller test suite covering disable/enable behavior, listing visibility, token invalidation, authorization boundaries, and idempotency; adds event emission validation via OnUserCountChanged capture; updates test data cleanup to handle disabled accounts; refactors existing test assertions to use modern assertion style.
Generated API schema and error translation
webapp/src/service/apiSchema.generated.ts, webapp/src/translationTools/useErrorTranslation.ts
Wires new org-scoped disable/enable paths, renames admin operation keys to disableUser_1/enableUser_1, extends UserAccountWithOrganizationRoleModel schema, adds user_is_not_managed_by_organization to error enums, and maps it in useErrorTranslation.
Frontend UI: DisableUserButton, EnableUserButton, MemberItem
webapp/src/views/organizations/members/DisableUserButton.tsx, webapp/src/views/organizations/members/EnableUserButton.tsx, webapp/src/views/organizations/members/MemberItem.tsx, e2e/cypress/support/dataCyType.d.ts
Adds DisableUserButton and EnableUserButton components with confirmation+mutation flows, refactors MemberItem.renderMemberAction to dispatch leave/enable/disable/remove based on user state, adds StyledDisabledLabel, and registers new Cypress data-cy selectors.
Cypress E2E tests
e2e/cypress/e2e/organizations/organizationsMembers.cy.ts
Replaces old managed-user-removal test with disable/re-enable flow assertions (label toggling, button state) and non-managed member UI control assertions.

Sequence Diagram(s)

sequenceDiagram
  participant OrgOwner as Org Owner (Browser)
  participant MemberItem as MemberItem / DisableUserButton
  participant OrgController as OrganizationController
  participant OrgRoleService as OrganizationRoleService
  participant UserAccountService as UserAccountService
  participant DB as UserAccountRepository

  OrgOwner->>MemberItem: click Disable
  MemberItem->>MemberItem: open confirmation dialog
  OrgOwner->>MemberItem: confirm
  MemberItem->>OrgController: PUT /v2/organizations/{orgId}/users/{userId}/disable
  OrgController->>OrgController: guard: reject if userId == authUser.id
  OrgController->>OrgRoleService: disableUser(userId, orgId)
  OrgRoleService->>OrgRoleService: isManagedBy(userId, orgId)
  alt not managed by this org
    OrgRoleService-->>OrgController: ValidationException (USER_IS_NOT_MANAGED_BY_ORGANIZATION)
    OrgController-->>MemberItem: 400 Bad Request
  else is managed
    OrgRoleService->>UserAccountService: disable(userId)
    UserAccountService->>DB: findActiveOrDisabled(userId)
    DB-->>UserAccountService: UserAccount
    UserAccountService->>UserAccountService: early-return if already disabled
    UserAccountService->>DB: save(disabledAt = now)
    UserAccountService->>UserAccountService: publish OnUserCountChanged(decrease)
    OrgRoleService-->>OrgController: ok
    OrgController-->>MemberItem: 200 OK
    MemberItem->>MemberItem: invalidate /v2/organizations cache
    MemberItem-->>OrgOwner: show success toast + disabled label
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • tolgee/tolgee-platform#3263: Introduced the original managed-user deactivation via the leave/remove endpoint (removeOrDeactivateUser) that this PR explicitly replaces with dedicated disable/enable endpoints.
  • tolgee/tolgee-platform#3461: Shares the same disabled-account foundation (UserAccountRepository.findActiveOrDisabled, disabledAt field handling) and authentication flow integration that must detect disabled users.

Suggested labels

enhancement

Suggested reviewers

  • JanCizmar
  • dkrizan

🐇 Hop hop, a button appears,
Disable the user, no more fears!
Enable them back with a click,
The managed users — what a trick!
No more leaving, no more confusion,
Just toggles for the organization's inclusion. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed All coding requirements from issue #3275 are met: dedicated disable/enable endpoints added, managed users remain visible but distinguished, owner controls implemented, previous hotfix reverted, and comprehensive tests included.
Out of Scope Changes check ✅ Passed All changes align with PR objectives. Minor improvements to test assertion syntax and test cleanup are supporting changes that enhance code quality without introducing unrelated functionality.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: adding disable/re-enable functionality for managed (SSO) users in organizations, which is the central objective of all changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jirikuchynka/reenable-managed-users

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (2)
webapp/src/views/organizations/members/DisableUserButton.tsx (1)

8-9: ⚡ Quick win

Use Tolgee path alias instead of a relative import.

Please switch this new import to the tg.views alias to keep import style consistent with repo conventions.

Suggested patch
-import { useOrganization } from '../useOrganization';
+import { useOrganization } from 'tg.views/organizations/useOrganization';

As per coding guidelines, “Use Tolgee custom TypeScript path aliases (tg.component, tg.service, tg.hooks, tg.views, tg.globalContext) instead of relative imports.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/views/organizations/members/DisableUserButton.tsx` around lines 8
- 9, The import statement for useOrganization is using a relative path import
(../useOrganization) instead of the Tolgee path alias convention. Replace the
relative import of useOrganization with the tg.views path alias to maintain
consistency with repository conventions. Specifically, change the import
statement that currently uses '../useOrganization' to use the tg.views alias
instead.

Source: Coding guidelines

webapp/src/views/organizations/members/EnableUserButton.tsx (1)

8-9: ⚡ Quick win

Use Tolgee path alias instead of a relative import.

Please switch this new import to the tg.views alias for consistency with the webapp import convention.

Suggested patch
-import { useOrganization } from '../useOrganization';
+import { useOrganization } from 'tg.views/organizations/useOrganization';

As per coding guidelines, “Use Tolgee custom TypeScript path aliases (tg.component, tg.service, tg.hooks, tg.views, tg.globalContext) instead of relative imports.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/views/organizations/members/EnableUserButton.tsx` around lines 8 -
9, The import statement for useOrganization is using a relative path import
instead of following the Tolgee path alias convention. Replace the relative
import path for useOrganization with the tg.views path alias to be consistent
with other imports in the codebase and align with the webapp import conventions.
The messageService import on line 9 already correctly uses the tg.service alias
as a reference for the proper pattern to follow.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/administration/AdministrationControllerTest.kt`:
- Line 160: In the AdministrationControllerTest class, the assertion on line 160
uses `.isNotNull` without parentheses, which is inconsistent with the method
call syntax used on line 156 with `.isNull()`. Add parentheses to the isNotNull
assertion to make it a proper method call: change `.isNotNull` to `.isNotNull()`
to match the consistent assertion pattern throughout the test.

In
`@backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerManagedUsersTest.kt`:
- Around line 25-30: The test class prepareManagedUsersTestData method uses
`@BeforeEach` to create and save test data but lacks a corresponding `@AfterEach`
cleanup method, which violates test isolation guidelines. Add an `@AfterEach`
annotated method that uses testDataService to clean up the testData that was
saved in prepareManagedUsersTestData, ensuring each test starts with a clean
state and no test data persists between test executions.

In
`@backend/app/src/test/kotlin/io/tolgee/service/UserAccountDisableEnableEventTest.kt`:
- Around line 56-60: The saveTestData() helper method persists TestData but
lacks a corresponding cleanup hook, violating the backend test convention. Add
an `@AfterEach` annotated cleanup method that disposes of or clears the saved
TestData. Store the DisableManagedUserTestData instance returned from
saveTestData() as a class-level property so it can be accessed in the cleanup
method, then invoke the appropriate testDataService cleanup method in `@AfterEach`
to ensure proper test isolation.

In
`@backend/data/src/main/kotlin/io/tolgee/service/security/UserAccountService.kt`:
- Around line 646-650: The disable/enable user transitions in this code have a
race condition where concurrent requests can both pass the idempotency check and
emit OnUserCountChanged events. Make these operations atomic by either
implementing optimistic locking with a `@Version` field on the User entity or by
refactoring the logic in the repository to use an atomic UPDATE query that only
modifies the user if the disabledAt/enabledAt field has not already changed.
This ensures that the read-check-write-publish sequence in both the method that
sets disabledAt (around line 646) and the corresponding method that resets it
(around line 656) cannot be interrupted by concurrent requests, preserving true
idempotency.

In `@e2e/cypress/e2e/organizations/organizationsMembers.cy.ts`:
- Around line 77-85: Replace the text-dependent cy.contains('Lonely Developer')
calls with data-cy attribute-based selection using gcy() or cy.gcy(). Instead of
locating the organization-member-item row via text content, use a deterministic
data-cy selector to identify the specific member row, then use that hook to
target the organization-members-remove-user-button and
organization-members-disable-user-button elements. If the member row does not
have a suitable data-cy attribute, add one in the UI component to make it
identifiable without relying on text content. Apply this same fix to all
affected test blocks at lines 91-98, 104-111, and 117-127.

In `@webapp/src/translationTools/useErrorTranslation.ts`:
- Around line 177-178: The t() function call for the
'user_is_not_managed_by_organization' case is missing a defaultValue parameter,
which means the UI will display untranslated text before the Tolgee translations
are synced. Add a defaultValue parameter to the t() function call with a
meaningful fallback string that describes the error when the translation is not
yet available. This ensures the UI remains readable even before translations are
uploaded to Tolgee.

---

Nitpick comments:
In `@webapp/src/views/organizations/members/DisableUserButton.tsx`:
- Around line 8-9: The import statement for useOrganization is using a relative
path import (../useOrganization) instead of the Tolgee path alias convention.
Replace the relative import of useOrganization with the tg.views path alias to
maintain consistency with repository conventions. Specifically, change the
import statement that currently uses '../useOrganization' to use the tg.views
alias instead.

In `@webapp/src/views/organizations/members/EnableUserButton.tsx`:
- Around line 8-9: The import statement for useOrganization is using a relative
path import instead of following the Tolgee path alias convention. Replace the
relative import path for useOrganization with the tg.views path alias to be
consistent with other imports in the codebase and align with the webapp import
conventions. The messageService import on line 9 already correctly uses the
tg.service alias as a reference for the proper pattern to follow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7e9dc91f-f7c2-47df-97ae-23fd50508d54

📥 Commits

Reviewing files that changed from the base of the PR and between b965b1b and 8a80128.

📒 Files selected for processing (19)
  • backend/api/src/main/kotlin/io/tolgee/api/v2/controllers/organization/OrganizationController.kt
  • backend/api/src/main/kotlin/io/tolgee/hateoas/organization/UserAccountWithOrganizationRoleModel.kt
  • backend/api/src/main/kotlin/io/tolgee/hateoas/organization/UserAccountWithOrganizationRoleModelAssembler.kt
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/administration/AdministrationControllerTest.kt
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerManagedUsersTest.kt
  • backend/app/src/test/kotlin/io/tolgee/service/UserAccountDisableEnableEventTest.kt
  • backend/data/src/main/kotlin/io/tolgee/constants/Message.kt
  • backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/data/DisableManagedUserTestData.kt
  • backend/data/src/main/kotlin/io/tolgee/model/views/UserAccountWithOrganizationRoleView.kt
  • backend/data/src/main/kotlin/io/tolgee/repository/UserAccountRepository.kt
  • backend/data/src/main/kotlin/io/tolgee/service/organization/OrganizationRoleService.kt
  • backend/data/src/main/kotlin/io/tolgee/service/security/UserAccountService.kt
  • e2e/cypress/e2e/organizations/organizationsMembers.cy.ts
  • e2e/cypress/support/dataCyType.d.ts
  • webapp/src/service/apiSchema.generated.ts
  • webapp/src/translationTools/useErrorTranslation.ts
  • webapp/src/views/organizations/members/DisableUserButton.tsx
  • webapp/src/views/organizations/members/EnableUserButton.tsx
  • webapp/src/views/organizations/members/MemberItem.tsx

Comment thread e2e/cypress/e2e/organizations/organizationsMembers.cy.ts
Comment thread webapp/src/translationTools/useErrorTranslation.ts
Anty0 added 2 commits June 17, 2026 17:28
- Use the Kotlin `.assert` form for isNotNull/isNull in the touched and surrounding organization tests
- Add @AfterEach testData cleanup to the disable/enable test classes (and AdministrationControllerTest)
- Fix cleanTestData to delete disabled users too (findActiveOrDisabled), so disabled test accounts don't leak across the shared test DB

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/administration/AdministrationControllerTest.kt (1)

160-168: ⚠️ Potential issue | 🟡 Minor | 💤 Low value

Add parentheses to isNotNull on line 167 for consistency.

Line 163 uses .isNull() with parentheses, but line 167 uses .isNotNull without parentheses. This inconsistency within the same test should be resolved by adding () to match method call syntax.

-    userAccountService.findActive(testData.user.id).assert.isNotNull
+    userAccountService.findActive(testData.user.id).assert.isNotNull()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/administration/AdministrationControllerTest.kt`
around lines 160 - 168, In the test function disable and enable are idempotent,
add parentheses to the isNotNull method call to make it isNotNull() to match the
syntax used in the isNull() call earlier in the same test. This ensures
consistent method call syntax throughout the test function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In
`@backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/administration/AdministrationControllerTest.kt`:
- Around line 160-168: In the test function disable and enable are idempotent,
add parentheses to the isNotNull method call to make it isNotNull() to match the
syntax used in the isNull() call earlier in the same test. This ensures
consistent method call syntax throughout the test function.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 59b6ae2c-e6d8-4984-9344-01f7b12708cf

📥 Commits

Reviewing files that changed from the base of the PR and between 410a825 and 73c3426.

📒 Files selected for processing (7)
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/administration/AdministrationControllerTest.kt
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerLeavingTest.kt
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerManagedUsersTest.kt
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerMembersTest.kt
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerTest.kt
  • backend/app/src/test/kotlin/io/tolgee/service/UserAccountDisableEnableEventTest.kt
  • backend/data/src/main/kotlin/io/tolgee/development/testDataBuilder/TestDataService.kt
✅ Files skipped from review due to trivial changes (1)
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerLeavingTest.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • backend/app/src/test/kotlin/io/tolgee/api/v2/controllers/organizationController/OrganizationControllerManagedUsersTest.kt
  • backend/app/src/test/kotlin/io/tolgee/service/UserAccountDisableEnableEventTest.kt

@Anty0 Anty0 changed the title feat: allow organization owners to disable and re-enable managed users feat: allow organization owners to disable and re-enable managed users (SSO users) Jun 17, 2026
@Anty0
Anty0 requested a review from dkrizan June 17, 2026 16:57

@dkrizan dkrizan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@Anty0, General question - I thought the purpose of disabling a user was to restrict it only to Admins. This means we can no longer disable a user from the Admin section because any organization manager or owner can re-enable them. Am I correct? If this is the intended functionality, I’m fine with it.

@Anty0

Anty0 commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

Yes, for managed users, the organization manages their accounts, including whether they are disabled. We can still disable the organization owner's account - doing so would prevent the organization from re-enabling its users, so there is still a way. I don't expect us to selectively disable individual accounts within an SSO organization.

If we want it separate, I could probably add a reason for the account being disabled and only allow the org owner to re-enable if they were the one who disabled it.

@Anty0
Anty0 requested a review from dkrizan June 19, 2026 11:25
@dkrizan

dkrizan commented Jun 19, 2026

Copy link
Copy Markdown
Member

My only concern is the admin moderation path, which this currently regresses. Maybe, keep disabledAt as the single login kill-switch and add a disabledBy flag (ADMIN / ORGANIZATION). Org enable only works when disabledBy == ORGANIZATION, and the member list surfaces org-disabled users only — so an admin-disabled account stays out of the org owner's reach. Cheap to add and closes the regression.

What do you think ?

@Anty0

Anty0 commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

Sure, I can do that. I didn't think it was worth the effort :3
I'll take a look at it during the next cooldown. ^^

@github-actions

Copy link
Copy Markdown
Contributor

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions Bot added the stale label Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for re-enabling disabled managed users by organization owners

2 participants