<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>
<docker.location>${basedir}/target/${project.artifactId}</docker.location>
<datarouter.prov.image.name>${docker.image.root}${project.artifactId}</datarouter.prov.image.name>
- <sonar.exclusions>**/src/main/java/org/onap/dmaap/datarouter/reports/**</sonar.exclusions>
+ <sonar.exclusions>**/src/main/java/org/onap/dmaap/datarouter/reports/**,
+ **/src/main/java/org/onap/dmaap/authz/impl/AuthRespSupplementImpl.java</sonar.exclusions>
<sonar.language>java</sonar.language>
<sonar.skip>false</sonar.skip>
</properties>
<configuration>
<excludes>
<exclude>**/src/main/java/org/onap/dmaap/datarouter/reports/**</exclude>
+ <exclude>**/src/main/java/org/onap/dmaap/authz/impl/AuthRespSupplementImpl.java</exclude>
</excludes>
</configuration>
</plugin>
/** Constructor. This version will not be used in Data Router R1 since we will not have advice and obligations.\r
*\r
* @param authorized flag indicating whether the response carried a permit response (<code>true</code>)\r
- * or something else (<code>false</code>).\r
+ * or something else (<code>false</code>).\r
* @param advice list of advice elements returned in the response.\r
* @param obligations list of obligation elements returned in the response.\r
*/\r
- public AuthRespImpl(boolean authorized, List<AuthorizationResponseSupplement> advice, List<AuthorizationResponseSupplement> obligations) {\r
+ private AuthRespImpl(boolean authorized, List<AuthorizationResponseSupplement> advice,\r
+ List<AuthorizationResponseSupplement> obligations) {\r
this.authorized = authorized;\r
- this.advice = (advice == null ? null : new ArrayList<AuthorizationResponseSupplement> (advice));\r
- this.obligations = (obligations == null ? null : new ArrayList<AuthorizationResponseSupplement> (obligations));\r
+ this.advice = (advice == null ? null : new ArrayList<>(advice));\r
+ this.obligations = (obligations == null ? null : new ArrayList<>(obligations));\r
}\r
\r
/** Constructor. Simple version for authorization responses that have no advice and no obligations.\r
*\r
- * @param authorized flag indicating whether the response carried a permit (<code>true</code>) or something else (<code>false</code>).\r
+ * @param authorized flag indicating whether the response carried a permit (<code>true</code>)\r
+ * or something else (<code>false</code>).\r
*/\r
- public AuthRespImpl(boolean authorized) {\r
+ AuthRespImpl(boolean authorized) {\r
this(authorized, null, null);\r
}\r
\r
*/\r
@Override\r
public boolean isAuthorized() {\r
- return authorized;\r
+ return authorized;\r
}\r
\r
/**\r
* Returns any advice elements that were included in the authorization response.\r
*\r
- * @return A list of objects implementing the <code>AuthorizationResponseSupplement</code> interface, with each object representing an\r
- * advice element from the authorization response.\r
+ * @return A list of objects implementing the <code>AuthorizationResponseSupplement</code> interface,\r
+ * with each object representing an advice element from the authorization response.\r
*/\r
@Override\r
public List<AuthorizationResponseSupplement> getAdvice() {\r
- return advice;\r
+ return advice;\r
}\r
\r
/**\r
* Returns any obligation elements that were included in the authorization response.\r
*\r
- * @return A list of objects implementing the <code>AuthorizationResponseSupplement</code> interface, with each object representing an\r
- * obligation element from the authorization response.\r
+ * @return A list of objects implementing the <code>AuthorizationResponseSupplement</code> interface,\r
+ * with each object representing an obligation element from the authorization response.\r
*/\r
@Override\r
public List<AuthorizationResponseSupplement> getObligations() {\r
*/\r
public class AuthRespSupplementImpl implements AuthorizationResponseSupplement {\r
\r
- private String id = null;\r
- private Map<String, String> attributes = null;\r
+ private String id;\r
+ private Map<String, String> attributes;\r
\r
/** Constructor, available within the package.\r
*\r
* @param id The identifier for the advice or obligation element\r
* @param attributes The attributes (name-value pairs) for the advice or obligation element.\r
*/\r
- AuthRespSupplementImpl (String id, Map<String, String> attributes) {\r
+ AuthRespSupplementImpl(String id, Map<String, String> attributes) {\r
this.id = id;\r
- this.attributes = new HashMap<String,String>(attributes);\r
+ this.attributes = new HashMap<>(attributes);\r
}\r
\r
/** Return the identifier for the supplementary information element.\r
/** Internal representation of an authorization resource (the entity to which access is being requested). Consists\r
* of a type and an identifier. The constructor takes the request URI from an HTTP request and checks it against\r
* patterns for the the different resource types. In DR R1, there are four resource types:\r
- * <ul>\r
* <li>the feeds collection resource, the target of POST requests to create a new feed and GET requests to list\r
* the existing feeds. This is the root resource for the DR provisioning system, and it has no explicit id.\r
* </li>\r
private String id = "";\r
\r
/* Construct an AuthzResource by matching a request URI against the various patterns */\r
- public AuthzResource(String rURI) {\r
- if (rURI != null) {\r
+ AuthzResource(String requestUri) {\r
+ if (requestUri != null) {\r
for (ResourceType t : ResourceType.values()) {\r
- Matcher m = t.getPattern().matcher(rURI);\r
+ Matcher m = t.getPattern().matcher(requestUri);\r
if (m.find(0)) {\r
this.type = t;\r
if (m.group("id") != null) {\r
*/\r
public enum ResourceType {\r
FEEDS_COLLECTION("((://[^/]+/)|(^/))(?<id>)$"),\r
- SUBS_COLLECTION ("((://[^/]+/)|(^/{0,1}))subscribe/(?<id>[^/]+)$"),\r
+ SUBS_COLLECTION("((://[^/]+/)|(^/{0,1}))subscribe/(?<id>[^/]+)$"),\r
FEED("((://[^/]+/)|(^/{0,1}))feed/(?<id>[^/]+)$"),\r
SUB("((://[^/]+/)|(^/{0,1}))subs/(?<id>[^/]+)$");\r
\r
private Pattern uriPattern;\r
\r
- private ResourceType(String patternString) {\r
+ ResourceType(String patternString) {\r
this.uriPattern = Pattern.compile(patternString);\r
}\r
\r
package org.onap.dmaap.datarouter.authz.impl;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-
import com.att.eelf.configuration.EELFLogger;
import com.att.eelf.configuration.EELFManager;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
import org.onap.dmaap.datarouter.authz.Authorizer;
import org.onap.dmaap.datarouter.authz.impl.AuthzResource.ResourceType;
-/** Authorizer for the provisioning API for Data Router R1
+/** Authorizer for the provisioning API for Data Router R1.
*
* @author J. F. Lucas
*
private static final String SUBJECT_HEADER = "X-DMAAP-DR-ON-BEHALF-OF"; // HTTP header carrying requester identity
private static final String SUBJECT_HEADER_GROUP = "X-DMAAP-DR-ON-BEHALF-OF-GROUP"; // HTTP header carrying requester identity by group Rally : US708115
+
/** Constructor. For the moment, do nothing special. Make it a singleton?
*
*/
*/
@Override
public AuthorizationResponse decide(HttpServletRequest request) {
- return this.decide(request, null);
+ return this.decide(request, null);
}
/**
@Override
public AuthorizationResponse decide(HttpServletRequest request,
Map<String, String> additionalAttrs) {
- log.trace ("Entering decide()");
-
+ log.trace("Entering decide()");
boolean decision = false;
-
// Extract interesting parts of the HTTP request
String method = request.getMethod();
AuthzResource resource = new AuthzResource(request.getRequestURI());
- String subject = (request.getHeader(SUBJECT_HEADER)); // identity of the requester
- String subjectgroup = (request.getHeader(SUBJECT_HEADER_GROUP)); // identity of the requester by group Rally : US708115
-
- log.trace("Method: " + method + " -- Type: " + resource.getType() + " -- Id: " + resource.getId() +
- " -- Subject: " + subject);
+ String subject = (request.getHeader(SUBJECT_HEADER));
+ String subjectgroup = (request.getHeader(SUBJECT_HEADER_GROUP));
+ log.trace("Method: " + method + " -- Type: " + resource.getType() + " -- Id: " + resource.getId()
+ + " -- Subject: " + subject);
// Choose authorization method based on the resource type
ResourceType resourceType = resource.getType();
if (resourceType != null) {
-
switch (resourceType) {
-
- case FEEDS_COLLECTION:
- decision = allowFeedsCollectionAccess(resource, method, subject, subjectgroup);
- break;
-
- case SUBS_COLLECTION:
- decision = allowSubsCollectionAccess(resource, method, subject, subjectgroup);
- break;
-
- case FEED:
- decision = allowFeedAccess(resource, method, subject, subjectgroup);
- break;
-
- case SUB:
- decision = allowSubAccess(resource, method, subject, subjectgroup);
- break;
-
- default:
- decision = false;
- break;
+ case FEEDS_COLLECTION:
+ decision = allowFeedsCollectionAccess(method);
+ break;
+ case SUBS_COLLECTION:
+ decision = allowSubsCollectionAccess(method);
+ break;
+ case FEED:
+ decision = allowFeedAccess(resource, method, subject, subjectgroup);
+ break;
+ case SUB:
+ decision = allowSubAccess(resource, method, subject, subjectgroup);
+ break;
+ default:
+ decision = false;
+ break;
}
}
- log.debug("Exit decide(): " + method + "|" + resourceType + "|" + resource.getId() + "|" + subject + " ==> " + decision);
+ log.debug("Exit decide(): " + method + "|" + resourceType + "|" + resource.getId() + "|"
+ + subject + " ==> " + decision);
return new AuthRespImpl(decision);
}
- private boolean allowFeedsCollectionAccess(AuthzResource resource, String method, String subject, String subjectgroup) {
-
+ private boolean allowFeedsCollectionAccess(String method) {
// Allow GET or POST unconditionally
return method != null && ("GET".equalsIgnoreCase(method) || "POST".equalsIgnoreCase(method));
}
- private boolean allowSubsCollectionAccess(AuthzResource resource, String method, String subject, String subjectgroup) {
-
+ private boolean allowSubsCollectionAccess(String method) {
// Allow GET or POST unconditionally
return method != null && ("GET".equalsIgnoreCase(method) || "POST".equalsIgnoreCase(method));
}
- private boolean allowFeedAccess(AuthzResource resource, String method, String subject, String subjectgroup) {
+ private boolean allowFeedAccess(AuthzResource resource, String method, String subject, String subjectgroup) {
boolean decision = false;
-
// Allow GET, PUT, or DELETE if requester (subject) is the owner (publisher) of the feed
- if ( method != null && ("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method) ||
- "DELETE".equalsIgnoreCase(method))) {
+ if ( method != null && ("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method) || "DELETE".equalsIgnoreCase(method))) {
String owner = provData.getFeedOwner(resource.getId());
decision = (owner != null) && owner.equals(subject);
-
//Verifying by group Rally : US708115
- if(subjectgroup != null) {
- String feedowner = provData.getGroupByFeedGroupId(subject, resource.getId());
- decision = (feedowner != null) && feedowner.equals(subjectgroup);
+ if (subjectgroup != null) {
+ String feedOwner = provData.getGroupByFeedGroupId(subject, resource.getId());
+ decision = (feedOwner != null) && feedOwner.equals(subjectgroup);
}
}
-
return decision;
}
boolean decision = false;
// Allow GET, PUT, or DELETE if requester (subject) is the owner of the subscription (subscriber)
- if (method != null && ("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method) ||
- "DELETE".equalsIgnoreCase(method) || "POST".equalsIgnoreCase(method))) {
+ if (method != null && ("GET".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method) || "DELETE".equalsIgnoreCase(method) || "POST".equalsIgnoreCase(method))) {
String owner = provData.getSubscriptionOwner(resource.getId());
decision = (owner != null) && owner.equals(subject);
//Verifying by group Rally : US708115
- if(subjectgroup != null) {
+ if (subjectgroup != null) {
String feedowner = provData.getGroupBySubGroupId(subject, resource.getId());
decision = (feedowner != null) && feedowner.equals(subjectgroup);
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.dmaap.datarouter.authz.impl;
+
+import static org.mockito.Mockito.when;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.onap.dmaap.datarouter.authz.AuthorizationResponse;
+import org.onap.dmaap.datarouter.authz.impl.ProvAuthorizer;
+import org.onap.dmaap.datarouter.provisioning.StatisticsServlet;
+import org.onap.dmaap.datarouter.provisioning.utils.DB;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class ProvAuthTest {
+
+ @Mock
+ private HttpServletRequest request;
+
+ @Mock
+ private StatisticsServlet statisticsServlet;
+
+ private ProvAuthorizer provAuthorizer;
+
+ private static EntityManagerFactory emf;
+ private static EntityManager em;
+ private DB db;
+
+ @BeforeClass
+ public static void init() {
+ emf = Persistence.createEntityManagerFactory("dr-unit-tests");
+ em = emf.createEntityManager();
+ System.setProperty(
+ "org.onap.dmaap.datarouter.provserver.properties",
+ "src/test/resources/h2Database.properties");
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ em.clear();
+ em.close();
+ emf.close();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ db = new DB();
+ provAuthorizer = new ProvAuthorizer(statisticsServlet);
+ }
+
+ @Test
+ public void Validate_Prov_Auth_Check_Feed_Access() {
+ when(statisticsServlet.getFeedOwner(Mockito.anyString())).thenReturn("dr-admin");
+ when(statisticsServlet.getGroupByFeedGroupId(Mockito.anyString(), Mockito.anyString())).thenReturn("stub_auth_id");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF")).thenReturn("dr-admin");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_auth_id");
+ when(request.getMethod()).thenReturn("PUT");
+ when(request.getRequestURI()).thenReturn("http://the-request-uri:443/feed/1?1");
+ AuthorizationResponse authResp;
+ authResp = provAuthorizer.decide(request);
+ Assert.assertTrue(authResp.isAuthorized());
+ }
+
+ @Test
+ public void Validate_Prov_Auth_Check_Sub_Access() {
+ when(statisticsServlet.getSubscriptionOwner(Mockito.anyString())).thenReturn("dr-admin");
+ when(statisticsServlet.getGroupBySubGroupId(Mockito.anyString(), Mockito.anyString())).thenReturn("stub_auth_id");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF")).thenReturn("dr-admin");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_auth_id");
+ when(request.getMethod()).thenReturn("PUT");
+ when(request.getRequestURI()).thenReturn("http://the-request-uri:443/subs/1?1");
+ AuthorizationResponse authResp;
+ authResp = provAuthorizer.decide(request);
+ Assert.assertTrue(authResp.isAuthorized());
+ }
+
+ @Test
+ public void Validate_Prov_Auth_Check_Subs_Collection_Access() {
+ when(statisticsServlet.getSubscriptionOwner(Mockito.anyString())).thenReturn("dr-admin");
+ when(statisticsServlet.getGroupBySubGroupId(Mockito.anyString(), Mockito.anyString())).thenReturn("stub_auth_id");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF")).thenReturn("dr-admin");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_auth_id");
+ when(request.getMethod()).thenReturn("POST");
+ when(request.getRequestURI()).thenReturn("http://the-request-uri:443/subscribe/1?1");
+ AuthorizationResponse authResp;
+ authResp = provAuthorizer.decide(request);
+ Assert.assertTrue(authResp.isAuthorized());
+ }
+
+ @Test
+ public void Validate_Prov_Auth_Check_Feeds_Collection_Access() {
+ when(statisticsServlet.getFeedOwner(Mockito.anyString())).thenReturn("dr-admin");
+ when(statisticsServlet.getGroupByFeedGroupId(Mockito.anyString(), Mockito.anyString())).thenReturn("stub_auth_id");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF")).thenReturn("dr-admin");
+ when(request.getHeader("X-DMAAP-DR-ON-BEHALF-OF-GROUP")).thenReturn("stub_auth_id");
+ when(request.getMethod()).thenReturn("POST");
+ when(request.getRequestURI()).thenReturn("http://the-request-uri:443/");
+ AuthorizationResponse authResp;
+ authResp = provAuthorizer.decide(request);
+ Assert.assertTrue(authResp.isAuthorized());
+ Assert.assertNull(authResp.getAdvice());
+ Assert.assertNull(authResp.getObligations());
+ }
+
+}