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

[web] Error handling during SSO linking

GitOrigin-RevId: 232ef0672e93dc7c68cd45396306e8b4328a35d9
This commit is contained in:
Alexandre Bourdin 2023-11-06 15:26:45 +01:00 committed by Copybot
parent 2783e89bc3
commit 6852ad2be7
4 changed files with 48 additions and 23 deletions

View file

@ -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) { async function checkUserCanEnrollInSubscription(userId, subscription) {
const ssoEnabled = await isSSOEnabled(subscription) const ssoConfig = await SSOConfig.findById(subscription?.ssoConfig).exec()
if (!ssoEnabled) { if (!ssoConfig?.enabled) {
return false 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) await checkUserCanEnrollInSubscription(userId, subscription)
if (!canEnroll) {
throw new Errors.SubscriptionNotFoundError(
'cannot enroll user in SSO subscription',
{
info: { 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,
}, },
} }

View file

@ -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": "",

View file

@ -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>
)
},
],
}

View file

@ -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.",