Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: torrent edit api #32

Merged
merged 3 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions internal/common/db/torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ func CreateTorrent(torrent *model.Torrent) (err error) {
return err
}

// PatchTorrent 更新种子信息,根据 torrentID 和 details 更新种子信息
func PatchTorrent[T *model.Torrent | map[string]any | any](torrentID int32, details T) (err error) {
q := query.Torrent
_, err = q.Where(q.TorrentID.Eq(torrentID)).Updates(details)
if err != nil {
return err
}
return nil
}

// GetTorrentByHash 根据 Hash 获取种子
func GetTorrentByHash(hash string) (*model.Torrent, error) {
q := query.Torrent
Expand Down
2 changes: 1 addition & 1 deletion internal/common/db/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func CreateUser(user *model.User) (err error) {
}

// PatchUser 更新用户信息,根据 userID 和 details 更新用户信息
func PatchUser(userID int32, details *model.User) (err error) {
func PatchUser[T *model.User | map[string]any | any](userID int32, details T) (err error) {
q := query.User
ResultInfo, err := q.Where(q.UserID.Eq(userID)).Updates(details)
if err != nil {
Expand Down
28 changes: 15 additions & 13 deletions internal/middleware/rbac/access_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/gin-gonic/gin"
)

// RABC 获取用户角色,存入上下文,进行权限控制,allowRoles 为允许的角色
// RABC 获取用户角色,存入上下文,进行权限控制,allowRoles 为允许的角色,为空则不限制
func RABC(allowRoles ...string) gin.HandlerFunc {
return func(c *gin.Context) {
userID, _ := resp.GetUserIDFromGinContext(c)
Expand All @@ -23,20 +23,22 @@ func RABC(allowRoles ...string) gin.HandlerFunc {
return
}

// 检查用户是否有合适的角色
hasAllowedRole := false
for _, role := range roles {
if util.CheckStringInSlice(role, allowRoles) {
hasAllowedRole = true
break
if len(allowRoles) > 0 {
// 检查用户是否有合适的角色
hasAllowedRole := false
for _, role := range roles {
if util.CheckStringInSlice(role, allowRoles) {
hasAllowedRole = true
break
}
}
}

// 用户没有合适的角色,拦截请求
if !hasAllowedRole {
resp.AbortWithMsg(c, code.AuthErrorNoPermission, "Role has no permission")
log.Logger.Errorf("RABC Role has no permission, userID: %d, roles: %v", userID, roles)
return
// 用户没有合适的角色,拦截请求
if !hasAllowedRole {
resp.AbortWithMsg(c, code.AuthErrorNoPermission, "Role has no permission")
log.Logger.Errorf("RABC Role has no permission, userID: %d, roles: %v", userID, roles)
return
}
}

// 将角色信息存储在 Gin 上下文中
Expand Down
6 changes: 5 additions & 1 deletion internal/router/api/v1/torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ func TorrentRouterGroup(api *gin.RouterGroup) {
jwt.RequireAuth(false),
rbac.RABC(role.ADMIN, role.UPLOADER, role.ADVANCED_USER),
torrent_service.Upload)

// 种子编辑
torrent.POST("edit",
jwt.RequireAuth(false),
rbac.RABC(),
torrent_service.Edit)
// 获取种子文件列表
torrent.GET("filelist",
jwt.RequireAuth(false),
Expand Down
68 changes: 68 additions & 0 deletions internal/service/torrent/edit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package torrent

import (
"github.com/TensoRaws/NuxBT-Backend/internal/common/db"
"github.com/TensoRaws/NuxBT-Backend/module/code"
"github.com/TensoRaws/NuxBT-Backend/module/log"
"github.com/TensoRaws/NuxBT-Backend/module/resp"
"github.com/TensoRaws/NuxBT-Backend/module/role"
"github.com/TensoRaws/NuxBT-Backend/module/util"
"github.com/gin-gonic/gin"
)

type EditRequest struct {
TorrentID int32 `form:"torrent_id" binding:"required"`
AnidbID int32 `form:"anidb_id" binding:"required"`
AudioCodec string `form:"audio_codec" binding:"required,oneof=FLAC AAC AC3 DTS DDP LPCM other"`
Description string `form:"description" binding:"required"`
Essay string `form:"essay" binding:"required"`
Genre string `form:"genre" binding:"required,oneof=BDrip WEBrip DVDrip Remux Blu-ray WEB-DL DVD HDTV other"` //nolint:lll
Img string `form:"img" binding:"required"`
Language string `form:"language" binding:"required,oneof=Chinese English Japanese other"`
Resolution string `form:"resolution" binding:"required,oneof=480p 720p 1080p 2160p other"`
Subtitle string `form:"subtitle" binding:"required"`
Title string `form:"title" binding:"required"`
VideoCodec string `form:"video_codec" binding:"required,oneof=H.265 H.264 AV1 VP9 other"`
}

// Edit 更新种子信息 (POST /edit)
func Edit(c *gin.Context) {
// 参数绑定
var req EditRequest
if err := c.ShouldBind(&req); err != nil {
resp.AbortWithMsg(c, code.RequestErrorInvalidParams, err.Error())
return
}

userID, _ := resp.GetUserIDFromGinContext(c)

roles, err := resp.GetRolesFromGinContext(c)
if err != nil {
resp.AbortWithMsg(c, code.UnknownError, err.Error())
log.Logger.Error("failed to get roles from gin context: " + err.Error())
return
}

bt, err := db.GetTorrentByID(req.TorrentID)
if err != nil {
resp.AbortWithMsg(c, code.DatabaseErrorRecordNotFound, err.Error())
log.Logger.Error("failed to get torrent by id: " + err.Error())
return
}

if bt.UploaderID != userID && !util.CheckStringInSlice(role.ADMIN, roles) {
resp.AbortWithMsg(c, code.AuthErrorNoPermission, "permission denied")
log.Logger.Errorf("permission denied, user id: %v", userID)
return
}

err = db.PatchTorrent(req.TorrentID, &req)
if err != nil {
resp.AbortWithMsg(c, code.DatabaseErrorRecordPatchFailed, err.Error())
return
}

resp.OK(c)

log.Logger.Infof("update torrent info success, torrent id: %v", req.TorrentID)
}
2 changes: 1 addition & 1 deletion internal/service/torrent/filelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type FileListRequest struct {

type FileListResponse []torrent.BitTorrentFileListItem

// FileList 获取种子文件列表
// FileList 获取种子文件列表 (GET /filelist)
func FileList(c *gin.Context) {
// 绑定参数
var req FileListRequest
Expand Down
1 change: 1 addition & 0 deletions internal/service/torrent/official.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package torrent
4 changes: 2 additions & 2 deletions internal/service/torrent/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type UploadRequest struct {
AnidbID int32 `form:"anidb_id" binding:"required"`
AudioCodec string `form:"audio_codec" binding:"required,oneof=FLAC AAC AC3 DTS DDP LPCM other"`
Description string `form:"description" binding:"required"`
Essay *string `form:"essay" binding:"omitempty"`
Essay string `form:"essay" binding:"required"`
Genre string `form:"genre" binding:"required,oneof=BDrip WEBrip DVDrip Remux Blu-ray WEB-DL DVD HDTV other"` //nolint:lll
Img string `form:"img" binding:"required"`
Language string `form:"language" binding:"required,oneof=Chinese English Japanese other"`
Expand Down Expand Up @@ -131,7 +131,7 @@ func Upload(c *gin.Context) {
Status: status,
Title: req.Title,
Subtitle: req.Subtitle,
Essay: *req.Essay,
Essay: req.Essay,
Description: req.Description,
Genre: req.Genre,
AnidbID: req.AnidbID,
Expand Down
1 change: 1 addition & 0 deletions internal/service/user/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type ProfileOthersRequest struct {
func ProfileMe(c *gin.Context) {
userID, _ := resp.GetUserIDFromGinContext(c)

// 更新活跃时间
err := db.PatchUser(userID, &model.User{LastActive: time.Now()})
if err != nil {
resp.AbortWithMsg(c, code.UnknownError, err.Error())
Expand Down
30 changes: 14 additions & 16 deletions internal/service/user/profile_update.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package user

import (
"github.com/TensoRaws/NuxBT-Backend/dal/model"
"github.com/TensoRaws/NuxBT-Backend/internal/common/db"
"github.com/TensoRaws/NuxBT-Backend/module/code"
"github.com/TensoRaws/NuxBT-Backend/module/log"
Expand All @@ -11,12 +10,12 @@ import (
)

type ProfileUpdateRequest struct {
Avatar *string `json:"avatar" binding:"omitempty"`
Background *string `json:"background" binding:"omitempty"`
Email *string `json:"email" binding:"omitempty,email"`
Private *bool `json:"private" binding:"omitempty"`
Signature *string `json:"signature" binding:"omitempty"`
Username *string `json:"username" binding:"omitempty"`
Avatar string `json:"avatar" binding:"required"`
Background string `json:"background" binding:"required"`
Email string `json:"email" binding:"required,email"`
Private *bool `json:"private" binding:"required"`
Signature string `json:"signature" binding:"required"`
Username string `json:"username" binding:"required"`
}

// ProfileUpdate 用户信息更新 (POST /profile/update)
Expand All @@ -28,23 +27,22 @@ func ProfileUpdate(c *gin.Context) {
return
}

err := util.CheckUsername(*req.Username)
err := util.CheckUsername(req.Username)
if err != nil {
resp.AbortWithMsg(c, code.UserErrorInvalidUsername, err.Error())
return
}

userID, _ := resp.GetUserIDFromGinContext(c)

// 没传数字,直接序列化嗯造
updateInfo, err := util.StructToMap(req)
if err != nil {
resp.AbortWithMsg(c, code.UnknownError, err.Error())
return
}
// 执行更新
err = db.PatchUser(userID, &model.User{
Avatar: *req.Avatar,
Background: *req.Background,
Email: *req.Email,
Private: *req.Private,
Signature: *req.Signature,
Username: *req.Username,
})
err = db.PatchUser(userID, updateInfo)

if err != nil {
resp.AbortWithMsg(c, code.DatabaseErrorRecordPatchFailed, err.Error())
Expand Down
4 changes: 1 addition & 3 deletions internal/service/user/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ func ResetPassword(c *gin.Context) {
}

// 修改密码
err = db.PatchUser(userID, &model.User{
Password: string(password),
})
err = db.PatchUser(userID, &model.User{Password: string(password)})

if err != nil {
resp.AbortWithMsg(c, code.DatabaseErrorRecordPatchFailed, "reset password fail")
Expand Down
2 changes: 1 addition & 1 deletion module/util/ds.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func StringToStruct(str string, s interface{}) error {
return sonic.Unmarshal([]byte(str), s)
}

// StructToMap 结构体转 map[string]interface{}
// StructToMap 结构体转 map[string]interface{},请勿在有数字情况下使用,请使用反射
func StructToMap(s interface{}) (map[string]interface{}, error) {
// 使用 sonic 将结构体序列化为 JSON
jsonBytes, err := sonic.Marshal(s)
Expand Down
Loading