Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions _build/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,15 @@
"description": "prop_register.usergroupsfield_desc",
"value": ""
},
{
"name": "usergroupsFieldDisallow",
"description": "prop_register.usergroupsfielddisallow_desc",
"value": "Administrator"
},
{
"name": "usergroupsFieldAllow",
"description": "prop_register.usergroupsfieldallow_desc"
},
{
"name": "submittedResourceId",
"description": "prop_register.submittedresourceid_desc",
Expand Down
2 changes: 2 additions & 0 deletions core/components/login/lexicon/en/properties.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
$_lang['prop_register.submitvar_desc'] = 'The var to check for to load the Register functionality. If empty or set to false, Register will process the form on all POST requests.';
$_lang['prop_register.usergroups_desc'] = 'Optional. A comma-separated list of User Group names or IDs to add the newly-registered User to.';
$_lang['prop_register.usergroupsfield_desc'] = 'The name of the field to use to specify the User Group(s) to automatically add the new User to. Only used if this value is not blank.';
$_lang['prop_register.usergroupsfielddisallow_desc'] = 'Optional. A comma-separated list of User Group names or IDs to prevent the newly-registered User from being added to. Only used if this value is not blank.';
$_lang['prop_register.usergroupsfieldallow_desc'] = 'Optional. A comma-separated allowlist of User Group names or IDs the newly-registered User can be added to. Only used if this value is not blank.';
$_lang['prop_register.submittedresourceid_desc'] = 'If set, will redirect to the specified Resource after the User submits the registration form.';
$_lang['prop_register.usernamefield_desc'] = 'The name of the field to use for the new User’s username.';
$_lang['prop_register.passwordfield_desc'] = 'The name of the field to use for the new User’s password.';
Expand Down
64 changes: 62 additions & 2 deletions core/components/login/processors/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ public function setUserFields() {
/* add user groups, if set */
$userGroupsField = $this->controller->getProperty('usergroupsField','');
$userGroups = !empty($userGroupsField) && array_key_exists($userGroupsField,$fields) ? $fields[$userGroupsField] : array();
$this->setUserGroups($userGroups);
$userGroupsFieldDisallow = $this->controller->getProperty('usergroupsFieldDisallow','Administrator');
$userGroupsFieldAllow = $this->controller->getProperty('usergroupsFieldAllow','');
$this->setUserGroups($userGroups, $userGroupsFieldDisallow, $userGroupsFieldAllow);
}

/**
Expand Down Expand Up @@ -198,12 +200,16 @@ public function filterAllowedFields(array $fields = array()) {
* @param string $userGroups
* @return array
*/
public function setUserGroups($userGroups) {
public function setUserGroups($userGroups, $userGroupsFieldDisallow = 'Administrator', $userGroupsFieldAllow = '') {
$added = array();
/* if $userGroups set in form, override here; otherwise use snippet property */
$this->userGroups = !empty($userGroups) ? $userGroups : $this->controller->getProperty('usergroups', '');
if (!empty($this->userGroups)) {
$this->userGroups = is_array($this->userGroups) ? $this->userGroups : explode(',',$this->userGroups);
$disallowed = $this->getUserGroups($userGroupsFieldDisallow);
$disallowedKeys = array_keys($disallowed);
$allowed = $this->getUserGroups($userGroupsFieldAllow);
$allowedKeys = array_keys($allowed);

foreach ($this->userGroups as $userGroupMeta) {
$userGroupMeta = explode(':',$userGroupMeta);
Expand All @@ -221,6 +227,37 @@ public function setUserGroups($userGroups) {
/** @var modUserGroupRole $role */
$role = $this->modx->getObject('modUserGroupRole',array('name' => $rolePk));

/* check if role is disallowed */
if (in_array($userGroup->get('name'), $disallowedKeys, true) ||
in_array($userGroup->get('id'), $disallowedKeys, true)) {
$disallowedKey = in_array($userGroup->get('name'), $disallowedKeys, true) ?
$userGroup->get('name') : $userGroup->get('id');
$disallowedRank = $disallowed[$disallowedKey];
if ($disallowedRank) {
if ($role && ($role->get('rank') < $disallowedRank)) {
continue;
}
} else {
continue;
}
}

if (!empty($allowedKeys)) {
if (!in_array($userGroup->get('name'), $allowedKeys, true) &&
!in_array($userGroup->get('id'), $allowedKeys, true)) {
continue;
}
$allowKey = in_array($userGroup->get('name'), $allowedKeys, true) ?
$userGroup->get('name') : $userGroup->get('id');
$allowRank = $allowed[$allowKey];
if ($allowRank) {
if ($role && ($role->get('rank') < $allowRank)) {
continue;
}
}
}


/* create membership */
/** @var modUserGroupMember $member */
$member = $this->modx->newObject('modUserGroupMember');
Expand Down Expand Up @@ -444,5 +481,28 @@ public function autoLogin() {

return true;
}

private function getUserGroups($userGroupsFieldDisallow): array
{
$userGroupsDisallowed = array();
$userGroupsFieldDisallow = is_array($userGroupsFieldDisallow) ?
$userGroupsFieldDisallow : explode(',',$userGroupsFieldDisallow);
foreach ($userGroupsFieldDisallow as $userGroupDisallow) {
$groupRole = explode(':',$userGroupDisallow);
$rank = 0;
if (empty($groupRole[0])) continue;
if (isset($groupRole[1]) && !empty($groupRole[1])) {
$role_pk = (int) $groupRole[1] > 0 ? ['id' => (int) $groupRole[1]] : ['name' => $groupRole[1]];
$role = $this->modx->getObject('modUserGroupRole', $role_pk);
if ($role) {
$rank = $role->get('rank');
} else if ((int) $groupRole[1] > 0) {
$rank = (int) $groupRole[1];
}
}
$userGroupsDisallowed[$groupRole[0]] = $rank;
}
return $userGroupsDisallowed;
}
}
return 'LoginRegisterProcessor';