Promote a group to be the owner group
authorAlexander Ebert <ebert@woltlab.com>
Thu, 11 Apr 2019 11:12:42 +0000 (13:12 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 11 Apr 2019 11:12:42 +0000 (13:12 +0200)
We cannot reliably determine the owner group during the upgrade, therefore it is up to an administrator to make the choice.

The notice is designed to be annoying and is present on all pages, however it does not prevent the user from carrying out tasks, e. g. setting up a proper group before promoting it to be the owner group.

wcfsetup/install/files/acp/style/layout.scss
wcfsetup/install/files/acp/templates/footer.tpl
wcfsetup/install/files/acp/templates/userGroupPromoteOwner.tpl [new file with mode: 0644]
wcfsetup/install/files/lib/acp/form/UserGroupEditForm.class.php
wcfsetup/install/files/lib/acp/form/UserGroupPromoteOwnerForm.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/user/group/UserGroupAction.class.php
wcfsetup/install/files/lib/system/WCFACP.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 4244f7f7d4e231b74fe506013cf16866963ee879..81b75e6a8dd96952f0feb68a210ab03b031bd4b4 100644 (file)
@@ -441,3 +441,26 @@ $wcfAcpSubMenuWidth: 300px;
                width: 100% !important;
        }
 }
+
+/* Owner Group */
+#wscMissingOwnerGroup {
+       background-color: rgb(248, 215, 218);
+       border-top: 5px solid red;
+       bottom: 0;
+       color: rgb(114, 28, 36);
+       left: 0;
+       padding: 10px;
+       position: fixed;
+       text-align: center;
+       right: 0;
+       z-index: 9999;
+       
+       @include screen-md-up {
+               padding: 20px;
+       }
+       
+       > a {
+               color: inherit;
+               text-decoration: underline;
+       }
+}
index da3b6ece2ca362a0259d032bdf4c45fab42df5cd..b348d669dc1607747a5066434bbcd13d7528e3cf 100644 (file)
@@ -8,6 +8,10 @@
 
 {if $__isRescueMode|empty}{include file='pageMenuMobile'}{/if}
 
+{if !$__wscMissingOwnerGroup|empty}
+       <div id="wscMissingOwnerGroup" role="alert">{lang}wcf.acp.group.missingOwnerGroup{/lang}</div>
+{/if}
+
 {event name='footer'}
 
 <!-- JAVASCRIPT_RELOCATE_POSITION -->
diff --git a/wcfsetup/install/files/acp/templates/userGroupPromoteOwner.tpl b/wcfsetup/install/files/acp/templates/userGroupPromoteOwner.tpl
new file mode 100644 (file)
index 0000000..a1eebfb
--- /dev/null
@@ -0,0 +1,13 @@
+{include file='header' pageTitle='wcf.acp.group.promoteOwner'}
+
+<header class="contentHeader">
+       <div class="contentHeaderTitle">
+               <h1 class="contentTitle">{lang}wcf.acp.group.promoteOwner{/lang}</h1>
+       </div>
+</header>
+
+<div class="warning">{lang}wcf.acp.group.promoteOwner.warning{/lang}</div>
+
+{@$form->getHtml()}
+
+{include file='footer'}
index d3cdf40c2f12e5f92ac0b3aabdbe6eb0946abd0f..d0bb4e032e9bbab33f1fa5f9aba68cad9a1ddf40 100755 (executable)
@@ -122,8 +122,6 @@ class UserGroupEditForm extends UserGroupAddForm {
                        $ownerGroupPermissions[] = 'admin.user.accessibleGroups';
                }
                
