package agent import ( "context" "testing" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/rolepolicy" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/handler" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" _ "github.com/gogf/gf/contrib/drivers/sqlite/v2" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" ) func TestEnsureRoleNotInheritedAllowsSuperAdmin(t *testing.T) { ctx := contexts.Set(context.Background(), &model.Context{ User: &model.Identity{BaseClaims: model.BaseClaims{ TenantId: "000000", Roles: []model.Role{{RoleId: consts.SuperAdminRoleId}}, }}, }) if err := NewAgentRole().ensureRoleNotInherited(ctx, 100); err != nil { t.Fatalf("super admin should edit inherited roles, got error: %v", err) } } func TestCurrentSuperAdminChecksLiveRoleAssignment(t *testing.T) { setupAgentRoleSyncTestDB(t) ctx := context.Background() mustExecAgentRoleSyncTest(t, ctx, "INSERT INTO sys_role (role_id,tenant_id,dept_id,status) VALUES (1,'000000',1,'0')") mustExecAgentRoleSyncTest(t, ctx, "INSERT INTO sys_user_role (tenant_id,user_id,role_id) VALUES ('000000',99,1)") isAdmin, err := rolepolicy.CurrentSuperAdmin(ctx, 99) if err != nil || !isAdmin { t.Fatalf("expected active administrator: %v %v", isAdmin, err) } mustExecAgentRoleSyncTest(t, ctx, "DELETE FROM sys_user_role WHERE user_id=99") isAdmin, err = rolepolicy.CurrentSuperAdmin(ctx, 99) if err != nil || isAdmin { t.Fatalf("revoked administrator must lose access: %v %v", isAdmin, err) } } func TestNoActiveRolesCannotReadFilteredData(t *testing.T) { setupAgentRoleSyncTestDB(t) ctx := contexts.Set(context.Background(), &model.Context{User: &model.Identity{BaseClaims: model.BaseClaims{ID: 99, TenantId: "000000", DeptId: 2}}}) mustExecAgentRoleSyncTest(t, ctx, "INSERT INTO sys_role (role_id,tenant_id,dept_id,status) VALUES (21,'000000',2,'0')") count, err := g.DB().Model("sys_role").Ctx(ctx).Handler(handler.FilterAuth).Count() if err != nil || count != 0 { t.Fatalf("user without roles must not read filtered data: %d %v", count, err) } } func setupAgentRoleSyncTestDB(t *testing.T) { t.Helper() if err := gdb.SetConfig(gdb.Config{ "default": gdb.ConfigGroup{ {Type: "sqlite", Link: "sqlite::@file(:memory:)", Debug: false}, }, }); err != nil { t.Fatalf("configure sqlite failed: %v", err) } ctx := context.Background() t.Cleanup(func() { _ = g.DB().Close(ctx) }) mustExecAgentRoleSyncTest(t, ctx, `CREATE TABLE sys_dept (dept_id INTEGER PRIMARY KEY, tenant_id TEXT, parent_id INTEGER, dept_type INTEGER, status TEXT DEFAULT '0', dept_role INTEGER, deleted_at DATETIME)`) mustExecAgentRoleSyncTest(t, ctx, `CREATE TABLE sys_config (config_id INTEGER PRIMARY KEY, tenant_id TEXT, config_name TEXT, config_key TEXT, config_value TEXT, config_type TEXT, created_dept INTEGER, created_by INTEGER, created_at DATETIME, updated_by INTEGER, updated_at DATETIME, remark TEXT)`) mustExecAgentRoleSyncTest(t, ctx, `CREATE TABLE sys_role ( role_id INTEGER PRIMARY KEY AUTOINCREMENT, tenant_id TEXT, dept_id INTEGER, role_name TEXT, role_key TEXT, role_sort INTEGER, data_scope TEXT, menu_check_strictly INTEGER, dept_check_strictly INTEGER, status TEXT, is_pass INTEGER, created_dept INTEGER, created_by INTEGER, created_at DATETIME, updated_by INTEGER, updated_at DATETIME, deleted_by INTEGER, deleted_at DATETIME, remark TEXT)`) mustExecAgentRoleSyncTest(t, ctx, `CREATE TABLE sys_role_menu (tenant_id TEXT, role_id INTEGER, menu_id INTEGER, data_scope TEXT)`) mustExecAgentRoleSyncTest(t, ctx, `CREATE TABLE sys_role_dept (tenant_id TEXT, role_id INTEGER, dept_id INTEGER)`) mustExecAgentRoleSyncTest(t, ctx, `CREATE TABLE sys_user_role (tenant_id TEXT DEFAULT '000000', user_id INTEGER, role_id INTEGER)`) } func mustExecAgentRoleSyncTest(t *testing.T, ctx context.Context, sql string) { t.Helper() if _, err := g.DB().Exec(ctx, sql); err != nil { t.Fatalf("execute sql failed: %v", err) } } func assertAgentRoleSyncCount(t *testing.T, ctx context.Context, sql string, expected int) { t.Helper() count, err := g.DB().GetValue(ctx, sql) if err != nil { t.Fatalf("query count failed: %v", err) } if count.Int() != expected { t.Fatalf("count = %d, want %d, sql=%s", count.Int(), expected, sql) } }