go vendor

This commit is contained in:
lealife
2017-11-30 19:55:33 +08:00
parent 2856da6888
commit 0fb92efbf3
670 changed files with 199010 additions and 0 deletions

53
vendor/github.com/revel/modules/auth/casbin/README.md generated vendored Normal file
View File

@@ -0,0 +1,53 @@
modules/casbin
======
Casbin authz is an authorization middleware for [Revel](https://github.com/revel/revel), it's based on [https://github.com/casbin/casbin](https://github.com/casbin/casbin).
## Simple Example
```Go
package main
import (
"net/http"
"net/http/httptest"
"github.com/casbin/casbin"
"github.com/revel/revel"
"github.com/revel/modules/auth/casbin"
)
var adapter = casbinauth.NewAdapter(params)
var enforcer = casbin.NewEnforcer("authz_model.conf", adapter)
var casbinModule = casbinauth.NewCasbinModule(enforcer)
var testFilters = []revel.Filter{
casbinModule.AuthzFilter,
func(c *revel.Controller, fc []revel.Filter) {
c.RenderHTML("OK.")
},
}
func main() {
r, _ := http.NewRequest("GET", "/dataset1/resource1", nil)
r.SetBasicAuth("alice", "123")
w := httptest.NewRecorder()
context := revel.NewGoContext(nil)
context.Request.SetRequest(r)
context.Response.SetResponse(w)
c := revel.NewController(context)
testFilters[0](c, testFilters)
}
```
## Documentation
The authorization determines a request based on ``{subject, object, action}``, which means what ``subject`` can perform what ``action`` on what ``object``. In this plugin, the meanings are:
1. ``subject``: the logged-on user name
2. ``object``: the URL path for the web resource like "dataset1/item1"
3. ``action``: HTTP method like GET, POST, PUT, DELETE, or the high-level actions you defined like "read-file", "write-blog"
For how to write authorization policy and other details, please refer to [the Casbin's documentation](https://github.com/casbin/casbin).

162
vendor/github.com/revel/modules/auth/casbin/adapter.go generated vendored Normal file
View File

@@ -0,0 +1,162 @@
package casbinauthz
import (
"errors"
"github.com/casbin/casbin/model"
"github.com/casbin/casbin/persist"
"github.com/jinzhu/gorm"
"github.com/revel/modules/orm/gorm/app"
)
type Line struct {
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"`
}
// Adapter represents the Gorm adapter for policy storage.
type Adapter struct {
driverName string
dataSourceName string
db *gorm.DB
}
// NewAdapter is the constructor for Adapter.
func NewAdapter(params gormdb.DbInfo) *Adapter {
a := &Adapter{}
gormdb.InitDBWithParameters(params)
a.db = gormdb.DB
return a
}
func (a *Adapter) createTable() {
if a.db.HasTable(&Line{}) {
return
}
err := a.db.CreateTable(&Line{}).Error
if err != nil {
panic(err)
}
}
func (a *Adapter) dropTable() {
err := a.db.DropTable(&Line{}).Error
if err != nil {
panic(err)
}
}
func loadPolicyLine(line Line, model model.Model) {
lineText := line.PType
if line.V0 != "" {
lineText += ", " + line.V0
}
if line.V1 != "" {
lineText += ", " + line.V1
}
if line.V2 != "" {
lineText += ", " + line.V2
}
if line.V3 != "" {
lineText += ", " + line.V3
}
if line.V4 != "" {
lineText += ", " + line.V4
}
if line.V5 != "" {
lineText += ", " + line.V5
}
persist.LoadPolicyLine(lineText, model)
}
// LoadPolicy loads policy from database.
func (a *Adapter) LoadPolicy(model model.Model) error {
var lines []Line
err := a.db.Find(&lines).Error
if err != nil {
return err
}
for _, line := range lines {
loadPolicyLine(line, model)
}
return nil
}
func savePolicyLine(ptype string, rule []string) Line {
line := Line{}
line.PType = ptype
if len(rule) > 0 {
line.V0 = rule[0]
}
if len(rule) > 1 {
line.V1 = rule[1]
}
if len(rule) > 2 {
line.V2 = rule[2]
}
if len(rule) > 3 {
line.V3 = rule[3]
}
if len(rule) > 4 {
line.V4 = rule[4]
}
if len(rule) > 5 {
line.V5 = rule[5]
}
return line
}
// SavePolicy saves policy to database.
func (a *Adapter) SavePolicy(model model.Model) error {
a.dropTable()
a.createTable()
for ptype, ast := range model["p"] {
for _, rule := range ast.Policy {
line := savePolicyLine(ptype, rule)
err := a.db.Create(&line).Error
if err != nil {
return err
}
}
}
for ptype, ast := range model["g"] {
for _, rule := range ast.Policy {
line := savePolicyLine(ptype, rule)
err := a.db.Create(&line).Error
if err != nil {
return err
}
}
}
return nil
}
// 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")
}

49
vendor/github.com/revel/modules/auth/casbin/authz.go generated vendored Normal file
View File

@@ -0,0 +1,49 @@
package casbinauthz
import (
"net/http"
"github.com/casbin/casbin"
"github.com/revel/revel"
)
type CasbinModule struct {
enforcer *casbin.Enforcer
}
func NewCasbinModule(enforcer *casbin.Enforcer) *CasbinModule {
cm := &CasbinModule{}
cm.enforcer = enforcer
return cm
}
// AuthzFilter enables the authorization based on Casbin.
//
// Usage:
// 1) Add `casbin.AuthzFilter` to the app's filters (it must come after the authentication).
// 2) Init the Casbin enforcer.
func (cm *CasbinModule) AuthzFilter(c *revel.Controller, fc []revel.Filter) {
if !CheckPermission(cm.enforcer, c.Request) {
c.Result = c.Forbidden("Access denied by the Authz plugin.")
return
} else {
fc[0](c, fc[1:])
}
}
// GetUserName gets the user name from the request.
// Currently, only HTTP basic authentication is supported
func GetUserName(r *revel.Request) string {
req := r.In.GetRaw().(*http.Request)
username, _, _ := req.BasicAuth()
return username
}
// CheckPermission checks the user/method/path combination from the request.
// Returns true (permission granted) or false (permission forbidden)
func CheckPermission(e *casbin.Enforcer, r *revel.Request) bool {
user := GetUserName(r)
method := r.Method
path := r.URL.Path
return e.Enforce(user, path, method)
}

View File

@@ -0,0 +1,14 @@
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")

View File

@@ -0,0 +1,7 @@
p, alice, /dataset1/*, GET
p, alice, /dataset1/resource1, POST
p, bob, /dataset2/resource1, *
p, bob, /dataset2/resource2, GET
p, bob, /dataset2/folder1/*, POST
p, dataset1_admin, /dataset1/*, *
g, cathy, dataset1_admin
1 p, alice, /dataset1/*, GET
2 p, alice, /dataset1/resource1, POST
3 p, bob, /dataset2/resource1, *
4 p, bob, /dataset2/resource2, GET
5 p, bob, /dataset2/folder1/*, POST
6 p, dataset1_admin, /dataset1/*, *
7 g, cathy, dataset1_admin

View File

@@ -0,0 +1,129 @@
package casbinauthz
import (
"log"
"net/http"
"net/http/httptest"
"testing"
"github.com/casbin/casbin"
"github.com/casbin/casbin/util"
_ "github.com/go-sql-driver/mysql"
"github.com/revel/revel"
"github.com/revel/modules/orm/gorm/app"
)
var adapter = NewAdapter(DefaultDbParams())
var enforcer = casbin.NewEnforcer("authz_model.conf", adapter)
var casbinModule = NewCasbinModule(enforcer)
var testFilters = []revel.Filter{
casbinModule.AuthzFilter,
func(c *revel.Controller, fc []revel.Filter) {
c.RenderHTML("OK.")
},
}
func DefaultDbParams() gormdb.DbInfo {
params := gormdb.DbInfo{}
params.DbDriver = "mysql"
params.DbHost = "(localhost:3306)"
params.DbUser = "root"
params.DbPassword = ""
params.DbName = "casbin"
return params
}
func testRequest(t *testing.T, user string, path string, method string, code int) {
r, _ := http.NewRequest(method, path, nil)
r.SetBasicAuth(user, "123")
w := httptest.NewRecorder()
context := revel.NewGoContext(nil)
context.Request.SetRequest(r)
context.Response.SetResponse(w)
c := revel.NewController(context)
testFilters[0](c, testFilters)
if c.Response.Status != code {
t.Errorf("%s, %s, %s: %d, supposed to be %d", user, path, method, c.Response.Status, code)
}
}
func testGetPolicy(t *testing.T, e *casbin.Enforcer, res [][]string) {
myRes := e.GetPolicy()
log.Print("Policy: ", myRes)
if !util.Array2DEquals(res, myRes) {
t.Error("Policy: ", myRes, ", supposed to be ", res)
}
}
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("authz_model.conf", "authz_policy.csv")
a := NewAdapter(DefaultDbParams())
// 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)
}
}
func TestBasic(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.
testRequest(t, "alice", "/dataset1/resource1", "GET", 200)
testRequest(t, "alice", "/dataset1/resource1", "POST", 200)
testRequest(t, "alice", "/dataset1/resource2", "GET", 200)
testRequest(t, "alice", "/dataset1/resource2", "POST", 403)
}
func TestPathWildcard(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.
testRequest(t, "bob", "/dataset2/resource1", "GET", 200)
testRequest(t, "bob", "/dataset2/resource1", "POST", 200)
testRequest(t, "bob", "/dataset2/resource1", "DELETE", 200)
testRequest(t, "bob", "/dataset2/resource2", "GET", 200)
testRequest(t, "bob", "/dataset2/resource2", "POST", 403)
testRequest(t, "bob", "/dataset2/resource2", "DELETE", 403)
testRequest(t, "bob", "/dataset2/folder1/item1", "GET", 403)
testRequest(t, "bob", "/dataset2/folder1/item1", "POST", 200)
testRequest(t, "bob", "/dataset2/folder1/item1", "DELETE", 403)
testRequest(t, "bob", "/dataset2/folder1/item2", "GET", 403)
testRequest(t, "bob", "/dataset2/folder1/item2", "POST", 200)
testRequest(t, "bob", "/dataset2/folder1/item2", "DELETE", 403)
}
func TestRBAC(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.
// cathy can access all /dataset1/* resources via all methods because it has the dataset1_admin role.
testRequest(t, "cathy", "/dataset1/item", "GET", 200)
testRequest(t, "cathy", "/dataset1/item", "POST", 200)
testRequest(t, "cathy", "/dataset1/item", "DELETE", 200)
testRequest(t, "cathy", "/dataset2/item", "GET", 403)
testRequest(t, "cathy", "/dataset2/item", "POST", 403)
testRequest(t, "cathy", "/dataset2/item", "DELETE", 403)
}