memberships: Return user public keys from /api/users

Change-Id: I82ffc7d396c2775aee07e04aeaab757615a258b0
diff --git a/core/auth/memberships/main.go b/core/auth/memberships/main.go
index 8322933..942846f 100644
--- a/core/auth/memberships/main.go
+++ b/core/auth/memberships/main.go
@@ -55,6 +55,7 @@
 	Id       string `json:"id"`
 	Username string `json:"username"`
 	Email    string `json:"email"`
+	SSHPublicKeys []string `json:"sshPublicKeys,omitempty"`
 }
 
 func getLoggedInUser(r *http.Request) (string, error) {
@@ -696,6 +697,14 @@
 		http.Error(w, "Failed to retrieve user infos", http.StatusInternalServerError)
 		return
 	}
+	for i, user := range users {
+		sshKeys, err := s.store.GetUserPublicKeys(nil, user.Id)
+		if err != nil {
+			http.Error(w, "Failed to retrieve user infos", http.StatusInternalServerError)
+			return
+		}
+		users[i].SSHPublicKeys = sshKeys
+	}
 	w.Header().Set("Content-Type", "application/json")
 	if err := json.NewEncoder(w).Encode(users); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
diff --git a/core/installer/server/dodo-app/server.go b/core/installer/server/dodo-app/server.go
index 2bbbb7c..5e0e2e0 100644
--- a/core/installer/server/dodo-app/server.go
+++ b/core/installer/server/dodo-app/server.go
@@ -1709,7 +1709,7 @@
 		fmt.Println(err)
 		return
 	}
-	keyToUser := make(map[string]string)
+	existingPublicKeys := make(map[string]struct{})
 	for _, clientUser := range allClientUsers {
 		if clientUser == "admin" || clientUser == "fluxcd" {
 			continue
@@ -1728,15 +1728,19 @@
 			}
 			for _, existingKey := range existingKeys {
 				cleanKey := soft.CleanKey(existingKey)
-				keyOk := slices.ContainsFunc(userData.SSHPublicKeys, func(key string) bool {
+				found := slices.ContainsFunc(userData.SSHPublicKeys, func(key string) bool {
 					return cleanKey == soft.CleanKey(key)
 				})
-				if !keyOk {
+				if !found {
 					if err := s.client.RemovePublicKey(clientUser, existingKey); err != nil {
 						fmt.Println(err)
 					}
 				} else {
-					keyToUser[cleanKey] = clientUser
+					if _, ok := existingPublicKeys[cleanKey]; ok {
+						fmt.Println(fmt.Errorf("duplicate key: %s", cleanKey))
+						return
+					}
+					existingPublicKeys[cleanKey] = struct{}{}
 				}
 			}
 		}
@@ -1762,15 +1766,11 @@
 		} else {
 			for _, key := range u.SSHPublicKeys {
 				cleanKey := soft.CleanKey(key)
-				if user, ok := keyToUser[cleanKey]; ok {
-					if u.Username != user {
-						panic("MUST NOT REACH! IMPOSSIBLE KEY USER RECORD")
+				if _, ok := existingPublicKeys[cleanKey]; !ok {
+					if err := s.client.AddPublicKey(u.Username, cleanKey); err != nil {
+						fmt.Println(err)
+						return
 					}
-					continue
-				}
-				if err := s.client.AddPublicKey(u.Username, cleanKey); err != nil {
-					fmt.Println(err)
-					return
 				}
 			}
 		}
@@ -1785,7 +1785,7 @@
 		}
 		for _, u := range users {
 			if err := s.client.AddReadWriteCollaborator(r, u.Username); err != nil {
-				fmt.Println(err)
+				fmt.Printf("%s %s\n", u.Username, err)
 				continue
 			}
 		}