From 01bb47e823e92d4df390ed813e117a82a6f0d91d Mon Sep 17 00:00:00 2001
From: Martin Weise <martin.weise@tuwien.ac.at>
Date: Fri, 21 Apr 2023 21:37:37 +0200
Subject: [PATCH] WIP

- frontend still missing unique column constraints form
---
 Makefile                                      | 19 +++++++++
 .../tuwien/endpoints/ContainerEndpoint.java   |  2 +-
 .../service/impl/ContainerServiceImpl.java    |  4 +-
 .../at/tuwien/endpoints/DatabaseEndpoint.java |  8 ++--
 .../at/tuwien/mapper/IdentifierMapper.java    |  1 -
 .../service/impl/MariaDbServiceImpl.java      |  7 ++--
 .../tuwien/endpoints/IdentifierEndpoint.java  |  2 +-
 .../service/impl/IdentifierServiceImpl.java   |  6 +--
 .../at/tuwien/api/database/ViewBriefDto.java  |  3 +-
 .../java/at/tuwien/api/database/ViewDto.java  |  3 +-
 .../api/database/query/QueryBriefDto.java     |  3 +-
 .../tuwien/api/database/query/QueryDto.java   |  6 +--
 .../tuwien/entities/container/Container.java  | 16 +++++++-
 .../at/tuwien/entities/database/Database.java | 26 ++++++++++--
 .../entities/database/DatabaseAccess.java     |  2 +
 .../at/tuwien/entities/database/View.java     |  9 +++-
 .../tuwien/entities/database/table/Table.java |  8 +++-
 .../database/table/columns/TableColumn.java   |  9 +++-
 .../tuwien/entities/identifier/Creator.java   |  9 +++-
 .../entities/identifier/Identifier.java       |  9 +++-
 .../identifier/RelatedIdentifier.java         |  9 +++-
 .../at/tuwien/entities/user/Credential.java   |  3 ++
 .../java/at/tuwien/entities/user/Realm.java   |  4 ++
 .../java/at/tuwien/entities/user/Role.java    |  4 ++
 .../at/tuwien/entities/user/RoleMapping.java  |  3 ++
 .../java/at/tuwien/entities/user/User.java    | 41 +++++++++++++++++--
 .../tuwien/entities/user/UserAttribute.java   |  3 ++
 .../main/java/at/tuwien/test/BaseTest.java    |  4 +-
 .../at/tuwien/endpoint/ExportEndpoint.java    |  4 +-
 .../at/tuwien/endpoint/QueryEndpoint.java     | 10 ++---
 .../java/at/tuwien/endpoint/ViewEndpoint.java |  8 ++--
 .../java/at/tuwien/mapper/ViewMapper.java     |  3 --
 .../tuwien/service/impl/ViewServiceImpl.java  |  2 +-
 .../java/at/tuwien/mapper/TableMapper.java    |  1 +
 .../tuwien/service/impl/TableServiceImpl.java |  2 +-
 dbrepo-ui/api/middleware.service.js           |  8 ++--
 dbrepo-ui/components/DBToolbar.vue            |  8 ++--
 dbrepo-ui/components/EMPTY.vue                | 23 -----------
 dbrepo-ui/components/TableToolbar.vue         | 12 +++---
 .../database/_database_id/table/import.vue    | 11 ++---
 dbrepo-user-service/Dockerfile                |  2 +-
 dbrepo-user-service/pom.xml                   |  6 +++
 .../java/at/tuwien/endpoint/UserEndpoint.java | 23 ++++++++---
 .../src/main/resources/application-local.yml  |  4 ++
 .../src/main/resources/application.yml        |  4 ++
 .../src/test/java/at/tuwien/BaseUnitTest.java |  9 ++++
 .../java/at/tuwien/mapper/UserMapperTest.java | 40 ++++++++++++++++++
 .../java/at/tuwien/config/GatewayConfig.java  | 16 ++++++++
 .../java/at/tuwien/mapper/UserMapper.java     |  2 +-
 .../tuwien/service/impl/UserServiceImpl.java  |  9 ++--
 50 files changed, 317 insertions(+), 113 deletions(-)
 delete mode 100644 dbrepo-ui/components/EMPTY.vue
 create mode 100644 dbrepo-user-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java
 create mode 100644 dbrepo-user-service/rest-service/src/test/java/at/tuwien/mapper/UserMapperTest.java

diff --git a/Makefile b/Makefile
index af0b593ed7..2b252e8475 100644
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,25 @@ build-docker:
 	docker compose build dbrepo-metadata-db
 	docker compose build --parallel
 
+build-docker-slow:
+	docker compose build dbrepo-analyse-service
+	docker compose build dbrepo-authentication-service
+	docker compose build dbrepo-broker-service
+	docker compose build dbrepo-metadata-db
+	docker compose build dbrepo-container-service
+	docker compose build dbrepo-database-service
+	docker compose build dbrepo-discovery-service
+	docker compose build dbrepo-gateway-service
+	docker compose build dbrepo-identifier-service
+	docker compose build dbrepo-metadata-service
+	docker compose build dbrepo-proxy
+	docker compose build dbrepo-query-service
+	docker compose build dbrepo-search-service
+	docker compose build dbrepo-semantics-service
+	docker compose build dbrepo-table-service
+	docker compose build dbrepo-ui
+	docker compose build dbrepo-user-service
+
 build-frontend:
 	yarn --cwd ./dbrepo-ui install --legacy-peer-deps
 	yarn --cwd ./dbrepo-ui run build
diff --git a/dbrepo-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java b/dbrepo-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java
index 0c9cf4e4a6..38d02adb7b 100644
--- a/dbrepo-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java
+++ b/dbrepo-container-service/rest-service/src/main/java/at/tuwien/endpoints/ContainerEndpoint.java
@@ -245,7 +245,7 @@ public class ContainerEndpoint {
     })
     public ResponseEntity<?> delete(@NotNull @PathVariable("id") Long containerId,
                                     @NotNull Principal principal) throws ContainerNotFoundException,
