Add support for inverted permissions with Simple ACL
authorjoshuaruesweg <ruesweg@woltlab.com>
Thu, 4 Feb 2021 12:08:55 +0000 (13:08 +0100)
committerjoshuaruesweg <ruesweg@woltlab.com>
Thu, 4 Feb 2021 15:20:07 +0000 (16:20 +0100)
ts/WoltLabSuite/Core/Ui/Acl/Simple.ts
wcfsetup/install/files/acp/templates/aclSimple.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Acl/Simple.js
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 47abca96dfd82cd37cbce348cc19ff399141811d..76db762ff5e036477c8aa906f48e518807a239c7 100644 (file)
@@ -17,15 +17,21 @@ class UiAclSimple {
     this.inputName = inputName || "aclValues";
 
     const container = document.getElementById(this.prefix + "aclInputContainer")!;
-
+    const invertPermissionsDl = document.getElementById(this.prefix + "invertPermissionsDl");
     const allowAll = document.getElementById(this.prefix + "aclAllowAll") as HTMLInputElement;
     allowAll.addEventListener("change", () => {
       DomUtil.hide(container);
+      if (invertPermissionsDl) {
+        DomUtil.hide(invertPermissionsDl);
+      }
     });
 
     const denyAll = document.getElementById(this.prefix + "aclAllowAll_no")!;
     denyAll.addEventListener("change", () => {
       DomUtil.show(container);
+      if (invertPermissionsDl) {
+        DomUtil.show(invertPermissionsDl);
+      }
     });
 
     this.list = document.getElementById(this.prefix + "aclAccessList") as HTMLUListElement;
@@ -48,6 +54,27 @@ class UiAclSimple {
 
     this.aclListContainer = document.getElementById(this.prefix + "aclListContainer")!;
 
+    const invertPermission = document.getElementById(this.prefix + "invertPermissions") as HTMLInputElement | null;
+    if (invertPermission) {
+      invertPermission.addEventListener("change", () => {
+        this.invertPermissions(true);
+      });
+    }
+
+    const normalPermission = document.getElementById(this.prefix + "invertPermissions_no") as HTMLInputElement | null;
+    if (normalPermission) {
+      normalPermission.addEventListener("change", () => {
+        this.invertPermissions(false);
+      });
+    }
+
+    const invertPermissionRadioButton = document.getElementById(
+      this.prefix + "invertPermissions",
+    ) as HTMLInputElement | null;
+    if (invertPermissionRadioButton) {
+      this.invertPermissions(!!invertPermissionRadioButton.value);
+    }
+
     DomChangeListener.trigger();
   }
 
@@ -95,6 +122,14 @@ class UiAclSimple {
       }
     }
   }
+
+  private invertPermissions(invert: boolean): void {
+    const aclListContainerDt = document.getElementById(this.prefix + "aclListContainerDt");
+    const aclSearchInputLabel = document.getElementById(this.prefix + "aclSearchInputLabel");
+
+    aclListContainerDt!.textContent = Language.get(invert ? "wcf.acl.access.denied" : "wcf.acl.access.granted");
+    aclSearchInputLabel!.textContent = Language.get(invert ? "wcf.acl.access.deny" : "wcf.acl.access.grant");
+  }
 }
 
 Core.enableLegacyInheritance(UiAclSimple);
index 1c69e5d6ddeed53821dcb6110bade88a83ac03d5..557ac8e1d2becf3853c824f3eee01a4b8942d59e 100644 (file)
@@ -1,5 +1,6 @@
 {if !$__aclSimplePrefix|isset}{assign var='__aclSimplePrefix' value=''}{/if}
 {if !$__aclInputName|isset}{assign var='__aclInputName' value='aclValues'}{/if}
+{if !$__supportsInvertedPermissions|isset}{assign var='__supportsInvertedPermissions' value=false}{/if}
 
 <div class="section">
        <dl>
                        </ol>
                </dd>
        </dl>
+       
+       {if $__supportsInvertedPermissions}
+               {if !$invertPermissionsPrefixed|isset}{assign var='invertPermissionsPrefixed' value=$__aclSimplePrefix}{/if}
+               <dl id="{@$__aclSimplePrefix}invertPermissionsDl" {if $aclValues[allowAll]} style="display: none;"{/if}>
+                       <dt><label for="{@$__aclSimplePrefix}invertPermissions">{lang}wcf.acl.access.invertPermissions{/lang}</label></dt>
+                       <dd>
+                               <ol class="flexibleButtonGroup">
+                                       <li>
+                                               <input type="radio" id="{@$__aclSimplePrefix}invertPermissions" name="{@$__aclSimplePrefix}invertPermissions" value="1"{if $invertPermissions} checked{/if}>
+                                               <label for="{@$__aclSimplePrefix}invertPermissions" class="green"><span class="icon icon16 fa-check"></span> {lang}wcf.acp.option.type.boolean.yes{/lang}</label>
+                                       </li>
+                                       <li>
+                                               <input type="radio" id="{@$__aclSimplePrefix}invertPermissions_no" name="{@$__aclSimplePrefix}invertPermissions" value="0"{if !$invertPermissions} checked{/if}>
+                                               <label for="{@$__aclSimplePrefix}invertPermissions_no" class="red"><span class="icon icon16 fa-times"></span> {lang}wcf.acp.option.type.boolean.no{/lang}</label>
+                                       </li>
+                               </ol>
+                               <small>{lang}wcf.acl.access.invertPermissions.description{/lang}</small>
+                       </dd>
+               </dl>
+       {/if}
 </div>
 
 <section class="section" id="{@$__aclSimplePrefix}aclInputContainer"{if $aclValues[allowAll]} style="display: none;"{/if}>
        <h2 class="sectionTitle">{lang}wcf.acl.access{/lang}</h2>
        <dl>
-               <dt><label for="{@$__aclSimplePrefix}aclSearchInput">{lang}wcf.acl.access.grant{/lang}</label></dt>
+               <dt><label for="{@$__aclSimplePrefix}aclSearchInput" id="{@$__aclSimplePrefix}aclSearchInputLabel">{lang}wcf.acl.access.grant{/lang}</label></dt>
                <dd>
                        <input type="text" id="{@$__aclSimplePrefix}aclSearchInput" class="long" placeholder="{lang}wcf.acl.search.description{/lang}">
                </dd>
        </dl>
        
        <dl id="{@$__aclSimplePrefix}aclListContainer"{if $aclValues[allowAll]} style="display: none;"{/if}>
-               <dt>{lang}wcf.acl.access.granted{/lang}</dt>
+               <dt id="{@$__aclSimplePrefix}aclListContainerDt">{lang}wcf.acl.access.granted{/lang}</dt>
                <dd>
                        <ul id="{@$__aclSimplePrefix}aclAccessList" class="aclList containerList">
                                {foreach from=$aclValues[group] item=aclGroup}
 </section>
 
 <script data-relocate="true">
