gormadapter

package module
v3.32.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2024 License: Apache-2.0 Imports: 18 Imported by: 429

README

Gorm Adapter

In v3.0.3, method NewAdapterByDB creates table named casbin_rules,
we fix it to casbin_rule after that.
If you used v3.0.3 and less, and you want to update it,
you might need to migrate data manually. Find out more at: https://github.com/casbin/gorm-adapter/issues/78

Go Report Card Go Coverage Status Godoc Release Discord Sourcegraph

Gorm Adapter is the Gorm adapter for Casbin. With this library, Casbin can load policy from Gorm supported database or save policy to it.

Based on Officially Supported Databases, The current supported databases are:

  • MySQL
  • PostgreSQL
  • SQL Server
  • Sqlite3

gorm-adapter use github.com/glebarez/sqlite instead of gorm official sqlite driver gorm.io/driver/sqlite because the latter needs cgo support. But there is almost no difference between the two driver. If there is a difference in use, please submit an issue.

  • other 3rd-party supported DBs in Gorm website or other places.

Installation

go get github.com/casbin/gorm-adapter/v3

Simple Example

package main

import (
	"github.com/casbin/casbin/v2"
	gormadapter "github.com/casbin/gorm-adapter/v3"
	_ "github.com/go-sql-driver/mysql"
)

func main() {
	// Initialize a Gorm adapter and use it in a Casbin enforcer:
	// The adapter will use the MySQL database named "casbin".
	// If it doesn't exist, the adapter will create it automatically.
	// You can also use an already existing gorm instance with gormadapter.NewAdapterByDB(gormInstance)
	a, _ := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/") // Your driver and data source.
	e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)
	
	// Or you can use an existing DB "abc" like this:
	// The adapter will use the table named "casbin_rule".
	// If it doesn't exist, the adapter will create it automatically.
	// a := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/abc", true)

	// Load the policy from DB.
	e.LoadPolicy()
	
	// Check the permission.
	e.Enforce("alice", "data1", "read")
	
	// Modify the policy.
	// e.AddPolicy(...)
	// e.RemovePolicy(...)
	
	// Save the policy back to DB.
	e.SavePolicy()
}

Turn off AutoMigrate

New an adapter will use AutoMigrate by default for create table, if you want to turn it off, please use API TurnOffAutoMigrate(db *gorm.DB) *gorm.DB. See example:

db, err := gorm.Open(mysql.Open("root:@tcp(127.0.0.1:3306)/casbin"), &gorm.Config{})
TurnOffAutoMigrate(db)
// a,_ := NewAdapterByDB(...)
// a,_ := NewAdapterByDBUseTableName(...)
a,_ := NewAdapterByDBWithCustomTable(...)

Find out more details at gorm-adapter#162

Customize table columns example

You can change the gorm struct tags, but the table structure must stay the same.

package main

import (
	"github.com/casbin/casbin/v2"
	gormadapter "github.com/casbin/gorm-adapter/v3"
	"gorm.io/gorm"
)

func main() {
	// Increase the column size to 512.
	type CasbinRule struct {
		ID    uint   `gorm:"primaryKey;autoIncrement"`
		Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
		V0    string `gorm:"size:512;uniqueIndex:unique_index"`
		V1    string `gorm:"size:512;uniqueIndex:unique_index"`
		V2    string `gorm:"size:512;uniqueIndex:unique_index"`
		V3    string `gorm:"size:512;uniqueIndex:unique_index"`
		V4    string `gorm:"size:512;uniqueIndex:unique_index"`
		V5    string `gorm:"size:512;uniqueIndex:unique_index"`
	}

	db, _ := gorm.Open(...)

	// Initialize a Gorm adapter and use it in a Casbin enforcer:
	// The adapter will use an existing gorm.DB instnace.
	a, _ := gormadapter.NewAdapterByDBWithCustomTable(db, &CasbinRule{}) 
	e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)
	
	// Load the policy from DB.
	e.LoadPolicy()
	
	// Check the permission.
	e.Enforce("alice", "data1", "read")
	
	// Modify the policy.
	// e.AddPolicy(...)
	// e.RemovePolicy(...)
	
	// Save the policy back to DB.
	e.SavePolicy()
}

