* Added refresh tenant functionality add icon to Users page to change password commit work to date to github for ongoing use add modal with fields for current and new password on icon click missing swagger files remove unneeded files move changeUserPassword to admin_api, remove field for current password, include selected user Please enter the commit message for your changes. Lines starting added missing js files asset and function signature formatting changes * fixed lint * removed Current Password field, returned Groups label, added selectedUser to modal text * disabled save button if newPasssword and reNewPassword don't match, removed commented out code * Added refresh tenant functionality add icon to Users page to change password commit work to date to github for ongoing use add modal with fields for current and new password on icon click missing swagger files remove unneeded files move changeUserPassword to admin_api, remove field for current password, include selected user Please enter the commit message for your changes. Lines starting added missing js files asset and function signature formatting changes * removed Current Password field, returned Groups label, added selectedUser to modal text * changed Swagger parameters to camel case Co-authored-by: Jill <jill@minio.io>
625 lines
19 KiB
Go
625 lines
19 KiB
Go
// This file is part of MinIO Console Server
|
|
// Copyright (c) 2021 MinIO, Inc.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package restapi
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/go-openapi/errors"
|
|
"github.com/go-openapi/runtime/middleware"
|
|
"github.com/minio/console/models"
|
|
"github.com/minio/console/restapi/operations"
|
|
"github.com/minio/console/restapi/operations/admin_api"
|
|
"github.com/minio/madmin-go"
|
|
iampolicy "github.com/minio/pkg/iam/policy"
|
|
)
|
|
|
|
// Policy evaluated constants
|
|
const (
|
|
Unknown = 0
|
|
Allow = 1
|
|
Deny = -1
|
|
)
|
|
|
|
func registerUsersHandlers(api *operations.ConsoleAPI) {
|
|
// List Users
|
|
api.AdminAPIListUsersHandler = admin_api.ListUsersHandlerFunc(func(params admin_api.ListUsersParams, session *models.Principal) middleware.Responder {
|
|
listUsersResponse, err := getListUsersResponse(session)
|
|
if err != nil {
|
|
return admin_api.NewListUsersDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
return admin_api.NewListUsersOK().WithPayload(listUsersResponse)
|
|
})
|
|
// Add User
|
|
api.AdminAPIAddUserHandler = admin_api.AddUserHandlerFunc(func(params admin_api.AddUserParams, session *models.Principal) middleware.Responder {
|
|
userResponse, err := getUserAddResponse(session, params)
|
|
if err != nil {
|
|
return admin_api.NewAddUserDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
return admin_api.NewAddUserCreated().WithPayload(userResponse)
|
|
})
|
|
// Remove User
|
|
api.AdminAPIRemoveUserHandler = admin_api.RemoveUserHandlerFunc(func(params admin_api.RemoveUserParams, session *models.Principal) middleware.Responder {
|
|
err := getRemoveUserResponse(session, params)
|
|
if err != nil {
|
|
return admin_api.NewRemoveUserDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
return admin_api.NewRemoveUserNoContent()
|
|
})
|
|
// Update User-Groups
|
|
api.AdminAPIUpdateUserGroupsHandler = admin_api.UpdateUserGroupsHandlerFunc(func(params admin_api.UpdateUserGroupsParams, session *models.Principal) middleware.Responder {
|
|
userUpdateResponse, err := getUpdateUserGroupsResponse(session, params)
|
|
if err != nil {
|
|
return admin_api.NewUpdateUserGroupsDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
|
|
return admin_api.NewUpdateUserGroupsOK().WithPayload(userUpdateResponse)
|
|
})
|
|
// Get User
|
|
api.AdminAPIGetUserInfoHandler = admin_api.GetUserInfoHandlerFunc(func(params admin_api.GetUserInfoParams, session *models.Principal) middleware.Responder {
|
|
userInfoResponse, err := getUserInfoResponse(session, params)
|
|
if err != nil {
|
|
return admin_api.NewGetUserInfoDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
|
|
return admin_api.NewGetUserInfoOK().WithPayload(userInfoResponse)
|
|
})
|
|
// Update User
|
|
api.AdminAPIUpdateUserInfoHandler = admin_api.UpdateUserInfoHandlerFunc(func(params admin_api.UpdateUserInfoParams, session *models.Principal) middleware.Responder {
|
|
userUpdateResponse, err := getUpdateUserResponse(session, params)
|
|
if err != nil {
|
|
return admin_api.NewUpdateUserInfoDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
|
|
return admin_api.NewUpdateUserInfoOK().WithPayload(userUpdateResponse)
|
|
})
|
|
// Update User-Groups Bulk
|
|
api.AdminAPIBulkUpdateUsersGroupsHandler = admin_api.BulkUpdateUsersGroupsHandlerFunc(func(params admin_api.BulkUpdateUsersGroupsParams, session *models.Principal) middleware.Responder {
|
|
err := getAddUsersListToGroupsResponse(session, params)
|
|
if err != nil {
|
|
return admin_api.NewBulkUpdateUsersGroupsDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
|
|
return admin_api.NewBulkUpdateUsersGroupsOK()
|
|
})
|
|
api.AdminAPIListUsersWithAccessToBucketHandler = admin_api.ListUsersWithAccessToBucketHandlerFunc(func(params admin_api.ListUsersWithAccessToBucketParams, session *models.Principal) middleware.Responder {
|
|
response, err := getListUsersWithAccessToBucketResponse(session, params.Bucket)
|
|
if err != nil {
|
|
return admin_api.NewListUsersWithAccessToBucketDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
return admin_api.NewListUsersWithAccessToBucketOK().WithPayload(response)
|
|
})
|
|
// Change User Password
|
|
api.AdminAPIChangeUserPasswordHandler = admin_api.ChangeUserPasswordHandlerFunc(func(params admin_api.ChangeUserPasswordParams, session *models.Principal) middleware.Responder {
|
|
err := getChangeUserPasswordResponse(session, params)
|
|
if err != nil {
|
|
return admin_api.NewChangeUserPasswordDefault(int(err.Code)).WithPayload(err)
|
|
}
|
|
return admin_api.NewChangeUserPasswordCreated()
|
|
})
|
|
}
|
|
|
|
func listUsers(ctx context.Context, client MinioAdmin) ([]*models.User, error) {
|
|
|
|
// Get list of all users in the MinIO
|
|
// This call requires explicit authentication, no anonymous requests are
|
|
// allowed for listing users.
|
|
userMap, err := client.listUsers(ctx)
|
|
if err != nil {
|
|
return []*models.User{}, err
|
|
}
|
|
|
|
var users []*models.User
|
|
for accessKey, user := range userMap {
|
|
userElem := &models.User{
|
|
AccessKey: accessKey,
|
|
Status: string(user.Status),
|
|
Policy: strings.Split(user.PolicyName, ","),
|
|
MemberOf: user.MemberOf,
|
|
}
|
|
users = append(users, userElem)
|
|
}
|
|
|
|
return users, nil
|
|
}
|
|
|
|
// getListUsersResponse performs listUsers() and serializes it to the handler's output
|
|
func getListUsersResponse(session *models.Principal) (*models.ListUsersResponse, *models.Error) {
|
|
ctx := context.Background()
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
users, err := listUsers(ctx, adminClient)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
// serialize output
|
|
listUsersResponse := &models.ListUsersResponse{
|
|
Users: users,
|
|
}
|
|
return listUsersResponse, nil
|
|
}
|
|
|
|
// addUser invokes adding a users on `MinioAdmin` and builds the response `models.User`
|
|
func addUser(ctx context.Context, client MinioAdmin, accessKey, secretKey *string, groups []string) (*models.User, error) {
|
|
// Calls into MinIO to add a new user if there's an error return it
|
|
if err := client.addUser(ctx, *accessKey, *secretKey); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(groups) > 0 {
|
|
userElem, errUG := updateUserGroups(ctx, client, *accessKey, groups)
|
|
|
|
if errUG != nil {
|
|
return nil, errUG
|
|
}
|
|
return userElem, nil
|
|
}
|
|
|
|
userRet := &models.User{
|
|
AccessKey: *accessKey,
|
|
MemberOf: nil,
|
|
Policy: []string{},
|
|
Status: "",
|
|
}
|
|
return userRet, nil
|
|
}
|
|
|
|
func getUserAddResponse(session *models.Principal, params admin_api.AddUserParams) (*models.User, *models.Error) {
|
|
ctx := context.Background()
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
user, err := addUser(ctx, adminClient, params.Body.AccessKey, params.Body.SecretKey, params.Body.Groups)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
return user, nil
|
|
}
|
|
|
|
//removeUser invokes removing an user on `MinioAdmin`, then we return the response from API
|
|
func removeUser(ctx context.Context, client MinioAdmin, accessKey string) error {
|
|
if err := client.removeUser(ctx, accessKey); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getRemoveUserResponse(session *models.Principal, params admin_api.RemoveUserParams) *models.Error {
|
|
ctx := context.Background()
|
|
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return prepareError(err)
|
|
}
|
|
|
|
if session.AccountAccessKey == params.Name {
|
|
return prepareError(errAvoidSelfAccountDelete)
|
|
}
|
|
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
if err := removeUser(ctx, adminClient, params.Name); err != nil {
|
|
return prepareError(err)
|
|
}
|
|
|
|
log.Println("User removed successfully:", params.Name)
|
|
return nil
|
|
}
|
|
|
|
// getUserInfo calls MinIO server get the User Information
|
|
func getUserInfo(ctx context.Context, client MinioAdmin, accessKey string) (*madmin.UserInfo, error) {
|
|
userInfo, err := client.getUserInfo(ctx, accessKey)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &userInfo, nil
|
|
}
|
|
|
|
func getUserInfoResponse(session *models.Principal, params admin_api.GetUserInfoParams) (*models.User, *models.Error) {
|
|
ctx := context.Background()
|
|
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
user, err := getUserInfo(ctx, adminClient, params.Name)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
|
|
userInformation := &models.User{
|
|
AccessKey: params.Name,
|
|
MemberOf: user.MemberOf,
|
|
Policy: strings.Split(user.PolicyName, ","),
|
|
Status: string(user.Status),
|
|
}
|
|
|
|
return userInformation, nil
|
|
}
|
|
|
|
// updateUserGroups invokes getUserInfo() to get the old groups from the user,
|
|
// then we merge the list with the new groups list to have a shorter iteration between groups and we do a comparison between the current and old groups.
|
|
// We delete or update the groups according the location in each list and send the user with the new groups from `MinioAdmin` to the client
|
|
func updateUserGroups(ctx context.Context, client MinioAdmin, user string, groupsToAssign []string) (*models.User, error) {
|
|
parallelUserUpdate := func(groupName string, originGroups []string) chan error {
|
|
chProcess := make(chan error)
|
|
|
|
go func() error {
|
|
defer close(chProcess)
|
|
|
|
//Compare if groupName is in the arrays
|
|
isGroupPersistent := IsElementInArray(groupsToAssign, groupName)
|
|
isInOriginGroups := IsElementInArray(originGroups, groupName)
|
|
|
|
if isGroupPersistent && isInOriginGroups { // Group is already assigned and doesn't need to be updated
|
|
chProcess <- nil
|
|
|
|
return nil
|
|
}
|
|
|
|
isRemove := false // User is added by default
|
|
|
|
// User is deleted from the group
|
|
if !isGroupPersistent {
|
|
isRemove = true
|
|
}
|
|
|
|
userToAddRemove := []string{user}
|
|
|
|
updateReturn := updateGroupMembers(ctx, client, groupName, userToAddRemove, isRemove)
|
|
|
|
chProcess <- updateReturn
|
|
|
|
return updateReturn
|
|
}()
|
|
|
|
return chProcess
|
|
}
|
|
|
|
userInfoOr, err := getUserInfo(ctx, client, user)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
memberOf := userInfoOr.MemberOf
|
|
mergedGroupArray := UniqueKeys(append(memberOf, groupsToAssign...))
|
|
|
|
var listOfUpdates []chan error
|
|
|
|
// Each group must be updated individually because there is no way to update all the groups at once for a user,
|
|
// we are using the same logic as 'mc admin group add' command
|
|
for _, groupN := range mergedGroupArray {
|
|
proc := parallelUserUpdate(groupN, memberOf)
|
|
listOfUpdates = append(listOfUpdates, proc)
|
|
}
|
|
|
|
channelHasError := false
|
|
|
|
for _, chanRet := range listOfUpdates {
|
|
locError := <-chanRet
|
|
|
|
if locError != nil {
|
|
channelHasError = true
|
|
}
|
|
}
|
|
|
|
if channelHasError {
|
|
errRt := errors.New(500, "there was an error updating the groups")
|
|
return nil, errRt
|
|
}
|
|
|
|
userInfo, err := getUserInfo(ctx, client, user)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
policies := strings.Split(userInfo.PolicyName, ",")
|
|
|
|
userReturn := &models.User{
|
|
AccessKey: user,
|
|
MemberOf: userInfo.MemberOf,
|
|
Policy: policies,
|
|
Status: string(userInfo.Status),
|
|
}
|
|
|
|
return userReturn, nil
|
|
}
|
|
|
|
func getUpdateUserGroupsResponse(session *models.Principal, params admin_api.UpdateUserGroupsParams) (*models.User, *models.Error) {
|
|
ctx := context.Background()
|
|
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
user, err := updateUserGroups(ctx, adminClient, params.Name, params.Body.Groups)
|
|
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// setUserStatus invokes setUserStatus from madmin to update user status
|
|
func setUserStatus(ctx context.Context, client MinioAdmin, user string, status string) error {
|
|
var setStatus madmin.AccountStatus
|
|
switch status {
|
|
case "enabled":
|
|
setStatus = madmin.AccountEnabled
|
|
case "disabled":
|
|
setStatus = madmin.AccountDisabled
|
|
default:
|
|
return errors.New(500, "status not valid")
|
|
}
|
|
|
|
if err := client.setUserStatus(ctx, user, setStatus); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getUpdateUserResponse(session *models.Principal, params admin_api.UpdateUserInfoParams) (*models.User, *models.Error) {
|
|
ctx := context.Background()
|
|
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
name := params.Name
|
|
status := *params.Body.Status
|
|
groups := params.Body.Groups
|
|
|
|
if err := setUserStatus(ctx, adminClient, name, status); err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
|
|
userElem, errUG := updateUserGroups(ctx, adminClient, name, groups)
|
|
|
|
if errUG != nil {
|
|
return nil, prepareError(errUG)
|
|
}
|
|
return userElem, nil
|
|
}
|
|
|
|
// addUsersListToGroups iterates over the user list & assigns the requested groups to each user.
|
|
func addUsersListToGroups(ctx context.Context, client MinioAdmin, usersToUpdate []string, groupsToAssign []string) error {
|
|
// We update each group with the complete usersList
|
|
parallelGroupsUpdate := func(groupToAssign string) chan error {
|
|
groupProcess := make(chan error)
|
|
|
|
go func() {
|
|
defer close(groupProcess)
|
|
// We add the users array to the group.
|
|
err := updateGroupMembers(ctx, client, groupToAssign, usersToUpdate, false)
|
|
|
|
groupProcess <- err
|
|
}()
|
|
return groupProcess
|
|
}
|
|
|
|
var groupsUpdateList []chan error
|
|
|
|
// We get each group name & add users accordingly
|
|
for _, groupName := range groupsToAssign {
|
|
// We update the group
|
|
proc := parallelGroupsUpdate(groupName)
|
|
groupsUpdateList = append(groupsUpdateList, proc)
|
|
}
|
|
|
|
errorsList := []string{} // We get the errors list because we want to have all errors at once.
|
|
for _, err := range groupsUpdateList {
|
|
errorFromUpdate := <-err // We store the error to avoid Data Race
|
|
if errorFromUpdate != nil {
|
|
// If there is an error, we store the errors strings so we can join them after we receive all errors
|
|
errorsList = append(errorsList, errorFromUpdate.Error()) // We wait until all the channels have been closed.
|
|
}
|
|
}
|
|
|
|
// If there are errors, we throw the final error with the errors inside
|
|
if len(errorsList) > 0 {
|
|
errGen := fmt.Errorf("error in users-groups assignation: %q", strings.Join(errorsList[:], ","))
|
|
return errGen
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getAddUsersListToGroupsResponse(session *models.Principal, params admin_api.BulkUpdateUsersGroupsParams) *models.Error {
|
|
ctx := context.Background()
|
|
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return prepareError(err)
|
|
}
|
|
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
usersList := params.Body.Users
|
|
groupsList := params.Body.Groups
|
|
|
|
if err := addUsersListToGroups(ctx, adminClient, usersList, groupsList); err != nil {
|
|
return prepareError(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getListUsersWithAccessToBucketResponse(session *models.Principal, bucket string) ([]string, *models.Error) {
|
|
ctx := context.Background()
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
return listUsersWithAccessToBucket(ctx, adminClient, bucket)
|
|
}
|
|
|
|
func policyAllowsAndMatchesBucket(policy *iampolicy.Policy, bucket string) int {
|
|
policyStatements := policy.Statements
|
|
for i := 0; i < len(policyStatements); i++ {
|
|
resources := policyStatements[i].Resources
|
|
effect := policyStatements[i].Effect
|
|
if resources.Match(bucket, map[string][]string{}) {
|
|
if effect.IsValid() {
|
|
if effect.IsAllowed(true) {
|
|
return Allow
|
|
}
|
|
return Deny
|
|
}
|
|
}
|
|
}
|
|
return Unknown
|
|
}
|
|
|
|
func listUsersWithAccessToBucket(ctx context.Context, adminClient MinioAdmin, bucket string) ([]string, *models.Error) {
|
|
users, err := adminClient.listUsers(ctx)
|
|
if err != nil {
|
|
return nil, prepareError(err)
|
|
}
|
|
var retval []string
|
|
akHasAccess := make(map[string]bool)
|
|
akIsDenied := make(map[string]bool)
|
|
for k, v := range users {
|
|
for _, policyName := range strings.Split(v.PolicyName, ",") {
|
|
policyName = strings.TrimSpace(policyName)
|
|
policy, err := adminClient.getPolicy(ctx, policyName)
|
|
if err == nil {
|
|
if !akIsDenied[k] {
|
|
switch policyAllowsAndMatchesBucket(policy, bucket) {
|
|
case Allow:
|
|
if !akHasAccess[k] {
|
|
akHasAccess[k] = true
|
|
}
|
|
case Deny:
|
|
akIsDenied[k] = true
|
|
akHasAccess[k] = false
|
|
}
|
|
}
|
|
} else {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
groups, err := listGroups(ctx, adminClient)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return retval, nil
|
|
}
|
|
for i := 0; i < len(*groups); i++ {
|
|
info, err := groupInfo(ctx, adminClient, (*groups)[i])
|
|
if err == nil {
|
|
policy, err2 := adminClient.getPolicy(ctx, info.Policy)
|
|
if err2 == nil {
|
|
for j := 0; j < len(info.Members); j++ {
|
|
if !akIsDenied[info.Members[j]] {
|
|
switch policyAllowsAndMatchesBucket(policy, bucket) {
|
|
case Allow:
|
|
if !akHasAccess[info.Members[j]] {
|
|
akHasAccess[info.Members[j]] = true
|
|
}
|
|
case Deny:
|
|
akIsDenied[info.Members[j]] = true
|
|
akHasAccess[info.Members[j]] = false
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
log.Println(err2)
|
|
}
|
|
} else {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
for k, v := range akHasAccess {
|
|
if v {
|
|
retval = append(retval, k)
|
|
}
|
|
}
|
|
sort.Strings(retval)
|
|
return retval, nil
|
|
}
|
|
|
|
// changeUserPassword changes password of selectedUser to newSecretKey
|
|
func changeUserPassword(ctx context.Context, client MinioAdmin, selectedUser string, newSecretKey string) error {
|
|
if err := client.changePassword(ctx, selectedUser, newSecretKey); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// getChangeUserPasswordResponse will change the password of selctedUser to newSecretKey
|
|
func getChangeUserPasswordResponse(session *models.Principal, params admin_api.ChangeUserPasswordParams) *models.Error {
|
|
ctx := context.Background()
|
|
mAdmin, err := newMAdminClient(session)
|
|
if err != nil {
|
|
return prepareError(err)
|
|
}
|
|
// create a minioClient interface implementation
|
|
// defining the client to be used
|
|
adminClient := adminClient{client: mAdmin}
|
|
|
|
// params will contain selectedUser and newSecretKey credentials for the user
|
|
user := *params.Body.SelectedUser
|
|
newSecretKey := *params.Body.NewSecretKey
|
|
|
|
// changes password of user to newSecretKey
|
|
if err := changeUserPassword(ctx, adminClient, user, newSecretKey); err != nil {
|
|
return prepareError(err)
|
|
}
|
|
return nil
|
|
}
|