001/** 002 * Copyright (C) 2006-2023 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.server.front.security; 017 018import static java.util.stream.Collectors.toList; 019import static java.util.stream.Collectors.toMap; 020 021import java.util.Collection; 022import java.util.List; 023import java.util.Map; 024import java.util.Map.Entry; 025import java.util.stream.Stream; 026 027import javax.enterprise.context.Dependent; 028import javax.inject.Inject; 029 030import org.talend.sdk.component.runtime.manager.ParameterMeta; 031import org.talend.sdk.components.vault.client.VaultClient; 032 033@Dependent 034public class SecurityUtils { 035 036 public static final String CREDENTIAL = "tcomp::ui::credential"; 037 038 @Inject 039 private VaultClient vault; 040 041 public Map<String, String> decrypt(final Collection<ParameterMeta> spec, final Map<String, String> config, 042 final String tenant) { 043 if (!hasCipheredKeys(config)) { 044 return config; 045 } 046 047 final List<String> toDecipher = spec.stream() 048 .flatMap(s -> flatten(s) 049 .filter(p -> Boolean.parseBoolean(p.getMetadata().getOrDefault(CREDENTIAL, "false")))) 050 .map(m -> m.getPath()) 051 .collect(toList()); 052 053 return Stream.concat(vault.decrypt(config.entrySet() 054 .stream() 055 .filter(e -> toDecipher.contains(e.getKey())) 056 .collect(toMap(Entry::getKey, Entry::getValue)), tenant) 057 .entrySet() 058 .stream(), config.entrySet().stream().filter(e -> !toDecipher.contains(e.getKey()))) 059 .collect(toMap(Entry::getKey, Entry::getValue)); 060 } 061 062 public boolean hasCipheredKeys(final Map<String, String> configuration) { 063 return configuration.values().stream().anyMatch(v -> v.startsWith("vault:")); 064 } 065 066 public List<String> findCipheredKeys(final ParameterMeta meta, final Map<String, String> original) { 067 return flatten(meta) 068 .filter(p -> Boolean.parseBoolean(p.getMetadata().getOrDefault(CREDENTIAL, "false"))) 069 .map(m -> m.getPath()) 070 .collect(toList()); 071 } 072 073 private Stream<ParameterMeta> flatten(final ParameterMeta meta) { 074 if (meta.getNestedParameters() == null || meta.getNestedParameters().isEmpty()) { 075 return Stream.of(meta); 076 } 077 return Stream.concat(meta.getNestedParameters().stream().flatMap(this::flatten), Stream.of(meta)); 078 } 079 080}