casbin / gorm-adapter

GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex

Home Page:https://github.com/casbin/casbin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Understanding how to correctly update policies in a database

andrerav opened this issue · comments

Hi,

I have inherited a legacy Go program that uses casbin and gorm-adapter to update a set of policies in a database. The program is basically sequenced as follows:

	rules = [][]string { ... } 
	roles = [][]string { ... } 
	users = [][]string { ... } 

	enforcer.GetAdapter().(*gormadapter.Adapter).Transaction(enforcer, func(e casbin.IEnforcer) error {
		var userGroups [][]string
		namedGroupingPolices := enforcer.GetNamedGroupingPolicy("g")

		for _, namedGroupingPolicy := range namedGroupingPolices {
			if strings.Contains(namedGroupingPolicy[0], "user:") {
				userGroups = append(userGroups, namedGroupingPolicy)
			}
		}

		gormDB.Exec("DELETE FROM casbin_rule")

		enforcer.LoadPolicy()
		enforcer.AddNamedPolicies("p", rules)
		enforcer.AddNamedGroupingPolicies("g", roles)
		enforcer.AddNamedGroupingPolicies("g", userGroups)
		enforcer.AddNamedGroupingPolicies("g", users)
		return nil
	})
	if err != nil {
		fmt.Printf("Transaction failed: %+v\n", err)
		return
	}

Now, the obvious problem I am trying to fix is that the line with the DELETE sql statement is being executed outside the transaction. However, I don't understand why the DELETE statement is there. All I know is that if I simply remove it, this program will not update the policies in the database.

What is the recommended practice to do what this program is supposed to do, given that you hopefully understand what this program is trying to achieve?

(Sorry for posting this as an issue, but you don't have a discussion section here)

commented

about use transaction, you can use db := enforcer.GetAdapter().(*gormadapter.Adapter).GetDb() to exec sql like
casbin/casbin#1205 (comment)
about update policies, can use update api

// UpdatableAdapter is the interface for Casbin adapters with add update policy function.
type UpdatableAdapter interface {
	Adapter
	// UpdatePolicy updates a policy rule from storage.
	// This is part of the Auto-Save feature.
	UpdatePolicy(sec string, ptype string, oldRule, newRule []string) error
	// UpdatePolicies updates some policy rules to storage, like db, redis.
	UpdatePolicies(sec string, ptype string, oldRules, newRules [][]string) error
	// UpdateFilteredPolicies deletes old rules and adds new rules.
	UpdateFilteredPolicies(sec string, ptype string, newRules [][]string, fieldIndex int, fieldValues ...string) ([][]string, error)
}

Fantastic @weloe, thank you very much. On the short term, using GetDb() solved my problem. On the longer term, I will definitely try to rewrite this into using UpdatableAdapter instead.