Skip to content

Commit

Permalink
refactor(cmfx): 重构项目
Browse files Browse the repository at this point in the history
  • Loading branch information
caixw committed May 14, 2024
1 parent a5d65df commit 3590945
Show file tree
Hide file tree
Showing 43 changed files with 866 additions and 499 deletions.
6 changes: 4 additions & 2 deletions cmd/server/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@
<router>
<url>http://localhost:8080</url>
</router>
<admin accessExpires="43200" refreshExpires="86400">
<urlPrefix>/admin</urlPrefix>
<admin superUser="1">
<user accessExpires="43200" refreshExpires="86400">
<urlPrefix>/admin</urlPrefix>
</user>
</admin>
</user>
</web>
4 changes: 1 addition & 3 deletions cmfx/cmfx.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ const (
UnauthorizedSecurityToken = "40103" // 需要强验证
UnauthorizedInvalidAccount = "40104" // 无效的账号或密码
UnauthorizedNeedChangePassword = "40105"

// 可注册的状态,比如 OAuth2 验证,如果未注册,返回一个 ID 可用以注册。
UnauthorizedRegistrable = "40106"
UnauthorizedRegistrable = "40106" // 可注册的状态,比如 OAuth2 验证,如果未注册,返回一个 ID 可用以注册。
)

