Merge pull request #3930 from appsmithorg/task/apply-encryption
Applying AOP encryption
This commit is contained in:
commit
ea9743123b
|
|
@ -53,144 +53,146 @@ public class EncryptionHandler {
|
|||
|
||||
// If it is not known, scan each field for annotation or Appsmith type
|
||||
List<CandidateField> finalCandidateFields = new ArrayList<>();
|
||||
ReflectionUtils.doWithFields(sourceClass, field -> {
|
||||
if (field.getAnnotation(Encrypted.class) != null) {
|
||||
CandidateField candidateField = new CandidateField(field, CandidateField.Type.ANNOTATED_FIELD);
|
||||
finalCandidateFields.add(candidateField);
|
||||
} else if (AppsmithDomain.class.isAssignableFrom(field.getType())) {
|
||||
CandidateField candidateField = null;
|
||||
|
||||
field.setAccessible(true);
|
||||
Object fieldValue = ReflectionUtils.getField(field, source);
|
||||
if (fieldValue == null) {
|
||||
if (this.encryptedFieldsMap.containsKey(field.getType())) {
|
||||
// If this field is null, but the cache has a non-empty list of candidates already,
|
||||
// then this is an appsmith field with known annotations
|
||||
candidateField = new CandidateField(field, CandidateField.Type.APPSMITH_FIELD_KNOWN);
|
||||
} else {
|
||||
// If it is null and the cache is not aware of the field, this is still a prospect,
|
||||
// but with an unknown type (could also be polymorphic)
|
||||
candidateField = new CandidateField(field, CandidateField.Type.APPSMITH_FIELD_UNKNOWN);
|
||||
}
|
||||
} else {
|
||||
// If an object exists, check if the object type is the same as the field type
|
||||
CandidateField.Type appsmithFieldType;
|
||||
if (field.getType().getCanonicalName().equals(fieldValue.getClass().getCanonicalName())) {
|
||||
// If they match, then this is going to be an appsmith known field
|
||||
appsmithFieldType = CandidateField.Type.APPSMITH_FIELD_KNOWN;
|
||||
} else {
|
||||
// If not, then this field is polymorphic,
|
||||
// it will need to be checked for type every time
|
||||
appsmithFieldType = CandidateField.Type.APPSMITH_FIELD_POLYMORPHIC;
|
||||
}
|
||||
// Now, go into field type and repeat
|
||||
List<CandidateField> candidateFieldsForType = findCandidateFieldsForType(fieldValue);
|
||||
|
||||
if (appsmithFieldType.equals(CandidateField.Type.APPSMITH_FIELD_POLYMORPHIC)
|
||||
|| !candidateFieldsForType.isEmpty()) {
|
||||
// This type only qualifies as a candidate if it is polymorphic,
|
||||
// or has a list of candidates
|
||||
candidateField = new CandidateField(field, appsmithFieldType);
|
||||
}
|
||||
}
|
||||
|
||||
field.setAccessible(false);
|
||||
if (candidateField != null) {
|
||||
// This will only ever be null if the field value is populated,
|
||||
// and is known to be a non-encryption related field
|
||||
synchronized (sourceClass) {
|
||||
ReflectionUtils.doWithFields(sourceClass, field -> {
|
||||
if (field.getAnnotation(Encrypted.class) != null) {
|
||||
CandidateField candidateField = new CandidateField(field, CandidateField.Type.ANNOTATED_FIELD);
|
||||
finalCandidateFields.add(candidateField);
|
||||
}
|
||||
} else if (Collection.class.isAssignableFrom(field.getType()) &&
|
||||
field.getGenericType() instanceof ParameterizedType) {
|
||||
// If this is a collection, check if the Type parameter is an AppsmithDomain
|
||||
Type[] typeArguments;
|
||||
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
|
||||
typeArguments = parameterizedType.getActualTypeArguments();
|
||||
Class<?> subFieldType = (Class<?>) typeArguments[0];
|
||||
|
||||
if (this.encryptedFieldsMap.containsKey(subFieldType)) {
|
||||
// This is a known type, it should necessarily be of AppsmithDomain type
|
||||
assert AppsmithDomain.class.isAssignableFrom(subFieldType);
|
||||
final List<CandidateField> existingSubTypeCandidates = this.encryptedFieldsMap.get(subFieldType);
|
||||
if (!existingSubTypeCandidates.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_KNOWN));
|
||||
}
|
||||
} else if (AppsmithDomain.class.isAssignableFrom(subFieldType)) {
|
||||
// If the type is not known, then this is either not parsed yet, or has polymorphic implementations
|
||||
} else if (AppsmithDomain.class.isAssignableFrom(field.getType())) {
|
||||
CandidateField candidateField = null;
|
||||
|
||||
field.setAccessible(true);
|
||||
Object fieldValue = ReflectionUtils.getField(field, source);
|
||||
List<?> list = (List<?>) fieldValue;
|
||||
|
||||
if (list == null || list.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_UNKNOWN));
|
||||
if (fieldValue == null) {
|
||||
if (this.encryptedFieldsMap.containsKey(field.getType())) {
|
||||
// If this field is null, but the cache has a non-empty list of candidates already,
|
||||
// then this is an appsmith field with known annotations
|
||||
candidateField = new CandidateField(field, CandidateField.Type.APPSMITH_FIELD_KNOWN);
|
||||
} else {
|
||||
// If it is null and the cache is not aware of the field, this is still a prospect,
|
||||
// but with an unknown type (could also be polymorphic)
|
||||
candidateField = new CandidateField(field, CandidateField.Type.APPSMITH_FIELD_UNKNOWN);
|
||||
}
|
||||
} else {
|
||||
for (final Object o : list) {
|
||||
if (o == null) {
|
||||
continue;
|
||||
}
|
||||
if (o.getClass().getCanonicalName().equals(subFieldType.getTypeName())) {
|
||||
final List<CandidateField> candidateFieldsForListMember = findCandidateFieldsForType(o);
|
||||
if (candidateFieldsForListMember != null && !candidateFieldsForListMember.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_KNOWN));
|
||||
}
|
||||
} else {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_POLYMORPHIC));
|
||||
}
|
||||
break;
|
||||
// If an object exists, check if the object type is the same as the field type
|
||||
CandidateField.Type appsmithFieldType;
|
||||
if (field.getType().getCanonicalName().equals(fieldValue.getClass().getCanonicalName())) {
|
||||
// If they match, then this is going to be an appsmith known field
|
||||
appsmithFieldType = CandidateField.Type.APPSMITH_FIELD_KNOWN;
|
||||
} else {
|
||||
// If not, then this field is polymorphic,
|
||||
// it will need to be checked for type every time
|
||||
appsmithFieldType = CandidateField.Type.APPSMITH_FIELD_POLYMORPHIC;
|
||||
}
|
||||
// Now, go into field type and repeat
|
||||
List<CandidateField> candidateFieldsForType = findCandidateFieldsForType(fieldValue);
|
||||
|
||||
if (appsmithFieldType.equals(CandidateField.Type.APPSMITH_FIELD_POLYMORPHIC)
|
||||
|| !candidateFieldsForType.isEmpty()) {
|
||||
// This type only qualifies as a candidate if it is polymorphic,
|
||||
// or has a list of candidates
|
||||
candidateField = new CandidateField(field, appsmithFieldType);
|
||||
}
|
||||
}
|
||||
|
||||
field.setAccessible(false);
|
||||
|
||||
}
|
||||
// TODO Add support for nested collections
|
||||
} else if (Map.class.isAssignableFrom(field.getType()) &&
|
||||
field.getGenericType() instanceof ParameterizedType) {
|
||||
Type[] typeArguments;
|
||||
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
|
||||
typeArguments = parameterizedType.getActualTypeArguments();
|
||||
Class<?> subFieldType = (Class<?>) typeArguments[1];
|
||||
|
||||
if (this.encryptedFieldsMap.containsKey(subFieldType)) {
|
||||
// This is a known type, it should necessarily be of AppsmithDomain type
|
||||
assert AppsmithDomain.class.isAssignableFrom(subFieldType);
|
||||
final List<CandidateField> existingSubTypeCandidates = this.encryptedFieldsMap.get(subFieldType);
|
||||
if (!existingSubTypeCandidates.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_KNOWN));
|
||||
if (candidateField != null) {
|
||||
// This will only ever be null if the field value is populated,
|
||||
// and is known to be a non-encryption related field
|
||||
finalCandidateFields.add(candidateField);
|
||||
}
|
||||
} else if (AppsmithDomain.class.isAssignableFrom(subFieldType)) {
|
||||
// If the type is not known, then this is either not parsed yet, or has polymorphic implementations
|
||||
} else if (Collection.class.isAssignableFrom(field.getType()) &&
|
||||
field.getGenericType() instanceof ParameterizedType) {
|
||||
// If this is a collection, check if the Type parameter is an AppsmithDomain
|
||||
Type[] typeArguments;
|
||||
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
|
||||
typeArguments = parameterizedType.getActualTypeArguments();
|
||||
Class<?> subFieldType = (Class<?>) typeArguments[0];
|
||||
|
||||
field.setAccessible(true);
|
||||
Object fieldValue = ReflectionUtils.getField(field, source);
|
||||
Map<?, ?> map = (Map<?, ?>) fieldValue;
|
||||
if (map == null || map.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_UNKNOWN));
|
||||
} else {
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
final Object value = entry.getValue();
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
if (value.getClass().getCanonicalName().equals(subFieldType.getTypeName())) {
|
||||
final List<CandidateField> candidateFieldsForListMember = findCandidateFieldsForType(value);
|
||||
if (candidateFieldsForListMember != null && !candidateFieldsForListMember.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_KNOWN));
|
||||
}
|
||||
} else {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_POLYMORPHIC));
|
||||
}
|
||||
break;
|
||||
if (this.encryptedFieldsMap.containsKey(subFieldType)) {
|
||||
// This is a known type, it should necessarily be of AppsmithDomain type
|
||||
assert AppsmithDomain.class.isAssignableFrom(subFieldType);
|
||||
final List<CandidateField> existingSubTypeCandidates = this.encryptedFieldsMap.get(subFieldType);
|
||||
if (!existingSubTypeCandidates.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_KNOWN));
|
||||
}
|
||||
}
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
} else if (AppsmithDomain.class.isAssignableFrom(subFieldType)) {
|
||||
// If the type is not known, then this is either not parsed yet, or has polymorphic implementations
|
||||
|
||||
}, field -> field.getAnnotation(Encrypted.class) != null ||
|
||||
AppsmithDomain.class.isAssignableFrom(field.getType()) ||
|
||||
Collection.class.isAssignableFrom(field.getType()) ||
|
||||
Map.class.isAssignableFrom(field.getType()));
|
||||
field.setAccessible(true);
|
||||
Object fieldValue = ReflectionUtils.getField(field, source);
|
||||
List<?> list = (List<?>) fieldValue;
|
||||
|
||||
if (list == null || list.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_UNKNOWN));
|
||||
} else {
|
||||
for (final Object o : list) {
|
||||
if (o == null) {
|
||||
continue;
|
||||
}
|
||||
if (o.getClass().getCanonicalName().equals(subFieldType.getTypeName())) {
|
||||
final List<CandidateField> candidateFieldsForListMember = findCandidateFieldsForType(o);
|
||||
if (candidateFieldsForListMember != null && !candidateFieldsForListMember.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_KNOWN));
|
||||
}
|
||||
} else {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_LIST_POLYMORPHIC));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
field.setAccessible(false);
|
||||
|
||||
}
|
||||
// TODO Add support for nested collections
|
||||
} else if (Map.class.isAssignableFrom(field.getType()) &&
|
||||
field.getGenericType() instanceof ParameterizedType) {
|
||||
Type[] typeArguments;
|
||||
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
|
||||
typeArguments = parameterizedType.getActualTypeArguments();
|
||||
Class<?> subFieldType = (Class<?>) typeArguments[1];
|
||||
|
||||
if (this.encryptedFieldsMap.containsKey(subFieldType)) {
|
||||
// This is a known type, it should necessarily be of AppsmithDomain type
|
||||
assert AppsmithDomain.class.isAssignableFrom(subFieldType);
|
||||
final List<CandidateField> existingSubTypeCandidates = this.encryptedFieldsMap.get(subFieldType);
|
||||
if (!existingSubTypeCandidates.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_KNOWN));
|
||||
}
|
||||
} else if (AppsmithDomain.class.isAssignableFrom(subFieldType)) {
|
||||
// If the type is not known, then this is either not parsed yet, or has polymorphic implementations
|
||||
|
||||
field.setAccessible(true);
|
||||
Object fieldValue = ReflectionUtils.getField(field, source);
|
||||
Map<?, ?> map = (Map<?, ?>) fieldValue;
|
||||
if (map == null || map.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_UNKNOWN));
|
||||
} else {
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
final Object value = entry.getValue();
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
if (value.getClass().getCanonicalName().equals(subFieldType.getTypeName())) {
|
||||
final List<CandidateField> candidateFieldsForListMember = findCandidateFieldsForType(value);
|
||||
if (candidateFieldsForListMember != null && !candidateFieldsForListMember.isEmpty()) {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_KNOWN));
|
||||
}
|
||||
} else {
|
||||
finalCandidateFields.add(new CandidateField(field, CandidateField.Type.APPSMITH_MAP_POLYMORPHIC));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
|
||||
}, field -> field.getAnnotation(Encrypted.class) != null ||
|
||||
AppsmithDomain.class.isAssignableFrom(field.getType()) ||
|
||||
Collection.class.isAssignableFrom(field.getType()) ||
|
||||
Map.class.isAssignableFrom(field.getType()));
|
||||
}
|
||||
// Update cache for next use
|
||||
encryptedFieldsMap.put(sourceClass, finalCandidateFields);
|
||||
|
||||
|
|
@ -198,7 +200,7 @@ public class EncryptionHandler {
|
|||
|
||||
}
|
||||
|
||||
boolean convertEncryption(Object source, Function<String, String> transformer) {
|
||||
synchronized boolean convertEncryption(Object source, Function<String, String> transformer) {
|
||||
if (source == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -294,12 +296,11 @@ public class EncryptionHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
field.setAccessible(false);
|
||||
}
|
||||
|
||||
field.setAccessible(false);
|
||||
}
|
||||
|
||||
return hasEncryptedFields;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.appsmith.external.models;
|
||||
|
||||
import com.appsmith.external.annotations.encryption.Encrypted;
|
||||
import com.appsmith.external.constants.Authentication;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
|
|
@ -11,8 +10,6 @@ import lombok.Setter;
|
|||
import org.springframework.data.annotation.Transient;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
|
|
@ -53,25 +50,6 @@ public class AuthenticationDTO implements AppsmithDomain {
|
|||
@JsonIgnore
|
||||
AuthenticationResponse authenticationResponse;
|
||||
|
||||
@JsonIgnore
|
||||
public Map<String, String> getEncryptionFields() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public void setEncryptionFields(Map<String, String> encryptedFields) {
|
||||
// This is supposed to be overridden by implementations.
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Set<String> getEmptyEncryptionFields() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Boolean isEncrypted() {
|
||||
return this.isEncrypted;
|
||||
}
|
||||
|
||||
public Mono<Boolean> hasExpired() {
|
||||
return Mono.just(Boolean.FALSE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.appsmith.external.models;
|
||||
|
||||
import com.appsmith.external.annotations.encryption.Encrypted;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
|
@ -14,13 +15,17 @@ import java.time.Instant;
|
|||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AuthenticationResponse implements AppsmithDomain {
|
||||
|
||||
@Encrypted
|
||||
String token;
|
||||
|
||||
@Encrypted
|
||||
String refreshToken;
|
||||
|
||||
Instant issuedAt;
|
||||
|
||||
Instant expiresAt;
|
||||
|
||||
@Encrypted
|
||||
Object tokenResponse;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.appsmith.external.models;
|
||||
|
||||
import com.appsmith.external.annotations.documenttype.DocumentType;
|
||||
import com.appsmith.external.annotations.encryption.Encrypted;
|
||||
import com.appsmith.external.constants.Authentication;
|
||||
import com.appsmith.external.constants.FieldName;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
|
@ -10,9 +10,6 @@ import lombok.NoArgsConstructor;
|
|||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
|
|
@ -29,31 +26,9 @@ public class DBAuth extends AuthenticationDTO {
|
|||
|
||||
String username;
|
||||
|
||||
@Encrypted
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
String password;
|
||||
|
||||
String databaseName;
|
||||
|
||||
@Override
|
||||
public Map<String, String> getEncryptionFields() {
|
||||
if (this.password != null && !this.password.isBlank()) {
|
||||
return Map.of(FieldName.PASSWORD, this.password);
|
||||
}
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEncryptionFields(Map<String, String> encryptedFields) {
|
||||
if (encryptedFields != null && encryptedFields.containsKey(FieldName.PASSWORD)) {
|
||||
this.password = encryptedFields.get(FieldName.PASSWORD);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getEmptyEncryptionFields() {
|
||||
if (this.password == null || this.password.isBlank()) {
|
||||
return Set.of(FieldName.PASSWORD);
|
||||
}
|
||||
return Set.of();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
package com.appsmith.external.models;
|
||||
|
||||
import com.appsmith.external.annotations.documenttype.DocumentType;
|
||||
import com.appsmith.external.annotations.encryption.Encrypted;
|
||||
import com.appsmith.external.constants.Authentication;
|
||||
import com.appsmith.external.constants.FieldName;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
|
@ -14,13 +12,8 @@ import lombok.ToString;
|
|||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -46,6 +39,7 @@ public class OAuth2 extends AuthenticationDTO {
|
|||
|
||||
String clientId;
|
||||
|
||||
@Encrypted
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
String clientSecret;
|
||||
|
||||
|
|
@ -79,73 +73,4 @@ public class OAuth2 extends AuthenticationDTO {
|
|||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getEncryptionFields() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
if (this.clientSecret != null) {
|
||||
map.put(FieldName.CLIENT_SECRET, this.clientSecret);
|
||||
}
|
||||
if (this.getAuthenticationResponse() != null) {
|
||||
if (this.authenticationResponse.getToken() != null) {
|
||||
map.put(FieldName.TOKEN, this.authenticationResponse.getToken());
|
||||
}
|
||||
if (this.authenticationResponse.getRefreshToken() != null) {
|
||||
map.put(FieldName.REFRESH_TOKEN, this.authenticationResponse.getRefreshToken());
|
||||
}
|
||||
if (this.authenticationResponse.getTokenResponse() != null) {
|
||||
map.put(FieldName.TOKEN_RESPONSE, String.valueOf(this.authenticationResponse.getTokenResponse()));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEncryptionFields(Map<String, String> encryptedFields) {
|
||||
if (encryptedFields != null) {
|
||||
if (encryptedFields.containsKey(FieldName.CLIENT_SECRET)) {
|
||||
this.clientSecret = encryptedFields.get(FieldName.CLIENT_SECRET);
|
||||
}
|
||||
if (encryptedFields.containsKey(FieldName.TOKEN)) {
|
||||
this.authenticationResponse.setToken(encryptedFields.get(FieldName.TOKEN));
|
||||
}
|
||||
if (encryptedFields.containsKey(FieldName.REFRESH_TOKEN)) {
|
||||
this.authenticationResponse.setRefreshToken(encryptedFields.get(FieldName.REFRESH_TOKEN));
|
||||
}
|
||||
if (encryptedFields.containsKey(FieldName.TOKEN_RESPONSE)) {
|
||||
this.authenticationResponse.setTokenResponse(encryptedFields.get(FieldName.TOKEN_RESPONSE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getEmptyEncryptionFields() {
|
||||
Set<String> set = new HashSet<>();
|
||||
if (this.clientSecret == null || this.clientSecret.isEmpty()) {
|
||||
set.add(FieldName.CLIENT_SECRET);
|
||||
}
|
||||
if (this.getAuthenticationResponse() != null) {
|
||||
if (this.authenticationResponse.getToken() == null || this.authenticationResponse.getToken().isEmpty()) {
|
||||
set.add(FieldName.TOKEN);
|
||||
}
|
||||
if (this.authenticationResponse.getRefreshToken() == null || this.authenticationResponse.getRefreshToken().isEmpty()) {
|
||||
set.add(FieldName.REFRESH_TOKEN);
|
||||
}
|
||||
if (this.authenticationResponse.getTokenResponse() == null || (String.valueOf(this.authenticationResponse.getTokenResponse())).isEmpty()) {
|
||||
set.add(FieldName.TOKEN_RESPONSE);
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> hasExpired() {
|
||||
if (this.authenticationResponse == null) {
|
||||
return Mono.error(new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_ERROR,
|
||||
"Expected datasource to have valid authentication tokens at this point"));
|
||||
}
|
||||
|
||||
return Mono.just(authenticationResponse.expiresAt.isBefore(Instant.now().plusSeconds(60)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@ public class MongoConfig {
|
|||
return converter;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public EncryptionMongoEventListener encryptionMongoEventListener(EncryptionService encryptionService) {
|
||||
// return new EncryptionMongoEventListener(encryptionService);
|
||||
// }
|
||||
@Bean
|
||||
public EncryptionMongoEventListener encryptionMongoEventListener(EncryptionService encryptionService) {
|
||||
return new EncryptionMongoEventListener(encryptionService);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.external.models.AuthenticationDTO;
|
||||
import com.appsmith.server.domains.Datasource;
|
||||
import com.appsmith.server.domains.DatasourceContext;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
@ -22,6 +21,4 @@ public interface DatasourceContextService {
|
|||
<T> Mono<T> retryOnce(Datasource datasource, Function<DatasourceContext, Mono<T>> task);
|
||||
|
||||
Mono<DatasourceContext> deleteDatasourceContext(String datasourceId);
|
||||
|
||||
AuthenticationDTO decryptSensitiveFields(AuthenticationDTO authenticationDTO);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import java.time.Instant;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.appsmith.server.acl.AclPermission.EXECUTE_DATASOURCES;
|
||||
|
||||
|
|
@ -88,13 +87,6 @@ public class DatasourceContextServiceImpl implements DatasourceContextService {
|
|||
.flatMap(objects -> {
|
||||
Datasource datasource1 = objects.getT1();
|
||||
|
||||
// If authentication exists for the datasource, decrypt the fields
|
||||
if (datasource1.getDatasourceConfiguration() != null &&
|
||||
datasource1.getDatasourceConfiguration().getAuthentication() != null) {
|
||||
AuthenticationDTO authentication = datasource1.getDatasourceConfiguration().getAuthentication();
|
||||
datasource1.getDatasourceConfiguration().setAuthentication(decryptSensitiveFields(authentication));
|
||||
}
|
||||
|
||||
PluginExecutor<Object> pluginExecutor = objects.getT2();
|
||||
|
||||
if (isStale) {
|
||||
|
|
@ -185,18 +177,4 @@ public class DatasourceContextServiceImpl implements DatasourceContextService {
|
|||
return datasourceContextMap.remove(datasourceId);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationDTO decryptSensitiveFields(AuthenticationDTO authentication) {
|
||||
if (authentication != null && Boolean.TRUE.equals(authentication.isEncrypted())) {
|
||||
Map<String, String> decryptedFields = authentication.getEncryptionFields().entrySet().stream()
|
||||
.filter(e -> e.getValue() != null && !e.getValue().isBlank())
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> encryptionService.decryptString(e.getValue())));
|
||||
authentication.setEncryptionFields(decryptedFields);
|
||||
authentication.setIsEncrypted(false);
|
||||
}
|
||||
return authentication;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.external.models.AuthenticationDTO;
|
||||
import com.appsmith.external.models.DatasourceTestResult;
|
||||
import com.appsmith.server.acl.AclPermission;
|
||||
import com.appsmith.server.domains.Datasource;
|
||||
|
|
@ -30,7 +29,5 @@ public interface DatasourceService extends CrudService<Datasource, String> {
|
|||
|
||||
Flux<Datasource> saveAll(List<Datasource> datasourceList);
|
||||
|
||||
AuthenticationDTO encryptAuthenticationFields(AuthenticationDTO authentication);
|
||||
|
||||
public Mono<Datasource> populateHintMessages(Datasource datasource);
|
||||
Mono<Datasource> populateHintMessages(Datasource datasource);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.appsmith.server.services;
|
||||
|
||||
import com.appsmith.external.helpers.BeanCopyUtils;
|
||||
import com.appsmith.external.helpers.MustacheHelper;
|
||||
import com.appsmith.external.models.AuthenticationDTO;
|
||||
import com.appsmith.external.models.DatasourceConfiguration;
|
||||
import com.appsmith.external.models.DatasourceTestResult;
|
||||
import com.appsmith.external.models.Endpoint;
|
||||
|
|
@ -36,7 +36,6 @@ import javax.validation.Validator;
|
|||
import javax.validation.constraints.NotNull;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -84,17 +83,6 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
|||
this.encryptionService = encryptionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Datasource> getById(String s) {
|
||||
return super.getById(s).flatMap(datasource -> {
|
||||
if (datasource.getDatasourceConfiguration().getAuthentication() != null &&
|
||||
Boolean.TRUE.equals(datasource.getDatasourceConfiguration().getAuthentication().isEncrypted())) {
|
||||
datasource.getDatasourceConfiguration().setAuthentication(decryptSensitiveFields(datasource.getDatasourceConfiguration().getAuthentication()));
|
||||
}
|
||||
return Mono.just(datasource);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Datasource> create(@NotNull Datasource datasource) {
|
||||
String orgId = datasource.getOrganizationId();
|
||||
|
|
@ -105,11 +93,6 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
|||
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
|
||||
}
|
||||
|
||||
// If Authentication Details are present in the datasource, encrypt the details before saving
|
||||
if (datasource.getDatasourceConfiguration() != null) {
|
||||
datasource.getDatasourceConfiguration().setAuthentication(encryptAuthenticationFields(datasource.getDatasourceConfiguration().getAuthentication()));
|
||||
}
|
||||
|
||||
Mono<Datasource> datasourceMono = Mono.just(datasource);
|
||||
if (StringUtils.isEmpty(datasource.getName())) {
|
||||
datasourceMono = sequenceService
|
||||
|
|
@ -190,11 +173,6 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
|||
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
|
||||
}
|
||||
|
||||
// If Authentication Details are present in the datasource, encrypt the details before saving
|
||||
if (datasource.getDatasourceConfiguration() != null) {
|
||||
datasource.getDatasourceConfiguration().setAuthentication(encryptAuthenticationFields(datasource.getDatasourceConfiguration().getAuthentication()));
|
||||
}
|
||||
|
||||
// Since policies are a server only concept, first set the empty set (set by constructor) to null
|
||||
datasource.setPolicies(null);
|
||||
|
||||
|
|
@ -215,23 +193,6 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
|||
.flatMap(this::populateHintMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationDTO encryptAuthenticationFields(AuthenticationDTO authentication) {
|
||||
if (authentication != null
|
||||
&& !Boolean.TRUE.equals(authentication.isEncrypted())) {
|
||||
Map<String, String> encryptedFields = authentication.getEncryptionFields().entrySet().stream()
|
||||
.filter(e -> e.getValue() != null)
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> encryptionService.encryptString(e.getValue())));
|
||||
if (!encryptedFields.isEmpty()) {
|
||||
authentication.setEncryptionFields(encryptedFields);
|
||||
authentication.setIsEncrypted(true);
|
||||
}
|
||||
}
|
||||
return authentication;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Datasource> validateDatasource(Datasource datasource) {
|
||||
Set<String> invalids = new HashSet<>();
|
||||
|
|
@ -318,22 +279,18 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
|||
*/
|
||||
@Override
|
||||
public Mono<DatasourceTestResult> testDatasource(Datasource datasource) {
|
||||
Mono<Datasource> datasourceMono = null;
|
||||
Mono<Datasource> datasourceMono = Mono.just(datasource);
|
||||
// Fetch any fields that maybe encrypted from the db if the datasource being tested does not have those fields set.
|
||||
// This scenario would happen whenever an existing datasource is being tested and no changes are present in the
|
||||
// encrypted field (because encrypted fields are not sent over the network after encryption back to the client
|
||||
if (datasource.getId() != null && datasource.getDatasourceConfiguration() != null &&
|
||||
datasource.getDatasourceConfiguration().getAuthentication() != null) {
|
||||
Set<String> emptyFields = datasource.getDatasourceConfiguration().getAuthentication().getEmptyEncryptionFields();
|
||||
if (emptyFields != null && !emptyFields.isEmpty()) {
|
||||
|
||||
datasourceMono = getById(datasource.getId())
|
||||
.switchIfEmpty(Mono.just(datasource));
|
||||
}
|
||||
}
|
||||
|
||||
if (datasourceMono == null) {
|
||||
datasourceMono = Mono.just(datasource);
|
||||
datasourceMono = getById(datasource.getId())
|
||||
.map(datasource1 -> {
|
||||
BeanCopyUtils.copyNestedNonNullProperties(datasource, datasource1);
|
||||
return datasource1;
|
||||
})
|
||||
.switchIfEmpty(Mono.just(datasource));
|
||||
}
|
||||
|
||||
return datasourceMono
|
||||
|
|
@ -426,19 +383,4 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
|||
.flatMap(toDelete -> repository.archive(toDelete).thenReturn(toDelete))
|
||||
.flatMap(analyticsService::sendDeleteEvent);
|
||||
}
|
||||
|
||||
private AuthenticationDTO decryptSensitiveFields(AuthenticationDTO authentication) {
|
||||
if (authentication != null && Boolean.TRUE.equals(authentication.isEncrypted())) {
|
||||
Map<String, String> decryptedFields = authentication.getEncryptionFields().entrySet().stream()
|
||||
.filter(e -> e.getValue() != null)
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> encryptionService.decryptString(e.getValue())));
|
||||
authentication.setEncryptionFields(decryptedFields);
|
||||
authentication.setIsEncrypted(false);
|
||||
}
|
||||
return authentication;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.appsmith.external.helpers.MustacheHelper;
|
|||
import com.appsmith.external.models.ActionConfiguration;
|
||||
import com.appsmith.external.models.ActionExecutionRequest;
|
||||
import com.appsmith.external.models.ActionExecutionResult;
|
||||
import com.appsmith.external.models.AuthenticationDTO;
|
||||
import com.appsmith.external.models.Param;
|
||||
import com.appsmith.external.models.Policy;
|
||||
import com.appsmith.external.models.Provider;
|
||||
|
|
@ -243,17 +242,6 @@ public class NewActionServiceImpl extends BaseService<NewActionRepository, NewAc
|
|||
|
||||
Mono<Datasource> datasourceMono;
|
||||
if (action.getDatasource().getId() == null) {
|
||||
if (action.getDatasource().getDatasourceConfiguration() != null &&
|
||||
action.getDatasource().getDatasourceConfiguration().getAuthentication() != null) {
|
||||
action.getDatasource()
|
||||
.getDatasourceConfiguration()
|
||||
.setAuthentication(datasourceService.encryptAuthenticationFields(action
|
||||
.getDatasource()
|
||||
.getDatasourceConfiguration()
|
||||
.getAuthentication()
|
||||
));
|
||||
}
|
||||
|
||||
datasourceMono = Mono.just(action.getDatasource())
|
||||
.flatMap(datasourceService::validateDatasource);
|
||||
} else {
|
||||
|
|
@ -540,13 +528,6 @@ public class NewActionServiceImpl extends BaseService<NewActionRepository, NewAc
|
|||
// Set the action name
|
||||
actionName.set(action.getName());
|
||||
|
||||
// If authentication exists for the datasource, decrypt the fields
|
||||
if (datasource.getDatasourceConfiguration() != null &&
|
||||
datasource.getDatasourceConfiguration().getAuthentication() != null) {
|
||||
AuthenticationDTO authentication = datasource.getDatasourceConfiguration().getAuthentication();
|
||||
datasource.getDatasourceConfiguration().setAuthentication(datasourceContextService.decryptSensitiveFields(authentication));
|
||||
}
|
||||
|
||||
ActionConfiguration actionConfiguration = action.getActionConfiguration();
|
||||
|
||||
Integer timeoutDuration = actionConfiguration.getTimeoutInMillisecond();
|
||||
|
|
@ -562,12 +543,6 @@ public class NewActionServiceImpl extends BaseService<NewActionRepository, NewAc
|
|||
.flatMap(datasourceContextService::getDatasourceContext)
|
||||
// Now that we have the context (connection details), execute the action.
|
||||
.flatMap(resourceContext -> validatedDatasourceMono.flatMap(datasource1 -> {
|
||||
// Check encryption again
|
||||
if (datasource1.getDatasourceConfiguration() != null &&
|
||||
datasource1.getDatasourceConfiguration().getAuthentication() != null) {
|
||||
AuthenticationDTO authentication = datasource1.getDatasourceConfiguration().getAuthentication();
|
||||
datasource1.getDatasourceConfiguration().setAuthentication(datasourceContextService.decryptSensitiveFields(authentication));
|
||||
}
|
||||
return (Mono<ActionExecutionResult>) pluginExecutor.executeParameterized(
|
||||
resourceContext.getConnection(),
|
||||
executeActionDTO,
|
||||
|
|
|
|||
|
|
@ -388,7 +388,6 @@ public class AuthenticationService {
|
|||
datasource.getDatasourceConfiguration() != null &&
|
||||
datasource.getDatasourceConfiguration().getAuthentication() instanceof OAuth2);
|
||||
OAuth2 oAuth2 = (OAuth2) datasource.getDatasourceConfiguration().getAuthentication();
|
||||
assert (!oAuth2.isEncrypted());
|
||||
return pluginService.findById(datasource.getPluginId())
|
||||
.filter(plugin -> PluginType.SAAS.equals(plugin.getType()))
|
||||
.zipWith(configService.getInstanceId())
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package com.appsmith.server.solutions;
|
|||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.StaleConnectionException;
|
||||
import com.appsmith.external.models.AuthenticationDTO;
|
||||
import com.appsmith.external.models.DatasourceStructure;
|
||||
import com.appsmith.external.plugins.PluginExecutor;
|
||||
import com.appsmith.external.services.EncryptionService;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.domains.Datasource;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
|
|
@ -14,7 +14,6 @@ import com.appsmith.server.helpers.PluginExecutorHelper;
|
|||
import com.appsmith.server.repositories.CustomDatasourceRepository;
|
||||
import com.appsmith.server.services.DatasourceContextService;
|
||||
import com.appsmith.server.services.DatasourceService;
|
||||
import com.appsmith.external.services.EncryptionService;
|
||||
import com.appsmith.server.services.PluginService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -23,9 +22,7 @@ import org.springframework.util.CollectionUtils;
|
|||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
|
|
@ -78,8 +75,6 @@ public class DatasourceStructureSolution {
|
|||
return Mono.just(datasource.getStructure());
|
||||
}
|
||||
|
||||
decryptEncryptedFieldsInDatasource(datasource);
|
||||
|
||||
// This mono, when computed, will load the structure of the datasource by calling the plugin method.
|
||||
return pluginExecutorHelper
|
||||
.getPluginExecutor(pluginService.findById(datasource.getPluginId()))
|
||||
|
|
@ -130,23 +125,4 @@ public class DatasourceStructureSolution {
|
|||
: datasourceRepository.saveStructure(datasource.getId(), structure).thenReturn(structure)
|
||||
);
|
||||
}
|
||||
|
||||
private Datasource decryptEncryptedFieldsInDatasource(Datasource datasource) {
|
||||
// If datasource has encrypted fields, decrypt and set it in the datasource.
|
||||
if (datasource.getDatasourceConfiguration() != null) {
|
||||
AuthenticationDTO authentication = datasource.getDatasourceConfiguration().getAuthentication();
|
||||
if (authentication != null && authentication.isEncrypted()) {
|
||||
Map<String, String> decryptedFields = authentication.getEncryptionFields().entrySet().stream()
|
||||
.filter(e -> e.getValue() != null)
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> encryptionService.decryptString(e.getValue())));
|
||||
authentication.setEncryptionFields(decryptedFields);
|
||||
authentication.setIsEncrypted(false);
|
||||
}
|
||||
}
|
||||
|
||||
return datasource;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -404,9 +404,6 @@ public class ExamplesOrganizationCloner {
|
|||
makePristine(templateDatasource);
|
||||
|
||||
templateDatasource.setOrganizationId(toOrganizationId);
|
||||
if (authentication != null) {
|
||||
datasourceContextService.decryptSensitiveFields(authentication);
|
||||
}
|
||||
|
||||
return createSuffixedDatasource(templateDatasource);
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.appsmith.server.services;
|
|||
|
||||
import com.appsmith.external.models.DBAuth;
|
||||
import com.appsmith.external.models.DatasourceConfiguration;
|
||||
import com.appsmith.external.services.EncryptionService;
|
||||
import com.appsmith.server.acl.AclPermission;
|
||||
import com.appsmith.server.domains.Datasource;
|
||||
import com.appsmith.server.domains.Organization;
|
||||
|
|
@ -10,6 +11,7 @@ import com.appsmith.server.helpers.MockPluginExecutor;
|
|||
import com.appsmith.server.helpers.PluginExecutorHelper;
|
||||
import com.appsmith.server.repositories.OrganizationRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
@ -22,15 +24,13 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@Slf4j
|
||||
public class DatasourceContextServiceTest {
|
||||
|
||||
@Autowired
|
||||
DatasourceContextService datasourceContextService;
|
||||
EncryptionService encryptionService;
|
||||
|
||||
@Autowired
|
||||
OrganizationRepository organizationRepository;
|
||||
|
|
@ -44,7 +44,7 @@ public class DatasourceContextServiceTest {
|
|||
@MockBean
|
||||
PluginExecutorHelper pluginExecutorHelper;
|
||||
|
||||
String orgId = "";
|
||||
String orgId = "";
|
||||
|
||||
@Before
|
||||
@WithUserDetails(value = "api_user")
|
||||
|
|
@ -53,7 +53,6 @@ public class DatasourceContextServiceTest {
|
|||
orgId = testOrg.getId();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void checkDecryptionOfAuthenticationDTOTest() {
|
||||
|
|
@ -73,21 +72,29 @@ public class DatasourceContextServiceTest {
|
|||
datasource.setDatasourceConfiguration(datasourceConfiguration);
|
||||
datasource.setOrganizationId(orgId);
|
||||
|
||||
Mono<Datasource> datasourceMono = pluginMono.map(plugin -> {
|
||||
datasource.setPluginId(plugin.getId());
|
||||
return datasource;
|
||||
}).flatMap(datasourceService::create);
|
||||
final Datasource createdDatasource = pluginMono
|
||||
.map(plugin -> {
|
||||
datasource.setPluginId(plugin.getId());
|
||||
return datasource;
|
||||
})
|
||||
.flatMap(datasourceService::create)
|
||||
.block();
|
||||
|
||||
assert createdDatasource != null;
|
||||
Mono<Datasource> datasourceMono = datasourceService.findById(createdDatasource.getId());
|
||||
|
||||
StepVerifier
|
||||
.create(datasourceMono)
|
||||
.assertNext(savedDatasource -> {
|
||||
DBAuth authentication = (DBAuth) savedDatasource.getDatasourceConfiguration().getAuthentication();
|
||||
DBAuth decryptedAuthentication = (DBAuth) datasourceContextService.decryptSensitiveFields(authentication);
|
||||
assertThat(decryptedAuthentication.getPassword()).isEqualTo(password);
|
||||
Assert.assertEquals(password, authentication.getPassword());
|
||||
DBAuth encryptedAuthentication = (DBAuth) createdDatasource.getDatasourceConfiguration().getAuthentication();
|
||||
Assert.assertEquals(encryptionService.encryptString(password), encryptedAuthentication.getPassword());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "api_user")
|
||||
public void checkDecryptionOfAuthenticationDTONullPassword() {
|
||||
|
|
@ -103,17 +110,24 @@ public class DatasourceContextServiceTest {
|
|||
datasource.setDatasourceConfiguration(datasourceConfiguration);
|
||||
datasource.setOrganizationId(orgId);
|
||||
|
||||
Mono<Datasource> datasourceMono = pluginMono.map(plugin -> {
|
||||
datasource.setPluginId(plugin.getId());
|
||||
return datasource;
|
||||
}).flatMap(datasourceService::create);
|
||||
final Datasource createdDatasource = pluginMono
|
||||
.map(plugin -> {
|
||||
datasource.setPluginId(plugin.getId());
|
||||
return datasource;
|
||||
})
|
||||
.flatMap(datasourceService::create)
|
||||
.block();
|
||||
|
||||
assert createdDatasource != null;
|
||||
Mono<Datasource> datasourceMono = datasourceService.findById(createdDatasource.getId());
|
||||
|
||||
StepVerifier
|
||||
.create(datasourceMono)
|
||||
.assertNext(savedDatasource -> {
|
||||
DBAuth authentication = (DBAuth) savedDatasource.getDatasourceConfiguration().getAuthentication();
|
||||
DBAuth decryptedAuthentication = (DBAuth) datasourceContextService.decryptSensitiveFields(authentication);
|
||||
assertThat(decryptedAuthentication.getPassword()).isNull();
|
||||
Assert.assertNull(authentication.getPassword());
|
||||
DBAuth encryptedAuthentication = (DBAuth) createdDatasource.getDatasourceConfiguration().getAuthentication();
|
||||
Assert.assertNull(encryptedAuthentication.getPassword());
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -611,7 +611,6 @@ public class DatasourceServiceTest {
|
|||
DBAuth authentication = (DBAuth) savedDatasource.getDatasourceConfiguration().getAuthentication();
|
||||
assertThat(authentication.getUsername()).isEqualTo(username);
|
||||
assertThat(authentication.getPassword()).isEqualTo(encryptionService.encryptString(password));
|
||||
assertThat(authentication.isEncrypted()).isTrue();
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
|
@ -645,7 +644,6 @@ public class DatasourceServiceTest {
|
|||
DBAuth authentication = (DBAuth) savedDatasource.getDatasourceConfiguration().getAuthentication();
|
||||
assertThat(authentication.getUsername()).isNull();
|
||||
assertThat(authentication.getPassword()).isNull();
|
||||
assertThat(authentication.isEncrypted()).isNull();
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
|
@ -695,7 +693,6 @@ public class DatasourceServiceTest {
|
|||
|
||||
assertThat(authentication.getUsername()).isEqualTo(username);
|
||||
assertThat(encryptionService.encryptString(password)).isEqualTo(authentication.getPassword());
|
||||
assertThat(authentication.isEncrypted()).isTrue();
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -929,7 +929,8 @@ public class ExamplesOrganizationClonerTests {
|
|||
.thenReturn(targetOrg1);
|
||||
});
|
||||
})
|
||||
.flatMap(this::loadOrganizationData);
|
||||
.flatMap(this::loadOrganizationData)
|
||||
.doOnError(error -> log.error("Error in test", error));
|
||||
|
||||
StepVerifier.create(resultMono)
|
||||
.assertNext(data -> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user