Transaction

You can modify policies within a transaction.See example:

package main

func main() {
	a, err := NewAdapterByDB(db)
	e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)
	err = e.GetAdapter().(*Adapter).Transaction(e, func(e casbin.IEnforcer) error {
		_, err := e.AddPolicy("jack", "data1", "write")
		if err != nil {
			return err
		}
		_, err = e.AddPolicy("jack", "data2", "write")
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		// handle if transaction failed
		return
	}
}

ConditionsToGormQuery

ConditionsToGormQuery() is a function that converts multiple query conditions into a GORM query statement You can use the GetAllowedObjectConditions() API of Casbin to get conditions, and choose the way of combining conditions through combineType.

ConditionsToGormQuery() allows Casbin to be combined with SQL, and you can use it to implement many functions.

Example: GetAllowedRecordsForUser

DataBase example:

id title author publisher publish_data price category_id
1 book1 author1 publisher1 2023-04-09 16:23:42 10 1
2 book2 author1 publisher1 2023-04-09 16:23:44 20 2
3 book3 author2 publisher1 2023-04-09 16:23:44 30 1
4 book4 author2 publisher2 2023-04-09 16:23:45 10 3
5 book5 author3 publisher2 2023-04-09 16:23:45 50 1
6 book6 author3 publisher2 2023-04-09 16:23:46 60 2
type Book struct {
    ID          int
    Title       string
    Author      string
    Publisher   string
    PublishDate time.Time
    Price       float64
    CategoryID  int
}

func TestGetAllowedRecordsForUser(t *testing.T) {
	e, _ := casbin.NewEnforcer("examples/object_conditions_model.conf", "examples/object_conditions_policy.csv")

	conditions, err := e.GetAllowedObjectConditions("alice", "read", "r.obj.")
	if err != nil {
		panic(err)
	}
	fmt.Println(conditions)

	dsn := "root:root@tcp(127.0.0.1:3307)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic(err)
	}

	fmt.Println("CombineTypeOr")
	rows, err := ConditionsToGormQuery(db, conditions, CombineTypeOr).Model(&Book{}).Rows()
	defer rows.Close()
	var b Book
	for rows.Next() {
		err := db.ScanRows(rows, &b)
		if err != nil {
			panic(err)
		}
		log.Println(b)
	}

	fmt.Println("CombineTypeAnd")
	rows, err = ConditionsToGormQuery(db, conditions, CombineTypeAnd).Model(&Book{}).Rows()
	defer rows.Close()
	for rows.Next() {
		err := db.ScanRows(rows, &b)
		if err != nil {
			panic(err)
		}
		log.Println(b)
	}
}

Context Adapter

gormadapter supports adapter with context, the following is a timeout control implemented using context

a, _ := gormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/") // Your driver and data source.
// Limited time 300s
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Microsecond)
defer cancel()
err := a.AddPolicyCtx(ctx, "p", "p", []string{"alice", "data1", "read"})
if err != nil {
    panic(err)
}

Getting Help

License

This project is under Apache 2.0 License. See the LICENSE file for the full license text.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConditionsToGormQuery added in v3.17.0

func ConditionsToGormQuery(db *gorm.DB, conditions []string, combineType CombineType) *gorm.DB

ConditionsToGormQuery is a function that converts multiple query conditions into a GORM query statement You can use the GetAllowedObjectConditions() API of Casbin to get conditions, and choose the way of combining conditions through combineType.

func TurnOffAutoMigrate added in v3.7.1

func TurnOffAutoMigrate(db *gorm.DB)

Types

type Adapter

type Adapter struct {
	// contains filtered or unexported fields
}

Adapter represents the Gorm adapter for policy storage.

func NewAdapter

func NewAdapter(driverName string, dataSourceName string, params ...interface{}) (*Adapter, error)

NewAdapter is the constructor for Adapter. Params : databaseName,tableName,dbSpecified

