Preventing users from granting more permissions than they have
authorAlexander Ebert <ebert@woltlab.com>
Tue, 27 May 2014 20:36:52 +0000 (22:36 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 27 May 2014 20:36:52 +0000 (22:36 +0200)
wcfsetup/install/files/acp/templates/userGroupOption.tpl
wcfsetup/install/files/lib/acp/form/UserGroupOptionForm.class.php
wcfsetup/install/files/lib/system/option/AbstractOptionType.class.php
wcfsetup/install/files/lib/system/option/BooleanOptionType.class.php
wcfsetup/install/files/lib/system/option/user/group/UserGroupOptionHandler.class.php
wcfsetup/install/files/lib/system/option/user/group/UserGroupsUserGroupOptionType.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 14b94387aef1bd876860893bacf89b8eb2e8e65d..ab6cd929d9e1293dcd88b7604eff26fbe614e06a 100644 (file)
                                        <dd>
                                                {@$formElements[$group->groupID]}
                                                
+                                               {if $errorType[$group->groupID]|isset}
+                                                       <small class="innerError">
+                                                               {lang}wcf.acp.group.option.error.{$errorType[$group->groupID]}{/lang}
+                                                       </small>
+                                               {/if}
                                                {hascontent}<small>{content}{lang __optional=true}wcf.acp.group.option.{@$userGroupOption->optionName}.description{/lang}{/content}</small>{/hascontent}
                                        </dd>
                                </dl>
index 9f5ab252b112e7fc313dfd23775aa7ac3bb32c15..898bd96ab0f9804058104bffe315103139e9c390 100644 (file)
@@ -157,6 +157,10 @@ class UserGroupOptionForm extends AbstractForm {
                        catch (UserInputException $e) {
                                $this->errorType[$e->getField()] = $e->getType();
                        }
+                       
+                       if ($this->optionType->compare($optionValue, WCF::getSession()->getPermission($this->userGroupOption->optionName)) == 1) {
+                               $this->errorType[$groupID] = 'exceedsOwnPermission';
+                       }
                }
                
                // add missing values for option type 'boolean'
index 2725a8b9630b240a5f7cf702808f9018db21781b..3889a6c27826a88bcf724b3ce85d15c82537ac26 100644 (file)
@@ -48,7 +48,7 @@ abstract class AbstractOptionType implements IOptionType {
        /**
         * @see \wcf\system\option\IOptionType::compare()
         */
-       public function compare() {
+       public function compare($value1, $value2) {
                return 0;
        }
 }
index 7c8fb32b3a84cdd197581e7abe1dce931832d0c3..51038c199c61963eaf1539445279701e6f37209d 100644 (file)
@@ -99,6 +99,6 @@ class BooleanOptionType extends AbstractOptionType implements ISearchableUserOpt
                        return 0;
                }
                
-               return ($value1 === true) ? 1 : -1;
+               return ($value1) ? 1 : -1;
        }
 }
index 1cb5b3b2b406383293e5f07cb6172c88111e3c1c..7a63e3cfb4461df8c8e4fbfb583bed227f4bf21f 100644 (file)
@@ -4,6 +4,9 @@ use wcf\data\user\group\UserGroup;
 use wcf\system\exception\SystemException;
 use wcf\system\option\OptionHandler;
 use wcf\util\ClassUtil;
+use wcf\system\WCF;
+use wcf\system\exception\UserInputException;
+use wcf\data\option\Option;
 
 /**
  * Handles user group options.
@@ -27,6 +30,12 @@ class UserGroupOptionHandler extends OptionHandler {
         */
        protected $group = null;
        
