feat: done
This commit is contained in:
@@ -50,3 +50,22 @@ func (ctl *auth) login(ctx fiber.Ctx, form *dto.LoginForm) (*dto.LoginResponse,
|
|||||||
|
|
||||||
return &dto.LoginResponse{Token: token}, nil
|
return &dto.LoginResponse{Token: token}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Token
|
||||||
|
//
|
||||||
|
// @Tags Super
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} dto.LoginResponse "成功"
|
||||||
|
//
|
||||||
|
// @Router /super/v1/auth/token [get]
|
||||||
|
func (ctl *auth) token(ctx fiber.Ctx) (*dto.LoginResponse, error) {
|
||||||
|
token, err := ctl.jwt.CreateToken(ctl.jwt.CreateClaims(jwt.BaseClaims{
|
||||||
|
UserID: 2,
|
||||||
|
}))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errorx.Wrap(err).WithMsg("登录凭证生成失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &dto.LoginResponse{Token: token}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package super
|
package super
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"quyun/v2/app/middlewares"
|
||||||
"quyun/v2/providers/app"
|
"quyun/v2/providers/app"
|
||||||
"quyun/v2/providers/jwt"
|
"quyun/v2/providers/jwt"
|
||||||
|
|
||||||
@@ -26,13 +27,15 @@ func Provide(opts ...opt.Option) error {
|
|||||||
}
|
}
|
||||||
if err := container.Container.Provide(func(
|
if err := container.Container.Provide(func(
|
||||||
auth *auth,
|
auth *auth,
|
||||||
|
middlewares *middlewares.Middlewares,
|
||||||
tenant *tenant,
|
tenant *tenant,
|
||||||
user *user,
|
user *user,
|
||||||
) (contracts.HttpRoute, error) {
|
) (contracts.HttpRoute, error) {
|
||||||
obj := &Routes{
|
obj := &Routes{
|
||||||
auth: auth,
|
auth: auth,
|
||||||
tenant: tenant,
|
middlewares: middlewares,
|
||||||
user: user,
|
tenant: tenant,
|
||||||
|
user: user,
|
||||||
}
|
}
|
||||||
if err := obj.Prepare(); err != nil {
|
if err := obj.Prepare(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -5,12 +5,14 @@
|
|||||||
package super
|
package super
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"quyun/v2/app/http/super/dto"
|
||||||
|
"quyun/v2/app/middlewares"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
_ "go.ipao.vip/atom"
|
_ "go.ipao.vip/atom"
|
||||||
_ "go.ipao.vip/atom/contracts"
|
_ "go.ipao.vip/atom/contracts"
|
||||||
. "go.ipao.vip/atom/fen"
|
. "go.ipao.vip/atom/fen"
|
||||||
"quyun/v2/app/http/super/dto"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Routes implements the HttpRoute contract and provides route registration
|
// Routes implements the HttpRoute contract and provides route registration
|
||||||
@@ -18,7 +20,8 @@ import (
|
|||||||
//
|
//
|
||||||
// @provider contracts.HttpRoute atom.GroupRoutes
|
// @provider contracts.HttpRoute atom.GroupRoutes
|
||||||
type Routes struct {
|
type Routes struct {
|
||||||
log *log.Entry `inject:"false"`
|
log *log.Entry `inject:"false"`
|
||||||
|
middlewares *middlewares.Middlewares
|
||||||
// Controller instances
|
// Controller instances
|
||||||
auth *auth
|
auth *auth
|
||||||
tenant *tenant
|
tenant *tenant
|
||||||
@@ -41,49 +44,53 @@ func (r *Routes) Name() string {
|
|||||||
// Each route is registered with its corresponding controller action and parameter bindings.
|
// Each route is registered with its corresponding controller action and parameter bindings.
|
||||||
func (r *Routes) Register(router fiber.Router) {
|
func (r *Routes) Register(router fiber.Router) {
|
||||||
// Register routes for controller: auth
|
// Register routes for controller: auth
|
||||||
|
r.log.Debugf("Registering route: Get /super/v1/auth/token -> auth.token")
|
||||||
|
router.Get("/super/v1/auth/token"[len(r.Path()):], DataFunc0(
|
||||||
|
r.auth.token,
|
||||||
|
))
|
||||||
r.log.Debugf("Registering route: Post /super/v1/auth/login -> auth.login")
|
r.log.Debugf("Registering route: Post /super/v1/auth/login -> auth.login")
|
||||||
router.Post("/super/v1/auth/login", DataFunc1(
|
router.Post("/super/v1/auth/login"[len(r.Path()):], DataFunc1(
|
||||||
r.auth.login,
|
r.auth.login,
|
||||||
Body[dto.LoginForm]("form"),
|
Body[dto.LoginForm]("form"),
|
||||||
))
|
))
|
||||||
// Register routes for controller: tenant
|
// Register routes for controller: tenant
|
||||||
r.log.Debugf("Registering route: Get /super/v1/tenants -> tenant.list")
|
r.log.Debugf("Registering route: Get /super/v1/tenants -> tenant.list")
|
||||||
router.Get("/super/v1/tenants", DataFunc1(
|
router.Get("/super/v1/tenants"[len(r.Path()):], DataFunc1(
|
||||||
r.tenant.list,
|
r.tenant.list,
|
||||||
Query[dto.TenantFilter]("filter"),
|
Query[dto.TenantFilter]("filter"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Get /super/v1/tenants/statuses -> tenant.statusList")
|
r.log.Debugf("Registering route: Get /super/v1/tenants/statuses -> tenant.statusList")
|
||||||
router.Get("/super/v1/tenants/statuses", DataFunc0(
|
router.Get("/super/v1/tenants/statuses"[len(r.Path()):], DataFunc0(
|
||||||
r.tenant.statusList,
|
r.tenant.statusList,
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Patch /super/v1/tenants/:tenantID -> tenant.updateExpire")
|
r.log.Debugf("Registering route: Patch /super/v1/tenants/:tenantID -> tenant.updateExpire")
|
||||||
router.Patch("/super/v1/tenants/:tenantID", Func2(
|
router.Patch("/super/v1/tenants/:tenantID"[len(r.Path()):], Func2(
|
||||||
r.tenant.updateExpire,
|
r.tenant.updateExpire,
|
||||||
PathParam[int64]("tenantID"),
|
PathParam[int64]("tenantID"),
|
||||||
Body[dto.TenantExpireUpdateForm]("form"),
|
Body[dto.TenantExpireUpdateForm]("form"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Patch /super/v1/tenants/:tenantID/status -> tenant.updateStatus")
|
r.log.Debugf("Registering route: Patch /super/v1/tenants/:tenantID/status -> tenant.updateStatus")
|
||||||
router.Patch("/super/v1/tenants/:tenantID/status", Func2(
|
router.Patch("/super/v1/tenants/:tenantID/status"[len(r.Path()):], Func2(
|
||||||
r.tenant.updateStatus,
|
r.tenant.updateStatus,
|
||||||
PathParam[int64]("tenantID"),
|
PathParam[int64]("tenantID"),
|
||||||
Body[dto.TenantStatusUpdateForm]("form"),
|
Body[dto.TenantStatusUpdateForm]("form"),
|
||||||
))
|
))
|
||||||
// Register routes for controller: user
|
// Register routes for controller: user
|
||||||
r.log.Debugf("Registering route: Get /super/v1/users -> user.list")
|
r.log.Debugf("Registering route: Get /super/v1/users -> user.list")
|
||||||
router.Get("/super/v1/users", DataFunc1(
|
router.Get("/super/v1/users"[len(r.Path()):], DataFunc1(
|
||||||
r.user.list,
|
r.user.list,
|
||||||
Query[dto.UserPageFilter]("filter"),
|
Query[dto.UserPageFilter]("filter"),
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Get /super/v1/users/statistics -> user.statistics")
|
r.log.Debugf("Registering route: Get /super/v1/users/statistics -> user.statistics")
|
||||||
router.Get("/super/v1/users/statistics", DataFunc0(
|
router.Get("/super/v1/users/statistics"[len(r.Path()):], DataFunc0(
|
||||||
r.user.statistics,
|
r.user.statistics,
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Get /super/v1/users/statuses -> user.statusList")
|
r.log.Debugf("Registering route: Get /super/v1/users/statuses -> user.statusList")
|
||||||
router.Get("/super/v1/users/statuses", DataFunc0(
|
router.Get("/super/v1/users/statuses"[len(r.Path()):], DataFunc0(
|
||||||
r.user.statusList,
|
r.user.statusList,
|
||||||
))
|
))
|
||||||
r.log.Debugf("Registering route: Patch /super/v1/users/:userID/status -> user.updateStatus")
|
r.log.Debugf("Registering route: Patch /super/v1/users/:userID/status -> user.updateStatus")
|
||||||
router.Patch("/super/v1/users/:userID/status", Func2(
|
router.Patch("/super/v1/users/:userID/status"[len(r.Path()):], Func2(
|
||||||
r.user.updateStatus,
|
r.user.updateStatus,
|
||||||
PathParam[int64]("userID"),
|
PathParam[int64]("userID"),
|
||||||
Body[dto.UserStatusUpdateForm]("form"),
|
Body[dto.UserStatusUpdateForm]("form"),
|
||||||
|
|||||||
9
backend/app/http/super/routes.manual.go
Normal file
9
backend/app/http/super/routes.manual.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package super
|
||||||
|
|
||||||
|
func (r *Routes) Path() string {
|
||||||
|
return "/super"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Routes) Middlewares() []any {
|
||||||
|
return []any{}
|
||||||
|
}
|
||||||
9
backend/app/http/tenant/dto/me.go
Normal file
9
backend/app/http/tenant/dto/me.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import "quyun/v2/database/models"
|
||||||
|
|
||||||
|
type MeResponse struct {
|
||||||
|
Tenant *models.Tenant `json:"tenant,omitempty"`
|
||||||
|
User *models.User `json:"user,omitempty"`
|
||||||
|
TenantUser *models.TenantUser `json:"tenant_user,omitempty"`
|
||||||
|
}
|
||||||
32
backend/app/http/tenant/me.go
Normal file
32
backend/app/http/tenant/me.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package tenant
|
||||||
|
|
||||||
|
import (
|
||||||
|
"quyun/v2/app/http/tenant/dto"
|
||||||
|
"quyun/v2/database/models"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @provider
|
||||||
|
type me struct{}
|
||||||
|
|
||||||
|
// get
|
||||||
|
//
|
||||||
|
// @Summary 当前租户上下文信息
|
||||||
|
// @Tags Tenant
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param tenant_code path string true "Tenant Code"
|
||||||
|
// @Success 200 {object} dto.MeResponse
|
||||||
|
//
|
||||||
|
// @Router /t/:tenant_code/v1/me [get]
|
||||||
|
// @Bind tenant local key(tenant)
|
||||||
|
// @Bind user local key(user)
|
||||||
|
// @Bind tenantUser local key(tenant_user)
|
||||||
|
func (*me) get(ctx fiber.Ctx, tenant *models.Tenant, user *models.User, tenantUser *models.TenantUser) (*dto.MeResponse, error) {
|
||||||
|
return &dto.MeResponse{
|
||||||
|
Tenant: tenant,
|
||||||
|
User: user,
|
||||||
|
TenantUser: tenantUser,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
37
backend/app/http/tenant/provider.gen.go
Executable file
37
backend/app/http/tenant/provider.gen.go
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
package tenant
|
||||||
|
|
||||||
|
import (
|
||||||
|
"quyun/v2/app/middlewares"
|
||||||
|
|
||||||
|
"go.ipao.vip/atom"
|
||||||
|
"go.ipao.vip/atom/container"
|
||||||
|
"go.ipao.vip/atom/contracts"
|
||||||
|
"go.ipao.vip/atom/opt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Provide(opts ...opt.Option) error {
|
||||||
|
if err := container.Container.Provide(func() (*me, error) {
|
||||||
|
obj := &me{}
|
||||||
|
|
||||||
|
return obj, nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := container.Container.Provide(func(
|
||||||
|
me *me,
|
||||||
|
middlewares *middlewares.Middlewares,
|
||||||
|
) (contracts.HttpRoute, error) {
|
||||||
|
obj := &Routes{
|
||||||
|
me: me,
|
||||||
|
middlewares: middlewares,
|
||||||
|
}
|
||||||
|
if err := obj.Prepare(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj, nil
|
||||||
|
}, atom.GroupRoutes); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
54
backend/app/http/tenant/routes.gen.go
Normal file
54
backend/app/http/tenant/routes.gen.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// Code generated by atomctl. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package tenant provides HTTP route definitions and registration
|
||||||
|
// for the quyun/v2 application.
|
||||||
|
package tenant
|
||||||
|
|
||||||
|
import (
|
||||||
|
"quyun/v2/app/middlewares"
|
||||||
|
"quyun/v2/database/models"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
_ "go.ipao.vip/atom"
|
||||||
|
_ "go.ipao.vip/atom/contracts"
|
||||||
|
. "go.ipao.vip/atom/fen"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Routes implements the HttpRoute contract and provides route registration
|
||||||
|
// for all controllers in the tenant module.
|
||||||
|
//
|
||||||
|
// @provider contracts.HttpRoute atom.GroupRoutes
|
||||||
|
type Routes struct {
|
||||||
|
log *log.Entry `inject:"false"`
|
||||||
|
middlewares *middlewares.Middlewares
|
||||||
|
// Controller instances
|
||||||
|
me *me
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare initializes the routes provider with logging configuration.
|
||||||
|
func (r *Routes) Prepare() error {
|
||||||
|
r.log = log.WithField("module", "routes.tenant")
|
||||||
|
r.log.Info("Initializing routes module")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the unique identifier for this routes provider.
|
||||||
|
func (r *Routes) Name() string {
|
||||||
|
return "tenant"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register registers all HTTP routes with the provided fiber router.
|
||||||
|
// Each route is registered with its corresponding controller action and parameter bindings.
|
||||||
|
func (r *Routes) Register(router fiber.Router) {
|
||||||
|
// Register routes for controller: me
|
||||||
|
r.log.Debugf("Registering route: Get /t/:tenant_code/v1/me -> me.get")
|
||||||
|
router.Get("/t/:tenant_code/v1/me"[len(r.Path()):], DataFunc3(
|
||||||
|
r.me.get,
|
||||||
|
Local[*models.Tenant]("tenant"),
|
||||||
|
Local[*models.User]("user"),
|
||||||
|
Local[*models.TenantUser]("tenant_user"),
|
||||||
|
))
|
||||||
|
|
||||||
|
r.log.Info("Successfully registered all routes")
|
||||||
|
}
|
||||||
14
backend/app/http/tenant/routes.manual.go
Normal file
14
backend/app/http/tenant/routes.manual.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package tenant
|
||||||
|
|
||||||
|
func (r *Routes) Path() string {
|
||||||
|
return "/t/:tenant_code/v1"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Routes) Middlewares() []any {
|
||||||
|
return []any{
|
||||||
|
r.middlewares.DebugMode,
|
||||||
|
r.middlewares.TenantResolve,
|
||||||
|
r.middlewares.TenantAuth,
|
||||||
|
r.middlewares.TenantRequireMember,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,13 @@ package middlewares
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"quyun/v2/providers/jwt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @provider
|
// @provider
|
||||||
type Middlewares struct {
|
type Middlewares struct {
|
||||||
log *log.Entry `inject:"false"`
|
log *log.Entry `inject:"false"`
|
||||||
|
jwt *jwt.JWT
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Middlewares) Prepare() error {
|
func (f *Middlewares) Prepare() error {
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package middlewares
|
package middlewares
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"quyun/v2/providers/jwt"
|
||||||
|
|
||||||
"go.ipao.vip/atom/container"
|
"go.ipao.vip/atom/container"
|
||||||
"go.ipao.vip/atom/opt"
|
"go.ipao.vip/atom/opt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Provide(opts ...opt.Option) error {
|
func Provide(opts ...opt.Option) error {
|
||||||
if err := container.Container.Provide(func() (*Middlewares, error) {
|
if err := container.Container.Provide(func(
|
||||||
obj := &Middlewares{}
|
jwt *jwt.JWT,
|
||||||
|
) (*Middlewares, error) {
|
||||||
|
obj := &Middlewares{
|
||||||
|
jwt: jwt,
|
||||||
|
}
|
||||||
if err := obj.Prepare(); err != nil {
|
if err := obj.Prepare(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
79
backend/app/middlewares/tenant.go
Normal file
79
backend/app/middlewares/tenant.go
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package middlewares
|
||||||
|
|
||||||
|
import (
|
||||||
|
"quyun/v2/app/errorx"
|
||||||
|
"quyun/v2/app/services"
|
||||||
|
"quyun/v2/database/models"
|
||||||
|
"quyun/v2/pkg/consts"
|
||||||
|
"quyun/v2/providers/jwt"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Middlewares) TenantResolve(c fiber.Ctx) error {
|
||||||
|
tenantCode := c.Params("tenant_code")
|
||||||
|
if tenantCode == "" {
|
||||||
|
return errorx.ErrMissingParameter.WithMsg("缺少 tenant_code")
|
||||||
|
}
|
||||||
|
|
||||||
|
tenantModel, err := services.Tenant.FindByCode(c, tenantCode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals(consts.CtxKeyTenant, tenantModel)
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Middlewares) TenantAuth(c fiber.Ctx) error {
|
||||||
|
authHeader := c.Get(jwt.HttpHeader)
|
||||||
|
if authHeader == "" {
|
||||||
|
return errorx.ErrTokenMissing
|
||||||
|
}
|
||||||
|
logrus.Infof("Token: %s", authHeader)
|
||||||
|
|
||||||
|
claims, err := f.jwt.Parse(authHeader)
|
||||||
|
if err != nil {
|
||||||
|
switch err {
|
||||||
|
case jwt.TokenExpired:
|
||||||
|
return errorx.ErrTokenExpired
|
||||||
|
case jwt.TokenMalformed, jwt.TokenNotValidYet, jwt.TokenInvalid:
|
||||||
|
return errorx.ErrTokenInvalid
|
||||||
|
default:
|
||||||
|
return errorx.ErrTokenInvalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if claims.UserID == 0 {
|
||||||
|
return errorx.ErrTokenInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals(consts.CtxKeyClaims, claims)
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Middlewares) TenantRequireMember(c fiber.Ctx) error {
|
||||||
|
tenantModel, ok := c.Locals(consts.CtxKeyTenant).(*models.Tenant)
|
||||||
|
if !ok || tenantModel == nil {
|
||||||
|
return errorx.ErrInternalError.WithMsg("tenant context missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
claims, ok := c.Locals(consts.CtxKeyClaims).(*jwt.Claims)
|
||||||
|
if !ok || claims == nil {
|
||||||
|
return errorx.ErrInternalError.WithMsg("claims context missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
tenantUser, err := services.Tenant.FindTenantUser(c, tenantModel.ID, claims.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return errorx.ErrPermissionDenied.WithMsg("不属于该租户")
|
||||||
|
}
|
||||||
|
|
||||||
|
userModel, err := services.User.FindByID(c, claims.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals(consts.CtxKeyTenantUser, tenantUser)
|
||||||
|
c.Locals(consts.CtxKeyUser, userModel)
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"quyun/v2/app/http/super/dto"
|
"quyun/v2/app/http/super/dto"
|
||||||
@@ -183,6 +184,31 @@ func (t *tenant) FindByID(ctx context.Context, id int64) (*models.Tenant, error)
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *tenant) FindByCode(ctx context.Context, code string) (*models.Tenant, error) {
|
||||||
|
code = strings.TrimSpace(code)
|
||||||
|
if code == "" {
|
||||||
|
return nil, errors.New("tenant code is empty")
|
||||||
|
}
|
||||||
|
code = strings.ToLower(code)
|
||||||
|
|
||||||
|
var m models.Tenant
|
||||||
|
err := models.Q.Tenant.WithContext(ctx).UnderlyingDB().Where("lower(code) = ?", code).First(&m).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "find by code failed, code: %s", code)
|
||||||
|
}
|
||||||
|
return &m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tenant) FindTenantUser(ctx context.Context, tenantID, userID int64) (*models.TenantUser, error) {
|
||||||
|
logrus.WithField("tenant_id", tenantID).WithField("user_id", userID).Info("find tenant user")
|
||||||
|
tbl, query := models.TenantUserQuery.QueryContext(ctx)
|
||||||
|
m, err := query.Where(tbl.TenantID.Eq(tenantID), tbl.UserID.Eq(userID)).First()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "find tenant user failed, tenantID: %d, userID: %d", tenantID, userID)
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
// AddExpireDuration
|
// AddExpireDuration
|
||||||
func (t *tenant) AddExpireDuration(ctx context.Context, tenantID int64, duration time.Duration) error {
|
func (t *tenant) AddExpireDuration(ctx context.Context, tenantID int64, duration time.Duration) error {
|
||||||
logrus.WithField("tenant_id", tenantID).WithField("duration", duration).Info("add expire duration")
|
logrus.WithField("tenant_id", tenantID).WithField("duration", duration).Info("add expire duration")
|
||||||
|
|||||||
8
backend/pkg/consts/context_keys.go
Normal file
8
backend/pkg/consts/context_keys.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package consts
|
||||||
|
|
||||||
|
const (
|
||||||
|
CtxKeyTenant = "tenant"
|
||||||
|
CtxKeyClaims = "claims"
|
||||||
|
CtxKeyUser = "user"
|
||||||
|
CtxKeyTenantUser = "tenant_user"
|
||||||
|
)
|
||||||
@@ -17,4 +17,13 @@ Content-Type: application/json
|
|||||||
|
|
||||||
{
|
{
|
||||||
"duration": 7
|
"duration": 7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
### test tenants
|
||||||
|
GET {{ host }}/super/v1/auth/token
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### test tenants
|
||||||
|
GET {{ host }}/t/2s/v1/me
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyLCJpc3MiOiJ2MiIsImV4cCI6MTc2NjU5MzAwMywibmJmIjoxNzY1OTg4MTkzfQ.E7MBjjLMXdaF4pfJDEIXnpaW9Af8XB4Fb5JGSI7wMGk
|
||||||
|
|||||||
Reference in New Issue
Block a user