diff --git a/source/java/org/alfresco/rest/api/PublicApiDeclarativeRegistry.java b/source/java/org/alfresco/rest/api/PublicApiDeclarativeRegistry.java
index ecabb4bec7..28d8178325 100644
--- a/source/java/org/alfresco/rest/api/PublicApiDeclarativeRegistry.java
+++ b/source/java/org/alfresco/rest/api/PublicApiDeclarativeRegistry.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -23,14 +23,16 @@
* along with Alfresco. If not, see .
* #L%
*/
-package org.alfresco.rest.api;
-
+package org.alfresco.rest.api;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
-import java.util.*;
-
-import org.alfresco.rest.api.authentications.AuthenticationTicketsEntityResource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.core.ResourceLocator;
import org.alfresco.rest.framework.core.ResourceWithMetadata;
@@ -43,24 +45,25 @@ import org.alfresco.rest.framework.resource.actions.interfaces.ResourceAction;
import org.alfresco.rest.framework.tools.ApiAssistant;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.webscripts.*;
-import org.springframework.extensions.webscripts.Description.FormatStyle;
-import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
-import org.springframework.extensions.webscripts.Description.RequiredTransaction;
-import org.springframework.extensions.webscripts.Description.TransactionCapability;
+import org.springframework.extensions.webscripts.Description.FormatStyle;
+import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
+import org.springframework.extensions.webscripts.Description.RequiredTransaction;
+import org.springframework.extensions.webscripts.Description.TransactionCapability;
import org.springframework.http.HttpMethod;
-
+
/**
*
* @author steveglover
* @author janv
+ * @author Jamal Kaabi-Mofrad
* @since PublicApi1.0
*/
-public class PublicApiDeclarativeRegistry extends DeclarativeRegistry
-{
- private WebScript getNetworksWebScript;
- private WebScript getNetworkWebScript;
- private Container container;
-
+public class PublicApiDeclarativeRegistry extends DeclarativeRegistry
+{
+ private WebScript getNetworksWebScript;
+ private WebScript getNetworkWebScript;
+ private Container container;
+
private ResourceLocator locator;
public void setLocator(ResourceLocator locator)
@@ -68,27 +71,27 @@ public class PublicApiDeclarativeRegistry extends DeclarativeRegistry
this.locator = locator;
}
- public void setGetNetworksWebScript(WebScript getNetworksWebScript)
- {
- this.getNetworksWebScript = getNetworksWebScript;
- }
-
- public void setGetNetworkWebScript(WebScript getNetworkWebScript)
- {
- this.getNetworkWebScript = getNetworkWebScript;
- }
-
- public void setContainer(Container container)
- {
- super.setContainer(container);
- this.container = container;
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.web.scripts.Registry#findWebScript(java.lang.String, java.lang.String)
- */
- public Match findWebScript(String method, String uri)
- {
+ public void setGetNetworksWebScript(WebScript getNetworksWebScript)
+ {
+ this.getNetworksWebScript = getNetworksWebScript;
+ }
+
+ public void setGetNetworkWebScript(WebScript getNetworkWebScript)
+ {
+ this.getNetworkWebScript = getNetworkWebScript;
+ }
+
+ public void setContainer(Container container)
+ {
+ super.setContainer(container);
+ this.container = container;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.Registry#findWebScript(java.lang.String, java.lang.String)
+ */
+ public Match findWebScript(String method, String uri)
+ {
Match match;
HttpMethod httpMethod = HttpMethod.valueOf(method);
@@ -189,17 +192,46 @@ public class PublicApiDeclarativeRegistry extends DeclarativeRegistry
else if (HttpMethod.POST.equals(httpMethod))
{
match = super.findWebScript(method, uri);
- if (match != null && uri.endsWith(AuthenticationTicketsEntityResource.COLLECTION_RESOURCE_NAME))
+ if (match != null)
{
ResourceWithMetadata rwm = getResourceWithMetadataOrNull(match.getTemplateVars(), httpMethod);
- if (rwm != null && AuthenticationTicketsEntityResource.class.equals(rwm.getResource().getClass()))
+ if (rwm != null)
{
Class extends ResourceAction> resAction = null;
- if (EntityResourceAction.Create.class.isAssignableFrom(rwm.getResource().getClass()))
+ Boolean noAuth = null;
+ switch (rwm.getMetaData().getType())
{
- resAction = EntityResourceAction.Create.class;
+ case ENTITY:
+ if (EntityResourceAction.Create.class.isAssignableFrom(rwm.getResource().getClass()))
+ {
+ resAction = EntityResourceAction.Create.class;
+ }
+ else if (EntityResourceAction.CreateWithResponse.class.isAssignableFrom(rwm.getResource().getClass()))
+ {
+ resAction = EntityResourceAction.CreateWithResponse.class;
+ }
+ break;
+ case RELATIONSHIP:
+ if (RelationshipResourceAction.Create.class.isAssignableFrom(rwm.getResource().getClass()))
+ {
+ resAction = RelationshipResourceAction.Create.class;
+ }
+ else if (RelationshipResourceAction.CreateWithResponse.class.isAssignableFrom(rwm.getResource().getClass()))
+ {
+ resAction = RelationshipResourceAction.CreateWithResponse.class;
+ }
+ break;
+ case OPERATION:
+ noAuth = rwm.getMetaData().isNoAuth(null);
+ break;
+ default:
+ break;
+ }
+
+ if (noAuth == null)
+ {
+ noAuth = (resAction != null && rwm.getMetaData().isNoAuth(resAction));
}
- final boolean noAuth = (resAction != null && rwm.getMetaData().isNoAuth(resAction));
if (noAuth)
{
// override match with noAuth
@@ -224,7 +256,7 @@ public class PublicApiDeclarativeRegistry extends DeclarativeRegistry
{
if (templateVars.get("apiName") != null)
{
- // NOTE: noAuth currently only exposed for GET or Create Ticket (login)
+ // NOTE: noAuth currently only exposed for GET or POST
Api api = ApiAssistant.determineApi(templateVars);
// TODO can we avoid locating resource more than once (or at least provide a common code to determine the GET resourceAction) ?
@@ -435,27 +467,27 @@ public class PublicApiDeclarativeRegistry extends DeclarativeRegistry
// override match with noAuth
return new Match(match.getTemplate(), match.getTemplateVars(), match.getPath(), noAuthWebScriptWrapper);
- }
+ }
- private void initWebScript(WebScript webScript, String name)
- {
- DescriptionImpl serviceDesc = new DescriptionImpl(name, name, name, name);
- serviceDesc.setRequiredAuthentication(RequiredAuthentication.user);
- TransactionParameters transactionParameters = new TransactionParameters();
- transactionParameters.setRequired(RequiredTransaction.required);
- transactionParameters.setCapability(TransactionCapability.readonly);
- serviceDesc.setRequiredTransactionParameters(transactionParameters);
- serviceDesc.setFormatStyle(FormatStyle.argument);
- serviceDesc.setDefaultFormat("json");
- serviceDesc.setUris(new String[] { name });
- webScript.init(container, serviceDesc);
- }
-
- public void reset()
- {
- super.reset();
- initWebScript(getNetworksWebScript, "networks");
- initWebScript(getNetworkWebScript, "network");
- }
-}
+ private void initWebScript(WebScript webScript, String name)
+ {
+ DescriptionImpl serviceDesc = new DescriptionImpl(name, name, name, name);
+ serviceDesc.setRequiredAuthentication(RequiredAuthentication.user);
+ TransactionParameters transactionParameters = new TransactionParameters();
+ transactionParameters.setRequired(RequiredTransaction.required);
+ transactionParameters.setCapability(TransactionCapability.readonly);
+ serviceDesc.setRequiredTransactionParameters(transactionParameters);
+ serviceDesc.setFormatStyle(FormatStyle.argument);
+ serviceDesc.setDefaultFormat("json");
+ serviceDesc.setUris(new String[] { name });
+ webScript.init(container, serviceDesc);
+ }
+
+ public void reset()
+ {
+ super.reset();
+ initWebScript(getNetworksWebScript, "networks");
+ initWebScript(getNetworkWebScript, "network");
+ }
+}
diff --git a/source/java/org/alfresco/rest/framework/core/OperationResourceMetaData.java b/source/java/org/alfresco/rest/framework/core/OperationResourceMetaData.java
index 56c7f926a8..919028df79 100644
--- a/source/java/org/alfresco/rest/framework/core/OperationResourceMetaData.java
+++ b/source/java/org/alfresco/rest/framework/core/OperationResourceMetaData.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -40,6 +40,7 @@ import java.util.Set;
public class OperationResourceMetaData extends ResourceMetadata
{
private final Method operationMethod;
+ private final boolean noAuthRequired;
/**
* Use this constructor to create the resource metadata
@@ -47,8 +48,9 @@ public class OperationResourceMetaData extends ResourceMetadata
* @param operations
* @param api
* @param operationMethod
+ * @param noAuthRequired
*/
- public OperationResourceMetaData(String uniqueId, List operations, Api api, Method operationMethod)
+ public OperationResourceMetaData(String uniqueId, List operations, Api api, Method operationMethod, boolean noAuthRequired)
{
super(uniqueId, RESOURCE_TYPE.OPERATION, operations, api, null, null, null);
if (operations.size()!= 1)
@@ -56,6 +58,7 @@ public class OperationResourceMetaData extends ResourceMetadata
throw new IllegalArgumentException("Only 1 operation per url is supported for an entity");
}
this.operationMethod = operationMethod;
+ this.noAuthRequired = noAuthRequired;
}
/**
@@ -63,11 +66,13 @@ public class OperationResourceMetaData extends ResourceMetadata
* @param uniqueId
* @param api
* @param apiDeleted
+ * @param noAuthRequired
*/
- public OperationResourceMetaData(String uniqueId, Api api, Set> apiDeleted)
+ public OperationResourceMetaData(String uniqueId, Api api, Set> apiDeleted, boolean noAuthRequired)
{
super(uniqueId, RESOURCE_TYPE.OPERATION, null, api, apiDeleted, null, null);
this.operationMethod = null;
+ this.noAuthRequired = noAuthRequired;
}
public Method getOperationMethod()
@@ -75,6 +80,12 @@ public class OperationResourceMetaData extends ResourceMetadata
return operationMethod;
}
+ @Override
+ public boolean isNoAuth(Class extends ResourceAction> resourceAction)
+ {
+ return this.noAuthRequired;
+ }
+
@Override
public String toString()
{
@@ -91,7 +102,8 @@ public class OperationResourceMetaData extends ResourceMetadata
builder.append(this.getOperations());
builder.append(", apiDeleted=");
builder.append(this.getApiDeleted());
- builder.append("operationMethod=").append(operationMethod);
+ builder.append(", operationMethod=").append(operationMethod);
+ builder.append(", noAuthRequired=").append(noAuthRequired);
builder.append("]");
return builder.toString();
}
diff --git a/source/java/org/alfresco/rest/framework/core/ResourceInspector.java b/source/java/org/alfresco/rest/framework/core/ResourceInspector.java
index 8fde2e6ec6..424c103725 100644
--- a/source/java/org/alfresco/rest/framework/core/ResourceInspector.java
+++ b/source/java/org/alfresco/rest/framework/core/ResourceInspector.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -308,7 +308,7 @@ public class ResourceInspector
{
if (! (httpMethod.equals(HttpMethod.GET) || httpMethod.equals(HttpMethod.POST)))
{
- throw new IllegalArgumentException("@WebApiNoAuth should only be on GET methods: "+operation.getTitle()+" Or POST method for creating a ticket.");
+ throw new IllegalArgumentException("@WebApiNoAuth should only be on GET or POST methods: " + operation.getTitle());
}
helper.whenOperationNoAuth(resourceInterfaceWithOneMethod, aMethod);
}
@@ -327,7 +327,7 @@ public class ResourceInspector
Annotation annot = AnnotationUtils.findAnnotation(aMethod, WebApiDescription.class);
List parameters = new ArrayList();
parameters.addAll(inspectParameters(resource, aMethod, httpMethod));
-
+
if (annot != null)
{
Map annotAttribs = AnnotationUtils.getAnnotationAttributes(annot);
@@ -638,6 +638,7 @@ public class ResourceInspector
* Inspect a resource to find operations on it.
* @param api Api
* @param entityPath String
+ * @param metainfo resource metadata
*/
public static void inspectOperations(Api api, Class> resource, final String entityPath, List metainfo)
{
@@ -646,13 +647,16 @@ public class ResourceInspector
{
for (Entry> opera : operations.entrySet())
{
- if (isDeleted(opera.getValue().getSecond()))
+ Method annotatedMethod = opera.getValue().getSecond();
+ final boolean isNoAuthRequired = isNoAuth(annotatedMethod);
+
+ if (isDeleted(annotatedMethod))
{
- metainfo.add(new OperationResourceMetaData(opera.getKey(), api, new HashSet(Arrays.asList(opera.getValue().getFirst()))));
+ metainfo.add(new OperationResourceMetaData(opera.getKey(), api, new HashSet(Arrays.asList(opera.getValue().getFirst())), isNoAuthRequired));
}
else
{
- metainfo.add(new OperationResourceMetaData(opera.getKey(), Arrays.asList(opera.getValue().getFirst()), api, opera.getValue().getSecond()));
+ metainfo.add(new OperationResourceMetaData(opera.getKey(), Arrays.asList(opera.getValue().getFirst()), api, annotatedMethod, isNoAuthRequired));
}
}
}
diff --git a/source/java/org/alfresco/rest/framework/core/ResourceMetadata.java b/source/java/org/alfresco/rest/framework/core/ResourceMetadata.java
index 3a008d5f6a..79b7f6bcb8 100644
--- a/source/java/org/alfresco/rest/framework/core/ResourceMetadata.java
+++ b/source/java/org/alfresco/rest/framework/core/ResourceMetadata.java
@@ -1,8 +1,9 @@
+/*
/*
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -86,16 +87,17 @@ public class ResourceMetadata
}
/**
- * Indicates if this resource can support the specified HTTPMethod
- * @param supportedMethod HttpMethod
- * @return true if can support it
+ * Gets the data type of the resource parameter
+ *
+ * @param operation {@code ResourceOperation} object
+ * @return The data type of the resource parameter
*/
- @SuppressWarnings("rawtypes")
public Class getObjectType(ResourceOperation operation)
{
for (ResourceParameter param : operation.getParameters())
{
- if (ResourceParameter.KIND.HTTP_BODY_OBJECT.equals(param.getParamType())) {
+ if (ResourceParameter.KIND.HTTP_BODY_OBJECT.equals(param.getParamType()))
+ {
return param.getDataType();
}
}
diff --git a/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java b/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java
index 275c4c4eea..c5dd36c21e 100644
--- a/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java
+++ b/source/test-java/org/alfresco/rest/framework/tests/api/mocks/GrassEntityResource.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -27,6 +27,7 @@ package org.alfresco.rest.framework.tests.api.mocks;
import org.alfresco.rest.framework.Operation;
import org.alfresco.rest.framework.WebApiDescription;
+import org.alfresco.rest.framework.WebApiNoAuth;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.core.ResourceParameter;
import org.alfresco.rest.framework.resource.EntityResource;
@@ -73,4 +74,11 @@ public class GrassEntityResource implements EntityResourceAction.ReadById
{
//I did a delete
}
+
+ @Operation("cut-noAuth")
+ @WebApiNoAuth
+ @WebApiDescription(title = "Cut the grass",successStatus = Status.STATUS_NOT_IMPLEMENTED)
+ public String cutLawnWithoutAuth(String id, Void notused, Parameters parameters, WithResponse withResponse) {
+ return "All done without Auth";
+ }
}
diff --git a/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java b/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java
index 70da787514..164b16b69a 100644
--- a/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java
+++ b/source/test-java/org/alfresco/rest/framework/tests/core/InspectorTests.java
@@ -2,7 +2,7 @@
* #%L
* Alfresco Remote API
* %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * Copyright (C) 2005 - 2017 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -41,7 +41,6 @@ import java.util.Map;
import org.alfresco.rest.api.model.Comment;
import org.alfresco.rest.api.nodes.NodeCommentsRelation;
-import org.alfresco.rest.api.nodes.NodesEntityResource;
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.core.OperationResourceMetaData;
import org.alfresco.rest.framework.core.ResourceInspector;
@@ -76,9 +75,7 @@ import org.alfresco.rest.framework.tests.api.mocks3.GrassEntityResourceNowDelete
import org.alfresco.rest.framework.tests.api.mocks3.SheepBlackSheepResourceIsNoMore;
import org.alfresco.rest.framework.tests.api.mocks3.SheepEntityResourceWithDeletedMethods;
import org.alfresco.rest.framework.tests.api.mocks3.SlimGoat;
-import org.alfresco.rest.framework.tools.ApiAssistant;
import org.alfresco.rest.framework.tools.ResponseWriter;
-import org.alfresco.rest.framework.webscripts.ApiWebScript;
import org.alfresco.rest.framework.webscripts.WithResponse;
import org.alfresco.util.Pair;
import org.junit.Test;
@@ -459,7 +456,7 @@ public class InspectorTests
GrassEntityResource grassEntityResource = new GrassEntityResource();
ResourceInspector.inspectOperations(api, GrassEntityResource.class,"-root-", metainfo);
- assertTrue(metainfo.size()==2);
+ assertEquals(3, metainfo.size());
for (ResourceMetadata resourceMetadata : metainfo)
{
@@ -480,6 +477,7 @@ public class InspectorTests
Object paramObj = paramType.newInstance();
result = (String) ResourceInspectorUtil.invokeMethod(actionMethod,grassEntityResource, "xyz", paramObj, Params.valueOf("notUsed", null, mock(WebScriptRequest.class)), wr);
assertEquals("Growing well",result);
+ assertFalse(operationResourceMetaData.isNoAuth(null));
break;
case "/-root-/{id}/cut":
assertNotNull("GrassEntityResource supports POST", resourceMetadata.getOperation(HttpMethod.POST));
@@ -489,6 +487,16 @@ public class InspectorTests
assertEquals("cut should return ACCEPTED", Status.STATUS_NOT_IMPLEMENTED, op.getSuccessStatus());
result = (String) ResourceInspectorUtil.invokeMethod(actionMethod,grassEntityResource, "xyz", null, Params.valueOf("notUsed", null, mock(WebScriptRequest.class)), wr);
assertEquals("All done",result);
+ assertFalse(operationResourceMetaData.isNoAuth(null));
+ break;
+ case "/-root-/{id}/cut-noAuth":
+ assertNotNull("GrassEntityResource supports POST", resourceMetadata.getOperation(HttpMethod.POST));
+ op = resourceMetadata.getOperation(HttpMethod.POST);
+ assertNull(resourceMetadata.getObjectType(op));
+ assertEquals("cut should return ACCEPTED", Status.STATUS_NOT_IMPLEMENTED, op.getSuccessStatus());
+ result = (String) ResourceInspectorUtil.invokeMethod(actionMethod,grassEntityResource, "xyz", null, Params.valueOf("notUsed", null, mock(WebScriptRequest.class)), wr);
+ assertEquals("All done without Auth",result);
+ assertTrue(operationResourceMetaData.isNoAuth(null));
break;
default:
fail("Invalid action information.");