From 90a745610f1929aa6065b4de76b0cd9b1c76c442 Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Fri, 4 Jan 2013 19:52:36 +0100 Subject: [PATCH] Fixes permission calculation This fix is relevant for user group option types that can have a list of values (e.g. list of usable attachments). In the database, only the difference between the default value and the user group's value is stored. This difference is calculated by `IUserGroupOptionType::diff()`. When the permissions for a certain type of user groups are calculated, the difference for all relevant user groups have to be merged, which is done by `IUserGroupOptionType::merge()`. The code of the previous merge function is the same as the code of the new diff function. This worked fine when calculating the difference to store the values. But if the merge of two option values was calculated during the permission calculation for a certain type of user groups, again, the difference was calculated, not the merge. This had the effect, that if, for instance, the default value for the usable attachment types was "gif, jpg" and the value for the administrator group was "foo, jpg", administrators were only allowed to use "foo" attachments (which is the diff of the two) instead of "foo", "gif" and "jpg". --- .../lib/acp/form/UserGroupAddForm.class.php | 2 +- .../lib/acp/form/UserGroupEditForm.class.php | 2 +- .../lib/acp/form/UserGroupOptionForm.class.php | 2 +- .../group/BooleanUserGroupOptionType.class.php | 9 ++++++++- .../FileSizeUserGroupOptionType.class.php | 7 +++++++ .../user/group/IUserGroupOptionType.class.php | 10 ++++++++++ ...nfiniteIntegerUserGroupOptionType.class.php | 7 +++++++ ...InverseIntegerUserGroupOptionType.class.php | 7 +++++++ .../group/IntegerUserGroupOptionType.class.php | 7 +++++++ ...InverseIntegerUserGroupOptionType.class.php | 7 +++++++ .../group/TextUserGroupOptionType.class.php | 17 +++++++++++++++-- .../TextareaUserGroupOptionType.class.php | 18 ++++++++++++++---- .../UserGroupsUserGroupOptionType.class.php | 14 ++++++++++++-- 13 files changed, 97 insertions(+), 12 deletions(-) diff --git a/wcfsetup/install/files/lib/acp/form/UserGroupAddForm.class.php b/wcfsetup/install/files/lib/acp/form/UserGroupAddForm.class.php index 6576e6ddf4..d101e978cd 100755 --- a/wcfsetup/install/files/lib/acp/form/UserGroupAddForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/UserGroupAddForm.class.php @@ -127,7 +127,7 @@ class UserGroupAddForm extends AbstractOptionListForm { $defaultValue = $defaultGroup->getGroupOption($option->optionName); $typeObject = $this->optionHandler->getTypeObject($option->optionType); - $newValue = $typeObject->merge($defaultValue, $optionValues[$option->optionID]); + $newValue = $typeObject->diff($defaultValue, $optionValues[$option->optionID]); if ($newValue !== null) { $saveOptions[$option->optionID] = $newValue; } diff --git a/wcfsetup/install/files/lib/acp/form/UserGroupEditForm.class.php b/wcfsetup/install/files/lib/acp/form/UserGroupEditForm.class.php index 8296e82842..aa954abed8 100755 --- a/wcfsetup/install/files/lib/acp/form/UserGroupEditForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/UserGroupEditForm.class.php @@ -133,7 +133,7 @@ class UserGroupEditForm extends UserGroupAddForm { $defaultValue = $defaultGroup->getGroupOption($option->optionName); $typeObject = $this->optionHandler->getTypeObject($option->optionType); - $newValue = $typeObject->merge($defaultValue, $optionValues[$option->optionID]); + $newValue = $typeObject->diff($defaultValue, $optionValues[$option->optionID]); if ($newValue !== null) { $saveOptions[$option->optionID] = $newValue; } diff --git a/wcfsetup/install/files/lib/acp/form/UserGroupOptionForm.class.php b/wcfsetup/install/files/lib/acp/form/UserGroupOptionForm.class.php index 56416c776d..51e13ab8ab 100644 --- a/wcfsetup/install/files/lib/acp/form/UserGroupOptionForm.class.php +++ b/wcfsetup/install/files/lib/acp/form/UserGroupOptionForm.class.php @@ -199,7 +199,7 @@ class UserGroupOptionForm extends AbstractForm { // check if not editing default value if ($groupID != $this->groupEveryone->groupID) { - $newValue = $this->optionType->merge($this->defaultValue, $optionValue); + $newValue = $this->optionType->diff($this->defaultValue, $optionValue); if ($newValue === null) { unset($this->values[$groupID]); } diff --git a/wcfsetup/install/files/lib/system/option/user/group/BooleanUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/BooleanUserGroupOptionType.class.php index d2ac2acb9b..2db22d68a8 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/BooleanUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/BooleanUserGroupOptionType.class.php @@ -6,7 +6,7 @@ use wcf\system\option\BooleanOptionType; * User group option type implementation for boolean values. * * The merge of option values returns true, if at least one value is true. - * + * * @author Marcel Werk * @copyright 2001-2012 WoltLab GmbH * @license GNU Lesser General Public License @@ -15,6 +15,13 @@ use wcf\system\option\BooleanOptionType; * @category Community Framework */ class BooleanUserGroupOptionType extends BooleanOptionType implements IUserGroupOptionType { + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() + */ + public function diff($defaultValue, $groupValue) { + return $this->merge($defaultValue, $groupValue); + } + /** * @see wcf\system\option\user\group\IUserGroupOptionType::merge() */ diff --git a/wcfsetup/install/files/lib/system/option/user/group/FileSizeUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/FileSizeUserGroupOptionType.class.php index 8387aca516..14bbfa2c3e 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/FileSizeUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/FileSizeUserGroupOptionType.class.php @@ -15,6 +15,13 @@ use wcf\system\option\FileSizeOptionType; * @category Community Framework */ class FileSizeUserGroupOptionType extends FileSizeOptionType implements IUserGroupOptionType { + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() + */ + public function diff($defaultValue, $groupValue) { + return $this->merge($defaultValue, $groupValue); + } + /** * @see wcf\system\option\user.group\IUserGroupOptionType::merge() */ diff --git a/wcfsetup/install/files/lib/system/option/user/group/IUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/IUserGroupOptionType.class.php index 05af310b29..19e336df71 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/IUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/IUserGroupOptionType.class.php @@ -13,6 +13,16 @@ use wcf\system\option\IOptionType; * @category Community Framework */ interface IUserGroupOptionType extends IOptionType { + /** + * Returns the value which results by calculating the difference of the + * given values. + * + * @param mixed $defaultValue + * @param mixed $groupValue + * @return mixed + */ + public function diff($defaultValue, $groupValue); + /** * Returns the value which results by merging or null if nothing should be saved. * diff --git a/wcfsetup/install/files/lib/system/option/user/group/InfiniteIntegerUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/InfiniteIntegerUserGroupOptionType.class.php index 1a8bc7cdd2..3b584b41c1 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/InfiniteIntegerUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/InfiniteIntegerUserGroupOptionType.class.php @@ -16,6 +16,13 @@ namespace wcf\system\option\user\group; * @category Community Framework */ class InfiniteIntegerUserGroupOptionType extends IntegerUserGroupOptionType { + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() + */ + public function diff($defaultValue, $groupValue) { + return $this->merge($defaultValue, $groupValue); + } + /** * @see wcf\system\option\user\group\IUserGroupOptionType::merge() */ diff --git a/wcfsetup/install/files/lib/system/option/user/group/InfiniteInverseIntegerUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/InfiniteInverseIntegerUserGroupOptionType.class.php index f7d9c2b742..6367412114 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/InfiniteInverseIntegerUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/InfiniteInverseIntegerUserGroupOptionType.class.php @@ -15,6 +15,13 @@ namespace wcf\system\option\user\group; * @category Community Framework */ class InfiniteInverseIntegerUserGroupOptionType extends InverseIntegerUserGroupOptionType { + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() + */ + public function diff($defaultValue, $groupValue) { + return $this->merge($defaultValue, $groupValue); + } + /** * @see wcf\system\option\user\group\IUserGroupOptionType::merge() */ diff --git a/wcfsetup/install/files/lib/system/option/user/group/IntegerUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/IntegerUserGroupOptionType.class.php index abdd28bb7c..fc5febb71b 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/IntegerUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/IntegerUserGroupOptionType.class.php @@ -15,6 +15,13 @@ use wcf\system\option\IntegerOptionType; * @category Community Framework */ class IntegerUserGroupOptionType extends IntegerOptionType implements IUserGroupOptionType { + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() + */ + public function diff($defaultValue, $groupValue) { + return $this->merge($defaultValue, $groupValue); + } + /** * @see wcf\system\option\user.group\IUserGroupOptionType::merge() */ diff --git a/wcfsetup/install/files/lib/system/option/user/group/InverseIntegerUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/InverseIntegerUserGroupOptionType.class.php index 47819d8426..15bbd53db1 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/InverseIntegerUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/InverseIntegerUserGroupOptionType.class.php @@ -15,6 +15,13 @@ use wcf\system\option\IntegerOptionType; * @category Community Framework */ class InverseIntegerUserGroupOptionType extends IntegerOptionType implements IUserGroupOptionType { + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() + */ + public function diff($defaultValue, $groupValue) { + return $this->merge($defaultValue, $groupValue); + } + /** * @see wcf\system\option\user\group\IUserGroupOptionType::merge() */ diff --git a/wcfsetup/install/files/lib/system/option/user/group/TextUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/TextUserGroupOptionType.class.php index cf102b2bfd..73d323df66 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/TextUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/TextUserGroupOptionType.class.php @@ -14,12 +14,15 @@ use wcf\util\StringUtil; * @package com.woltlab.wcf * @subpackage system.option.user.group * @category Community Framework + * + * @todo text options types can't have line breaks, why use them to split + * values? what to do? */ class TextUserGroupOptionType extends TextOptionType implements IUserGroupOptionType { /** - * @see wcf\system\option\user\group\IUserGroupOptionType::merge() + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() */ - public function merge($defaultValue, $groupValue) { + public function diff($defaultValue, $groupValue) { $defaultValue = explode("\n", StringUtil::unifyNewlines($defaultValue)); $groupValue = explode("\n", StringUtil::unifyNewlines($groupValue)); @@ -30,4 +33,14 @@ class TextUserGroupOptionType extends TextOptionType implements IUserGroupOption return implode("\n", $result); } + + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::merge() + */ + public function merge($defaultValue, $groupValue) { + $defaultValue = empty($defaultValue) ? array() : explode("\n", StringUtil::unifyNewlines($defaultValue)); + $groupValue = empty($groupValue) ? array() : explode("\n", StringUtil::unifyNewlines($groupValue)); + + return implode("\n", array_unique(array_merge($defaultValue, $groupValue))); + } } diff --git a/wcfsetup/install/files/lib/system/option/user/group/TextareaUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/TextareaUserGroupOptionType.class.php index c7c078db8d..b4087a30f8 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/TextareaUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/TextareaUserGroupOptionType.class.php @@ -17,17 +17,27 @@ use wcf\util\StringUtil; */ class TextareaUserGroupOptionType extends TextareaOptionType implements IUserGroupOptionType { /** - * @see wcf\system\option\user\group\IUserGroupOptionType::merge() + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() */ - public function merge($defaultValue, $groupValue) { + public function diff($defaultValue, $groupValue) { $defaultValue = explode("\n", StringUtil::unifyNewlines($defaultValue)); $groupValue = explode("\n", StringUtil::unifyNewlines($groupValue)); - + $result = array_diff($groupValue, $defaultValue); if (empty($result)) { return null; } - + return implode("\n", $result); } + + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::merge() + */ + public function merge($defaultValue, $groupValue) { + $defaultValue = empty($defaultValue) ? array() : explode("\n", StringUtil::unifyNewlines($defaultValue)); + $groupValue = empty($groupValue) ? array() : explode("\n", StringUtil::unifyNewlines($groupValue)); + + return implode("\n", array_unique(array_merge($defaultValue, $groupValue))); + } } diff --git a/wcfsetup/install/files/lib/system/option/user/group/UserGroupsUserGroupOptionType.class.php b/wcfsetup/install/files/lib/system/option/user/group/UserGroupsUserGroupOptionType.class.php index 441fc4251f..3336fca803 100644 --- a/wcfsetup/install/files/lib/system/option/user/group/UserGroupsUserGroupOptionType.class.php +++ b/wcfsetup/install/files/lib/system/option/user/group/UserGroupsUserGroupOptionType.class.php @@ -67,9 +67,9 @@ class UserGroupsUserGroupOptionType extends AbstractOptionType implements IUserG } /** - * @see wcf\system\option\user\group\IUserGroupOptionType::merge() + * @see wcf\system\option\user\group\IUserGroupOptionType::diff() */ - public function merge($defaultValue, $groupValue) { + public function diff($defaultValue, $groupValue) { $defaultValue = explode(',', $defaultValue); $groupValue = explode(',', $groupValue); @@ -80,4 +80,14 @@ class UserGroupsUserGroupOptionType extends AbstractOptionType implements IUserG return implode(',', $result); } + + /** + * @see wcf\system\option\user\group\IUserGroupOptionType::merge() + */ + public function merge($defaultValue, $groupValue) { + $defaultValue = empty($defaultValue) ? array() : explode(',', StringUtil::unifyNewlines($defaultValue)); + $groupValue = empty($groupValue) ? array() : explode(',', StringUtil::unifyNewlines($groupValue)); + + return implode(',', array_unique(array_merge($defaultValue, $groupValue))); + } } -- 2.20.1