databaseName,{tableName/dbSpecified}
{database/dbSpecified}

databaseName and tableName are user defined. Their default value are "casbin" and "casbin_rule"

dbSpecified is an optional bool parameter. The default value is false. It's up to whether you have specified an existing DB in dataSourceName. If dbSpecified == true, you need to make sure the DB in dataSourceName exists. If dbSpecified == false, the adapter will automatically create a DB named databaseName.

func NewAdapterByDB

func NewAdapterByDB(db *gorm.DB) (*Adapter, error)

NewAdapterByDB creates gorm-adapter by an existing Gorm instance

func NewAdapterByDBUseTableName added in v3.0.3

func NewAdapterByDBUseTableName(db *gorm.DB, prefix string, tableName string) (*Adapter, error)

NewAdapterByDBUseTableName creates gorm-adapter by an existing Gorm instance and the specified table prefix and table name Example: gormadapter.NewAdapterByDBUseTableName(&db, "cms", "casbin") Automatically generate table name like this "cms_casbin"

func NewAdapterByDBWithCustomTable added in v3.2.0

func NewAdapterByDBWithCustomTable(db *gorm.DB, t interface{}, tableName ...string) (*Adapter, error)

func NewAdapterByMulDb added in v3.3.0

func NewAdapterByMulDb(dbPool DbPool, dbName string, prefix string, tableName string) (*Adapter, error)

func NewFilteredAdapter added in v3.0.5

func NewFilteredAdapter(driverName string, dataSourceName string, params ...interface{}) (*Adapter, error)

NewFilteredAdapter is the constructor for FilteredAdapter. Casbin will not automatically call LoadPolicy() for a filtered adapter.

func NewFilteredAdapterByDB added in v3.13.0

func NewFilteredAdapterByDB(db *gorm.DB, prefix string, tableName string) (*Adapter, error)

NewFilteredAdapterByDB is the constructor for FilteredAdapter. Casbin will not automatically call LoadPolicy() for a filtered adapter.

func (*Adapter) AddLogger added in v3.2.10

func (a *Adapter) AddLogger(l logger.Interface)

AddLogger adds logger to db

func (*Adapter) AddPolicies

func (a *Adapter) AddPolicies(sec string, ptype string, rules [][]string) error

AddPolicies adds multiple policy rules to the storage.

func (*Adapter) AddPolicy

func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error

AddPolicy adds a policy rule to the storage.

func (*Adapter) AddPolicyCtx added in v3.24.0

func (a *Adapter) AddPolicyCtx(ctx context.Context, sec string, ptype string, rule []string) error

AddPolicyCtx adds a policy rule to the storage.

func (*Adapter) Close added in v3.5.0

func (a *Adapter) Close() error

func (*Adapter) Copy added in v3.31.0

func (a *Adapter) Copy() *Adapter

func (*Adapter) GetDb added in v3.15.0

func (a *Adapter) GetDb() *gorm.DB

func (*Adapter) IsFiltered

func (a *Adapter) IsFiltered() bool

IsFiltered returns true if the loaded policy has been filtered.

func (*Adapter) LoadFilteredPolicy

func (a *Adapter) LoadFilteredPolicy(model model.Model, filter interface{}) error

LoadFilteredPolicy loads only policy rules that match the filter.

func (*Adapter) LoadPolicy

func (a *Adapter) LoadPolicy(model model.Model) error

LoadPolicy loads policy from database.

func (*Adapter) LoadPolicyCtx added in v3.24.0

func (a *Adapter) LoadPolicyCtx(ctx context.Context, model model.Model) error

LoadPolicyCtx loads policy from database.

func (*Adapter) Open added in v3.5.0

func (a *Adapter) Open() error

func (*Adapter) Preview added in v3.11.0

func (a *Adapter) Preview(rules *[]CasbinRule, model model.Model) error

Preview Pre-checking to avoid causing partial load success and partial failure deep

func (*Adapter) RemoveFilteredPolicy

func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error