+       /**
+        * true if current user can edit every user group
+        * @var boolean
+        */
+       protected $isAdmin = null;
+       
        /**
         * Sets current user group.
         * 
@@ -70,4 +79,40 @@ class UserGroupOptionHandler extends OptionHandler {
                        }
                }
        }
+       
+       /**
+        * Returns true if current user has the permissions to edit every user group.
+        * 
+        * @return      boolean
+        */
+       protected function isAdmin() {
+               if ($this->isAdmin === null) {
+                       $this->isAdmin = false;
+                       
+                       foreach (WCF::getUser()->getGroupIDs() as $groupID) {
+                               if (UserGroup::getGroupByID($groupID)->isAdminGroup()) {
+                                       $this->isAdmin = true;
+                                       break;
+                               }
+                       }
+               }
+               
+               return $this->isAdmin;
+       }
+       
+       /**
+        * @see \wcf\system\option\OptionHandler::validateOption()
+        */
+       protected function validateOption(Option $option) {
+               parent::validateOption($option);
+               
+               if (!$this->isAdmin()) {
+                       // get type object
+                       $typeObj = $this->getTypeObject($option->optionType);
+                       
+                       if ($typeObj->compare($this->optionValues[$option->optionName], WCF::getSession()->getPermission($option->optionName)) == 1) {
+                               throw new UserInputException($option->optionName, 'exceedsOwnPermission');
+                       }
+               }
+       }
 }
index 2c0843c803c0c8a94da340d67f453786dd08b7c9..dbe99d1a612a954a9eb7eb10d49460dec468f8d5 100644 (file)
@@ -80,8 +80,8 @@ class UserGroupsUserGroupOptionType extends AbstractOptionType implements IUserG
         * @see \wcf\system\option\IOptionType::compare()
         */
        public function compare($value1, $value2) {
-               $value1 = explode(',', $value1);
-               $value2 = explode(',', $value2);
+               $value1 = ($value1) ? explode(',', $value1) : array();
+               $value2 = ($value2) ? explode(',', $value2) : array();
                
                // check if value1 contains more elements than value2
                $diff = array_diff($value1, $value2);
index e0b849831ee1d0de227f15ee9624f9809f1e40e6..ac829df136ef33b79494324925df54f68c9e2268 100644 (file)
                <item name="wcf.acp.group.option.category.user"><![CDATA[Allgemeine Rechte]]></item>
                <item name="wcf.acp.group.option.category.user.message"><![CDATA[Nachrichten]]></item>
                <item name="wcf.acp.group.option.category.user.message.comment"><![CDATA[Kommentare]]></item>
+               <item name="wcf.acp.group.option.error.exceedsOwnPermission"><![CDATA[Sie können Benutzergruppen keine Berechtigungen gewähren, die Ihre eigenen Berechtigungen übersteigen.]]></item>
                <item name="wcf.acp.group.option.error.tooHigh"><![CDATA[Der angegebene Wert ist zu hoch.{if $option->maxvalue !== null} Der maximale Wert ist {#$option->maxvalue}.{/if}]]></item>
                <item name="wcf.acp.group.option.error.tooLow"><![CDATA[Der angegebene Wert ist zu gering.{if $option->minvalue !== null} Der minimale Wert ist {#$option->minvalue}.{/if}]]></item>
                <item name="wcf.acp.group.showMembers"><![CDATA[Zeige die Mitglieder dieser Benutzergruppe]]></item>
index e0c638cc768ce8708c538925900c55d62a853a8b..46275d16ff8f3b0830d07d3113c1e6256751c411 100644 (file)
@@ -279,6 +279,7 @@ Examples for medium ID detection:
                <item name="wcf.acp.group.option.category.user"><![CDATA[General Permissions]]></item>
                <item name="wcf.acp.group.option.category.user.message"><![CDATA[Messages]]></item>
                <item name="wcf.acp.group.option.category.user.message.comment"><![CDATA[Comments]]></item>
+               <item name="wcf.acp.group.option.error.exceedsOwnPermission"><![CDATA[You cannot grant user group permissions exceeding your own permissions.]]></item>
                <item name="wcf.acp.group.option.error.tooHigh"><![CDATA[The given value is too high.{if $option->maxvalue !== null} The maximum value is {#$option->maxvalue}.{/if}]]></item>
                <item name="wcf.acp.group.option.error.tooLow"><![CDATA[The given value is too low.{if $option->minvalue !== null} The minimum value is {#$option->minvalue}.{/if}]]></item>
                <item name="wcf.acp.group.showMembers"><![CDATA[Show Members]]></item>