diff --git a/api/http/handler/users/user_update.go b/api/http/handler/users/user_update.go
index e61a62085..55e2f4e59 100644
--- a/api/http/handler/users/user_update.go
+++ b/api/http/handler/users/user_update.go
@@ -3,6 +3,7 @@ package users
import (
"net/http"
+ "github.com/asaskevich/govalidator"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
@@ -11,11 +12,16 @@ import (
)
type userUpdatePayload struct {
+ Username string
Password string
Role int
}
func (payload *userUpdatePayload) Validate(r *http.Request) error {
+ if govalidator.Contains(payload.Username, " ") {
+ return portainer.Error("Invalid username. Must not contain any whitespace")
+ }
+
if payload.Role != 0 && payload.Role != 1 && payload.Role != 2 {
return portainer.Error("Invalid role value. Value must be one of: 1 (administrator) or 2 (regular user)")
}
@@ -55,6 +61,18 @@ func (handler *Handler) userUpdate(w http.ResponseWriter, r *http.Request) *http
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a user with the specified identifier inside the database", err}
}
+ if payload.Username != "" && payload.Username != user.Username {
+ sameNameUser, err := handler.DataStore.User().UserByUsername(payload.Username)
+ if err != nil && err != portainer.ErrObjectNotFound {
+ return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve users from the database", err}
+ }
+ if sameNameUser != nil && sameNameUser.ID != portainer.UserID(userID) {
+ return &httperror.HandlerError{http.StatusConflict, "Another user with the same username already exists", portainer.ErrUserAlreadyExists}
+ }
+
+ user.Username = payload.Username
+ }
+
if payload.Password != "" {
user.Password, err = handler.CryptoService.Hash(payload.Password)
if err != nil {
diff --git a/app/portainer/services/api/userService.js b/app/portainer/services/api/userService.js
index d9950f772..ef23fffc3 100644
--- a/app/portainer/services/api/userService.js
+++ b/app/portainer/services/api/userService.js
@@ -78,12 +78,8 @@ angular.module('portainer.app').factory('UserService', [
return Users.remove({ id: id }).$promise;
};
- service.updateUser = function (id, password, role) {
- var query = {
- password: password,
- role: role,
- };
- return Users.update({ id: id }, query).$promise;
+ service.updateUser = function (id, { password, role, username }) {
+ return Users.update({ id }, { password, role, username }).$promise;
};
service.updateUserPassword = function (id, currentPassword, newPassword) {
diff --git a/app/portainer/views/users/edit/user.html b/app/portainer/views/users/edit/user.html
index 849d0d53c..bfc01dca4 100644
--- a/app/portainer/views/users/edit/user.html
+++ b/app/portainer/views/users/edit/user.html
@@ -1,7 +1,7 @@
- | - {{ user.Username }} - - | -
- - - | -