Resolving conflicts with database changes relating with DMPs entities and the new refactored code

This commit is contained in:
Thomas Georgios Giannos 2023-11-20 11:12:45 +02:00
parent 91f7dbd785
commit 75471e5587
15 changed files with 273 additions and 102 deletions

View File

@ -15,7 +15,7 @@ import java.util.UUID;
@Entity
@Table(name = "\"DMPProfile\"")
@Table(name = "\"DmpBlueprint\"")
public class DMPProfile implements DataEntity<DMPProfile, UUID> {
public enum Status {
@ -48,7 +48,7 @@ public class DMPProfile implements DataEntity<DMPProfile, UUID> {
@Id
@GeneratedValue
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
@Column(name = "\"id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID id;
@ -56,22 +56,22 @@ public class DMPProfile implements DataEntity<DMPProfile, UUID> {
private Set<DMP> dmps;
@Column(name = "\"Label\"")
@Column(name = "\"label\"")
private String label;
@Column(name = "\"Definition\"", columnDefinition = "xml", nullable = true)
@Column(name = "\"definition\"", columnDefinition = "xml", nullable = true)
private String definition;
@Column(name = "\"Status\"", nullable = false)
@Column(name = "\"status\"", nullable = false)
private int status;
@Column(name = "\"Created\"")
@Column(name = "\"created_at\"")
@Convert(converter = DateToUTCConverter.class)
private Date created = null;
@Column(name = "\"Modified\"")
@Column(name = "\"updated_at\"")
@Convert(converter = DateToUTCConverter.class)
private Date modified = new Date();

View File

@ -46,46 +46,46 @@ public class DescriptionTemplate implements DataEntity<DescriptionTemplate,UUID>
@Id
@GeneratedValue
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
@Column(name = "\"id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID id;
@Column(name = "\"Label\"", nullable = false)
@Column(name = "\"label\"", nullable = false)
private String label;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "profile")
private Set<Dataset> dataset;
@Column(name = "\"Definition\"", columnDefinition = "xml", nullable = false)
@Column(name = "\"definition\"", columnDefinition = "xml", nullable = false)
private String definition;
@Column(name = "\"Status\"", nullable = false)
@Column(name = "\"status\"", nullable = false)
private Short status;
@Column(name = "\"Created\"")
@Column(name = "\"created_at\"")
@Convert(converter = DateToUTCConverter.class)
private Date created;
@Column(name = "\"Modified\"")
@Column(name = "\"updated_at\"")
@Convert(converter = DateToUTCConverter.class)
private Date modified = new Date();
@Column(name = "\"Description\"")
@Column(name = "\"description\"")
private String description;
@Column(name = "\"GroupId\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
@Column(name = "\"group_id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID groupId;
@Column(name = "\"Version\"", nullable = false)
@Column(name = "\"version\"", nullable = false)
private Short version;
@OneToMany(fetch = FetchType.LAZY)
private Set<DMP> dmps;
@Column(name = "\"Language\"", nullable = false)
@Column(name = "\"language\"", nullable = false)
private String language;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "\"Type\"", nullable = false)
@JoinColumn(name = "\"type\"", nullable = false)
private DescriptionTemplateType type;
@OneToMany(mappedBy = "descriptionTemplate", fetch = FetchType.LAZY)

View File

@ -40,13 +40,13 @@ public class DescriptionTemplateType implements DataEntity<DescriptionTemplateTy
@Id
@GeneratedValue
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
@Column(name = "\"id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID id;
@Column(name = "\"Name\"", nullable = false)
@Column(name = "\"name\"", nullable = false)
private String name;
@Column(name = "\"Status\"", nullable = false)
@Column(name = "\"status\"", nullable = false)
private Short status;
public UUID getId() {

View File

@ -20,29 +20,29 @@ public class EntityDoi implements DataEntity<EntityDoi, UUID> {
}
@Id
@Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
@Column(name = "\"id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID id;
@Enumerated(EnumType.STRING)
@Column(name = "\"EntityType\"", nullable = false)
@Column(name = "\"entity_type\"", nullable = false)
private EntityType entityType;
@Column(name = "\"RepositoryId\"", nullable = false)
@Column(name = "\"repository_id\"", nullable = false)
private String repositoryId;
@Column(name = "\"Doi\"", nullable = false)
@Column(name = "\"doi\"", nullable = false)
private String doi;
@Column(name = "\"CreatedAt\"", nullable = false)
@Column(name = "\"created_at\"", nullable = false)
@Convert(converter = DateToUTCConverter.class)
private Date createdAt;
@Column(name = "\"UpdatedAt\"", nullable = false)
@Column(name = "\"updated_at\"", nullable = false)
@Convert(converter = DateToUTCConverter.class)
private Date updatedAt;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "\"EntityId\"", nullable = false)
@JoinColumn(name = "\"entity_id\"", nullable = false)
private DMP entityId;
public UUID getId() {

View File

@ -16,14 +16,14 @@ public class UserRole implements DataEntity<UserRole, UUID> {
@Id
@GeneratedValue
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "\"Id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
@Column(name = "\"id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID id;
@Column(name = "\"Role\"", nullable = false)
@Column(name = "\"role\"", nullable = false)
private int role;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "\"UserId\"", nullable = false)
@JoinColumn(name = "\"user\"", nullable = false)
private UserInfo userInfo;
public UUID getId() {

View File

@ -21,7 +21,7 @@ public class DMPQuery extends Query<DMP, UUID> {
private String label;
private int version;
private GrantQuery grantQuery;
private UserQuery userQuery;
private OldUserQuery userQuery;
private DatasetQuery datasetQuery;
private List<Integer> statuses;
private Date created;
@ -99,11 +99,11 @@ public class DMPQuery extends Query<DMP, UUID> {
this.modified = modified;
}
public UserQuery getUserQuery() {
public OldUserQuery getUserQuery() {
return userQuery;
}
public void setUserQuery(UserQuery userQuery) {
public void setUserQuery(OldUserQuery userQuery) {
this.userQuery = userQuery;
}

View File

@ -21,7 +21,7 @@ public class GrantQuery extends Query<Grant, UUID> {
private List<Integer> statuses;
private Date created;
private Date modified;
private UserQuery userQuery;
private OldUserQuery userQuery;
public GrantQuery(DatabaseAccessLayer<Grant, UUID> databaseAccessLayer) {
super(databaseAccessLayer);
@ -79,11 +79,11 @@ public class GrantQuery extends Query<Grant, UUID> {
this.modified = modified;
}
public UserQuery getUserQuery() {
public OldUserQuery getUserQuery() {
return userQuery;
}
public void setUserQuery(UserQuery userQuery) {
public void setUserQuery(OldUserQuery userQuery) {
this.userQuery = userQuery;
}

View File

@ -17,7 +17,7 @@ public class LockQuery extends Query<Lock, UUID> {
private UUID id;
private UUID target;
private UserQuery userQuery;
private OldUserQuery userQuery;
private Date touchedAt;
public UUID getId() {
@ -36,11 +36,11 @@ public class LockQuery extends Query<Lock, UUID> {
this.target = target;
}
public UserQuery getUserQuery() {
public OldUserQuery getUserQuery() {
return userQuery;
}
public void setUserQuery(UserQuery userQuery) {
public void setUserQuery(OldUserQuery userQuery) {
this.userQuery = userQuery;
}

View File

@ -7,7 +7,7 @@ import eu.eudat.queryable.QueryableList;
import java.util.List;
import java.util.UUID;
public class UserQuery extends Query<UserInfo, UUID> {
public class OldUserQuery extends Query<UserInfo, UUID> {
private UUID id;
@ -19,11 +19,11 @@ public class UserQuery extends Query<UserInfo, UUID> {
this.id = id;
}
public UserQuery(DatabaseAccessLayer<UserInfo, UUID> databaseAccessLayer) {
public OldUserQuery(DatabaseAccessLayer<UserInfo, UUID> databaseAccessLayer) {
super(databaseAccessLayer);
}
public UserQuery(DatabaseAccessLayer<UserInfo, UUID> databaseAccessLayer, List<String> selectionFields) {
public OldUserQuery(DatabaseAccessLayer<UserInfo, UUID> databaseAccessLayer, List<String> selectionFields) {
super(databaseAccessLayer, selectionFields);
}

View File

@ -27,16 +27,4 @@ public class EuDatApplication extends SpringBootServletInitializer {
SpringApplication.run(EuDatApplication.class, args);
}
@Bean
AuthorizationRequirementMapper authorizationRequirementMapper() {
return (resource, matchAll, permissions) -> {
Class<?> type = resource.getClass();
if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
if (OwnedResource.class.equals(type)) {
return new OwnedAuthorizationRequirement();
}
throw new IllegalArgumentException("resource");
};
}
}

View File

@ -0,0 +1,144 @@
package eu.eudat.configurations;
import eu.eudat.authorization.OwnedAuthorizationRequirement;
import eu.eudat.authorization.OwnedResource;
import gr.cite.commons.web.authz.handler.AuthorizationHandler;
import gr.cite.commons.web.authz.handler.PermissionAuthenticatedAuthorizationHandler;
import gr.cite.commons.web.authz.handler.PermissionClaimAuthorizationHandler;
import gr.cite.commons.web.authz.handler.PermissionClientAuthorizationHandler;
import gr.cite.commons.web.authz.policy.AuthorizationRequirement;
import gr.cite.commons.web.authz.policy.AuthorizationRequirementMapper;
import gr.cite.commons.web.authz.policy.AuthorizationResource;
import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyConfigurer;
import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyResolverStrategy;
import gr.cite.commons.web.oidc.configuration.WebSecurityProperties;
import jakarta.servlet.Filter;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManagerResolver;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import java.util.List;
import java.util.Set;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
private final WebSecurityProperties webSecurityProperties;
private final AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
private final Filter apiKeyFilter;
@Autowired
public SecurityConfiguration(WebSecurityProperties webSecurityProperties,
@Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver,
@Qualifier("apiKeyFilter") Filter apiKeyFilter) {
this.webSecurityProperties = webSecurityProperties;
this.authenticationManagerResolver = authenticationManagerResolver;
this.apiKeyFilter = apiKeyFilter;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
HttpSecurity tempHttp = http
.csrf(AbstractHttpConfigurer::disable)
.cors(httpSecurityCorsConfigurer -> {})
.headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
// .addFilterBefore(apiKeyFilter, AbstractPreAuthenticatedProcessingFilter.class)
.authorizeHttpRequests(authRequest ->
authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).permitAll() //TODO: Authz
.requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).permitAll())
.sessionManagement( sessionManagementConfigurer-> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER))
.oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver));
return tempHttp.build();
}
@Bean
AuthorizationPolicyConfigurer authorizationPolicyConfigurer() {
return new AuthorizationPolicyConfigurer() {
@Override
public AuthorizationPolicyResolverStrategy strategy() {
return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED;
}
//Here you can register your custom authorization handlers, which will get used as well as the existing ones
//This is optional and can be omitted
//If not set / set to null, only the default authorization handlers will be used
@Override
public List<AuthorizationHandler<? extends AuthorizationRequirement>> addCustomHandlers() {
return List.of();
}
//Here you can register your custom authorization requirements (if any)
//This is optional and can be omitted
//If not set / set to null, only the default authorization requirements will be used
@Override
public List<? extends AuthorizationRequirement> extendRequirements() {
return List.of(
// new TimeOfDayAuthorizationRequirement(new TimeOfDay("08:00","16:00"), true)
);
}
//Here you can select handlers you want to disable by providing the classes they are implemented by
//You can disable any handler (including any custom one)
//This is optional and can be omitted
//If not set / set to null, all the handlers will be invoked, based on their requirement support
//In the example below, the default client handler will be ignored by the resolver
@Override
public List<Class<? extends AuthorizationHandler<? extends AuthorizationRequirement>>> disableHandlers() {
return List.of(
PermissionClientAuthorizationHandler.class,
PermissionAuthenticatedAuthorizationHandler.class,
PermissionClaimAuthorizationHandler.class);
}
};
}
@Bean
AuthorizationRequirementMapper authorizationRequirementMapper() {
return new AuthorizationRequirementMapper() {
@Override
public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) {
Class<?> type = resource.getClass();
if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource");
if (OwnedResource.class.equals(type)) {
return new OwnedAuthorizationRequirement();
}
throw new IllegalArgumentException("resource");
}
};
}
private String[] buildAntPatterns(Set<String> endpoints) {
if (endpoints == null) {
return new String[0];
}
return endpoints.stream()
.filter(endpoint -> endpoint != null && !endpoint.isBlank())
.map(endpoint -> "/" + stripUnnecessaryCharacters(endpoint) + "/**")
.toArray(String[]::new);
}
private String stripUnnecessaryCharacters(String endpoint) {
endpoint = endpoint.strip();
if (endpoint.startsWith("/")) {
endpoint = endpoint.substring(1);
}
if (endpoint.endsWith("/")) {
endpoint = endpoint.substring(0, endpoint.length() - 1);
}
return endpoint;
}
}

View File

@ -1,44 +0,0 @@
package eu.eudat.configurations;
import eu.eudat.controllers.interceptors.RequestInterceptor;
import eu.eudat.logic.handlers.PrincipalArgumentResolver;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@EnableAsync
@Configuration
@EnableScheduling
public class WebMVCConfiguration implements WebMvcConfigurer {
private ApiContext apiContext;
private AuthenticationService verifiedUserAuthenticationService;
private AuthenticationService nonVerifiedUserAuthenticationService;
@Autowired
public WebMVCConfiguration(ApiContext apiContext, AuthenticationService verifiedUserAuthenticationService, AuthenticationService nonVerifiedUserAuthenticationService) {
this.apiContext = apiContext;
this.verifiedUserAuthenticationService = verifiedUserAuthenticationService;
this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
}
@Autowired
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new PrincipalArgumentResolver(verifiedUserAuthenticationService, nonVerifiedUserAuthenticationService));
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(new RequestInterceptor(this.apiContext.getHelpersService().getLoggerService()));
}
}

View File

@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import eu.eudat.criteria.entities.Criteria;
import eu.eudat.logic.services.operations.DatabaseRepository;
import eu.eudat.query.OldUserQuery;
import eu.eudat.query.UserQuery;
import java.io.IOException;
@ -57,9 +58,9 @@ public class UserCriteria {
return new LinkedList<>(fields);
}
public UserQuery buildQuery(DatabaseRepository dao) {
public OldUserQuery buildQuery(DatabaseRepository dao) {
List<String> fields = this.buildFields("");
UserQuery query = new UserQuery(dao.getUserInfoDao(), fields);
OldUserQuery query = new OldUserQuery(dao.getUserInfoDao(), fields);
if (this.id != null) query.setId(this.id.getValue());
return query;
}

View File

@ -316,6 +316,88 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
return this;
}
public DataManagementPlan fromDataModelWithoutUsers(DMP entity) {
this.id = entity.getId();
this.profile = entity.getProfile() != null ? new Tuple<UUID, String>(entity.getProfile().getId(), entity.getProfile().getLabel()) : null;
this.organisations = entity.getOrganisations() != null ? entity.getOrganisations().stream().map(item -> new Organisation().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>();
this.researchers = entity.getResearchers() != null ? entity.getResearchers().stream().map(item -> new Researcher().fromDataModel(item)).collect(Collectors.toList()): new ArrayList<>();
this.version = entity.getVersion();
this.groupId = this.groupId == null ? null : entity.getGroupId();
this.label = entity.getLabel();
this.properties = entity.getProperties() != null ? new org.json.JSONObject(entity.getProperties()).toMap() : null;
if(entity.getGrant() != null) {
this.grant = new Grant();
this.grant.fromDataModel(entity.getGrant());
}
else {
this.grant = null;
}
this.creator = new eu.eudat.models.data.userinfo.UserInfo();
this.groupId = entity.getGroupId();
this.lockable = entity.getDataset() != null && entity.getDataset().stream().findAny().isPresent();
if (this.properties != null) {
this.extraFields = new ArrayList<>();
this.properties.forEach((id, value) -> {
if (value != null) {
ExtraFieldModel extraField = new ExtraFieldModel();
extraField.setId(id);
extraField.setValue(value.toString());
this.extraFields.add(extraField);
}
});
}
if (entity.getUsers() != null && entity.getUsers().stream().anyMatch(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())))
this.creator.fromDataModel(entity.getUsers().stream().filter(user -> user.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser());
if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) {
this.profiles = new LinkedList<>();
for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile());
associatedProfile.setId(dmpDescriptionProfile.getId());
try {
associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference<Map<String, Object>>() {}));
}
catch (Exception e) {
associatedProfile.setData(null);
}
this.profiles.add(associatedProfile);
}
}
if (entity.getDataset() != null) {
if (entity.isPublic()) {
this.datasets = entity.getDataset().stream()
.filter(dataset -> !dataset.getStatus().equals(Dataset.Status.DELETED.getValue()) && !dataset.getStatus().equals(Dataset.Status.CANCELED.getValue()) && !dataset.getStatus().equals(Dataset.Status.SAVED.getValue()))
.map(x -> new DatasetWizardModel().fromDataModelNoDmp(x)).collect(Collectors.toList());
} else {
this.datasets = entity.getDataset().stream()
.filter(dataset -> !dataset.getStatus().equals(Dataset.Status.DELETED.getValue()) && !dataset.getStatus().equals(Dataset.Status.CANCELED.getValue()))
.map(x -> new DatasetWizardModel().fromDataModelNoDmp(x)).collect(Collectors.toList());
}
}
this.modified = entity.getModified();
this.created = entity.getCreated();
this.description = entity.getDescription();
this.status = entity.getStatus();
this.associatedUsers = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserListingModel().fromDataModel(item.getUser())).collect(Collectors.toList()) : new ArrayList<>();
this.users = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserInfoListingModel().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>();
this.dois = entity.getDois() != null ? entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList()): new ArrayList<>();
if (entity.getProject() != null) {
this.project = new Project();
this.project = new Project().fromDataModel(entity.getProject());
}
if (entity.getGrant() != null && entity.getGrant().getFunder() != null) {
this.funder = new Funder();
this.funder.fromDataModel(entity.getGrant().getFunder());
}
this.isPublic = entity.isPublic();
this.extraProperties = entity.getExtraProperties() != null ? new org.json.JSONObject(entity.getExtraProperties()).toMap() : null;
return this;
}
@Override
public DMP toDataModel() throws Exception {
DMP dataManagementPlanEntity = new DMP();

View File

@ -2,7 +2,7 @@ web:
security:
enabled: true
authorized-endpoints: [ api ]
allowed-endpoints: [ api/public, api/description/public ]
allowed-endpoints: [ error, api/public, api/description/public ]
idp:
api-key:
enabled: true