Git Product home page Git Product logo

xorm-adapter's Introduction

Xorm Adapter

Go Coverage Status Go Report Card Godoc

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

Based on Xorm Drivers Support, The current supported databases are:

Installation

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

Simple MySQL Example

package main

import (
	"github.com/casbin/casbin/v2"
	_ "github.com/go-sql-driver/mysql"

	"github.com/casbin/xorm-adapter/v3"
)

func main() {
	// Initialize a Xorm 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.
	a, _ := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/") // Your driver and data source. 

	// 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 := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/abc", true)

	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()
}

Simple Postgres Example

package main

import (
	"github.com/casbin/casbin/v2"
	_ "github.com/lib/pq"

	"github.com/casbin/xorm-adapter/v3"
)

func main() {
	// Initialize a Xorm adapter and use it in a Casbin enforcer:
	// The adapter will use the Postgres database named "casbin".
	// If it doesn't exist, the adapter will create it automatically.
	a, _ := xormadapter.NewAdapter("postgres", "user=postgres_username password=postgres_password host=127.0.0.1 port=5432 sslmode=disable") // Your driver and data source.

	// 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 := xormadapter.NewAdapter("postgres", "dbname=abc user=postgres_username password=postgres_password host=127.0.0.1 port=5432 sslmode=disable", true)

	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()
}

Context Adapter

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

a, _ := xormadapter.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.

xorm-adapter's People

Contributors

abawchen avatar abingcbc avatar cyjaysong avatar dawndiy avatar dovics avatar ev1lquark avatar hsluoyz avatar jalinwang avatar kilosonc avatar linxing avatar luochuanyuewu avatar mousedownmike avatar mrchar avatar muzhou233 avatar nodece avatar ogkevin avatar pokisemaine avatar sadayuki-matsuno avatar selflocking avatar tangyang9464 avatar tson1111 avatar vishal-bihani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xorm-adapter's Issues

UpdateFilteredPolicies returns the oldPolicy containing ptype, Is this a bug?

oldPolicy := v.toStringPolicy()

xorm-adapter/adapter.go

Lines 560 to 562 in eadfe04

if c.PType != "" {
policy = append(policy, c.PType)
}

will returns the oldPolicy containing ptype

but in usage:
https://github.com/casbin/casbin/blob/c4cf679dfe87889c4228be7172a346282c2efdd4/internal_api.go#L339
https://github.com/casbin/casbin/blob/c4cf679dfe87889c4228be7172a346282c2efdd4/model/policy.go#L271

model[sec][ptype].PolicyMap key does not contain ptype
so, it cannot delete policy correctly

I'm not sure if this is an adapter bug or a casbin bug

Interface conversion (Panic) *xormadapter.Adapter is not persist.UpdatableAdapter: missing method UpdatePolicies

Description

Panic error when trying to use the function UpdateGroupingPolicy() or UpdateNamedGroupingPolicy()

The xormadapter.Adapter cannot be converted to persist.UpdatableAdapter because of missing function UpdatePolicies() in the xorm-adapter

stacktrace

panic serving [::1]:35256: interface conversion: *xormadapter.Adapter is not persist.UpdatableAdapter: missing method UpdatePolicies
goroutine 23 [running]:
net/http.(*conn).serve.func1(0xc0002981e0)
        /snap/go/current/src/net/http/server.go:1824 +0x14c
panic(0xb14e60, 0xc0003d6ba0)
        /snap/go/current/src/runtime/panic.go:971 +0x4c7
github.com/casbin/casbin/v2.(*Enforcer).updatePolicy(0xc00038a780, 0xb8e9f8, 0x1, 0xb8e9f8, 0x1, 0xc0003d6b40, 0x3, 0x3, 0xc0003d6b70, 0x3, ...)
        /home/kserrano/go/pkg/mod/github.com/casbin/casbin/[email protected]/internal_api.go:154 +0x1d5
github.com/casbin/casbin/v2.(*Enforcer).UpdateNamedGroupingPolicy(0xc00038a780, 0xb8e9f8, 0x1, 0xc0003d6b40, 0x3, 0x3, 0xc0003d6b70, 0x3, 0x3, 0xe73500, ...)
        /home/kserrano/go/pkg/mod/github.com/casbin/casbin/[email protected]/management_api.go:314 +0xd8
github.com/casbin/casbin/v2.(*Enforcer).UpdateGroupingPolicy(0xc00038a780, 0xc0003d6b40, 0x3, 0x3, 0xc0003d6b70, 0x3, 0x3, 0x0, 0x0, 0x0)
        /home/kserrano/go/pkg/mod/github.com/casbin/casbin/[email protected]/management_api.go:310 +0xbe
