Compare commits

...

4 Commits

Author SHA1 Message Date
lejianwen
9b4fa679c2 add batch add ab from peer
add batch update ab tags
2024-12-06 19:45:41 +08:00
lejianwen
c2ae95c4cc up api docs 2024-12-06 10:36:40 +08:00
lejianwen
b2b7f60fd5 add batch delete user token 2024-12-06 10:36:27 +08:00
lejianwen
a465888b31 up username length to 32 #70 2024-12-06 10:22:28 +08:00
15 changed files with 214 additions and 37 deletions

View File

@@ -3569,7 +3569,7 @@ const docTemplateadmin = `{
"token": []
}
],
"description": "登录凭证删除",
"description": "登录凭证批量删除",
"consumes": [
"application/json"
],
@@ -3579,7 +3579,7 @@ const docTemplateadmin = `{
"tags": [
"登录凭证"
],
"summary": "登录凭证删除",
"summary": "登录凭证批量删除",
"parameters": [
{
"description": "登录凭证信息",
@@ -3587,7 +3587,7 @@ const docTemplateadmin = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/model.UserToken"
"$ref": "#/definitions/admin.UserTokenBatchDeleteForm"
}
}
],
@@ -3798,12 +3798,12 @@ const docTemplateadmin = `{
"properties": {
"new_password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
},
"old_password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
}
}
@@ -4038,7 +4038,7 @@ const docTemplateadmin = `{
},
"username": {
"type": "string",
"maxLength": 10,
"maxLength": 32,
"minLength": 2
}
}
@@ -4066,11 +4066,25 @@ const docTemplateadmin = `{
},
"password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
}
}
},
"admin.UserTokenBatchDeleteForm": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"model.AddressBook": {
"type": "object",
"properties": {

View File

@@ -3562,7 +3562,7 @@
"token": []
}
],
"description": "登录凭证删除",
"description": "登录凭证批量删除",
"consumes": [
"application/json"
],
@@ -3572,7 +3572,7 @@
"tags": [
"登录凭证"
],
"summary": "登录凭证删除",
"summary": "登录凭证批量删除",
"parameters": [
{
"description": "登录凭证信息",
@@ -3580,7 +3580,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/model.UserToken"
"$ref": "#/definitions/admin.UserTokenBatchDeleteForm"
}
}
],
@@ -3791,12 +3791,12 @@
"properties": {
"new_password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
},
"old_password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
}
}
@@ -4031,7 +4031,7 @@
},
"username": {
"type": "string",
"maxLength": 10,
"maxLength": 32,
"minLength": 2
}
}
@@ -4059,11 +4059,25 @@
},
"password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
}
}
},
"admin.UserTokenBatchDeleteForm": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"model.AddressBook": {
"type": "object",
"properties": {

View File

@@ -78,11 +78,11 @@ definitions:
admin.ChangeCurPasswordForm:
properties:
new_password:
maxLength: 20
maxLength: 32
minLength: 4
type: string
old_password:
maxLength: 20
maxLength: 32
minLength: 4
type: string
required:
@@ -238,7 +238,7 @@ definitions:
- $ref: '#/definitions/model.StatusCode'
minimum: 0
username:
maxLength: 10
maxLength: 32
minLength: 2
type: string
required:
@@ -258,13 +258,22 @@ definitions:
id:
type: integer
password:
maxLength: 20
maxLength: 32
minLength: 4
type: string
required:
- id
- password
type: object
admin.UserTokenBatchDeleteForm:
properties:
ids:
items:
type: integer
type: array
required:
- ids
type: object
model.AddressBook:
properties:
alias:
@@ -2871,14 +2880,14 @@ paths:
post:
consumes:
- application/json
description: 登录凭证删除
description: 登录凭证批量删除
parameters:
- description: 登录凭证信息
in: body
name: body
required: true
schema:
$ref: '#/definitions/model.UserToken'
$ref: '#/definitions/admin.UserTokenBatchDeleteForm'
produces:
- application/json
responses:
@@ -2892,7 +2901,7 @@ paths:
$ref: '#/definitions/response.Response'
security:
- token: []
summary: 登录凭证删除
summary: 登录凭证批量删除
tags:
- 登录凭证
/admin/user_token/list:

View File

@@ -1356,7 +1356,7 @@ const docTemplateapi = `{
},
"password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
},
"type": {
@@ -1364,7 +1364,7 @@ const docTemplateapi = `{
},
"username": {
"type": "string",
"maxLength": 10,
"maxLength": 32,
"minLength": 2
},
"uuid": {

View File

@@ -1349,7 +1349,7 @@
},
"password": {
"type": "string",
"maxLength": 20,
"maxLength": 32,
"minLength": 4
},
"type": {
@@ -1357,7 +1357,7 @@
},
"username": {
"type": "string",
"maxLength": 10,
"maxLength": 32,
"minLength": 2
},
"uuid": {

View File

@@ -62,13 +62,13 @@ definitions:
id:
type: string
password:
maxLength: 20
maxLength: 32
minLength: 4
type: string
type:
type: string
username:
maxLength: 10
maxLength: 32
minLength: 2
type: string
uuid:

View File

@@ -6,6 +6,7 @@ import (
"Gwen/http/response"
"Gwen/model"
"Gwen/service"
"encoding/json"
_ "encoding/json"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
@@ -327,3 +328,70 @@ func (ct *AddressBook) ShareByWebClient(c *gin.Context) {
"share_token": m.ShareToken,
})
}
func (ct *AddressBook) BatchCreateFromPeers(c *gin.Context) {
f := &admin.BatchCreateFromPeersForm{}
if err := c.ShouldBindJSON(f); err != nil {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
return
}
u := service.AllService.UserService.CurUser(c)
if f.CollectionId != 0 {
collection := service.AllService.AddressBookService.CollectionInfoById(f.CollectionId)
if collection.Id == 0 {
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
return
}
if collection.UserId != u.Id {
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
return
}
}
peers := service.AllService.PeerService.List(1, 999, func(tx *gorm.DB) {
tx.Where("row_id in ?", f.PeerIds)
tx.Where("user_id = ?", u.Id)
})
if peers.Total == 0 {
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
return
}
tags, _ := json.Marshal(f.Tags)
for _, peer := range peers.Peers {
ab := service.AllService.AddressBookService.FromPeer(peer)
ab.Tags = tags
ab.CollectionId = f.CollectionId
ex := service.AllService.AddressBookService.InfoByUserIdAndIdAndCid(u.Id, ab.Id, ab.CollectionId)
if ex.RowId != 0 {
continue
}
service.AllService.AddressBookService.Create(ab)
}
response.Success(c, nil)
}
func (ct *AddressBook) BatchUpdateTags(c *gin.Context) {
f := &admin.BatchUpdateTagsForm{}
if err := c.ShouldBindJSON(f); err != nil {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
return
}
u := service.AllService.UserService.CurUser(c)
abs := service.AllService.AddressBookService.List(1, 999, func(tx *gorm.DB) {
tx.Where("row_id in ?", f.RowIds)
tx.Where("user_id = ?", u.Id)
})
if abs.Total == 0 {
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
return
}
err := service.AllService.AddressBookService.BatchUpdateTags(abs.AddressBooks, f.Tags)
if err != nil {
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
return
}
response.Success(c, nil)
}

View File

@@ -81,3 +81,33 @@ func (ct *UserToken) Delete(c *gin.Context) {
}
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
}
// BatchDelete 批量删除
// @Tags 登录凭证
// @Summary 登录凭证批量删除
// @Description 登录凭证批量删除
// @Accept json
// @Produce json
// @Param body body admin.UserTokenBatchDeleteForm true "登录凭证信息"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /admin/user_token/delete [post]
// @Security token
func (ct *UserToken) BatchDelete(c *gin.Context) {
f := &admin.UserTokenBatchDeleteForm{}
if err := c.ShouldBindJSON(f); err != nil {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
return
}
ids := f.Ids
if len(ids) == 0 {
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
return
}
err := service.AllService.UserService.BatchDeleteUserToken(ids)
if err == nil {
response.Success(c, nil)
return
}
response.Fail(c, 101, err.Error())
}

View File

@@ -94,7 +94,7 @@ func (i *WebClient) SharedPeer(c *gin.Context) {
// @Produce json
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /server-config [get]
// @Router /server-config-v2 [get]
// @Security token
func (i *WebClient) ServerConfigV2(c *gin.Context) {
response.Success(

View File

@@ -122,3 +122,13 @@ type AddressBookCollectionRuleQuery struct {
IsMy int `form:"is_my"`
PageQuery
}
type BatchCreateFromPeersForm struct {
CollectionId uint `json:"collection_id"`
PeerIds []uint `json:"peer_ids"`
Tags []string `json:"tags"`
}
type BatchUpdateTagsForm struct {
RowIds []uint `json:"row_ids"`
Tags []string `json:"tags"`
}

View File

@@ -6,7 +6,7 @@ import (
type UserForm struct {
Id uint `json:"id"`
Username string `json:"username" validate:"required,gte=2,lte=10"`
Username string `json:"username" validate:"required,gte=2,lte=32"`
Email string `json:"email"` //validate:"required,email" email不强制
//Password string `json:"password" validate:"required,gte=4,lte=20"`
Nickname string `json:"nickname"`
@@ -51,12 +51,12 @@ type UserQuery struct {
}
type UserPasswordForm struct {
Id uint `json:"id" validate:"required"`
Password string `json:"password" validate:"required,gte=4,lte=20"`
Password string `json:"password" validate:"required,gte=4,lte=32"`
}
type ChangeCurPasswordForm struct {
OldPassword string `json:"old_password" validate:"required,gte=4,lte=20"`
NewPassword string `json:"new_password" validate:"required,gte=4,lte=20"`
OldPassword string `json:"old_password" validate:"required,gte=4,lte=32"`
NewPassword string `json:"new_password" validate:"required,gte=4,lte=32"`
}
type GroupUsersQuery struct {
IsMy int `json:"is_my"`
@@ -64,8 +64,12 @@ type GroupUsersQuery struct {
}
type RegisterForm struct {
Username string `json:"username" validate:"required,gte=2,lte=10"`
Username string `json:"username" validate:"required,gte=2,lte=32"`
Email string `json:"email"` // validate:"required,email"
Password string `json:"password" validate:"required,gte=4,lte=20"`
ConfirmPassword string `json:"confirm_password" validate:"required,gte=4,lte=20"`
Password string `json:"password" validate:"required,gte=4,lte=32"`
ConfirmPassword string `json:"confirm_password" validate:"required,gte=4,lte=32"`
}
type UserTokenBatchDeleteForm struct {
Ids []uint `json:"ids" validate:"required"`
}

View File

@@ -34,8 +34,8 @@ type LoginForm struct {
Id string `json:"id" label:"id"`
Type string `json:"type" label:"type"`
Uuid string `json:"uuid" label:"uuid"`
Username string `json:"username" validate:"required,gte=2,lte=10" label:"用户名"`
Password string `json:"password,omitempty" validate:"gte=4,lte=20" label:"密码"`
Username string `json:"username" validate:"required,gte=2,lte=32" label:"用户名"`
Password string `json:"password,omitempty" validate:"gte=4,lte=32" label:"密码"`
}
type UserListQuery struct {

View File

@@ -107,9 +107,12 @@ func AddressBookBind(rg *gin.RouterGroup) {
aR.POST("/update", cont.Update)
aR.POST("/delete", cont.Delete)
aR.POST("/shareByWebClient", cont.ShareByWebClient)
aR.POST("/batchCreateFromPeers", cont.BatchCreateFromPeers)
aR.POST("/batchUpdateTags", cont.BatchUpdateTags)
arp := aR.Use(middleware.AdminPrivilege())
arp.POST("/batchCreate", cont.BatchCreate)
}
}
func PeerBind(rg *gin.RouterGroup) {
@@ -195,6 +198,7 @@ func UserTokenBind(rg *gin.RouterGroup) {
cont := &admin.UserToken{}
aR.GET("/list", cont.List)
aR.POST("/delete", cont.Delete)
aR.POST("/batchDelete", cont.BatchDelete)
}
func ConfigBind(rg *gin.RouterGroup) {
aR := rg.Group("/config")

View File

@@ -3,6 +3,7 @@ package service
import (
"Gwen/global"
"Gwen/model"
"encoding/json"
"github.com/google/uuid"
"gorm.io/gorm"
"strings"
@@ -116,6 +117,16 @@ func (s *AddressBookService) List(page, pageSize uint, where func(tx *gorm.DB))
return
}
func (s *AddressBookService) FromPeer(peer *model.Peer) (a *model.AddressBook) {
a = &model.AddressBook{}
a.Id = peer.Id
a.Username = peer.Username
a.Hostname = peer.Hostname
a.UserId = peer.UserId
a.Platform = s.PlatformFromOs(peer.Os)
return a
}
// Create 创建
func (s *AddressBookService) Create(u *model.AddressBook) error {
res := global.DB.Create(u).Error
@@ -318,3 +329,12 @@ func (s *AddressBookService) CheckCollectionOwner(uid uint, cid uint) bool {
p := s.CollectionInfoById(cid)
return p.UserId == uid
}
func (s *AddressBookService) BatchUpdateTags(abs []*model.AddressBook, tags []string) error {
ids := make([]uint, 0)
for _, ab := range abs {
ids = append(ids, ab.RowId)
}
tagsv, _ := json.Marshal(tags)
return global.DB.Model(&model.AddressBook{}).Where("row_id in ?", ids).Update("tags", tagsv).Error
}

View File

@@ -458,3 +458,7 @@ func (us *UserService) AutoRefreshAccessToken(ut *model.UserToken) {
us.RefreshAccessToken(ut)
}
}
func (us *UserService) BatchDeleteUserToken(ids []uint) error {
return global.DB.Where("id in ?", ids).Delete(&model.UserToken{}).Error
}