From 2fbf203a7c3b5ca4abce0c9cb8a9d891b3db7035 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Thu, 3 Feb 2022 17:34:16 +0100
Subject: [PATCH] Fix sign-up of an previosly unknown user

---
 .../server/accessControl/UserSources.java     | 29 +++++++++++--------
 .../backend/transaction/LogUserVisit.java     |  2 +-
 .../transaction/RetrieveUserTransaction.java  | 11 +++++--
 3 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/src/main/java/org/caosdb/server/accessControl/UserSources.java b/src/main/java/org/caosdb/server/accessControl/UserSources.java
index 3c6a3646..04c2ecab 100644
--- a/src/main/java/org/caosdb/server/accessControl/UserSources.java
+++ b/src/main/java/org/caosdb/server/accessControl/UserSources.java
@@ -33,6 +33,7 @@ import java.util.Set;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authz.AuthorizationException;
 import org.apache.shiro.config.Ini;
+import org.apache.shiro.subject.Subject;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.ServerProperties;
 import org.caosdb.server.entity.Message;
@@ -72,6 +73,7 @@ import org.slf4j.LoggerFactory;
 public class UserSources extends HashMap<String, UserSource> {
 
   public static final String USERNAME_PASSWORD_AUTHENTICATION = "USERNAME_PASSWORD_AUTHENTICATION";
+  private static final Subject transactor = new SinglePermissionSubject("ACM:*:RETRIEVE:*");
   private static final Logger logger = LoggerFactory.getLogger(UserSources.class);
   public static final String KEY_DEFAULT_REALM = "defaultRealm";
   public static final String KEY_REALMS = "realms";
@@ -183,7 +185,7 @@ public class UserSources extends HashMap<String, UserSource> {
       realm = guessRealm(username);
     }
 
-    RetrieveUserTransaction t = new RetrieveUserTransaction(realm, username);
+    RetrieveUserTransaction t = new RetrieveUserTransaction(realm, username, transactor);
     try {
       t.execute();
       if (t.getUser() != null) return t.getRoles();
@@ -191,14 +193,7 @@ public class UserSources extends HashMap<String, UserSource> {
       throw new AuthorizationException("Could not resolve roles for " + username + "@" + realm);
     }
 
-    UserSource userSource = instance.get(realm);
-    if (userSource == null) {
-      return null;
-    }
-    // find all roles that are associated with this principal in this realm
-    final Set<String> ret = userSource.resolveRolesForUsername(username);
-
-    return ret;
+    return null;
   }
 
   public static String guessRealm(final String username) {
@@ -250,8 +245,7 @@ public class UserSources extends HashMap<String, UserSource> {
   }
 
   public static boolean isRoleExisting(final String role) {
-    final RetrieveRoleTransaction t =
-        new RetrieveRoleTransaction(role, new SinglePermissionSubject("ACM:*:RETRIEVE:*"));
+    final RetrieveRoleTransaction t = new RetrieveRoleTransaction(role, transactor);
     try {
       t.execute();
       return true;
@@ -311,7 +305,7 @@ public class UserSources extends HashMap<String, UserSource> {
   }
 
   private static boolean isActive(final String realm, final String username) {
-    final RetrieveUserTransaction t = new RetrieveUserTransaction(realm, username);
+    final RetrieveUserTransaction t = new RetrieveUserTransaction(realm, username, transactor);
     try {
       t.execute();
       if (t.getUser() != null) {
@@ -336,4 +330,15 @@ public class UserSources extends HashMap<String, UserSource> {
     }
     return isActive(principal.getRealm(), principal.getUsername());
   }
+
+  public static Set<String> getDefaultRoles(String realm, String username) {
+    UserSource userSource = instance.get(realm);
+    if (userSource == null) {
+      return null;
+    }
+    // find all roles that are associated with this principal in this realm
+    final Set<String> ret = userSource.resolveRolesForUsername(username);
+
+    return ret;
+  }
 }
diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/LogUserVisit.java b/src/main/java/org/caosdb/server/database/backend/transaction/LogUserVisit.java
index b9ec7a10..43fd8749 100644
--- a/src/main/java/org/caosdb/server/database/backend/transaction/LogUserVisit.java
+++ b/src/main/java/org/caosdb/server/database/backend/transaction/LogUserVisit.java
@@ -54,7 +54,7 @@ public class LogUserVisit extends BackendTransaction {
       user.name = username;
       user.email = UserSources.getDefaultUserEmail(realm, username);
       user.status = UserSources.getDefaultUserStatus(realm, username);
-      user.roles = new HashSet<>(UserSources.resolveRoles(realm, username));
+      user.roles = new HashSet<>(UserSources.getDefaultRoles(realm, username));
 
       UpdateUserImpl insertUser = getImplementation(UpdateUserImpl.class);
       insertUser.execute(user);
diff --git a/src/main/java/org/caosdb/server/transaction/RetrieveUserTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrieveUserTransaction.java
index 4847c4b3..eb24fb24 100644
--- a/src/main/java/org/caosdb/server/transaction/RetrieveUserTransaction.java
+++ b/src/main/java/org/caosdb/server/transaction/RetrieveUserTransaction.java
@@ -38,14 +38,19 @@ public class RetrieveUserTransaction extends AccessControlTransaction {
 
   private final Principal principal;
   private ProtoUser user;
+  private final Subject currentUser;
 
   public RetrieveUserTransaction(final String realm, final String name) {
-    this.principal = new Principal(realm, name);
+    this(realm, name, SecurityUtils.getSubject());
+  }
+
+  public RetrieveUserTransaction(String realm, String username, Subject transactor) {
+    currentUser = transactor;
+    this.principal = new Principal(realm, username);
   }
 
   @Override
   protected void transaction() throws Exception {
-    Subject currentUser = SecurityUtils.getSubject();
     if (!UserSources.isUserExisting(this.principal)
         || !currentUser.isPermitted(
             ACMPermissions.PERMISSION_RETRIEVE_USER_INFO(
@@ -54,7 +59,7 @@ public class RetrieveUserTransaction extends AccessControlTransaction {
     }
     this.user = execute(new RetrieveUser(this.principal), getAccess()).getUser();
 
-    if (user.roles != null) {
+    if (user != null && user.roles != null) {
       if (!currentUser.isPermitted(
           ACMPermissions.PERMISSION_RETRIEVE_USER_ROLES(user.realm, user.name))) {
         user.roles = null;
-- 
GitLab