nessie.xyz/authorization/internal/models.UpdateMember(0xc00051c1a0, 0xc0002a4290, 0x6, 0xc0002a42b0, 0xa, 0xc0002a42c0, 0xb, 0xc0002a4296, 0x6, 0xc0002a42a0, ...)

Versions

Using the following versions for Casbin and Adapter (extracted from go.mod file)
Casbin v2.25.5 (latest as of today)
xorm-adapter v2.2.0 (latest as of today)

go 1.15

require (
	github.com/casbin/casbin/v2 v2.25.5
	github.com/casbin/xorm-adapter/v2 v2.2.0
	github.com/go-sql-driver/mysql v1.5.0
)

SavePolicy reports "No element on slice when insert" error when the model's policy is null

hi, I am using SavePolicy of enforcer in my program to save policies manully. but I get an xorm error which is ErrNoElementsOnSlice when the model is null. I found the following code:

// SavePolicy saves policy to database.
func (a *Adapter) SavePolicy(model model.Model) error {
	err := a.dropTable()
	if err != nil {
		return err
	}
	err = a.createTable()
	if err != nil {
		return err
	}

	lines := make([]*CasbinRule, 0, 64)

	for ptype, ast := range model["p"] {
		for _, rule := range ast.Policy {
			line := a.genPolicyLine(ptype, rule)
			lines = append(lines, line)
		}
	}

	for ptype, ast := range model["g"] {
		for _, rule := range ast.Policy {
			line := a.genPolicyLine(ptype, rule)
			lines = append(lines, line)
		}
	}

	_, err = a.engine.Insert(&lines)

	return err
}

I want to know whether we can add a length check about lines in this function to solve the problem?

Fails to connect to pg 16.1

Using PG 16.1 or 15.5, the adapter fails to connect:

error: adapter: pq: trailing junk after parameter at or near "$1A"

a, err := xormadapter.NewAdapter("postgres", "dbname=dbname user=admin password=admin host=localhost port=5432 sslmode=disable", true)

OR

a, err := xormadapter.NewAdapter("postgres", "user=admin password=admin host=localhost port=5432 sslmode=disable")

Both fail. It works the first time, it will create the casbin_rule table and perform a query. The second time I boot the application I get the above error.

Primary key support?

Hey,

So I wanted to add a column to my casbin table, specifically a primary key so I can identify rules if I do SQL queries by ID for ease of identification. Is that possible, I know currently there is no support for it but is there a reason for this?

README is wrong (for v1 only)

The install command is for v1 wrongly:

go get github.com/casbin/xorm-adapter should be: go get github.com/casbin/xorm-adapter/v2

Adapter.SavePolicy() not safe for concurrent use?

xorm-adapter/adapter.go

Lines 226 to 249 in 9b17d80

// SavePolicy saves policy to database.
func (a *Adapter) SavePolicy(model model.Model) error {
a.dropTable()
a.createTable()
var lines []CasbinRule
for ptype, ast := range model["p"] {
for _, rule := range ast.Policy {
line := savePolicyLine(ptype, rule)
lines = append(lines, line)
}
}
for ptype, ast := range model["g"] {
for _, rule := range ast.Policy {
line := savePolicyLine(ptype, rule)
lines = append(lines, line)
}
}
_, err := a.engine.Insert(&lines)
return err
}

Is SavePolicy() is safe for concurrent use as it drops the table and recreates it from the model? What if a go routine is in the middle of creating a table and another one tries to drop it? Here's a snippet of my logs from postgres which I think stems from calling SavePolicy() concurrently.

image

The error I'm getting: ERROR: relation "casbin_rule" does not exist.

I can get around this issue by having my own locking logic if that's the case.

[Question] Can I configure casbin xorm to "skip" table creation ?

What's your scenario? What do you want to achieve?
I am creating a cached enforcer in casbin and using XORM to store my policies to store my policies on a cloud managed Postgres DB.
It looks like casbin internally calls : https://github.com/xormplus/xorm/blob/master/session_schema.go#L236
whenever it wants to connect to the DB and to determine whether the table needs to be created or not.
This query is long running seems to cause time outs on our end.

Question - Is there any way I can specify casbin to NOT create the tables and assume that the table is created and skip this call altogether ?
Or is there any other way we can work around the time outs?

Thank You!

Is it necessary to add 'p_type' tag to compatible the old version?

Two days ago I have a pr improve , and it has been merged.

On line 28:

Ptype string xorm:"varchar(100) index"

would not compatible the old version if someone upgrade production envrionment with data.

And is it necessary add to add a tag:

Ptype string xorm:"varchar(100) index 'p_type'"

or refactor Ptype to PType in the whole file.

I'm releally so sorry.

Connect to specific table

How do I connect to a specific table inside an sqlite database?
adapter := xormadapter.NewAdapter("sqlite3", "./database.db", true) connects successfully with my sqlite database, but creates a default table casbin_rules.

