mirror of
https://github.com/snowykami/neo-blog.git
synced 2025-09-03 15:56:22 +00:00
⚡ implement OIDC configuration management with CRUD operations, add admin routes, and enhance error handling
This commit is contained in:
92
internal/controller/v1/console.go
Normal file
92
internal/controller/v1/console.go
Normal file
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
12
internal/dto/console.go
Normal file
12
internal/dto/console.go
Normal file
@ -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"`
|
||||
}
|
@ -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列表
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
55
internal/repo/label.go
Normal file
55
internal/repo/label.go
Normal file
@ -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
|
||||
}
|
69
internal/repo/oidc_config.go
Normal file
69
internal/repo/oidc_config.go
Normal file
@ -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
|
||||
}
|
54
internal/repo/post.go
Normal file
54
internal/repo/post.go
Normal file
@ -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
|
||||
}
|
@ -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
|
||||
|
20
internal/router/apiv1/console.go
Normal file
20
internal/router/apiv1/console.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ func RegisterRoutes(h *server.Hertz) {
|
||||
apiV1Group := h.Group("/api/v1")
|
||||
{
|
||||
registerCommentRoutes(apiV1Group)
|
||||
registerAdminRoutes(apiV1Group)
|
||||
registerFileRoutes(apiV1Group)
|
||||
registerLabelRoutes(apiV1Group)
|
||||
registerPageRoutes(apiV1Group)
|
||||
|
75
internal/service/console.go
Normal file
75
internal/service/console.go
Normal file
@ -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)
|
||||
}
|
46
internal/service/post.go
Normal file
46
internal/service/post.go
Normal file
@ -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() {}
|
@ -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
|
||||
}
|
||||
|
@ -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"}
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user