mirror of
https://github.com/overleaf/overleaf.git
synced 2025-03-13 10:53:15 +00:00
Merge pull request #13560 from overleaf/bg-group-policy-tests
add policies and tests for managed users GitOrigin-RevId: 1f17e0911306b7dba8f4e2ab25a320a08c44702c
This commit is contained in:
parent
3b60d05074
commit
efdc2dfca4
3 changed files with 119 additions and 3 deletions
|
@ -1,3 +1,93 @@
|
|||
const {
|
||||
registerCapability,
|
||||
registerPolicy,
|
||||
} = require('../Authorization/PermissionsManager')
|
||||
const SubscriptionLocator = require('./SubscriptionLocator')
|
||||
|
||||
// This file defines the capabilities and policies that are used to
|
||||
// determine what managed users can and cannot do.
|
||||
|
||||
// Register the capability for a user to delete their own account.
|
||||
registerCapability('delete-own-account', { default: true })
|
||||
|
||||
// Register the capability for a user to add a secondary email to their account.
|
||||
registerCapability('add-secondary-email', { default: true })
|
||||
|
||||
// Register the capability for a user to sign in with Google to their account
|
||||
registerCapability('link-google-sso', { default: true })
|
||||
|
||||
// Register the capability for a user to link other third party SSO to their account
|
||||
registerCapability('link-other-third-party-sso', { default: true })
|
||||
|
||||
// Register the capability for a user to leave a managed group subscription.
|
||||
registerCapability('leave-managing-group-subscription', { default: true })
|
||||
|
||||
// Register the capability for a user to start a subscription.
|
||||
registerCapability('start-subscription', { default: true })
|
||||
|
||||
// Register a policy to prevent a user deleting their own account.
|
||||
registerPolicy('userCannotDeleteOwnAccount', {
|
||||
'delete-own-account': false,
|
||||
})
|
||||
|
||||
// Register a policy to prevent a user having secondary email addresses on their account.
|
||||
registerPolicy(
|
||||
'userCannotAddSecondaryEmail',
|
||||
{
|
||||
'add-secondary-email': false,
|
||||
},
|
||||
{
|
||||
validator: async user => {
|
||||
// return true if the user does not have any secondary emails
|
||||
return user.emails.length === 1
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Register a policy to prevent a user leaving the group subscription they are managed by.
|
||||
registerPolicy('userCannotLeaveManagingGroupSubscription', {
|
||||
'leave-managing-group-subscription': false,
|
||||
})
|
||||
|
||||
// Register a policy to prevent a user having third-party SSO linked to their account.
|
||||
registerPolicy(
|
||||
'userCannotHaveGoogleSSO',
|
||||
{ 'link-google-sso': false },
|
||||
{
|
||||
// return true if the user does not have Google SSO linked
|
||||
validator: async user =>
|
||||
!user.thirdPartyIdentifiers?.some(
|
||||
identifier => identifier.providerId === 'google'
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
// Register a policy to prevent a user having third-party SSO linked to their account.
|
||||
registerPolicy(
|
||||
'userCannotHaveOtherThirdPartySSO',
|
||||
{ 'link-other-third-party-sso': false },
|
||||
{
|
||||
// return true if the user does not have any other third party SSO linked
|
||||
validator: async user =>
|
||||
!user.thirdPartyIdentifiers?.some(
|
||||
identifier => identifier.providerId !== 'google'
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
// Register a policy to prevent a user having an active personal subscription.
|
||||
registerPolicy(
|
||||
'userCannotHaveSubscription',
|
||||
{ 'start-subscription': false },
|
||||
{
|
||||
validator: async user => {
|
||||
return !(await SubscriptionLocator.promises.getUserIndividualSubscription(
|
||||
user
|
||||
))
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* Returns the default group policy for managed users.
|
||||
* Managed users are users who are part of a group subscription, and are
|
||||
|
@ -14,7 +104,8 @@ function getDefaultPolicy() {
|
|||
userCannotAddSecondaryEmail: true,
|
||||
userCannotHaveSubscription: true,
|
||||
userCannotLeaveManagingGroupSubscription: true,
|
||||
userCannotHaveThirdPartySSO: true,
|
||||
userCannotHaveGoogleSSO: false, // we want to allow google SSO by default
|
||||
userCannotHaveOtherThirdPartySSO: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,11 @@ const GroupPolicySchema = new Schema(
|
|||
// User can't choose to leave the group subscription they are managed by
|
||||
userCannotLeaveManagingGroupSubscription: Boolean,
|
||||
|
||||
// User can't have Google/Twitter/ORCID SSO active on their account, nor can they link it to their account
|
||||
userCannotHaveThirdPartySSO: Boolean,
|
||||
// User can't have a Google SSO account, nor can they link it to their account
|
||||
userCannotHaveGoogleSSO: Boolean,
|
||||
|
||||
// User can't have other third-party SSO (e.g. Twitter/ORCID/IEEE) active on their account, nor can they link it to their account
|
||||
userCannotHaveOtherThirdPartySSO: Boolean,
|
||||
},
|
||||
{ minimize: false }
|
||||
)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
const { db, ObjectId } = require('../../../../app/src/infrastructure/mongodb')
|
||||
const { expect } = require('chai')
|
||||
const { promisify } = require('util')
|
||||
const SubscriptionUpdater = require('../../../../app/src/Features/Subscription/SubscriptionUpdater')
|
||||
const ManagedUsersHandler = require('../../../../app/src/Features/Subscription/ManagedUsersHandler')
|
||||
const PermissionsManager = require('../../../../app/src/Features/Authorization/PermissionsManager')
|
||||
const SubscriptionModel =
|
||||
require('../../../../app/src/models/Subscription').Subscription
|
||||
const DeletedSubscriptionModel =
|
||||
|
@ -68,6 +70,14 @@ class Subscription {
|
|||
ManagedUsersHandler.getGroupPolicyForUser(user, callback)
|
||||
}
|
||||
|
||||
getCapabilities(groupPolicy) {
|
||||
return PermissionsManager.getUserCapabilities(groupPolicy)
|
||||
}
|
||||
|
||||
getUserValidationStatus(user, groupPolicy, callback) {
|
||||
PermissionsManager.getUserValidationStatus(user, groupPolicy, callback)
|
||||
}
|
||||
|
||||
enrollManagedUser(user, callback) {
|
||||
SubscriptionModel.findById(this._id).exec((error, subscription) => {
|
||||
if (error) {
|
||||
|
@ -108,4 +118,16 @@ class Subscription {
|
|||
}
|
||||
}
|
||||
|
||||
Subscription.promises = class extends Subscription {}
|
||||
|
||||
// promisify User class methods - works for methods with 0-1 output parameters,
|
||||
// otherwise we will need to implement the method manually instead
|
||||
const nonPromiseMethods = ['constructor', 'getCapabilities']
|
||||
Object.getOwnPropertyNames(Subscription.prototype).forEach(methodName => {
|
||||
const method = Subscription.prototype[methodName]
|
||||
if (typeof method === 'function' && !nonPromiseMethods.includes(methodName)) {
|
||||
Subscription.promises.prototype[methodName] = promisify(method)
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = Subscription
|
||||
|
|
Loading…
Reference in a new issue