chore: update token related logic

This commit is contained in:
JustSong
2022-11-11 20:02:28 +08:00
parent e1d09aa58f
commit d42b4511cf
6 changed files with 71 additions and 55 deletions

View File

@@ -57,9 +57,16 @@ func pushMessageHelper(c *gin.Context, message *channel.Message) {
}) })
return return
} }
if user.Token != "" { if user.Token != "" && user.Token != " " {
if message.Token == "" { if message.Token == "" {
message.Token = c.Request.Header.Get("Authorization") message.Token = c.Request.Header.Get("Authorization")
if message.Token == "" {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": "token 为空",
})
return
}
} }
if user.Token != message.Token { if user.Token != message.Token {
c.JSON(http.StatusForbidden, gin.H{ c.JSON(http.StatusForbidden, gin.H{

View File

@@ -350,7 +350,9 @@ func UpdateSelf(c *gin.Context) {
}) })
return return
} }
if user.Password == "" {
user.Password = "$I_LOVE_U" // make Validator happy :)
}
if err := common.Validate.Struct(&user); err != nil { if err := common.Validate.Struct(&user); err != nil {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
@@ -364,8 +366,15 @@ func UpdateSelf(c *gin.Context) {
Username: user.Username, Username: user.Username,
Password: user.Password, Password: user.Password,
DisplayName: user.DisplayName, DisplayName: user.DisplayName,
Token: user.Token,
}
if cleanUser.Token == "" {
cleanUser.Token = " " // this is because gorm will ignore zero value
}
if user.Password == "$I_LOVE_U" {
user.Password = "" // rollback to what it should be
cleanUser.Password = ""
} }
updatePassword := user.Password != "" updatePassword := user.Password != ""
if err := cleanUser.Update(updatePassword); err != nil { if err := cleanUser.Update(updatePassword); err != nil {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{

View File

@@ -16,7 +16,7 @@ func authHelper(c *gin.Context, minRole int) {
if username == nil { if username == nil {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
"message": "无权进行此操作,未登录或 token 无效", "message": "无权进行此操作,用户未登录",
}) })
c.Abort() c.Abort()
return return
@@ -32,7 +32,7 @@ func authHelper(c *gin.Context, minRole int) {
if role.(int) < minRole { if role.(int) < minRole {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
"message": "无权进行此操作,未登录或 token 无效,或没有权限", "message": "无权进行此操作,用户未登录或没有权限",
}) })
c.Abort() c.Abort()
return return

View File

@@ -3,7 +3,6 @@ package model
import ( import (
"errors" "errors"
"message-pusher/common" "message-pusher/common"
"strings"
) )
type User struct { type User struct {
@@ -13,7 +12,7 @@ type User struct {
DisplayName string `json:"display_name" gorm:"index" validate:"max=20"` DisplayName string `json:"display_name" gorm:"index" validate:"max=20"`
Role int `json:"role" gorm:"type:int;default:1"` // admin, common Role int `json:"role" gorm:"type:int;default:1"` // admin, common
Status int `json:"status" gorm:"type:int;default:1"` // enabled, disabled Status int `json:"status" gorm:"type:int;default:1"` // enabled, disabled
Token string `json:"token;" gorm:"index"` Token string `json:"token"`
Email string `json:"email" gorm:"index" validate:"max=50"` Email string `json:"email" gorm:"index" validate:"max=50"`
GitHubId string `json:"github_id" gorm:"column:github_id;index"` GitHubId string `json:"github_id" gorm:"column:github_id;index"`
WeChatId string `json:"wechat_id" gorm:"column:wechat_id;index"` WeChatId string `json:"wechat_id" gorm:"column:wechat_id;index"`
@@ -43,7 +42,7 @@ func GetUserById(id int, selectAll bool) (*User, error) {
if selectAll { if selectAll {
err = DB.First(&user, "id = ?", id).Error err = DB.First(&user, "id = ?", id).Error
} else { } else {
err = DB.Select([]string{"id", "username", "display_name", "role", "status", "email", "wechat_id", "github_id"}).First(&user, "id = ?", id).Error err = DB.Select([]string{"id", "username", "display_name", "role", "status", "email", "wechat_id", "github_id", "token"}).First(&user, "id = ?", id).Error
} }
return &user, err return &user, err
} }
@@ -118,18 +117,6 @@ func (user *User) FillUserByUsername() {
DB.Where(User{Username: user.Username}).First(user) DB.Where(User{Username: user.Username}).First(user)
} }
func ValidateUserToken(token string) (user *User) {
if token == "" {
return nil
}
token = strings.Replace(token, "Bearer ", "", 1)
user = &User{}
if DB.Where("token = ?", token).First(user).RowsAffected == 1 {
return user
}
return nil
}
func IsEmailAlreadyTaken(email string) bool { func IsEmailAlreadyTaken(email string) bool {
return DB.Where("email = ?", email).Find(&User{}).RowsAffected == 1 return DB.Where("email = ?", email).Find(&User{}).RowsAffected == 1
} }

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Image, Modal } from 'semantic-ui-react'; import { Button, Form, Image, Modal } from 'semantic-ui-react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { API, copy, showError, showSuccess } from '../helpers'; import { API, showError, showSuccess } from '../helpers';
const PersonalSetting = () => { const PersonalSetting = () => {
const [inputs, setInputs] = useState({ const [inputs, setInputs] = useState({
@@ -25,17 +25,6 @@ const PersonalSetting = () => {
setInputs((inputs) => ({ ...inputs, [name]: value })); setInputs((inputs) => ({ ...inputs, [name]: value }));
}; };
const generateToken = async () => {
const res = await API.get('/api/user/token');
const { success, message, data } = res.data;
if (success) {
await copy(data);
showSuccess(`令牌已重置并已复制到剪切板:${data}`);
} else {
showError(message);
}
};
const bindWeChat = async () => { const bindWeChat = async () => {
if (inputs.wechat_verification_code === '') return; if (inputs.wechat_verification_code === '') return;
const res = await API.get( const res = await API.get(
@@ -86,7 +75,6 @@ const PersonalSetting = () => {
<Button as={Link} to={`/user/edit/`}> <Button as={Link} to={`/user/edit/`}>
更新个人信息 更新个人信息
</Button> </Button>
<Button onClick={generateToken}>生成访问令牌</Button>
<Button <Button
onClick={() => { onClick={() => {
setShowWeChatBindModal(true); setShowWeChatBindModal(true);

View File

@@ -13,9 +13,18 @@ const EditUser = () => {
password: '', password: '',
github_id: '', github_id: '',
wechat_id: '', wechat_id: '',
email:'' email: '',
token: '',
}); });
const { username, display_name, password, github_id, wechat_id, email } = inputs; const {
username,
display_name,
password,
github_id,
wechat_id,
email,
token,
} = inputs;
const handleInputChange = (e, { name, value }) => { const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value })); setInputs((inputs) => ({ ...inputs, [name]: value }));
}; };
@@ -30,6 +39,9 @@ const EditUser = () => {
const { success, message, data } = res.data; const { success, message, data } = res.data;
if (success) { if (success) {
data.password = ''; data.password = '';
if (data.token === ' ') {
data.token = '';
}
setInputs(data); setInputs(data);
} else { } else {
showError(message); showError(message);
@@ -58,64 +70,77 @@ const EditUser = () => {
return ( return (
<> <>
<Segment loading={loading}> <Segment loading={loading}>
<Header as="h3">更新用户信息</Header> <Header as='h3'>更新用户信息</Header>
<Form autoComplete="off"> <Form autoComplete='off'>
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label="用户名" label='用户名'
name="username" name='username'
placeholder={'请输入新的用户名'} placeholder={'请输入新的用户名'}
onChange={handleInputChange} onChange={handleInputChange}
value={username} value={username}
autoComplete="off" autoComplete='off'
/> />
</Form.Field> </Form.Field>
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label="密码" label='密码'
name="password" name='password'
type={'password'} type={'password'}
placeholder={'请输入新的密码'} placeholder={'请输入新的密码'}
onChange={handleInputChange} onChange={handleInputChange}
value={password} value={password}
autoComplete="off" autoComplete='off'
/> />
</Form.Field> </Form.Field>
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label="显示名称" label='显示名称'
name="display_name" name='display_name'
placeholder={'请输入新的显示名称'} placeholder={'请输入新的显示名称'}
onChange={handleInputChange} onChange={handleInputChange}
value={display_name} value={display_name}
autoComplete="off" autoComplete='off'
/> />
</Form.Field> </Form.Field>
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label="已绑定的 GitHub 账户" label='推送鉴权 Token'
name="github_id" name='token'
placeholder={'请输入新的 Token留空则将 Token 置空'}
onChange={handleInputChange}
value={token}
autoComplete='off'
/>
</Form.Field>
<Form.Field>
<Form.Input
label='已绑定的 GitHub 账户'
name='github_id'
value={github_id} value={github_id}
autoComplete="off" autoComplete='off'
readOnly readOnly
placeholder={'如需绑定请到个人设置页面进行绑定'}
/> />
</Form.Field> </Form.Field>
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label="已绑定的微信账户" label='已绑定的微信账户'
name="wechat_id" name='wechat_id'
value={wechat_id} value={wechat_id}
autoComplete="off" autoComplete='off'
readOnly readOnly
placeholder={'如需绑定请到个人设置页面进行绑定'}
/> />
</Form.Field> </Form.Field>
<Form.Field> <Form.Field>
<Form.Input <Form.Input
label="已绑定的邮箱账户" label='已绑定的邮箱账户'
name="email" name='email'
value={email} value={email}
autoComplete="off" autoComplete='off'
readOnly readOnly
placeholder={'如需绑定请到个人设置页面进行绑定'}
/> />
</Form.Field> </Form.Field>
<Button onClick={submit}>提交</Button> <Button onClick={submit}>提交</Button>