Перейти к основному содержимому

Adapters

Casbin загружает и сохраняет политики через adapters. Enforcer вызывает LoadPolicy() для загрузки правил и, если поддерживается, SavePolicy() для их сохранения. Адаптеры реализованы в отдельных пакетах, чтобы ядро библиотеки оставалось компактным.

Поддерживаемые адаптеры​

Ниже перечислены адаптеры по языкам. Чтобы добавить сторонний адаптер, создайте issue или pull request.

Adapter Type Author AutoSave Description
File Adapter (built-in) File Casbin ❌ For .CSV (Comma-Separated Values) files
Filtered File Adapter (built-in) File @faceless-saint ❌ For .CSV (Comma-Separated Values) files with policy subset loading support
SQL Adapter SQL @Blank-Xu ✅ MySQL, PostgreSQL, SQL Server, SQLite3 are supported in master branch and Oracle is supported in oracle branch by database/sql
Xorm Adapter ORM Casbin ✅ MySQL, PostgreSQL, TiDB, SQLite, SQL Server, Oracle are supported by Xorm
GORM Adapter ORM Casbin ✅ MySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
GORM Adapter Ex ORM Casbin ✅ MySQL, PostgreSQL, Sqlite3, SQL Server are supported by GORM
Ent Adapter ORM Casbin ✅ MySQL, MariaDB, PostgreSQL, SQLite, Gremlin-based graph databases are supported by ent ORM
Beego ORM Adapter ORM Casbin ✅ MySQL, PostgreSQL, Sqlite3 are supported by Beego ORM
SQLX Adapter ORM @memwey ✅ MySQL, PostgreSQL, SQLite, Oracle are supported by SQLX
Sqlx Adapter ORM @Blank-Xu ✅ MySQL, PostgreSQL, SQL Server, SQLite3 are supported in master branch and Oracle is supported in oracle branch by sqlx
GF ORM Adapter ORM @vance-liu ✅ MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame ORM Adapter ORM @kotlin2018 ✅ MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
gf-adapter ORM @zcyc ✅ MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
Gdb Adapter ORM @jxo-me ✅ MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
GoFrame V2 Adapter ORM @hailaz ✅ MySQL, SQLite, PostgreSQL, Oracle, SQL Server are supported by GoFrame ORM
Bun Adapter ORM @JunNishimura ✅ MySQL, SQLite, PostgreSQL, SQL Server are supported by Bun ORM
Filtered PostgreSQL Adapter SQL Casbin ✅ For PostgreSQL
Filtered pgx Adapter SQL @pckhoi ✅ PostgreSQL is supported by pgx
Pgx Adapter SQL @gtoxlili ✅ PostgreSQL is supported by pgx, supports customizable column count
casbin-pgx-adapter SQL @noho-digital ✅ A PostgreSQL adapter for Casbin using the pgx driver.
PostgreSQL Adapter SQL @cychiuae ✅ For PostgreSQL
RQLite Adapter SQL EDOMO Systems ✅ For RQLite
MongoDB Adapter NoSQL Casbin ✅ For MongoDB based on MongoDB Go Driver
RethinkDB Adapter NoSQL @adityapandey9 ✅ For RethinkDB
Cassandra Adapter NoSQL Casbin ❌ For Apache Cassandra DB
DynamoDB Adapter NoSQL HOOQ ❌ For Amazon DynamoDB
Dynacasbin NoSQL NewbMiao ✅ For Amazon DynamoDB
ArangoDB Adapter NoSQL @adamwasila ✅ For ArangoDB
Amazon S3 Adapter Cloud Soluto ❌ For Minio and Amazon S3
Go CDK Adapter Cloud @bartventer ✅ Adapter based on Go Cloud Dev Kit that supports: Amazon DynamoDB, Azure CosmosDB, GCP Firestore, MongoDB, In-Memory
Azure Cosmos DB Adapter Cloud @spacycoder ✅ For Microsoft Azure Cosmos DB
GCP Firestore Adapter Cloud @reedom ❌ For Google Cloud Platform Firestore
GCP Cloud Storage Adapter Cloud qurami ❌ For Google Cloud Platform Cloud Storage
GCP Cloud Spanner Adapter Cloud @flowerinthenight ✅ For Google Cloud Platform Cloud Spanner
Consul Adapter KV store @ankitm123 ❌ For HashiCorp Consul
Redis Adapter (Redigo) KV store Casbin ✅ For Redis
Redis Adapter (go-redis) KV store @mlsen ✅ For Redis
Etcd Adapter KV store @sebastianliu ❌ For etcd
BoltDB Adapter KV store @speza ✅ For Bolt
Bolt Adapter KV store @wirepair ❌ For Bolt
BadgerDB Adapter KV store @inits ✅ For BadgerDB
Protobuf Adapter Stream Casbin ❌ For Google Protocol Buffers
JSON Adapter String Casbin ❌ For JSON
String Adapter String @qiangmzsx ❌ For String
HTTP File Adapter HTTP @h4ckedneko ❌ For http.FileSystem
FileSystem Adapter File @naucon ❌ For fs.FS and embed.FS
NATS JetStream Adapter KV store grepplabs ✅ For NATS JetStream
Kubernetes Adapter Cloud grepplabs ✅ For Kubernetes
примечание
  1. При вызове casbin.NewEnforcer() с адаптером (явным или неявным) политики загружаются автоматически.
  2. Вызовите e.LoadPolicy(), чтобы обновить политики из хранилища.
  3. Без поддержки Auto-Save адаптеры не могут автоматически сохранять изменения политик при их модификации. Вызывайте SavePolicy() вручную, чтобы сохранить все правила.

