mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Worked on user admin features, can now create and edit users as a grafana admin user, #1446
This commit is contained in:
parent
088ad881e0
commit
e165e2af95
@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
@ -12,9 +13,83 @@ func AdminSearchUsers(c *middleware.Context) {
|
|||||||
|
|
||||||
query := m.SearchUsersQuery{Query: "", Page: 0, Limit: 20}
|
query := m.SearchUsersQuery{Query: "", Page: 0, Limit: 20}
|
||||||
if err := bus.Dispatch(&query); err != nil {
|
if err := bus.Dispatch(&query); err != nil {
|
||||||
c.JsonApiErr(500, "Failed to fetch collaboratos", err)
|
c.JsonApiErr(500, "Failed to fetch users", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(200, query.Result)
|
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")
|
||||||
|
}
|
||||||
|
@ -93,6 +93,9 @@ func Register(r *macaron.Macaron) {
|
|||||||
// admin api
|
// admin api
|
||||||
r.Group("/api/admin", func() {
|
r.Group("/api/admin", func() {
|
||||||
r.Get("/users", AdminSearchUsers)
|
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)
|
}, reqGrafanaAdmin)
|
||||||
|
|
||||||
// rendering
|
// rendering
|
||||||
|
14
pkg/api/dtos/user.go
Normal file
14
pkg/api/dtos/user.go
Normal file
@ -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"`
|
||||||
|
}
|
@ -63,6 +63,11 @@ type GetUserByLoginQuery struct {
|
|||||||
Result *User
|
Result *User
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetUserByIdQuery struct {
|
||||||
|
Id int64
|
||||||
|
Result *User
|
||||||
|
}
|
||||||
|
|
||||||
type GetSignedInUserQuery struct {
|
type GetSignedInUserQuery struct {
|
||||||
UserId int64
|
UserId int64
|
||||||
Result *SignedInUser
|
Result *SignedInUser
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
bus.AddHandler("sql", CreateUser)
|
bus.AddHandler("sql", CreateUser)
|
||||||
|
bus.AddHandler("sql", GetUserById)
|
||||||
bus.AddHandler("sql", UpdateUser)
|
bus.AddHandler("sql", UpdateUser)
|
||||||
bus.AddHandler("sql", GetUserByLogin)
|
bus.AddHandler("sql", GetUserByLogin)
|
||||||
bus.AddHandler("sql", SetUsingAccount)
|
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 {
|
func GetUserByLogin(query *m.GetUserByLoginQuery) error {
|
||||||
if query.LoginOrEmail == "" {
|
if query.LoginOrEmail == "" {
|
||||||
return m.ErrAccountNotFound
|
return m.ErrUserNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
user := new(m.User)
|
user := new(m.User)
|
||||||
|
40
src/app/features/admin/adminEditUserCtrl.js
Normal file
40
src/app/features/admin/adminEditUserCtrl.js
Normal file
@ -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();
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
74
src/app/features/admin/partials/edit_user.html
Normal file
74
src/app/features/admin/partials/edit_user.html
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<topnav icon="fa fa-cube" title="Admin" subnav="true">
|
||||||
|
<ul class="nav">
|
||||||
|
<li><a href="admin">Settings</a></li>
|
||||||
|
<li><a href="admin/users">Users</a></li>
|
||||||
|
<li ng-class="{active: createMode}"><a href="admin/users/new">Create user</a></li>
|
||||||
|
<li class="active" ng-show="!createMode"><a href="admin/users/new">Edit user</a></li>
|
||||||
|
</ul>
|
||||||
|
</topnav>
|
||||||
|
|
||||||
|
<div class="page-container">
|
||||||
|
<div class="page">
|
||||||
|
<h2 ng-show="createMode">
|
||||||
|
Create a new user
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<h2 ng-show="!createMode">
|
||||||
|
Edit user
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<form name="userForm">
|
||||||
|
<div>
|
||||||
|
<div class="tight-form">
|
||||||
|
<ul class="tight-form-list">
|
||||||
|
<li class="tight-form-item" style="width: 100px">
|
||||||
|
<strong>Name</strong>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" required ng-model="user.name" class="input-xxlarge tight-form-input last" >
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<div class="tight-form" style="margin-top: 5px">
|
||||||
|
<ul class="tight-form-list">
|
||||||
|
<li class="tight-form-item" style="width: 100px">
|
||||||
|
<strong>Email</strong>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="email" ng-model="user.email" class="input-xxlarge tight-form-input last" >
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<div class="tight-form" style="margin-top: 5px">
|
||||||
|
<ul class="tight-form-list">
|
||||||
|
<li class="tight-form-item" style="width: 100px">
|
||||||
|
<strong>Username</strong>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="text" ng-model="user.login" class="input-xxlarge tight-form-input last" >
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tight-form" style="margin-top: 5px" ng-if="createMode">
|
||||||
|
<ul class="tight-form-list">
|
||||||
|
<li class="tight-form-item" style="width: 100px">
|
||||||
|
<strong>Password</strong>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="password" required ng-model="user.password" class="input-xxlarge tight-form-input last" >
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<button type="submit" class="pull-right btn btn-success" ng-click="update()" ng-show="createMode">Create</button>
|
||||||
|
<button type="submit" class="pull-right btn btn-success" ng-click="update()" ng-show="!createMode">Update</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -2,30 +2,33 @@
|
|||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
<li><a href="admin">Settings</a></li>
|
<li><a href="admin">Settings</a></li>
|
||||||
<li class="active"><a href="admin/users">Users</a></li>
|
<li class="active"><a href="admin/users">Users</a></li>
|
||||||
|
<li><a href="admin/users/create">Create user</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</topnav>
|
</topnav>
|
||||||
|
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<h2>Users</h2>
|
<h2>
|
||||||
|
Users
|
||||||
|
</h2>
|
||||||
|
|
||||||
<table class="grafana-options-table">
|
<table class="grafana-options-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="text-align:left">Id</th>
|
<th style="text-align:left">Id</th>
|
||||||
|
<th>Name</th>
|
||||||
<th>Login</th>
|
<th>Login</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Name</th>
|
|
||||||
<th>Admin</th>
|
<th>Admin</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-repeat="user in users">
|
<tr ng-repeat="user in users">
|
||||||
<td>{{user.id}}</td>
|
<td>{{user.id}}</td>
|
||||||
|
<td>{{user.name}}</td>
|
||||||
<td>{{user.login}}</td>
|
<td>{{user.login}}</td>
|
||||||
<td>{{user.email}}</td>
|
<td>{{user.email}}</td>
|
||||||
<td>{{user.name}}</td>
|
|
||||||
<td>{{user.isAdmin}}</td>
|
<td>{{user.isAdmin}}</td>
|
||||||
<td style="width: 1%">
|
<td style="width: 1%">
|
||||||
<a ng-click="edit(variable)" class="btn btn-success btn-small">
|
<a href="admin/users/edit/{{user.id}}" class="btn btn-inverse btn-small">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i>
|
||||||
Edit
|
Edit
|
||||||
</a>
|
</a>
|
||||||
|
@ -16,5 +16,6 @@ define([
|
|||||||
'./account/accountCtrl',
|
'./account/accountCtrl',
|
||||||
'./admin/adminUsersCtrl',
|
'./admin/adminUsersCtrl',
|
||||||
'./admin/adminCtrl',
|
'./admin/adminCtrl',
|
||||||
|
'./admin/adminEditUserCtrl',
|
||||||
'./grafanaDatasource/datasource',
|
'./grafanaDatasource/datasource',
|
||||||
], function () {});
|
], function () {});
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<strong>Email</strong>
|
<strong>Email</strong>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="text" required ng-model="user.email" class="input-xxlarge tight-form-input last" >
|
<input type="email" required ng-model="user.email" class="input-xxlarge tight-form-input last" >
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
|
@ -62,6 +62,14 @@ define([
|
|||||||
templateUrl: 'app/features/admin/partials/users.html',
|
templateUrl: 'app/features/admin/partials/users.html',
|
||||||
controller : 'AdminUsersCtrl',
|
controller : 'AdminUsersCtrl',
|
||||||
})
|
})
|
||||||
|
.when('/admin/users/create', {
|
||||||
|
templateUrl: 'app/features/admin/partials/edit_user.html',
|
||||||
|
controller : 'AdminEditUserCtrl',
|
||||||
|
})
|
||||||
|
.when('/admin/users/edit/:id', {
|
||||||
|
templateUrl: 'app/features/admin/partials/edit_user.html',
|
||||||
|
controller : 'AdminEditUserCtrl',
|
||||||
|
})
|
||||||
.when('/login', {
|
.when('/login', {
|
||||||
templateUrl: 'app/partials/login.html',
|
templateUrl: 'app/partials/login.html',
|
||||||
controller : 'LoginCtrl',
|
controller : 'LoginCtrl',
|
||||||
|
Loading…
Reference in New Issue
Block a user