2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 * ============LICENSE_END=========================================================
16 * Modifications copyright (c) 2019 Nokia
17 * ================================================================================
20 package org.openecomp.sdc.common.utils;
22 import com.google.common.collect.Multimap;
24 import org.apache.commons.collections4.CollectionUtils;
25 import org.apache.commons.io.FilenameUtils;
26 import org.apache.commons.lang3.tuple.ImmutablePair;
27 import org.apache.commons.lang3.tuple.Pair;
28 import org.openecomp.core.utilities.file.FileContentHandler;
29 import org.openecomp.core.utilities.file.FileUtils;
30 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
31 import org.openecomp.sdc.common.errors.CoreException;
32 import org.openecomp.sdc.common.errors.ErrorCategory;
33 import org.openecomp.sdc.common.errors.ErrorCode;
34 import org.openecomp.sdc.common.errors.Messages;
36 import java.io.ByteArrayInputStream;
38 import java.io.IOException;
39 import java.lang.reflect.Field;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.HashSet;
43 import java.util.List;
45 import java.util.Objects;
46 import java.util.Optional;
48 import java.util.zip.ZipEntry;
49 import java.util.zip.ZipException;
50 import java.util.zip.ZipInputStream;
52 public class CommonUtil {
53 static final String DEFAULT = "default";
54 static final String _DEFAULT = "_default";
56 private CommonUtil() {
57 // prevent instantiation
60 public static FileContentHandler validateAndUploadFileContent(OnboardingTypesEnum type,
61 byte[] uploadedFileData)
63 return getFileContentMapFromOrchestrationCandidateZipAndValidateNoFolders(type,
68 * Gets files out of the zip AND validates zip is flat (no folders)
70 * @param uploadFileData zip file
71 * @return FileContentHandler if input is valid and has no folders
73 private static FileContentHandler getFileContentMapFromOrchestrationCandidateZipAndValidateNoFolders(
74 OnboardingTypesEnum type, byte[] uploadFileData)
76 Pair<FileContentHandler, List<String>> pair =
77 getFileContentMapFromOrchestrationCandidateZip(uploadFileData);
79 if (isFileOriginFromZip(type.toString())) {
80 validateNoFolders(pair.getRight());
83 return pair.getLeft();
86 public static Pair<FileContentHandler, List<String>> getFileContentMapFromOrchestrationCandidateZip(
87 byte[] uploadFileData)
90 List<String> folderList = new ArrayList<>();
91 FileContentHandler mapFileContent = new FileContentHandler();
92 try (ByteArrayInputStream in = new ByteArrayInputStream(uploadFileData);
93 ZipInputStream inputZipStream = new ZipInputStream(in)) {
94 byte[] fileByteContent;
95 String currentEntryName;
97 while ((zipEntry = inputZipStream.getNextEntry()) != null) {
98 assertEntryNotVulnerable(zipEntry);
99 currentEntryName = zipEntry.getName();
100 fileByteContent = FileUtils.toByteArray(inputZipStream);
102 int index = lastIndexFileSeparatorIndex(currentEntryName);
104 folderList.add(currentEntryName);
106 if (isFile(currentEntryName)) {
107 mapFileContent.addFile(currentEntryName, fileByteContent);
111 } catch (RuntimeException exception) {
112 throw new IOException(exception);
115 return new ImmutablePair<>(mapFileContent, folderList);
118 private static void assertEntryNotVulnerable(ZipEntry entry) throws ZipException {
119 if (entry.getName().contains("../")) {
120 throw new ZipException("Path traversal attempt discovered.");
124 private static boolean isFile(String currentEntryName) {
125 return !(currentEntryName.endsWith("\\") || currentEntryName.endsWith("/"));
128 private static void validateNoFolders(List<String> folderList) {
129 if (CollectionUtils.isNotEmpty(folderList)) {
130 throw new CoreException((new ErrorCode.ErrorCodeBuilder())
131 .withMessage(Messages.ZIP_SHOULD_NOT_CONTAIN_FOLDERS.getErrorMessage())
132 .withId(Messages.ZIP_SHOULD_NOT_CONTAIN_FOLDERS.getErrorMessage())
133 .withCategory(ErrorCategory.APPLICATION).build());
137 private static int lastIndexFileSeparatorIndex(String filePath) {
138 int length = filePath.length() - 1;
140 for (int i = length; i >= 0; i--) {
141 char currChar = filePath.charAt(i);
142 if (currChar == '/' || currChar == File.separatorChar || currChar == File.pathSeparatorChar) {
146 // if we've reached to the start of the string and didn't find file separator - return -1
150 private static boolean validateFilesExtensions(Set<String> allowedExtensions, FileContentHandler
152 for (String fileName : files.getFileList()) {
153 if (!allowedExtensions.contains(FilenameUtils.getExtension(fileName))) {
160 public static boolean validateAllFilesYml(FileContentHandler files) {
161 Set<String> allowedExtensions = new HashSet<>(Arrays.asList("yml", "yaml"));
162 return validateFilesExtensions(allowedExtensions, files);
165 public static boolean isFileOriginFromZip(String fileOrigin) {
166 return Objects.nonNull(fileOrigin)
167 && fileOrigin.equalsIgnoreCase(OnboardingTypesEnum.ZIP.toString());
170 public static Set<String> getClassFieldNames(Class<? extends Object> classType) {
171 Set<String> fieldNames = new HashSet<>();
172 Arrays.stream(classType.getDeclaredFields()).forEach(field -> fieldNames.add(field.getName()));
177 public static <T> Optional<T> createObjectUsingSetters(Object objectCandidate,
178 Class<T> classToCreate)
180 return org.onap.sdc.tosca.services.CommonUtil.createObjectUsingSetters(objectCandidate, classToCreate);
183 private static boolean isComplexClass(Field field) {
184 return !field.getType().equals(Map.class)
185 && !field.getType().equals(String.class)
186 && !field.getType().equals(Integer.class)
187 && !field.getType().equals(Float.class)
188 && !field.getType().equals(Double.class)
189 && !field.getType().equals(Set.class)
190 && !field.getType().equals(Object.class)
191 && !field.getType().equals(List.class);
194 public static Map<String, Object> getObjectAsMap(Object obj) {
195 return org.onap.sdc.tosca.services.CommonUtil.getObjectAsMap(obj);
198 public static <K, V> boolean isMultimapEmpty(Multimap<K, V> obj) {
199 return Objects.isNull(obj) || obj.isEmpty();