This commit is contained in:
Mathieu Leplatre 2017-10-04 13:35:48 +02:00
Родитель 3c2cf1bd77
Коммит fbaee2e235
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 767B105F81A15CDD
7 изменённых файлов: 57 добавлений и 57 удалений

Просмотреть файл

@ -2,8 +2,8 @@ GO_LINT := $(GOPATH)/bin/golint
GO_GLIDE := $(GOPATH)/bin/glide
GO_BINDATA := $(GOPATH)/bin/go-bindata
DATA_FILES := ./utilities/openapi.yaml ./utilities/contribute.yaml
SRC := *.go ./utilities/*.go ./warden/*.go
PACKAGES := ./ ./utilities/ ./warden/
SRC := *.go ./utilities/*.go ./doorman/*.go
PACKAGES := ./ ./utilities/ ./doorman/
main: vendor utilities/bindata.go $(SRC)
CGO_ENABLED=0 go build -o main *.go

Просмотреть файл

@ -1,4 +1,4 @@
package warden
package doorman
import (
"encoding/json"
@ -20,30 +20,30 @@ import (
// DefaultPoliciesFilename is the default policies filename.
const DefaultPoliciesFilename string = "policies.yaml"
// ContextKey is the Gin context key to obtain the *Warden instance.
const ContextKey string = "warden"
// ContextKey is the Gin context key to obtain the *Doorman instance.
const ContextKey string = "doorman"
const maxInt int64 = 1<<63 - 1
// Config contains the settings of the warden.
// Config contains the settings of the doorman.
type Config struct {
PoliciesFilename string
JWTIssuer string
}
// Warden is the backend in charge of checking requests against policies.
type Warden struct {
// Doorman is the backend in charge of checking requests against policies.
type Doorman struct {
l ladon.Ladon
Manager ladon.Manager
Config *Config
}
// New instantiates a new warden.
func New(config *Config) *Warden {
// New instantiates a new doorman.
func New(config *Config) *Doorman {
l := ladon.Ladon{
Manager: manager.NewMemoryManager(),
}
w := &Warden{l, l.Manager, config}
w := &Doorman{l, l.Manager, config}
if err := w.LoadPolicies(config.PoliciesFilename); err != nil {
log.Fatal(err.Error())
}
@ -51,12 +51,12 @@ func New(config *Config) *Warden {
}
// IsAllowed is responsible for deciding if subject can perform action on a resource with a context.
func (warden *Warden) IsAllowed(request *ladon.Request) error {
return warden.l.IsAllowed(request)
func (doorman *Doorman) IsAllowed(request *ladon.Request) error {
return doorman.l.IsAllowed(request)
}
// LoadPolicies reads policies from the YAML file.
func (warden *Warden) LoadPolicies(filename string) error {
func (doorman *Doorman) LoadPolicies(filename string) error {
// If not specified, read it from ENV or read local `.policies.yaml`
if filename == "" {
filename = os.Getenv("POLICIES_FILE")
@ -95,19 +95,19 @@ func (warden *Warden) LoadPolicies(filename string) error {
}
// Clear every existing policy, and load new ones.
existing, err := warden.Manager.GetAll(0, maxInt)
existing, err := doorman.Manager.GetAll(0, maxInt)
if err != nil {
return err
}
for _, pol := range existing {
err := warden.Manager.Delete(pol.GetID())
err := doorman.Manager.Delete(pol.GetID())
if err != nil {
return err
}
}
for _, pol := range policies {
log.Info("Load policy ", pol.GetID()+": ", pol.GetDescription())
err := warden.Manager.Create(pol)
err := doorman.Manager.Create(pol)
if err != nil {
return err
}
@ -116,19 +116,19 @@ func (warden *Warden) LoadPolicies(filename string) error {
return nil
}
// ContextMiddleware adds the Warden instance to the Gin context.
func ContextMiddleware(warden *Warden) gin.HandlerFunc {
// ContextMiddleware adds the Doorman instance to the Gin context.
func ContextMiddleware(doorman *Doorman) gin.HandlerFunc {
return func(c *gin.Context) {
c.Set(ContextKey, warden)
c.Set(ContextKey, doorman)
c.Next()
}
}
// SetupRoutes adds warden views to query the policies.
func SetupRoutes(r *gin.Engine, warden *Warden) {
r.Use(ContextMiddleware(warden))
if warden.Config.JWTIssuer != "" {
r.Use(VerifyJWTMiddleware(warden.Config.JWTIssuer))
// SetupRoutes adds doorman views to query the policies.
func SetupRoutes(r *gin.Engine, doorman *Doorman) {
r.Use(ContextMiddleware(doorman))
if doorman.Config.JWTIssuer != "" {
r.Use(VerifyJWTMiddleware(doorman.Config.JWTIssuer))
}
r.POST("/allowed", allowedHandler)
}
@ -156,13 +156,13 @@ func allowedHandler(c *gin.Context) {
accessRequest.Subject = payloadJWT.(*jwt.Claims).Subject
}
warden := c.MustGet(ContextKey).(*Warden)
err := warden.IsAllowed(&accessRequest)
doorman := c.MustGet(ContextKey).(*Doorman)
err := doorman.IsAllowed(&accessRequest)
allowed := (err == nil)
// Show some debug information about matched policy.
if allowed && gin.Mode() != gin.ReleaseMode {
policies, _ := warden.Manager.FindRequestCandidates(&accessRequest)
policies, _ := doorman.Manager.FindRequestCandidates(&accessRequest)
matched := policies[0]
log.Debug("Policy matched ", matched.GetID()+": ", matched.GetDescription())
}

Просмотреть файл

@ -1,4 +1,4 @@
package warden
package doorman
import (
"bytes"
@ -38,28 +38,28 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
func loadTempFile(warden *Warden, content []byte) error {
func loadTempFile(doorman *Doorman, content []byte) error {
tmpfile, _ := ioutil.TempFile("", "")
defer os.Remove(tmpfile.Name()) // clean up
tmpfile.Write(content)
tmpfile.Close()
return warden.LoadPolicies(tmpfile.Name())
return doorman.LoadPolicies(tmpfile.Name())
}
func TestLoadPolicies(t *testing.T) {
warden := New(&Config{"../policies.yaml", ""})
doorman := New(&Config{"../policies.yaml", ""})
// Missing file
var err error
err = warden.LoadPolicies("/tmp/unknown.yaml")
err = doorman.LoadPolicies("/tmp/unknown.yaml")
assert.NotNil(t, err)
// Bad YAML
err = loadTempFile(warden, []byte("$\\--xx"))
err = loadTempFile(doorman, []byte("$\\--xx"))
assert.NotNil(t, err)
// Bad policies
err = loadTempFile(warden, []byte(`
err = loadTempFile(doorman, []byte(`
-
id: "1"
conditions:
@ -69,7 +69,7 @@ func TestLoadPolicies(t *testing.T) {
assert.NotNil(t, err)
// Duplicated ID
err = loadTempFile(warden, []byte(`
err = loadTempFile(doorman, []byte(`
-
id: "1"
effect: allow
@ -95,7 +95,7 @@ func performAllowed(t *testing.T, r *gin.Engine, body io.Reader, expected int, r
require.Nil(t, err)
}
func TestWardenGet(t *testing.T) {
func TestDoormanGet(t *testing.T) {
r := gin.New()
SetupRoutes(r, New(&defaultConfig))
@ -103,7 +103,7 @@ func TestWardenGet(t *testing.T) {
assert.Equal(t, w.Code, http.StatusNotFound)
}
func TestWardenEmpty(t *testing.T) {
func TestDoormanEmpty(t *testing.T) {
r := gin.New()
SetupRoutes(r, New(&defaultConfig))
@ -112,7 +112,7 @@ func TestWardenEmpty(t *testing.T) {
assert.Equal(t, response.Message, "Missing body")
}
func TestWardenInvalidJSON(t *testing.T) {
func TestDoormanInvalidJSON(t *testing.T) {
r := gin.New()
SetupRoutes(r, New(&defaultConfig))
@ -122,11 +122,11 @@ func TestWardenInvalidJSON(t *testing.T) {
assert.Contains(t, response.Message, "invalid character ';'")
}
func TestWardenAllowed(t *testing.T) {
func TestDoormanAllowed(t *testing.T) {
r := gin.New()
warden := New(&defaultConfig)
warden.LoadPolicies(samplePoliciesFile)
SetupRoutes(r, warden)
doorman := New(&defaultConfig)
doorman.LoadPolicies(samplePoliciesFile)
SetupRoutes(r, doorman)
for _, request := range []*ladon.Request{
// Policy #1
@ -180,11 +180,11 @@ func TestWardenAllowed(t *testing.T) {
}
}
func TestWardenNotAllowed(t *testing.T) {
func TestDoormanNotAllowed(t *testing.T) {
r := gin.New()
warden := New(&defaultConfig)
warden.LoadPolicies(samplePoliciesFile)
SetupRoutes(r, warden)
doorman := New(&defaultConfig)
doorman.LoadPolicies(samplePoliciesFile)
SetupRoutes(r, doorman)
for _, request := range []*ladon.Request{
// Policy #1

Просмотреть файл

@ -1,4 +1,4 @@
package warden
package doorman
import (
"net/http"

Просмотреть файл

@ -1,4 +1,4 @@
package warden
package doorman
import (
"net/http"
@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
)
// TestMain defined in warden_test.go
// TestMain defined in doorman_test.go
// func TestMain(m *testing.M) {}
func TestVerifyJWT(t *testing.T) {

10
main.go
Просмотреть файл

@ -9,7 +9,7 @@ import (
"go.mozilla.org/mozlogrus"
"github.com/leplatrem/iam/utilities"
"github.com/leplatrem/iam/warden"
"github.com/leplatrem/iam/doorman"
)
func init() {
@ -49,13 +49,13 @@ func setupRouter() *gin.Engine {
r.Use(gin.Logger())
}
// Setup warden with default config (read policies from disk)
config := &warden.Config{
// Setup doorman with default config (read policies from disk)
config := &doorman.Config{
PoliciesFilename: "",
JWTIssuer: os.Getenv("JWT_ISSUER"),
}
w := warden.New(config)
warden.SetupRoutes(r, w)
w := doorman.New(config)
doorman.SetupRoutes(r, w)
utilities.SetupRoutes(r)

Просмотреть файл

@ -11,7 +11,7 @@ info:
tags:
- name: Utilities
- name: Warden
- name: Doorman
paths:
/__heartbeat__:
@ -123,4 +123,4 @@ paths:
allowed:
type: boolean
tags:
- Warden
- Doorman