-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmockokta.go
340 lines (293 loc) · 11.6 KB
/
mockokta.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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
package mockokta
import (
"context"
"fmt"
"math/rand"
"time"
"github.com/okta/okta-sdk-golang/v2/okta"
"github.com/okta/okta-sdk-golang/v2/okta/query"
)
var adminRoles = []string{"SUPER_ADMIN", "ORG_ADMIN", "GROUP_ADMIN", "GROUP_MEMBERSHIP_ADMIN", "USER_ADMIN", "APP_ADMIN", "READ_ONLY_ADMIN", "MOBILE_ADMIN", "HELP_DESK_ADMIN", "REPORT_ADMIN", "API_ACCESS_MANAGEMENT_ADMIN", "CUSTOM"}
// MockClient is our client to simulate the okta golang sdk client
type MockClient struct {
Group *GroupResource
User *UserResource
}
// NewClient Creates a New Okta Client with all the necessary attributes
func NewClient() *MockClient {
c := &MockClient{}
c.Group = &GroupResource{
Client: c,
GroupRoles: make(map[string][]*okta.Role),
GroupUsers: make(map[string][]string),
}
c.User = &UserResource{
Client: c,
}
return c
}
// GroupResource contains all the information to add fake groups, and maps of Group Names
// to Roles and Users
type GroupResource struct {
Client *MockClient
Groups []*okta.Group
GroupRoles map[string][]*okta.Role
GroupUsers map[string][]string
}
// Wrapper methods for Okta API Calls
// Initialize is an empty method so we can match the okta client interface with tests
func (client *MockClient) Initialize(ctx context.Context, conf ...okta.ConfigSetter) error {
return nil
}
// ListGroups is a wrapper to call client.Group.ListGroups to make it easier to match an interface for the okta client
func (client *MockClient) ListGroups(ctx context.Context, qp *query.Params) ([]*okta.Group, *okta.Response, error) {
return client.Group.ListGroups(ctx, qp)
}
// ListGroupUsers is a wrapper to call client.Group.ListGroupUsers to make it easier to match an interface for the okta client
func (client *MockClient) ListGroupUsers(ctx context.Context, groupID string, qp *query.Params) ([]*okta.User, *okta.Response, error) {
return client.Group.ListGroupUsers(ctx, groupID, qp)
}
// ListGroupAssignedRoles is a wrapper to call client.Group.ListGroupAssignedRoles to make it easier to match an interface for the okta client
func (client *MockClient) ListGroupAssignedRoles(ctx context.Context, groupID string, qp *query.Params) ([]*okta.Role, *okta.Response, error) {
return client.Group.ListGroupAssignedRoles(ctx, groupID, qp)
}
// CreateGroup is a wrapper to call client.Group.CreateGroup to make it easier to match an interface for the okta client
func (client *MockClient) CreateGroup(ctx context.Context, group okta.Group) (*okta.Group, *okta.Response, error) {
return client.Group.CreateGroup(ctx, group)
}
// DeleteGroup is a wrapper to call client.Group.DeleteGroup to make it easier to match an interface for the okta client
func (client *MockClient) DeleteGroup(ctx context.Context, groupID string) (*okta.Response, error) {
return client.Group.DeleteGroup(ctx, groupID)
}
// AssignRoleToGroup is a wrapper to call client.Group.AssignRoleToGroup to make it easier to match an interface for the okta client
func (client *MockClient) AssignRoleToGroup(ctx context.Context, groupID string, assignRoleRequest okta.AssignRoleRequest, qp *query.Params) (*okta.Role, *okta.Response, error) {
return client.Group.AssignRoleToGroup(ctx, groupID, assignRoleRequest, qp)
}
// ListUsers is a wrapper to call client.Group.ListUsers to make it easier to match an interface for the okta client
func (client *MockClient) ListUsers(ctx context.Context, qp *query.Params) ([]*okta.User, *okta.Response, error) {
return client.User.ListUsers(ctx, qp)
}
// AddUserToGroup is a wrapper to call client.Group.AddUserToGroup to make it easier to match an interface for the okta client
func (client *MockClient) AddUserToGroup(ctx context.Context, groupID string, userID string) (*okta.Response, error) {
return client.Group.AddUserToGroup(ctx, groupID, userID)
}
// RemoveUserFromGroup is a wrapper to call client.Group.RemoveUserFromGroup to make it easier to match an interface for the okta client
func (client *MockClient) RemoveUserFromGroup(ctx context.Context, groupID string, userID string) (*okta.Response, error) {
return client.Group.RemoveUserFromGroup(ctx, groupID, userID)
}
// NewGroup will Create a New *okta.Group with the specified Group name
func NewGroup(groupName string) *okta.Group {
return &okta.Group{
Profile: &okta.GroupProfile{
Name: groupName,
},
}
}
// CreateGroup will add the group to the list of groups
func (g *GroupResource) CreateGroup(ctx context.Context, group okta.Group) (*okta.Group, *okta.Response, error) {
group.Id = fmt.Sprint(len(g.Groups) + 1)
for _, x := range g.Groups {
if x.Profile.Name == group.Profile.Name {
return nil, nil, fmt.Errorf("unable to create group: group exists")
}
}
if len(group.Profile.Name) > 255 || len(group.Profile.Name) < 1 {
return nil, nil, fmt.Errorf("unable to create group: invalid name length")
}
g.Groups = append(g.Groups, &group)
return &group, nil, nil
}
// DeleteGroup will remove a specified group ID from the list of Groups
func (g *GroupResource) DeleteGroup(ctx context.Context, groupID string) (*okta.Response, error) {
for idx, group := range g.Groups {
if group.Id == groupID {
g.Groups[idx] = g.Groups[len(g.Groups)-1]
g.Groups[len(g.Groups)-1] = &okta.Group{}
g.Groups = g.Groups[:len(g.Groups)-1]
return nil, nil
}
}
return nil, fmt.Errorf("group not found")
}
// ListGroups will return a list of all groups
func (g *GroupResource) ListGroups(context.Context, *query.Params) ([]*okta.Group, *okta.Response, error) {
return g.Groups, nil, nil
}
// AddUserToGroup will take a groupID and userID and add the user to the group
func (g *GroupResource) AddUserToGroup(ctx context.Context, groupID string, userID string) (*okta.Response, error) {
group, err := g.GetGroupByID(groupID)
if err != nil {
return nil, err
}
user, err := g.Client.User.GetUserByID(userID)
if err != nil {
return nil, err
}
g.GroupUsers[group.Profile.Name] = append(g.GroupUsers[group.Profile.Name], (*user.Profile)["email"].(string))
return nil, nil
}
// RemoveUserFromGroup will take a groupID and userID and remove the user from the group
func (g *GroupResource) RemoveUserFromGroup(ctx context.Context, groupID string, userID string) (*okta.Response, error) {
group, err := g.GetGroupByID(groupID)
if err != nil {
return nil, err
}
groupName := group.Profile.Name
user, err := g.Client.User.GetUserByID(userID)
if err != nil {
return nil, err
}
userEmail := (*user.Profile)["email"].(string)
for idx, u := range g.GroupUsers[groupName] {
if u == userEmail {
g.GroupUsers[groupName][idx] = g.GroupUsers[groupName][len(g.GroupUsers[groupName])-1]
g.GroupUsers[groupName][len(g.GroupUsers[groupName])-1] = ""
g.GroupUsers[groupName] = g.GroupUsers[groupName][:len(g.GroupUsers[groupName])-1]
}
}
return nil, nil
}
// AssignRoleToGroup will assigned the role in the assignRoleRequest to the group specified by ID, and return the role it assigned
func (g *GroupResource) AssignRoleToGroup(ctx context.Context, groupID string, assignRoleRequest okta.AssignRoleRequest, qp *query.Params) (*okta.Role, *okta.Response, error) {
if !SliceContainsString(adminRoles, assignRoleRequest.Type) {
return nil, nil, fmt.Errorf("invalid role")
}
group, err := g.GetGroupByID(groupID)
if err != nil {
return nil, nil, err
}
if g.GroupContainsRole(*group, assignRoleRequest.Type) {
return nil, nil, fmt.Errorf("group role exists")
}
role := NewRole(assignRoleRequest.Type)
role.Id = fmt.Sprintf("%v", len(g.GroupRoles)+1)
g.GroupRoles[group.Profile.Name] = append(g.GroupRoles[group.Profile.Name], &role)
return &role, nil, nil
}
// ListGroupAssignedRoles will list all the roles for a specified groupID
func (g *GroupResource) ListGroupAssignedRoles(ctx context.Context, groupID string, qp *query.Params) ([]*okta.Role, *okta.Response, error) {
group, _ := g.GetGroupByID(groupID)
roles := make([]*okta.Role, 0)
roles = append(roles, g.GroupRoles[group.Profile.Name]...)
return roles, nil, nil
}
// GroupContainsRole will search a group for a certain role and return a boolean of it found it
func (g *GroupResource) GroupContainsRole(group okta.Group, roleType string) bool {
for _, groupRole := range g.GroupRoles[group.Profile.Name] {
if groupRole.Type == roleType {
return true
}
}
return false
}
// ListGroupUsers will return a slice of all users in the specified group
func (g *GroupResource) ListGroupUsers(ctx context.Context, groupID string, qp *query.Params) ([]*okta.User, *okta.Response, error) {
group, _ := g.GetGroupByID(groupID)
users := make([]*okta.User, 0)
for _, user := range g.GroupUsers[group.Profile.Name] {
user, _ := g.Client.User.GetUserByEmail(user)
users = append(users, user)
}
return users, nil, nil
}
// GroupContainsUser will search a group for a user by email and return a boolean indicating
// if it found the user or not
func (g *GroupResource) GroupContainsUser(group okta.Group, userEmail string) bool {
for _, groupUser := range g.GroupUsers[group.Profile.Name] {
if groupUser == userEmail {
return true
}
}
return false
}
// GetGroupByID will search for a group with the specified groupID and return the group
func (g *GroupResource) GetGroupByID(groupID string) (*okta.Group, error) {
for _, group := range g.Groups {
if group.Id == groupID {
return group, nil
}
}
return nil, fmt.Errorf("group not found")
}
// GetGroupByName will search for a group with the specified groupName and return the group
func (g *GroupResource) GetGroupByName(groupName string) (*okta.Group, error) {
for _, group := range g.Groups {
if group.Profile.Name == groupName {
return group, nil
}
}
return nil, fmt.Errorf("group not found")
}
// UserResource contains the simulated Users
type UserResource struct {
Client *MockClient
Users []*okta.User
}
// CreateUser will Create a User with the specified email and return it
func (u *UserResource) CreateUser(userEmail string) (*okta.User, error) {
userID := fmt.Sprint(len(u.Users) + 1)
for _, u := range u.Users {
if (*u.Profile)["email"] == userEmail {
return nil, fmt.Errorf("user exists")
}
}
user := &okta.User{
Id: userID,
Profile: &okta.UserProfile{
"email": userEmail,
},
}
u.Users = append(u.Users, user)
return user, nil
}
// ListUsers returns a list of all okta Users
func (u *UserResource) ListUsers(ctx context.Context, qp *query.Params) ([]*okta.User, *okta.Response, error) {
users := make([]*okta.User, 0)
users = append(users, u.Users...)
return users, nil, nil
}
// GetUserByEmail searches for a user with the email and returns it
func (u *UserResource) GetUserByEmail(email string) (*okta.User, error) {
for _, user := range u.Users {
if (*user.Profile)["email"] == email {
return user, nil
}
}
return nil, fmt.Errorf("user not found")
}
// GetUserByID searches for user by userID and returns it
func (u *UserResource) GetUserByID(userID string) (*okta.User, error) {
for _, user := range u.Users {
if user.Id == userID {
return user, nil
}
}
return nil, fmt.Errorf("user not found")
}
// NewRole Creates a new okta role and returns it
func NewRole(roleType string) okta.Role {
return okta.Role{
Type: roleType,
}
}
// NewAssignRoleRequest Creates a new AssignRoleRequest and returns it
func NewAssignRoleRequest(roleType string) okta.AssignRoleRequest {
return okta.AssignRoleRequest{
Type: roleType,
}
}
// SliceContainsString searches a slice for a string and returns it
func SliceContainsString(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}
// RandAdminRoleRequest generates a random role from the valid admin roles
func RandAdminRoleRequest() okta.AssignRoleRequest {
rand.Seed(time.Now().UnixNano())
roleRequest := NewAssignRoleRequest(adminRoles[rand.Intn(len(adminRoles))])
return roleRequest
}