Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/casbin/gorm-adapter
GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex
https://github.com/casbin/gorm-adapter
abac access-control acl adapter auth authorization authz casbin go golang gorm orm rbac storage-driver
Last synced: 5 days ago
JSON representation
GORM adapter for Casbin, see extended version of GORM Adapter Ex at: https://github.com/casbin/gorm-adapter-ex
- Host: GitHub
- URL: https://github.com/casbin/gorm-adapter
- Owner: casbin
- License: apache-2.0
- Created: 2017-07-29T02:34:31.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-08-19T07:47:56.000Z (5 months ago)
- Last Synced: 2024-10-29T22:37:47.195Z (3 months ago)
- Topics: abac, access-control, acl, adapter, auth, authorization, authz, casbin, go, golang, gorm, orm, rbac, storage-driver
- Language: Go
- Homepage: https://github.com/casbin/casbin
- Size: 183 KB
- Stars: 692
- Watchers: 6
- Forks: 206
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
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](https://goreportcard.com/badge/github.com/casbin/gorm-adapter)](https://goreportcard.com/report/github.com/casbin/gorm-adapter)
[![Go](https://github.com/casbin/gorm-adapter/actions/workflows/ci.yml/badge.svg)](https://github.com/casbin/gorm-adapter/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/casbin/gorm-adapter/badge.svg?branch=master)](https://coveralls.io/github/casbin/gorm-adapter?branch=master)
[![Godoc](https://godoc.org/github.com/casbin/gorm-adapter?status.svg)](https://godoc.org/github.com/casbin/gorm-adapter)
[![Release](https://img.shields.io/github/release/casbin/gorm-adapter.svg)](https://github.com/casbin/gorm-adapter/releases/latest)
[![Discord](https://img.shields.io/discord/1022748306096537660?logo=discord&label=discord&color=5865F2)](https://discord.gg/S5UjpzGZjN)
[![Sourcegraph](https://sourcegraph.com/github.com/casbin/gorm-adapter/-/badge.svg)](https://sourcegraph.com/github.com/casbin/gorm-adapter?badge)Gorm Adapter is the [Gorm](https://gorm.io/gorm) adapter for [Casbin](https://github.com/casbin/casbin). With this library, Casbin can load policy from Gorm supported database or save policy to it.
Based on [Officially Supported Databases](https://v1.gorm.io/docs/connecting_to_the_database.html#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
```go
package mainimport (
"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:
```go
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](https://github.com/casbin/gorm-adapter/issues/162)
## Customize table columns example
You can change the gorm struct tags, but the table structure must stay the same.
```go
package mainimport (
"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:
```go
package mainfunc 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
* model example: [object_conditions_model.conf](examples/object_conditions_model.conf)
* policy example: [object_conditions_policy.csv](examples/object_conditions_policy.csv)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|```go
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
```go
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
- [Casbin](https://github.com/casbin/casbin)
## License
This project is under Apache 2.0 License. See the [LICENSE](LICENSE) file for the full license text.