// 403
Expand Down
4 changes: 2 additions & 2 deletions cmfx/initial/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ func initServer(name, ver string, o *server.Options, user *Config, action string
adminL := admin.Load(adminMod, user.Admin)
system.Load(systemMod, user.System, adminL)
case "install":
admin.Install(adminMod)
system.Install(systemMod)
adminL := admin.Install(adminMod, user.Admin)
system.Install(systemMod, user.System, adminL)
case "upgrade":
panic("not implements")
default:
Expand Down
146 changes: 73 additions & 73 deletions cmfx/initial/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,97 +5,97 @@
package cmd

import (
"github.com/issue9/orm/v6"
"github.com/issue9/orm/v6/dialect"
"github.com/issue9/web"
"github.com/issue9/orm/v6"
"github.com/issue9/orm/v6/dialect"
"github.com/issue9/web"

"github.com/issue9/cmfx/cmfx/modules/system"
"github.com/issue9/cmfx/cmfx/user"
"github.com/issue9/cmfx/locales"
"github.com/issue9/cmfx/cmfx/modules/admin"
"github.com/issue9/cmfx/cmfx/modules/system"
"github.com/issue9/cmfx/locales"
)

// Config 配置文件的自定义部分内容
type Config struct {
// DB 数据库配置
DB *DB `yaml:"db" xml:"db" json:"db"`
// DB 数据库配置
DB *DB `yaml:"db" xml:"db" json:"db"`

// URL 路由的基地址
URL string `yaml:"url" xml:"url" json:"url"`
// URL 路由的基地址
URL string `yaml:"url" xml:"url" json:"url"`

// Admin 后台管理员用户的相关配置
Admin *user.Config `yaml:"admin" xml:"admin" json:"admin"`
// Admin 后台管理员用户的相关配置
Admin *admin.Config `yaml:"admin" xml:"admin" json:"admin"`

// System 系统模块的相关配置
System *system.Config `yaml:"system,omitempty" xml:"system,omitempty" json:"system,omitempty"`
// System 系统模块的相关配置
System *system.Config `yaml:"system,omitempty" xml:"system,omitempty" json:"system,omitempty"`
}

// DB 数据库的配置项
type DB struct {
// Prefix 表名前缀
//
// 可以为空。
Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty" xml:"prefix,attr,omitempty"`

// 表示数据库的类型
//
// 目前支持以下几种类型:
// - sqlite3
// - sqlite 纯 Go
// - mysql
// - mariadb
// - postgres
Type string `yaml:"type" json:"type" xml:"type,attr"`

// 连接数据库的参数
DSN string `yaml:"dsn" json:"dsn" xml:"dsn"`

db *orm.DB
// Prefix 表名前缀
//
// 可以为空。
Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty" xml:"prefix,attr,omitempty"`

// 表示数据库的类型
//
// 目前支持以下几种类型:
// - sqlite3
// - sqlite 纯 Go
// - mysql
// - mariadb
// - postgres
Type string `yaml:"type" json:"type" xml:"type,attr"`

// 连接数据库的参数
DSN string `yaml:"dsn" json:"dsn" xml:"dsn"`

db *orm.DB
}

func (c *Config) SanitizeConfig() *web.FieldError {
if err := c.DB.SanitizeConfig(); err != nil {
return err.AddFieldParent("db")
}
if err := c.Admin.SanitizeConfig(); err != nil {
return err.AddFieldParent("admin")
}

if c.System != nil {
if err := c.System.SanitizeConfig(); err != nil {
return err.AddFieldParent("system")
}
}

return nil
if err := c.DB.SanitizeConfig(); err != nil {
return err.AddFieldParent("db")
}

if err := c.Admin.SanitizeConfig(); err != nil {
return err.AddFieldParent("admin")
}

if c.System != nil {
if err := c.System.SanitizeConfig(); err != nil {
return err.AddFieldParent("system")
}
}

return nil
}

func (conf *DB) SanitizeConfig() *web.FieldError {
var d orm.Dialect
switch conf.Type {
case "sqlite3":
d = dialect.Sqlite3("sqlite3")
case "sqlite":
d = dialect.Sqlite3("sqlite")
case "mysql":
d = dialect.Mysql("mysql")
case "mariadb":
d = dialect.Mariadb("mysql")
case "postgres":
d = dialect.Postgres("postgres")
default:
err := web.NewFieldError("type", locales.InvalidValue)
err.Value = conf.Type
return err
}

db, err := orm.NewDB(conf.Prefix, conf.DSN, d)
if err != nil {
return web.NewFieldError("", err)
}
conf.db = db

return nil
var d orm.Dialect
switch conf.Type {
case "sqlite3":
d = dialect.Sqlite3("sqlite3")
case "sqlite":
d = dialect.Sqlite3("sqlite")
case "mysql":
d = dialect.Mysql("mysql")
case "mariadb":
d = dialect.Mariadb("mysql")
case "postgres":
d = dialect.Postgres("postgres")
default:
err := web.NewFieldError("type", locales.InvalidValue)
err.Value = conf.Type
return err
}

db, err := orm.NewDB(conf.Prefix, conf.DSN, d)
if err != nil {
return web.NewFieldError("", err)
}
conf.db = db

return nil
}

// DB 返回根据配置项生成的 [orm.DB] 实例
Expand Down
41 changes: 31 additions & 10 deletions cmfx/modules/admin/admintest/admintest.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,47 @@
package admintest

import (
"encoding/json"
"net/http"

"github.com/issue9/assert/v4"
"github.com/issue9/mux/v8/header"
"github.com/issue9/webuse/v7/middlewares/auth/token"

"github.com/issue9/cmfx/cmfx/initial/test"
"github.com/issue9/cmfx/cmfx/modules/admin"
"github.com/issue9/cmfx/cmfx/user"
)

func NewAdmin(s *test.Suite) *admin.Loader {
// NewAdmin 声明一个用于测试的 [admin.Module] 实例
func NewAdmin(s *test.Suite) *admin.Module {
mod := s.NewModule("admin")
admin.Install(mod)

o := &user.Config{
URLPrefix: "/admin",
AccessExpired: 60,
RefreshExpired: 120,
o := &admin.Config{
SuperUser: 1,
User: &user.Config{
URLPrefix: "/admin",
AccessExpired: 60,
RefreshExpired: 120,
},
}
s.Assertion().NotError(o.SanitizeConfig())

a := admin.Load(mod, o)
s.Assertion().NotNil(a)
loader := admin.Install(mod, o)
s.Assertion().NotNil(loader)

return loader
}

// TODO 返回用于测试的令牌
// GetToken 获得后台的访问令牌
func GetToken(s *test.Suite, loader *admin.Module) string {
r := &token.Response{}
s.Post(loader.URLPrefix()+"/login?type=password", []byte(`{"username":"admin","password":"123"}`)).
Header(header.ContentType, header.JSON+";charset=utf-8").
Header(header.Accept, header.JSON).
Do(nil).
Status(http.StatusCreated).
BodyFunc(func(a *assert.Assertion, body []byte) { a.NotError(json.Unmarshal(body, r)) })

return a
return r.AccessToken
}
32 changes: 32 additions & 0 deletions cmfx/modules/admin/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: 2024 caixw
//
// SPDX-License-Identifier: MIT

package admin

import (
"github.com/issue9/web"

"github.com/issue9/cmfx/cmfx/user"
"github.com/issue9/cmfx/locales"
)

type Config struct {
// SuperUser 超级用户的 ID
SuperUser int64 `json:"superUser" xml:"superUser,attr" yaml:"superUser"`

// User 用户相关的配置
User *user.Config `json:"user" xml:"user" yaml:"user"`
}

func (c *Config) SanitizeConfig() *web.FieldError {
if c.SuperUser <= 0 {
return web.NewFieldError("superUser", locales.MustBeGreaterThan(0))
}

if err := c.User.SanitizeConfig(); err != nil {
return err.AddFieldParent("user")
}

return nil
}
22 changes: 22 additions & 0 deletions cmfx/modules/admin/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2024 caixw
//
// SPDX-License-Identifier: MIT

package admin

import (
"testing"

"github.com/issue9/assert/v4"
"github.com/issue9/config"
)

var _ config.Sanitizer = &Config{}

func TestConfig_SanitizeConfig(t *testing.T) {
a := assert.New(t, false)

conf := &Config{}
err := conf.SanitizeConfig()
a.Equal(err.Field, "superUser")
}
20 changes: 8 additions & 12 deletions cmfx/modules/admin/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"github.com/issue9/cmfx/cmfx/user/rbac"
)

func Install(mod *cmfx.Module) {
func Install(mod *cmfx.Module, o *Config) *Module {
user.Install(mod)
password.Install(mod)
rbac.Install(mod)
Expand All @@ -25,19 +25,15 @@ func Install(mod *cmfx.Module) {
panic(web.SprintError(mod.Server().Locale().Printer(), true, err))
}

r := rbac.New(mod, nil)
a, err := r.NewRoleGroup(mod.ID(), 0)
if err != nil {
panic(web.SprintError(mod.Server().Locale().Printer(), true, err))
}
l := Load(mod, o)

if _, err = a.NewRole("管理员", "拥有超级权限", ""); err != nil {
if _, err := l.newRole("管理员", "拥有超级权限", ""); err != nil {
panic(web.SprintError(mod.Server().Locale().Printer(), true, err))
}
if _, err = a.NewRole("财务", "财务", ""); err != nil {
if _, err := l.newRole("财务", "财务", ""); err != nil {
panic(web.SprintError(mod.Server().Locale().Printer(), true, err))
}
if _, err = a.NewRole("编辑", "仅有编辑文章的相关权限", ""); err != nil {
if _, err := l.newRole("编辑", "仅有编辑文章的相关权限", ""); err != nil {
panic(web.SprintError(mod.Server().Locale().Printer(), true, err))
}

Expand Down Expand Up @@ -87,11 +83,11 @@ func Install(mod *cmfx.Module) {
},
}

p := password.New(mod, 11)

for _, u := range us {
if err := newAdmin(mod, p, u, time.Now()); err != nil {
if err := l.newAdmin(l.password, u, time.Now()); err != nil {
panic(web.SprintError(mod.Server().Locale().Printer(), true, err))
}
}

return l
}
13 changes: 12 additions & 1 deletion cmfx/modules/admin/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/issue9/assert/v4"

"github.com/issue9/cmfx/cmfx/initial/test"
"github.com/issue9/cmfx/cmfx/user"
)

func TestInstall(t *testing.T) {
Expand All @@ -18,7 +19,17 @@ func TestInstall(t *testing.T) {
defer suite.Close()

mod := suite.NewModule("test")
Install(mod)
o := &Config{
SuperUser: 1,
User: &user.Config{
URLPrefix: "/admin",
AccessExpired: 60,
RefreshExpired: 120,
},
}
suite.Assertion().NotError(o.SanitizeConfig())
l := Install(mod, o)
a.NotNil(l)

suite.TableExists(mod.ID() + "_info")
}
Loading

0 comments on commit 3590945

Please sign in to comment.