diff --git a/bitwarden_license/src/Sso/Controllers/AccountController.cs b/bitwarden_license/src/Sso/Controllers/AccountController.cs index 00657a4e7f..5776912bd3 100644 --- a/bitwarden_license/src/Sso/Controllers/AccountController.cs +++ b/bitwarden_license/src/Sso/Controllers/AccountController.cs @@ -255,9 +255,12 @@ public class AccountController : Controller _logger.LogDebug("External claims: {@claims}", externalClaims); // Lookup our user and external provider info + // Note: the user will only exist if the user has already been provisioned and exists in the User table and the SSO user table. var (user, provider, providerUserId, claims, ssoConfigData) = await FindUserFromExternalProviderAsync(result); if (user == null) { + // User does not exist in SSO User table. They could have an existing BW account in the User table. + // This might be where you might initiate a custom workflow for user registration // in this sample we don't show how that would be done, as our sample implementation // simply auto-provisions new external user @@ -268,6 +271,8 @@ public class AccountController : Controller if (user != null) { + // User was JIT provisioned (this could be an existing user or a new user) + // This allows us to collect any additional claims or properties // for the specific protocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. @@ -487,12 +492,8 @@ public class AccountController : Controller throw new Exception(_i18nService.T("UserAlreadyExistsInviteProcess")); } - if (orgUser.Status == OrganizationUserStatusType.Invited) - { - // Org User is invited - they must manually accept the invite via email and authenticate with MP - // This allows us to enroll them in MP reset if required - throw new Exception(_i18nService.T("AcceptInviteBeforeUsingSSO", organization.DisplayName())); - } + EnsureOrgUserStatusAllowed(orgUser.Status, organization.DisplayName(), + allowedStatuses: [OrganizationUserStatusType.Accepted, OrganizationUserStatusType.Confirmed]); // Accepted or Confirmed - create SSO link and return; await CreateSsoUserRecord(providerUserId, existingUser.Id, orgId, orgUser); @@ -587,6 +588,36 @@ public class AccountController : Controller return user; } + private void EnsureOrgUserStatusAllowed( + OrganizationUserStatusType status, + string organizationDisplayName, + params OrganizationUserStatusType[] allowedStatuses) + { + // if this status is one of the allowed ones, just return + if (allowedStatuses.Contains(status)) + { + return; + } + + // otherwise throw the appropriate exception + switch (status) + { + case OrganizationUserStatusType.Invited: + // Org User is invited – must accept via email first + throw new Exception( + _i18nService.T("AcceptInviteBeforeUsingSSO", organizationDisplayName)); + case OrganizationUserStatusType.Revoked: + // Revoked users may not be (auto)‑provisioned + throw new Exception( + _i18nService.T("OrganizationUserAccessRevoked", organizationDisplayName)); + default: + // anything else is “unknown” + throw new Exception( + _i18nService.T("OrganizationUserUnknownStatus", organizationDisplayName)); + } + } + + private IActionResult InvalidJson(string errorMessageKey, Exception ex = null) { Response.StatusCode = ex == null ? 400 : 500; diff --git a/src/Core/Resources/SharedResources.en.resx b/src/Core/Resources/SharedResources.en.resx index 90a791222f..97cac5a610 100644 --- a/src/Core/Resources/SharedResources.en.resx +++ b/src/Core/Resources/SharedResources.en.resx @@ -532,6 +532,12 @@ To accept your invite to {0}, you must first log in using your master password. Once your invite has been accepted, you will be able to log in using SSO. + + Your access to organization {0} has been revoked. Please contact your administrator for assistance. + + + Your access to organization {0} is in an unknown state. Please contact your administrator for assistance. + You were removed from the organization managing single sign-on for your account. Contact the organization administrator for help regaining access to your account.