Fix audit, metric and error logs as per logging specification
[clamp.git] / src / main / java / org / onap / clamp / authorization / AuthorizationController.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Modifications Copyright (c) 2019 Samsung
9  * ================================================================================
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ============LICENSE_END============================================
22  * ===================================================================
23  *
24  */
25
26 package org.onap.clamp.authorization;
27
28 import com.att.eelf.configuration.EELFLogger;
29 import com.att.eelf.configuration.EELFManager;
30 import java.util.Date;
31 import org.apache.camel.Exchange;
32 import org.onap.clamp.clds.config.ClampProperties;
33 import org.onap.clamp.clds.exception.NotAuthorizedException;
34 import org.onap.clamp.clds.model.ClampInformation;
35 import org.onap.clamp.clds.util.LoggingUtils;
36 import org.springframework.beans.factory.annotation.Autowired;
37 import org.springframework.security.core.Authentication;
38 import org.springframework.security.core.GrantedAuthority;
39 import org.springframework.security.core.context.SecurityContext;
40 import org.springframework.security.core.context.SecurityContextHolder;
41 import org.springframework.security.core.userdetails.UserDetails;
42 import org.springframework.stereotype.Component;
43
44 /**
45  * Verify user has right permissions.
46  */
47 @Component
48 public class AuthorizationController {
49
50     protected static final EELFLogger logger =
51         EELFManager.getInstance().getLogger(AuthorizationController.class);
52     protected static final EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
53     protected static final EELFLogger securityLogger =
54         EELFManager.getInstance().getSecurityLogger();
55
56     // By default we'll set it to a default handler
57     @Autowired
58     private ClampProperties refProp;
59
60     private SecurityContext securityContext = SecurityContextHolder.getContext();
61
62     public static final String PERM_PREFIX = "security.permission.type.";
63     private static final String PERM_INSTANCE = "security.permission.instance";
64
65     private static String retrieveUserName(SecurityContext securityContext) {
66         if (securityContext == null || securityContext.getAuthentication() == null) {
67             return null;
68         }
69         if ((securityContext.getAuthentication().getPrincipal()) instanceof String) {
70             // anonymous case
71             return ((String) securityContext.getAuthentication().getPrincipal());
72         } else {
73             return ((UserDetails) securityContext.getAuthentication().getPrincipal()).getUsername();
74         }
75     }
76
77     /**
78      * Get the principal name.
79      *
80      * @return The principal name
81      */
82     public static String getPrincipalName(SecurityContext securityContext) {
83         String principal = AuthorizationController.retrieveUserName(securityContext);
84         String name = "Not found";
85         if (principal != null) {
86             name = principal;
87         }
88         return name;
89     }
90
91     /**
92      * Insert authorize the api based on the permission.
93      *
94      * @param camelExchange The Camel Exchange object containing the properties
95      * @param typeVar The type of the permissions
96      * @param instanceVar The instance of the permissions. e.g. dev
97      * @param action The action of the permissions. e.g. read
98      */
99     public void authorize(Exchange camelExchange, String typeVar, String instanceVar,
100         String action) {
101         String type = refProp.getStringValue(PERM_PREFIX + typeVar);
102         String instance = refProp.getStringValue(PERM_INSTANCE);
103
104         if (null == type || type.isEmpty()) {
105             // authorization is turned off, since the permission is not defined
106             return;
107         }
108         if (null != instanceVar && !instanceVar.isEmpty()) {
109             instance = instanceVar;
110         }
111         String principalName = AuthorizationController.getPrincipalName(this.securityContext);
112         SecureServicePermission perm = SecureServicePermission.create(type, instance, action);
113         Date startTime = new Date();
114         LoggingUtils.setTargetContext("Clamp", "authorize");
115         LoggingUtils.setTimeContext(startTime, new Date());
116         securityLogger.debug("checking if {} has permission: {}", principalName, perm);
117
118         if (!isUserPermitted(perm)) {
119             String msg = principalName + " does not have permission: " + perm;
120             LoggingUtils.setErrorContext("100", "Authorization Error");
121             securityLogger.warn(msg);
122             throw new NotAuthorizedException(msg);
123         }
124     }
125
126     /**
127      * Insert authorize the api based on the permission.
128      *
129      * @param inPermission Security permission in input
130      * @return True if user is permitted
131      */
132     public boolean isUserPermitted(SecureServicePermission inPermission) {
133
134         String principalName = AuthorizationController.getPrincipalName(this.securityContext);
135         // check if the user has the permission key or the permission key with a
136         // combination of all instance and/or all action.
137         if (hasRole(inPermission.getKey()) || hasRole(inPermission.getKeyAllInstance())) {
138             auditLogger.info("{} authorized because user has permission with * for instance: {}",
139                 principalName, inPermission.getKey().replace("|", ":"));
140             return true;
141             // the rest of these don't seem to be required - isUserInRole method
142             // appears to take * as a wildcard
143         } else if (hasRole(inPermission.getKeyAllInstanceAction())) {
144             auditLogger.info(
145                 "{} authorized because user has permission with * for instance and * for action: {}",
146                 principalName, inPermission.getKey().replace("|", ":"));
147             return true;
148         } else if (hasRole(inPermission.getKeyAllAction())) {
149             auditLogger.info("{} authorized because user has permission with * for action: {}",
150                 principalName, inPermission.getKey().replace("|", ":"));
151             return true;
152         } else {
153             return false;
154         }
155     }
156
157     protected boolean hasRole(String role) {
158         Authentication authentication = securityContext.getAuthentication();
159         if (authentication == null) {
160             return false;
161         }
162         for (GrantedAuthority auth : authentication.getAuthorities()) {
163             if (role.equals(auth.getAuthority())) {
164                 return true;
165             }
166         }
167         return false;
168     }
169
170     /**
171      * Gets clds info. CLDS IFO service will return 3 things 1. User Name 2. CLDS
172      * code version that is currently installed from pom.xml file 3. User
173      * permissions
174      *
175      * @return the clds info
176      */
177     public ClampInformation getClampInformation() {
178         ClampInformation clampInfo = new ClampInformation();
179         Authentication authentication = securityContext.getAuthentication();
180         if (authentication == null) {
181             return new ClampInformation();
182         }
183         clampInfo.setUserName(AuthorizationController.getPrincipalName(this.securityContext));
184         for (GrantedAuthority auth : authentication.getAuthorities()) {
185             clampInfo.getAllPermissions().add(auth.getAuthority());
186         }
187         return clampInfo;
188     }
189 }