diff --git a/internal/controller/v1/console.go b/internal/controller/v1/console.go new file mode 100644 index 0000000..af2c0d1 --- /dev/null +++ b/internal/controller/v1/console.go @@ -0,0 +1,92 @@ +package v1 + +import ( + "context" + "github.com/cloudwego/hertz/pkg/app" + "github.com/snowykami/neo-blog/internal/dto" + "github.com/snowykami/neo-blog/internal/service" + "github.com/snowykami/neo-blog/pkg/errs" + "github.com/snowykami/neo-blog/pkg/resps" +) + +type AdminController struct { + service *service.AdminService +} + +func NewAdminController() *AdminController { + return &AdminController{ + service: service.NewAdminService(), + } +} + +func (cc *AdminController) CreateOidc(ctx context.Context, c *app.RequestContext) { + var adminCreateOidcReq dto.AdminOidcConfigDto + if err := c.BindAndValidate(&adminCreateOidcReq); err != nil { + c.JSON(400, map[string]string{"error": "Invalid parameters"}) + return + } + err := cc.service.CreateOidcConfig(&adminCreateOidcReq) + if err != nil { + serviceErr := errs.AsServiceError(err) + resps.Custom(c, serviceErr.Code, serviceErr.Message, nil) + return + } + resps.Ok(c, resps.Success, nil) +} + +func (cc *AdminController) DeleteOidc(ctx context.Context, c *app.RequestContext) { + id := c.Param("id") + if id == "" { + resps.BadRequest(c, resps.ErrParamInvalid) + return + } + + err := cc.service.DeleteOidcConfig(id) + if err != nil { + serviceErr := errs.AsServiceError(err) + resps.Custom(c, serviceErr.Code, serviceErr.Message, nil) + return + } + resps.Ok(c, resps.Success, nil) +} + +func (cc *AdminController) GetOidcByID(ctx context.Context, c *app.RequestContext) { + id := c.Param("id") + if id == "" { + resps.BadRequest(c, resps.ErrParamInvalid) + return + } + + config, err := cc.service.GetOidcConfigByID(id) + if err != nil { + serviceErr := errs.AsServiceError(err) + resps.Custom(c, serviceErr.Code, serviceErr.Message, nil) + return + } + resps.Ok(c, resps.Success, config) +} + +func (cc *AdminController) ListOidc(ctx context.Context, c *app.RequestContext) { + configs, err := cc.service.ListOidcConfigs(false) + if err != nil { + serviceErr := errs.AsServiceError(err) + resps.Custom(c, serviceErr.Code, serviceErr.Message, nil) + return + } + resps.Ok(c, resps.Success, configs) +} + +func (cc *AdminController) UpdateOidc(ctx context.Context, c *app.RequestContext) { + var adminUpdateOidcReq dto.AdminOidcConfigDto + if err := c.BindAndValidate(&adminUpdateOidcReq); err != nil { + c.JSON(400, map[string]string{"error": "Invalid parameters"}) + return + } + err := cc.service.UpdateOidcConfig(&adminUpdateOidcReq) + if err != nil { + serviceErr := errs.AsServiceError(err) + resps.Custom(c, serviceErr.Code, serviceErr.Message, nil) + return + } + resps.Ok(c, resps.Success, nil) +} diff --git a/internal/controller/v1/post.go b/internal/controller/v1/post.go index 0eeb4a2..92e0ee4 100644 --- a/internal/controller/v1/post.go +++ b/internal/controller/v1/post.go @@ -3,28 +3,57 @@ package v1 import ( "context" "github.com/cloudwego/hertz/pkg/app" + "github.com/snowykami/neo-blog/internal/dto" + "github.com/snowykami/neo-blog/internal/service" + "github.com/snowykami/neo-blog/pkg/errs" + "github.com/snowykami/neo-blog/pkg/resps" ) -type postType struct{} +type PostController struct { + service *service.PostService +} -var Post = new(postType) +func NewPostController() *PostController { + return &PostController{ + service: service.NewPostService(), + } +} -func (p *postType) Create(ctx context.Context, c *app.RequestContext) { +func (p *PostController) Create(ctx context.Context, c *app.RequestContext) { + var req dto.CreateOrUpdatePostReq + if err := c.BindAndValidate(&req); err != nil { + resps.BadRequest(c, resps.ErrParamInvalid) + } + if err := p.service.CreatePost(&req); err != nil { + serviceErr := errs.AsServiceError(err) + resps.Custom(c, serviceErr.Code, serviceErr.Message, nil) + return + } + resps.Ok(c, resps.Success, nil) +} + +func (p *PostController) Delete(ctx context.Context, c *app.RequestContext) { + id := c.Param("id") + if id == "" { + resps.BadRequest(c, resps.ErrParamInvalid) + return + } + if err := p.service.DeletePost(ctx, id); err != nil { + serviceErr := errs.AsServiceError(err) + resps.Custom(c, serviceErr.Code, serviceErr.Message, nil) + return + } + resps.Ok(c, resps.Success, nil) +} + +func (p *PostController) Get(ctx context.Context, c *app.RequestContext) { // TODO: Impl } -func (p *postType) Delete(ctx context.Context, c *app.RequestContext) { +func (p *PostController) Update(ctx context.Context, c *app.RequestContext) { // TODO: Impl } -func (p *postType) Get(ctx context.Context, c *app.RequestContext) { - // TODO: Impl -} - -func (p *postType) Update(ctx context.Context, c *app.RequestContext) { - // TODO: Impl -} - -func (p *postType) List(ctx context.Context, c *app.RequestContext) { +func (p *PostController) List(ctx context.Context, c *app.RequestContext) { // TODO: Impl } diff --git a/internal/controller/v1/user.go b/internal/controller/v1/user.go index c87c356..b01cb77 100644 --- a/internal/controller/v1/user.go +++ b/internal/controller/v1/user.go @@ -12,15 +12,17 @@ import ( "strconv" ) -type userType struct { +type UserController struct { service *service.UserService } -var User = &userType{ - service: service.NewUserService(), +func NewUserController() *UserController { + return &UserController{ + service: service.NewUserService(), + } } -func (u *userType) Login(ctx context.Context, c *app.RequestContext) { +func (u *UserController) Login(ctx context.Context, c *app.RequestContext) { var userLoginReq dto.UserLoginReq if err := c.BindAndValidate(&userLoginReq); err != nil { resps.BadRequest(c, resps.ErrParamInvalid) @@ -40,7 +42,7 @@ func (u *userType) Login(ctx context.Context, c *app.RequestContext) { }) } -func (u *userType) Register(ctx context.Context, c *app.RequestContext) { +func (u *UserController) Register(ctx context.Context, c *app.RequestContext) { var userRegisterReq dto.UserRegisterReq if err := c.BindAndValidate(&userRegisterReq); err != nil { resps.BadRequest(c, resps.ErrParamInvalid) @@ -61,12 +63,12 @@ func (u *userType) Register(ctx context.Context, c *app.RequestContext) { }) } -func (u *userType) Logout(ctx context.Context, c *app.RequestContext) { +func (u *UserController) Logout(ctx context.Context, c *app.RequestContext) { ctxutils.ClearTokenAndRefreshTokenCookie(c) resps.Ok(c, resps.Success, nil) } -func (u *userType) OidcList(ctx context.Context, c *app.RequestContext) { +func (u *UserController) OidcList(ctx context.Context, c *app.RequestContext) { resp, err := u.service.ListOidcConfigs() if err != nil { serviceErr := errs.AsServiceError(err) @@ -78,7 +80,7 @@ func (u *userType) OidcList(ctx context.Context, c *app.RequestContext) { }) } -func (u *userType) OidcLogin(ctx context.Context, c *app.RequestContext) { +func (u *UserController) OidcLogin(ctx context.Context, c *app.RequestContext) { name := c.Param("name") code := c.Param("code") state := c.Param("state") @@ -100,7 +102,7 @@ func (u *userType) OidcLogin(ctx context.Context, c *app.RequestContext) { }) } -func (u *userType) GetUser(ctx context.Context, c *app.RequestContext) { +func (u *UserController) GetUser(ctx context.Context, c *app.RequestContext) { userID := c.Param("id") if userID == "" { resps.BadRequest(c, resps.ErrParamInvalid) @@ -121,7 +123,7 @@ func (u *userType) GetUser(ctx context.Context, c *app.RequestContext) { resps.Ok(c, resps.Success, resp.User) } -func (u *userType) UpdateUser(ctx context.Context, c *app.RequestContext) { +func (u *UserController) UpdateUser(ctx context.Context, c *app.RequestContext) { userID := c.Param("id") if userID == "" { resps.BadRequest(c, resps.ErrParamInvalid) @@ -156,7 +158,7 @@ func (u *userType) UpdateUser(ctx context.Context, c *app.RequestContext) { resps.Ok(c, resps.Success, resp) } -func (u *userType) VerifyEmail(ctx context.Context, c *app.RequestContext) { +func (u *UserController) VerifyEmail(ctx context.Context, c *app.RequestContext) { var verifyEmailReq dto.VerifyEmailReq if err := c.BindAndValidate(&verifyEmailReq); err != nil { resps.BadRequest(c, resps.ErrParamInvalid) diff --git a/internal/dto/console.go b/internal/dto/console.go new file mode 100644 index 0000000..f4c1288 --- /dev/null +++ b/internal/dto/console.go @@ -0,0 +1,12 @@ +package dto + +type AdminOidcConfigDto struct { + ID uint `json:"id"` + Name string `json:"name"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + DisplayName string `json:"display_name"` + Icon string `json:"icon"` + OidcDiscoveryUrl string `json:"oidc_discovery_url"` + Enabled bool `json:"enabled"` +} diff --git a/internal/dto/post.go b/internal/dto/post.go index 50ed6b3..cac3a36 100644 --- a/internal/dto/post.go +++ b/internal/dto/post.go @@ -8,9 +8,9 @@ type PostDto struct { IsPrivate bool `json:"is_private"` // 是否为私密帖子 } -type CreatePostReq struct { - Title string `json:"title"` - Content string `json:"content"` - Labels []LabelDto `json:"labels"` - IsPrivate bool `json:"is_private"` +type CreateOrUpdatePostReq struct { + Title string `json:"title"` + Content string `json:"content"` + IsPrivate bool `json:"is_private"` + Labels []uint `json:"labels"` // 标签ID列表 } diff --git a/internal/dto/user.go b/internal/dto/user.go index 0811780..b334800 100644 --- a/internal/dto/user.go +++ b/internal/dto/user.go @@ -10,7 +10,7 @@ type UserDto struct { Role string `json:"role"` } -type OidcConfigDto struct { +type UserOidcConfigDto struct { Name string `json:"name"` // OIDC配置名称 DisplayName string `json:"display_name"` // OIDC配置显示名称 Icon string `json:"icon"` // OIDC配置图标URL @@ -62,7 +62,7 @@ type OidcLoginResp struct { } type ListOidcConfigResp struct { - OidcConfigs []OidcConfigDto `json:"oidc_configs"` // OIDC配置列表 + OidcConfigs []UserOidcConfigDto `json:"oidc_configs"` // OIDC配置列表 } type GetUserReq struct { diff --git a/internal/model/oidc_config.go b/internal/model/oidc_config.go index 28c4082..e552738 100644 --- a/internal/model/oidc_config.go +++ b/internal/model/oidc_config.go @@ -83,11 +83,25 @@ func (o *OidcConfig) BeforeSave(tx *gorm.DB) (err error) { return nil } -// ToDto 不包含LoginUrl,在service层自行实现 -func (o *OidcConfig) ToDto() *dto.OidcConfigDto { - return &dto.OidcConfigDto{ +// ToUserDto 返回给用户侧 +func (o *OidcConfig) ToUserDto() *dto.UserOidcConfigDto { + return &dto.UserOidcConfigDto{ Name: o.Name, DisplayName: o.DisplayName, Icon: o.Icon, } } + +// ToAdminDto 返回给管理员侧 +func (o *OidcConfig) ToAdminDto() *dto.AdminOidcConfigDto { + return &dto.AdminOidcConfigDto{ + ID: o.ID, + Name: o.Name, + ClientID: o.ClientID, + ClientSecret: o.ClientSecret, + DisplayName: o.DisplayName, + Icon: o.Icon, + OidcDiscoveryUrl: o.OidcDiscoveryUrl, + Enabled: o.Enabled, + } +} diff --git a/internal/repo/label.go b/internal/repo/label.go new file mode 100644 index 0000000..9c57dbc --- /dev/null +++ b/internal/repo/label.go @@ -0,0 +1,55 @@ +package repo + +import "github.com/snowykami/neo-blog/internal/model" + +type labelRepo struct{} + +var Label = &labelRepo{} + +func (l *labelRepo) CreateLabel(key, value, color, tailwindClassName string) error { + label := &model.Label{ + Key: key, + Value: value, + Color: color, + TailwindClassName: tailwindClassName, + } + return GetDB().Create(label).Error +} + +func (l *labelRepo) GetLabelByKey(key string) (*model.Label, error) { + var label model.Label + if err := GetDB().Where("key = ?", key).First(&label).Error; err != nil { + return nil, err + } + return &label, nil +} + +func (l *labelRepo) GetLabelByID(id uint) (*model.Label, error) { + var label model.Label + if err := GetDB().Where("id = ?", id).First(&label).Error; err != nil { + return nil, err + } + return &label, nil +} + +func (l *labelRepo) ListLabels() ([]model.Label, error) { + var labels []model.Label + if err := GetDB().Find(&labels).Error; err != nil { + return nil, err + } + return labels, nil +} + +func (l *labelRepo) UpdateLabel(label *model.Label) error { + if err := GetDB().Save(label).Error; err != nil { + return err + } + return nil +} + +func (l *labelRepo) DeleteLabel(id uint) error { + if err := GetDB().Where("id = ?", id).Delete(&model.Label{}).Error; err != nil { + return err + } + return nil +} diff --git a/internal/repo/oidc_config.go b/internal/repo/oidc_config.go new file mode 100644 index 0000000..39a4bf1 --- /dev/null +++ b/internal/repo/oidc_config.go @@ -0,0 +1,69 @@ +package repo + +import ( + "github.com/snowykami/neo-blog/internal/model" + "github.com/snowykami/neo-blog/pkg/errs" + "net/http" +) + +type oidcRepo struct { +} + +var Oidc = &oidcRepo{} + +func (o *oidcRepo) CreateOidcConfig(oidcConfig *model.OidcConfig) error { + if err := GetDB().Create(oidcConfig).Error; err != nil { + return err + } + return nil +} + +func (o *oidcRepo) DeleteOidcConfig(id string) error { + if id == "" { + return errs.New(http.StatusBadRequest, "invalid OIDC config ID", nil) + } + if err := GetDB().Where("id = ?", id).Delete(&model.OidcConfig{}).Error; err != nil { + return err + } + return nil +} + +func (o *oidcRepo) ListOidcConfigs(onlyEnabled bool) ([]model.OidcConfig, error) { + var configs []model.OidcConfig + if onlyEnabled { + if err := GetDB().Where("enabled = ?", true).Find(&configs).Error; err != nil { + return nil, err + } + } else { + if err := GetDB().Find(&configs).Error; err != nil { + return nil, err + } + } + return configs, nil +} + +func (o *oidcRepo) GetOidcConfigByName(name string) (*model.OidcConfig, error) { + var config model.OidcConfig + if err := GetDB().Where("name = ?", name).First(&config).Error; err != nil { + return nil, err + } + return &config, nil +} + +func (o *oidcRepo) GetOidcConfigByID(id string) (*model.OidcConfig, error) { + var config model.OidcConfig + if err := GetDB().Where("id = ?", id).First(&config).Error; err != nil { + return nil, err + } + return &config, nil +} + +func (o *oidcRepo) UpdateOidcConfig(oidcConfig *model.OidcConfig) error { + if oidcConfig.ID == 0 { + return errs.New(http.StatusBadRequest, "invalid OIDC config ID", nil) + } + if err := GetDB().Updates(oidcConfig).Error; err != nil { + return err + } + return nil +} diff --git a/internal/repo/post.go b/internal/repo/post.go new file mode 100644 index 0000000..c102a94 --- /dev/null +++ b/internal/repo/post.go @@ -0,0 +1,54 @@ +package repo + +import ( + "github.com/snowykami/neo-blog/internal/model" + "github.com/snowykami/neo-blog/pkg/errs" + "net/http" +) + +type postRepo struct{} + +var Post = &postRepo{} + +func (p *postRepo) CreatePost(post *model.Post) error { + if err := GetDB().Create(post).Error; err != nil { + return err + } + return nil +} + +func (p *postRepo) DeletePost(id string) error { + if id == "" { + return errs.New(http.StatusBadRequest, "invalid post ID", nil) + } + if err := GetDB().Where("id = ?", id).Delete(&model.Post{}).Error; err != nil { + return err + } + return nil +} + +func (p *postRepo) GetPostByID(id string) (*model.Post, error) { + var post model.Post + if err := GetDB().Where("id = ?", id).Preload("User").First(&post).Error; err != nil { + return nil, err + } + return &post, nil +} + +func (p *postRepo) UpdatePost(post *model.Post) error { + if post.ID == 0 { + return errs.New(http.StatusBadRequest, "invalid post ID", nil) + } + if err := GetDB().Save(post).Error; err != nil { + return err + } + return nil +} + +func (p *postRepo) ListPosts(limit, offset int) ([]model.Post, error) { + var posts []model.Post + if err := GetDB().Limit(limit).Offset(offset).Find(&posts).Error; err != nil { + return nil, err + } + return posts, nil +} diff --git a/internal/repo/user.go b/internal/repo/user.go index 9a3b6c9..9a1d302 100644 --- a/internal/repo/user.go +++ b/internal/repo/user.go @@ -68,28 +68,6 @@ func (user *userRepo) CheckEmailExists(email string) (bool, error) { return count > 0, nil } -func (user *userRepo) ListOidcConfigs(onlyEnabled bool) ([]model.OidcConfig, error) { - var configs []model.OidcConfig - if onlyEnabled { - if err := GetDB().Where("enabled = ?", true).Find(&configs).Error; err != nil { - return nil, err - } - } else { - if err := GetDB().Find(&configs).Error; err != nil { - return nil, err - } - } - return configs, nil -} - -func (user *userRepo) GetOidcConfigByName(name string) (*model.OidcConfig, error) { - var config model.OidcConfig - if err := GetDB().Where("name = ?", name).First(&config).Error; err != nil { - return nil, err - } - return &config, nil -} - func (user *userRepo) CreateOrUpdateUserOpenID(userOpenID *model.UserOpenID) error { if err := GetDB().Save(userOpenID).Error; err != nil { return err diff --git a/internal/router/apiv1/console.go b/internal/router/apiv1/console.go new file mode 100644 index 0000000..4dccb27 --- /dev/null +++ b/internal/router/apiv1/console.go @@ -0,0 +1,20 @@ +package apiv1 + +import ( + "github.com/cloudwego/hertz/pkg/route" + v1 "github.com/snowykami/neo-blog/internal/controller/v1" + "github.com/snowykami/neo-blog/internal/middleware" +) + +func registerAdminRoutes(group *route.RouterGroup) { + // Need Admin Middleware + adminController := v1.NewAdminController() + consoleGroup := group.Group("/admin").Use(middleware.UseAuth(true)) + { + consoleGroup.POST("/oidc/o", adminController.CreateOidc) + consoleGroup.DELETE("/oidc/o/:id", adminController.DeleteOidc) + consoleGroup.GET("/oidc/o/:id", adminController.GetOidcByID) + consoleGroup.GET("/oidc/list", adminController.ListOidc) + consoleGroup.PUT("/oidc/o/:id", adminController.UpdateOidc) + } +} diff --git a/internal/router/apiv1/post.go b/internal/router/apiv1/post.go index cc8075f..3fdd915 100644 --- a/internal/router/apiv1/post.go +++ b/internal/router/apiv1/post.go @@ -9,13 +9,14 @@ import ( // post 文章API路由 func registerPostRoutes(group *route.RouterGroup) { + postController := v1.NewPostController() postGroup := group.Group("/post").Use(middleware.UseAuth(true)) postGroupWithoutAuth := group.Group("/post").Use(middleware.UseAuth(false)) { - postGroupWithoutAuth.GET("/p/:id", v1.Post.Get) - postGroupWithoutAuth.GET("/list", v1.Post.List) - postGroup.POST("/p", v1.Post.Create) - postGroup.PUT("/p", v1.Post.Update) - postGroup.DELETE("/p", v1.Post.Delete) + postGroupWithoutAuth.GET("/p/:id", postController.Get) + postGroupWithoutAuth.GET("/list", postController.List) + postGroup.POST("/p", postController.Create) + postGroup.PUT("/p", postController.Update) + postGroup.DELETE("/p", postController.Delete) } } diff --git a/internal/router/apiv1/user.go b/internal/router/apiv1/user.go index 008bf46..e935036 100644 --- a/internal/router/apiv1/user.go +++ b/internal/router/apiv1/user.go @@ -7,17 +7,18 @@ import ( ) func registerUserRoutes(group *route.RouterGroup) { + userController := v1.NewUserController() userGroup := group.Group("/user").Use(middleware.UseAuth(true)) userGroupWithoutAuth := group.Group("/user") userGroupWithoutAuthNeedsCaptcha := userGroupWithoutAuth.Use(middleware.UseCaptcha()) { - userGroupWithoutAuthNeedsCaptcha.POST("/login", v1.User.Login) - userGroupWithoutAuthNeedsCaptcha.POST("/register", v1.User.Register) - userGroupWithoutAuthNeedsCaptcha.POST("/email/verify", v1.User.VerifyEmail) // Send email verification code - userGroupWithoutAuth.GET("/oidc/list", v1.User.OidcList) - userGroupWithoutAuth.GET("/oidc/login/:name", v1.User.OidcLogin) - userGroupWithoutAuth.GET("/u/:id", v1.User.GetUser) - userGroup.POST("/logout", v1.User.Logout) - userGroup.PUT("/u/:id", v1.User.UpdateUser) + userGroupWithoutAuthNeedsCaptcha.POST("/login", userController.Login) + userGroupWithoutAuthNeedsCaptcha.POST("/register", userController.Register) + userGroupWithoutAuthNeedsCaptcha.POST("/email/verify", userController.VerifyEmail) // Send email verification code + userGroupWithoutAuth.GET("/oidc/list", userController.OidcList) + userGroupWithoutAuth.GET("/oidc/login/:name", userController.OidcLogin) + userGroupWithoutAuth.GET("/u/:id", userController.GetUser) + userGroup.POST("/logout", userController.Logout) + userGroup.PUT("/u/:id", userController.UpdateUser) } } diff --git a/internal/router/apiv1/v1.go b/internal/router/apiv1/v1.go index 6fe5afa..5d8174a 100644 --- a/internal/router/apiv1/v1.go +++ b/internal/router/apiv1/v1.go @@ -6,6 +6,7 @@ func RegisterRoutes(h *server.Hertz) { apiV1Group := h.Group("/api/v1") { registerCommentRoutes(apiV1Group) + registerAdminRoutes(apiV1Group) registerFileRoutes(apiV1Group) registerLabelRoutes(apiV1Group) registerPageRoutes(apiV1Group) diff --git a/internal/service/console.go b/internal/service/console.go new file mode 100644 index 0000000..da0d819 --- /dev/null +++ b/internal/service/console.go @@ -0,0 +1,75 @@ +package service + +import ( + "github.com/snowykami/neo-blog/internal/dto" + "github.com/snowykami/neo-blog/internal/model" + "github.com/snowykami/neo-blog/internal/repo" + "github.com/snowykami/neo-blog/pkg/errs" + "gorm.io/gorm" +) + +type AdminService struct{} + +func NewAdminService() *AdminService { + return &AdminService{} +} + +func (c *AdminService) CreateOidcConfig(req *dto.AdminOidcConfigDto) error { + oidcConfig := &model.OidcConfig{ + Name: req.Name, + DisplayName: req.DisplayName, + Icon: req.Icon, + ClientID: req.ClientID, + ClientSecret: req.ClientSecret, + OidcDiscoveryUrl: req.OidcDiscoveryUrl, + Enabled: req.Enabled, + } + return repo.Oidc.CreateOidcConfig(oidcConfig) +} + +func (c *AdminService) DeleteOidcConfig(id string) error { + if id == "" { + return errs.ErrBadRequest + } + return repo.Oidc.DeleteOidcConfig(id) +} + +func (c *AdminService) GetOidcConfigByID(id string) (*dto.AdminOidcConfigDto, error) { + if id == "" { + return nil, errs.ErrBadRequest + } + config, err := repo.Oidc.GetOidcConfigByID(id) + if err != nil { + return nil, err + } + return config.ToAdminDto(), nil +} + +func (c *AdminService) ListOidcConfigs(onlyEnabled bool) ([]*dto.AdminOidcConfigDto, error) { + configs, err := repo.Oidc.ListOidcConfigs(onlyEnabled) + if err != nil { + return nil, err + } + var dtos []*dto.AdminOidcConfigDto + for _, config := range configs { + dtos = append(dtos, config.ToAdminDto()) + } + return dtos, nil +} + +func (c *AdminService) UpdateOidcConfig(req *dto.AdminOidcConfigDto) error { + if req.ID == 0 { + return errs.ErrBadRequest + } + oidcConfig := &model.OidcConfig{ + Model: gorm.Model{ID: req.ID}, + Name: req.Name, + DisplayName: req.DisplayName, + Icon: req.Icon, + ClientID: req.ClientID, + ClientSecret: req.ClientSecret, + OidcDiscoveryUrl: req.OidcDiscoveryUrl, + Enabled: req.Enabled, + } + return repo.Oidc.UpdateOidcConfig(oidcConfig) +} diff --git a/internal/service/post.go b/internal/service/post.go new file mode 100644 index 0000000..61b3e5c --- /dev/null +++ b/internal/service/post.go @@ -0,0 +1,46 @@ +package service + +import ( + "context" + "github.com/snowykami/neo-blog/internal/ctxutils" + "github.com/snowykami/neo-blog/internal/dto" + "github.com/snowykami/neo-blog/internal/model" + "github.com/snowykami/neo-blog/internal/repo" + "github.com/snowykami/neo-blog/pkg/errs" + "net/http" +) + +type PostService struct{} + +func NewPostService() *PostService { + return &PostService{} +} + +func (p *PostService) CreatePost(ctx context.Context, req *dto.CreateOrUpdatePostReq) error { + currentUser := ctxutils.GetCurrentUser(ctx) + if currentUser == nil { + return errs.ErrUnauthorized + } + + post := &model.Post{ + Title: req.Title, + Content: req.Content, + UserID: currentUser.ID, + Labels: req.Labels, + IsPrivate: req.IsPrivate, + } + + if err := repo.Post.CreatePost(post); err != nil { + return err + } + return nil +} + +func (p *PostService) DeletePost(ctx context.Context, id string) error { +} + +func (p *PostService) GetPost(ctx context.Context, id string) (*model.Post, error) {} + +func (p *PostService) UpdatePost(req *dto.CreateOrUpdatePostReq) error {} + +func (p *PostService) ListPosts() {} diff --git a/internal/service/user.go b/internal/service/user.go index 6b5083d..79e2212 100644 --- a/internal/service/user.go +++ b/internal/service/user.go @@ -127,17 +127,17 @@ func (s *UserService) RequestVerifyEmail(req *dto.VerifyEmailReq) (*dto.VerifyEm } func (s *UserService) ListOidcConfigs() (*dto.ListOidcConfigResp, error) { - enabledOidcConfigs, err := repo.User.ListOidcConfigs(true) + enabledOidcConfigs, err := repo.Oidc.ListOidcConfigs(true) if err != nil { return nil, errs.ErrInternalServer } - var oidcConfigsDtos []dto.OidcConfigDto + var oidcConfigsDtos []dto.UserOidcConfigDto for _, oidcConfig := range enabledOidcConfigs { state := utils.Strings.GenerateRandomString(32) kvStore := utils.KV.GetInstance() kvStore.Set(constant.KVKeyOidcState+state, oidcConfig.Name, 5*time.Minute) - oidcConfigsDtos = append(oidcConfigsDtos, dto.OidcConfigDto{ + oidcConfigsDtos = append(oidcConfigsDtos, dto.UserOidcConfigDto{ Name: oidcConfig.Name, DisplayName: oidcConfig.DisplayName, Icon: oidcConfig.Icon, @@ -163,7 +163,7 @@ func (s *UserService) OidcLogin(req *dto.OidcLoginReq) (*dto.OidcLoginResp, erro return nil, errs.New(http.StatusForbidden, "invalid oidc state", nil) } // 获取OIDC配置 - oidcConfig, err := repo.User.GetOidcConfigByName(req.Name) + oidcConfig, err := repo.Oidc.GetOidcConfigByName(req.Name) if err != nil { return nil, errs.ErrInternalServer } diff --git a/pkg/errs/errors.go b/pkg/errs/errors.go index 05b6c6a..0c1aa28 100644 --- a/pkg/errs/errors.go +++ b/pkg/errs/errors.go @@ -27,6 +27,7 @@ var ( ErrConflict = &ServiceError{Code: http.StatusConflict, Message: "resource conflict"} ErrInternalServer = &ServiceError{Code: http.StatusInternalServerError, Message: "internal server error"} ErrBadRequest = &ServiceError{Code: http.StatusBadRequest, Message: "invalid request parameters"} + ErrUnauthorized = &ServiceError{Code: http.StatusUnauthorized, Message: "unauthorized access"} ErrForbidden = &ServiceError{Code: http.StatusForbidden, Message: "access forbidden"} )