-               $ownerGroup = UserGroup::getGroupByType(UserGroup::OWNER);
-               
                WCF::getTPL()->assign([
                        'groupID' => $this->group->groupID,
                        'group' => $this->group,
@@ -135,7 +133,7 @@ class UserGroupEditForm extends UserGroupAddForm {
                        'groupIsOwner' => $this->group->isOwner(),
                        'isUnmentionableGroup' => $this->isUnmentionableGroup ? 1 : 0,
                        'ownerGroupPermissions' => $ownerGroupPermissions,
-                       'ownerGroupID' => $ownerGroup ? $ownerGroup->groupID : null,
+                       'ownerGroupID' => UserGroup::getOwnerGroupID(),
                ]);
                
                // add warning when the initiator is in the group
diff --git a/wcfsetup/install/files/lib/acp/form/UserGroupPromoteOwnerForm.class.php b/wcfsetup/install/files/lib/acp/form/UserGroupPromoteOwnerForm.class.php
new file mode 100644 (file)
index 0000000..ddbd167
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+namespace wcf\acp\form;
+use wcf\data\user\group\UserGroup;
+use wcf\data\user\group\UserGroupAction;
+use wcf\form\AbstractForm;
+use wcf\system\form\builder\container\FormContainer;
+use wcf\system\form\builder\field\RadioButtonFormField;
+use wcf\system\form\builder\FormDocument;
+use wcf\system\form\builder\IFormDocument;
+use wcf\system\request\LinkHandler;
+use wcf\system\WCF;
+use wcf\util\HeaderUtil;
+
+/**
+ * Promotes a user group to be the owner group.
+ * 
+ * @author      ALexander Ebert
+ * @copyright   2001-2019 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package     WoltLabSuite\Core\Acp\Form
+ * @since       5.2
+ */
+class UserGroupPromoteOwnerForm extends AbstractForm {
+       /**
+        * @inheritDoc
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.group.list';
+       
+       /**
+        * @var IFormDocument
+        */
+       public $form;
+       
+       /**
+        * @var UserGroup
+        */
+       public $groups = [];
+       
+       /**
+        * @inheritDoc
+        */
+       public $neededPermissions = ['admin.configuration.package.canInstallPackage'];
+       
+       /**
+        * @inheritDoc
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               $this->groups = UserGroup::getGroupsByType([UserGroup::OTHER]);
+               $this->groups = array_filter($this->groups, function (UserGroup $group) {
+                       return $group->isAdminGroup();
+               });
+               uasort($this->groups, function(UserGroup $a, UserGroup $b) {
+                       return $a->getName() <=> $b->getName();
+               });
+               
+               $this->form = FormDocument::create('promoteGroup')
+                       ->appendChild(
+                               FormContainer::create('groupSection')
+                                       ->appendChild(
+                                               RadioButtonFormField::create('groupID')
+                                                       ->label('wcf.acp.group.promoteOwner.group')
+                                                       ->required()
+                                                       ->options($this->groups)
+                                       )
+                       );
+               $this->form->action(LinkHandler::getInstance()->getLink('UserGroupPromoteOwner'));
+               $this->form->build();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function readFormParameters() {
+               parent::readFormParameters();
+               
+               $this->form->readValues();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function validate() {
+               parent::validate();
+               
+               $this->form->validate();
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function save() {
+               parent::save();
+               
+               $groupID = $this->form->getData()['data']['groupID'];
+               
+               $this->objectAction = new UserGroupAction([$this->groups[$groupID]], 'promoteOwner');
+               $this->objectAction->executeAction();
+               
+               $this->saved();
+               
+               HeaderUtil::redirect(LinkHandler::getInstance()->getLink());
+               exit;
+       }
+       
+       /**
+        * @inheritDoc
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign([
+                       'form' => $this->form,
+                       // Hide the notice on this page only.
+                       '__wscMissingOwnerGroup' => false,
+               ]);
+       }
+}
index 3de57bf6996ff1a31db580af0631b1d0d8b92232..62e3614e06d79e8c027e69faacd0041a192d0df7 100644 (file)
@@ -212,4 +212,20 @@ class UserGroupAction extends AbstractDatabaseObjectAction {
                        ])
                ];
        }
+       
+       public function promoteOwner() {
+               if (UserGroup::getOwnerGroupID() !== null) {
+                       throw new \LogicException('There is already an owner group.');
+               }
+               else if (count($this->objects) !== 1) {
+                       throw new \InvalidArgumentException('Only a single group can be promoted to be the owner group.');
+               }
+               
+               $groupEditor = reset($this->objects);
+               $groupEditor->update([
+                       'groupType' => UserGroup::OWNER,
+               ]);
+               
+               UserGroupEditor::resetCache();
+       }
 }
index efc5c42559d1054a37aebef4458d2f87ef8fe431..accd8f18100f0252a21a87a026e2c2d8d5991404 100644 (file)
@@ -4,6 +4,7 @@ use wcf\acp\form\MasterPasswordForm;
 use wcf\acp\form\MasterPasswordInitForm;
 use wcf\data\menu\Menu;
 use wcf\data\menu\MenuCache;
+use wcf\data\user\group\UserGroup;
 use wcf\system\application\ApplicationHandler;
 use wcf\system\cache\builder\ACPSearchProviderCacheBuilder;
 use wcf\system\event\EventHandler;
@@ -176,6 +177,10 @@ class WCFACP extends WCF {
                                self::$overrideDebugMode = true;
                        }
                }
+               
+               if (PACKAGE_ID && WCF::getUser()->userID && WCF::getSession()->getPermission('admin.configuration.package.canInstallPackage') && UserGroup::getOwnerGroupID() === null) {
+                       self::getTPL()->assign(['__wscMissingOwnerGroup' => true]);
+               }
        }
        
        /**
index c144dadd23ddfe14952f904fddff8cf4028713cf..90a61965fe5545ea09f4c450b3609b0ef8ea84e7 100644 (file)
@@ -883,6 +883,10 @@ Das Fehlerprotokoll enthält {$data[count]} neue Einträge. Die ersten drei, in
                <item name="wcf.acp.group.type.owner"><![CDATA[Besitzer]]></item>
                <item name="wcf.acp.group.type.owner.description"><![CDATA[Die Besitzer-Gruppe verfügt über nicht entziehbare Berechtigungen und kann von anderen Gruppen nicht bearbeitet werden, diese Gruppe kann nur durch die Besitzer-Gruppe selbst bearbeitet werden. Mitglieder dieser Benutzer können andere Benutzer zu dieser Gruppe hinzufügen, sich aber selbst nicht daraus entfernen.]]></item>
                <item name="wcf.acp.group.ownerGroupPermission"><![CDATA[Die Besitzer-Gruppe verfügt immer über diese Berechtigung, sie kann nicht entzogen werden.]]></item>
+               <item name="wcf.acp.group.missingOwnerGroup"><![CDATA[Es wurde noch keine Besitzer-Gruppe festgelegt, <a href="{link controller='UserGroupPromoteOwner'}{/link}">bitte {if LANGUAGE_USE_INFORMAL_VARIANT}lege{else}legen Sie{/if} diese umgehend fest</a>.]]></item>
+               <item name="wcf.acp.group.promoteOwner"><![CDATA[Besitzer-Gruppe festlegen]]></item>
+               <item name="wcf.acp.group.promoteOwner.group"><![CDATA[Besitzer-Gruppe auswählen]]></item>
+               <item name="wcf.acp.group.promoteOwner.warning"><![CDATA[Die Besitzer-Gruppe kann, einmal festgelegt, nicht mehr geändert werden. Diese Gruppe verfügt über besondere Berechtigungen und wird vor Änderungen durch andere Gruppen geschützt, Mitglieder dieser Gruppe können nicht mehr gesperrt werden.]]></item>
        </category>
        <category name="wcf.acp.index">
                <item name="wcf.acp.index.credits"><![CDATA[Über WoltLab Suite&trade;]]></item>
index 2e154db23aa4b5165e72e4b448ec34c681f74e50..b4c53fcc58bd9baa5555f6e1e82d4692ca31c08d 100644 (file)
@@ -860,6 +860,11 @@ This protocol file contains {$data[count]} new entries. The first three error me
                <item name="wcf.acp.group.type.owner"><![CDATA[Owner]]></item>
                <item name="wcf.acp.group.type.owner.description"><![CDATA[The owner group features a few irrevocable permissions and is protected from edits by other groups, only the owner group can edit itself. Members of this group can add other users to this group, but cannot remove themselves.]]></item>
                <item name="wcf.acp.group.ownerGroupPermission"><![CDATA[The owner group always has this permission, it cannot be revoked.]]></item>
+               
+               <item name="wcf.acp.group.missingOwnerGroup"><![CDATA[No owner group has been configured yet, <a href="{link controller='UserGroupPromoteOwner'}{/link}">please set it up now</a>.]]></item>
+               <item name="wcf.acp.group.promoteOwner"><![CDATA[Set Up the Owner Group]]></item>
+               <item name="wcf.acp.group.promoteOwner.group"><![CDATA[Select the owner group]]></item>
+               <item name="wcf.acp.group.promoteOwner.warning"><![CDATA[The owner group cannot be modified once it has been set up. This group has special privileges and is protected from modifications by any other group, its members cannot be banned.]]></item>
        </category>
        <category name="wcf.acp.index">
                <item name="wcf.acp.index.credits"><![CDATA[About WoltLab Suite&trade;]]></item>