mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Added change password feature, Closes #1455
This commit is contained in:
parent
afc52f57a2
commit
47c6c6e1b7
@ -50,6 +50,7 @@ func Register(r *macaron.Macaron) {
|
||||
r.Get("/accounts", GetUserAccounts)
|
||||
r.Post("/stars/dashboard/:id", StarDashboard)
|
||||
r.Delete("/stars/dashboard/:id", UnstarDashboard)
|
||||
r.Put("/password", bind(m.ChangeUserPasswordCommand{}), ChangeUserPassword)
|
||||
})
|
||||
|
||||
// account
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func GetUser(c *middleware.Context) {
|
||||
@ -84,3 +85,33 @@ func SetUsingAccount(c *middleware.Context) {
|
||||
|
||||
c.JsonOK("Active account changed")
|
||||
}
|
||||
|
||||
func ChangeUserPassword(c *middleware.Context, cmd m.ChangeUserPasswordCommand) {
|
||||
userQuery := m.GetUserByIdQuery{Id: c.UserId}
|
||||
|
||||
if err := bus.Dispatch(&userQuery); err != nil {
|
||||
c.JsonApiErr(500, "Could not read user from database", err)
|
||||
return
|
||||
}
|
||||
|
||||
passwordHashed := util.EncodePassword(cmd.OldPassword, userQuery.Result.Salt)
|
||||
if passwordHashed != userQuery.Result.Password {
|
||||
c.JsonApiErr(401, "Invalid old password", nil)
|
||||
return
|
||||
}
|
||||
|
||||
if len(cmd.NewPassword) < 4 {
|
||||
c.JsonApiErr(400, "New password too short", nil)
|
||||
return
|
||||
}
|
||||
|
||||
cmd.UserId = c.UserId
|
||||
cmd.NewPassword = util.EncodePassword(cmd.NewPassword, userQuery.Result.Salt)
|
||||
|
||||
if err := bus.Dispatch(&cmd); err != nil {
|
||||
c.JsonApiErr(500, "Failed to change user password", err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JsonOK("User password changed")
|
||||
}
|
||||
|
@ -52,6 +52,13 @@ type UpdateUserCommand struct {
|
||||
UserId int64 `json:"-"`
|
||||
}
|
||||
|
||||
type ChangeUserPasswordCommand struct {
|
||||
OldPassword string `json:"oldPassword"`
|
||||
NewPassword string `json:"newPassword"`
|
||||
|
||||
UserId int64 `json:"-"`
|
||||
}
|
||||
|
||||
type DeleteUserCommand struct {
|
||||
UserId int64
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ func init() {
|
||||
bus.AddHandler("sql", CreateUser)
|
||||
bus.AddHandler("sql", GetUserById)
|
||||
bus.AddHandler("sql", UpdateUser)
|
||||
bus.AddHandler("sql", ChangeUserPassword)
|
||||
bus.AddHandler("sql", GetUserByLogin)
|
||||
bus.AddHandler("sql", SetUsingAccount)
|
||||
bus.AddHandler("sql", GetUserInfo)
|
||||
@ -181,6 +182,22 @@ func UpdateUser(cmd *m.UpdateUserCommand) error {
|
||||
})
|
||||
}
|
||||
|
||||
func ChangeUserPassword(cmd *m.ChangeUserPasswordCommand) error {
|
||||
return inTransaction2(func(sess *session) error {
|
||||
|
||||
user := m.User{
|
||||
Password: cmd.NewPassword,
|
||||
Updated: time.Now(),
|
||||
}
|
||||
|
||||
if _, err := sess.Id(cmd.UserId).Update(&user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func SetUsingAccount(cmd *m.SetUsingAccountCommand) error {
|
||||
return inTransaction(func(sess *xorm.Session) error {
|
||||
user := m.User{}
|
||||
|
@ -9,6 +9,7 @@ define([
|
||||
'./dashboard/all',
|
||||
'./panel/all',
|
||||
'./profile/profileCtrl',
|
||||
'./profile/changePasswordCtrl',
|
||||
'./account/all',
|
||||
'./admin/all',
|
||||
'./grafanaDatasource/datasource',
|
||||
|
@ -120,7 +120,7 @@ function (angular, _, kbn) {
|
||||
}
|
||||
|
||||
function convertTargetToQuery(target) {
|
||||
if (!target.metric) {
|
||||
if (!target.metric || target.hide) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
28
src/app/features/profile/changePasswordCtrl.js
Normal file
28
src/app/features/profile/changePasswordCtrl.js
Normal file
@ -0,0 +1,28 @@
|
||||
define([
|
||||
'angular',
|
||||
'config',
|
||||
],
|
||||
function (angular) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('ChangePasswordCtrl', function($scope, backendSrv, $location) {
|
||||
|
||||
$scope.command = {};
|
||||
|
||||
$scope.changePassword = function() {
|
||||
if (!$scope.userForm.$valid) { return; }
|
||||
|
||||
if ($scope.command.newPassword !== $scope.command.confirmNew) {
|
||||
$scope.appEvent('alert-warning', ['New passwords do not match', '']);
|
||||
return;
|
||||
}
|
||||
|
||||
backendSrv.put('/api/user/password', $scope.command).then(function() {
|
||||
$location.path("profile");
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
});
|
56
src/app/features/profile/partials/password.html
Normal file
56
src/app/features/profile/partials/password.html
Normal file
@ -0,0 +1,56 @@
|
||||
<topnav title="{{contextSrv.user.name}}" section="Profile" icon="fa fa-user" subnav="true">
|
||||
<ul class="nav">
|
||||
<li><a href="profile">Overview</a></li>
|
||||
<li class="active"><a href="profile/password">Change password</a></li>
|
||||
</ul>
|
||||
</topnav>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page">
|
||||
|
||||
<h2>Change password</h2>
|
||||
|
||||
<form name="userForm">
|
||||
<div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
<strong>Old Password</strong>
|
||||
</li>
|
||||
<li>
|
||||
<input type="password" required ng-model="command.oldPassword" 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>New Password</strong>
|
||||
</li>
|
||||
<li>
|
||||
<input type="password" required ng-model="command.newPassword" ng-minlength="4" 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>Confirm New</strong>
|
||||
</li>
|
||||
<li>
|
||||
<input type="password" required ng-model="command.confirmNew" ng-minlength="4" 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="changePassword()">Change Password</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,8 @@
|
||||
<topnav title="{{contextSrv.user.name}}"
|
||||
section="Profile"
|
||||
icon="fa fa-user">
|
||||
<topnav title="{{contextSrv.user.name}}" section="Profile" icon="fa fa-user" subnav="true">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="profile">Overview</a></li>
|
||||
<li><a href="profile/password">Change password</a></li>
|
||||
</ul>
|
||||
</topnav>
|
||||
|
||||
<div class="page-container">
|
||||
|
@ -7,7 +7,7 @@ function (angular, config) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('ProfileCtrl', function($scope, $http, backendSrv) {
|
||||
module.controller('ProfileCtrl', function($scope, backendSrv) {
|
||||
|
||||
$scope.newAccount = {name: ''};
|
||||
|
||||
|
@ -62,6 +62,10 @@ define([
|
||||
templateUrl: 'app/features/profile/partials/profile.html',
|
||||
controller : 'ProfileCtrl',
|
||||
})
|
||||
.when('/profile/password', {
|
||||
templateUrl: 'app/features/profile/partials/password.html',
|
||||
controller : 'ChangePasswordCtrl',
|
||||
})
|
||||
.when('/admin/settings', {
|
||||
templateUrl: 'app/features/admin/partials/settings.html',
|
||||
controller : 'AdminSettingsCtrl',
|
||||
|
Loading…
Reference in New Issue
Block a user