forked from tangled.org/core
this repo has no description

init rbac work

Changed files
+147 -4
appview
+106
appview/state/rbac.go
···
+
package state
+
+
import (
+
"database/sql"
+
"path"
+
+
sqladapter "github.com/Blank-Xu/sql-adapter"
+
"github.com/casbin/casbin/v2"
+
"github.com/casbin/casbin/v2/model"
+
)
+
+
const (
+
Model = `
+
[request_definition]
+
r = sub, dom, obj, act
+
+
[policy_definition]
+
p = sub, dom, obj, act
+
+
[role_definition]
+
g = _, _, _
+
+
[policy_effect]
+
e = some(where (p.eft == allow))
+
+
[matchers]
+
m = (r.act == p.act && r.dom == p.dom && keyMatch2(r.obj, p.obj) && g(r.sub, p.sub, r.dom))
+
`
+
)
+
+
type Enforcer struct {
+
E *casbin.SyncedEnforcer
+
domain string
+
}
+
+
func keyMatch2(key1 string, key2 string) bool {
+
matched, _ := path.Match(key2, key1)
+
return matched
+
}
+
+
func NewEnforcer(domain string) (*Enforcer, error) {
+
m, err := model.NewModelFromString(Model)
+
if err != nil {
+
return nil, err
+
}
+
+
// TODO: conf this
+
db, err := sql.Open("sqlite3", "appview.db")
+
if err != nil {
+
return nil, err
+
}
+
+
a, err := sqladapter.NewAdapter(db, "sqlite3", "acl")
+
if err != nil {
+
return nil, err
+
}
+
+
e, err := casbin.NewSyncedEnforcer(m, a)
+
if err != nil {
+
return nil, err
+
}
+
+
e.EnableAutoSave(true)
+
e.AddFunction("keyMatch2", keyMatch2Func)
+
+
// Add policies with patterns
+
_, err = e.AddPolicies([][]string{
+
{"server:owner", domain, domain, "server:invite"},
+
{"server:owner", domain, domain, "repo:create"},
+
{"server:owner", domain, domain, "repo:delete"}, // priveledged operation, delete any repo in domain
+
{"server:member", domain, domain, "repo:create"}, // priveledged operation, delete any repo in domain
+
})
+
if err != nil {
+
return nil, err
+
}
+
+
return &Enforcer{e, domain}, nil
+
}
+
+
func (e *Enforcer) AddOwner(owner string) error {
+
_, err := e.E.AddGroupingPolicy(owner, "server:owner", e.domain)
+
return err
+
}
+
+
func (e *Enforcer) AddMember(member string) error {
+
_, err := e.E.AddGroupingPolicy(member, "server:member", e.domain)
+
return err
+
}
+
+
func (e *Enforcer) AddRepo(member, domain, repo string) error {
+
_, err := e.E.AddPolicies([][]string{
+
{member, e.domain, repo, "repo:push"},
+
{member, e.domain, repo, "repo:owner"},
+
{member, e.domain, repo, "repo:invite"},
+
{member, e.domain, repo, "repo:delete"},
+
})
+
return err
+
}
+
+
// keyMatch2Func is a wrapper for keyMatch2 to make it compatible with Casbin
+
func keyMatch2Func(args ...interface{}) (interface{}, error) {
+
name1 := args[0].(string)
+
name2 := args[1].(string)
+
+
return keyMatch2(name1, name2), nil
+
}
+23 -4
appview/state/state.go
···
)
type State struct {
-
db *db.DB
-
auth *auth.Auth
+
Db *db.DB
+
Auth *auth.Auth
}
func Make() (*State, error) {
···
return nil, err
}
-
return &State{db, auth}, nil
+
return &State{db, auth, nil}, nil
}
func (s *State) Login(w http.ResponseWriter, r *http.Request) {
···
w.Write([]byte("check success"))
// mark as registered
-
err = s.db.Register(domain)
+
err = s.Db.Register(domain)
+
if err != nil {
+
log.Println("failed to register domain", err)
+
http.Error(w, err.Error(), http.StatusInternalServerError)
+
}
+
+
// set permissions for this did as owner
+
_, did, err := s.Db.RegistrationStatus(domain)
if err != nil {
log.Println("failed to register domain", err)
+
http.Error(w, err.Error(), http.StatusInternalServerError)
+
}
+
+
e, err := NewEnforcer(domain)
+
if err != nil {
+
log.Println("failed to setup owner of domain", err)
+
http.Error(w, err.Error(), http.StatusInternalServerError)
+
}
+
+
err = e.AddOwner(did)
+
if err != nil {
+
log.Println("failed to setup owner of domain", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
+4
go.mod
···
)
require (
+
github.com/Blank-Xu/sql-adapter v1.1.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
+
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
github.com/carlmjohnson/versioninfo v0.22.5 // indirect
+
github.com/casbin/casbin/v2 v2.103.0 // indirect
+
github.com/casbin/govaluate v1.3.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudflare/circl v1.4.0 // indirect
github.com/cyphar/filepath-securejoin v0.3.3 // indirect
+14
go.sum
···
+
github.com/Blank-Xu/sql-adapter v1.1.1 h1:+g7QXU9sl/qT6Po97teMpf3GjAO0X9aFaqgSePXvYko=
+
github.com/Blank-Xu/sql-adapter v1.1.1/go.mod h1:o2g8EZhZ3TudnYEGDkoU+3jCTCgDgx1o/Ig5ajKkaLY=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
···
github.com/bluekeyes/go-gitdiff v0.8.0/go.mod h1:WWAk1Mc6EgWarCrPFO+xeYlujPu98VuLW3Tu+B/85AE=
github.com/bluesky-social/indigo v0.0.0-20250123072624-9e3b84fdbb20 h1:yHusfYYi8odoCcsI6AurU+dRWb7itHAQNwt3/Rl9Vfs=
github.com/bluesky-social/indigo v0.0.0-20250123072624-9e3b84fdbb20/go.mod h1:Qp4YqWf+AQ3TwQCxV5Ls8O2tXE55zVTGVs3zTmn7BOg=
+
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
+
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
+
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
+
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc=
github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8=
+
github.com/casbin/casbin/v2 v2.100.0/go.mod h1:LO7YPez4dX3LgoTCqSQAleQDo0S0BeZBDxYnPUl95Ng=
+
github.com/casbin/casbin/v2 v2.103.0 h1:dHElatNXNrr8XcseUov0ZSiWjauwmZZE6YMV3eU1yic=
+
github.com/casbin/casbin/v2 v2.103.0/go.mod h1:Ee33aqGrmES+GNL17L0h9X28wXuo829wnNUnS0edAco=
+
github.com/casbin/govaluate v1.2.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
+
github.com/casbin/govaluate v1.3.0 h1:VA0eSY0M2lA86dYd5kPPuNZMUD9QkWnOCnavGrw9myc=
+
github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
···
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
···
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=