Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5a9fb623
authored
Apr 26, 2023
by
JustSong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: able to manage system vai access token (close #12)
parent
863d8424
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
92 additions
and
7 deletions
+92
-7
controller/user.go
+36
-0
middleware/auth.go
+25
-6
model/user.go
+14
-0
router/api-router.go
+1
-0
web/src/components/PersonalSetting.js
+16
-1
No files found.
controller/user.go
View file @
5a9fb623
...
...
@@ -243,6 +243,42 @@ func GetUser(c *gin.Context) {
return
}
func
GenerateAccessToken
(
c
*
gin
.
Context
)
{
id
:=
c
.
GetInt
(
"id"
)
user
,
err
:=
model
.
GetUserById
(
id
,
true
)
if
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
err
.
Error
(),
})
return
}
user
.
AccessToken
=
common
.
GetUUID
()
if
model
.
DB
.
Where
(
"token = ?"
,
user
.
AccessToken
)
.
First
(
user
)
.
RowsAffected
!=
0
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"请重试,系统生成的 UUID 竟然重复了!"
,
})
return
}
if
err
:=
user
.
Update
(
false
);
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
err
.
Error
(),
})
return
}
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
true
,
"message"
:
""
,
"data"
:
user
.
AccessToken
,
})
return
}
func
GetSelf
(
c
*
gin
.
Context
)
{
id
:=
c
.
GetInt
(
"id"
)
user
,
err
:=
model
.
GetUserById
(
id
,
false
)
...
...
middleware/auth.go
View file @
5a9fb623
...
...
@@ -16,12 +16,31 @@ func authHelper(c *gin.Context, minRole int) {
id
:=
session
.
Get
(
"id"
)
status
:=
session
.
Get
(
"status"
)
if
username
==
nil
{
c
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"success"
:
false
,
"message"
:
"无权进行此操作,未登录"
,
})
c
.
Abort
()
return
// Check access token
accessToken
:=
c
.
Request
.
Header
.
Get
(
"Authorization"
)
if
accessToken
==
""
{
c
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"success"
:
false
,
"message"
:
"无权进行此操作,未登录且未提供 access token"
,
})
c
.
Abort
()
return
}
user
:=
model
.
ValidateAccessToken
(
accessToken
)
if
user
!=
nil
&&
user
.
Username
!=
""
{
// Token is valid
username
=
user
.
Username
role
=
user
.
Role
id
=
user
.
Id
status
=
user
.
Status
}
else
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"无权进行此操作,access token 无效"
,
})
c
.
Abort
()
return
}
}
if
status
.
(
int
)
==
common
.
UserStatusDisabled
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
...
...
model/user.go
View file @
5a9fb623
...
...
@@ -3,6 +3,7 @@ package model
import
(
"errors"
"one-api/common"
"strings"
)
// User if you add sensitive fields, don't forget to clean them in setupLogin function.
...
...
@@ -19,6 +20,7 @@ type User struct {
WeChatId
string
`json:"wechat_id" gorm:"column:wechat_id;index"`
VerificationCode
string
`json:"verification_code" gorm:"-:all"`
// this field is only for Email verification, don't save it to database!
Balance
int
`json:"balance" gorm:"type:int;default:0"`
AccessToken
string
`json:"access_token" gorm:"column:access_token;uniqueIndex"`
// this token is for system management
}
func
GetMaxUserId
()
int
{
...
...
@@ -188,3 +190,15 @@ func IsAdmin(userId int) bool {
}
return
user
.
Role
>=
common
.
RoleAdminUser
}
func
ValidateAccessToken
(
token
string
)
(
user
*
User
)
{
if
token
==
""
{
return
nil
}
token
=
strings
.
Replace
(
token
,
"Bearer "
,
""
,
1
)
user
=
&
User
{}
if
DB
.
Where
(
"access_token = ?"
,
token
)
.
First
(
user
)
.
RowsAffected
==
1
{
return
user
}
return
nil
}
router/api-router.go
View file @
5a9fb623
...
...
@@ -35,6 +35,7 @@ func SetApiRouter(router *gin.Engine) {
selfRoute
.
GET
(
"/self"
,
controller
.
GetSelf
)
selfRoute
.
PUT
(
"/self"
,
controller
.
UpdateSelf
)
selfRoute
.
DELETE
(
"/self"
,
controller
.
DeleteSelf
)
selfRoute
.
GET
(
"/token"
,
controller
.
GenerateAccessToken
)
}
adminRoute
:=
userRoute
.
Group
(
"/"
)
...
...
web/src/components/PersonalSetting.js
View file @
5a9fb623
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Button
,
Divider
,
Form
,
Header
,
Image
,
Modal
}
from
'semantic-ui-react'
;
import
{
Button
,
Divider
,
Form
,
Header
,
Image
,
M
essage
,
M
odal
}
from
'semantic-ui-react'
;
import
{
Link
}
from
'react-router-dom'
;
import
{
API
,
copy
,
showError
,
showInfo
,
showSuccess
}
from
'../helpers'
;
import
Turnstile
from
'react-turnstile'
;
...
...
@@ -34,6 +34,17 @@ const PersonalSetting = () => {
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
};
const
generateAccessToken
=
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
()
=>
{
if
(
inputs
.
wechat_verification_code
===
''
)
return
;
const
res
=
await
API
.
get
(
...
...
@@ -92,9 +103,13 @@ const PersonalSetting = () => {
return
(
<
div
style
=
{{
lineHeight
:
'40px'
}}
>
<
Header
as
=
'h3'
>
通用设置
<
/Header
>
<
Message
>
注意,此处生成的令牌用于系统管理,而非用于请求
OpenAI
相关的服务,请知悉。
<
/Message
>
<
Button
as
=
{
Link
}
to
=
{
`/user/edit/`
}
>
更新个人信息
<
/Button
>
<
Button
onClick
=
{
generateAccessToken
}
>
生成系统访问令牌
<
/Button
>
<
Divider
/>
<
Header
as
=
'h3'
>
账号绑定
<
/Header
>
<
Button
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment