Skip to content

Commit

Permalink
rbac: bump casbin library
Browse files Browse the repository at this point in the history
  • Loading branch information
lebauce committed Nov 3, 2020
1 parent ec9cf4c commit c17f4f9
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 23 deletions.
8 changes: 6 additions & 2 deletions graffiti/api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,12 @@ func (a *Server) serveLogin(w http.ResponseWriter, r *http.Request, authBackend
bytes, _ := json.Marshal(body)
w.Write(bytes)

roles := rbac.GetUserRoles(username)
logging.GetLogger().Infof("User %s authenticated with %s backend with roles %s", username, authBackend.Name(), roles)
roles, err := rbac.GetUserRoles(username)
if err != nil {
logging.GetLogger().Errorf("Failed to get roles for user '%s': err", username, err)
} else {
logging.GetLogger().Infof("User %s authenticated with %s backend with roles %s", username, authBackend.Name(), roles)
}
return
}

Expand Down
10 changes: 8 additions & 2 deletions graffiti/http/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,21 @@ func Authenticate(backend AuthenticationBackend, w http.ResponseWriter, username
return "", nil, err
}

if roles := rbac.GetUserRoles(username); len(roles) == 0 {
roles, err := rbac.GetUserRoles(username)
if err != nil {
return "", nil, err
} else if len(roles) == 0 {
rbac.AddRoleForUser(username, backend.DefaultUserRole(username))
}

if token != "" {
http.SetCookie(w, AuthCookie(token, "/"))
}

permissions := rbac.GetPermissionsForUser(username)
permissions, err := rbac.GetPermissionsForUser(username)
if err != nil {
return "", nil, err
}
setPermissionsCookie(w, permissions)

return token, permissions, nil
Expand Down
12 changes: 10 additions & 2 deletions graffiti/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,19 @@ func (s *Server) Stop() {
func postAuthHandler(f auth.AuthenticatedHandlerFunc, authBackend AuthenticationBackend) func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
return func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
// re-add user to its group
if roles := rbac.GetUserRoles(r.Username); len(roles) == 0 {
roles, err := rbac.GetUserRoles(r.Username)
if err != nil {
return
}

if len(roles) == 0 {
rbac.AddRoleForUser(r.Username, authBackend.DefaultUserRole(r.Username))
}

permissions := rbac.GetPermissionsForUser(r.Username)
permissions, err := rbac.GetPermissionsForUser(r.Username)
if err != nil {
return
}
setPermissionsCookie(w, permissions)

// re-add auth cookie
Expand Down
19 changes: 12 additions & 7 deletions graffiti/rbac/enforcer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package rbac

import (
"context"

"github.com/casbin/casbin"
"github.com/casbin/casbin/model"
etcd "github.com/coreos/etcd/client"
Expand Down Expand Up @@ -53,7 +55,7 @@ func Init(model model.Model, kapi etcd.KeysAPI, loadPolicy func(model.Model) err
}
casbinEnforcer.BuildRoleLinks()

watcher := NewEtcdWatcher(kapi)
watcher := NewEtcdWatcher(kapi, context.Background())

watcher.SetUpdateCallback(func(string) {
casbinEnforcer.LoadPolicy()
Expand Down Expand Up @@ -88,21 +90,24 @@ func AddRoleForUser(user, role string) bool {
}

// GetUserRoles returns the roles of a user
func GetUserRoles(user string) []string {
func GetUserRoles(user string) ([]string, error) {
if enforcer == nil {
return []string{}
return nil, nil
}

return enforcer.GetRolesForUser(user)
}

// GetPermissionsForUser returns all the allow and deny permissions for a user
func GetPermissionsForUser(user string) []Permission {
func GetPermissionsForUser(user string) ([]Permission, error) {
if enforcer == nil {
return nil
return nil, nil
}

subjects := enforcer.GetRolesForUser(user)
subjects, err := enforcer.GetRolesForUser(user)
if err != nil {
return nil, err
}
subjects = append(subjects, user)

mperms := make(map[string]Permission)
Expand All @@ -120,5 +125,5 @@ func GetPermissionsForUser(user string) []Permission {
permissions = append(permissions, permission)
}

return permissions
return permissions, nil
}
17 changes: 13 additions & 4 deletions graffiti/rbac/etcdwatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,29 @@ type EtcdWatcher struct {
kapi etcd.KeysAPI
running bool
callback func(string)
cancel context.CancelFunc
}

// finalizer is the destructor for EtcdWatcher.
func finalizer(w *EtcdWatcher) {
w.running = false
w.cancel()
}

// NewEtcdWatcher returns new etcd change watcher
func NewEtcdWatcher(kapi etcd.KeysAPI) persist.Watcher {
func NewEtcdWatcher(kapi etcd.KeysAPI, parent context.Context) persist.Watcher {
ctx, cancel := context.WithCancel(parent)

w := &EtcdWatcher{
kapi: kapi,
running: true,
cancel: cancel,
}

// Call the destructor when the object is released.
runtime.SetFinalizer(w, finalizer)

go w.startWatch()
go w.startWatch(ctx)

return w
}
Expand All @@ -67,15 +72,19 @@ func (w *EtcdWatcher) Update() error {
return nil
}

func (w *EtcdWatcher) Close() {
w.cancel()
}

// startWatch is a goroutine that watches the policy change.
func (w *EtcdWatcher) startWatch() error {
func (w *EtcdWatcher) startWatch(ctx context.Context) error {
watcher := w.kapi.Watcher(etcdPolicyKey, &etcd.WatcherOptions{Recursive: false})
for {
if !w.running {
return nil
}

res, err := watcher.Next(context.Background())
res, err := watcher.Next(ctx)
if err != nil {
return err
}
Expand Down
18 changes: 12 additions & 6 deletions ui/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,24 @@ func (s *Server) serveStatics(w http.ResponseWriter, r *http.Request) {

// ServeIndex servers the index page
func (s *Server) ServeIndex(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
username := r.Username
if username == "" {
username = "admin"
}

permissions, err := rbac.GetPermissionsForUser(username)
if err != nil {
logging.GetLogger().Errorf("Unable to execute index template: %s", err)
return
}

html, err := s.readStatics("statics/index.html")
if err != nil {
logging.GetLogger().Error("Unable to find the asset index.html")
w.WriteHeader(http.StatusNotFound)
return
}

username := r.Username
if username == "" {
username = "admin"
}

s.RLock()
defer s.RUnlock()

Expand All @@ -162,7 +168,7 @@ func (s *Server) ServeIndex(w http.ResponseWriter, r *auth.AuthenticatedRequest)
}{
ExtraAssets: s.extraAssets,
GlobalVars: s.globalVars,
Permissions: rbac.GetPermissionsForUser(username),
Permissions: permissions,
}

shttp.SetTLSHeader(w, &r.Request)
Expand Down

0 comments on commit c17f4f9

Please sign in to comment.