Files
new-api-custom/service/authz/authz_test.go
T
Codex bb7968b612
Publish Docker image (Multi-arch) / Build & push (amd64) (push) Failing after 9m20s
Release (Linux, macOS, Windows) / Linux Release (push) Failing after 55m7s
Publish Docker image (Multi-arch) / Build & push (arm64) (push) Canceled after 0s
Release (Linux, macOS, Windows) / macOS Release (push) Canceled after 0s
Release (Linux, macOS, Windows) / Windows Release (push) Canceled after 0s
Publish Docker image (Multi-arch) / Create multi-arch manifests (push) Canceled after 0s
feat: publish v1.0.0-rc.36-custom.1
2026-09-11 05:07:48 +08:00

274 lines
8.6 KiB
Go

package authz
import (
"testing"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/model"
"github.com/glebarez/sqlite"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
func newAuthzTestDB(t *testing.T) *gorm.DB {
t.Helper()
wasMaster := common.IsMasterNode
common.IsMasterNode = true
t.Cleanup(func() {
common.IsMasterNode = wasMaster
})
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
sqlDB, err := db.DB()
require.NoError(t, err)
sqlDB.SetMaxOpenConns(1)
require.NoError(t, db.AutoMigrate(&model.CasbinRule{}, &model.AuthzRole{}))
return db
}
func TestInitSeedsBuiltInRolesAndPoliciesOnce(t *testing.T) {
db := newAuthzTestDB(t)
require.NoError(t, Init(db))
require.NoError(t, Init(db))
// root is a superuser role and is granted everything implicitly, so only the
// admin baseline is written as explicit policy rows.
var count int64
require.NoError(t, db.Model(&model.CasbinRule{}).Count(&count).Error)
assert.Equal(t, int64(len(PermissionsForRole(BuiltInRoleAdmin))), count)
var roles []model.AuthzRole
require.NoError(t, db.Order("sort asc").Find(&roles).Error)
require.Len(t, roles, 2)
assert.Equal(t, BuiltInRoleRoot, roles[0].Key)
assert.Equal(t, BuiltInRoleAdmin, roles[1].Key)
assert.True(t, Can(1, common.RoleRootUser, ChannelSensitiveWrite))
assert.True(t, Can(2, common.RoleAdminUser, ChannelRead))
assert.True(t, Can(2, common.RoleAdminUser, ChannelOperate))
assert.True(t, Can(2, common.RoleAdminUser, ChannelWrite))
assert.False(t, Can(2, common.RoleAdminUser, ChannelSensitiveWrite))
assert.False(t, Can(3, common.RoleCommonUser, ChannelRead))
}
func TestInitOnSlaveOnlyLoadsPolicies(t *testing.T) {
wasMaster := common.IsMasterNode
common.IsMasterNode = false
t.Cleanup(func() {
common.IsMasterNode = wasMaster
})
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
sqlDB, err := db.DB()
require.NoError(t, err)
sqlDB.SetMaxOpenConns(1)
require.NoError(t, db.AutoMigrate(&model.CasbinRule{}, &model.AuthzRole{}))
require.NoError(t, Init(db))
var roleCount int64
require.NoError(t, db.Model(&model.AuthzRole{}).Count(&roleCount).Error)
assert.Equal(t, int64(0), roleCount)
var policyCount int64
require.NoError(t, db.Model(&model.CasbinRule{}).Count(&policyCount).Error)
assert.Equal(t, int64(0), policyCount)
assert.False(t, Can(2, common.RoleAdminUser, ChannelRead))
}
func TestSetUserPermissionsStoresOnlyOverrides(t *testing.T) {
db := newAuthzTestDB(t)
require.NoError(t, Init(db))
require.NoError(t, SetUserPermissions(42, PermissionsMap{
ResourceChannel: {
ActionRead: true,
ActionOperate: true,
ActionWrite: false,
ActionSensitiveWrite: true,
ActionSecretView: false,
"unknown": true,
},
"unknown": {
ActionRead: true,
},
}))
assert.True(t, Can(42, common.RoleAdminUser, ChannelSensitiveWrite))
assert.False(t, Can(42, common.RoleAdminUser, ChannelWrite))
assert.Equal(t, PermissionsMap{
ResourceChannel: {
ActionRead: true,
ActionOperate: true,
ActionWrite: false,
ActionSensitiveWrite: true,
ActionSecretView: false,
},
ResourceTaskPlugin: {
ActionBind: false,
},
ResourceAudit: {ActionRead: false},
}, ExplicitUserPermissions(42))
assert.Equal(t, PermissionsMap{
ResourceChannel: {
ActionSensitiveWrite: true,
ActionWrite: false,
},
}, ExplicitUserOverrides(42))
var userPolicyCount int64
require.NoError(t, db.Model(&model.CasbinRule{}).Where("v0 = ?", UserSubject(42)).Count(&userPolicyCount).Error)
assert.Equal(t, int64(2), userPolicyCount)
require.NoError(t, SetUserPermissions(42, PermissionsMap{ResourceChannel: {
ActionRead: true,
ActionOperate: true,
ActionWrite: true,
ActionSensitiveWrite: false,
ActionSecretView: false,
}}))
assert.False(t, Can(42, common.RoleAdminUser, ChannelSensitiveWrite))
assert.Equal(t, PermissionsMap{
ResourceChannel: {
ActionRead: true,
ActionOperate: true,
ActionWrite: true,
ActionSensitiveWrite: false,
ActionSecretView: false,
},
ResourceTaskPlugin: {
ActionBind: false,
},
ResourceAudit: {ActionRead: false},
}, ExplicitUserPermissions(42))
assert.Empty(t, ExplicitUserOverrides(42))
}
func TestClearUserAuthorizationRemovesOverrides(t *testing.T) {
db := newAuthzTestDB(t)
require.NoError(t, Init(db))
require.NoError(t, SetUserPermissions(90, PermissionsMap{ResourceChannel: {
ActionWrite: false,
ActionSensitiveWrite: true,
}}))
assert.True(t, Can(90, common.RoleAdminUser, ChannelSensitiveWrite))
assert.False(t, Can(90, common.RoleAdminUser, ChannelWrite))
require.NoError(t, ClearUserAuthorization(90))
assert.Empty(t, ExplicitUserOverrides(90))
assert.True(t, Can(90, common.RoleAdminUser, ChannelRead))
assert.True(t, Can(90, common.RoleAdminUser, ChannelWrite))
assert.False(t, Can(90, common.RoleAdminUser, ChannelSensitiveWrite))
assert.False(t, Can(90, common.RoleCommonUser, ChannelRead))
}
func TestSetUserPermissionsInTxDoesNotMutateEnforcerBeforeReload(t *testing.T) {
db := newAuthzTestDB(t)
require.NoError(t, Init(db))
require.NoError(t, db.Transaction(func(tx *gorm.DB) error {
return SetUserPermissionsInTx(tx, 42, PermissionsMap{ResourceChannel: {
ActionRead: true,
ActionOperate: true,
ActionWrite: true,
ActionSensitiveWrite: true,
ActionSecretView: false,
}})
}))
assert.False(t, Can(42, common.RoleAdminUser, ChannelSensitiveWrite))
require.NoError(t, ReloadPolicy())
assert.True(t, Can(42, common.RoleAdminUser, ChannelSensitiveWrite))
}
func TestSetUserPermissionsInTxRollbackLeavesNoPolicy(t *testing.T) {
db := newAuthzTestDB(t)
require.NoError(t, Init(db))
tx := db.Begin()
require.NoError(t, tx.Error)
require.NoError(t, SetUserPermissionsInTx(tx, 43, PermissionsMap{ResourceChannel: {
ActionSensitiveWrite: true,
}}))
require.NoError(t, tx.Rollback().Error)
require.NoError(t, ReloadPolicy())
assert.False(t, Can(43, common.RoleAdminUser, ChannelSensitiveWrite))
var count int64
require.NoError(t, db.Model(&model.CasbinRule{}).Where("v0 = ?", UserSubject(43)).Count(&count).Error)
assert.Equal(t, int64(0), count)
}
func TestAdapterAddPolicyIsIdempotent(t *testing.T) {
db := newAuthzTestDB(t)
adapter := newGormAdapter(db)
rule := []string{UserSubject(55), ResourceChannel, ActionSensitiveWrite, EffectAllow}
require.NoError(t, adapter.AddPolicy("p", "p", rule))
require.NoError(t, adapter.AddPolicy("p", "p", rule))
var count int64
require.NoError(t, db.Model(&model.CasbinRule{}).Where(
"ptype = ? AND v0 = ? AND v1 = ? AND v2 = ? AND v3 = ?",
"p",
UserSubject(55),
ResourceChannel,
ActionSensitiveWrite,
EffectAllow,
).Count(&count).Error)
assert.Equal(t, int64(1), count)
}
func TestCapabilitiesUseCatalogShape(t *testing.T) {
db := newAuthzTestDB(t)
require.NoError(t, Init(db))
capabilities := Capabilities(7, common.RoleAdminUser)
assert.True(t, capabilities[ResourceChannel][ActionRead])
assert.True(t, capabilities[ResourceChannel][ActionOperate])
assert.True(t, capabilities[ResourceChannel][ActionWrite])
assert.False(t, capabilities[ResourceChannel][ActionSensitiveWrite])
assert.False(t, capabilities[ResourceChannel][ActionSecretView])
assert.False(t, capabilities[ResourceTaskPlugin][ActionBind])
}
func TestTaskPluginBindIsRootOnlyUntilGranted(t *testing.T) {
db := newAuthzTestDB(t)
require.NoError(t, Init(db))
var bindAction *ActionDefinition
for _, resource := range Catalog() {
if resource.Resource != ResourceTaskPlugin {
continue
}
assert.Equal(t, "Task Plugin", resource.LabelKey)
for i := range resource.Actions {
if resource.Actions[i].Action == ActionBind {
bindAction = &resource.Actions[i]
}
}
}
require.NotNil(t, bindAction)
assert.Equal(t, "Bind task plugins", bindAction.LabelKey)
assert.Equal(t, "List registered task plugins and bind them when creating or editing task plugin channels.", bindAction.DescriptionKey)
assert.Empty(t, bindAction.DefaultRoles)
assert.False(t, Can(2, common.RoleAdminUser, TaskPluginBind))
assert.True(t, Can(1, common.RoleRootUser, TaskPluginBind))
enforcer := currentEnforcer()
require.NotNil(t, enforcer)
_, err := enforcer.AddPolicy(RoleSubject(BuiltInRoleAdmin), ResourceTaskPlugin, ActionBind, EffectAllow)
require.NoError(t, err)
assert.True(t, Can(2, common.RoleAdminUser, TaskPluginBind))
_, err = enforcer.RemovePolicy(RoleSubject(BuiltInRoleAdmin), ResourceTaskPlugin, ActionBind, EffectAllow)
require.NoError(t, err)
assert.False(t, Can(2, common.RoleAdminUser, TaskPluginBind))
}