RemoveFilteredPolicy removes policy rules that match the filter from the storage.

func (*Adapter) RemoveFilteredPolicyCtx added in v3.24.0

func (a *Adapter) RemoveFilteredPolicyCtx(ctx context.Context, sec string, ptype string, fieldIndex int, fieldValues ...string) error

RemoveFilteredPolicyCtx removes policy rules that match the filter from the storage.

func (*Adapter) RemovePolicies

func (a *Adapter) RemovePolicies(sec string, ptype string, rules [][]string) error

RemovePolicies removes multiple policy rules from the storage.

func (*Adapter) RemovePoliciesCtx added in v3.24.0

func (a *Adapter) RemovePoliciesCtx(ctx context.Context, sec string, ptype string, rules [][]string) error

RemovePoliciesCtx removes multiple policy rules from the storage.

func (*Adapter) RemovePolicy

func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error

RemovePolicy removes a policy rule from the storage.

func (*Adapter) RemovePolicyCtx added in v3.24.0

func (a *Adapter) RemovePolicyCtx(ctx context.Context, sec string, ptype string, rule []string) error

RemovePolicyCtx removes a policy rule from the storage.

func (*Adapter) SavePolicy

func (a *Adapter) SavePolicy(model model.Model) error

SavePolicy saves policy to database.

func (*Adapter) SavePolicyCtx added in v3.24.0

func (a *Adapter) SavePolicyCtx(ctx context.Context, model model.Model) error

SavePolicyCtx saves policy to database.

func (*Adapter) Transaction added in v3.10.0

func (a *Adapter) Transaction(e casbin.IEnforcer, fc func(casbin.IEnforcer) error, opts ...*sql.TxOptions) error

Transaction perform a set of operations within a transaction

func (*Adapter) UpdateFilteredPolicies added in v3.2.9

func (a *Adapter) UpdateFilteredPolicies(sec string, ptype string, newPolicies [][]string, fieldIndex int, fieldValues ...string) ([][]string, error)

func (*Adapter) UpdatePolicies added in v3.2.5

func (a *Adapter) UpdatePolicies(sec string, ptype string, oldRules, newRules [][]string) error

func (*Adapter) UpdatePolicy added in v3.0.6

func (a *Adapter) UpdatePolicy(sec string, ptype string, oldRule, newPolicy []string) error

UpdatePolicy updates a new policy rule to DB.

type BatchFilter added in v3.8.0

type BatchFilter struct {
	// contains filtered or unexported fields
}

type CasbinRule

type CasbinRule struct {
	ID    uint   `gorm:"primaryKey;autoIncrement"`
	Ptype string `gorm:"size:100"`
	V0    string `gorm:"size:100"`
	V1    string `gorm:"size:100"`
	V2    string `gorm:"size:100"`
	V3    string `gorm:"size:100"`
	V4    string `gorm:"size:100"`
	V5    string `gorm:"size:100"`
}

func (CasbinRule) TableName

func (CasbinRule) TableName() string

type CombineType added in v3.17.0

type CombineType uint32

CombineType represents different types of condition combining strategies

const (
	CombineTypeOr  CombineType = iota // Combine conditions with OR operator
	CombineTypeAnd                    // Combine conditions with AND operator
)

type DbPool added in v3.3.0

type DbPool struct {
	// contains filtered or unexported fields
}

func InitDbResolver added in v3.3.0

func InitDbResolver(dbArr []gorm.Dialector, dbNames []string) (DbPool, error)

InitDbResolver multiple databases support Example usage: dbPool,err := InitDbResolver([]gorm.Dialector{mysql.Open(dsn),mysql.Open(dsn2)},[]string{"casbin1","casbin2"}) a := initAdapterWithGormInstanceByMulDb(t,dbPool,"casbin1","","casbin_rule1") a = initAdapterWithGormInstanceByMulDb(t,dbPool,"casbin2","","casbin_rule2")/*

type Filter

type Filter struct {
	Ptype []string
	V0    []string
	V1    []string
	V2    []string
	V3    []string
	V4    []string
	V5    []string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL