added change password for current user

This commit is contained in:
knoxfighter 2021-01-14 03:48:01 +01:00
parent f8fa0494bd
commit 63186c61dc
6 changed files with 162 additions and 0 deletions

View File

@ -171,6 +171,29 @@ func (a *Auth) removeUser(username string) error {
return nil
}
func (a *Auth) changePassword(username, password string) error {
var user User
result := a.db.Model(&User{}).Where(&User{Username: username}).Take(&user)
if result.Error != nil {
return result.Error
}
hashPW, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
// TODO
return err
}
user.Password = base64.StdEncoding.EncodeToString(hashPW)
result = a.db.Save(&user)
if result.Error != nil {
return result.Error
}
return nil
}
// middleware function, that will be called for every request, that has to be authorized
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

View File

@ -597,6 +597,66 @@ func RemoveUser(w http.ResponseWriter, r *http.Request) {
resp = fmt.Sprintf("User: %s successfully removed.", user.Username)
}
func ChangePassword(w http.ResponseWriter, r *http.Request) {
var resp interface{}
defer func() {
WriteResponse(w, resp)
}()
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
body, err := ReadRequestBody(w, r, &resp)
if err != nil {
return
}
var user struct {
OldPassword string `json:"old_password"`
NewPassword string `json:"new_password"`
NewPasswordConfirm string `json:"new_password_confirmation"`
}
err = json.Unmarshal(body, &user)
if err != nil {
resp = fmt.Sprintf("Unable to parse the request body: %s", err)
log.Println(resp)
w.WriteHeader(http.StatusBadRequest)
return
}
// only allow to change its own password
// get username from session cookie
session, err := sessionStore.Get(r, "authentication")
if err != nil {
// TODO
return
}
username := session.Values["username"].(string)
// check if password for user is correct
err = auth.checkPassword(username, user.OldPassword)
if err != nil {
// TODO
w.WriteHeader(http.StatusUnauthorized)
return
}
// only run, when confirmation correct
if user.NewPassword != user.NewPasswordConfirm {
// TODO
w.WriteHeader(http.StatusBadRequest)
return
}
err = auth.changePassword(username, user.NewPassword)
if err != nil {
// TODO
w.WriteHeader(http.StatusInternalServerError)
return
}
}
// GetServerSettings returns JSON response of server-settings.json file
func GetServerSettings(w http.ResponseWriter, r *http.Request) {
var resp interface{}

View File

@ -199,6 +199,11 @@ var apiRoutes = Routes{
"POST",
"/user/remove",
RemoveUser,
}, {
"ChangePassword",
"POST",
"/user/password",
ChangePassword,
}, {
"GetServerSettings",
"GET",

View File

@ -2,6 +2,7 @@ import Panel from "../../components/Panel";
import React, {useCallback, useEffect, useState} from "react";
import user from "../../../api/resources/user";
import CreateUserForm from "./components/CreateUserForm";
import ChangePasswordForm from "./components/ChangePasswordForm"
import {faTrashAlt} from "@fortawesome/free-solid-svg-icons";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
@ -55,9 +56,15 @@ const UserManagement = () => {
}
className="mb-4"
/>
<Panel
title="Change Password"
content={<ChangePasswordForm/>}
className="mb-4"
/>
<Panel
title="Create User"
content={<CreateUserForm updateUserList={updateList}/>}
className="mb-4"
/>
</>
)

View File

@ -0,0 +1,63 @@
import {useForm} from "react-hook-form";
import React from "react";
import user from "../../../../api/resources/user";
import Button from "../../../components/Button";
const ChangePasswordForm = () => {
const {register, handleSubmit, errors, watch} = useForm();
const password = watch('new_password');
const onSubmit = async (data) => {
const res = await user.changePassword(data);
if (res) {
// Update successful
}
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="mb-4">
<label className="block text-white text-sm font-bold mb-2" htmlFor="old_password">
Old Password:
</label>
<input className="shadow appearance-none border w-full py-2 px-3 text-black"
ref={register({required: true})}
id="old_password"
name="old_password"
type="password"
placeholder="**********"
/>
{errors.old_password && <span className="block text-red">Old Password is required</span>}
</div>
<div className="mb-4">
<label className="block text-white text-sm font-bold mb-2" htmlFor="new_password">
New Password:
</label>
<input className="shadow appearance-none border w-full py-2 px-3 text-black"
ref={register({required: true})}
id="new_password"
name="new_password"
type="password"
placeholder="**********"
/>
{errors.new_password && <span className="block text-red">New Password is required</span>}
</div>
<div className="mb-4">
<label className="block text-white text-sm font-bold mb-2" htmlFor="new_password_confirmation">
New Password Confirmation:
</label>
<input className="shadow appearance-none border w-full py-2 px-3 text-black"
ref={register({required: true, validate: confirmation => confirmation === password})}
id="new_password_confirmation"
name="new_password_confirmation"
type="password"
placeholder="**********"
/>
{errors.new_password_confirmation && <span className="block text-red">New Password Confirmation is required</span>}
</div>
<Button isSubmit={true} type="success">Change</Button>
</form>
)
}
export default ChangePasswordForm

View File

@ -24,5 +24,9 @@ export default {
delete: async (username) => {
const response = await client.post('/api/user/remove', JSON.stringify({username}));
return response.data;
},
changePassword: async data => {
const response = await client.post('/api/user/password', data);
return response.data;
}
}