Примеры​

Ниже приведено несколько примеров использования адаптеров:

Файловый адаптер (встроенный)​

Инициализация enforcer с использованием встроенного файлового адаптера:

import "github.com/casbin/casbin/v3"

e := casbin.NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")

Эквивалентная альтернатива:

import (
"github.com/casbin/casbin/v3"
fileadapter "github.com/casbin/casbin/v3/persist/file-adapter"
)

a := fileadapter.NewAdapter("examples/basic_policy.csv")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

MySQL adapter​

Инициализация enforcer с использованием соединения с базой данных MySQL по адресу 127.0.0.1:3306, пользователь root, без пароля:

import (
"github.com/casbin/casbin/v3"
"github.com/casbin/mysql-adapter"
)

a := mysqladapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

Использование собственного адаптера хранилища​

Интеграция пользовательского адаптера:

import (
"github.com/casbin/casbin/v3"
"github.com/your-username/your-repo"
)

a := yourpackage.NewAdapter(params)
e := casbin.NewEnforcer("examples/basic_model.conf", a)

Миграция/Конвертация между разными адаптерами​

Чтобы перенести политики из адаптера A в адаптер B:

  1. Загрузите политику из A в память
e, _ := NewEnforcer(m, A)

или

e.SetAdapter(A)
e.LoadPolicy()
  1. Переключитесь с адаптера A на B
e.SetAdapter(B)
  1. Сохраните политику из памяти в B
e.SavePolicy()

Load/Save во время выполнения​

Перезагрузка моделей и политик или сохранение изменений политики после инициализации:

// Reload the model from the model CONF file.
e.LoadModel()

// Reload the policy from file/database.
e.LoadPolicy()

// Save the current policy (usually after changed with Casbin API) back to file/database.
e.SavePolicy()

AutoSave​

Адаптеры с поддержкой Auto-Save могут сохранять отдельные изменения политики непосредственно в хранилище без полной операции сохранения. Это отличается от SavePolicy(), который очищает хранилище и перезаписывает все политики, что может вызывать проблемы с производительностью при большом количестве политик.

Когда адаптер поддерживает Auto-Save, управляйте этим поведением через Enforcer.EnableAutoSave(). По умолчанию эта опция включена для совместимых адаптеров.

примечание
  1. Auto-Save — это необязательная функция. Адаптеры могут её реализовать или нет.
  2. Auto-Save работает только тогда, когда адаптер энфорсера его поддерживает.
  3. Проверьте столбец AutoSave в списке адаптеров выше, чтобы определить поддержку.

Пример использования Auto-Save:

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

// AutoSave is enabled by default when using compatible adapters with enforcers.
a := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/")
e := casbin.NewEnforcer("examples/basic_model.conf", a)

// Disable AutoSave.
e.EnableAutoSave(false)

// Policy changes affect only the in-memory enforcer,
// not the storage.
e.AddPolicy(...)
e.RemovePolicy(...)

// Enable AutoSave.
e.EnableAutoSave(true)

// Policy changes now persist to storage
// in addition to updating the in-memory enforcer.
e.AddPolicy(...)
e.RemovePolicy(...)

Дополнительные примеры: https://github.com/apache/casbin-xorm-adapter/blob/master/adapter_test.go

Как написать адаптер​

Реализуйте интерфейс Adapter как минимум с двумя обязательными методами: LoadPolicy(model model.Model) error и SavePolicy(model model.Model) error.

Три необязательных метода обеспечивают поддержку Auto-Save.

МетодТипОписание
LoadPolicy()mandatoryLoad all policy rules from the storage
SavePolicy()mandatorySave all policy rules to the storage
AddPolicy()optionalAdd a policy rule to the storage
RemovePolicy()optionalRemove a policy rule from the storage
RemoveFilteredPolicy()optionalRemove policy rules that match the filter from the storage
примечание

Если адаптер не поддерживает Auto-Save, предоставьте пустые реализации для трёх необязательных методов. Пример на Golang:

// AddPolicy adds a policy rule to the storage.
func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemovePolicy removes a policy rule from the storage.
func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
return errors.New("not implemented")
}

// RemoveFilteredPolicy removes policy rules that match the filter from the storage.
func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
return errors.New("not implemented")
}

Энфорсеры Casbin игнорируют ошибку "not implemented" при вызове этих необязательных методов.

