You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by hn...@apache.org on 2022/07/19 12:38:04 UTC

[myfaces-tobago] 03/03: fix: AuthorizationHelper

This is an automated email from the ASF dual-hosted git repository.

hnoeth pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git

commit ca1e9dea2f4f94bd52d0d7298cc6c49d4c3f3625
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Tue Jul 19 11:43:35 2022 +0200

    fix: AuthorizationHelper
    
    * fix getSecurityAnnotation() method
    * adjust demo example
    * add test
    
    Issue: TOBAGO-2149
---
 .../tobago/internal/util/AuthorizationHelper.java  | 33 ++++++++++++++++------
 .../2008-roles-allowed/Roles_Allowed.test.js       |  3 ++
 .../2008-roles-allowed/Roles_Allowed.xhtml         |  6 ++--
 .../resources/demo-components/rolesTest.xhtml      |  9 +++---
 4 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java
index 1d07f972c2..6eac36a2b9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/util/AuthorizationHelper.java
@@ -19,19 +19,21 @@
 
 package org.apache.myfaces.tobago.internal.util;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import jakarta.annotation.security.DenyAll;
 import jakarta.annotation.security.PermitAll;
 import jakarta.annotation.security.RolesAllowed;
 import jakarta.el.ELContext;
+import jakarta.el.MethodExpression;
+import jakarta.el.ValueExpression;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.enterprise.inject.spi.Bean;
 import jakarta.enterprise.inject.spi.BeanManager;
 import jakarta.faces.component.UIComponent;
 import jakarta.faces.context.FacesContext;
 import jakarta.inject.Named;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.lang.annotation.Annotation;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.AnnotatedElement;
@@ -165,16 +167,29 @@ public class AuthorizationHelper {
       UIComponent compositeComponent = getParentCompositeComponent(component);
       if (compositeComponent != null) {
         final int attrNameStart = expression.indexOf(CC_ATTRS) + CC_ATTRS.length();
-        final int attrNameEnd = attrNameStart + expression.substring(attrNameStart).indexOf(".");
+        final int attrNameEnd = expression.substring(attrNameStart).contains(".")
+          ? attrNameStart + expression.substring(attrNameStart).indexOf(".")
+          : attrNameStart + expression.substring(attrNameStart).indexOf("}");
         final String attrName = expression.substring(attrNameStart, attrNameEnd);
 
-        final String ccExpression = compositeComponent.getValueExpression(attrName).getExpressionString();
-        final int bracketStart = ccExpression.indexOf('{');
-        final int bracketEnd = ccExpression.indexOf("}");
-        final String trimmedCcExpression = ccExpression.substring(bracketStart + 1, bracketEnd).trim();
+        ValueExpression valueExpression = compositeComponent.getValueExpression(attrName);
+        if (valueExpression != null) {
+          final String ccExpression = valueExpression.getExpressionString();
+          final int bracketStart = ccExpression.indexOf('{');
+          final int bracketEnd = ccExpression.indexOf("}");
+          final String trimmedCcExpression = ccExpression.substring(bracketStart + 1, bracketEnd).trim();
 
-        return getSecurityAnnotation(facesContext, component,
+          return getSecurityAnnotation(facesContext, component,
             expression.replace(CC_ATTRS + attrName, trimmedCcExpression));
+        }
+
+        MethodExpression methodExpression = (MethodExpression) compositeComponent.getAttributes().get(attrName);
+        if (methodExpression != null) {
+          return getSecurityAnnotation(facesContext, component,
+            methodExpression.getExpressionString().replaceAll(" ", ""));
+        }
+
+        return securityAnnotation;
       } else {
         return securityAnnotation;
       }
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.test.js b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.test.js
index 5dc2110fea..135558f431 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.test.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.test.js
@@ -29,6 +29,7 @@ it("RolesAllowed as 'guest'", function (done) {
   const ccOutputLabelFn = querySelectorFn("#page\\:mainForm\\:ccRolesTest\\:out label");
   const ccOutputValueFn = querySelectorFn("#page\\:mainForm\\:ccRolesTest\\:out .form-control-plaintext");
   const ccButtonFn = elementByIdFn("page:mainForm:ccRolesTest:submit");
+  const ccButton2Fn = elementByIdFn("page:mainForm:ccRolesTest:submit2");
 
   const url = document.getElementById("page:testframe").contentWindow.location.href;
   let time;
@@ -41,6 +42,7 @@ it("RolesAllowed as 'guest'", function (done) {
   test.do(() => expect(buttonFn().disabled).toBeTrue());
   test.do(() => expect(ccOutputLabelFn().textContent).toBe("Label"));
   test.do(() => expect(ccButtonFn().disabled).toBeTrue());
+  test.do(() => expect(ccButton2Fn().disabled).toBeTrue());
 
   test.do(() => userFn().value = "guest");
   test.do(() => passwordFn().value = "guest");
@@ -53,6 +55,7 @@ it("RolesAllowed as 'guest'", function (done) {
   test.do(() => expect(buttonFn().disabled).toBeFalse());
   test.do(() => expect(ccOutputLabelFn().textContent).toBe("Label"));
   test.do(() => expect(ccButtonFn().disabled).toBeFalse());
+  test.do(() => expect(ccButton2Fn().disabled).toBeFalse());
 
   test.do(() => time = outputValueFn().textContent);
   test.event("click", buttonFn, () => outputValueFn().textContent !== time);
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.xhtml
index 8cc3ae573b..f20b353fa5 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/5500-compositeComponent/2008-roles-allowed/Roles_Allowed.xhtml
@@ -25,6 +25,7 @@
   <ui:param name="title" value="Composite Components"/>
 
   <tc:box label="Login">
+    <p>user=guest; pw=guest</p>
     <tc:panel rendered="#{request.userPrincipal == null}">
       <tc:in id="username" value="#{loginController.username}" label="User" required="true"/>
       <tc:in id="password" value="#{loginController.password}" password="true" label="Password" required="true"/>
@@ -41,7 +42,8 @@
     <tc:button id="button" label="Reload" action="#{roleController.refreshTime}"/>
   </tc:section>
 
-  <tc:section label="RolesTest Composite Component">
-    <dc:rolesTest id="ccRolesTest" label="Label" controller="#{roleController}"/>
+  <tc:section label="RolesTest1 Composite Component">
+    <dc:rolesTest id="ccRolesTest" label="Label" controller="#{ roleController }"
+                  action="#{ roleController.refreshTime }"/>
   </tc:section>
 </ui:composition>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/resources/demo-components/rolesTest.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/resources/demo-components/rolesTest.xhtml
index 620b269718..ba2ffeae0e 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/resources/demo-components/rolesTest.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/resources/demo-components/rolesTest.xhtml
@@ -15,17 +15,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
 -->
-<!DOCTYPE html
-        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns:cc="http://xmlns.jcp.org/jsf/composite"
       xmlns:tc="http://myfaces.apache.org/tobago/component">
 <cc:interface>
   <cc:attribute name="label"/>
   <cc:attribute name="controller" type="RoleController"/>
+  <cc:attribute name="action" method-signature="java.lang.String action()"/>
 </cc:interface>
 <cc:implementation>
   <tc:out id="out" label="#{cc.attrs.label}" value="#{cc.attrs.controller.time}"/>
-  <tc:button id="submit" label="Reload" action="#{cc.attrs.controller.refreshTime}"/>
+  <tc:button id="submit" label="Reload 1" action="#{cc.attrs.controller.refreshTime}"/>
+  <tc:button id="submit2" label="Reload 2" action="#{cc.attrs.action}"/>
 </cc:implementation>
 </html>