Просмотр исходного кода

Merge pull request #15569 from overleaf/msm-group-sso-link-errors

[web] Error handling during SSO linking

GitOrigin-RevId: 232ef0672e93dc7c68cd45396306e8b4328a35d9
Alexandre Bourdin 2 лет назад
Родитель
Сommit
6852ad2be7

+ 9 - 23
services/web/app/src/Features/Subscription/GroupSSOHandler.js

@@ -5,17 +5,17 @@ const SAMLIdentityManager = require('../User/SAMLIdentityManager')
 const { User } = require('../../models/User')
 const { User } = require('../../models/User')
 const Errors = require('../Errors/Errors')
 const Errors = require('../Errors/Errors')
 
 
-async function canEnrollInSubscription(userId, subscription) {
-  const ssoEnabled = await isSSOEnabled(subscription)
-  if (!ssoEnabled) {
-    return false
+async function checkUserCanEnrollInSubscription(userId, subscription) {
+  const ssoConfig = await SSOConfig.findById(subscription?.ssoConfig).exec()
+  if (!ssoConfig?.enabled) {
+    throw new Errors.SAMLGroupSSODisabledError()
   }
   }
 
 
   const userIsMember = subscription.member_ids.some(
   const userIsMember = subscription.member_ids.some(
     memberId => memberId.toString() === userId.toString()
     memberId => memberId.toString() === userId.toString()
   )
   )
   if (!userIsMember) {
   if (!userIsMember) {
-    return false
+    throw new Errors.SAMLGroupSSOLoginIdentityNotFoundError()
   }
   }
 
 
   const user = await User.findOne(
   const user = await User.findOne(
@@ -27,9 +27,8 @@ async function canEnrollInSubscription(userId, subscription) {
     enrollment => enrollment.groupId.toString() === subscription._id.toString()
     enrollment => enrollment.groupId.toString() === subscription._id.toString()
   )
   )
   if (userIsEnrolled) {
   if (userIsEnrolled) {
-    return false
+    throw new Errors.SAMLIdentityExistsError()
   }
   }
-  return true
 }
 }
 
 
 async function enrollInSubscription(
 async function enrollInSubscription(
@@ -39,15 +38,8 @@ async function enrollInSubscription(
   userIdAttribute,
   userIdAttribute,
   auditLog
   auditLog
 ) {
 ) {
-  const canEnroll = await canEnrollInSubscription(userId, subscription)
-  if (!canEnroll) {
-    throw new Errors.SubscriptionNotFoundError(
-      'cannot enroll user in SSO subscription',
-      {
-        info: { userId, subscription },
-      }
-    )
-  }
+  await checkUserCanEnrollInSubscription(userId, subscription)
+
   const providerId = `ol-group-subscription-id:${subscription._id.toString()}`
   const providerId = `ol-group-subscription-id:${subscription._id.toString()}`
 
 
   const userBySamlIdentifier = await SAMLIdentityManager.getUser(
   const userBySamlIdentifier = await SAMLIdentityManager.getUser(
@@ -86,15 +78,9 @@ async function enrollInSubscription(
   )
   )
 }
 }
 
 
-async function isSSOEnabled(subscription) {
-  const ssoConfig = await SSOConfig.findById(subscription.ssoConfig).exec()
-  return ssoConfig?.enabled
-}
-
 module.exports = {
 module.exports = {
   promises: {
   promises: {
-    canEnrollInSubscription,
+    checkUserCanEnrollInSubscription,
     enrollInSubscription,
     enrollInSubscription,
-    isSSOEnabled,
   },
   },
 }
 }

+ 9 - 0
services/web/frontend/extracted-translations.json

@@ -990,6 +990,12 @@
   "revoke_invite": "",
   "revoke_invite": "",
   "right": "",
   "right": "",
   "role": "",
   "role": "",
+  "saml_auth_error": "",
+  "saml_invalid_signature_error": "",
+  "saml_login_disabled_error": "",
+  "saml_login_failure": "",
+  "saml_login_identity_mismatch_error": "",
+  "saml_login_identity_not_found_error": "",
   "save": "",
   "save": "",
   "save_or_cancel-cancel": "",
   "save_or_cancel-cancel": "",
   "save_or_cancel-or": "",
   "save_or_cancel-or": "",
@@ -1116,8 +1122,11 @@
   "sso_is_enabled": "",
   "sso_is_enabled": "",
   "sso_is_enabled_explanation_1": "",
   "sso_is_enabled_explanation_1": "",
   "sso_is_enabled_explanation_2": "",
   "sso_is_enabled_explanation_2": "",
+  "sso_link_currently_signed_in": "",
   "sso_link_error": "",
   "sso_link_error": "",
   "sso_link_invite_has_been_sent_to_email": "",
   "sso_link_invite_has_been_sent_to_email": "",
+  "sso_link_now_or_later": "",
+  "sso_link_your_group_uses_sso": "",
   "sso_logs": "",
   "sso_logs": "",
   "sso_not_active": "",
   "sso_not_active": "",
   "start_a_free_trial": "",
   "start_a_free_trial": "",

+ 27 - 0
services/web/frontend/stories/subscription/sso/sso-link-interstitial.stories.tsx

@@ -0,0 +1,27 @@
+import { useMeta } from '../../hooks/use-meta'
+import SSOLinkConfirm from '../../../../modules/managed-users/frontend/js/components/sso-link-confirm'
+
+export const LinkConfirmInterstitial = () => {
+  return <SSOLinkConfirm />
+}
+
+export const LinkConfirmInterstitialWithError = () => {
+  useMeta({ 'ol-error': 'SAMLInvalidSignatureError' })
+  return <SSOLinkConfirm />
+}
+
+export default {
+  title: 'Subscription / SSO / Link',
+  component: SSOLinkConfirm,
+  decorators: [
+    (Story: any) => {
+      useMeta({ 'ol-groupId': '123' })
+      useMeta({ 'ol-email': 'user@example.com' })
+      return (
+        <div className="container">
+          <Story />
+        </div>
+      )
+    },
+  ],
+}

+ 3 - 0
services/web/locales/en.json

@@ -1690,8 +1690,11 @@
   "sso_is_enabled": "SSO is enabled",
   "sso_is_enabled": "SSO is enabled",
   "sso_is_enabled_explanation_1": "Group members will <0>only</0> be able to sign in via SSO",
   "sso_is_enabled_explanation_1": "Group members will <0>only</0> be able to sign in via SSO",
   "sso_is_enabled_explanation_2": "If there are any problems with the configuration, only you (as the group administrator) will be able to disable SSO.",
   "sso_is_enabled_explanation_2": "If there are any problems with the configuration, only you (as the group administrator) will be able to disable SSO.",
+  "sso_link_currently_signed_in": "Currently signed in as <0>__email__</0>. <1>Log out.</1>",
   "sso_link_error": "Error linking account",
   "sso_link_error": "Error linking account",
   "sso_link_invite_has_been_sent_to_email": "An SSO invite reminder has been sent to <0>__email__</0>",
   "sso_link_invite_has_been_sent_to_email": "An SSO invite reminder has been sent to <0>__email__</0>",
+  "sso_link_now_or_later": "We need to link your account with the group identity provider. You can either do this now, or do this later.",
+  "sso_link_your_group_uses_sso": "The group you are part of uses single sign-on",
   "sso_logs": "SSO Logs",
   "sso_logs": "SSO Logs",
   "sso_not_active": "SSO not active",
   "sso_not_active": "SSO not active",
   "sso_not_linked": "You have not linked your account to __provider__. Please log in to your account another way and link your __provider__ account via your account settings.",
   "sso_not_linked": "You have not linked your account to __provider__. Please log in to your account another way and link your __provider__ account via your account settings.",