adapter := xormadapter.NewAdapter("sqlite3", "./database.db/mytable", true) unfortunately interprets database.db as directory.

I want to store a policy in DB each time.

In the current implementation, I think that the table is deleted every time when saving the policy information in the DB.

Then, errors will occur when we save policies at the same time. I want to make CRUD on a line by line basis, make the range of competition as narrow as possible and make it possible to roll back.

That is, I want to insert or delete policy information every time when adding policy information.
Do you plan to prepare such interfaces with casbin?

Missing method UpdateFilteredPolicies

I am using xorm-adapter and mysql together to update policy and group policy, but here the error occurred:

panic: interface conversion: *xormadapter.Adapter is not persist.UpdatableAdapter: missing method UpdateFilteredPolicies
goroutine 1 [running]:
github.com/casbin/casbin/v2.(*Enforcer).updatePolicy(0xc000132e00, 0x867e9b, 0x1, 0x867e9b, 0x1, 0xc0000c69e0, 0x2, 0x2, 0xc0000c6a00, 0x2, ...)
/usr/local/go/bin/pkg/mod/github.com/casbin/casbin/[email protected]/internal_api.go:159 +0x459
github.com/casbin/casbin/v2.(*Enforcer).UpdateNamedGroupingPolicy(...)
/usr/local/go/bin/pkg/mod/github.com/casbin/casbin/[email protected]/management_api.go:322
github.com/casbin/casbin/v2.(*Enforcer).UpdateGroupingPolicy(0xc000132e00, 0xc0000c69e0, 0x2, 0x2, 0xc0000c6a00, 0x2, 0x2, 0xc0000bf700, 0x0, 0x0)
/usr/local/go/bin/pkg/mod/github.com/casbin/casbin/[email protected]/management_api.go:318 +0xa5

And if I use a csv file above is not happened.

panic: interface conversion: *xormadapter.Adapter is not persist.Adapter: missing method LoadPolicy

package main

import (
	"github.com/casbin/casbin/v2"
	_ "github.com/go-sql-driver/mysql"

	"github.com/casbin/xorm-adapter"
)

func main() {
	// Initialize a Xorm 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.
	a, _ := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/") // Your driver and data source. 

	// 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 := xormadapter.NewAdapter("mysql", "mysql_username:mysql_password@tcp(127.0.0.1:3306)/abc", true)

	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()
}
panic: interface conversion: *xormadapter.Adapter is not persist.Adapter: missing method LoadPolicy

goroutine 1 [running]:
github.com/casbin/casbin/v2.NewEnforcer(0xc00012bf00, 0x2, 0x2, 0x1c, 0x0, 0x0)
        /home/char/go/pkg/mod/github.com/casbin/casbin/[email protected]/enforcer.go:84 +0x143
main.main()
        /home/char/Documents/nova/dingyue/authorization/test/adapter/xorm.go:23 +0xde

Uncaught network connection error

If a Postgres database is not available on the specified port/host, adapter panics with

panic: interface conversion: error is *net.OpError, not *pq.Error

goroutine 1 [running]:
github.com/cgpaas/casbin/vendor/github.com/casbin/xorm-adapter.(*Adapter).createDatabase(0xc000122000, 0x0, 0x0)
	/go/src/github.com/cgpaas/casbin/vendor/github.com/casbin/xorm-adapter/adapter.go:93 +0x30c
github.com/cgpaas/casbin/vendor/github.com/casbin/xorm-adapter.(*Adapter).open(0xc000122000)
	/go/src/github.com/cgpaas/casbin/vendor/github.com/casbin/xorm-adapter/adapter.go:113 +0xc6
github.com/cgpaas/casbin/vendor/github.com/casbin/xorm-adapter.NewAdapter(0x857f52, 0x8, 0xc0000f82d0, 0x47, 0x0, 0x0, 0x0, 0x850fc0)
	/go/src/github.com/cgpaas/casbin/vendor/github.com/casbin/xorm-adapter/adapter.go:69 +0x8f

There could be a handler for this case with a helpful error message

the func SavePolicy will drop table?

xorm-adapter/adapter.go

Lines 226 to 249 in 9b17d80

// SavePolicy saves policy to database.
func (a *Adapter) SavePolicy(model model.Model) error {
a.dropTable()
a.createTable()
var lines []CasbinRule
for ptype, ast := range model["p"] {
for _, rule := range ast.Policy {
line := savePolicyLine(ptype, rule)
lines = append(lines, line)
}
}
for ptype, ast := range model["g"] {
for _, rule := range ast.Policy {
line := savePolicyLine(ptype, rule)
lines = append(lines, line)
}
}
_, err := a.engine.Insert(&lines)
return err
}

the func SavePolicy will drop table?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.