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

mridulpathak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 9f86d1040e Fixed: ModelApiReader resolved omitted auth/publish 
attributes to false, opposite of rest-api.xsd's declared default (#2011)
9f86d1040e is described below

commit 9f86d1040e1a19e675f9f6ad2605dc18adf6cfee
Author: Mridul Pathak <[email protected]>
AuthorDate: Thu Sep 17 14:48:36 2026 +0530

    Fixed: ModelApiReader resolved omitted auth/publish attributes to false, 
opposite of rest-api.xsd's declared default (#2011)
    
    ModelApiReader parsed an omitted auth or publish attribute via 
Boolean.parseBoolean(""), which resolves to false, while rest-api.xsd declares 
both attributes default="true". A .rest.xml resource or operation that omits 
auth therefore registered without the @Secured binding OFBizApiConfig applies 
based on isAuth(), contrary to what the schema documents. ModelApiReader now 
defaults both attributes to true when omitted, matching the XSD.
---
 .../apache/ofbiz/ws/rs/model/ModelApiReader.java   | 23 ++++++++++++++++++----
 .../ofbiz/ws/rs/model/ModelApiReaderTest.java      | 10 ++++------
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/model/ModelApiReader.java
 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/model/ModelApiReader.java
index a6aab6c294..bec41a8739 100644
--- 
a/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/model/ModelApiReader.java
+++ 
b/framework/rest-api/src/main/java/org/apache/ofbiz/ws/rs/model/ModelApiReader.java
@@ -61,7 +61,7 @@ public final class ModelApiReader {
         
api.setName(UtilXml.checkEmpty(docElement.getAttribute("name")).intern());
         
api.setDescription(UtilXml.checkEmpty(docElement.getAttribute("description")).intern());
         
api.setPath(UtilXml.checkEmpty(docElement.getAttribute("path")).intern());
-        
api.setPublish(Boolean.parseBoolean(UtilXml.checkEmpty(docElement.getAttribute("publish")).intern()));
+        
api.setPublish(parseBooleanDefaultTrue(docElement.getAttribute("publish")));
         for (Element resourceEle : UtilXml.childElementList(docElement, 
"resource")) {
             createModelResource(resourceEle, api);
         }
@@ -107,8 +107,8 @@ public final class ModelApiReader {
                 
.description(UtilXml.checkEmpty(resourceEle.getAttribute("description")).intern())
                 
.displayName(UtilXml.checkEmpty(resourceEle.getAttribute("displayName")).intern())
                 
.path(UtilXml.checkEmpty(resourceEle.getAttribute("path")).intern())
-                
.publish(Boolean.parseBoolean(UtilXml.checkEmpty(resourceEle.getAttribute("publish")).intern()))
-                
.auth(Boolean.parseBoolean(UtilXml.checkEmpty(resourceEle.getAttribute("auth")).intern()))
+                
.publish(parseBooleanDefaultTrue(resourceEle.getAttribute("publish")))
+                
.auth(parseBooleanDefaultTrue(resourceEle.getAttribute("auth")))
                 
.primaryPermission(UtilXml.checkEmpty(resourceEle.getAttribute("primaryPermission")).intern())
                 
.mainAction(UtilXml.checkEmpty(resourceEle.getAttribute("mainAction")).intern())
                 
.customHeaders(UtilXml.checkEmpty(resourceEle.getAttribute("customHeaders")).intern());
@@ -125,7 +125,7 @@ public final class ModelApiReader {
                         
.produces(UtilXml.checkEmpty(operationEle.getAttribute("produces")).intern())
                         
.consumes(UtilXml.checkEmpty(operationEle.getAttribute("consumes")).intern())
                         
.description(UtilXml.checkEmpty(operationEle.getAttribute("description")).intern())
-                        
.auth(Boolean.parseBoolean(UtilXml.checkEmpty(operationEle.getAttribute("auth")).intern()))
+                        
.auth(parseBooleanDefaultTrue(operationEle.getAttribute("auth")))
                         
.primaryPermission(UtilXml.checkEmpty(operationEle.getAttribute("primaryPermission"),
                                 
resourceEle.getAttribute("primaryPermission")).intern())
                         
.mainAction(UtilXml.checkEmpty(operationEle.getAttribute("mainAction"),
@@ -144,6 +144,21 @@ public final class ModelApiReader {
     }
 
 
+    /**
+     * Parses an {@code xs:boolean}-typed attribute that {@code rest-api.xsd} 
declares with
+     * {@code default="true"} (currently {@code publish} and {@code auth}). 
DOM's
+     * {@code Element.getAttribute} returns {@code ""} for an attribute that 
is absent from the
+     * source XML, so the omitted case must be defaulted explicitly rather 
than handed to
+     * {@link Boolean#parseBoolean(String)}, which would otherwise resolve it 
to {@code false}.
+     *
+     * @param attributeValue the raw attribute value, or {@code ""} if the 
attribute was omitted
+     * @return {@code true} if the attribute was omitted or explicitly {@code 
"true"}; {@code false} otherwise
+     */
+    private static boolean parseBooleanDefaultTrue(String attributeValue) {
+        String value = UtilXml.checkEmpty(attributeValue).intern();
+        return value.isEmpty() || Boolean.parseBoolean(value);
+    }
+
     private static void createQueryParams(Element operationEle, ModelOperation 
operation) {
         for (Element queryParamEle : UtilXml.childElementList(operationEle, 
"queryParam")) {
             ModelQueryParam qp = new ModelQueryParam()
diff --git 
a/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/model/ModelApiReaderTest.java
 
b/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/model/ModelApiReaderTest.java
index 5cb0f398da..6d21ed7e6f 100644
--- 
a/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/model/ModelApiReaderTest.java
+++ 
b/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/model/ModelApiReaderTest.java
@@ -19,7 +19,6 @@
 package org.apache.ofbiz.ws.rs.model;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -67,15 +66,14 @@ class ModelApiReaderTest {
     }
 
     @Test
-    void testGetModelApiMissingPublishAttributeDefaultsToFalse() throws 
IOException {
-        // No "publish" attribute at all -> UtilXml.checkEmpty(...) yields "",
-        // and Boolean.parseBoolean("") is false. This locks in that implicit
-        // default so a change in checkEmpty/parseBoolean behavior is caught.
+    void testGetModelApiMissingPublishAttributeDefaultsToTrue() throws 
IOException {
+        // No "publish" attribute at all -> rest-api.xsd declares this 
attribute
+        // default="true", so an omitted attribute must resolve to true.
         File file = writeXml("<api name=\"myApi\"/>");
 
         ModelApi api = ModelApiReader.getModelApi(file);
 
-        assertFalse(api.isPublish());
+        assertTrue(api.isPublish());
     }
 
     @Test

Reply via email to