Modify the Ui
[clamp.git] / src / main / java / org / onap / clamp / clds / service / SecureServiceBase.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END============================================
20  * ===================================================================
21  *
22  */
23
24 package org.onap.clamp.clds.service;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28
29 import java.util.Date;
30 import javax.ws.rs.NotAuthorizedException;
31
32 import org.onap.clamp.clds.util.LoggingUtils;
33 import org.onap.clamp.clds.util.OnapLogConstants;
34 import org.slf4j.event.Level;
35 import org.springframework.security.core.Authentication;
36 import org.springframework.security.core.GrantedAuthority;
37 import org.springframework.security.core.context.SecurityContext;
38 import org.springframework.security.core.context.SecurityContextHolder;
39 import org.springframework.security.core.userdetails.UserDetails;
40
41 /**
42  * Base/abstract Service class. Implements shared security methods.
43  */
44 public abstract class SecureServiceBase {
45     protected static final EELFLogger logger          = EELFManager.getInstance().getLogger(SecureServiceBase.class);
46     protected static final EELFLogger auditLogger     = EELFManager.getInstance().getAuditLogger();
47     protected static final EELFLogger securityLogger  = EELFManager.getInstance().getSecurityLogger();
48
49     // By default we'll set it to a default handler
50     private static UserNameHandler    userNameHandler = new DefaultUserNameHandler();
51
52
53     private SecurityContext           securityContext = SecurityContextHolder.getContext();
54
55     /**
56      * Get the userId from AAF/CSP.
57      *
58      * @return user ID
59      */
60     public String getUserId() {
61         return getUserName();
62     }
63
64     /**
65      * Get the Full name.
66      *
67      * @return user name
68      */
69     public String getUserName() {
70         String name = userNameHandler.retrieveUserName(securityContext);
71         Date startTime = new Date();
72         LoggingUtils.setTargetContext("CLDS", "getUserName");
73         LoggingUtils.setTimeContext(startTime, new Date());
74         securityLogger.debug("User logged into the CLDS system={}", name);
75         return name;
76     }
77
78     /**
79      * Get the principal name.
80      *
81      * @return the principal name
82      */
83     public String getPrincipalName() {
84         String principal = ((UserDetails)securityContext.getAuthentication().getPrincipal()).getUsername();
85         String name = "Not found";
86         if (principal != null) {
87             name = principal;
88         }
89         logger.debug("userPrincipal.getName()={}", name);
90         return name;
91     }
92
93     /**
94      * Check if user is authorized for the given the permission. Allow matches
95      * if user has a permission with an "*" in permission instance or permission
96      * action even if the permission to check has a specific value in those
97      * fields. For example: if the user has this permission: app-perm-type|*|*
98      * it will be authorized if the inPermission to check is:
99      * app-perm-type|dev|read
100      *
101      * @param inPermission
102      *            The permission to validate
103      * @return A boolean to indicate if the user has the permission to do
104      *         execute the inPermission
105      * @throws NotAuthorizedException
106      *             In case of issues with the permission test, error is returned
107      *             in this exception
108      */
109     public boolean isAuthorized(SecureServicePermission inPermission) throws NotAuthorizedException {
110         Date startTime = new Date();
111         LoggingUtils.setTargetContext("CLDS", "isAuthorized");
112         LoggingUtils.setTimeContext(startTime, new Date());
113         securityLogger.debug("checking if {} has permission: {}", getPrincipalName(), inPermission);
114         try {
115             return isUserPermitted(inPermission);
116         } catch (NotAuthorizedException nae) {
117             String msg = getPrincipalName() + " does not have permission: " + inPermission;
118             LoggingUtils.setErrorContext("100", "Authorization Error");
119             securityLogger.warn(msg);
120             throw new NotAuthorizedException(msg);
121         }
122     }
123
124     /**
125      * Check if user is authorized for the given aaf permission. Allow matches
126      * if user has a permission with an "*" in permission instance or permission
127      * action even if the permission to check has a specific value in those
128      * fields. For example: if the user has this permission: app-perm-type|*|*
129      * it will be authorized if the inPermission to check is:
130      * app-perm-type|dev|read
131      *
132      * @param inPermission
133      *            The permission to validate
134      * @return A boolean to indicate if the user has the permission to do
135      *         execute the inPermission
136      */
137     public boolean isAuthorizedNoException(SecureServicePermission inPermission) {
138         securityLogger.debug("checking if {} has permission: {}", getPrincipalName(), inPermission);
139         Date startTime = new Date();
140         LoggingUtils.setTargetContext("CLDS", "isAuthorizedNoException");
141         LoggingUtils.setTimeContext(startTime, new Date());
142         try {
143             return isUserPermitted(inPermission);
144         } catch (NotAuthorizedException nae) {
145             String msg = getPrincipalName() + " does not have permission: " + inPermission;
146             LoggingUtils.setErrorContext("100", "Authorization Error");
147             securityLogger.warn(msg);
148         }
149         return false;
150     }
151
152     /**
153      * This method can be used by the Application.class to set the
154      * UserNameHandler that must be used in this class. The UserNameHandler
155      * where to get the User name
156      *
157      * @param handler
158      *            The Handler impl to use
159      */
160     public static final void setUserNameHandler(UserNameHandler handler) {
161         if (handler != null) {
162             userNameHandler = handler;
163         }
164     }
165
166     public void setSecurityContext(SecurityContext securityContext) {
167         this.securityContext = securityContext;
168     }
169
170     private boolean isUserPermitted(SecureServicePermission inPermission) {
171         boolean authorized = false;
172         // check if the user has the permission key or the permission key with a
173         // combination of  all instance and/or all action.
174         if (hasRole(inPermission.getKey())) {
175             securityLogger.info("{} authorized for permission: {}", getPrincipalName(), inPermission.getKey());
176             authorized = true;
177             // the rest of these don't seem to be required - isUserInRole method
178             // appears to take * as a wildcard
179         } else if (hasRole(inPermission.getKeyAllInstance())) {
180             securityLogger.info("{} authorized because user has permission with * for instance: {}",
181                                 getPrincipalName(), inPermission.getKey());
182             authorized = true;
183         } else if (hasRole(inPermission.getKeyAllInstanceAction())) {
184             securityLogger.info("{} authorized because user has permission with * for instance and * for action: {}",
185                                 getPrincipalName(), inPermission.getKey());
186             authorized = true;
187         } else if (hasRole(inPermission.getKeyAllAction())) {
188             securityLogger.info("{} authorized because user has permission with * for action: {}",
189                                 getPrincipalName(), inPermission.getKey());
190             authorized = true;
191         } else {
192             throw new NotAuthorizedException("");
193         }
194         return authorized;
195     }
196
197     protected boolean hasRole(String role) {
198         Authentication authentication = securityContext.getAuthentication();
199         if (authentication == null) {
200             return false;
201         }
202
203         for (GrantedAuthority auth : authentication.getAuthorities()) {
204             if (role.equals(auth.getAuthority())) {
205                 return true;
206             }
207         }
208
209         return false;
210     }
211
212     protected void auditLogInfo(LoggingUtils util, String actionDescription, Date startTime) {
213         LoggingUtils.setTimeContext(startTime, new Date());
214         auditLogger.info(actionDescription + " completed");
215         util.exiting("200", actionDescription + " success", Level.INFO,
216             OnapLogConstants.ResponseStatus.COMPLETED);
217     }
218
219     protected void auditLogInfo(String actionDescription, Date startTime) {
220
221         LoggingUtils.setTimeContext(startTime, new Date());
222         LoggingUtils.setResponseContext("0", actionDescription + " success",
223             this.getClass().getName());
224         auditLogger.info(actionDescription + " completed");
225     }
226 }