Files
Verso/services/web/app/src/Features/Subscription/GroupSSOHandler.js
T
Miguel SerranoandCopybot e22e8ff7a8 [web] SSO linking for existing group members (#15471)
* [web] SSO linking for existing group users

GitOrigin-RevId: 22a5a5a28a213860f88ae0284c1ef51a31bb268f
2023-11-01 09:03:19 +00:00

101 lines
2.3 KiB
JavaScript

const { SSOConfig } = require('../../models/SSOConfig')
const UserAuditLogHandler = require('../User/UserAuditLogHandler')
const UserUpdater = require('../User/UserUpdater')
const SAMLIdentityManager = require('../User/SAMLIdentityManager')
const { User } = require('../../models/User')
const Errors = require('../Errors/Errors')
async function canEnrollInSubscription(userId, subscription) {
const ssoEnabled = await isSSOEnabled(subscription)
if (!ssoEnabled) {
return false
}
const userIsMember = subscription.member_ids.some(
memberId => memberId.toString() === userId.toString()
)
if (!userIsMember) {
return false
}
const user = await User.findOne(
{ _id: userId },
{ projection: { enrollment: 1 } }
).exec()
const userIsEnrolled = user.enrollment?.sso?.some(
enrollment => enrollment.groupId.toString() === subscription._id.toString()
)
if (userIsEnrolled) {
return false
}
return true
}
async function enrollInSubscription(
userId,
subscription,
externalUserId,
userIdAttribute,
auditLog
) {
const canEnroll = await canEnrollInSubscription(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 userBySamlIdentifier = await SAMLIdentityManager.getUser(
providerId,
externalUserId,
userIdAttribute
)
if (userBySamlIdentifier) {
throw new Errors.SAMLIdentityExistsError()
}
const samlIdentifiers = {
externalUserId,
userIdAttribute,
providerId,
}
await UserUpdater.promises.updateUser(userId, {
$push: {
samlIdentifiers,
'enrollment.sso': {
groupId: subscription._id,
linkedAt: new Date(),
primary: true,
},
},
})
await UserAuditLogHandler.promises.addEntry(
userId,
'group-sso-link',
auditLog.initiatorId,
auditLog.ipAddress,
samlIdentifiers
)
}
async function isSSOEnabled(subscription) {
const ssoConfig = await SSOConfig.findById(subscription.ssoConfig).exec()
return ssoConfig?.enabled
}
module.exports = {
promises: {
canEnrollInSubscription,
enrollInSubscription,
isSSOEnabled,
},
}