Improve handling 'empty'/null string in Service fields
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ConsumerBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.components.impl;
21
22 import fj.data.Either;
23 import java.util.Date;
24 import org.apache.commons.lang3.StringUtils;
25 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
26 import org.openecomp.sdc.be.config.BeEcompErrorManager;
27 import org.openecomp.sdc.be.dao.api.ActionStatus;
28 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
29 import org.openecomp.sdc.be.model.ConsumerDefinition;
30 import org.openecomp.sdc.be.model.User;
31 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
32 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
33 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
34 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
35 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
36 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
37 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
38 import org.openecomp.sdc.be.model.operations.impl.ConsumerOperation;
39 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
40 import org.openecomp.sdc.be.resources.data.ConsumerData;
41 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
42 import org.openecomp.sdc.be.user.Role;
43 import org.openecomp.sdc.common.log.wrappers.Logger;
44 import org.openecomp.sdc.common.util.ValidationUtils;
45 import org.openecomp.sdc.exception.ResponseFormat;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.stereotype.Component;
48
49 @Component("ConsumerBusinessLogic")
50 public class ConsumerBusinessLogic extends BaseBusinessLogic {
51
52     private static final String CONSUMER_NAME = "Consumer name";
53     private static final String CONSUMER_SALT = "Consumer salt";
54     private static final String CONSUMER_PW = "Consumer password";
55     private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
56     private static final Logger log = Logger.getLogger(ConsumerBusinessLogic.class.getName());
57     @javax.annotation.Resource
58     private ConsumerOperation consumerOperation;
59
60     @Autowired
61     public ConsumerBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
62                                  IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
63                                  InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation) {
64         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
65             artifactToscaOperation);
66     }
67
68     public Either<ConsumerDefinition, ResponseFormat> createConsumer(User user, ConsumerDefinition consumer) {
69         Either<User, ResponseFormat> userValidation = validateUser(user, consumer, AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS);
70         if (userValidation.isRight()) {
71             return Either.right(userValidation.right().value());
72         }
73         checkFieldsForOverrideAttempt(consumer);
74         user = userValidation.left().value();
75         consumer.setLastModfierAtuid(user.getUserId());
76         Either<ConsumerDefinition, ResponseFormat> consumerValidationResponse = validateConsumer(consumer);
77         if (consumerValidationResponse.isRight()) {
78             ResponseFormat responseFormat = consumerValidationResponse.right().value();
79             componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user);
80             return Either.right(responseFormat);
81         }
82         String consumerName = consumer.getConsumerName();
83         StorageOperationStatus lockResult = graphLockOperation.lockComponent(consumerName, NodeTypeEnum.ConsumerCredentials);
84         if (!lockResult.equals(StorageOperationStatus.OK)) {
85             BeEcompErrorManager.getInstance().logBeFailedLockObjectError("createConsumer", NodeTypeEnum.ConsumerCredentials.getName(), consumerName);
86             log.debug("Failed to lock consumer: {} error - {}", consumerName, lockResult);
87             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
88             componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user);
89             return Either.right(responseFormat);
90         }
91         try {
92             Either<ConsumerData, StorageOperationStatus> getResponse = consumerOperation.getCredentials(consumerName);
93             if (getResponse.isLeft() && getResponse.left().value() != null) {
94                 return updateConsumer(consumer);
95             }
96             Date date = new Date();
97             consumer.setConsumerDetailsLastupdatedtime(date.getTime());
98             consumer.setConsumerLastAuthenticationTime(Long.valueOf(0));
99             Either<ConsumerData, StorageOperationStatus> createResponse = consumerOperation.createCredentials(new ConsumerData(consumer));
100             if (createResponse.isRight()) {
101                 ResponseFormat responseFormat = componentsUtils
102                     .getResponseFormat(componentsUtils.convertFromStorageResponseForConsumer(createResponse.right().value()));
103                 componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user);
104                 return Either.right(responseFormat);
105             }
106             log.debug("Consumer created successfully!!!");
107             consumer = new ConsumerDefinition(createResponse.left().value().getConsumerDataDefinition());
108             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
109             componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user);
110             return Either.left(consumer);
111         } finally {
112             graphLockOperation.unlockComponent(consumerName, NodeTypeEnum.ConsumerCredentials);
113         }
114     }
115
116     private Either<User, ResponseFormat> validateUser(User user, ConsumerDefinition consumer, AuditingActionEnum auditAction) {
117         if (user.getUserId() == null || user.getUserId().trim().isEmpty()) {
118             log.debug("createEcompUser method - user is missing. userId= {}", user.getUserId());
119             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
120             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
121             componentsUtils.auditConsumerCredentialsEvent(auditAction, consumer, responseFormat, user);
122             return Either.right(responseFormat);
123         }
124         log.debug("get user from DB");
125         User userFromDB;
126         try {
127             userFromDB = userAdmin.getUser(user.getUserId(), false);
128         } catch (ByActionStatusComponentException e) {
129             log.debug("createEcompUser method - user is not listed. userId= {}", user.getUserId());
130             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_ACCESS);
131             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
132             componentsUtils.auditConsumerCredentialsEvent(auditAction, consumer, responseFormat, user);
133             return Either.right(responseFormat);
134         }
135         user = userFromDB;
136         // validate user role
137         log.debug("validate user role");
138         if (!user.getRole().equals(Role.ADMIN.name())) {
139             log.info("role {} is not allowed to perform this action", user.getRole());
140             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
141             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
142             componentsUtils.auditConsumerCredentialsEvent(auditAction, consumer, responseFormat, user);
143             return Either.right(responseFormat);
144         }
145         return Either.left(user);
146     }
147
148     private Either<ConsumerDefinition, ResponseFormat> validateConsumer(ConsumerDefinition consumer) {
149         Either<ConsumerDefinition, ResponseFormat> validateConsumerName = validateConsumerName(consumer);
150         if (validateConsumerName.isRight()) {
151             return Either.right(validateConsumerName.right().value());
152         }
153         Either<ConsumerDefinition, ResponseFormat> validateConsumerPassword = validateConsumerPassword(consumer);
154         if (validateConsumerPassword.isRight()) {
155             return Either.right(validateConsumerPassword.right().value());
156         }
157         consumer = validateConsumerPassword.left().value();
158         Either<ConsumerDefinition, ResponseFormat> validateEcompUserSalt = validateConsumerSalt(consumer);
159         if (validateEcompUserSalt.isRight()) {
160             return Either.right(validateEcompUserSalt.right().value());
161         }
162         return Either.left(consumer);
163     }
164
165     private Either<ConsumerDefinition, ResponseFormat> validateConsumerName(ConsumerDefinition consumer) {
166         String name = consumer.getConsumerName();
167         if (StringUtils.isEmpty(name)) {
168             log.debug("Consumer name cannot be empty.");
169             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, CONSUMER_NAME));
170         }
171         if (!ValidationUtils.validateConsumerName(name)) {
172             log.debug("Consumer name is invalid.");
173             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_NAME));
174         }
175         if (!ValidationUtils.validateLength(name, ValidationUtils.CONSUMER_NAME_MAX_LENGTH)) {
176             log.debug("Consumer name exceeds limit.");
177             return Either.right(componentsUtils
178                 .getResponseFormat(ActionStatus.EXCEEDS_LIMIT, CONSUMER_NAME, String.valueOf(ValidationUtils.CONSUMER_NAME_MAX_LENGTH)));
179         }
180         if (!ValidationUtils.isUTF8Str(name)) {
181             log.debug("Consumer name includes non UTF 8 characters.");
182             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_NAME));
183         }
184         return Either.left(consumer);
185     }
186
187     private Either<ConsumerDefinition, ResponseFormat> validateConsumerPassword(ConsumerDefinition consumer) {
188         String password = consumer.getConsumerPassword();
189         if (StringUtils.isEmpty(password)) {
190             log.debug("Consumer password cannot be empty.");
191             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, CONSUMER_PW));
192         }
193         if (password.length() != ValidationUtils.CONSUMER_PASSWORD_LENGTH) {
194             log.debug("Consumer password length is not valid.");
195             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_LENGTH, CONSUMER_PW));
196         }
197         consumer.setConsumerPassword(password.toLowerCase());
198         if (!ValidationUtils.validateConsumerPassSalt(consumer.getConsumerPassword())) {
199             log.debug("Consumer password is invalid.");
200             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_PW));
201         }
202         return Either.left(consumer);
203     }
204
205     private Either<ConsumerDefinition, ResponseFormat> validateConsumerSalt(ConsumerDefinition consumer) {
206         String salt = consumer.getConsumerSalt();
207         if (StringUtils.isEmpty(salt)) {
208             log.debug("Consumer salt cannot be empty.");
209             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, CONSUMER_SALT));
210         }
211         if (salt.length() != ValidationUtils.CONSUMER_SALT_LENGTH) {
212             log.debug("Consumer salt length is not valid.");
213             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_LENGTH, CONSUMER_SALT));
214         }
215         if (!ValidationUtils.validateConsumerPassSalt(salt)) {
216             log.debug("Consumer salt is invalid.");
217             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_SALT));
218         }
219         return Either.left(consumer);
220     }
221
222     public Either<ConsumerDefinition, ResponseFormat> getConsumer(String consumerId, User user) {
223         ConsumerDefinition tmpConsumer = new ConsumerDefinition();
224         tmpConsumer.setConsumerName(consumerId);
225         // In case of filter (southbound) call
226         if (user != null) {
227             Either<User, ResponseFormat> userValidation = validateUser(user, tmpConsumer, AuditingActionEnum.GET_ECOMP_USER_CREDENTIALS);
228             if (userValidation.isRight()) {
229                 return Either.right(userValidation.right().value());
230             }
231             user = userValidation.left().value();
232         }
233         Either<ConsumerData, StorageOperationStatus> getResult = consumerOperation.getCredentials(consumerId);
234         if (getResult.isRight()) {
235             ActionStatus action = componentsUtils.convertFromStorageResponseForConsumer(getResult.right().value());
236             ResponseFormat responseFormat;
237             if (action == ActionStatus.ECOMP_USER_NOT_FOUND) {
238                 responseFormat = componentsUtils.getResponseFormat(action, consumerId);
239             } else {
240                 responseFormat = componentsUtils.getResponseFormat(action);
241             }
242             componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.GET_ECOMP_USER_CREDENTIALS, tmpConsumer, responseFormat, user);
243             return Either.right(responseFormat);
244         }
245         ConsumerDefinition consumer = new ConsumerDefinition(getResult.left().value().getConsumerDataDefinition());
246         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
247         componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.GET_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user);
248         return Either.left(consumer);
249     }
250
251     public Either<ConsumerDefinition, ResponseFormat> getConsumer(String consumerId) {
252         return getConsumer(consumerId, null);
253     }
254
255     public Either<ConsumerDefinition, ResponseFormat> deleteConsumer(String consumerId, User user) {
256         ConsumerDefinition tmpConsumer = new ConsumerDefinition();
257         tmpConsumer.setConsumerName(consumerId);
258         Either<User, ResponseFormat> userValidation = validateUser(user, tmpConsumer, AuditingActionEnum.DELETE_ECOMP_USER_CREDENTIALS);
259         if (userValidation.isRight()) {
260             return Either.right(userValidation.right().value());
261         }
262         user = userValidation.left().value();
263         Either<ConsumerData, StorageOperationStatus> deleteResult = consumerOperation.deleteCredentials(consumerId);
264         if (deleteResult.isRight()) {
265             ActionStatus action = componentsUtils.convertFromStorageResponseForConsumer(deleteResult.right().value());
266             ResponseFormat responseFormat;
267             if (action == ActionStatus.ECOMP_USER_NOT_FOUND) {
268                 responseFormat = componentsUtils.getResponseFormat(action, consumerId);
269             } else {
270                 responseFormat = componentsUtils.getResponseFormat(action);
271             }
272             componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.DELETE_ECOMP_USER_CREDENTIALS, tmpConsumer, responseFormat, user);
273             return Either.right(responseFormat);
274         }
275         ConsumerDefinition consumer = new ConsumerDefinition(deleteResult.left().value().getConsumerDataDefinition());
276         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
277         componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.DELETE_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user);
278         return Either.left(consumer);
279     }
280
281     public Either<ConsumerDefinition, ResponseFormat> updateConsumer(ConsumerDefinition consumer) {
282         Either<ConsumerData, StorageOperationStatus> updateResult = consumerOperation.updateCredentials(new ConsumerData(consumer));
283         if (updateResult.isRight()) {
284             ResponseFormat responseFormat = componentsUtils
285                 .getResponseFormat(componentsUtils.convertFromStorageResponseForConsumer(updateResult.right().value()));
286             return Either.right(responseFormat);
287         }
288         consumer = new ConsumerDefinition(updateResult.left().value().getConsumerDataDefinition());
289         return Either.left(consumer);
290     }
291
292     private void checkFieldsForOverrideAttempt(ConsumerDefinition consumer) {
293         if (consumer.getConsumerDetailsLastupdatedtime() != null) {
294             log.info("Consumer Details Last updated time cannot be defined by user. This field will be overridden by the application");
295         }
296         if (consumer.getConsumerLastAuthenticationTime() != null) {
297             log.info("Consumer Last Authentication time cannot be defined by user. This field will be overridden by the application");
298         }
299         if (consumer.getLastModfierAtuid() != null) {
300             log.info("Consumer Last Modifier USER_ID cannot be defined by user. This field will be overridden by the application");
301         }
302     }
303 }