forked from influxdata/influxdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathusers.go
197 lines (171 loc) · 4.71 KB
/
users.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
package enterprise
import (
"context"
"fmt"
"github.com/influxdata/influxdb/chronograf"
)
// UserStore uses a control client operate on Influx Enterprise users
type UserStore struct {
Ctrl
Logger chronograf.Logger
}
// Add creates a new User in Influx Enterprise
func (c *UserStore) Add(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
if err := c.Ctrl.CreateUser(ctx, u.Name, u.Passwd); err != nil {
return nil, err
}
perms := ToEnterprise(u.Permissions)
if err := c.Ctrl.SetUserPerms(ctx, u.Name, perms); err != nil {
return nil, err
}
for _, role := range u.Roles {
if err := c.Ctrl.AddRoleUsers(ctx, role.Name, []string{u.Name}); err != nil {
return nil, err
}
}
return c.Get(ctx, chronograf.UserQuery{Name: &u.Name})
}
// Delete the User from Influx Enterprise
func (c *UserStore) Delete(ctx context.Context, u *chronograf.User) error {
return c.Ctrl.DeleteUser(ctx, u.Name)
}
// Num of users in Influx
func (c *UserStore) Num(ctx context.Context) (int, error) {
all, err := c.All(ctx)
if err != nil {
return 0, err
}
return len(all), nil
}
// Get retrieves a user if name exists.
func (c *UserStore) Get(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
if q.Name == nil {
return nil, fmt.Errorf("query must specify name")
}
u, err := c.Ctrl.User(ctx, *q.Name)
if err != nil {
return nil, err
}
ur, err := c.Ctrl.UserRoles(ctx)
if err != nil {
return nil, err
}
role := ur[*q.Name]
cr := role.ToChronograf()
// For now we are removing all users from a role being returned.
for i, r := range cr {
r.Users = []chronograf.User{}
cr[i] = r
}
return &chronograf.User{
Name: u.Name,
Permissions: ToChronograf(u.Permissions),
Roles: cr,
}, nil
}
// Update the user's permissions or roles
func (c *UserStore) Update(ctx context.Context, u *chronograf.User) error {
// Only allow one type of change at a time. If it is a password
// change then do it and return without any changes to permissions
if u.Passwd != "" {
return c.Ctrl.ChangePassword(ctx, u.Name, u.Passwd)
}
if u.Roles != nil {
// Make a list of the roles we want this user to have:
want := make([]string, len(u.Roles))
for i, r := range u.Roles {
want[i] = r.Name
}
// Find the list of all roles this user is currently in
userRoles, err := c.UserRoles(ctx)
if err != nil {
return nil
}
// Make a list of the roles the user currently has
roles := userRoles[u.Name]
have := make([]string, len(roles.Roles))
for i, r := range roles.Roles {
have[i] = r.Name
}
// Calculate the roles the user will be removed from and the roles the user
// will be added to.
revoke, add := Difference(want, have)
// First, add the user to the new roles
for _, role := range add {
if err := c.Ctrl.AddRoleUsers(ctx, role, []string{u.Name}); err != nil {
return err
}
}
// ... and now remove the user from an extra roles
for _, role := range revoke {
if err := c.Ctrl.RemoveRoleUsers(ctx, role, []string{u.Name}); err != nil {
return err
}
}
}
if u.Permissions != nil {
perms := ToEnterprise(u.Permissions)
return c.Ctrl.SetUserPerms(ctx, u.Name, perms)
}
return nil
}
// All is all users in influx
func (c *UserStore) All(ctx context.Context) ([]chronograf.User, error) {
all, err := c.Ctrl.Users(ctx, nil)
if err != nil {
return nil, err
}
ur, err := c.Ctrl.UserRoles(ctx)
if err != nil {
return nil, err
}
res := make([]chronograf.User, len(all.Users))
for i, user := range all.Users {
role := ur[user.Name]
cr := role.ToChronograf()
// For now we are removing all users from a role being returned.
for i, r := range cr {
r.Users = []chronograf.User{}
cr[i] = r
}
res[i] = chronograf.User{
Name: user.Name,
Permissions: ToChronograf(user.Permissions),
Roles: cr,
}
}
return res, nil
}
// ToEnterprise converts chronograf permission shape to enterprise
func ToEnterprise(perms chronograf.Permissions) Permissions {
res := Permissions{}
for _, perm := range perms {
if perm.Scope == chronograf.AllScope {
// Enterprise uses empty string as the key for all databases
res[""] = perm.Allowed
} else {
res[perm.Name] = perm.Allowed
}
}
return res
}
// ToChronograf converts enterprise permissions shape to chronograf shape
func ToChronograf(perms Permissions) chronograf.Permissions {
res := chronograf.Permissions{}
for db, perm := range perms {
// Enterprise uses empty string as the key for all databases
if db == "" {
res = append(res, chronograf.Permission{
Scope: chronograf.AllScope,
Allowed: perm,
})
} else {
res = append(res, chronograf.Permission{
Scope: chronograf.DBScope,
Name: db,
Allowed: perm,
})
}
}
return res
}