diff --git a/cmd/init/casbin.go b/cmd/init/casbin.go index df16060..6823da5 100644 --- a/cmd/init/casbin.go +++ b/cmd/init/casbin.go @@ -9,8 +9,8 @@ func loadCasbinPolicies() { enforcer := casbin_agent.GetDefaultCasbinEnforcer() _, err := enforcer.AddGroupingPolicies([][]string{ - {`user_root`, `role_super`, `system`}, - {`role_super`, `role_admin`, `system`}, + {`user:root`, `role:super`, `system`}, + {`role:super`, `role:admin`, `system`}, }) if err != nil { panic(err) diff --git a/models/user/user_db.go b/models/user/user_db.go index ec45961..e72534f 100644 --- a/models/user/user_db.go +++ b/models/user/user_db.go @@ -2,6 +2,7 @@ package user_model import ( "fmt" + "strings" "github.com/alexedwards/argon2id" "github.com/oj-lab/oj-lab-platform/models" @@ -92,13 +93,22 @@ type GetUserOptions struct { Limit *int } -// Count the total number of users that match the options, -// ignoring the offset and limit. -func CountUserByOptions(tx *gorm.DB, options GetUserOptions) (int64, error) { - var count int64 - +func buildGetUserTXByOptions(tx *gorm.DB, options GetUserOptions, isCount bool) *gorm.DB { tx = tx.Model(&User{}) + if options.DomainRole != nil { + enforcer := casbin_agent.GetDefaultCasbinEnforcer() + subjects := enforcer.GetUsersForRoleInDomain(options.DomainRole.Role, options.DomainRole.Domain) + accounts := []string{} + for _, subject := range subjects { + if strings.HasPrefix(subject, casbin_agent.UserSubjectPrefix) { + account := strings.TrimPrefix(subject, casbin_agent.UserSubjectPrefix) + accounts = append(accounts, account) + } + } + tx = tx.Where("account IN ?", accounts) + } + if options.AccountQuery != "" { tx = tx.Where("account LIKE ?", options.AccountQuery) } @@ -106,32 +116,39 @@ func CountUserByOptions(tx *gorm.DB, options GetUserOptions) (int64, error) { tx = tx.Where("email LIKE ?", options.EmailQuery) } + if !isCount { + if options.Offset != nil { + tx = tx.Offset(*options.Offset) + } + if options.Limit != nil { + tx = tx.Limit(*options.Limit) + } + } + + return tx +} + +// Count the total number of users that match the options, +// ignoring the offset and limit. +func CountUsersByOptions(tx *gorm.DB, options GetUserOptions) (int64, error) { + var count int64 + + tx = buildGetUserTXByOptions(tx, options, true) + err := tx.Count(&count).Error return count, err } -func GetUserByOptions(tx *gorm.DB, options GetUserOptions) ([]User, int64, error) { - total, err := CountUserByOptions(tx, options) +func GetUsersByOptions(tx *gorm.DB, options GetUserOptions) ([]User, int64, error) { + total, err := CountUsersByOptions(tx, options) if err != nil { return nil, 0, err } db_users := []User{} - if options.AccountQuery != "" { - tx = tx.Where("account LIKE ?", options.AccountQuery) - } - if options.EmailQuery != "" { - tx = tx.Where("email LIKE ?", options.EmailQuery) - } - - if options.Offset != nil { - tx = tx.Offset(*options.Offset) - } - if options.Limit != nil { - tx = tx.Limit(*options.Limit) - } + tx = buildGetUserTXByOptions(tx, options, false) err = tx.Find(&db_users).Error if err != nil { diff --git a/models/user/user_test.go b/models/user/user_test.go index fd5b3e5..bfdc043 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -5,6 +5,7 @@ import ( "fmt" "testing" + casbin_agent "github.com/oj-lab/oj-lab-platform/modules/agent/casbin" gorm_agent "github.com/oj-lab/oj-lab-platform/modules/agent/gorm" ) @@ -43,4 +44,17 @@ func TestUserDB(t *testing.T) { if err != nil { t.Error(err) } + + users, _, err := GetUsersByOptions(db, GetUserOptions{ + DomainRole: &casbin_agent.DomainRole{ + Role: "role:super", + Domain: "system", + }, + }) + if err != nil { + t.Fatal(err) + } + if len(users) == 0 { + t.Fatal("no super user") + } } diff --git a/modules/agent/casbin/model.go b/modules/agent/casbin/model.go index 4aca00e..86c3c6f 100644 --- a/modules/agent/casbin/model.go +++ b/modules/agent/casbin/model.go @@ -31,8 +31,8 @@ e = some(where (p.eft == allow)) && !some(where (p.eft == deny)) m = g(r.sub, p.sub) && eval(p.ext_rule) && r.dom == p.dom && keyMatchGin(r.obj, p.obj) && regexMatch(r.act, p.act) ` -const UserSubjectPrefix = "user_" -const RoleSubjectPrefix = "role_" +const UserSubjectPrefix = "user:" +const RoleSubjectPrefix = "role:" type ExtraInfo struct { IsVIP bool diff --git a/services/user/user.go b/services/user/user.go index 7273b0b..47754c7 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -29,7 +29,7 @@ func GetUserList( ctx context.Context, options user_model.GetUserOptions, ) ([]user_model.User, int64, error) { db := gorm_agent.GetDefaultDB() - users, total, err := user_model.GetUserByOptions(db, options) + users, total, err := user_model.GetUsersByOptions(db, options) if err != nil { return nil, 0, err } @@ -54,7 +54,7 @@ func CheckUserExist(ctx context.Context, account string) (bool, error) { AccountQuery: account, } db := gorm_agent.GetDefaultDB() - count, err := user_model.CountUserByOptions(db, getOptions) + count, err := user_model.CountUsersByOptions(db, getOptions) if err != nil { return false, err }