feat: sync deployed v1.0.0-rc.38-custom.42
Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
1 parent
aa6c3f50f4
commit
ceddfd3d6b
828 files changed
+122253
-13702
No files matched your search
+24
-17
@@ -1,8 +1,9 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"fmt"
|
||||
|
||||
"github.com/QuantumNous/new-api/common"
|
||||
"github.com/QuantumNous/new-api/model"
|
||||
casbinmodel "github.com/casbin/casbin/v2/model"
|
||||
"github.com/casbin/casbin/v2/persist"
|
||||
@@ -24,7 +25,28 @@ func (a *gormAdapter) LoadPolicy(m casbinmodel.Model) error {
|
||||
return err
|
||||
}
|
||||
for _, rule := range rules {
|
||||
if err := persist.LoadPolicyLine(ruleToLine(rule), m); err != nil {
|
||||
if rule.Ptype != "p" {
|
||||
// This model has no role-inheritance or other policy sections.
|
||||
continue
|
||||
}
|
||||
if rule.V0 == "" || rule.V1 == "" || rule.V2 == "" {
|
||||
return fmt.Errorf("authorization policy %d is missing a subject, resource or action", rule.Id)
|
||||
}
|
||||
effect := rule.V3
|
||||
if effect == "" {
|
||||
effect = EffectAllow
|
||||
}
|
||||
if effect != EffectAllow && effect != EffectDeny {
|
||||
return fmt.Errorf("authorization policy %d has an invalid effect", rule.Id)
|
||||
}
|
||||
if rule.V5 != "" || (rule.V4 != "" && rule.V4 != "all") {
|
||||
// The current model cannot enforce legacy own/other scopes. Keep
|
||||
// the stored rule for review and deny this permission in memory.
|
||||
// Skipping a per-user rule would expose the admin role baseline.
|
||||
effect = EffectDeny
|
||||
common.SysLog(fmt.Sprintf("authorization policy %d has an unsupported legacy scope; loaded as deny; review the stored policy before granting access", rule.Id))
|
||||
}
|
||||
if err := persist.LoadPolicyArray([]string{rule.Ptype, rule.V0, rule.V1, rule.V2, effect}, m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -104,18 +126,3 @@ func newRule(ptype string, policy []string) model.CasbinRule {
|
||||
}
|
||||
return rule
|
||||
}
|
||||
|
||||
func ruleToLine(rule model.CasbinRule) string {
|
||||
parts := []string{rule.Ptype}
|
||||
values := []string{rule.V0, rule.V1, rule.V2, rule.V3, rule.V4, rule.V5}
|
||||
if rule.Ptype == "p" && rule.V0 != "" && rule.V1 != "" && rule.V2 != "" && rule.V3 == "" {
|
||||
values[3] = EffectAllow
|
||||
}
|
||||
for _, value := range values {
|
||||
if value == "" {
|
||||
continue
|
||||
}
|
||||
parts = append(parts, value)
|
||||
}
|
||||
return strings.Join(parts, ", ")
|
||||
}
|
||||
@@ -77,6 +77,55 @@ func TestInitOnSlaveOnlyLoadsPolicies(t *testing.T) {
|
||||
assert.False(t, Can(2, common.RoleAdminUser, ChannelRead))
|
||||
}
|
||||
|
||||
func TestLegacyScopedPoliciesDoNotExpandPermissions(t *testing.T) {
|
||||
for _, master := range []bool{true, false} {
|
||||
name := "master"
|
||||
if !master {
|
||||
name = "slave"
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
db := newAuthzTestDB(t)
|
||||
common.IsMasterNode = master
|
||||
rules := []model.CasbinRule{
|
||||
{Ptype: "p", V0: "role:vendor", V1: "channel", V2: "read", V3: "allow", V4: "own"},
|
||||
{Ptype: "p", V0: UserSubject(42), V1: "channel", V2: "read", V3: "allow", V4: "own"},
|
||||
{Ptype: "p", V0: UserSubject(43), V1: "channel", V2: "sensitive_write", V3: "allow", V4: "all"},
|
||||
{Ptype: "p", V0: UserSubject(44), V1: "channel", V2: "secret_view", V3: "deny", V4: "all"},
|
||||
{Ptype: "p", V0: UserSubject(45), V1: "channel", V2: "read"},
|
||||
{Ptype: "p", V0: UserSubject(46), V1: "channel", V2: "read", V3: "allow", V4: "unknown-scope"},
|
||||
{Ptype: "p", V0: UserSubject(47), V1: "channel", V2: "read", V3: "allow", V5: "own"},
|
||||
{Ptype: "p", V0: UserSubject(48), V1: "channel", V2: "read", V3: "allow", V4: "own"},
|
||||
{Ptype: "p", V0: UserSubject(48), V1: "channel", V2: "read", V3: "allow", V4: "all"},
|
||||
{Ptype: "p", V0: RoleSubject(BuiltInRoleAdmin), V1: "channel", V2: "operate", V3: "allow", V4: "own"},
|
||||
{Ptype: "p", V0: UserSubject(50), V1: "channel", V2: "sensitive_write", V3: "allow"},
|
||||
{Ptype: "g", V0: UserSubject(99), V1: RoleSubject(BuiltInRoleAdmin)},
|
||||
}
|
||||
require.NoError(t, db.Create(&rules).Error)
|
||||
ids := make([]uint, len(rules))
|
||||
for i := range rules {
|
||||
ids[i] = rules[i].Id
|
||||
}
|
||||
for range 2 {
|
||||
require.NoError(t, Init(db))
|
||||
require.NoError(t, ReloadPolicy())
|
||||
assert.False(t, Can(42, common.RoleAdminUser, ChannelRead), "own must not fall back to the admin allow baseline")
|
||||
assert.True(t, Can(43, common.RoleAdminUser, ChannelSensitiveWrite))
|
||||
assert.False(t, Can(44, common.RoleAdminUser, ChannelSecretView))
|
||||
assert.True(t, Can(45, common.RoleAdminUser, ChannelRead))
|
||||
for _, userID := range []int{46, 47, 48} {
|
||||
assert.False(t, Can(userID, common.RoleAdminUser, ChannelRead))
|
||||
}
|
||||
assert.False(t, Can(51, common.RoleAdminUser, ChannelOperate), "reseed must not erase a scoped role restriction")
|
||||
assert.True(t, Can(50, common.RoleAdminUser, ChannelSensitiveWrite))
|
||||
assert.False(t, Can(99, common.RoleCommonUser, ChannelRead))
|
||||
var stored []model.CasbinRule
|
||||
require.NoError(t, db.Where("id IN ?", ids).Order("id").Find(&stored).Error)
|
||||
assert.Equal(t, rules, stored, "legacy rows must remain available for administrator review")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetUserPermissionsStoresOnlyOverrides(t *testing.T) {
|
||||
db := newAuthzTestDB(t)
|
||||
require.NoError(t, Init(db))
|
||||
|
||||
@@ -39,7 +39,11 @@ func resetBuiltInRolePolicies(db *gorm.DB) error {
|
||||
for _, spec := range builtInRoles {
|
||||
subjects = append(subjects, RoleSubject(spec.Key))
|
||||
}
|
||||
return db.Where("ptype = ? AND v0 IN ?", "p", subjects).Delete(&model.CasbinRule{}).Error
|
||||
// Scoped legacy rules must survive baseline reseeding so the adapter can
|
||||
// retain their restrictions instead of replacing them with global grants.
|
||||
return db.Where("ptype = ? AND v0 IN ?", "p", subjects).
|
||||
Where("(v4 = ? OR v4 IS NULL) AND (v5 = ? OR v5 IS NULL)", "", "").
|
||||
Delete(&model.CasbinRule{}).Error
|
||||
}
|
||||
|
||||
func seedDefaultPolicies() error {
|
||||
|
||||
Reference in new issue
Block a user