import full test suite
This commit is contained in:
+20
-2
@@ -13,6 +13,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ = tls.Config{}
|
||||
|
||||
type (
|
||||
Client struct {
|
||||
Transport *http.Transport
|
||||
@@ -21,9 +23,21 @@ type (
|
||||
isDebug bool
|
||||
config configuration
|
||||
}
|
||||
|
||||
ClientInterface interface {
|
||||
Users() *Users
|
||||
Roles() *Roles
|
||||
Resources() *Resources
|
||||
Sessions() *Sessions
|
||||
}
|
||||
)
|
||||
|
||||
func (c *Client) Users() *Users { return &Users{c} }
|
||||
func (c *Client) Users() *Users { return &Users{c} }
|
||||
func (c *Client) Roles() *Roles { return &Roles{c} }
|
||||
func (c *Client) Resources() *Resources { return &Resources{c} }
|
||||
func (c *Client) Sessions() *Sessions { return &Sessions{c} }
|
||||
|
||||
var _ ClientInterface = &Client{}
|
||||
|
||||
func New() (*Client, error) {
|
||||
if err := config.validate(); err != nil {
|
||||
@@ -38,7 +52,7 @@ func New() (*Client, error) {
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: timeout,
|
||||
// @todo: === remove this line ===
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
//TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
@@ -70,6 +84,10 @@ func (c *Client) Post(url string, body interface{}) (*http.Response, error) {
|
||||
return c.Request("POST", url, body)
|
||||
}
|
||||
|
||||
func (c *Client) Patch(url string, body interface{}) (*http.Response, error) {
|
||||
return c.Request("PATCH", url, body)
|
||||
}
|
||||
|
||||
func (c *Client) Delete(url string) (*http.Response, error) {
|
||||
return c.Request("DELETE", url, nil)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package rbac_test
|
||||
|
||||
import (
|
||||
"github.com/crusttech/crust/rbac"
|
||||
"github.com/namsral/flag"
|
||||
)
|
||||
|
||||
var loaded bool
|
||||
|
||||
func getClient() (*rbac.Client, error) {
|
||||
if !loaded {
|
||||
rbac.Flags()
|
||||
flag.Parse()
|
||||
loaded = true
|
||||
}
|
||||
return rbac.New()
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package rbac
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type (
|
||||
Resources struct {
|
||||
*Client
|
||||
}
|
||||
|
||||
ResourcesInterface interface {
|
||||
Create(resourceID string, operations []string) error
|
||||
Delete(resourceID string) error
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
resourcesCreate = "/resources/%s"
|
||||
resourcesDelete = "/resources/%s"
|
||||
)
|
||||
|
||||
func (u *Resources) Create(resourceID string, operations []string) error {
|
||||
body := struct {
|
||||
Operations []string `json:"operations"`
|
||||
}{operations}
|
||||
|
||||
resp, err := u.Client.Post(fmt.Sprintf(resourcesCreate, resourceID), body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Resources) Delete(resourceID string) error {
|
||||
resp, err := u.Client.Delete(fmt.Sprintf(resourcesCreate, resourceID))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
var _ ResourcesInterface = &Resources{}
|
||||
@@ -0,0 +1,28 @@
|
||||
package rbac_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResources(t *testing.T) {
|
||||
rbac, err := getClient()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error when creating RBAC instance: %+v", err)
|
||||
}
|
||||
rbac.Debug(false)
|
||||
|
||||
resources := rbac.Resources()
|
||||
resources.Delete("test-resource")
|
||||
|
||||
if err := resources.Create("test-resource", []string{"view", "edit", "delete"}); err != nil {
|
||||
t.Errorf("Error when creating test-resource, %+v", err)
|
||||
}
|
||||
|
||||
if err := resources.Delete("test-resource"); err != nil {
|
||||
t.Errorf("Unexpected error deleting a resource, %+v", err)
|
||||
}
|
||||
|
||||
if err := resources.Delete("test-resource"); err == nil {
|
||||
t.Errorf("Expected error when deleting unexistant resource, got none")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package rbac
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type (
|
||||
Roles struct {
|
||||
*Client
|
||||
}
|
||||
|
||||
RolesInterface interface {
|
||||
Create(role string) error
|
||||
Delete(role string) error
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
rolesCreate = "/roles/%s"
|
||||
rolesDelete = "/roles/%s"
|
||||
)
|
||||
|
||||
func (u *Roles) Create(role string) error {
|
||||
resp, err := u.Client.Post(fmt.Sprintf(rolesCreate, role), nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Roles) Delete(role string) error {
|
||||
resp, err := u.Client.Delete(fmt.Sprintf(rolesDelete, role))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
var _ RolesInterface = &Roles{}
|
||||
@@ -0,0 +1,28 @@
|
||||
package rbac_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRoles(t *testing.T) {
|
||||
rbac, err := getClient()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error when creating RBAC instance: %+v", err)
|
||||
}
|
||||
rbac.Debug(false)
|
||||
|
||||
roles := rbac.Roles()
|
||||
roles.Delete("test-role")
|
||||
|
||||
if err := roles.Create("test-role"); err != nil {
|
||||
t.Errorf("Error when creating test-role: %+v", err)
|
||||
}
|
||||
|
||||
if err := roles.Delete("test-role"); err != nil {
|
||||
t.Errorf("Error when deleting test-role: %+v", err)
|
||||
}
|
||||
|
||||
if err := roles.Delete("non-existant"); err == nil {
|
||||
t.Errorf("Expected error on deleting a non-existant role")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package rbac
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/crusttech/crust/rbac/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type (
|
||||
Sessions struct {
|
||||
*Client
|
||||
}
|
||||
|
||||
SessionsInterface interface {
|
||||
Create(sessionID string, username string, roles []string) error
|
||||
Get(sessionID string) (*types.Session, error)
|
||||
Delete(sessionID string) error
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
sessionsCreate = "/sessions/%s"
|
||||
sessionsGet = "/sessions/%s"
|
||||
sessionsDelete = "/sessions/%s"
|
||||
)
|
||||
|
||||
func (u *Sessions) Create(sessionID string, username string, roles []string) error {
|
||||
body := struct {
|
||||
Username string `json:"username"`
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
}{username, roles}
|
||||
|
||||
resp, err := u.Client.Post(fmt.Sprintf(sessionsCreate, sessionID), body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Sessions) Get(sessionID string) (*types.Session, error) {
|
||||
resp, err := u.Client.Get(fmt.Sprintf(sessionsGet, sessionID))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
session := &types.Session{}
|
||||
return session, errors.Wrap(json.NewDecoder(resp.Body).Decode(session), "decoding json failed")
|
||||
default:
|
||||
return nil, toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Sessions) Delete(sessionID string) error {
|
||||
resp, err := u.Client.Delete(fmt.Sprintf(sessionsDelete, sessionID))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
var _ SessionsInterface = &Sessions{}
|
||||
@@ -0,0 +1,38 @@
|
||||
package rbac_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSessions(t *testing.T) {
|
||||
rbac, err := getClient()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error when creating RBAC instance: %+v", err)
|
||||
}
|
||||
rbac.Debug(false)
|
||||
|
||||
sessions := rbac.Sessions()
|
||||
users := rbac.Users()
|
||||
|
||||
// clean up data
|
||||
users.Delete("test-user")
|
||||
sessions.Delete("test-session")
|
||||
|
||||
if err := users.Create("test-user", "test-password"); err != nil {
|
||||
t.Errorf("Unexpected error when creating test-user, %+v", err)
|
||||
return
|
||||
}
|
||||
if err := sessions.Create("test-session", "test-user", []string{}); err != nil {
|
||||
t.Errorf("Unexpected error when creating test-session, %+v", err)
|
||||
}
|
||||
|
||||
if _, err := sessions.Get("test-session"); err != nil {
|
||||
t.Errorf("Unexpected error when getting test-session, %+v", err)
|
||||
}
|
||||
|
||||
if err := sessions.Delete("test-session"); err != nil {
|
||||
t.Errorf("Unexpected error when deleting test-session, %+v", err)
|
||||
}
|
||||
|
||||
// Write tests (need users, roles)
|
||||
}
|
||||
@@ -2,6 +2,11 @@ package types
|
||||
|
||||
type (
|
||||
User struct {
|
||||
username string
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
Session struct {
|
||||
Username string `json:"username"`
|
||||
Roles []string `json:"roles"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -15,6 +15,8 @@ type (
|
||||
Create(username, password string) error
|
||||
Get(username string) (*types.User, error)
|
||||
Delete(username string) error
|
||||
|
||||
Assign(username string, roles []string) error
|
||||
}
|
||||
)
|
||||
|
||||
@@ -36,6 +38,42 @@ func (u *Users) Create(username, password string) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Users) Assign(username string, roles []string) error {
|
||||
body := struct {
|
||||
Roles []string `json:"roles"`
|
||||
}{roles}
|
||||
|
||||
resp, err := u.Client.Patch("/users/"+username+"/assignRoles", body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Users) Deassign(username string, roles []string) error {
|
||||
body := struct {
|
||||
Roles []string `json:"roles"`
|
||||
}{roles}
|
||||
|
||||
resp, err := u.Client.Patch("/users/"+username+"/deassignRoles", body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
default:
|
||||
return toError(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Users) Get(username string) (*types.User, error) {
|
||||
resp, err := u.Client.Get("/users/" + username)
|
||||
if err != nil {
|
||||
|
||||
+10
-33
@@ -1,55 +1,32 @@
|
||||
package rbac_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/crusttech/crust/rbac"
|
||||
"github.com/namsral/flag"
|
||||
)
|
||||
|
||||
var _ = os.Setenv
|
||||
|
||||
func TestUsers(t *testing.T) {
|
||||
rbac.Flags()
|
||||
flag.Parse()
|
||||
|
||||
rbac, err := rbac.New()
|
||||
rbac, err := getClient()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error when creating RBAC instance: %+v", err)
|
||||
}
|
||||
rbac.Debug(false)
|
||||
|
||||
users := rbac.Users()
|
||||
users.Delete("test-user")
|
||||
|
||||
// clean up env
|
||||
{
|
||||
// just making sure we don't have one
|
||||
// and we're ignoring possible err's
|
||||
users.Delete("test-user")
|
||||
if err := users.Create("test-user", "test-password"); err != nil {
|
||||
t.Errorf("Error when creating test-user: %+v", err)
|
||||
}
|
||||
|
||||
// create a user
|
||||
{
|
||||
err := users.Create("test-user", "test-password")
|
||||
if err != nil {
|
||||
t.Errorf("Error when creating test-user: %+v", err)
|
||||
}
|
||||
if err := users.Delete("test-user"); err != nil {
|
||||
t.Errorf("Error when deleting test-user: %+v", err)
|
||||
}
|
||||
|
||||
// delete a user
|
||||
{
|
||||
err := users.Delete("test-user")
|
||||
if err != nil {
|
||||
t.Errorf("Error when deleting test-user: %+v", err)
|
||||
}
|
||||
if _, err := users.Get("non-existant"); err == nil {
|
||||
t.Errorf("Expected error on retrieving a non-existant user")
|
||||
}
|
||||
|
||||
// check getting a non-existant user fails
|
||||
{
|
||||
_, err := users.Get("non-existant")
|
||||
if err == nil {
|
||||
t.Errorf("Expected error on retrieving a non-existant user")
|
||||
}
|
||||
if err := users.Delete("non-existant"); err == nil {
|
||||
t.Errorf("Expected error on deleting a non-existant user")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user