Unverified Commit 81e886d9 authored by Roy Wu(伍健君)'s avatar Roy Wu(伍健君) Committed by GitHub
Browse files

Merge branch 'dev' into demo_in_single_host

parents eb5c0f50 427a4707
Showing with 2030 additions and 1675 deletions
+2030 -1675
......@@ -4,15 +4,38 @@ import com.webank.wecube.platform.auth.client.encryption.StringUtilsEx;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
/**
*
* @author gavinli
*
*/
public class DefaultJwtSsoTokenParser implements JwtSsoTokenParser {
private static final String SIGNING_KEY = "Platform+Auth+Server+Secret";
private String jwtSigningKey;
private JwtParser jwtParser;
public DefaultJwtSsoTokenParser(String jwtSigningKey) {
if (jwtSigningKey == null) {
this.jwtSigningKey = SIGNING_KEY;
} else {
this.jwtSigningKey = jwtSigningKey;
}
this.jwtParser = Jwts.parser().setSigningKey(StringUtilsEx.decodeBase64(getJwtSigningKey()));
}
@Override
public Jws<Claims> parseJwt(String token) {
return Jwts.parser().setSigningKey(StringUtilsEx.decodeBase64(SIGNING_KEY)).parseClaimsJws(token);
return jwtParser.parseClaimsJws(token);
}
private String getJwtSigningKey() {
return jwtSigningKey;
}
}
package com.webank.wecube.platform.auth.client.filter;
public class JwtClientConfig {
private String signingKey;
public String getSigningKey() {
return signingKey;
}
public void setSigningKey(String signingKey) {
this.signingKey = signingKey;
}
}
......@@ -33,18 +33,20 @@ import io.jsonwebtoken.JwtException;
public class JwtSsoBasedAuthenticationFilter extends BasicAuthenticationFilter {
private static final Logger log = LoggerFactory.getLogger(JwtSsoBasedAuthenticationFilter.class);
private JwtSsoTokenParser jwtParser = new DefaultJwtSsoTokenParser();
private JwtSsoTokenParser jwtParser = null;
private boolean ignoreFailure = false;
public JwtSsoBasedAuthenticationFilter(AuthenticationManager authenticationManager) {
public JwtSsoBasedAuthenticationFilter(AuthenticationManager authenticationManager, JwtClientConfig jwtClientConfig) {
super(authenticationManager);
this.ignoreFailure = true;
this.jwtParser = new DefaultJwtSsoTokenParser(jwtClientConfig.getSigningKey());
}
public JwtSsoBasedAuthenticationFilter(AuthenticationManager authenticationManager,
AuthenticationEntryPoint authenticationEntryPoint) {
AuthenticationEntryPoint authenticationEntryPoint, JwtClientConfig jwtClientConfig) {
super(authenticationManager, authenticationEntryPoint);
this.jwtParser = new DefaultJwtSsoTokenParser(jwtClientConfig.getSigningKey());
}
@Override
......
......@@ -6,6 +6,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
public class ApplicationProperties {
private String gatewayUrl = "127.0.0.1:19110";
private String dbInitStrategy = "update";
private String jwtSigningKey = "Platform+Auth+Server+Secret";
@ConfigurationProperties(prefix = "wecube.core.config")
public class AppConfigProperties {
......@@ -330,4 +331,13 @@ public class ApplicationProperties {
this.gatewayUrl = gatewayUrl;
}
public String getJwtSigningKey() {
return jwtSigningKey;
}
public void setJwtSigningKey(String jwtSigningKey) {
this.jwtSigningKey = jwtSigningKey;
}
}
......@@ -16,7 +16,9 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.webank.wecube.platform.auth.client.filter.Http401AuthenticationEntryPoint;
import com.webank.wecube.platform.auth.client.filter.JwtClientConfig;
import com.webank.wecube.platform.auth.client.filter.JwtSsoBasedAuthenticationFilter;
import com.webank.wecube.platform.core.commons.ApplicationProperties;
import com.webank.wecube.platform.core.interceptor.AuthenticationRequestContextInterceptor;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
......@@ -33,6 +35,9 @@ public class LocalSpringWebConfig extends WebSecurityConfigurerAdapter implement
@Autowired
private AuthenticationRequestContextInterceptor authenticationRequestContextInterceptor;
@Autowired
private ApplicationProperties applicationProperties;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
......@@ -69,7 +74,10 @@ public class LocalSpringWebConfig extends WebSecurityConfigurerAdapter implement
}
protected Filter jwtSsoBasedAuthenticationFilter() throws Exception {
JwtSsoBasedAuthenticationFilter f = new JwtSsoBasedAuthenticationFilter(authenticationManager());
JwtClientConfig jwtClientConfig = new JwtClientConfig();
jwtClientConfig.setSigningKey(applicationProperties.getJwtSigningKey());
JwtSsoBasedAuthenticationFilter f = new JwtSsoBasedAuthenticationFilter(authenticationManager(),
jwtClientConfig);
return (Filter) f;
}
......
......@@ -2,7 +2,6 @@ package com.webank.wecube.platform.core.config;
import javax.servlet.Filter;
import com.webank.wecube.platform.core.support.cache.CacheHandlerInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
......@@ -18,8 +17,11 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.webank.wecube.platform.auth.client.filter.Http401AuthenticationEntryPoint;
import com.webank.wecube.platform.auth.client.filter.JwtClientConfig;
import com.webank.wecube.platform.auth.client.filter.JwtSsoBasedAuthenticationFilter;
import com.webank.wecube.platform.core.commons.ApplicationProperties;
import com.webank.wecube.platform.core.interceptor.AuthenticationRequestContextInterceptor;
import com.webank.wecube.platform.core.support.cache.CacheHandlerInterceptor;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
......@@ -39,6 +41,9 @@ public class SpringWebConfig extends WebSecurityConfigurerAdapter implements Web
@Autowired
private CacheHandlerInterceptor cacheHandlerInterceptor;
@Autowired
private ApplicationProperties applicationProperties;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
......@@ -86,7 +91,10 @@ public class SpringWebConfig extends WebSecurityConfigurerAdapter implements Web
}
protected Filter jwtSsoBasedAuthenticationFilter() throws Exception {
JwtSsoBasedAuthenticationFilter f = new JwtSsoBasedAuthenticationFilter(authenticationManager());
JwtClientConfig jwtClientConfig = new JwtClientConfig();
jwtClientConfig.setSigningKey(applicationProperties.getJwtSigningKey());
JwtSsoBasedAuthenticationFilter f = new JwtSsoBasedAuthenticationFilter(authenticationManager(),
jwtClientConfig);
return (Filter) f;
}
......
......@@ -85,13 +85,14 @@ public class PluginConfigMigrationService {
.findByPluginPackage_idOrderByName(pluginPackageId);
if (!pluginConfigsOpt.isPresent()) {
throw new WecubeCoreException("3228","Such package ID has no plugin configs.");
}
log.info("Such package ID has no plugin configs.PluginPackageId={}", pluginPackageId);
}else {
List<PluginConfig> pluginConfigs = pluginConfigsOpt.get();
List<PluginConfig> pluginConfigs = pluginConfigsOpt.get();
PluginConfigsType xmlPluginConfigs = buildXmlPluginConfigs(pluginPackage, pluginConfigs);
xmlPluginPackage.setPlugins(xmlPluginConfigs);
PluginConfigsType xmlPluginConfigs = buildXmlPluginConfigs(pluginPackage, pluginConfigs);
xmlPluginPackage.setPlugins(xmlPluginConfigs);
}
SystemParametersType xmlSystemVariables = buildSystemParametersType(pluginPackage);
xmlPluginPackage.setSystemParameters(xmlSystemVariables);
......@@ -138,6 +139,17 @@ public class PluginConfigMigrationService {
if (xmlPluginPackage == null) {
throw new WecubeCoreException("3232","Bad xml contents.");
}
String xmlPackageName = xmlPluginPackage.getName();
String packageName = pluginPackage.getName();
if(!packageName.equals(xmlPackageName)) {
throw new WecubeCoreException("3312",
String.format("Plugin packages do not match.The name from XML is %s but the package you chose is %s.",
xmlPackageName,
packageName),
xmlPackageName,
packageName);
}
performImportPluginRegistersForOnePackage(pluginPackage, xmlPluginPackage);
performImportSystemParametersForOnePackage(pluginPackage, xmlPluginPackage);
......
......@@ -8,6 +8,7 @@ import static com.webank.wecube.platform.core.domain.plugin.PluginPackage.Status
import static com.webank.wecube.platform.core.dto.PluginConfigInterfaceParameterDto.MappingType.entity;
import static com.webank.wecube.platform.core.dto.PluginConfigInterfaceParameterDto.MappingType.system_variable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
......@@ -416,7 +417,8 @@ public class PluginConfigService {
"PluginPackageEntity not found for packageName:dataModelVersion:entityName [%s:%s:%s] for plugin config: %s",
targetPackage, dataModelVersion, targetEntity, pluginConfigName);
log.error(errorMessage);
throw new WecubeCoreException("3050", errorMessage, targetPackage, dataModelVersion, targetEntity, pluginConfigName);
throw new WecubeCoreException("3050", errorMessage, targetPackage, dataModelVersion, targetEntity,
pluginConfigName);
}
}
}
......@@ -458,13 +460,17 @@ public class PluginConfigService {
if ("Y".equalsIgnoreCase(inputParameter.getRequired())) {
if (system_variable.name().equals(inputParameter.getMappingType())
&& inputParameter.getMappingSystemVariableName() == null) {
throw new WecubeCoreException("3054", String.format(
"System variable is required for parameter [%s]", inputParameter.getId()), inputParameter.getId());
throw new WecubeCoreException("3054",
String.format("System variable is required for parameter [%s]",
inputParameter.getId()),
inputParameter.getId());
}
if (entity.name().equals(inputParameter.getMappingType())
&& StringUtils.isBlank(inputParameter.getMappingEntityExpression())) {
throw new WecubeCoreException("3055", String.format(
"Entity expression is required for parameter [%s]", inputParameter.getId()), inputParameter.getId());
throw new WecubeCoreException("3055",
String.format("Entity expression is required for parameter [%s]",
inputParameter.getId()),
inputParameter.getId());
}
}
});
......@@ -475,8 +481,10 @@ public class PluginConfigService {
if ("Y".equalsIgnoreCase(outputParameter.getRequired())) {
if (entity.name().equals(outputParameter.getMappingType())
&& StringUtils.isBlank(outputParameter.getMappingEntityExpression())) {
throw new WecubeCoreException("3056", String.format(
"Entity expression is required for parameter [%s]", outputParameter.getId()), outputParameter.getId());
throw new WecubeCoreException("3056",
String.format("Entity expression is required for parameter [%s]",
outputParameter.getId()),
outputParameter.getId());
}
}
});
......@@ -518,7 +526,7 @@ public class PluginConfigService {
.add(PluginConfigInterfaceDto.fromDomain(pluginConfigInterface)));
}
return filterWithPermissionValidation(pluginConfigInterfaceDtos, PluginAuthEntity.PERM_TYPE_USE);
return filterDtoWithPermissionValidation(pluginConfigInterfaceDtos, PluginAuthEntity.PERM_TYPE_USE);
}
public List<PluginConfigInterfaceDto> queryAllEnabledPluginConfigInterfaceForEntityByFilterRule(
......@@ -551,7 +559,12 @@ public class PluginConfigService {
.findPluginConfigInterfaceByPluginConfig_TargetPackageAndPluginConfig_TargetEntityAndPluginConfig_Status(
packageName, entityName, ENABLED);
if (allEnabledInterfacesOptional.isPresent()) {
pluginConfigInterfaceDtos.addAll(allEnabledInterfacesOptional.get().stream()
List<PluginConfigInterface> rawPluginIntfs = allEnabledInterfacesOptional.get();
List<PluginConfigInterface> filteredPluginConfigIntfs = filterWithPermissionValidation(rawPluginIntfs, PluginAuthEntity.PERM_TYPE_USE);
List<PluginConfigInterface> filteredLatestConfigIntfs = filterLatestPluginConfigInterfaces(filteredPluginConfigIntfs);
pluginConfigInterfaceDtos.addAll(filteredLatestConfigIntfs.stream()
.map(pluginConfigInterface -> PluginConfigInterfaceDto.fromDomain(pluginConfigInterface))
.collect(Collectors.toList()));
}
......@@ -562,7 +575,11 @@ public class PluginConfigService {
.findPluginConfigInterfaceByPluginConfig_TargetPackageAndPluginConfig_TargetEntityAndPluginConfig_StatusAndPluginConfig_TargetEntityFilterRuleIsNull(
packageName, entityName, ENABLED);
if (filterRuleIsNullEnabledInterfacesOptional.isPresent()) {
pluginConfigInterfaceDtos.addAll(filterRuleIsNullEnabledInterfacesOptional.get().stream()
List<PluginConfigInterface> rawPluginIntfs = filterRuleIsNullEnabledInterfacesOptional.get();
List<PluginConfigInterface> filteredPluginConfigIntfs = filterWithPermissionValidation(rawPluginIntfs, PluginAuthEntity.PERM_TYPE_USE);
List<PluginConfigInterface> filteredLatestConfigIntfs = filterLatestPluginConfigInterfaces(filteredPluginConfigIntfs);
pluginConfigInterfaceDtos.addAll(filteredLatestConfigIntfs.stream()
.map(pluginConfigInterface -> PluginConfigInterfaceDto.fromDomain(pluginConfigInterface))
.collect(Collectors.toList()));
}
......@@ -570,7 +587,11 @@ public class PluginConfigService {
.findPluginConfigInterfaceByPluginConfig_TargetPackageAndPluginConfig_TargetEntityAndPluginConfig_TargetEntityFilterRuleAndPluginConfig_Status(
packageName, entityName, "", ENABLED);
if (filterRuleIsEmptyEnabledInterfacesOptional.isPresent()) {
pluginConfigInterfaceDtos.addAll(filterRuleIsEmptyEnabledInterfacesOptional.get().stream()
List<PluginConfigInterface> rawPluginIntfs = filterRuleIsNullEnabledInterfacesOptional.get();
List<PluginConfigInterface> filteredPluginConfigIntfs = filterWithPermissionValidation(rawPluginIntfs, PluginAuthEntity.PERM_TYPE_USE);
List<PluginConfigInterface> filteredLatestConfigIntfs = filterLatestPluginConfigInterfaces(filteredPluginConfigIntfs);
pluginConfigInterfaceDtos.addAll(filteredLatestConfigIntfs.stream()
.map(pluginConfigInterface -> PluginConfigInterfaceDto.fromDomain(pluginConfigInterface))
.collect(Collectors.toList()));
}
......@@ -579,25 +600,97 @@ public class PluginConfigService {
.findPluginConfigInterfaceByPluginConfig_TargetPackageAndPluginConfig_TargetEntityAndPluginConfig_TargetEntityFilterRuleAndPluginConfig_Status(
packageName, entityName, filterRuleDto.getTargetEntityFilterRule(), ENABLED);
if (allEnabledInterfacesOptional.isPresent()) {
pluginConfigInterfaceDtos.addAll(allEnabledInterfacesOptional.get().stream()
List<PluginConfigInterface> rawPluginIntfs = allEnabledInterfacesOptional.get();
List<PluginConfigInterface> filteredPluginConfigIntfs = filterWithPermissionValidation(rawPluginIntfs, PluginAuthEntity.PERM_TYPE_USE);
List<PluginConfigInterface> filteredLatestConfigIntfs = filterLatestPluginConfigInterfaces(filteredPluginConfigIntfs);
pluginConfigInterfaceDtos.addAll(filteredLatestConfigIntfs.stream()
.map(pluginConfigInterface -> PluginConfigInterfaceDto.fromDomain(pluginConfigInterface))
.collect(Collectors.toList()));
}
}
}
Optional<List<PluginConfigInterface>> allEnabledWithEntityNameNullOptional = pluginConfigInterfaceRepository
Optional<List<PluginConfigInterface>> allEnabledWithEntityNameNullOpt = pluginConfigInterfaceRepository
.findAllEnabledWithEntityNameNull();
if (allEnabledWithEntityNameNullOptional.isPresent()) {
pluginConfigInterfaceDtos.addAll(allEnabledWithEntityNameNullOptional.get().stream()
if (allEnabledWithEntityNameNullOpt.isPresent()) {
List<PluginConfigInterface> rawPluginConfigIntfs = allEnabledWithEntityNameNullOpt.get();
List<PluginConfigInterface> filteredPluginConfigIntfs = filterWithPermissionValidation(rawPluginConfigIntfs, PluginAuthEntity.PERM_TYPE_USE);
List<PluginConfigInterface> filteredLatestConfigIntfs = filterLatestPluginConfigInterfaces(filteredPluginConfigIntfs);
pluginConfigInterfaceDtos.addAll(filteredLatestConfigIntfs.stream()
.map(pluginConfigInterface -> PluginConfigInterfaceDto.fromDomain(pluginConfigInterface))
.collect(Collectors.toList()));
}
return filterWithPermissionValidation(pluginConfigInterfaceDtos, PluginAuthEntity.PERM_TYPE_USE);
return pluginConfigInterfaceDtos;
}
private List<PluginConfigInterface> filterLatestPluginConfigInterfaces(List<PluginConfigInterface> pluginConfigIntfs){
if (pluginConfigIntfs == null || pluginConfigIntfs.isEmpty()) {
return pluginConfigIntfs;
}
Map<String,PluginConfigInterface> serviceNamedPluginConfigIntfs = new HashMap<String,PluginConfigInterface>();
for(PluginConfigInterface pluginConfigIntf : pluginConfigIntfs){
String serviceName = pluginConfigIntf.generateServiceName();
PluginConfigInterface existIntf = serviceNamedPluginConfigIntfs.get(serviceName);
if(existIntf == null){
serviceNamedPluginConfigIntfs.put(serviceName, pluginConfigIntf);
}else{
if(isLaterThen(pluginConfigIntf, existIntf)){
log.info("plugin interface {} is later than plugin interface {}", pluginConfigIntf.getId(), existIntf.getId());
serviceNamedPluginConfigIntfs.put(serviceName, pluginConfigIntf);
}
}
}
List<PluginConfigInterface> filteredPluginConfigIntfs = new ArrayList<PluginConfigInterface>();
serviceNamedPluginConfigIntfs.values().forEach(intf -> {
filteredPluginConfigIntfs.add(intf);
});
return filteredPluginConfigIntfs;
}
private boolean isLaterThen(PluginConfigInterface intfa, PluginConfigInterface intfb){
Timestamp timea = intfa.getPluginConfig().getPluginPackage().getUploadTimestamp();
Timestamp timeb = intfb.getPluginConfig().getPluginPackage().getUploadTimestamp();
if(timea == null || timeb == null){
return false;
}
return timea.getTime() > timeb.getTime();
}
private List<PluginConfigInterface> filterWithPermissionValidation(List<PluginConfigInterface> pluginConfigIntfs,
String permission) {
if (pluginConfigIntfs == null || pluginConfigIntfs.isEmpty()) {
return pluginConfigIntfs;
}
private List<PluginConfigInterfaceDto> filterWithPermissionValidation(
Set<String> currUserRoles = AuthenticationContextHolder.getCurrentUserRoles();
if (currUserRoles == null || currUserRoles.isEmpty()) {
log.warn("roles of current user is empty.");
throw new WecubeCoreException("3059", "Lack of permission to perform such operation.");
}
List<PluginConfigInterface> filteredPluginConfigIntfs = new ArrayList<>();
for (PluginConfigInterface pluginConfigIntf : pluginConfigIntfs) {
if (verifyPluginConfigInterfacePrivilege(pluginConfigIntf.getPluginConfig().getId(), permission,
currUserRoles)) {
filteredPluginConfigIntfs.add(pluginConfigIntf);
}
}
return filteredPluginConfigIntfs;
}
private List<PluginConfigInterfaceDto> filterDtoWithPermissionValidation(
List<PluginConfigInterfaceDto> srcPluginConfigInterfaceDtos, String permission) {
if (srcPluginConfigInterfaceDtos == null || srcPluginConfigInterfaceDtos.isEmpty()) {
log.warn("interfaces is empty and return it directly.");
......@@ -611,7 +704,7 @@ public class PluginConfigService {
List<PluginConfigInterfaceDto> privilegedPluginConfigInterfaceDtos = new ArrayList<>();
for (PluginConfigInterfaceDto pluginConfigInterfaceDto : srcPluginConfigInterfaceDtos) {
if (verifyPluginConfigInterfacePrivilege(pluginConfigInterfaceDto, permission, currUserRoles)) {
if (verifyPluginConfigInterfacePrivilege(pluginConfigInterfaceDto.getPluginConfigId(), permission, currUserRoles)) {
privilegedPluginConfigInterfaceDtos.add(pluginConfigInterfaceDto);
}
}
......@@ -619,13 +712,10 @@ public class PluginConfigService {
return privilegedPluginConfigInterfaceDtos;
}
private boolean verifyPluginConfigInterfacePrivilege(PluginConfigInterfaceDto pluginConfigInterfaceDto,
String permission, Set<String> currUserRoles) {
if (StringUtils.isBlank(pluginConfigInterfaceDto.getPluginConfigId())) {
throw new WecubeCoreException("3060", "Plugin config ID cannot be blank.");
}
List<PluginAuthEntity> entities = pluginAuthRepository
.findAllByPluginConfigIdAndPermission(pluginConfigInterfaceDto.getPluginConfigId(), permission);
private boolean verifyPluginConfigInterfacePrivilege(String pluginConfigId, String permission,
Set<String> currUserRoles) {
List<PluginAuthEntity> entities = pluginAuthRepository.findAllByPluginConfigIdAndPermission(pluginConfigId,
permission);
if (entities.isEmpty()) {
return false;
}
......
......@@ -35,6 +35,7 @@ import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.stereotype.Service;
import com.google.common.collect.Lists;
import com.webank.wecube.platform.core.commons.ApplicationProperties;
import com.webank.wecube.platform.core.commons.ApplicationProperties.PluginProperties;
import com.webank.wecube.platform.core.commons.ApplicationProperties.ResourceProperties;
import com.webank.wecube.platform.core.commons.WecubeCoreException;
......@@ -78,6 +79,8 @@ public class PluginInstanceService {
@Autowired
private PluginProperties pluginProperties;
@Autowired
private ApplicationProperties applicationProperties;
@Autowired
PluginInstanceRepository pluginInstanceRepository;
......@@ -558,6 +561,7 @@ public class PluginInstanceService {
dbInfo.getPassword(), resourceProperties.getPasswordEncryptionSeed(), dbInfo.getSchema()));
}
logger.info("before replace envVariablesString=" + envVariablesString);
envVariablesString = replaceJwtSigningKey(envVariablesString);
envVariablesString = replaceSystemVariablesForEnvVariables(pluginPackage.getName(), envVariablesString);
logger.info("after replace envVariablesString=" + envVariablesString);
......@@ -587,6 +591,19 @@ public class PluginInstanceService {
logger.error("Launch instance has done, but register routing information is failed, please check");
}
}
private String replaceJwtSigningKey(String envVariablesString) {
if(StringUtils.isBlank(envVariablesString)) {
return envVariablesString;
}
String jwtSigningKey = applicationProperties.getJwtSigningKey();
if(StringUtils.isBlank(jwtSigningKey)) {
jwtSigningKey = "";
}
return envVariablesString.replace("{{JWT_SIGNING_KEY}}", jwtSigningKey);
}
private DatabaseInfo initMysqlDatabaseSchema(Set<PluginPackageRuntimeResourcesMysql> mysqlSet,
PluginPackage pluginPackage) {
......
......@@ -33,9 +33,9 @@ public class MysqlAccountManagementService implements ResourceItemService {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
if(Strings.isNullOrEmpty(database)) {
dataSource.setUrl("jdbc:mysql://" + host + ":" + port + "?characterEncoding=utf8&serverTimezone=UTC");
dataSource.setUrl("jdbc:mysql://" + host + ":" + port + "?characterEncoding=utf8&serverTimezone=UTC&nullCatalogMeansCurrent=true");
}else {
dataSource.setUrl("jdbc:mysql://" + host + ":" + port +"/"+ database +"?characterEncoding=utf8&serverTimezone=UTC");
dataSource.setUrl("jdbc:mysql://" + host + ":" + port +"/"+ database +"?characterEncoding=utf8&serverTimezone=UTC&nullCatalogMeansCurrent=true");
}
dataSource.setUsername(username);
dataSource.setPassword(password);
......
package com.webank.wecube.platform.core.service.resource;
import java.io.Closeable;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
......@@ -10,12 +13,18 @@ import java.sql.Timestamp;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -44,7 +53,11 @@ import com.webank.wecube.platform.core.utils.EncryptionUtils;
@Service
public class ResourceDataQueryService {
private Logger logger = LoggerFactory.getLogger(ResourceDataQueryService.class);
private static final List<String> ALLOWED_SQL_FUNCTIONS = Arrays.asList("count", "avg", "sum", "min", "max",
"distinct");
private static final String[] JDBC_METADATA_TABLE_TYPES = { "TABLE" };
@Autowired
private PluginMysqlInstanceRepository pluginMysqlInstanceRepository;
@Autowired
......@@ -53,7 +66,7 @@ public class ResourceDataQueryService {
private ResourceProperties resourceProperties;
@Autowired
private MysqlAccountManagementService mysqlAcctMngService;
@Autowired
private S3Client s3client;
......@@ -61,42 +74,44 @@ public class ResourceDataQueryService {
private PluginInstanceRepository pluginInstanceRepository;
@Autowired
private ResourceItemRepository resourceItemRepository;
public QueryResponse<List<String>> queryDB(String packageId, SqlQueryRequest sqlQueryRequest){
public QueryResponse<List<String>> queryDB(String packageId, SqlQueryRequest sqlQueryRequest) {
DataSource dataSource = getDataSource(packageId);
return queryDB(dataSource,sqlQueryRequest);
return queryDB(dataSource, sqlQueryRequest);
}
public QueryResponse<List<String>> queryDB(DataSource dataSource, SqlQueryRequest sqlQueryRequest){
List<List<String>> results = new LinkedList<>();
public QueryResponse<List<String>> queryDB(DataSource dataSource, SqlQueryRequest sqlQueryRequest) {
List<List<String>> results = new LinkedList<>();
sqlInjectionValidation(sqlQueryRequest.getSqlQuery(), dataSource);
try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement();) {
int totalCount = queryTotalCount(statement,sqlQueryRequest.getSqlQuery());
String limitedSql = getLimitedSql(sqlQueryRequest);
int totalCount = queryTotalCount(statement, sqlQueryRequest.getSqlQuery());
String limitedSql = getLimitedSql(sqlQueryRequest);
ResultSet rs = statement.executeQuery(limitedSql);
ResultSetMetaData resultSetMd = rs.getMetaData();
int columnCount = resultSetMd.getColumnCount();
List<String> headers = getHeaders(resultSetMd);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
while(rs.next()) {
while (rs.next()) {
List<String> rowValue = new ArrayList<>(columnCount);
for(int col=1;col<=columnCount;col++) {
for (int col = 1; col <= columnCount; col++) {
int colType = resultSetMd.getColumnType(col);
String literalVal = null;
switch(colType) {
switch (colType) {
case Types.DATE:
Date date = rs.getDate(col);
if(date != null) {
if (date != null) {
literalVal = dateFormat.format(date);
}
break;
case Types.TIMESTAMP:
Timestamp timestamp = rs.getTimestamp(col);
if(timestamp != null) {
if (timestamp != null) {
literalVal = datetimeFormat.format(timestamp);
}
break;
......@@ -109,133 +124,234 @@ public class ResourceDataQueryService {
results.add(rowValue);
}
QueryResponse<List<String>> response = null;
if(sqlQueryRequest.getPageable() != null) {
response = new QueryResponse<>(new PageInfo(totalCount,sqlQueryRequest.getPageable().getStartIndex(),sqlQueryRequest.getPageable().getPageSize()),
results,headers);
}else {
response = new QueryResponse<>(new PageInfo(totalCount,0,totalCount),results,headers);
if (sqlQueryRequest.getPageable() != null) {
response = new QueryResponse<>(new PageInfo(totalCount, sqlQueryRequest.getPageable().getStartIndex(),
sqlQueryRequest.getPageable().getPageSize()), results, headers);
} else {
response = new QueryResponse<>(new PageInfo(totalCount, 0, totalCount), results, headers);
}
return response;
}catch(Exception e) {
} catch (Exception e) {
String errorMessage = String.format("Fail to execute sql query:%s", sqlQueryRequest.toString());
logger.error(errorMessage, e);
throw new WecubeCoreException("3010",errorMessage, e);
}
throw new WecubeCoreException(errorMessage, e).withErrorCode("3010", sqlQueryRequest.toString());
}
}
private void sqlInjectionValidation(String rawSql, DataSource dataSource) {
if (StringUtils.isBlank(rawSql)) {
return;
}
String formattedSql = rawSql.trim().replaceAll("\\\\'", "ESCAPE");
formattedSql = formattedSql.replaceAll("'[^']*'", "?");
if (formattedSql.contains("'")) {
throw new WecubeCoreException("Single quote must be paired.").withErrorCode("3313");
}
formattedSql = formattedSql.toLowerCase();
if (formattedSql.contains("union")) {
throw new WecubeCoreException("Union query is not allowed.").withErrorCode("3314");
}
if (formattedSql.contains(";")) {
throw new WecubeCoreException("Semicolon is not allowed.").withErrorCode("3315");
}
validateSubSelection(formattedSql);
validateFunctions(formattedSql);
validateTableNames(formattedSql, dataSource);
}
private void validateSubSelection(String formattedSql) {
String selectCauseReg = "(\\W+)select(\\W+)";
Pattern selectp = Pattern.compile(selectCauseReg);
Matcher selectm = selectp.matcher(formattedSql);
if (selectm.find()) {
throw new WecubeCoreException("Sub-selection is not allowed.").withErrorCode("3316");
}
}
private void validateTableNames(String formattedSql, DataSource dataSource) {
formattedSql = formattedSql.trim() + " ";
String tableNameReg = "\\s+(from|join)\\s+(\\S+?)[\\s|\\)]+";
Pattern tableNameP = Pattern.compile(tableNameReg);
Matcher tableNameM = tableNameP.matcher(formattedSql);
Set<String> inputTableNames = new HashSet<String>();
while (tableNameM.find()) {
inputTableNames.add(tableNameM.group(2));
}
if (inputTableNames.isEmpty()) {
logger.info("None table names found in input SQL:{}", formattedSql);
return;
}
Set<String> tableNames = new HashSet<>();
ResultSet tablesRs = null;
Connection connection = null;
try {
connection = dataSource.getConnection();
String jdbcUrl = connection.getMetaData().getURL().toString();
String strSchema = null;
if (jdbcUrl.indexOf("?") > 0 && jdbcUrl.indexOf("/") > 0) {
strSchema = jdbcUrl.substring(0, jdbcUrl.indexOf("?"));
strSchema = strSchema.substring(strSchema.lastIndexOf("/") + 1);
}
DatabaseMetaData databaseMetaData = connection.getMetaData();
tablesRs = databaseMetaData.getTables(null, strSchema, null, JDBC_METADATA_TABLE_TYPES);
while (tablesRs.next()) {
String tableName = tablesRs.getString("TABLE_NAME");
tableName = tableName.trim().toLowerCase();
tableNames.add(tableName);
}
} catch (SQLException e) {
logger.error("", e);
throw new WecubeCoreException("Errors while fetching table names").withErrorCode("3317");
} finally {
closeSilently(tablesRs);
closeSilently(connection);
}
for (String inputTabName : inputTableNames) {
if (!tableNames.contains(inputTabName)) {
throw new WecubeCoreException(String.format("Selection to %s is not allowed.", inputTabName))
.withErrorCode("3318", inputTabName);
}
}
}
private void validateFunctions(String formattedSql) {
String functionNameReg = "(\\W+?)(\\w+?)\\(.*?\\)";
Pattern p = Pattern.compile(functionNameReg);
Matcher m = p.matcher(formattedSql);
while (m.find()) {
String funName = m.group(2);
if (!ALLOWED_SQL_FUNCTIONS.contains(funName)) {
throw new WecubeCoreException(String.format("Such function [%s] is not allowed.", funName))
.withErrorCode("3319", funName);
}
}
}
private List<String> getHeaders(ResultSetMetaData resultSetMd) throws SQLException {
List<String> headers = new ArrayList<>(resultSetMd.getColumnCount());
for(int i=1;i<=resultSetMd.getColumnCount();i++) {
for (int i = 1; i <= resultSetMd.getColumnCount(); i++) {
headers.add(resultSetMd.getColumnLabel(i));
}
return headers;
}
private String getLimitedSql(SqlQueryRequest sqlQueryRequest) {
if(sqlQueryRequest.getPageable() != null) {
if (sqlQueryRequest.getPageable() != null) {
int startIndex = sqlQueryRequest.getPageable().getStartIndex();
int pageSize = sqlQueryRequest.getPageable().getPageSize();
StringBuilder limitedSqlBuilder = new StringBuilder();
limitedSqlBuilder.append("select * from (")
.append(sqlQueryRequest.getSqlQuery())
.append(") alias limit ")
.append(startIndex)
.append(",")
.append(pageSize);
limitedSqlBuilder.append("select * from (").append(sqlQueryRequest.getSqlQuery()).append(") alias limit ")
.append(startIndex).append(",").append(pageSize);
return limitedSqlBuilder.toString();
}else {
} else {
return sqlQueryRequest.getSqlQuery();
}
}
private int queryTotalCount(Statement statement, String sqlQuery) {
StringBuilder countSqlBuilder = new StringBuilder();
countSqlBuilder.append("select count(1) from ")
.append("(")
.append(sqlQuery)
.append(") alias");
try(ResultSet rs = statement.executeQuery(countSqlBuilder.toString())){
if(rs.first()) {
countSqlBuilder.append("select count(1) from ").append("(").append(sqlQuery).append(") alias");
try (ResultSet rs = statement.executeQuery(countSqlBuilder.toString())) {
if (rs.first()) {
int totalCount = rs.getInt(1);
return totalCount;
}else {
throw new WecubeCoreException("3011",String.format("Failed to get total count of query: %s",sqlQuery));
} else {
throw new WecubeCoreException("3011", String.format("Failed to get total count of query: %s", sqlQuery),
sqlQuery);
}
}catch(Exception ex) {
throw new WecubeCoreException("3011",String.format("Failed to get total count of query: %s",sqlQuery));
} catch (Exception ex) {
throw new WecubeCoreException("3011", String.format("Failed to get total count of query: %s", sqlQuery),
sqlQuery);
}
}
private DataSource getDataSource(String packageId) {
Optional<PluginPackage> pluginPackageOpt = pluginPackageRepository.findById(packageId);
if(!pluginPackageOpt.isPresent()) {
throw new WecubeCoreException("3012",String.format("Can not find out PluginPackage for package id:%s",packageId));
if (!pluginPackageOpt.isPresent()) {
throw new WecubeCoreException("3012",
String.format("Can not find out PluginPackage for package id:%s", packageId));
}
PluginMysqlInstance pluginMysqlInstance = pluginMysqlInstanceRepository.findByPluginPackage_name(pluginPackageOpt.get().getName());
if(pluginMysqlInstance == null) {
throw new WecubeCoreException("3013",String.format("Can not find out PluginMysqlInstance for package name:%s",pluginPackageOpt.get().getName()));
PluginMysqlInstance pluginMysqlInstance = pluginMysqlInstanceRepository
.findByPluginPackage_name(pluginPackageOpt.get().getName());
if (pluginMysqlInstance == null) {
throw new WecubeCoreException("3013",
String.format("Can not find out PluginMysqlInstance for package name:%s",
pluginPackageOpt.get().getName()),
pluginPackageOpt.get().getName());
}
String dbUsername = pluginMysqlInstance.getUsername();
String password = EncryptionUtils.decryptWithAes(pluginMysqlInstance.getPassword(),resourceProperties.getPasswordEncryptionSeed(), dbUsername);
String password = EncryptionUtils.decryptWithAes(pluginMysqlInstance.getPassword(),
resourceProperties.getPasswordEncryptionSeed(), dbUsername);
ResourceItem resourceItem = pluginMysqlInstance.getResourceItem();
if(resourceItem == null) {
throw new WecubeCoreException("3014",String.format("Can not find out ResourceItem for packageId:%d", packageId));
if (resourceItem == null) {
throw new WecubeCoreException("3014",
String.format("Can not find out ResourceItem for packageId:%s", packageId), packageId);
}
ResourceServer resourceServer = resourceItem.getResourceServer();
if(resourceServer == null) {
throw new WecubeCoreException("3015",String.format("Can not find out mysql ResourceServer for packageId:%d", packageId));
if (resourceServer == null) {
throw new WecubeCoreException("3015",
String.format("Can not find out mysql ResourceServer for packageId:%s", packageId), packageId);
}
String mysqlHost = resourceServer.getHost();
String mysqlPort = resourceServer.getPort();
return mysqlAcctMngService.newMysqlDatasource(mysqlHost, mysqlPort, dbUsername, password,pluginMysqlInstance.getSchemaName());
return mysqlAcctMngService.newMysqlDatasource(mysqlHost, mysqlPort, dbUsername, password,
pluginMysqlInstance.getSchemaName());
}
public List<List<String>> queryS3Files(String packageId) {
List<PluginInstance> pluginInstances = pluginInstanceRepository.findByPluginPackage_Id(packageId);
if(pluginInstances == null || pluginInstances.size()==0) {
if (pluginInstances == null || pluginInstances.size() == 0) {
logger.info("Can not find out plugin instance for packageId:{}", packageId);
return Lists.newArrayList();
}
String bucketName = null;
for(PluginInstance ps:pluginInstances) {
if(ps.getS3BucketResourceId() == null) {
for (PluginInstance ps : pluginInstances) {
if (ps.getS3BucketResourceId() == null) {
continue;
}
Optional<ResourceItem> item= resourceItemRepository.findById(ps.getS3BucketResourceId());
if(item.isPresent()) {
Optional<ResourceItem> item = resourceItemRepository.findById(ps.getS3BucketResourceId());
if (item.isPresent()) {
bucketName = item.get().getName();
break;
}
}
if(Strings.isNullOrEmpty(bucketName)) {
if (Strings.isNullOrEmpty(bucketName)) {
return Lists.newArrayList();
}
List<S3ObjectSummary> s3Objs = s3client.listObjects(bucketName);
List<List<String>> response = new LinkedList<>();
SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for(S3ObjectSummary s3ObjSum:s3Objs) {
for (S3ObjectSummary s3ObjSum : s3Objs) {
List<String> rowVal = new ArrayList<>(4);
String key = s3ObjSum.getKey();
int lastSplitPos = key.lastIndexOf("/");
String path = "";
String fileName = "";
if(lastSplitPos > 0) {
path = key.substring(0,lastSplitPos+1);
fileName = key.substring(lastSplitPos+1);
}else {
if (lastSplitPos > 0) {
path = key.substring(0, lastSplitPos + 1);
fileName = key.substring(lastSplitPos + 1);
} else {
path = "/";
fileName = key;
}
......@@ -247,5 +363,25 @@ public class ResourceDataQueryService {
}
return response;
}
protected void closeSilently(AutoCloseable c) {
if (c != null) {
try {
c.close();
} catch (Exception e) {
logger.error("", e);
}
}
}
protected void closeSilently(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException e) {
logger.error("", e);
}
}
}
}
......@@ -634,13 +634,13 @@ public class WorkflowProcDefService extends AbstractWorkflowProcDefService {
if (!"subProcess".equalsIgnoreCase(nodeDto.getNodeType())) {
continue;
}
if (StringUtils.isBlank(nodeDto.getRoutineExpression()) || StringUtils.isBlank(nodeDto.getServiceId())) {
if (StringUtils.isBlank(nodeDto.getRoutineExpression())) {
throw new WecubeCoreException("3215",
String.format("Routine expression or service ID is invalid for %s", nodeDto.getNodeName()));
String.format("Routine expression is blank for %s", nodeDto.getNodeId()), nodeDto.getNodeId());
}
if (StringUtils.isBlank(nodeDto.getServiceId())) {
throw new WecubeCoreException("3216",String.format("Service ID not configured for %s", nodeDto.getNodeId()));
throw new WecubeCoreException("3216",String.format("Service ID is blank for %s", nodeDto.getNodeId()), nodeDto.getNodeId());
}
validateTaskNodePluginPermission(nodeDto, mgmtRoleIds);
......
......@@ -18,45 +18,45 @@ import com.webank.wecube.platform.core.support.plugin.dto.PluginResponse.Default
@Service("pluginInvocationRestClient")
public class PluginInvocationRestClient implements RestClient {
private static final Logger log = LoggerFactory.getLogger(PluginInvocationRestClient.class);
@Autowired
@Qualifier(value = "jwtSsoRestTemplate")
private RestTemplate jwtSsoRestTemplate;
public PluginResponse<Object> callPluginService(String instanceAddress, String path,
List<Map<String, Object>> parameters, String requestId, List<String> allowedOptions, String dueDate) {
PluginRequest<Map<String, Object>> requestObj = new DefaultPluginRequest().withInputs(parameters)
.withRequestId(requestId);
if (allowedOptions != null && !allowedOptions.isEmpty()) {
requestObj = requestObj.withAllowedOptions(allowedOptions);
}
requestObj = requestObj.withDueDate(dueDate);
return doCallPluginService(asPluginServerUrl(instanceAddress, path), requestObj);
}
public PluginResponse<Object> callPluginService(String instanceAddress, String path,
List<Map<String, Object>> parameters, String requestId) {
return doCallPluginService(asPluginServerUrl(instanceAddress, path),
new DefaultPluginRequest().withInputs(parameters).withRequestId(requestId));
}
protected PluginResponse<Object> doCallPluginService(String targetUrl, PluginRequest<?> parameters) {
log.debug("About to call {} with parameters: {} ", targetUrl, parameters);
PluginResponse<Object> response = jwtSsoRestTemplate.postForObject(targetUrl, parameters,
DefaultPluginResponse.class);
log.debug("Plugin response: {} ", response);
return response;
}
protected String asPluginServerUrl(String instanceAddress, String originPath, Object... pathVariables) {
String solvedPath = originPath;
if (pathVariables != null && pathVariables.length > 0) {
solvedPath = String.format(originPath, pathVariables);
}
return "http://" + instanceAddress + solvedPath;
}
private static final Logger log = LoggerFactory.getLogger(PluginInvocationRestClient.class);
@Autowired
@Qualifier(value = "jwtSsoRestTemplate")
private RestTemplate jwtSsoRestTemplate;
public PluginResponse<Object> callPluginService(String instanceAddress, String path,
List<Map<String, Object>> parameters, String requestId, List<String> allowedOptions, String dueDate) {
PluginRequest<Map<String, Object>> requestObj = new DefaultPluginRequest().withInputs(parameters)
.withRequestId(requestId);
if (allowedOptions != null && !allowedOptions.isEmpty()) {
requestObj = requestObj.withAllowedOptions(allowedOptions);
}
requestObj = requestObj.withDueDate(dueDate);
return doCallPluginService(asPluginServerUrl(instanceAddress, path), requestObj);
}
public PluginResponse<Object> callPluginService(String instanceAddress, String path,
List<Map<String, Object>> parameters, String requestId) {
return doCallPluginService(asPluginServerUrl(instanceAddress, path),
new DefaultPluginRequest().withInputs(parameters).withRequestId(requestId));
}
protected PluginResponse<Object> doCallPluginService(String targetUrl, PluginRequest<?> parameters) {
log.debug("About to call {} with parameters: {} ", targetUrl, parameters);
PluginResponse<Object> response = jwtSsoRestTemplate.postForObject(targetUrl, parameters,
DefaultPluginResponse.class);
log.debug("Plugin response: {} ", response);
return response;
}
protected String asPluginServerUrl(String instanceAddress, String originPath, Object... pathVariables) {
String solvedPath = originPath;
if (pathVariables != null && pathVariables.length > 0) {
solvedPath = String.format(originPath, pathVariables);
}
return "http://" + instanceAddress + solvedPath;
}
}
SET FOREIGN_KEY_CHECKS = 0;
drop table if exists plugin_packages;
drop table if exists plugin_package_dependencies;
drop table if exists plugin_package_menus;
DROP TABLE IF EXISTS plugin_packages;
DROP TABLE IF EXISTS plugin_package_dependencies;
DROP TABLE IF EXISTS plugin_package_menus;
DROP TABLE IF EXISTS plugin_package_data_model;
DROP TABLE IF EXISTS plugin_package_entities;
DROP TABLE IF EXISTS plugin_package_attributes;
drop table if exists system_variables;
drop table if exists plugin_package_authorities;
drop table if exists plugin_package_runtime_resources_docker;
drop table if exists plugin_package_runtime_resources_mysql;
drop table if exists plugin_package_runtime_resources_s3;
drop table if exists plugin_configs;
drop table if exists plugin_config_interfaces;
drop table if exists plugin_config_interface_parameters;
drop table if exists menu_items;
drop table if exists plugin_package_resource_files;
drop table if exists resource_server;
drop table if exists resource_item;
drop table if exists plugin_instances;
drop table if exists plugin_mysql_instances;
DROP TABLE if EXISTS role_menu;
DROP TABLE if EXISTS core_ru_proc_role_binding;
drop table if exists batch_execution_jobs;
drop table if exists execution_jobs;
drop table if exists execution_job_parameters;
DROP TABLE IF EXISTS system_variables;
DROP TABLE IF EXISTS plugin_package_authorities;
DROP TABLE IF EXISTS plugin_package_runtime_resources_docker;
DROP TABLE IF EXISTS plugin_package_runtime_resources_mysql;
DROP TABLE IF EXISTS plugin_package_runtime_resources_s3;
DROP TABLE IF EXISTS plugin_configs;
DROP TABLE IF EXISTS plugin_config_interfaces;
DROP TABLE IF EXISTS plugin_config_interface_parameters;
DROP TABLE IF EXISTS menu_items;
DROP TABLE IF EXISTS plugin_package_resource_files;
DROP TABLE IF EXISTS resource_server;
DROP TABLE IF EXISTS resource_item;
DROP TABLE IF EXISTS plugin_instances;
DROP TABLE IF EXISTS plugin_mysql_instances;
DROP TABLE IF EXISTS role_menu;
DROP TABLE IF EXISTS core_ru_proc_role_binding;
DROP TABLE IF EXISTS batch_execution_jobs;
DROP TABLE IF EXISTS execution_jobs;
DROP TABLE IF EXISTS execution_job_parameters;
DROP TABLE IF EXISTS favorites;
DROP TABLE IF EXISTS favorites_role;
DROP TABLE IF EXISTS plugin_artifact_pull_req;
......
......@@ -213,15 +213,15 @@ platform.core.msg.errorcode.3211=Service ID is invalid.
platform.core.msg.errorcode.3212=Plugin config interface does not exist.
platform.core.msg.errorcode.3213=Permission configuration should be provided.
platform.core.msg.errorcode.3214=Management permission configuration should be provided.
platform.core.msg.errorcode.3215=Routine expression or service ID is invalid for :{0}
platform.core.msg.errorcode.3216=Service ID is not configured for :{0}
platform.core.msg.errorcode.3217=Plugin config does not exist for interface::{0}
platform.core.msg.errorcode.3215=Routine expression is blank for :{0},the routine express should provide.
platform.core.msg.errorcode.3216=Service ID is blank for :{0}
platform.core.msg.errorcode.3217=Plugin config does not exist for interface:{0}
platform.core.msg.errorcode.3218=Lack of plugin permission to deploy workflow definition.
platform.core.msg.errorcode.3219=Lack of permission to deploy process.
platform.core.msg.errorcode.3220=Failed to retrieve Java runtime.
platform.core.msg.errorcode.3221=Returned result is expected but empty.
platform.core.msg.errorcode.3222=Incorrect user or password
platform.core.msg.errorcode.3223=Error occurred when running 'scp' command ::{0}
platform.core.msg.errorcode.3223=Error occurred when running 'scp' command :{0}
platform.core.msg.errorcode.3224=Index is not correct. Index:{0}, PackageName:{1}, EntityName:{2}
platform.core.msg.errorcode.3225=Process definition key {0} is NOT available.
platform.core.msg.errorcode.3226=Plugin package ID cannot be blank.
......@@ -310,3 +310,11 @@ platform.core.msg.errorcode.3308=Failed to decommission plugin package with erro
platform.core.msg.errorcode.3309=Errors occurred while fetching data from {0} due to status {1}.
platform.core.msg.errorcode.3310=Plugin dependency validation failed: make sure dependency package {0} {1} is in active status.
platform.core.msg.errorcode.3311=Cannot remove the account which belongs to the logon user.
platform.core.msg.errorcode.3312=Plugin packages do not match.The name from XML is {0} but the package you chose is {1}.
platform.core.msg.errorcode.3313=Single quote must be paired.
platform.core.msg.errorcode.3314=Union query is not allowed.
platform.core.msg.errorcode.3315=Semicolon is not allowed.
platform.core.msg.errorcode.3316=Sub-selection is not allowed.
platform.core.msg.errorcode.3317=Errors while fetching table names.
platform.core.msg.errorcode.3318=Selection to {0} is not allowed.
platform.core.msg.errorcode.3319=Such function [{0}] is not allowed.
......@@ -213,15 +213,15 @@ platform.core.msg.errorcode.3211=(CN):Service ID is invalid.
platform.core.msg.errorcode.3212=(CN):Plugin config interface does not exist.
platform.core.msg.errorcode.3213=(CN):Permission configuration should provide.
platform.core.msg.errorcode.3214=(CN):Management permission configuration should provide.
platform.core.msg.errorcode.3215=(CN):Routine expression or service ID is invalid for :{0}
platform.core.msg.errorcode.3216=(CN):Service ID not configured for :{0}
platform.core.msg.errorcode.3217=(CN):Plugin config does not exist for interface::{0}
platform.core.msg.errorcode.3215=(CN):Routine expression is invalid for :{0}
platform.core.msg.errorcode.3216=(CN):Service ID is not configured for :{0}
platform.core.msg.errorcode.3217=(CN):Plugin config does not exist for interface:{0}
platform.core.msg.errorcode.3218=(CN):Lack of plugin permission to deploy workflow definition.
platform.core.msg.errorcode.3219=(CN):Lack of permission to deploy process.
platform.core.msg.errorcode.3220=(CN):Create runtime false!
platform.core.msg.errorcode.3221=(CN):return is empty, please check !
platform.core.msg.errorcode.3222=(CN):User or password incorrect
platform.core.msg.errorcode.3223=(CN):Run 'scp' command meet error::{0}
platform.core.msg.errorcode.3223=(CN):Run 'scp' command meet error:{0}
platform.core.msg.errorcode.3224=(CN):Index is not correct.Index:{0}, PackageName:{1}, EntityName:{2}
platform.core.msg.errorcode.3225=(CN):Process definition key {0} is NOT available.
platform.core.msg.errorcode.3226=(CN):Plugin package ID cannot be blank.
......@@ -310,3 +310,12 @@ platform.core.msg.errorcode.3308=(CN):Failed to decommission plugin package with
platform.core.msg.errorcode.3309=(CN):Errors met while fetching data from {0} due to status {1}.
platform.core.msg.errorcode.3310=(CN):Plugin dependency validation failed:make sure dependency packege {0} {1} is in active status.
platform.core.msg.errorcode.3311=(CN):Cannot remove the account which belongs to the logon user.
platform.core.msg.errorcode.3312=(CN):Plugin packages do not match.The name from XML is {0} but the package you chose is {1}.
platform.core.msg.errorcode.3313=(CN):Single quote must be paired.
platform.core.msg.errorcode.3314=(CN):Union query is not allowed.
platform.core.msg.errorcode.3315=(CN):Semicolon is not allowed.
platform.core.msg.errorcode.3316=(CN):Sub-selection is not allowed.
platform.core.msg.errorcode.3317=(CN):Errors while fetching table names.
platform.core.msg.errorcode.3318=(CN):Selection to {0} is not allowed.
platform.core.msg.errorcode.3319=(CN):Such function [{0}] is not allowed.
<template>
<div class="plugin-register-page">
<Row>
<Col span="6" style="border-right: 1px solid #e8eaec">
<div v-if="plugins.length < 1">{{ $t('no_plugin') }}</div>
<Col span="6" style="border-right: 1px solid #e8eaec;">
<div style="height: calc(100vh - 180px);overflow-y:auto;">
<Menu theme="light" :active-name="currentPlugin" @on-select="selectPlugin" style="width: 100%;z-index:10">
<Submenu
v-for="(plugin, index) in plugins"
:name="plugin.pluginConfigName"
style="padding: 0;"
:key="index"
>
<template slot="title">
<Icon type="md-grid" />
<span style="font-size: 15px;">{{ plugin.pluginConfigName }}</span>
<div style="float:right;color: #2d8cf0;margin-right:30px">
<Tooltip :content="$t('add')" :delay="1000">
<Icon @click.stop.prevent="addPluginConfigDto(plugin)" style="" type="md-add" />
</Tooltip>
</div>
</template>
<MenuItem
v-for="(dto, index) in plugin.pluginConfigDtoList.filter(dto => dto.registerName)"
:name="dto.id"
<div v-if="plugins.length < 1">{{ $t('no_plugin') }}</div>
<div style="">
<Menu theme="light" :active-name="currentPlugin" @on-select="selectPlugin" style="width: 100%;z-index:10">
<Submenu
v-for="(plugin, index) in plugins"
:name="plugin.pluginConfigName"
style="padding: 0;"
:key="index"
style="padding: 5px 30px;"
>
<span
style="display: inline-block;white-space: nowrap; overflow: hidden; text-overflow: ellipsis;font-size: 15px; font-weight:400"
>{{ dto.registerName }}</span
<template slot="title">
<Icon type="md-grid" />
<span style="font-size: 15px;">{{ plugin.pluginConfigName }}</span>
<div style="float:right;color: #2d8cf0;margin-right:30px">
<Tooltip :content="$t('add')" :delay="1000">
<Icon @click.stop.prevent="addPluginConfigDto(plugin)" style="" type="md-add" />
</Tooltip>
</div>
</template>
<MenuItem
v-for="(dto, index) in plugin.pluginConfigDtoList.filter(dto => dto.registerName)"
:name="dto.id"
:key="index"
style="padding: 5px 30px;"
>
<div style="vertical-align: top;display: inline-block;float: right;">
<Tooltip :content="$t('copy')" :delay="500">
<Icon
size="16"
style="color: #19be6b;"
@click.stop.prevent="copyPluginConfigDto(dto.id)"
type="md-copy"
/>
</Tooltip>
<Tooltip :content="$t('config_permission')" :delay="500">
<Icon size="16" style="color: #2db7f5;" @click="permissionsHandler(dto)" type="md-contacts" />
</Tooltip>
</div>
</MenuItem>
</Submenu>
</Menu>
<span
style="display: inline-block;white-space: nowrap; overflow: hidden; text-overflow: ellipsis;font-size: 15px; font-weight:400"
>{{ dto.registerName }}</span
>
<div style="vertical-align: top;display: inline-block;float: right;">
<Tooltip :content="$t('copy')" :delay="500">
<Icon
size="16"
style="color: #19be6b;"
@click.stop.prevent="copyPluginConfigDto(dto.id)"
type="md-copy"
/>
</Tooltip>
<Tooltip :content="$t('config_permission')" :delay="500">
<Icon size="16" style="color: #2db7f5;" @click="permissionsHandler(dto)" type="md-contacts" />
</Tooltip>
</div>
</MenuItem>
</Submenu>
</Menu>
</div>
</div>
<div style="padding-right: 20px;margin-top: 10px;">
<Button type="info" long ghost @click="batchRegist">{{ $t('batch_regist') }}</Button>
......
......@@ -62,41 +62,45 @@
v-if="plugin.status !== 'DECOMMISSIONED' || isShowDecomissionedPackage"
:key="plugin.id"
>
<span :class="plugin.status !== 'DECOMMISSIONED' ? '' : 'decomissionedPkgName'">
{{ plugin.name + '_' + plugin.version }}
</span>
<span style="float: right; margin-right: 10px">
<Tooltip :content="$t('configuration_import')">
<Button
icon="ios-cloud-upload-outline"
v-if="plugin.status !== 'DECOMMISSIONED'"
size="small"
type="primary"
ghost
@click.stop.prevent="importBestPractices(plugin.id)"
></Button>
</Tooltip>
<Tooltip :content="$t('configuration_export')">
<Button
v-if="plugin.status !== 'DECOMMISSIONED'"
@click.stop.prevent="exportBestPractices(plugin.id)"
size="small"
type="primary"
ghost
icon="md-download"
></Button>
</Tooltip>
<Tooltip :content="$t('delete')">
<Button
v-if="plugin.status !== 'DECOMMISSIONED'"
@click.stop.prevent="deletePlugin(plugin.id)"
size="small"
type="error"
ghost
icon="ios-trash"
></Button>
</Tooltip>
</span>
<div style="float: right;width: calc(100% - 30px);">
<span
:class="plugin.status !== 'DECOMMISSIONED' ? 'plugin-title' : 'decomissionedPkgName plugin-title'"
>
{{ plugin.name + '_' + plugin.version }}
</span>
<span style="float: right; margin-right: 10px">
<Tooltip :content="$t('configuration_import')">
<Button
icon="ios-cloud-upload-outline"
v-if="plugin.status !== 'DECOMMISSIONED'"
size="small"
type="primary"
ghost
@click.stop.prevent="importBestPractices(plugin.id)"
></Button>
</Tooltip>
<Tooltip :content="$t('configuration_export')">
<Button
v-if="plugin.status !== 'DECOMMISSIONED'"
@click.stop.prevent="exportBestPractices(plugin.id)"
size="small"
type="primary"
ghost
icon="md-download"
></Button>
</Tooltip>
<Tooltip :content="$t('delete')">
<Button
v-if="plugin.status !== 'DECOMMISSIONED'"
@click.stop.prevent="deletePlugin(plugin.id)"
size="small"
type="error"
ghost
icon="ios-trash"
></Button>
</Tooltip>
</span>
</div>
<p slot="content" class="button-group">
<Button @click="configPlugin(plugin.id)" size="small" type="info" ghost icon="ios-checkmark-circle">
{{ $t('plugin_config_check') }}
......@@ -952,4 +956,12 @@ export default {
.clear-default-css {
margin-bottom: 0;
}
.plugin-title {
width: calc(100% - 110px);
display: block;
float: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment