diff --git a/auth/acl_interface.go b/auth/acl_interface.go new file mode 100644 index 0000000..a03aea1 --- /dev/null +++ b/auth/acl_interface.go @@ -0,0 +1,5 @@ +package auth + +type ACL interface { + GetPermission(id string) []string +} diff --git a/auth/auth_interface.go b/auth/auth_interface.go new file mode 100644 index 0000000..76e392f --- /dev/null +++ b/auth/auth_interface.go @@ -0,0 +1,6 @@ +package auth + +type Manager interface { + ACL + RBAC +} diff --git a/auth/rbac_interface.go b/auth/rbac_interface.go new file mode 100644 index 0000000..6701024 --- /dev/null +++ b/auth/rbac_interface.go @@ -0,0 +1,5 @@ +package auth + +type RBAC interface { + GetRole(id string) []string +} diff --git a/enforcer.go b/enforcer.go index fa2656a..23ffbaa 100644 --- a/enforcer.go +++ b/enforcer.go @@ -23,6 +23,7 @@ type Enforcer struct { adapter persist.Adapter watcher persist.Watcher logger log.Logger + authManager interface{} } func NewDefaultAdapter() persist.Adapter { diff --git a/enforcer_auth_api.go b/enforcer_auth_api.go new file mode 100644 index 0000000..59a2e08 --- /dev/null +++ b/enforcer_auth_api.go @@ -0,0 +1,51 @@ +package token_go + +import ( + "errors" + "fmt" + "github.com/weloe/token-go/auth" + "github.com/weloe/token-go/ctx" + "github.com/weloe/token-go/util" +) + +func (e *Enforcer) SetAuth(manager interface{}) { + e.authManager = manager +} + +func (e *Enforcer) CheckRole(ctx ctx.Context, role string) error { + if e.authManager == nil { + return errors.New("authManager is nil") + } + rbac, ok := e.authManager.(auth.RBAC) + if !ok { + return errors.New("authManager doesn't implement RBAC interface") + } + id, err := e.GetLoginId(ctx) + if err != nil { + return err + } + roles := rbac.GetRole(id) + if util.HasStr(roles, role) { + return nil + } + return fmt.Errorf("id %v doesn't has role %v", id, role) +} + +func (e *Enforcer) CheckPermission(ctx ctx.Context, permission string) error { + if e.authManager == nil { + return errors.New("authManager is nil") + } + acl, ok := e.authManager.(auth.ACL) + if !ok { + return errors.New("authManager doesn't implement ACL interface") + } + id, err := e.GetLoginId(ctx) + if err != nil { + return err + } + permissions := acl.GetPermission(id) + if util.HasStr(permissions, permission) { + return nil + } + return fmt.Errorf("id %v doesn't has permission %v", id, permission) +} diff --git a/enforcer_auth_api_test.go b/enforcer_auth_api_test.go new file mode 100644 index 0000000..8b37269 --- /dev/null +++ b/enforcer_auth_api_test.go @@ -0,0 +1,76 @@ +package token_go + +import ( + "github.com/weloe/token-go/model" + "testing" +) + +type MockRbacAuth struct { +} + +func (m *MockRbacAuth) GetRole(id string) []string { + var arr = make([]string, 2) + arr[1] = "user" + return arr +} + +type MockAclAuth struct { +} + +func (m *MockAclAuth) GetPermission(id string) []string { + var arr = make([]string, 2) + arr[1] = "user::get" + return arr +} + +func TestEnforcer_GetRole(t *testing.T) { + err, enforcer, ctx := NewTestEnforcer(t) + if err != nil { + t.Errorf("NewTestEnforcer() failed: %v", err) + } + m := &MockRbacAuth{} + enforcer.SetAuth(m) + loginModel := model.DefaultLoginModel() + loginModel.Token = "233" + _, err = enforcer.LoginByModel("id", loginModel, ctx) + if err != nil { + t.Errorf("Login() failed: %v", err) + } + + err = enforcer.CheckRole(ctx, "user") + if err != nil { + t.Errorf("CheckRole() failed: %v", err) + } + + err = enforcer.CheckPermission(ctx, "user::get") + if err == nil { + t.Errorf("CheckRole() failed") + } + t.Logf("CheckPermission() return %v", err) +} + +func TestEnforcer_CheckPermission(t *testing.T) { + err, enforcer, ctx := NewTestEnforcer(t) + if err != nil { + t.Errorf("NewTestEnforcer() failed: %v", err) + } + m := &MockAclAuth{} + enforcer.SetAuth(m) + loginModel := model.DefaultLoginModel() + loginModel.Token = "233" + _, err = enforcer.LoginByModel("id", loginModel, ctx) + if err != nil { + t.Errorf("Login() failed: %v", err) + } + + err = enforcer.CheckRole(ctx, "user") + if err == nil { + t.Errorf("CheckRole() failed") + } + t.Logf("CheckRole() return %v", err) + + err = enforcer.CheckPermission(ctx, "user::get") + if err != nil { + t.Errorf("CheckRole() failed: %v", err) + } +} \ No newline at end of file diff --git a/enforcer_interface.go b/enforcer_interface.go index 07bb64f..0babf42 100644 --- a/enforcer_interface.go +++ b/enforcer_interface.go @@ -26,6 +26,10 @@ type IEnforcer interface { CheckLogin(ctx ctx.Context) error + SetAuth(manager interface{}) + CheckRole(ctx ctx.Context, role string) error + CheckPermission(ctx ctx.Context, permission string) error + SetType(t string) GetType() string GetAdapter() persist.Adapter diff --git a/util/util.go b/util/util.go index c85c3ad..026f18e 100644 --- a/util/util.go +++ b/util/util.go @@ -8,3 +8,12 @@ func HasNil(arr []interface{}) bool { } return false } + +func HasStr(arr []string, str string) bool { + for _, s := range arr { + if s == str { + return true + } + } + return false +}