diff --git a/pkg/api/admin_users.go b/pkg/api/admin_users.go index 07a8cf05fd4..1b0c11543f5 100644 --- a/pkg/api/admin_users.go +++ b/pkg/api/admin_users.go @@ -29,9 +29,10 @@ func AdminGetUser(c *middleware.Context) { } result := m.UserDTO{ - Name: query.Result.Name, - Email: query.Result.Email, - Login: query.Result.Login, + Name: query.Result.Name, + Email: query.Result.Email, + Login: query.Result.Login, + IsGrafanaAdmin: query.Result.IsAdmin, } c.JSON(200, result) @@ -122,6 +123,22 @@ func AdminUpdateUserPassword(c *middleware.Context, form dtos.AdminUpdateUserPas c.JsonOK("User password updated") } +func AdminUpdateUserPermissions(c *middleware.Context, form dtos.AdminUpdateUserPermissionsForm) { + userId := c.ParamsInt64(":id") + + cmd := m.UpdateUserPermissionsCommand{ + UserId: userId, + IsGrafanaAdmin: form.IsGrafanaAdmin, + } + + if err := bus.Dispatch(&cmd); err != nil { + c.JsonApiErr(500, "Failed to update user permissions", err) + return + } + + c.JsonOK("User permissions updated") +} + func AdminDeleteUser(c *middleware.Context) { userId := c.ParamsInt64(":id") diff --git a/pkg/api/api.go b/pkg/api/api.go index f704ed3eb98..34c16075be9 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -104,6 +104,7 @@ func Register(r *macaron.Macaron) { r.Post("/users", bind(dtos.AdminCreateUserForm{}), AdminCreateUser) r.Put("/users/:id/details", bind(dtos.AdminUpdateUserForm{}), AdminUpdateUser) r.Put("/users/:id/password", bind(dtos.AdminUpdateUserPasswordForm{}), AdminUpdateUserPassword) + r.Put("/users/:id/permissions", bind(dtos.AdminUpdateUserPermissionsForm{}), AdminUpdateUserPermissions) r.Delete("/users/:id", AdminDeleteUser) }, reqGrafanaAdmin) diff --git a/pkg/api/dtos/user.go b/pkg/api/dtos/user.go index 3d671e64654..0047b3c5a98 100644 --- a/pkg/api/dtos/user.go +++ b/pkg/api/dtos/user.go @@ -16,3 +16,7 @@ type AdminUpdateUserForm struct { type AdminUpdateUserPasswordForm struct { Password string `json:"password" binding:"Required"` } + +type AdminUpdateUserPermissionsForm struct { + IsGrafanaAdmin bool `json:"IsGrafanaAdmin" binding:"Required"` +} diff --git a/pkg/models/user.go b/pkg/models/user.go index 3de69f5ac56..d5a3dbfacb6 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -59,6 +59,11 @@ type ChangeUserPasswordCommand struct { UserId int64 `json:"-"` } +type UpdateUserPermissionsCommand struct { + IsGrafanaAdmin bool + UserId int64 `json:"-"` +} + type DeleteUserCommand struct { UserId int64 } @@ -120,9 +125,10 @@ type SignedInUser struct { } type UserDTO struct { - Email string `json:"email"` - Name string `json:"name"` - Login string `json:"login"` + Email string `json:"email"` + Name string `json:"name"` + Login string `json:"login"` + IsGrafanaAdmin bool `json:"isGrafanaAdmin"` } type UserSearchHitDTO struct { diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index af3fbfcc0aa..5c3b69a2bb0 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -27,6 +27,7 @@ func init() { bus.AddHandler("sql", GetUserOrgList) bus.AddHandler("sql", DeleteUser) bus.AddHandler("sql", SetUsingOrg) + bus.AddHandler("sql", UpdateUserPermissions) } func getOrgIdForNewUser(userEmail string, sess *session) (int64, error) { @@ -284,3 +285,15 @@ func DeleteUser(cmd *m.DeleteUserCommand) error { return err }) } + +func UpdateUserPermissions(cmd *m.UpdateUserPermissionsCommand) error { + return inTransaction(func(sess *xorm.Session) error { + user := m.User{} + sess.Id(cmd.UserId).Get(&user) + + user.IsAdmin = cmd.IsGrafanaAdmin + sess.UseBool("is_admin") + _, err := sess.Id(user.Id).Update(&user) + return err + }) +} diff --git a/src/app/features/admin/adminEditUserCtrl.js b/src/app/features/admin/adminEditUserCtrl.js index 0d473bd950e..19deac532ea 100644 --- a/src/app/features/admin/adminEditUserCtrl.js +++ b/src/app/features/admin/adminEditUserCtrl.js @@ -8,6 +8,7 @@ function (angular) { module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv, $location) { $scope.user = {}; + $scope.permissions = {}; $scope.init = function() { if ($routeParams.id) { @@ -19,6 +20,7 @@ function (angular) { backendSrv.get('/api/admin/users/' + id).then(function(user) { $scope.user = user; $scope.user_id = id; + $scope.permissions.isGrafanaAdmin = user.isGrafanaAdmin; }); }; @@ -31,6 +33,14 @@ function (angular) { }); }; + $scope.updatePermissions = function() { + var payload = $scope.permissions; + + backendSrv.put('/api/admin/users/' + $scope.user_id + '/permissions', payload).then(function() { + $location.path('/admin/users'); + }); + }; + $scope.create = function() { if (!$scope.userForm.$valid) { return; } diff --git a/src/app/features/admin/partials/edit_user.html b/src/app/features/admin/partials/edit_user.html index 242dc4f51a1..9b2a18fd010 100644 --- a/src/app/features/admin/partials/edit_user.html +++ b/src/app/features/admin/partials/edit_user.html @@ -1,6 +1,5 @@ - +