-            ContainerStillRunningException, ContainerAlreadyRemovedException, DockerClientException {
+            ContainerStillRunningException, ContainerAlreadyRemovedException {
         log.debug("endpoint delete container, containerId={}, principal={}", containerId, principal);
         containerService.remove(containerId);
         return ResponseEntity.accepted()
diff --git a/dbrepo-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java b/dbrepo-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java
index 34d1b40739..124a27ebda 100644
--- a/dbrepo-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java
+++ b/dbrepo-container-service/services/src/main/java/at/tuwien/service/impl/ContainerServiceImpl.java
@@ -99,8 +99,8 @@ public class ContainerServiceImpl implements ContainerService {
                 response.getName() + ":/var/lib/mysql", availableTcpPort + ":" + image.get().getDefaultPort());
         log.trace("host config {}", hostConfig);
         final User user = userService.findByUsername(principal.getName());
-        container.setCreator(user);
-        container.setOwner(user);
+        container.setCreatedBy(user.getId());
+        container.setOwnedBy(user.getId());
         /* create the container */
         final CreateContainerResponse response1;
         try {
diff --git a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
index b2c23b9183..f44d81db88 100644
--- a/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
+++ b/dbrepo-database-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseEndpoint.java
@@ -148,7 +148,7 @@ public class DatabaseEndpoint {
                 principal);
         final Container container = containerService.find(containerId);
         final User user = userService.findByUsername(principal.getName());
-        if (!container.getOwner().getId().equals(user.getId())) {
+        if (!container.getOwner().equals(user)) {
             log.error("Failed to create database: not owner");
             throw new NotAllowedException(("Failed to create database: not owner"));
         }
@@ -195,7 +195,7 @@ public class DatabaseEndpoint {
                 databaseId, data, principal);
         final Database database = databaseService.findById(containerId, databaseId);
         final User user = userService.findByUsername(principal.getName());
-        if (!database.getOwner().getId().equals(user.getId())) {
+        if (!database.getOwner().equals(user)) {
             log.error("Failed to create database: not owner");
             throw new NotAllowedException(("Failed to create database: not owner"));
         }
@@ -236,7 +236,7 @@ public class DatabaseEndpoint {
                 databaseId, transferDto, principal);
         final Database database = databaseService.findById(containerId, databaseId);
         final User user = userService.findByUsername(principal.getName());
-        if (!database.getOwner().getId().equals(user.getId())) {
+        if (!database.getOwner().equals(user)) {
             log.error("Failed to create database: not owner");
             throw new NotAllowedException(("Failed to create database: not owner"));
         }
@@ -274,7 +274,7 @@ public class DatabaseEndpoint {
         log.debug("endpoint find database, containerId={}, databaseId={}", containerId, databaseId);
         final Database database = databaseService.findById(containerId, databaseId);
         final DatabaseDto dto = databaseMapper.databaseToDatabaseDto(database);
-        if (principal != null && database.getOwner().getUsername().equals(principal.getName())) {
+        if (principal != null && database.getOwner().equals(principal)) {
             /* only owner sees the access rights */ // TODO improve this by proper mapping
             final List<DatabaseAccess> accesses = accessService.list(databaseId);
             dto.setAccesses(accesses.stream()
diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/IdentifierMapper.java b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/IdentifierMapper.java
index c390464c5e..86a2ab27e3 100644
--- a/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/IdentifierMapper.java
+++ b/dbrepo-database-service/services/src/main/java/at/tuwien/mapper/IdentifierMapper.java
@@ -5,7 +5,6 @@ import at.tuwien.api.identifier.IdentifierDto;
 import at.tuwien.entities.identifier.Identifier;
 import org.mapstruct.Mapper;
 
-
 @Mapper(componentModel = "spring")
 public interface IdentifierMapper {
 
diff --git a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java
index 75b54f4fe7..69b821408c 100644
--- a/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java
+++ b/dbrepo-database-service/services/src/main/java/at/tuwien/service/impl/MariaDbServiceImpl.java
@@ -133,8 +133,9 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe
         database.setId(containerId);
         database.setContainer(container);
         final User owner = userService.findByUsername(principal.getName());
-        database.setCreator(owner);
-        database.setOwner(owner);
+        database.setOwnedBy(owner.getId());
+        database.setCreatedBy(owner.getId());
+        database.setContactPerson(owner.getId());
         database.setExchangeName("dbrepo." + database.getInternalName());
         final ComboPooledDataSource dataSource = getDataSource(container.getImage(), container, root);
         try {
@@ -185,7 +186,7 @@ public class MariaDbServiceImpl extends HibernateConnector implements DatabaseSe
         final Database entity = findById(containerId, databaseId);
         final User user = userService.findByUsername(transferDto.getUsername());
         /* update in metadata database */
-        entity.setOwner(user);
+        entity.setOwnedBy(user.getId());
         databaseIdxRepository.save(databaseMapper.databaseToDatabaseDto(entity));
         log.info("Updated database in elastic search with id {}", entity.getId());
         return entity;
diff --git a/dbrepo-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java b/dbrepo-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
index fab253577a..f92574b85f 100644
--- a/dbrepo-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
+++ b/dbrepo-identifier-service/rest-service/src/main/java/at/tuwien/endpoints/IdentifierEndpoint.java
@@ -174,7 +174,7 @@ public class IdentifierEndpoint {
     })
     public ResponseEntity<IdentifierDto> update(@NotNull @PathVariable("id") Long id,
                                                 @NotNull @Valid @RequestBody IdentifierDto data)
-            throws IdentifierPublishingNotAllowedException, IdentifierNotFoundException, IdentifierRequestException {
+            throws IdentifierNotFoundException, IdentifierRequestException {
         log.debug("endpoint update identifier, id={}, data={}", id, data);
         final Identifier identifier = identifierService.update(id, data);
         return ResponseEntity.accepted()
diff --git a/dbrepo-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java b/dbrepo-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
index f33ff8911b..f5a94274b6 100644
--- a/dbrepo-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
+++ b/dbrepo-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
@@ -116,7 +116,7 @@ public class IdentifierServiceImpl implements IdentifierService {
         tmp.setContainerId(data.getCid());
         tmp.setDatabaseId(data.getDbid());
         final User creator = userService.findByUsername(principal.getName());
-        tmp.setCreator(creator);
+        tmp.setCreatedBy(creator.getId());
         tmp.setCreators(List.of());
         if (data.getType().equals(IdentifierTypeDto.SUBSET)) {
             log.debug("identifier describes a subset");
@@ -136,7 +136,7 @@ public class IdentifierServiceImpl implements IdentifierService {
                 .map(c -> {
                     final Creator creatorDto = identifierMapper.creatorCreateDtoToCreator(c);
                     creatorDto.setPid(entity.getId());
-                    creatorDto.setCreator(creator);
+                    creatorDto.setCreatedBy(creator.getId());
                     return creatorDto;
                 })
                 .collect(Collectors.toList()));
@@ -146,7 +146,7 @@ public class IdentifierServiceImpl implements IdentifierService {
                     .forEach(r -> {
                         final RelatedIdentifier id = identifierMapper.relatedIdentifierCreateDtoToRelatedIdentifier(r);
                         id.setIid(entity.getId());
-                        id.setCreator(creator);
+                        id.setCreatedBy(creator.getId());
                         final RelatedIdentifier relatedIdentifier = relatedIdentifierRepository.save(id);
                         log.debug("identifier add related with id {}", relatedIdentifier.getId());
                         entity.getRelated().add(relatedIdentifier);
diff --git a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewBriefDto.java b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewBriefDto.java
index ab1c9766c2..ee656d297b 100644
--- a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewBriefDto.java
+++ b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewBriefDto.java
@@ -10,6 +10,7 @@ import lombok.*;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import java.time.Instant;
+import java.util.UUID;
 
 @Getter
 @Setter
@@ -52,7 +53,7 @@ public class ViewBriefDto {
     private Instant created;
 
     @JsonIgnore
-    private String createdBy;
+    private UUID createdBy;
 
     @NotNull
     private UserDto creator;
diff --git a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewDto.java b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewDto.java
index 3a7e78863f..867e83e771 100644
--- a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewDto.java
+++ b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/ViewDto.java
@@ -11,6 +11,7 @@ import org.springframework.data.elasticsearch.annotations.Document;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import java.time.Instant;
+import java.util.UUID;
 
 @Getter
 @Setter
@@ -57,7 +58,7 @@ public class ViewDto {
     private Instant created;
 
     @JsonIgnore
-    private String createdBy;
+    private UUID createdBy;
 
     @NotNull
     private UserDto creator;
diff --git a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java
index 895bf93ab0..3f641f1a1c 100644
--- a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java
+++ b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryBriefDto.java
@@ -13,6 +13,7 @@ import lombok.*;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import java.time.Instant;
+import java.util.UUID;
 
 
 @Getter
@@ -35,7 +36,7 @@ public class QueryBriefDto {
 
     @JsonIgnore
     @NotNull(message = "created by is required")
-    private String createdBy;
+    private UUID createdBy;
 
     @NotNull(message = "creator is required")
     private UserDto creator;
diff --git a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java
index d35bb51d7c..db5cb11fb7 100644
--- a/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java
+++ b/dbrepo-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java
@@ -5,15 +5,13 @@ import at.tuwien.api.user.UserDto;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
 
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import java.time.Instant;
+import java.util.UUID;
 
 
 @Getter
@@ -37,7 +35,7 @@ public class QueryDto {
     @JsonIgnore
     @EqualsAndHashCode.Exclude
     @NotNull(message = "created by is required")
-    private String createdBy;
+    private UUID createdBy;
 
     @NotNull(message = "creator is required")
     private UserDto creator;
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java
index b429c943a8..9fb7d40bbf 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/container/Container.java
@@ -6,12 +6,14 @@ import at.tuwien.entities.user.User;
 import com.github.dockerjava.api.model.HealthCheck;
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
 import java.time.Instant;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -31,15 +33,25 @@ public class Container {
     @Column(updatable = false, nullable = false)
     private Long id;
 
+    @ToString.Exclude
+    @Column(name = "createdBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "createdBy", referencedColumnName = "ID")
+            @JoinColumn(name = "createdBy", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User creator;
 
+    @ToString.Exclude
+    @Column(name = "ownedBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID ownedBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "ownedBy", referencedColumnName = "ID")
+            @JoinColumn(name = "ownedBy", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User owner;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java
index 9615cbae1d..c02cf1a3ca 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/Database.java
@@ -16,6 +16,7 @@ import javax.persistence.Entity;
 import java.io.Serializable;
 import java.time.Instant;
 import java.util.List;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -34,15 +35,26 @@ public class Database implements Serializable {
     @Column(updatable = false, nullable = false)
     private Long id;
 
+    @ToString.Exclude
+    @Column(name = "created_by", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
+    @Type(type = "uuid-char")
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "created_by", referencedColumnName = "ID")
+            @JoinColumn(name = "created_by", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User creator;
 
-    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+    @ToString.Exclude
+    @Column(name = "owned_by", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID ownedBy;
+
+    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "owned_by", referencedColumnName = "ID")
+            @JoinColumn(name = "owned_by", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User owner;
 
@@ -66,9 +78,15 @@ public class Database implements Serializable {
     @Column(columnDefinition = "TEXT")
     private String description;
 
+    @ToString.Exclude
+    @Column(name = "contact_person", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID contactPerson;
+
+    @Type(type = "uuid-char")
     @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "contact_person", referencedColumnName = "ID")
+            @JoinColumn(name = "contact_person", referencedColumnName = "ID", updatable = false, insertable = false)
     })
     private User contact;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/DatabaseAccess.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/DatabaseAccess.java
index 5f6e684785..19d71711fe 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/DatabaseAccess.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/DatabaseAccess.java
@@ -2,6 +2,7 @@ package at.tuwien.entities.database;
 
 import at.tuwien.entities.user.User;
 import lombok.*;
+import org.hibernate.annotations.Type;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
@@ -21,6 +22,7 @@ import java.util.UUID;
 public class DatabaseAccess {
 
     @Id
+    @Type(type = "uuid-char")
     @EqualsAndHashCode.Include
     @Column(name = "user_id", updatable = false, columnDefinition = "VARCHAR(36)")
     private UUID huserid;
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/View.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/View.java
index 16fd29e30d..90cca36bed 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/View.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/View.java
@@ -5,6 +5,7 @@ import at.tuwien.entities.user.User;
 import lombok.*;
 import net.sf.jsqlparser.statement.select.FromItem;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.elasticsearch.annotations.Document;
@@ -13,6 +14,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 import javax.persistence.*;
 import java.time.Instant;
 import java.util.List;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -40,9 +42,14 @@ public class View {
     @EqualsAndHashCode.Include
     private Long vdbid;
 
+    @ToString.Exclude
+    @Column(name = "createdBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "createdBy", referencedColumnName = "ID")
+            @JoinColumn(name = "createdBy", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User creator;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/Table.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/Table.java
index 0840dca2e7..6b9ee532fc 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/Table.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/Table.java
@@ -7,6 +7,7 @@ import at.tuwien.entities.user.User;
 import lombok.*;
 import net.sf.jsqlparser.statement.select.FromItem;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.elasticsearch.annotations.Document;
@@ -41,9 +42,14 @@ public class Table {
     @EqualsAndHashCode.Include
     private Long tdbid;
 
+    @ToString.Exclude
+    @Column(name = "createdBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "createdBy", referencedColumnName = "ID", columnDefinition = "VARCHAR(36)")
+            @JoinColumn(name = "createdBy", referencedColumnName = "ID", updatable = false, insertable = false)
     })
     private User creator;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java
index 871070728e..1c95089830 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java
@@ -6,6 +6,7 @@ import at.tuwien.entities.user.User;
 import lombok.*;
 import net.sf.jsqlparser.statement.select.SelectItem;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@@ -13,6 +14,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 import javax.persistence.*;
 import java.time.Instant;
 import java.util.List;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -58,9 +60,14 @@ public class TableColumn implements Comparable<TableColumn> {
     })
     private Table table;
 
+    @ToString.Exclude
+    @Column(name = "createdBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "createdBy", referencedColumnName = "ID")
+            @JoinColumn(name = "createdBy", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User creator;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Creator.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Creator.java
index 51492e8ba5..2b0a720cb7 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Creator.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Creator.java
@@ -3,12 +3,14 @@ package at.tuwien.entities.identifier;
 import at.tuwien.entities.user.User;
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
 import java.time.Instant;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -54,9 +56,14 @@ public class Creator {
     @CreatedDate
     private Instant created;
 
+    @ToString.Exclude
+    @Column(name = "createdBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "createdBy", referencedColumnName = "ID")
+            @JoinColumn(name = "createdBy", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User creator;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java
index fb857a53db..66a68c8ff7 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/Identifier.java
@@ -6,6 +6,7 @@ import at.tuwien.entities.database.License;
 import at.tuwien.entities.user.User;
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@@ -15,6 +16,7 @@ import javax.validation.constraints.NotBlank;
 import java.io.Serializable;
 import java.time.Instant;
 import java.util.List;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -44,9 +46,14 @@ public class Identifier implements Serializable {
     @Column(name = "qid")
     private Long queryId;
 
+    @ToString.Exclude
+    @Column(name = "createdBy", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
     @JoinColumns({
-            @JoinColumn(name = "createdBy", referencedColumnName = "ID")
+            @JoinColumn(name = "createdBy", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User creator;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java
index 9cb1c0ad1e..aed2577656 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/identifier/RelatedIdentifier.java
@@ -4,6 +4,7 @@ import at.tuwien.entities.user.User;
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
 import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.Type;
 import org.hibernate.annotations.Where;
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
@@ -11,6 +12,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
 import java.time.Instant;
+import java.util.UUID;
 
 @Data
 @Entity
@@ -48,9 +50,14 @@ public class RelatedIdentifier {
     @Enumerated(EnumType.STRING)
     private RelationType relation;
 
+    @ToString.Exclude
+    @Column(name = "created_by", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
+    private UUID createdBy;
+
     @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
     @JoinColumns({
-            @JoinColumn(name = "created_by", referencedColumnName = "ID")
+            @JoinColumn(name = "created_by", referencedColumnName = "ID", insertable = false, updatable = false)
     })
     private User creator;
 
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Credential.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Credential.java
index a422eed5e9..85dafd353d 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Credential.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Credential.java
@@ -2,6 +2,7 @@ package at.tuwien.entities.user;
 
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
@@ -21,12 +22,14 @@ public class Credential {
     @Id
     @EqualsAndHashCode.Include
     @Column(name = "ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID id;
 
     @Column(nullable = false)
     private String type;
 
     @Column(name = "user_id", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID userId;
 
     @Column(nullable = false)
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Realm.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Realm.java
index 96ba2ec661..3890974c2e 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Realm.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Realm.java
@@ -2,6 +2,8 @@ package at.tuwien.entities.user;
 
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Immutable;
+import org.hibernate.annotations.Type;
 
 import javax.persistence.*;
 import java.util.List;
@@ -13,6 +15,7 @@ import java.util.UUID;
 @AllArgsConstructor
 @NoArgsConstructor
 @ToString
+@Immutable
 @EqualsAndHashCode(onlyExplicitlyIncluded = true)
 @Table(name = "realm")
 @NamedQueries({
@@ -23,6 +26,7 @@ public class Realm {
     @Id
     @EqualsAndHashCode.Include
     @Column(name = "ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID id;
 
     @Column(nullable = false)
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Role.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Role.java
index 5d25bce86b..a06563f1d6 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Role.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/Role.java
@@ -2,6 +2,8 @@ package at.tuwien.entities.user;
 
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Immutable;
+import org.hibernate.annotations.Type;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
@@ -13,6 +15,7 @@ import java.util.UUID;
 @AllArgsConstructor
 @NoArgsConstructor
 @ToString
+@Immutable
 @EntityListeners(AuditingEntityListener.class)
 @EqualsAndHashCode(onlyExplicitlyIncluded = true)
 @Table(name = "keycloak_role")
@@ -21,6 +24,7 @@ public class Role {
     @Id
     @EqualsAndHashCode.Include
     @Column(name = "ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID id;
 
     @Column(name = "NAME", nullable = false)
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/RoleMapping.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/RoleMapping.java
index 7317453872..19b46e3307 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/RoleMapping.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/RoleMapping.java
@@ -1,6 +1,7 @@
 package at.tuwien.entities.user;
 
 import lombok.*;
+import org.hibernate.annotations.Type;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
@@ -21,11 +22,13 @@ public class RoleMapping {
     @Id
     @EqualsAndHashCode.Include
     @Column(name = "USER_ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID userId;
 
     @Id
     @EqualsAndHashCode.Include
     @Column(name = "ROLE_ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID roleId;
 
 }
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java
index b4469d77bf..9325962eac 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java
@@ -5,9 +5,12 @@ import at.tuwien.entities.database.Database;
 import at.tuwien.entities.identifier.Identifier;
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+import org.springframework.security.core.Authentication;
 
 import javax.persistence.*;
+import java.security.Principal;
 import java.util.List;
 import java.util.UUID;
 
@@ -24,15 +27,16 @@ import java.util.UUID;
         @UniqueConstraint(columnNames = {"REALM_ID", "USERNAME"})
 })
 @NamedQueries({
-        @NamedQuery(name = "User.findAll", query = "select u from User u join Realm r on r.name = 'dbrepo'"),
-        @NamedQuery(name = "User.findById", query = "select u from User u join Realm r on r.name = 'dbrepo' and u.id = ?1"),
-        @NamedQuery(name = "User.findByUsername", query = "select u from User u join Realm r on r.name = 'dbrepo' and u.username = ?1")
+        @NamedQuery(name = "User.findAll", query = "select u from User u join Realm r on r.name = 'dbrepo' and u.enabled = true"),
+        @NamedQuery(name = "User.findById", query = "select u from User u join Realm r on r.name = 'dbrepo' and u.id = ?1 and u.enabled = true"),
+        @NamedQuery(name = "User.findByUsername", query = "select u from User u join Realm r on r.name = 'dbrepo' and u.username = ?1 and u.enabled = true")
 })
 public class User {
 
     @Id
     @EqualsAndHashCode.Include
     @Column(name = "ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID id;
 
     @Column(nullable = false)
@@ -45,6 +49,7 @@ public class User {
     private String lastname;
 
     @Column(name = "REALM_ID", columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID realmId;
 
     @Column(nullable = false)
@@ -99,4 +104,34 @@ public class User {
     @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "creator")
     private List<at.tuwien.entities.database.table.Table> tables;
 
+    /**
+     * Compares if the user instance equals with another instance by the principal.
+     *
+     * @param principal The user principal.
+     * @return True if the user are equal, false otherwise.
+     */
+    public boolean equals(Principal principal) {
+        if (principal == null) {
+            return false;
+        }
+        return this.username.equals(principal.getName());
+    }
+
+    /**
+     * Compares the user principal and checks if a certain role is present.
+     *
+     * @param principal The user principal.
+     * @param role      The role.
+     * @return True if the role is present, false otherwise.
+     */
+    public static boolean hasRole(Principal principal, String role) {
+        if (principal == null || role == null) {
+            return false;
+        }
+        final Authentication authentication = (Authentication) principal;
+        return authentication.getAuthorities()
+                .stream()
+                .anyMatch(a -> a.getAuthority().equals(role));
+    }
+
 }
diff --git a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/UserAttribute.java b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/UserAttribute.java
index 976fc09f81..bbc19e8ef8 100644
--- a/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/UserAttribute.java
+++ b/dbrepo-metadata-db/entities/src/main/java/at/tuwien/entities/user/UserAttribute.java
@@ -2,6 +2,7 @@ package at.tuwien.entities.user;
 
 import lombok.*;
 import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Type;
 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 
 import javax.persistence.*;
@@ -21,10 +22,12 @@ public class UserAttribute {
     @Id
     @EqualsAndHashCode.Include
     @Column(name = "ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID id;
 
     @ToString.Exclude
     @Column(name = "USER_ID", nullable = false, columnDefinition = "VARCHAR(36)")
+    @Type(type = "uuid-char")
     private UUID userId;
 
     @Column(name = "NAME", nullable = false)
diff --git a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java
index 64137ee49a..db3137f986 100644
--- a/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java
+++ b/dbrepo-metadata-db/test/src/main/java/at/tuwien/test/BaseTest.java
@@ -2170,7 +2170,7 @@ public abstract class BaseTest {
             .resultHash(QUERY_1_RESULT_HASH)
             .created(QUERY_1_CREATED)
             .execution(QUERY_1_EXECUTION)
-            .createdBy(USER_1_ID.toString())
+            .createdBy(USER_1_ID)
             .creator(USER_1_DTO)
             .build();
 
@@ -2183,7 +2183,7 @@ public abstract class BaseTest {
             .resultHash(QUERY_1_RESULT_HASH)
             .created(QUERY_1_CREATED)
             .execution(QUERY_1_EXECUTION)
-            .createdBy(USER_1_ID.toString())
+            .createdBy(USER_1_ID)
             .creator(USER_1_DTO)
             .build();
 
diff --git a/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ExportEndpoint.java b/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ExportEndpoint.java
index f9a5a4f620..8e683d4348 100644
--- a/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ExportEndpoint.java
+++ b/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ExportEndpoint.java
@@ -2,6 +2,7 @@ package at.tuwien.endpoint;
 
 import at.tuwien.ExportResource;
 import at.tuwien.entities.database.Database;
+import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.service.*;
 import io.micrometer.core.annotation.Timed;
@@ -55,8 +56,7 @@ public class ExportEndpoint {
                 log.error("Failed to export private table: principal is null");
                 throw new NotAllowedException("Failed to export private table: principal is null");
             }
-            final Authentication authentication = (Authentication) principal;
-            if (authentication.getAuthorities().stream().noneMatch(a -> a.getAuthority().equals("export-table-data"))) {
+            if (!User.hasRole(principal, "export-table-data")) {
                 log.error("Failed to export private table: role missing");
                 throw new NotAllowedException("Failed to export private table: role missing");
             }
diff --git a/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java b/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java
index 89c871b554..d80b31df72 100644
--- a/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java
+++ b/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java
@@ -4,6 +4,7 @@ import at.tuwien.ExportResource;
 import at.tuwien.SortType;
 import at.tuwien.api.database.query.*;
 import at.tuwien.entities.database.Database;
+import at.tuwien.entities.user.User;
 import at.tuwien.querystore.Query;
 import at.tuwien.exception.*;
 import at.tuwien.service.*;
@@ -114,8 +115,7 @@ public class QueryEndpoint {
                 log.error("Failed to re-execute private query: principal is null");
                 throw new NotAllowedException("Failed to re-execute private query: principal is null");
             }
-            final Authentication authentication = (Authentication) principal;
-            if (authentication.getAuthorities().stream().noneMatch(a -> a.getAuthority().equals("re-execute-query"))) {
+            if (!User.hasRole(principal, "re-execute-query")) {
                 log.error("Failed to re-execute private query: role missing");
                 throw new NotAllowedException("Failed to re-execute private query: role missing");
             }
@@ -149,8 +149,7 @@ public class QueryEndpoint {
                 log.error("Failed to re-execute private query: principal is null");
                 throw new NotAllowedException("Failed to re-execute private query: principal is null");
             }
-            final Authentication authentication = (Authentication) principal;
-            if (authentication.getAuthorities().stream().noneMatch(a -> a.getAuthority().equals("re-execute-query"))) {
+            if (!User.hasRole(principal, "re-execute-query")) {
                 log.error("Failed to re-execute private query: role missing");
                 throw new NotAllowedException("Failed to re-execute private query: role missing");
             }
@@ -183,8 +182,7 @@ public class QueryEndpoint {
                 log.error("Failed to export private query: principal is null");
                 throw new NotAllowedException("Failed to export private query: principal is null");
             }
-            final Authentication authentication = (Authentication) principal;
-            if (authentication.getAuthorities().stream().noneMatch(a -> a.getAuthority().equals("export-query-data"))) {
+            if (!User.hasRole(principal, "export-query-data")) {
                 log.error("Failed to export private query: role missing");
                 throw new NotAllowedException("Failed to export private query: role missing");
             }
diff --git a/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ViewEndpoint.java b/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ViewEndpoint.java
index 44ce21e70a..d176b8741b 100644
--- a/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ViewEndpoint.java
+++ b/dbrepo-query-service/rest-service/src/main/java/at/tuwien/endpoint/ViewEndpoint.java
@@ -7,6 +7,7 @@ import at.tuwien.api.database.query.QueryResultDto;
 import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.entities.database.Database;
 import at.tuwien.entities.database.View;
+import at.tuwien.entities.user.User;
 import at.tuwien.exception.*;
 import at.tuwien.mapper.ViewMapper;
 import at.tuwien.service.*;
@@ -149,7 +150,7 @@ public class ViewEndpoint {
                 databaseId, data, principal);
         /* check */
         final Database database = databaseService.find(containerId, databaseId);
-        if (!database.getOwner().getUsername().equals(principal.getName())) {
+        if (!database.getOwner().equals(principal)) {
             log.error("Failed to create view: not the database owner");
             throw new NotAllowedException("Failed to create view: not the database owner");
         }
@@ -252,7 +253,7 @@ public class ViewEndpoint {
                 databaseId, viewId, principal);
         /* check */
         final Database database = databaseService.find(containerId, databaseId);
-        if (!database.getOwner().getUsername().equals(principal.getName())) {
+        if (!database.getOwner().equals(principal)) {
             log.error("Failed to delete view: not the database owner");
             throw new NotAllowedException("Failed to delete view: not the database owner");
         }
@@ -341,8 +342,7 @@ public class ViewEndpoint {
                 log.error("Failed to view data of private view: principal is null");
                 throw new NotAllowedException("Failed to view data of private view: principal is null");
             }
-            final Authentication authentication = (Authentication) principal;
-            if (authentication.getAuthorities().stream().noneMatch(a -> a.getAuthority().equals("view-database-view-data"))) {
+            if (!User.hasRole(principal, "view-database-view-data")) {
                 log.error("Failed to view data of private view: role missing");
                 throw new NotAllowedException("Failed to view data of private view: role missing");
             }
diff --git a/dbrepo-query-service/services/src/main/java/at/tuwien/mapper/ViewMapper.java b/dbrepo-query-service/services/src/main/java/at/tuwien/mapper/ViewMapper.java
index 91fb6bc00c..6cb6d4d77b 100644
--- a/dbrepo-query-service/services/src/main/java/at/tuwien/mapper/ViewMapper.java
+++ b/dbrepo-query-service/services/src/main/java/at/tuwien/mapper/ViewMapper.java
@@ -40,9 +40,6 @@ public interface ViewMapper {
     })
     ViewDto viewToViewDto(View data);
 
-    @Mappings({
-            @Mapping(target = "createdBy", expression = "java(data.getCreator().getId().toString())")
-    })
     ViewBriefDto viewToViewBriefDto(View data);
 
     default PreparedStatement viewToRawDeleteViewQuery(Connection connection, View view)
diff --git a/dbrepo-query-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java b/dbrepo-query-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java
index 0ab98c4ebe..0bc0916966 100644
--- a/dbrepo-query-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java
+++ b/dbrepo-query-service/services/src/main/java/at/tuwien/service/impl/ViewServiceImpl.java
@@ -146,7 +146,7 @@ public class ViewServiceImpl extends HibernateConnector implements ViewService {
                 .vdbid(databaseId)
                 .name(data.getName())
                 .internalName(viewMapper.nameToInternalName(data.getName()))
-                .creator(user)
+                .createdBy(user.getId())
                 .database(database)
                 .query(data.getQuery())
                 .isInitialView(false)
diff --git a/dbrepo-table-service/services/src/main/java/at/tuwien/mapper/TableMapper.java b/dbrepo-table-service/services/src/main/java/at/tuwien/mapper/TableMapper.java
index d12f4c9e43..311067b40c 100644
--- a/dbrepo-table-service/services/src/main/java/at/tuwien/mapper/TableMapper.java
+++ b/dbrepo-table-service/services/src/main/java/at/tuwien/mapper/TableMapper.java
@@ -208,6 +208,7 @@ public interface TableMapper {
             @Mapping(source = "table.creator", target = "creator"),
             @Mapping(source = "table", target = "table"),
             @Mapping(target = "id", ignore = true),
+            @Mapping(target = "createdBy", source = "table.createdBy"),
             @Mapping(target = "autoGenerated", expression = "java(data.getInternalName() == \"id\" && query.getGenerated())"),
             @Mapping(source = "data.name", target = "name"),
             @Mapping(source = "data.internalName", target = "internalName"),
diff --git a/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java b/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java
index 63a1199483..a6323d6591 100644
--- a/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java
+++ b/dbrepo-table-service/services/src/main/java/at/tuwien/service/impl/TableServiceImpl.java
@@ -172,7 +172,7 @@ public class TableServiceImpl extends HibernateConnector implements TableService
         tmp.setColumns(List.of());
         tmp.setConstraints(null);
         final User creator = userService.findByUsername(principal.getName());
-        tmp.setCreator(creator);
+        tmp.setCreatedBy(creator.getId());
         /* save in metadata database */
         final Table entity = tableRepository.save(tmp);
         entity.setColumns(createDto.getColumns()
diff --git a/dbrepo-ui/api/middleware.service.js b/dbrepo-ui/api/middleware.service.js
index ffa7bbf2b8..99899ab4aa 100644
--- a/dbrepo-ui/api/middleware.service.js
+++ b/dbrepo-ui/api/middleware.service.js
@@ -23,16 +23,16 @@ class MiddlewareService {
 
   buildQuery (data) {
     return new Promise((resolve, reject) => {
-      axios.post('/server-middleware/query/build', data, { headers: { 'Content-Type': 'multipart/form-data' } })
+      axios.post('/server-middleware/query/build', data, { headers: { 'Content-Type': 'application/json' } })
         .then((response) => {
           const file = response.data
-          console.debug('response file', file)
+          console.debug('response query', file)
           resolve(file)
         })
         .catch((error) => {
           const { code, message } = error
-          console.error('Failed to create database', error)
-          Vue.$toast.error(`[${code}] Failed to create database: ${message}`)
+          console.error('Failed to build query', error)
+          Vue.$toast.error(`[${code}] Failed to build query: ${message}`)
           reject(error)
         })
     })
diff --git a/dbrepo-ui/components/DBToolbar.vue b/dbrepo-ui/components/DBToolbar.vue
index 973d45682b..4ccfbf2b98 100644
--- a/dbrepo-ui/components/DBToolbar.vue
+++ b/dbrepo-ui/components/DBToolbar.vue
@@ -29,16 +29,16 @@
       <v-spacer />
       <v-toolbar-title>
         <v-btn v-if="canImportCsv" class="mr-2 mb-1" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/import`">
-          Import .csv
+          <v-icon left>mdi-cloud-upload</v-icon> Import .csv
         </v-btn>
         <v-btn v-if="canCreateSubset" color="secondary" class="mb-1 white--text" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/query/create`">
-          Create Subset
+          <v-icon left>mdi-wrench</v-icon> Create Subset
         </v-btn>
         <v-btn v-if="canCreateView" color="secondary" class="ml-2 mr-2 mb-1 white--text" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/view/create`">
-          Create View
+          <v-icon left>mdi-view-carousel-outline</v-icon> Create View
         </v-btn>
         <v-btn v-if="canCreateTable" color="primary" class="mb-1" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/create`">
-          Create Table
+          <v-icon left>mdi-table-large-plus</v-icon> Create Table
         </v-btn>
       </v-toolbar-title>
       <template v-slot:extension>
diff --git a/dbrepo-ui/components/EMPTY.vue b/dbrepo-ui/components/EMPTY.vue
deleted file mode 100644
index f8f6dddfc2..0000000000
--- a/dbrepo-ui/components/EMPTY.vue
+++ /dev/null
@@ -1,23 +0,0 @@
-<template>
-  <div>
-    EMPTY
-  </div>
-</template>
-
-<script>
-export default {
-  data () {
-    return {
-    }
-  },
-  computed: {
-  },
-  mounted () {
-  },
-  methods: {
-  }
-}
-</script>
-
-<style scoped>
-</style>
diff --git a/dbrepo-ui/components/TableToolbar.vue b/dbrepo-ui/components/TableToolbar.vue
index b4006495ac..80a54b2813 100644
--- a/dbrepo-ui/components/TableToolbar.vue
+++ b/dbrepo-ui/components/TableToolbar.vue
@@ -12,22 +12,22 @@
       <v-spacer />
       <v-toolbar-title>
         <v-btn v-if="canAddTuple" class="mr-2 mb-1" @click="addTuple">
-          Add
+          <v-icon left>mdi-plus</v-icon> Add
         </v-btn>
         <v-btn v-if="canEditTuple" color="warning" class="mr-2 mb-1 black--text" @click="editTuple">
-          Edit
+          <v-icon left>mdi-pencil</v-icon> Edit
         </v-btn>
         <v-btn v-if="canDeleteTuple" color="error" class="mr-2 mb-1" :loading="loadingDelete" @click="deleteItems">
-          Delete <span v-if="selection.length > 1">&nbsp;{{ selection.length }}</span>
+          <v-icon left>mdi-delete</v-icon> Delete <span v-if="selection.length > 1">&nbsp;{{ selection.length }}</span>
         </v-btn>
         <v-btn v-if="canExecuteQuery" class="mb-1" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/query/create?tid=${$route.params.table_id}`" color="secondary">
-          Create Subset
+          <v-icon left>mdi-wrench</v-icon> Create Subset
         </v-btn>
         <v-btn v-if="canCreateView" class="ml-2 mb-1" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/view/create?tid=${$route.params.table_id}`" color="secondary">
-          Create View
+          <v-icon left>mdi-view-carousel</v-icon> Create View
         </v-btn>
         <v-btn v-if="canImportCsv" class="ml-2 mb-1" :to="`/container/${$route.params.container_id}/database/${$route.params.database_id}/table/${$route.params.table_id}/import`">
-          Import csv
+          <v-icon left>mdi-cloud-upload</v-icon> Import .csv
         </v-btn>
       </v-toolbar-title>
     </v-toolbar>
diff --git a/dbrepo-ui/pages/container/_container_id/database/_database_id/table/import.vue b/dbrepo-ui/pages/container/_container_id/database/_database_id/table/import.vue
index 46fd9bdd58..a5c4f5949c 100644
--- a/dbrepo-ui/pages/container/_container_id/database/_database_id/table/import.vue
+++ b/dbrepo-ui/pages/container/_container_id/database/_database_id/table/import.vue
@@ -194,8 +194,8 @@
   </div>
 </template>
 <script>
+import { notEmpty, isNonNegativeInteger } from '@/utils'
 import TableSchema from '@/components/TableSchema'
-import { notEmpty, isNonNegativeInteger, isResearcher } from '@/utils'
 import ContainerService from '@/api/container.service'
 import TableService from '@/api/table.service'
 import MiddlewareService from '@/api/middleware.service'
@@ -280,12 +280,6 @@ export default {
     roles () {
       return this.$store.state.roles
     },
-    isResearcher () {
-      return isResearcher(this.user)
-    },
-    fileConfig () {
-      return { headers: { 'Content-Type': 'multipart/form-data' } }
-    },
     validTableName () {
       if (this.tableCreate.name === null) {
         return true
@@ -387,7 +381,8 @@ export default {
     },
     async loadDateFormats () {
       this.loading = true
-      this.dateFormats = await ContainerService.findOne(this.$route.params.container_id).image.date_formats
+      const res = await ContainerService.findOne(this.$route.params.container_id)
+      this.dateFormats = await ContainerService.findImage(res.image.id).date_formats
       this.loading = true
     },
     createTable () {
diff --git a/dbrepo-user-service/Dockerfile b/dbrepo-user-service/Dockerfile
index 151ebf831c..f4fb17c5e4 100644
--- a/dbrepo-user-service/Dockerfile
+++ b/dbrepo-user-service/Dockerfile
@@ -1,5 +1,5 @@
 ###### FIRST STAGE ######
-FROM fda-metadata-db:latest as dependency
+FROM dbrepo-metadata-db:latest as dependency
 MAINTAINER Martin Weise <martin.weise@tuwien.ac.at>
 
 ###### SECOND STAGE ######
diff --git a/dbrepo-user-service/pom.xml b/dbrepo-user-service/pom.xml
index 58cfe80e7c..8a5225c3fb 100644
--- a/dbrepo-user-service/pom.xml
+++ b/dbrepo-user-service/pom.xml
@@ -142,6 +142,12 @@
             <version>${project.version}</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>at.tuwien</groupId>
+            <artifactId>dbrepo-metadata-db-test</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
         <!-- Testing -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
diff --git a/dbrepo-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java b/dbrepo-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java
index 9ee7a22d2d..abee215b1e 100644
--- a/dbrepo-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java
+++ b/dbrepo-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java
@@ -106,7 +106,12 @@ public class UserEndpoint {
                                           @NotNull Principal principal)
             throws UserNotFoundException, ForeignUserException, UserAttributeNotFoundException {
         log.debug("endpoint modify a user, id={}, data={}, principal={}", id, data, principal);
-        final UserDto dto = userMapper.userToUserDto(userService.modify(UUID.fromString(id), data, principal));
+        final User user = userService.find(UUID.fromString(id));
+        if (!user.equals(principal)) {
+            log.error("Failed to modify user: attempting to modify other user");
+            throw new ForeignUserException("Failed to modify user: attempting to modify other user");
+        }
+        final UserDto dto = userMapper.userToUserDto(userService.modify(user.getId(), data, principal));
         log.trace("modify user resulted in dto {}", dto);
         return ResponseEntity.status(HttpStatus.ACCEPTED)
                 .body(dto);
@@ -122,8 +127,12 @@ public class UserEndpoint {
                                          @NotNull Principal principal)
             throws UserNotFoundException, ForeignUserException, UserAttributeNotFoundException {
         log.debug("endpoint modify a user theme, id={}, data={}, principal={}", id, data, principal);
-        final User user = userService.toggleTheme(UUID.fromString(id), data, principal);
-        final UserDto dto = userMapper.userToUserDto(user);
+        final User user = userService.find(UUID.fromString(id));
+        if (!user.equals(principal)) {
+            log.error("Failed to modify user: attempting to modify other user");
+            throw new ForeignUserException("Failed to modify user: attempting to modify other user");
+        }
+        final UserDto dto = userMapper.userToUserDto(userService.toggleTheme(user.getId(), data, principal));
         log.trace("modify user theme resulted in dto {}", dto);
         return ResponseEntity.accepted()
                 .body(dto);
@@ -139,8 +148,12 @@ public class UserEndpoint {
                                             @NotNull Principal principal)
             throws UserNotFoundException, ForeignUserException {
         log.debug("endpoint modify a user password, id={}, data={}, principal={}", id, data, principal);
-        final User user = userService.updatePassword(UUID.fromString(id), data, principal);
-        final UserDto dto = userMapper.userToUserDto(user);
+        final User user = userService.find(UUID.fromString(id));
+        if (!user.equals(principal)) {
+            log.error("Failed to modify user: attempting to modify other user");
+            throw new ForeignUserException("Failed to modify user: attempting to modify other user");
+        }
+        final UserDto dto = userMapper.userToUserDto(userService.updatePassword(user.getId(), data, principal));
         log.trace("updated user password resulted in dto {}", dto);
         return ResponseEntity.accepted()
                 .body(dto);
diff --git a/dbrepo-user-service/rest-service/src/main/resources/application-local.yml b/dbrepo-user-service/rest-service/src/main/resources/application-local.yml
index 7254853c65..6a5a1c57f8 100644
--- a/dbrepo-user-service/rest-service/src/main/resources/application-local.yml
+++ b/dbrepo-user-service/rest-service/src/main/resources/application-local.yml
@@ -20,6 +20,10 @@ spring:
           time_zone: UTC
   application:
     name: user-service
+  rabbitmq:
+    host: localhost
+    username: fda
+    password: fda
   cloud:
     loadbalancer.ribbon.enabled: false
 management.endpoints.web.exposure.include: health,info,prometheus
diff --git a/dbrepo-user-service/rest-service/src/main/resources/application.yml b/dbrepo-user-service/rest-service/src/main/resources/application.yml
index 7acd005839..f0606a3bf7 100644
--- a/dbrepo-user-service/rest-service/src/main/resources/application.yml
+++ b/dbrepo-user-service/rest-service/src/main/resources/application.yml
@@ -20,6 +20,10 @@ spring:
           time_zone: UTC
   application:
     name: user-service
+  rabbitmq:
+    host: broker-service
+    username: "${BROKER_USERNAME}"
+    password: "${BROKER_PASSWORD}"
   cloud:
     loadbalancer.ribbon.enabled: false
 management.endpoints.web.exposure.include: health,info,prometheus
diff --git a/dbrepo-user-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java b/dbrepo-user-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java
new file mode 100644
index 0000000000..c5adb93d3d
--- /dev/null
+++ b/dbrepo-user-service/rest-service/src/test/java/at/tuwien/BaseUnitTest.java
@@ -0,0 +1,9 @@
+package at.tuwien;
+
+import at.tuwien.test.BaseTest;
+import org.springframework.test.context.TestPropertySource;
+
+@TestPropertySource(locations = "classpath:application.properties")
+public abstract class BaseUnitTest extends BaseTest {
+
+}
\ No newline at end of file
diff --git a/dbrepo-user-service/rest-service/src/test/java/at/tuwien/mapper/UserMapperTest.java b/dbrepo-user-service/rest-service/src/test/java/at/tuwien/mapper/UserMapperTest.java
new file mode 100644
index 0000000000..613f43e10d
--- /dev/null
+++ b/dbrepo-user-service/rest-service/src/test/java/at/tuwien/mapper/UserMapperTest.java
@@ -0,0 +1,40 @@
+package at.tuwien.mapper;
+
+import at.tuwien.BaseUnitTest;
+import at.tuwien.entities.user.User;
+import lombok.extern.log4j.Log4j2;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+@Log4j2
+@SpringBootTest
+public class UserMapperTest extends BaseUnitTest {
+
+    @Test
+    public void equals_fails() {
+
+        /* test */
+        assertNotEquals(USER_1, USER_2);
+    }
+
+    @Test
+    public void equals_identitiy_succeeds() {
+
+        /* test */
+        assertEquals(USER_1, USER_1);
+    }
+
+    @Test
+    public void equals_similar_succeeds() {
+        final User tmp = User.builder()
+                .id(USER_1_ID)
+                .build();
+
+        /* test */
+        assertEquals(USER_1, tmp);
+    }
+
+}
diff --git a/dbrepo-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/dbrepo-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java
index 09e0ef8b0f..084171253f 100644
--- a/dbrepo-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java
+++ b/dbrepo-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java
@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.support.BasicAuthenticationInterceptor;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.util.DefaultUriBuilderFactory;
 
@@ -16,6 +17,12 @@ public class GatewayConfig {
     @Value("${fda.gateway.endpoint}")
     private String gatewayEndpoint;
 
+    @Value("${spring.rabbitmq.username}")
+    private String brokerUsername;
+
+    @Value("${spring.rabbitmq.password}")
+    private String brokerPassword;
+
     private final AuthenticationMapper authenticationMapper;
 
     @Autowired
@@ -30,4 +37,13 @@ public class GatewayConfig {
         restTemplate.getMessageConverters().add(authenticationMapper.mappingJackson2HttpMessageConverter());
         return restTemplate;
     }
+
+    @Bean("brokerRestTemplate")
+    public RestTemplate brokerRestTemplate() {
+        final RestTemplate restTemplate = new RestTemplate();
+        restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint));
+        restTemplate.getInterceptors()
+                .add(new BasicAuthenticationInterceptor(brokerUsername, brokerPassword));
+        return restTemplate;
+    }
 }
diff --git a/dbrepo-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java b/dbrepo-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java
index 9156ecd0c3..d0ea9d01a2 100644
--- a/dbrepo-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java
+++ b/dbrepo-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java
@@ -15,7 +15,6 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
 import java.util.UUID;
 
-
 @Mapper(componentModel = "spring")
 public interface UserMapper {
 
@@ -41,6 +40,7 @@ public interface UserMapper {
 
     default UserAttribute tripleToUserAttribute(UUID userId, String name, String value) {
         return UserAttribute.builder()
+                .id(UUID.randomUUID())
                 .userId(userId)
                 .name(name)
                 .value(value)
diff --git a/dbrepo-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/dbrepo-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
index 96fceaa61d..e791cc968e 100644
--- a/dbrepo-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
+++ b/dbrepo-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
@@ -17,6 +17,7 @@ import org.keycloak.common.util.Base64;
 import org.keycloak.common.util.PaddingUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.crypto.SecretKeyFactory;
 import javax.crypto.spec.PBEKeySpec;
@@ -85,6 +86,7 @@ public class UserServiceImpl implements UserService {
                 .append(Base64.encodeBytes(salt))
                 .append("\",\"additionalParameters\":{}}");
         Credential credential = Credential.builder()
+                .id(UUID.randomUUID())
                 .createdDate(Instant.now().toEpochMilli())
                 .secretData(secretData.toString())
                 .type("password")
@@ -93,6 +95,7 @@ public class UserServiceImpl implements UserService {
                 .build();
         /* save */
         User user = userMapper.signupRequestDtoToUser(data);
+        user.setId(UUID.randomUUID());
         user.setEmailVerified(false);
         user.setEnabled(true);
         user.setRealmId(realm.getId());
@@ -171,13 +174,9 @@ public class UserServiceImpl implements UserService {
 
     @Override
     public User toggleTheme(UUID id, UserThemeSetDto data, Principal principal) throws UserNotFoundException,
-            ForeignUserException, UserAttributeNotFoundException {
+            UserAttributeNotFoundException {
         /* check */
         final User user = find(id);
-        if (!user.getUsername().equals(principal.getName())) {
-            log.error("Failed to modify user: attempting to modify other user");
-            throw new ForeignUserException("Failed to modify user: attempting to modify other user");
-        }
         final UserAttribute entity = userAttributeService.update(user.getId(), "theme_dark", data.getThemeDark().toString());
         log.info("Updated theme by updating attribute with id {}", entity.getId());
         return user;
-- 
GitLab