diff --git a/pkg/api/admin_users.go b/pkg/api/admin_users.go
index b202c5ce2a8..0ffe0612ac0 100644
--- a/pkg/api/admin_users.go
+++ b/pkg/api/admin_users.go
@@ -1,6 +1,7 @@
package api
import (
+ "github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
@@ -12,9 +13,83 @@ func AdminSearchUsers(c *middleware.Context) {
query := m.SearchUsersQuery{Query: "", Page: 0, Limit: 20}
if err := bus.Dispatch(&query); err != nil {
- c.JsonApiErr(500, "Failed to fetch collaboratos", err)
+ c.JsonApiErr(500, "Failed to fetch users", err)
return
}
c.JSON(200, query.Result)
}
+
+func AdminGetUser(c *middleware.Context) {
+ userId := c.ParamsInt64(":id")
+
+ query := m.GetUserByIdQuery{Id: userId}
+
+ if err := bus.Dispatch(&query); err != nil {
+ c.JsonApiErr(500, "Failed to fetch user", err)
+ return
+ }
+
+ result := m.UserDTO{
+ Name: query.Result.Name,
+ Email: query.Result.Email,
+ Login: query.Result.Login,
+ }
+
+ c.JSON(200, result)
+}
+
+func AdminCreateUser(c *middleware.Context, form dtos.AdminCreateUserForm) {
+ cmd := m.CreateUserCommand{
+ Login: form.Login,
+ Email: form.Email,
+ Password: form.Password,
+ Name: form.Name,
+ }
+
+ if len(cmd.Login) == 0 {
+ cmd.Login = cmd.Email
+ if len(cmd.Login) == 0 {
+ c.JsonApiErr(400, "Validation error, need specify either username or email", nil)
+ return
+ }
+ }
+
+ if len(cmd.Password) < 4 {
+ c.JsonApiErr(400, "Password is missing or too short", nil)
+ return
+ }
+
+ if err := bus.Dispatch(&cmd); err != nil {
+ c.JsonApiErr(500, "failed to create user", err)
+ return
+ }
+
+ c.JsonOK("User created")
+}
+
+func AdminUpdateUser(c *middleware.Context, form dtos.AdminUpdateUserForm) {
+ userId := c.ParamsInt64(":id")
+
+ cmd := m.UpdateUserCommand{
+ UserId: userId,
+ Login: form.Login,
+ Email: form.Email,
+ Name: form.Name,
+ }
+
+ if len(cmd.Login) == 0 {
+ cmd.Login = cmd.Email
+ if len(cmd.Login) == 0 {
+ c.JsonApiErr(400, "Validation error, need specify either username or email", nil)
+ return
+ }
+ }
+
+ if err := bus.Dispatch(&cmd); err != nil {
+ c.JsonApiErr(500, "failed to update user", err)
+ return
+ }
+
+ c.JsonOK("User updated")
+}
diff --git a/pkg/api/api.go b/pkg/api/api.go
index 02994d1047f..4595869ab0b 100644
--- a/pkg/api/api.go
+++ b/pkg/api/api.go
@@ -93,6 +93,9 @@ func Register(r *macaron.Macaron) {
// admin api
r.Group("/api/admin", func() {
r.Get("/users", AdminSearchUsers)
+ r.Get("/users/:id", AdminGetUser)
+ r.Post("/users", bind(dtos.AdminCreateUserForm{}), AdminCreateUser)
+ r.Put("/users/:id", bind(dtos.AdminUpdateUserForm{}), AdminUpdateUser)
}, reqGrafanaAdmin)
// rendering
diff --git a/pkg/api/dtos/user.go b/pkg/api/dtos/user.go
new file mode 100644
index 00000000000..69fc3797029
--- /dev/null
+++ b/pkg/api/dtos/user.go
@@ -0,0 +1,14 @@
+package dtos
+
+type AdminCreateUserForm struct {
+ Email string `json:"email"`
+ Login string `json:"login"`
+ Name string `json:"name"`
+ Password string `json:"password" binding:"Required"`
+}
+
+type AdminUpdateUserForm struct {
+ Email string `json:"email"`
+ Login string `json:"login"`
+ Name string `json:"name"`
+}
diff --git a/pkg/models/user.go b/pkg/models/user.go
index 0a3de0c9a4d..b63ded299c7 100644
--- a/pkg/models/user.go
+++ b/pkg/models/user.go
@@ -63,6 +63,11 @@ type GetUserByLoginQuery struct {
Result *User
}
+type GetUserByIdQuery struct {
+ Id int64
+ Result *User
+}
+
type GetSignedInUserQuery struct {
UserId int64
Result *SignedInUser
diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go
index f56a64c8c0e..ac7286af77c 100644
--- a/pkg/services/sqlstore/user.go
+++ b/pkg/services/sqlstore/user.go
@@ -15,6 +15,7 @@ import (
func init() {
bus.AddHandler("sql", CreateUser)
+ bus.AddHandler("sql", GetUserById)
bus.AddHandler("sql", UpdateUser)
bus.AddHandler("sql", GetUserByLogin)
bus.AddHandler("sql", SetUsingAccount)
@@ -112,9 +113,24 @@ func CreateUser(cmd *m.CreateUserCommand) error {
})
}
+func GetUserById(query *m.GetUserByIdQuery) error {
+ user := new(m.User)
+ has, err := x.Id(query.Id).Get(user)
+
+ if err != nil {
+ return err
+ } else if has == false {
+ return m.ErrUserNotFound
+ }
+
+ query.Result = user
+
+ return nil
+}
+
func GetUserByLogin(query *m.GetUserByLoginQuery) error {
if query.LoginOrEmail == "" {
- return m.ErrAccountNotFound
+ return m.ErrUserNotFound
}
user := new(m.User)
diff --git a/src/app/features/admin/adminEditUserCtrl.js b/src/app/features/admin/adminEditUserCtrl.js
new file mode 100644
index 00000000000..d01d5d8559d
--- /dev/null
+++ b/src/app/features/admin/adminEditUserCtrl.js
@@ -0,0 +1,40 @@
+define([
+ 'angular',
+],
+function (angular) {
+ 'use strict';
+
+ var module = angular.module('grafana.controllers');
+
+ module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv) {
+ $scope.user = {};
+
+ $scope.init = function() {
+ if ($routeParams.id) {
+ $scope.createMode = false;
+ $scope.getUser($routeParams.id);
+ } else {
+ $scope.createMode = true;
+ }
+ };
+
+ $scope.getUser = function(id) {
+ backendSrv.get('/api/admin/users/' + id).then(function(user) {
+ $scope.user = user;
+ $scope.user_id = id;
+ });
+ };
+
+ $scope.update = function() {
+ if (!$scope.userForm.$valid) { return; }
+ if ($scope.createMode) {
+ backendSrv.post('/api/admin/users', $scope.user);
+ } else {
+ backendSrv.put('/api/admin/users/' + $scope.user_id, $scope.user);
+ }
+ };
+
+ $scope.init();
+
+ });
+});
diff --git a/src/app/features/admin/partials/edit_user.html b/src/app/features/admin/partials/edit_user.html
new file mode 100644
index 00000000000..4209b280d5b
--- /dev/null
+++ b/src/app/features/admin/partials/edit_user.html
@@ -0,0 +1,74 @@
+
Id | +Name | Login | Name | Admin | ||
---|---|---|---|---|---|---|
{{user.id}} | +{{user.name}} | {{user.login}} | {{user.email}} | -{{user.name}} | {{user.isAdmin}} |
-
+
Edit
diff --git a/src/app/features/all.js b/src/app/features/all.js
index a262a57b5ba..6ebabafcbad 100644
--- a/src/app/features/all.js
+++ b/src/app/features/all.js
@@ -16,5 +16,6 @@ define([
'./account/accountCtrl',
'./admin/adminUsersCtrl',
'./admin/adminCtrl',
+ './admin/adminEditUserCtrl',
'./grafanaDatasource/datasource',
], function () {});
diff --git a/src/app/features/profile/partials/profile.html b/src/app/features/profile/partials/profile.html
index 2a839db6e10..db9d9b52702 100644
--- a/src/app/features/profile/partials/profile.html
+++ b/src/app/features/profile/partials/profile.html
@@ -27,7 +27,7 @@
Email
|