Требования к реализации адаптера:

  • Структура данных. Поддержка чтения как минимум шести столбцов.
  • Имя базы данных. По умолчанию casbin.
  • Имя таблицы. По умолчанию casbin_rule.
  • Столбец Ptype. Имя ptype (не p_type или Ptype).
  • Определение таблицы: (id int primary key, ptype varchar, v0 varchar, v1 varchar, v2 varchar, v3 varchar, v4 varchar, v5 varchar).
  • Уникальный индекс: Построен на столбцах ptype,v0,v1,v2,v3,v4,v5.
  • LoadFilteredPolicy принимает параметр фильтра, структурированный следующим образом:
{
"p": ["", "domain1"],
"g": ["", "", "domain1"]
}

Кто отвечает за создание БД?​

По соглашению адаптеры должны автоматически создавать базу данных casbin, если она не существует, и использовать её для хранения политик. Референсная реализация: https://github.com/apache/casbin-xorm-adapter

Update Adapter​

Интерфейс UpdateAdapter расширяет базовый интерфейс Adapter, позволяя напрямую обновлять политики в хранилище. Этот подход более эффективен, чем последовательность удаления и добавления, при изменении существующих правил.

Адаптеры, реализующие UpdateAdapter, предоставляют следующие методы:

МетодТипОписание
UpdatePolicy()optionalОбновление одного правила политики в хранилище
UpdatePolicies()optionalОбновление нескольких правил политик в хранилище
UpdateFilteredPolicies()optionalОбновление правил политик, соответствующих фильтру, в хранилище

Пример​

Использование адаптера обновления:

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

a, _ := gormadapter.NewAdapter("mysql", "root:@tcp(127.0.0.1:3306)/")
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)

// Update a single policy
// Change: p, alice, data1, read -> p, alice, data1, write
e.UpdatePolicy(
[]string{"alice", "data1", "read"},
[]string{"alice", "data1", "write"},
)

// Update multiple policies at once
e.UpdatePolicies(
[][]string{{"alice", "data1", "write"}, {"bob", "data2", "read"}},
[][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}},
)

// Update all policies matching a filter
e.UpdateFilteredPolicies(
[][]string{{"alice", "data1", "write"}},
0,
"alice", "data1", "read",
)

Как написать адаптер обновления​

Чтобы реализовать UpdateAdapter, добавьте методы обновления в вашу базовую реализацию Adapter:

// UpdatePolicy updates a policy rule from storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdatePolicy(sec string, ptype string, oldRule, newRule []string) error {
// Update the policy in storage
// SQL example: UPDATE casbin_rule SET v0=?, v1=?, v2=? WHERE ptype=? AND v0=? AND v1=? AND v2=?
return nil
}

// UpdatePolicies updates multiple policy rules in the storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdatePolicies(sec string, ptype string, oldRules, newRules [][]string) error {
// Update multiple policies in storage
// Use transactions for consistency
return nil
}

// UpdateFilteredPolicies updates policy rules that match the filter from the storage.
// This is part of the UpdateAdapter interface.
func (a *Adapter) UpdateFilteredPolicies(sec string, ptype string, newRules [][]string, fieldIndex int, fieldValues ...string) error {
// Find policies matching the filter, then update them
return nil
}
примечание

Без поддержки UpdateAdapter Casbin автоматически переключается на комбинацию операций RemovePolicy() и AddPolicy().

Context Adapter​

ContextAdapter предоставляет операции, учитывающие контекст, для адаптеров Casbin.

Контекст позволяет использовать такие функции, как управление таймаутами для вызовов API адаптера.

Пример​

gormadapter поддерживает контекст. Ниже приведено управление таймаутом с использованием контекста:

ca, _ := NewContextAdapter("mysql", "root:@tcp(127.0.0.1:3306)/", "casbin")
// Set 300s timeout
ctx, cancel := context.WithTimeout(context.Background(), 300*time.Microsecond)
defer cancel()

err := ca.AddPolicyCtx(ctx, "p", "p", []string{"alice", "data1", "read"})
if err != nil {
panic(err)
}

Как написать context adapter​

API ContextAdapter добавляет слой обработки контекста поверх стандартного API Adapter. После реализации стандартного API Adapter оберните вашу логику обработкой контекста.

Референсная реализация: adapter.go

Транзакции​

Casbin поддерживает транзакции. Использование транзакций в gormadapter:

db, _ := gorm.Open(...)
adapter, _ := gormadapter.NewTransactionalAdapterByDB(db)
e, _ := casbin.NewTransactionalEnforcer("examples/rbac_model.conf", adapter)

ctx := context.Background()

// WithTransaction executes a function within a transaction.
// Errors trigger rollback; otherwise, automatic commit occurs.
err := e.WithTransaction(ctx, func(tx *casbin.Transaction) error {
tx.AddPolicy("alice", "data1", "read")
tx.AddPolicy("alice", "data1", "write")
return nil
})

// Manual transaction handling
tx, _ := e.BeginTransaction(ctx)
tx.AddPolicy("alice", "data1", "write")
if err := tx.Commit(); err != nil {
// handle transaction failure
}

Реализуйте TransactionalAdapter и TransactionContext из persist/transaction.go, чтобы добавить поддержку транзакций.

Ссылка: adapter.go

Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.