casbin / casbin-pg-adapter

A go-pg adapter for casbin
https://github.com/casbin/casbin
Apache License 2.0
38 stars 28 forks source link

interface conversion: *pgadapter.Adapter is not persist.UpdatableAdapter: missing method UpdateFilteredPolicies #33

Closed antipopp closed 3 years ago

antipopp commented 3 years ago

Hello, when running UpdatePolicy this error comes up.

interface conversion: *pgadapter.Adapter is not persist.UpdatableAdapter: missing method UpdateFilteredPolicies

my configuration:

import (
    db "backend/postgres"
    "encoding/json"
    "log"

    pgadapter "github.com/casbin/casbin-pg-adapter"
    "github.com/casbin/casbin/v2"
    "github.com/casbin/casbin/v2/model"
    defaultrolemanager "github.com/casbin/casbin/v2/rbac/default-role-manager"
    "github.com/casbin/casbin/v2/util"
)

var Enforcer *casbin.Enforcer

func Init() error {
    a, err := pgadapter.NewAdapterByDB(db.Db, pgadapter.WithTableName("casbin"))
    if err != nil {
        return err
    }

    m, err := model.NewModelFromString(`
[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub, r.dom) && (r.dom == p.dom) && (r.dom == p.dom) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)
`)

    if err != nil {
        log.Fatalf("error: model: %s", err)
    }

    enforcer, err := casbin.NewEnforcer(m, a)

    if err != nil {
        return err
    }

    r := enforcer.GetRoleManager()
    r.(*defaultrolemanager.RoleManager).AddDomainMatchingFunc("KeyMatch2", util.KeyMatch2)

    Enforcer = enforcer
    return AddDefaultPoliciesAndGroups()
}

the code that triggers the error:

oldPolicy := []string{strings.ToLower(subject), strings.ToLower(domain), object, oldAction}
newPolicy := []string{strings.ToLower(subject), strings.ToLower(domain), object, action}

_, err := enforcer.Enforcer.UpdatePolicy(oldPolicy, newPolicy)
if err != nil {
    log.Println(err)
    return nil, err
}
casbin-bot commented 3 years ago

@closetool @tangyang9464

tangyang9464 commented 3 years ago

@antipopp Can you give me the complete code? I'm a little confused whether your code can run? such as _, err := enforcer.Enforcer.UpdatePolicy(oldPolicy, newPolicy), Isn't it like this _, err := enforcer.UpdatePolicy(oldPolicy, newPolicy)

antipopp commented 3 years ago

Yes, the UpdatePolicy bit is in a GraphQL endpoint generated with gqlgen, the enforcer object is in it's own package.

The full generated endpoint is something like this:

import (
    "backend/enforcer"
    "backend/graph/auth"
    "backend/graph/model"
    "context"
    "log"
    "strings"
)

func (r *mutationResolver) UpdatePolicy(ctx context.Context, subject string, object string, action string) (*model.Policy, error) {
    user := auth.ForContext(ctx)
    if err := CheckPerms(ctx, "policy", "allow"); err != nil {
        return nil, err
    }
    oldAction := "allow"
    if action == "allow" {
        oldAction = "deny"
    }

    domain := user.Company
    oldPolicy := []string{strings.ToLower(subject), strings.ToLower(domain), object, oldAction}
    newPolicy := []string{strings.ToLower(subject), strings.ToLower(domain), object, action}

    _, err := enforcer.Enforcer.UpdatePolicy(oldPolicy, newPolicy)
    if err != nil {
        log.Println(err)
        return nil, err
    }

    return &model.Policy{}, nil
}

So the first enforcer of enforcer.Enforcer is the package, the capitalized one is the real object (declared in the configuration block of the first post). Sorry for the confusion.

hsluoyz commented 3 years ago

@tangyang9464 I think we need to implement new function UpdateFilteredPolicies() in this adapter code to satisfy the UpdatableAdapter interface. Plz make a PR.

tangyang9464 commented 3 years ago

@tangyang9464 I think we need to implement new function UpdateFilteredPolicies() in this adapter code to satisfy the UpdatableAdapter interface. Plz make a PR.

@hsluoyz But the function has been implemented.

tangyang9464 commented 3 years ago

@antipopp What version are you using? UpdateFilteredPolicies only be supported after v1.0.0 and my test code is as follows, there will be no error

a, _ := pgadapter.NewAdapter("postgresql://postgres:root@localhost:5432/postgres?sslmode=disable")
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)
e.LoadPolicy()
_, err := e.UpdatePolicy([]string{"alice","data1","read"},[]string{"alice","data1","write"})

Maybe you can check your code again or use other code to test.

antipopp commented 3 years ago

It doesn't work in my setup.

This is how I create the initial policies (this function is called right after my Init() function in the original post):

func AddDefaultPoliciesAndGroups() error {
    // p = sub, dom, obj, act
    policies := [][]string{
        {"admin", "domain1", "users", "allow"},
    }

    _, err := Enforcer.AddPolicies(policies)
    if err != nil {
        return err
    }

    groups := [][]string{
        {"admin@domain1.com", "admin", "domain1"},
    }

    _, err = Enforcer.AddNamedGroupingPolicies("g", groups)
    if err != nil {
        return err
    }

// I added this to test, and it still throws the same error
    _, err = Enforcer.UpdatePolicy([]string{"admin", "domain1", "users", "allow"}, []string{"admin", "domain1", "users", "deny"})
    if err != nil {
        return err
    }

    return nil
}

Maybe is it because I'm using domains?

This is the full panic log:

panic: interface conversion: *pgadapter.Adapter is not persist.UpdatableAdapter: missing method UpdateFilteredPolicies

goroutine 1 [running]:
github.com/casbin/casbin/v2.(*Enforcer).updatePolicy(0xc0000c6800, 0x1088809, 0x1, 0x1088809, 0x1, 0xc00015d600, 0x4, 0x4, 0xc00015d640, 0x4, ...)
        /home/dearr/go/pkg/mod/github.com/casbin/casbin/v2@v2.30.0/internal_api.go:154 +0x459
github.com/casbin/casbin/v2.(*Enforcer).UpdateNamedPolicy(...)
        /home/dearr/go/pkg/mod/github.com/casbin/casbin/v2@v2.30.0/management_api.go:166
github.com/casbin/casbin/v2.(*Enforcer).UpdatePolicy(0xc0000c6800, 0xc00015d600, 0x4, 0x4, 0xc00015d640, 0x4, 0x4, 0x1, 0xc000511c00, 0x0)
        /home/dearr/go/pkg/mod/github.com/casbin/casbin/v2@v2.30.0/management_api.go:162 +0xa5
backend/enforcer.AddDefaultPoliciesAndGroups(0xf253a0, 0xc0000a4600)
        /home/dearr/Work/whistle/backend/enforcer/enforcer.go:97 +0xcf1
backend/enforcer.Init(0x0, 0x0)
        /home/dearr/Work/whistle/backend/enforcer/enforcer.go:55 +0x225
main.init.0()
        /home/dearr/Work/whistle/backend/main.go:43 +0xb8
exit status 2

my go.mod has this versions:

github.com/casbin/casbin-pg-adapter v1.0.2
github.com/casbin/casbin/v2 v2.30.0
tangyang9464 commented 3 years ago

@antipopp This adapter implementation is outdated, I will update it

github-actions[bot] commented 3 years ago

:tada: This issue has been resolved in version 1.0.3 :tada:

The release is available on GitHub release

Your semantic-release bot :package::rocket: