/
groups.clj
129 lines (111 loc) · 4.81 KB
/
groups.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
(ns kaleidoscope.clj.api.groups
(:require [kaleidoscope.clj.persistence.rdbms :as rdbms]
[kaleidoscope.clj.utils.core :as utils]
[clojure.spec.alpha :as s]
[taoensso.timbre :as log]
[clojure.set :as set]))
(defn get-id
[group]
(:id group))
(defn get-owner
[group]
(:owner-id group))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Groups
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def ^:private get-groups
(rdbms/make-finder :groups))
#_(defn get-users-groups
"Only return the groups owned by the requesting user"
[database requester-id]
(get-groups database {:owner-id requester-id}))
(defn create-group!
[database {:keys [id] :as group}]
(let [now (utils/now)]
(rdbms/insert! database
:groups (assoc group
:created-at now
:modified-at now
:id (or id (utils/uuid)))
:ex-subtype :UnableToCreateGroup)))
(defn owns?
[database requester-id group-id]
(= requester-id (get-owner (first (get-groups database {:id group-id})))))
(defn delete-group!
"Only allow a user to delete a group if they are the owner.
The `user-id` is the identity of the user requesting the operation."
[database requester-id group-id]
(if (owns? database requester-id group-id)
(rdbms/delete! database
:groups group-id
:ex-subtype :UnableToDeleteGroup)
(log/warnf "User %s does not have permissions to delete the group %s" requester-id group-id)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Members in groups
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def ^:private get-group-memberships
(rdbms/make-finder :full-memberships))
(defn group-key
[full-membership]
(select-keys full-membership [:group-id
:group-modified-at :group-created-at
:display-name :owner-id]))
(defn select-membership-keys
[membership]
(select-keys membership [:membership-id
:membership-created-at
:alias
:email]))
(defn normalize-memberships
"Group memberships are denormalized - normalize them in Clojure so we have a
nested data structure of the form:
{:group-id \"123\"
...
:other-group-information \"stuff\"
...
:memberships [{:email string?
:alias string?
:membership-id string?
:membership-created-at inst?}]}"
[group-memberships]
(->> group-memberships
(group-by group-key)
(reduce-kv (fn [acc group-key memberships]
(conj acc (-> group-key
(assoc :memberships (if (some :membership-id memberships)
(map select-membership-keys memberships)
[])))))
[])))
(defn get-users-groups
"Only return the groups owned by the requesting user"
[database requester-id]
(log/infof "Getting groups that user `%s` owns" requester-id)
(normalize-memberships (get-group-memberships database {:owner-id requester-id})))
(defn add-users-to-group!
"This functionality makes a strong assumption: that users are uniquely identified
by their email addresses.
We do this in order to simplify the system: by adding email addresses to the
group, we don't have to worry about the problem of 'What is this users' unique
ID in Keycloak?"
[database requester-id group-id users]
(if (owns? database requester-id group-id)
(let [now-time (utils/now)
memberships (vec (for [{:keys [email alias] :as user} (if (vector? users) users [users])]
{:id (utils/uuid)
:email email
:alias alias
:group-id group-id
:created-at now-time}))]
(vec (rdbms/insert! database
:user-group-memberships memberships
:ex-subtype :UnableToAddUserToGroup)))
(log/warnf "User %s does not have permissions to add users to group %s" requester-id group-id)))
(defn remove-user-from-group!
[database requester-id group-id user-group-membership-id]
(if (owns? database requester-id group-id)
(rdbms/delete! database
:user-group-memberships user-group-membership-id
:ex-subtype :UnableToDeleteUserFromGroup)
(log/warnf "User %s does not have permissions to delete users from group %s" requester-id group-id)))
(comment
)