diff --git a/README.md b/README.md index ee6c29f..7161570 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,10 @@ -Go-pg Adapter -==== +# Go-pg Adapter Go-pg Adapter is the [Go-pg](https://github.com/go-pg/pg) adapter for [Casbin](https://github.com/casbin/casbin). With this library, Casbin can load policy from PostgreSQL or save policy to it. ## Installation - go get github.com/MonedaCacao/casbin-pg-adapter - -## Env Variables - -Populate .env with necessary environment variable values: - - $ nano .env - -``` -DATABASE_ADDRESSES= -DATABASE_USER_NAME= -DATABSE_USER_PASSORD= -``` + go get github.com/pckhoi/casbin-pg-adapter ## Simple Postgres Example @@ -25,7 +12,9 @@ DATABSE_USER_PASSORD= package main import ( - pgadapter "github.com/MonedaCacao/casbin-pg-adapter" + "os" + + pgadapter "github.com/pckhoi/casbin-pg-adapter" "github.com/casbin/casbin" ) @@ -33,7 +22,7 @@ func main() { // Initialize a Go-pg 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, _ := pgadapter.NewAdapter() // Your driver and data source. + a, _ := pgadapter.NewAdapter(os.Getenv("PG_CONN")) // Your driver and data source. // Or you can use an existing DB "abc" like this: // The adapter will use the table named "casbin_rule". @@ -58,7 +47,7 @@ func main() { ## Getting Help -- [Casbin](https://github.com/casbin/casbin) +- [Casbin](https://github.com/casbin/casbin) ## License diff --git a/adapter.go b/adapter.go index a21ce62..7eade0d 100644 --- a/adapter.go +++ b/adapter.go @@ -1,13 +1,14 @@ package pgadapter import ( - "github.com/MonedaCacao/casbin-pg-adapter/config" - "github.com/casbin/casbin/model" - "github.com/casbin/casbin/persist" - "github.com/go-pg/pg" - "github.com/go-pg/pg/orm" - "log" + "fmt" "strings" + + "github.com/casbin/casbin/v2/model" + "github.com/casbin/casbin/v2/persist" + "github.com/go-pg/pg/v9" + "github.com/go-pg/pg/v9/orm" + "golang.org/x/crypto/sha3" ) const ( @@ -16,7 +17,7 @@ const ( // CasbinRule represents a rule in Casbin. type CasbinRule struct { - Id int + ID string PType string V0 string V1 string @@ -35,74 +36,55 @@ type Adapter struct { func finalizer(a *Adapter) {} // NewAdapter is the constructor for Adapter. -// The adapter will automatically create a DB named "casbin" -func NewAdapter() (*Adapter, error) { - a := Adapter{} - - // Open the DB, create it if not existed. - err := a.open() +// arg should be a PostgreS URL string or of type *pg.Options +// The adapter will create a DB named "casbin" if it doesn't exist +func NewAdapter(arg interface{}) (*Adapter, error) { + db, err := createCasbinDatabase(arg) if err != nil { - return nil, err + return nil, fmt.Errorf("pgadapter.NewAdapter: %v", err) } - return &a, nil -} - -func (a *Adapter) createDatabase() error { - var err error - var db *pg.DB - - env := config.GetEnvVariables() - cfg := config.GetConfig(*env) + a := &Adapter{db: db} - db = pg.Connect(&pg.Options{ - Addr: cfg.DatabaseAddresses, - User: cfg.DatabaseUsername, - Password: cfg.DatabseUserPassord, - }) - - defer db.Close() - - _, err = db.Exec("CREATE DATABASE casbin") - if err != nil { - log.Println("can't create database", err) - return err + if err := a.createTable(); err != nil { + return nil, fmt.Errorf("pgadapter.NewAdapter: %v", err) } - return nil + return a, nil } -func (a *Adapter) open() error { +func createCasbinDatabase(arg interface{}) (*pg.DB, error) { + var opts *pg.Options var err error - var db *pg.DB - - env := config.GetEnvVariables() - cfg := config.GetConfig(*env) - - err = a.createDatabase() - if err != nil { - panic(err) + if connURL, ok := arg.(string); ok { + opts, err = pg.ParseURL(connURL) + if err != nil { + return nil, err + } + } else { + opts, ok = arg.(*pg.Options) + if !ok { + return nil, fmt.Errorf("must pass in a PostgreS URL string or an instance of *pg.Options, received %T instead", arg) + } } - db = pg.Connect(&pg.Options{ - Addr: cfg.DatabaseAddresses, - User: cfg.DatabaseUsername, - Password: cfg.DatabseUserPassord, - Database: "casbin", - }) + db := pg.Connect(opts) + defer db.Close() - a.db = db + _, err = db.Exec("CREATE DATABASE casbin") + db.Close() + + opts.Database = "casbin" + db = pg.Connect(opts) - return a.createTable() + return db, nil } -func (a *Adapter) close() error { - err := a.db.Close() - if err != nil { - return err +// Close close database connection +func (a *Adapter) Close() error { + if a != nil && a.db != nil { + return a.db.Close() } - - a.db = nil return nil } @@ -119,15 +101,6 @@ func (a *Adapter) createTable() error { return nil } -func (a *Adapter) dropTable() error { - err := a.db.DropTable(&CasbinRule{}, &orm.DropTableOptions{}) - if err != nil { - return err - } - - return nil -} - func loadPolicyLine(line *CasbinRule, model model.Model) { const prefixLine = ", " var sb strings.Builder @@ -199,20 +172,16 @@ func savePolicyLine(ptype string, rule []string) *CasbinRule { line.V5 = rule[5] } + data := strings.Join(append([]string{ptype}, rule...), ",") + sum := make([]byte, 64) + sha3.ShakeSum128(sum, []byte(data)) + line.ID = fmt.Sprintf("%x", sum) + return line } // 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 - } - var lines []*CasbinRule for ptype, ast := range model["p"] { @@ -229,14 +198,18 @@ func (a *Adapter) SavePolicy(model model.Model) error { } } - err = a.db.Insert(&lines) + _, err := a.db.Model(&lines). + OnConflict("DO NOTHING"). + Insert() return err } // AddPolicy adds a policy rule to the storage. func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error { line := savePolicyLine(ptype, rule) - err := a.db.Insert(line) + _, err := a.db.Model(line). + OnConflict("DO NOTHING"). + Insert() return err } diff --git a/adapter_test.go b/adapter_test.go index 28f9cd7..99754ae 100644 --- a/adapter_test.go +++ b/adapter_test.go @@ -1,106 +1,91 @@ package pgadapter import ( - "github.com/casbin/casbin" - "github.com/casbin/casbin/util" - "log" + "os" "testing" + + "github.com/casbin/casbin/v2" + "github.com/casbin/casbin/v2/util" + "github.com/go-pg/pg/v9" + "github.com/stretchr/testify/suite" ) -func testGetPolicy(t *testing.T, e *casbin.Enforcer, res [][]string) { - t.Helper() - myRes := e.GetPolicy() - log.Print("Policy Got: ", myRes) +// AdapterTestSuite tests all functionalities of Adapter +type AdapterTestSuite struct { + suite.Suite + e *casbin.Enforcer + a *Adapter +} + +func (s *AdapterTestSuite) testGetPolicy(res [][]string) { + myRes := s.e.GetPolicy() + s.Assert().True(util.Array2DEquals(res, myRes), "Policy Got: %v, supposed to be %v", myRes, res) +} - if !util.Array2DEquals(res, myRes) { - t.Error("Policy Got: ", myRes, ", supposed to be ", res) - } +func (s *AdapterTestSuite) dropCasbinDB() { + opts, err := pg.ParseURL(os.Getenv("PG_CONN")) + s.Require().NoError(err) + db := pg.Connect(opts) + defer db.Close() + _, err = db.Exec("DROP DATABASE casbin") + s.Require().NoError(err) } -func initPolicy(t *testing.T) { - // Because the DB is empty at first, - // so we need to load the policy from the file adapter (.CSV) first. - e := casbin.NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv") +func (s *AdapterTestSuite) SetupTest() { + s.dropCasbinDB() - a, err := NewAdapter() - if err != nil { - panic(err) - } + var err error + s.a, err = NewAdapter(os.Getenv("PG_CONN")) + s.Require().NoError(err) // This is a trick to save the current policy to the DB. // We can't call e.SavePolicy() because the adapter in the enforcer is still the file adapter. // The current policy means the policy in the Casbin enforcer (aka in memory). - err = a.SavePolicy(e.GetModel()) - if err != nil { - panic(err) - } - - // Clear the current policy. - e.ClearPolicy() - testGetPolicy(t, e, [][]string{}) - - // Load the policy from DB. - err = a.LoadPolicy(e.GetModel()) - if err != nil { - panic(err) - } - testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}}) -} + s.e, err = casbin.NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv") + s.Require().NoError(err) + err = s.a.SavePolicy(s.e.GetModel()) + s.Require().NoError(err) -func testSaveLoad(t *testing.T) { - // Initialize some policy in DB. - initPolicy(t) - // Note: you don't need to look at the above code - // if you already have a working DB with policy inside. - - // Now the DB has policy, so we can provide a normal use case. - // Create an adapter and an enforcer. - // NewEnforcer() will load the policy automatically. - a, _ := NewAdapter() - e := casbin.NewEnforcer("examples/rbac_model.conf", a) - testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}}) + s.e, err = casbin.NewEnforcer("examples/rbac_model.conf", s.a) + s.Require().NoError(err) } -func testAutoSave(t *testing.T) { - // Initialize some policy in DB. - initPolicy(t) - // Note: you don't need to look at the above code - // if you already have a working DB with policy inside. +func (s *AdapterTestSuite) TearDownTest() { + err := s.a.Close() + s.Require().NoError(err) +} - // Now the DB has policy, so we can provide a normal use case. - // Create an adapter and an enforcer. - // NewEnforcer() will load the policy automatically. - a, _ := NewAdapter() - e := casbin.NewEnforcer("examples/rbac_model.conf", a) +func (s *AdapterTestSuite) TestSaveLoad() { + s.testGetPolicy([][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}}) +} +func (s *AdapterTestSuite) TestAutoSave() { // AutoSave is enabled by default. // Now we disable it. - e.EnableAutoSave(false) + s.e.EnableAutoSave(false) // Because AutoSave is disabled, the policy change only affects the policy in Casbin enforcer, // it doesn't affect the policy in the storage. - e.AddPolicy("alice", "data1", "write") + _, err := s.e.AddPolicy("alice", "data1", "write") + s.Require().NoError(err) // Reload the policy from the storage to see the effect. - e.LoadPolicy() + err = s.e.LoadPolicy() + s.Require().NoError(err) // This is still the original policy. - testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}}) + s.testGetPolicy([][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}}) // Now we enable the AutoSave. - e.EnableAutoSave(true) + s.e.EnableAutoSave(true) // Because AutoSave is enabled, the policy change not only affects the policy in Casbin enforcer, // but also affects the policy in the storage. - e.AddPolicy("alice", "data1", "write") + s.e.AddPolicy("alice", "data1", "write") // Reload the policy from the storage to see the effect. - e.LoadPolicy() + s.e.LoadPolicy() // The policy has a new rule: {"alice", "data1", "write"}. - testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}, {"alice", "data1", "write"}}) - testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}, {"alice", "data1", "write"}}) + s.testGetPolicy([][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}, {"alice", "data1", "write"}}) } -func TestAdapters(t *testing.T) { - // You can also use the following way to use an existing DB "abc": - testSaveLoad(t) - - testAutoSave(t) +func TestAdapterTestSuite(t *testing.T) { + suite.Run(t, new(AdapterTestSuite)) } diff --git a/config/config.go b/config/config.go deleted file mode 100644 index a1ce09b..0000000 --- a/config/config.go +++ /dev/null @@ -1,91 +0,0 @@ -package config - -import ( - "os" - "path/filepath" - - log "github.com/inconshreveable/log15" - "github.com/spf13/viper" -) - -// Config contains the config.yml settings -type Config struct { - DatabaseAddresses string - DatabaseUsername string - DatabseUserPassord string - Database string -} - -// Env contains the environment variables -type Env struct { - Environment string - DatabasePassword string - ProjectRootPath string -} - -// GetEnvVariables gets the environment variables and returns a new env struct -func GetEnvVariables() *Env { - viper.AutomaticEnv() - viper.SetDefault("go_env", "development") - viper.SetDefault("database_password", "") - - // Get the current environment - environment := viper.GetString("go_env") - - log.Info("Initializing", "ENVIROMENT", environment) - - // Get the enviroment variables - log.Info("Obtaining env variables") - databasePassword := viper.GetString("database_password") - - env := &Env{ - Environment: environment, - DatabasePassword: databasePassword, - // Secret: secret, - } - - return env -} - -// GetConfig reads the configuration file and returns a new config -func GetConfig(env Env) *Config { - viper.SetConfigName("config") - viper.SetConfigType("yaml") - viper.AddConfigPath(".") - viper.AddConfigPath(env.ProjectRootPath) - - log.Info("Reading config file") - err := viper.ReadInConfig() - if err != nil { - log.Error("Missing configuration file.", "Error:", err) - os.Exit(1) - } - - var config Config - - err = viper.UnmarshalKey(env.Environment, &config) - if err != nil { - panic("Unable to unmarshal config") - } - - return &config -} - -// GetTestingEnvVariables returns env variables for testing -func GetTestingEnvVariables() *Env { - - wd, err := os.Getwd() - if err != nil { - panic(err) - } - - // Since we are loading configuration files from the root dir, when running from main package - // this is fine but for testing we need to find the root dir - dir := filepath.Dir(wd) - - for dir[len(dir)-24:] != "gopg-casbin-adapter" { - dir = filepath.Dir(dir) - } - - return &Env{Environment: "test", ProjectRootPath: dir} -} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..428543a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +--- +version: "3.4" +services: + postgres: + image: postgres:12 + ports: + - 5432:5432 + environment: + - POSTGRES_PASSWORD=password + go: + build: + context: ./go + depends_on: + - postgres + environment: + - PG_CONN=postgresql://postgres:password@postgres:5432/postgres?sslmode=disable + volumes: + - .:/app + - gopkg:/go/pkg + working_dir: /app + command: + - go + - test + - github.com/pckhoi/casbin-pg-adapter + +volumes: + gopkg: diff --git a/env-sample.txt b/env-sample.txt deleted file mode 100644 index de60b6f..0000000 --- a/env-sample.txt +++ /dev/null @@ -1,3 +0,0 @@ -DATABASE_ADDRESSES= -DATABASE_USER_NAME= -DATABSE_USER_PASSORD= \ No newline at end of file diff --git a/go.mod b/go.mod index cfb9032..b7a040a 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,11 @@ -module github.com/MonedaCacao/casbin-pg-adapter +module github.com/pckhoi/casbin-pg-adapter go 1.12 require ( github.com/casbin/casbin v1.9.1 - github.com/go-pg/pg v8.0.5+incompatible - github.com/inconshreveable/log15 v0.0.0-20180818164646-67afb5ed74ec - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/mattn/go-colorable v0.1.2 // indirect - github.com/onsi/ginkgo v1.8.0 // indirect - github.com/onsi/gomega v1.5.0 // indirect - github.com/spf13/viper v1.4.0 - mellium.im/sasl v0.2.1 // indirect + github.com/casbin/casbin/v2 v2.1.2 + github.com/go-pg/pg/v9 v9.1.0 + github.com/stretchr/testify v1.4.0 + golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 ) diff --git a/go.sum b/go.sum index 0d74cb6..947e917 100644 --- a/go.sum +++ b/go.sum @@ -11,13 +11,19 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM= github.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog= +github.com/casbin/casbin/v2 v2.1.2 h1:bTwon/ECRx9dwBy2ewRVr5OiqjeXSGiTUY74sDPQi/g= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/codemodus/kace v0.5.1 h1:4OCsBlE2c/rSJo375ggfnucv9eRzge/U5LrrOZd47HA= +github.com/codemodus/kace v0.5.1/go.mod h1:coddaHoX1ku1YFSe4Ip0mL9kQjJvKkzb9CfIdG1YR04= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -30,6 +36,17 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-pg/pg v8.0.5+incompatible h1:+USAV4GOW4mlX1tt1DsEQ1ZSqVkrkDlPPG+t4DqzpAA= github.com/go-pg/pg v8.0.5+incompatible/go.mod h1:a2oXow+aFOrvwcKs3eIA0lNFmMilrxK2sOkB5NWe0vA= +github.com/go-pg/pg v8.0.6+incompatible h1:Hi7yUJ2zwmHFq1Mar5XqhCe3NJ7j9r+BaiNmd+vqf+A= +github.com/go-pg/pg/v9 v9.0.0-beta.14/go.mod h1:T2Sr6bpTCOr2lUqOUMiXLMJqZHSUBKk1LdgSqjwhZfA= +github.com/go-pg/pg/v9 v9.0.3/go.mod h1:Tm/Q3Vt6gdQOH6TTN1H/xLlIXc+Qrka7TZ6uREtu/eA= +github.com/go-pg/pg/v9 v9.1.0 h1:yRXwMxYpbT3IxYZndQ2M2pTVGpV3ba9kbLcDVn51gew= +github.com/go-pg/pg/v9 v9.1.0/go.mod h1:R3slXUnppC1am3XiioEeszbPnU6uAzGHipxNyvpfpr4= +github.com/go-pg/urlstruct v0.1.0/go.mod h1:2Nag+BIny6G/KYCkdt++ZnqU/VinzimGapKfs4kwlN0= +github.com/go-pg/urlstruct v0.2.6/go.mod h1:dxENwVISWSOX+k87hDt0ueEJadD+gZWv3tHzwfmZPu8= +github.com/go-pg/urlstruct v0.2.8 h1:pasKiKzYyAtJ9YEpGe6G+3PB0M5Ez0qsMtjSA3gsw/g= +github.com/go-pg/urlstruct v0.2.8/go.mod h1:/XKyiUOUUS3onjF+LJxbfmSywYAdl6qMfVbX33Q8rgg= +github.com/go-pg/zerochecker v0.1.1 h1:av77Qe7Gs+1oYGGh51k0sbZ0bUaxJEdeP0r8YE64Dco= +github.com/go-pg/zerochecker v0.1.1/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -40,6 +57,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -74,13 +92,17 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mmcloughlin/meow v0.0.0-20181112033425-871e50784daf h1:bD6uvpTs5gpzCesUWCGmlEUnU2OINvCQHri8geYwuv0= +github.com/mmcloughlin/meow v0.0.0-20181112033425-871e50784daf/go.mod h1:uxCZJI8Z1PD2WRnSJtVJGHCyxC5qWhz5lOsx3Bx1NXo= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -109,11 +131,17 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/vmihailenco/tagparser v0.1.0/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -124,6 +152,11 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -131,8 +164,11 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -146,10 +182,17 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -160,6 +203,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -169,6 +213,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= mellium.im/sasl v0.2.1 h1:nspKSRg7/SyO0cRGY71OkfHab8tf9kCts6a6oTDut0w= mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= diff --git a/go/Dockerfile b/go/Dockerfile new file mode 100644 index 0000000..8a7c4ab --- /dev/null +++ b/go/Dockerfile @@ -0,0 +1,9 @@ +FROM golang:1.13-alpine + +RUN apk add --no-cache make git curl build-base tar + +RUN git clone https://github.com/go-delve/delve.git /go/src/github.com/go-delve/delve && \ + cd /go/src/github.com/go-delve/delve && \ + make install + +RUN go get golang.org/x/tools/cmd/godoc diff --git a/pgexample/main.go b/pgexample/main.go index a8ac057..64383f8 100644 --- a/pgexample/main.go +++ b/pgexample/main.go @@ -1,15 +1,17 @@ package main import ( - pgadapter "github.com/MonedaCacao/casbin-pg-adapter" + "os" + "github.com/casbin/casbin" + pgadapter "github.com/pckhoi/casbin-pg-adapter" ) func main() { // Initialize a Go-pg 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, _ := pgadapter.NewAdapter() // Your driver and data source. + a, _ := pgadapter.NewAdapter(os.Getenv("PG_CONN")) // Your driver and data source. // Or you can use an existing DB "abc" like this: // The adapter will use the table named "casbin_rule".