Skip to content

Commit 3dac86d

Browse files
bexsoftBenjamin Perez
andauthored
Implements remove user API (#42)
* Implementation of RemoveUser from madmin * Added removeUser structure. * Added removeUserResponse actions * Added delete API to swagger * Added tests to removeUser functions * Removed extra space at EOF * Changed context to be a parameter in admin_users functions Co-authored-by: Benjamin Perez <[email protected]>
1 parent 2001ab6 commit 3dac86d

File tree

10 files changed

+584
-11
lines changed

10 files changed

+584
-11
lines changed

restapi/admin_users.go

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,21 @@ func registerUsersHandlers(api *operations.McsAPI) {
4646
}
4747
return admin_api.NewAddUserCreated().WithPayload(userResponse)
4848
})
49+
// Remove User
50+
api.AdminAPIRemoveUserHandler = admin_api.RemoveUserHandlerFunc(func(params admin_api.RemoveUserParams, principal *models.Principal) middleware.Responder {
51+
err := getRemoveUserResponse(params)
52+
if err != nil {
53+
return admin_api.NewRemoveUserDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
54+
}
55+
return admin_api.NewRemoveUserNoContent()
56+
})
4957
}
5058

51-
func listUsers(client MinioAdmin) ([]*models.User, error) {
59+
func listUsers(ctx context.Context, client MinioAdmin) ([]*models.User, error) {
5260

5361
// Get list of all users in the MinIO
5462
// This call requires explicit authentication, no anonymous requests are
5563
// allowed for listing users.
56-
ctx := context.Background()
5764
userMap, err := client.listUsers(ctx)
5865
if err != nil {
5966
return []*models.User{}, err
@@ -75,6 +82,7 @@ func listUsers(client MinioAdmin) ([]*models.User, error) {
7582

7683
// getListUsersResponse performs listUsers() and serializes it to the handler's output
7784
func getListUsersResponse() (*models.ListUsersResponse, error) {
85+
ctx := context.Background()
7886
mAdmin, err := newMAdminClient()
7987
if err != nil {
8088
log.Println("error creating Madmin Client:", err)
@@ -84,7 +92,7 @@ func getListUsersResponse() (*models.ListUsersResponse, error) {
8492
// defining the client to be used
8593
adminClient := adminClient{client: mAdmin}
8694

87-
users, err := listUsers(adminClient)
95+
users, err := listUsers(ctx, adminClient)
8896
if err != nil {
8997
log.Println("error listing users:", err)
9098
return nil, err
@@ -97,9 +105,8 @@ func getListUsersResponse() (*models.ListUsersResponse, error) {
97105
}
98106

99107
// addUser invokes adding a users on `MinioAdmin` and builds the response `models.User`
100-
func addUser(client MinioAdmin, accessKey, secretKey *string) (*models.User, error) {
108+
func addUser(ctx context.Context, client MinioAdmin, accessKey, secretKey *string) (*models.User, error) {
101109
// Calls into MinIO to add a new user if there's an error return it
102-
ctx := context.Background()
103110
err := client.addUser(ctx, *accessKey, *secretKey)
104111
if err != nil {
105112
return nil, err
@@ -113,6 +120,7 @@ func addUser(client MinioAdmin, accessKey, secretKey *string) (*models.User, err
113120
}
114121

115122
func getUserAddResponse(params admin_api.AddUserParams) (*models.User, error) {
123+
ctx := context.Background()
116124
mAdmin, err := newMAdminClient()
117125
if err != nil {
118126
log.Println("error creating Madmin Client:", err)
@@ -122,10 +130,40 @@ func getUserAddResponse(params admin_api.AddUserParams) (*models.User, error) {
122130
// defining the client to be used
123131
adminClient := adminClient{client: mAdmin}
124132

125-
user, err := addUser(adminClient, params.Body.AccessKey, params.Body.SecretKey)
133+
user, err := addUser(ctx, adminClient, params.Body.AccessKey, params.Body.SecretKey)
126134
if err != nil {
127135
log.Println("error adding user:", err)
128136
return nil, err
129137
}
130138
return user, nil
131139
}
140+
141+
//removeUser invokes removing an user on `MinioAdmin`, then we return the response from API
142+
func removeUser(ctx context.Context, client MinioAdmin, accessKey string) error {
143+
if err := client.removeUser(ctx, accessKey); err != nil {
144+
return err
145+
}
146+
return nil
147+
}
148+
149+
func getRemoveUserResponse(params admin_api.RemoveUserParams) error {
150+
ctx := context.Background()
151+
152+
mAdmin, err := newMAdminClient()
153+
if err != nil {
154+
log.Println("error creating Madmin Client:", err)
155+
return err
156+
}
157+
158+
// create a minioClient interface implementation
159+
// defining the client to be used
160+
adminClient := adminClient{client: mAdmin}
161+
162+
if err := removeUser(ctx, adminClient, params.Name); err != nil {
163+
log.Println("error removing user:", err)
164+
return err
165+
}
166+
167+
log.Println("User removed successfully:", params.Name)
168+
return nil
169+
}

restapi/admin_users_test.go

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
// assigning mock at runtime instead of compile time
3232
var minioListUsersMock func() (map[string]madmin.UserInfo, error)
3333
var minioAddUserMock func(accessKey, secreyKey string) error
34+
var minioRemoveUserMock func(accessKey string) error
3435

3536
// mock function of listUsers()
3637
func (ac adminClientMock) listUsers(ctx context.Context) (map[string]madmin.UserInfo, error) {
@@ -42,9 +43,15 @@ func (ac adminClientMock) addUser(ctx context.Context, accessKey, secretKey stri
4243
return minioAddUserMock(accessKey, secretKey)
4344
}
4445

46+
// mock function of removeUser()
47+
func (ac adminClientMock) removeUser(ctx context.Context, accessKey string) error {
48+
return minioRemoveUserMock(accessKey)
49+
}
50+
4551
func TestListUsers(t *testing.T) {
4652
assert := asrt.New(t)
4753
adminClient := adminClientMock{}
54+
ctx := context.Background()
4855
// Test-1 : listUsers() Get response from minio client with two users and return the same number on listUsers()
4956
// mock minIO client
5057
mockUserMap := map[string]madmin.UserInfo{
@@ -69,7 +76,7 @@ func TestListUsers(t *testing.T) {
6976
// get list users response this response should have Name, CreationDate, Size and Access
7077
// as part of of each user
7178
function := "listUsers()"
72-
userMap, err := listUsers(adminClient)
79+
userMap, err := listUsers(ctx, adminClient)
7380
if err != nil {
7481
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
7582
}
@@ -87,7 +94,7 @@ func TestListUsers(t *testing.T) {
8794
minioListUsersMock = func() (map[string]madmin.UserInfo, error) {
8895
return nil, errors.New("error")
8996
}
90-
_, err = listUsers(adminClient)
97+
_, err = listUsers(ctx, adminClient)
9198
if assert.Error(err) {
9299
assert.Equal("error", err.Error())
93100
}
@@ -96,7 +103,7 @@ func TestListUsers(t *testing.T) {
96103
func TestAddUser(t *testing.T) {
97104
assert := asrt.New(t)
98105
adminClient := adminClientMock{}
99-
106+
ctx := context.Background()
100107
// Test-1: valid case of adding a user with a proper access key
101108
accessKey := "ABCDEFGHI"
102109
secretKey := "ABCDEFGHIABCDEFGHI"
@@ -107,7 +114,7 @@ func TestAddUser(t *testing.T) {
107114
}
108115
// adds a valid user to MinIO
109116
function := "addUser()"
110-
user, err := addUser(adminClient, &accessKey, &secretKey)
117+
user, err := addUser(ctx, adminClient, &accessKey, &secretKey)
111118
if err != nil {
112119
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
113120
}
@@ -124,7 +131,7 @@ func TestAddUser(t *testing.T) {
124131
return errors.New("error")
125132
}
126133

127-
user, err = addUser(adminClient, &accessKey, &secretKey)
134+
user, err = addUser(ctx, adminClient, &accessKey, &secretKey)
128135

129136
// no error should have been returned
130137
assert.Nil(user, "User is not null")
@@ -134,3 +141,31 @@ func TestAddUser(t *testing.T) {
134141
assert.Equal("error", err.Error())
135142
}
136143
}
144+
145+
func TestRemoveUser(t *testing.T) {
146+
assert := asrt.New(t)
147+
// mock minIO client
148+
adminClient := adminClientMock{}
149+
ctx := context.Background()
150+
function := "removeUser()"
151+
152+
// Test-1: removeUser() delete a user
153+
// mock function response from removeUser(accessKey)
154+
minioRemoveUserMock = func(accessKey string) error {
155+
return nil
156+
}
157+
158+
if err := removeUser(ctx, adminClient, "ABCDEFGHI"); err != nil {
159+
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
160+
}
161+
162+
// Test-2: removeUser() make sure errors are handled correctly when error on DeleteUser()
163+
// mock function response from removeUser(accessKey)
164+
minioRemoveUserMock = func(accessKey string) error {
165+
return errors.New("error")
166+
}
167+
168+
if err := removeUser(ctx, adminClient, "notexistentuser"); assert.Error(err) {
169+
assert.Equal("error", err.Error())
170+
}
171+
}

restapi/client-admin.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ var s3AdminNew = mcCmd.NewAdminFactory()
5757
type MinioAdmin interface {
5858
listUsers(ctx context.Context) (map[string]madmin.UserInfo, error)
5959
addUser(ctx context.Context, acessKey, SecretKey string) error
60+
removeUser(ctx context.Context, accessKey string) error
6061
listGroups(ctx context.Context) ([]string, error)
6162
updateGroupMembers(ctx context.Context, greq madmin.GroupAddRemove) error
6263
getGroupDescription(ctx context.Context, group string) (*madmin.GroupDesc, error)
@@ -93,6 +94,11 @@ func (ac adminClient) addUser(ctx context.Context, acessKey, secretKey string) e
9394
return ac.client.AddUser(ctx, acessKey, secretKey)
9495
}
9596

97+
// implements madmin.RemoveUser()
98+
func (ac adminClient) removeUser(ctx context.Context, accessKey string) error {
99+
return ac.client.RemoveUser(ctx, accessKey)
100+
}
101+
96102
// implements madmin.ListGroups()
97103
func (ac adminClient) listGroups(ctx context.Context) ([]string, error) {
98104
return ac.client.ListGroups(ctx)

restapi/embedded_spec.go

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

restapi/operations/admin_api/remove_user.go

Lines changed: 90 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)