-       require(['WoltLabSuite/Core/Ui/Acl/Simple'], function(UiAclSimple) {
+       require(['WoltLabSuite/Core/Ui/Acl/Simple', 'Language'], function(UiAclSimple, Language) {
+               Language.addObject({
+                       'wcf.acl.access.grant': '{jslang}wcf.acl.access.grant{/jslang}',
+                       'wcf.acl.access.deny': '{jslang}wcf.acl.access.deny{/jslang}',
+                       'wcf.acl.access.granted': '{jslang}wcf.acl.access.granted{/jslang}',
+                       'wcf.acl.access.denied': '{jslang}wcf.acl.access.denied{/jslang}',
+               });
+               
                new UiAclSimple('{@$__aclSimplePrefix}', '{@$__aclInputName}');
        });
 </script>
index 4c518d10f7b76f134523b424acf041af2a761a76..098bc13a096b254e726cd90d2bafb66034c75458 100644 (file)
@@ -11,13 +11,20 @@ define(["require", "exports", "tslib", "../../Core", "../../Language", "../../St
             this.prefix = prefix || "";
             this.inputName = inputName || "aclValues";
             const container = document.getElementById(this.prefix + "aclInputContainer");
+            const invertPermissionsDl = document.getElementById(this.prefix + "invertPermissionsDl");
             const allowAll = document.getElementById(this.prefix + "aclAllowAll");
             allowAll.addEventListener("change", () => {
                 Util_1.default.hide(container);
+                if (invertPermissionsDl) {
+                    Util_1.default.hide(invertPermissionsDl);
+                }
             });
             const denyAll = document.getElementById(this.prefix + "aclAllowAll_no");
             denyAll.addEventListener("change", () => {
                 Util_1.default.show(container);
+                if (invertPermissionsDl) {
+                    Util_1.default.show(invertPermissionsDl);
+                }
             });
             this.list = document.getElementById(this.prefix + "aclAccessList");
             this.list.addEventListener("click", this.removeItem.bind(this));
@@ -32,6 +39,22 @@ define(["require", "exports", "tslib", "../../Core", "../../Language", "../../St
                 preventSubmit: true,
             });
             this.aclListContainer = document.getElementById(this.prefix + "aclListContainer");
+            const invertPermission = document.getElementById(this.prefix + "invertPermissions");
+            if (invertPermission) {
+                invertPermission.addEventListener("change", () => {
+                    this.invertPermissions(true);
+                });
+            }
+            const normalPermission = document.getElementById(this.prefix + "invertPermissions_no");
+            if (normalPermission) {
+                normalPermission.addEventListener("change", () => {
+                    this.invertPermissions(false);
+                });
+            }
+            const invertPermissionRadioButton = document.getElementById(this.prefix + "invertPermissions");
+            if (invertPermissionRadioButton) {
+                this.invertPermissions(!!invertPermissionRadioButton.value);
+            }
             Listener_1.default.trigger();
         }
         select(listItem) {
@@ -69,6 +92,12 @@ define(["require", "exports", "tslib", "../../Core", "../../Language", "../../St
                 }
             }
         }
+        invertPermissions(invert) {
+            const aclListContainerDt = document.getElementById(this.prefix + "aclListContainerDt");
+            const aclSearchInputLabel = document.getElementById(this.prefix + "aclSearchInputLabel");
+            aclListContainerDt.textContent = Language.get(invert ? "wcf.acl.access.denied" : "wcf.acl.access.granted");
+            aclSearchInputLabel.textContent = Language.get(invert ? "wcf.acl.access.deny" : "wcf.acl.access.grant");
+        }
     }
     Core.enableLegacyInheritance(UiAclSimple);
     return UiAclSimple;
index 22b33d90fd6821090d6d2829dc9e2b40f9d9cffb..a1ef31cbe9a6c47d54f08e5e01ef5d402f674905 100644 (file)
@@ -3,7 +3,11 @@
        <category name="wcf.acl">
                <item name="wcf.acl.access"><![CDATA[Zugangsbeschränkung]]></item>
                <item name="wcf.acl.access.grant"><![CDATA[Zugang gewähren]]></item>
+               <item name="wcf.acl.access.deny"><![CDATA[Zugang verwehren]]></item>
                <item name="wcf.acl.access.granted"><![CDATA[Erlaubte Benutzer und Benutzergruppen]]></item>
+               <item name="wcf.acl.access.denied"><![CDATA[Verwehrte Benutzer und Benutzergruppen]]></item>
+               <item name="wcf.acl.access.invertPermissions"><![CDATA[Berechtigungen umkehren]]></item>
+               <item name="wcf.acl.access.invertPermissions.description"><![CDATA[Wenn ausgewählt, dürfen standardmäßig alle Benutzer, bis auf ausgewählte Benutzer und Benutzergruppen das Objekt sehen.]]></item>
                <item name="wcf.acl.allowAll"><![CDATA[Inhalt ist für alle Benutzer sichtbar]]></item>
                <item name="wcf.acl.option.deny"><![CDATA[Verweigern]]></item>
                <item name="wcf.acl.option.fullAccess"><![CDATA[Vollzugriff]]></item>
index 54042797df50ad2e904d855c238c0f9aff82a101..68a45a4816358fbc2ce1a268c164680429ce90a2 100644 (file)
@@ -3,7 +3,11 @@
        <category name="wcf.acl">
                <item name="wcf.acl.access"><![CDATA[Restricted Access]]></item>
                <item name="wcf.acl.access.grant"><![CDATA[Allow Access]]></item>
+               <item name="wcf.acl.access.deny"><![CDATA[Deny Access]]></item>
                <item name="wcf.acl.access.granted"><![CDATA[Granted Access for Users and User-Groups]]></item>
+               <item name="wcf.acl.access.denied"><![CDATA[Denied Access for Users and User-Groups]]></item>
+               <item name="wcf.acl.access.invertPermissions"><![CDATA[Invert Permissions]]></item>
+               <item name="wcf.acl.access.invertPermissions.description"><![CDATA[If selected, all users except selected users and user groups are allowed to see the object by default.]]></item>
                <item name="wcf.acl.allowAll"><![CDATA[Content Can be Accessed by Everyone]]></item>
                <item name="wcf.acl.option.deny"><![CDATA[Deny]]></item>
                <item name="wcf.acl.option.fullAccess"><![CDATA[Full Access]]></item>