[DMAAP-48] Initial code import
[dmaap/datarouter.git] / datarouter-prov / src / main / java / com / att / research / datarouter / authz / impl / ProvAuthorizer.java
1 /*******************************************************************************\r
2  * ============LICENSE_START==================================================\r
3  * * org.onap.dmaap\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * ===========================================================================\r
7  * * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * * you may not use this file except in compliance with the License.\r
9  * * You may obtain a copy of the License at\r
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \r
13  *  * Unless required by applicable law or agreed to in writing, software\r
14  * * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * * See the License for the specific language governing permissions and\r
17  * * limitations under the License.\r
18  * * ============LICENSE_END====================================================\r
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 \r
24 package com.att.research.datarouter.authz.impl;\r
25 \r
26 import java.util.Map;\r
27 \r
28 import javax.servlet.http.HttpServletRequest;\r
29 \r
30 import org.apache.log4j.Logger;\r
31 \r
32 import com.att.research.datarouter.authz.AuthorizationResponse;\r
33 import com.att.research.datarouter.authz.Authorizer;\r
34 import com.att.research.datarouter.authz.impl.AuthzResource.ResourceType;\r
35 \r
36 /** Authorizer for the provisioning API for Data Router R1\r
37  * \r
38  * @author J. F. Lucas\r
39  *\r
40  */\r
41 public class ProvAuthorizer implements Authorizer {\r
42         \r
43         private Logger log;\r
44         private ProvDataProvider provData;\r
45         \r
46         private static final String SUBJECT_HEADER = "X-ATT-DR-ON-BEHALF-OF";  // HTTP header carrying requester identity\r
47         private static final String SUBJECT_HEADER_GROUP = "X-ATT-DR-ON-BEHALF-OF-GROUP";  // HTTP header carrying requester identity  by group Rally : US708115\r
48         /** Constructor. For the moment, do nothing special.  Make it a singleton? \r
49          * \r
50          */\r
51         public ProvAuthorizer(ProvDataProvider provData) {\r
52                 this.provData = provData;\r
53                 this.log = Logger.getLogger(this.getClass());\r
54         }\r
55         \r
56         /**\r
57          * Determine if the API request carried in the <code>request</code> parameter is permitted.\r
58          * \r
59          * @param request the HTTP request for which an authorization decision is needed\r
60          * @return an object implementing the <code>AuthorizationResponse</code> interface.  This object includes the\r
61          * permit/deny decision for the request and (after R1) supplemental information related to the response in the form\r
62          * of advice and obligations.\r
63          */\r
64         @Override\r
65         public AuthorizationResponse decide(HttpServletRequest request) {\r
66                         return this.decide(request, null);\r
67         }\r
68         \r
69         /**\r
70          * Determine if the API request carried in the <code>request</code> parameter, with additional attributes provided in\r
71          * the <code>additionalAttrs</code> parameter, is permitted.   <code>additionalAttrs</code> isn't used in R1.\r
72          * \r
73          * @param request the HTTP request for which an authorization decision is needed\r
74          * @param additionalAttrs additional attributes that the <code>Authorizer</code> can in making an authorization decision\r
75          * @return an object implementing the <code>AuthorizationResponse</code> interface.  This object includes the\r
76          * permit/deny decision for the request and (after R1) supplemental information related to the response in the form\r
77          * of advice and obligations.\r
78          */\r
79         @Override\r
80         public AuthorizationResponse decide(HttpServletRequest request,\r
81                         Map<String, String> additionalAttrs) {\r
82                 log.trace ("Entering decide()");\r
83                 \r
84                 boolean decision = false;\r
85                 \r
86                 // Extract interesting parts of the HTTP request\r
87                 String method = request.getMethod();\r
88                 AuthzResource resource = new AuthzResource(request.getRequestURI());\r
89                 String subject = (request.getHeader(SUBJECT_HEADER));            // identity of the requester\r
90                 String subjectgroup = (request.getHeader(SUBJECT_HEADER_GROUP)); // identity of the requester by group Rally : US708115\r
91 \r
92                 log.trace("Method: " + method + " -- Type: " + resource.getType() + " -- Id: " + resource.getId() + \r
93                                 " -- Subject: " + subject);\r
94                 \r
95                 // Choose authorization method based on the resource type\r
96                 ResourceType resourceType = resource.getType();\r
97                 if (resourceType != null) {\r
98 \r
99                         switch (resourceType) {\r
100 \r
101                         case FEEDS_COLLECTION:\r
102                                 decision = allowFeedsCollectionAccess(resource, method, subject, subjectgroup);\r
103                                 break;\r
104 \r
105                         case SUBS_COLLECTION:\r
106                                 decision = allowSubsCollectionAccess(resource, method, subject, subjectgroup);\r
107                                 break;\r
108 \r
109                         case FEED:\r
110                                 decision = allowFeedAccess(resource, method, subject, subjectgroup);\r
111                                 break;\r
112 \r
113                         case SUB:\r
114                                 decision = allowSubAccess(resource, method, subject, subjectgroup);\r
115                                 break;\r
116 \r
117                         default:\r
118                                 decision = false;\r
119                                 break;\r
120                         }\r
121                 }\r
122                 log.debug("Exit decide(): "  + method + "|" + resourceType + "|" + resource.getId() + "|" + subject + " ==> " + decision);\r
123                 \r
124                 return new AuthRespImpl(decision);\r
125         }\r
126         \r
127         private boolean allowFeedsCollectionAccess(AuthzResource resource,      String method, String subject, String subjectgroup) {\r
128                 \r
129                 // Allow GET or POST unconditionally\r
130                 return method != null && (method.equalsIgnoreCase("GET") || method.equalsIgnoreCase("POST"));\r
131         }\r
132         \r
133         private boolean allowSubsCollectionAccess(AuthzResource resource, String method, String subject, String subjectgroup) {\r
134                 \r
135                 // Allow GET or POST unconditionally\r
136                 return method != null && (method.equalsIgnoreCase("GET") || method.equalsIgnoreCase("POST"));\r
137         }\r
138         \r
139         private boolean allowFeedAccess(AuthzResource resource, String method,  String subject, String subjectgroup) {\r
140                 boolean decision = false;\r
141                 \r
142                 // Allow GET, PUT, or DELETE if requester (subject) is the owner (publisher) of the feed\r
143                 if ( method != null && (method.equalsIgnoreCase("GET") || method.equalsIgnoreCase("PUT") ||\r
144                                 method.equalsIgnoreCase("DELETE"))) {\r
145                         \r
146                         String owner = provData.getFeedOwner(resource.getId());\r
147                         decision = (owner != null) && owner.equals(subject);\r
148                         \r
149                         //Verifying by group Rally : US708115\r
150                         if(subjectgroup != null) { \r
151                                 String feedowner = provData.getGroupByFeedGroupId(subject, resource.getId());\r
152                                 decision = (feedowner != null) && feedowner.equals(subjectgroup);\r
153                         }\r
154                 }\r
155                 \r
156                 return decision;\r
157         }\r
158         \r
159         private boolean allowSubAccess(AuthzResource resource, String method, String subject, String subjectgroup) {\r
160                 boolean decision = false;\r
161                 \r
162                 // Allow GET, PUT, or DELETE if requester (subject) is the owner of the subscription (subscriber)\r
163                 if (method != null && (method.equalsIgnoreCase("GET") || method.equalsIgnoreCase("PUT") || \r
164                                 method.equalsIgnoreCase("DELETE") || method.equalsIgnoreCase("POST"))) {\r
165                         \r
166                         String owner = provData.getSubscriptionOwner(resource.getId());\r
167                         decision = (owner != null) && owner.equals(subject);\r
168                         \r
169                         //Verifying by group Rally : US708115\r
170                         if(subjectgroup != null) {\r
171                                 String feedowner = provData.getGroupBySubGroupId(subject, resource.getId());\r
172                                 decision = (feedowner != null) && feedowner.equals(subjectgroup);\r
173                         }\r
174                 }\r
175                 \r
176                 return decision;\r
177         }\r
178 \r
179 }\r