-
Notifications
You must be signed in to change notification settings - Fork 0
/
user_groups.go
305 lines (230 loc) · 13.9 KB
/
user_groups.go
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/*******************************************************************************
*
*
* (c) Copyright Merative US L.P. and others 2020-2022
*
* SPDX-Licence-Identifier: Apache 2.0
*
*******************************************************************************/
// Package user_groups handles user management functions related to groups.
package user_groups
import (
"common/bchcls/cached_stub"
"common/bchcls/data_model"
"common/bchcls/internal/common/global"
"common/bchcls/internal/common/graph"
"common/bchcls/internal/metering_i"
"common/bchcls/internal/user_mgmt_i"
"common/bchcls/internal/user_mgmt_i/user_mgmt_c"
"common/bchcls/utils"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
var logger = shim.NewLogger("user_groups")
// ----------------- GROUP MEMBERSHIP FUNCTIONS -----------------
// PutUserInGroup adds the user as a member of the group.
// If the user is already a member of the group, then the admin status can be updated.
// Admins have read/write access to any assets that the group has read/write access to.
// Members have read access to assets that the group has read access to.
// userID must be the ID of a user, not a group.
// groupID must be the ID of a group, not a user.
// If isAdmin is true, user will be given write access to group assets.
// Caller must be an admin of the group in order to add members and admins.
// keyPaths are optional parameters. If passed in, they are used to get group's keys.
// The first keyPath is for getting the group symKey, and the second keyPath is for getting the group privateKey.
func PutUserInGroup(stub cached_stub.CachedStubInterface, caller data_model.User, userID string, groupID string, isAdmin bool, keyPaths ...[]string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v userId: %v groupId: %v isAdmin: %v", caller.ID, userID, groupID, isAdmin)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.PutUserInGroup(stub, caller, userID, groupID, isAdmin, keyPaths...)
}
// RegisterSubgroup registers a new group as a subgroup of an existing group.
// Admins of the parent group are admins of the subgroup.
// Members of the subgroup are members of parent group.
// Auditors of the parent group are auditors of the subgroup.
// Subgroups can only have one parent group.
//
// args = [subgroup, parentGroupID]
//
// subgroup is the subgroup to be registered.
// parentGroupID is the id of the parent group.
func RegisterSubgroup(stub cached_stub.CachedStubInterface, caller data_model.User, args []string) ([]byte, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("args: %v", args)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RegisterSubgroup(stub, caller, args)
}
// RegisterSubgroupWithParams registers a new group as a subgroup of an existing group.
// "WithParams" functions should only be called from within the chaincode.
//
// subgroup is the subgroup to register.
// parentGroupID is the id of the parent group.
// keyPaths are optional parameters. If passed in, they are used to get the parent group's keys.
// The first keyPath is for getting the parent group symKey, and the second keyPath is for getting the parent group privateKey.
func RegisterSubgroupWithParams(stub cached_stub.CachedStubInterface, caller data_model.User, subgroup data_model.User, parentGroupID string, keyPaths ...[]string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v, subgroup: %v, parentGroup: %v, keyPath: %v", caller.ID, subgroup.ID, parentGroupID, keyPaths)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RegisterSubgroupWithParams(stub, caller, subgroup, parentGroupID, keyPaths...)
}
// RemoveSubgroupFromGroup removes a subgroup from a group.
//
// subgroupID is the id of the subgroup to remove from group.
// groupID is the id of the group that the subgroup currently belongs to.
// keyPaths are optional parameters. If passed in, they are used to get the parent group's keys.
// The first keyPath is for getting the parent group symKey, and the second keyPath is for getting the parent group privateKey.
func RemoveSubgroupFromGroup(stub cached_stub.CachedStubInterface, caller data_model.User, subgroupID string, groupID string, keyPaths ...[]string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v, subgroupID: %v, groupID: %v, keyPaths: %v", caller.ID, subgroupID, groupID, keyPaths)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RemoveSubgroupFromGroup(stub, caller, subgroupID, groupID, keyPaths...)
}
// RemoveUserFromGroup removes a user from a group.
//
// args = [userID, groupID, removeSubGroup (optional: default=false)]
// If removeFromSubGroup is true, the function will also traverse the org tree, and remove the user from all
// subgroups of the given groupID. This operation could be slow depending on tree structure.
func RemoveUserFromGroup(stub cached_stub.CachedStubInterface, caller data_model.User, args []string) ([]byte, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("args: %v", args)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RemoveUserFromGroup(stub, caller, args)
}
// RemoveUserFromGroupWithParams is the internal function for removing a user from a group.
// "WithParams" functions should only be called from within the chaincode.
func RemoveUserFromGroupWithParams(stub cached_stub.CachedStubInterface, caller data_model.User, userID string, groupID string, keyPaths ...[]string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v, userID: %v, groupID: %v, keyPaths: %v", caller.ID, userID, groupID, keyPaths)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RemoveUserFromGroupWithParams(stub, caller, userID, groupID, keyPaths...)
}
// IsUserInGroup returns true if a user is either a direct or indirect member of a group.
func IsUserInGroup(stub cached_stub.CachedStubInterface, userID string, groupID string) (bool, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_c.IsUserInGroup(stub, userID, groupID)
}
// IsUserMemberOfGroup returns true if a user is in a group.
// This function does not check indirect membership.
func IsUserMemberOfGroup(stub cached_stub.CachedStubInterface, userID string, groupID string) (bool, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_c.IsUserMemberOfGroup(stub, userID, groupID)
}
// IsUserDirectAdminOfGroup is a helper function that checks if user is a direct admin of a group.
func IsUserDirectAdminOfGroup(stub cached_stub.CachedStubInterface, userID string, groupID string) (bool, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_c.IsUserDirectAdminOfGroup(stub, userID, groupID)
}
// IsUserAdminOfGroup checks if a user is a direct or indirect admin of a group.
// If it is an admin, returns a user admin chain as well. If not, returns an empty list.
func IsUserAdminOfGroup(stub cached_stub.CachedStubInterface, userID string, groupID string) (bool, []string, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_c.IsUserAdminOfGroup(stub, userID, groupID)
}
// IsParentGroup returns true if parentGroup is a direct or indirect parent of childGroup, false otherwise.
func IsParentGroup(stub cached_stub.CachedStubInterface, caller data_model.User, parentGroupID string, childGroupID string) bool {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.IsParentGroup(stub, caller, parentGroupID, childGroupID)
}
// SlowGetGroupMemberIDs returns a list of group member and admin IDs.
// This function searches the entire user graph, so it could be slow.
func SlowGetGroupMemberIDs(stub cached_stub.CachedStubInterface, groupID string) ([]string, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.SlowGetGroupMemberIDs(stub, groupID)
}
// SlowGetGroupAdminIDs returns a list of group admin IDs.
// This function searches the entire user graph, so it could be slow.
func SlowGetGroupAdminIDs(stub cached_stub.CachedStubInterface, groupID string) ([]string, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.SlowGetGroupAdminIDs(stub, groupID)
}
// SlowGetMyGroupIDs returns a list of group IDs for which the given user is either
// a direct or indirect member.
// If adminOnly is set to true, returns only group IDs for which the user is a direct or
// indirect admin.
// This function searches the entire user graph, so it could be slow.
func SlowGetMyGroupIDs(stub cached_stub.CachedStubInterface, caller data_model.User, userID string, adminOnly bool) ([]string, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.SlowGetMyGroupIDs(stub, caller, userID, adminOnly)
}
// SlowGetSubgroups returns a list of subgroup IDs of group's child groups.
// This function searches the entire user graph, so it could be slow.
func SlowGetSubgroups(stub cached_stub.CachedStubInterface, groupID string) ([]string, error) {
filter := fmt.Sprintf(`{"!=": [{"var": "type"}, "%v"]}`, global.SUBGROUP_EDGE)
_ = metering_i.SetEnvAndAddRow(stub)
return graph.SlowGetChildren(stub, global.USER_GRAPH, groupID, filter)
}
// GetMyDirectGroupIDs returns a list of group IDs for which the user is a direct member.
func GetMyDirectGroupIDs(stub cached_stub.CachedStubInterface, userID string) ([]string, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_c.GetMyDirectGroupIDs(stub, userID)
}
// GetMyDirectAdminGroupIDs returns a list of group IDs for which the user is a direct admin.
func GetMyDirectAdminGroupIDs(stub cached_stub.CachedStubInterface, userID string) ([]string, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_c.GetMyDirectAdminGroupIDs(stub, userID)
}
// GiveAdminPermissionOfGroup gives user admin permission to a group.
// Caller must be an admin of the group.
func GiveAdminPermissionOfGroup(stub cached_stub.CachedStubInterface, caller data_model.User, userID string, groupID string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("userID: %v, groupID: %v", userID, groupID)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.GiveAdminPermissionOfGroup(stub, caller, userID, groupID)
}
// RemoveAdminPermissionOfGroup removes group admin permission from a user.
// Caller must be an admin of the group.
//
// args = [userID, groupID]
func RemoveAdminPermissionOfGroup(stub cached_stub.CachedStubInterface, caller data_model.User, args []string) ([]byte, error) {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("args: %v", args)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RemoveAdminPermissionOfGroup(stub, caller, args)
}
// RemoveAdminPermissionOfGroupWithParams is the internal function for removing group admin permission from a user.
// "WithParams" functions should only be called from within the chaincode.
//
// keyPaths are optional parameters. If passed in, they are used to get group's keys.
// The first keyPath is for getting the group symKey, and the second keyPath is for getting the group privateKey.
func RemoveAdminPermissionOfGroupWithParams(stub cached_stub.CachedStubInterface, caller data_model.User, userID string, groupID string, keyPaths ...[]string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v userId: %v groupId: %v", caller.ID, userID, groupID)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RemoveAdminPermissionOfGroupWithParams(stub, caller, userID, groupID, keyPaths...)
}
// GiveAuditorPermissionOfGroupById adds group audit permission to a user for the given auditorID and groupID.
// Caller must be direct or indirect admin of group.
// keyPaths are optional parameters. If passed in, they are used to get group's keys.
// The first keyPath is for getting group symKey, the second keyPath is for getting group privateKey.
func GiveAuditorPermissionOfGroupById(stub cached_stub.CachedStubInterface, caller data_model.User, auditorID string, groupID string, keyPaths ...[]string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v auditorID: %v groupId: %v", caller.ID, auditorID, groupID)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.GiveAuditorPermissionOfGroupById(stub, caller, auditorID, groupID, keyPaths...)
}
// GiveAuditorPermissionOfGroup adds group audit permission to a user for the given auditor and group objects.
// Caller must be admin of group.
func GiveAuditorPermissionOfGroup(stub cached_stub.CachedStubInterface, caller, auditor, group data_model.User) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v auditorID: %v groupId: %v", caller.ID, auditor.ID, group.ID)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.GiveAuditorPermissionOfGroup(stub, caller, auditor, group)
}
// RemoveAuditorPermissionOfGroup removes group auditor's permission from a user.
// Caller must be admin of group.
func RemoveAuditorPermissionOfGroup(stub cached_stub.CachedStubInterface, caller data_model.User, auditorID string, groupID string) error {
defer utils.ExitFnLogger(logger, utils.EnterFnLogger(logger))
logger.Debugf("caller: %v auditorID: %v groupId: %v", caller.ID, auditorID, groupID)
_ = metering_i.SetEnvAndAddRow(stub)
return user_mgmt_i.RemoveAuditorPermissionOfGroup(stub, caller, auditorID, groupID)
}