2024-12-12 11:45:03 +08:00
|
|
|
package moto
|
|
|
|
|
2024-12-12 16:24:50 +08:00
|
|
|
import (
|
2024-12-13 10:37:09 +08:00
|
|
|
"embed"
|
2024-12-12 16:24:50 +08:00
|
|
|
"git.nobla.cn/golang/kos"
|
|
|
|
"git.nobla.cn/golang/kos/entry/http"
|
2024-12-13 10:37:09 +08:00
|
|
|
"git.nobla.cn/golang/kos/util/arrays"
|
2024-12-12 17:39:04 +08:00
|
|
|
"git.nobla.cn/golang/moto/common/db"
|
|
|
|
"git.nobla.cn/golang/moto/internal/organize"
|
|
|
|
"git.nobla.cn/golang/moto/internal/organize/passport"
|
|
|
|
"git.nobla.cn/golang/moto/internal/organize/types"
|
|
|
|
"git.nobla.cn/golang/moto/version"
|
|
|
|
"git.nobla.cn/golang/rest"
|
|
|
|
restTypes "git.nobla.cn/golang/rest/types"
|
|
|
|
"gorm.io/gorm"
|
2024-12-13 10:37:09 +08:00
|
|
|
httpkg "net/http"
|
2024-12-12 17:39:04 +08:00
|
|
|
"strconv"
|
2024-12-12 16:24:50 +08:00
|
|
|
)
|
|
|
|
|
2024-12-13 10:37:09 +08:00
|
|
|
//go:embed web/release
|
|
|
|
var webDir embed.FS
|
|
|
|
|
|
|
|
type (
|
|
|
|
resetPasswordRequest struct {
|
|
|
|
OldPassword string `json:"old_password"`
|
|
|
|
NewPassword string `json:"new_password"`
|
|
|
|
}
|
2024-12-13 11:43:32 +08:00
|
|
|
|
|
|
|
configureValue struct {
|
|
|
|
Attribute string `json:"attribute"`
|
|
|
|
Value string `json:"value"`
|
|
|
|
}
|
2024-12-13 10:37:09 +08:00
|
|
|
)
|
|
|
|
|
2024-12-12 16:24:50 +08:00
|
|
|
func (svr *Server) handleLogin(ctx *http.Context) (err error) {
|
|
|
|
var (
|
|
|
|
tk *types.Tokenize
|
|
|
|
req *passport.LoginRequest
|
|
|
|
)
|
|
|
|
req = &passport.LoginRequest{}
|
|
|
|
if err = ctx.Bind(req); err != nil {
|
|
|
|
return ctx.Error(http.ErrInvalidPayload, err.Error())
|
|
|
|
}
|
2024-12-13 10:43:49 +08:00
|
|
|
req.RealIP = ctx.RealIp()
|
|
|
|
req.UserAgent = ctx.Request().Header.Get("User-Agent")
|
2024-12-12 16:24:50 +08:00
|
|
|
if tk, err = passport.Login(ctx.Context(), req); err != nil {
|
|
|
|
return ctx.Error(http.ErrPermissionDenied, err.Error())
|
|
|
|
}
|
2024-12-13 10:37:09 +08:00
|
|
|
ctx.SetCookie(&httpkg.Cookie{Name: organize.CookieName, Value: tk.Token, Path: "/"})
|
2024-12-12 16:24:50 +08:00
|
|
|
return ctx.Success(tk)
|
|
|
|
}
|
|
|
|
|
2024-12-13 10:37:09 +08:00
|
|
|
func (svr *Server) handleResetPassword(ctx *http.Context) (err error) {
|
|
|
|
req := &resetPasswordRequest{}
|
|
|
|
if err = ctx.Bind(req); err != nil {
|
|
|
|
return ctx.Error(http.ErrInvalidPayload, err.Error())
|
|
|
|
}
|
|
|
|
userid := ctx.User().ID
|
|
|
|
if err = passport.ResetPassword(
|
|
|
|
ctx.Request().Context(),
|
|
|
|
userid,
|
|
|
|
req.OldPassword,
|
|
|
|
req.NewPassword,
|
|
|
|
); err != nil {
|
|
|
|
return ctx.Error(http.ErrResourceUpdate, err.Error())
|
|
|
|
}
|
|
|
|
return ctx.Success("OK")
|
|
|
|
}
|
|
|
|
|
2024-12-12 16:24:50 +08:00
|
|
|
func (svr *Server) handleLogout(ctx *http.Context) (err error) {
|
|
|
|
passport.Logout(ctx.Context(), ctx.User().Get("token"))
|
|
|
|
return ctx.Success("logout")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svr *Server) handleProfile(ctx *http.Context) (err error) {
|
|
|
|
var (
|
|
|
|
profile *types.Profile
|
|
|
|
)
|
2024-12-12 17:39:04 +08:00
|
|
|
if profile, err = organize.Profile(ctx.Context(), ctx.User().ID); err != nil {
|
2024-12-12 16:24:50 +08:00
|
|
|
return ctx.Error(http.ErrTemporaryUnavailable, err.Error())
|
|
|
|
}
|
2024-12-13 10:37:09 +08:00
|
|
|
if arrays.Exists(ctx.User().ID, svr.cfg.AdminUsers) {
|
|
|
|
profile.Admin = true
|
|
|
|
}
|
2024-12-12 16:24:50 +08:00
|
|
|
return ctx.Success(profile)
|
|
|
|
}
|
|
|
|
|
2024-12-13 10:37:09 +08:00
|
|
|
func (svr *Server) handleUpdateProfile(ctx *http.Context) (err error) {
|
|
|
|
var (
|
|
|
|
profile *types.Profile
|
|
|
|
)
|
|
|
|
profile = &types.Profile{}
|
|
|
|
if err = ctx.Bind(profile); err != nil {
|
|
|
|
return ctx.Error(http.ErrInvalidPayload, err.Error())
|
|
|
|
}
|
|
|
|
if err = organize.UpdateProfile(ctx.Context(), ctx.User().ID, profile); err == nil {
|
|
|
|
return ctx.Success(profile)
|
|
|
|
} else {
|
|
|
|
return ctx.Error(http.ErrTemporaryUnavailable, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-12 16:24:50 +08:00
|
|
|
func (svr *Server) handleGetConfigure(ctx *http.Context) (err error) {
|
2024-12-13 11:43:32 +08:00
|
|
|
ms := make([]configureValue, 0, len(svr.cfg.System.Settings))
|
|
|
|
for k, v := range svr.cfg.System.Settings {
|
|
|
|
ms = append(ms, configureValue{
|
|
|
|
Attribute: k,
|
|
|
|
Value: v,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return ctx.Success(ms)
|
2024-12-12 16:24:50 +08:00
|
|
|
}
|
|
|
|
|
2024-12-12 17:39:04 +08:00
|
|
|
func (svr *Server) handleListSchema(ctx *http.Context) (err error) {
|
|
|
|
var (
|
|
|
|
schemas []*restTypes.Schema
|
|
|
|
)
|
|
|
|
scenario := ctx.Query("scenario")
|
|
|
|
if scenario == "" {
|
|
|
|
schemas, err = rest.GetSchemas(
|
|
|
|
ctx.Request().Context(),
|
|
|
|
db.WithContext(ctx.Request().Context()),
|
2024-12-13 10:37:09 +08:00
|
|
|
"",
|
|
|
|
version.ModuleName,
|
2024-12-12 17:39:04 +08:00
|
|
|
ctx.Param("table"),
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
schemas, err = rest.VisibleSchemas(
|
|
|
|
ctx.Request().Context(),
|
|
|
|
db.WithContext(ctx.Request().Context()),
|
2024-12-13 10:37:09 +08:00
|
|
|
"",
|
|
|
|
version.ModuleName,
|
2024-12-12 17:39:04 +08:00
|
|
|
ctx.Param("table"),
|
|
|
|
scenario,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return ctx.Error(http.ErrResourceNotFound, err.Error())
|
|
|
|
} else {
|
|
|
|
return ctx.Success(schemas)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svr *Server) handleSaveSchema(ctx *http.Context) (err error) {
|
|
|
|
schemas := make([]*restTypes.Schema, 0)
|
|
|
|
if err = ctx.Bind(&schemas); err != nil {
|
|
|
|
return ctx.Error(http.ErrInvalidPayload, err.Error())
|
|
|
|
}
|
|
|
|
domainName := ctx.User().Get("domain")
|
|
|
|
for i, _ := range schemas {
|
|
|
|
schemas[i].Domain = domainName
|
|
|
|
}
|
|
|
|
if err = db.WithContext(ctx.Request().Context()).Transaction(func(tx *gorm.DB) (errTx error) {
|
|
|
|
for _, scm := range schemas {
|
|
|
|
if errTx = tx.Save(scm).Error; errTx != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}); err == nil {
|
|
|
|
return ctx.Success(map[string]interface{}{
|
|
|
|
"count": len(schemas),
|
|
|
|
"state": "success",
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
return ctx.Error(http.ErrTemporaryUnavailable, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svr *Server) handleDeleteSchema(ctx *http.Context) (err error) {
|
|
|
|
id, _ := strconv.Atoi(ctx.Param("id"))
|
|
|
|
model := &restTypes.Schema{Id: uint64(id)}
|
|
|
|
if err = db.WithContext(ctx.Request().Context()).Delete(model).Error; err == nil {
|
|
|
|
return ctx.Success(map[string]any{
|
|
|
|
"id": id,
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
return ctx.Error(http.ErrResourceDelete, err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-13 10:37:09 +08:00
|
|
|
func (svr *Server) handleDepartmentTypes(ctx *http.Context) (err error) {
|
|
|
|
return ctx.Success(organize.DepartmentTypes(ctx.Context()))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svr *Server) handleRoleTypes(ctx *http.Context) (err error) {
|
|
|
|
return ctx.Success(organize.RoleTypes(ctx.Context()))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svr *Server) handleUserTypes(ctx *http.Context) (err error) {
|
|
|
|
return ctx.Success(organize.UserTypes(ctx.Context()))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svr *Server) handleUserTags(ctx *http.Context) (err error) {
|
|
|
|
return ctx.Success(organize.UserTags(ctx.Context()))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svr *Server) handleUserAvatar(ctx *http.Context) (err error) {
|
|
|
|
organize.Avatar(ctx.Context(), svr.cfg.Avatar.Dirname, ctx.Param("id"), ctx.Request(), ctx.Response())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-12-12 11:45:03 +08:00
|
|
|
func (svr *Server) routes() {
|
2024-12-13 10:37:09 +08:00
|
|
|
|
2024-12-12 17:39:04 +08:00
|
|
|
kos.Http().Use(organize.AuthMiddleware)
|
|
|
|
organize.AllowUri("/passport/login")
|
2024-12-12 11:45:03 +08:00
|
|
|
|
2024-12-13 10:37:09 +08:00
|
|
|
kos.Http().Root("/web/release", httpkg.FS(webDir))
|
|
|
|
|
2024-12-12 16:24:50 +08:00
|
|
|
kos.Http().Handle(http.MethodPost, "/passport/login", svr.handleLogin)
|
2024-12-13 10:37:09 +08:00
|
|
|
kos.Http().Handle(http.MethodPut, "/passport/reset-password", svr.handleResetPassword)
|
2024-12-12 16:24:50 +08:00
|
|
|
kos.Http().Handle(http.MethodDelete, "/passport/logout", svr.handleLogout)
|
|
|
|
kos.Http().Handle(http.MethodGet, "/user/profile", svr.handleProfile)
|
2024-12-13 10:37:09 +08:00
|
|
|
kos.Http().Handle(http.MethodPut, "/user/profile", svr.handleUpdateProfile)
|
2024-12-12 16:24:50 +08:00
|
|
|
kos.Http().Handle(http.MethodGet, "/user/configures", svr.handleGetConfigure)
|
2024-12-12 17:39:04 +08:00
|
|
|
|
2024-12-13 10:37:09 +08:00
|
|
|
kos.Http().Handle(http.MethodGet, "/rest/schema/:table", svr.handleListSchema)
|
|
|
|
kos.Http().Handle(http.MethodPut, "/rest/schema/:table", svr.handleSaveSchema)
|
2024-12-12 17:39:04 +08:00
|
|
|
kos.Http().Handle(http.MethodDelete, "/rest/schema/:id", svr.handleDeleteSchema)
|
|
|
|
|
2024-12-13 10:37:09 +08:00
|
|
|
kos.Http().Handle(http.MethodGet, "/organize/department-types", svr.handleDepartmentTypes)
|
|
|
|
kos.Http().Handle(http.MethodGet, "/organize/role-types", svr.handleRoleTypes)
|
|
|
|
kos.Http().Handle(http.MethodGet, "/organize/user-types", svr.handleUserTypes)
|
|
|
|
kos.Http().Handle(http.MethodGet, "/organize/user-tags", svr.handleUserTags)
|
|
|
|
kos.Http().Handle(http.MethodGet, "/profile/avatar/:id", svr.handleUserAvatar)
|
2024-12-12 11:45:03 +08:00
|
|
|
}
|