2017-10-09 21:16:24 +00:00
|
|
|
|
package server
|
2017-02-22 03:36:23 +00:00
|
|
|
|
|
|
|
|
|
import (
|
2017-03-10 19:24:48 +00:00
|
|
|
|
"bytes"
|
2017-02-22 03:36:23 +00:00
|
|
|
|
"context"
|
2017-10-09 21:16:24 +00:00
|
|
|
|
"encoding/json"
|
2017-02-22 03:36:23 +00:00
|
|
|
|
"fmt"
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"net/http"
|
|
|
|
|
"net/http/httptest"
|
|
|
|
|
"testing"
|
|
|
|
|
|
2017-03-10 19:24:48 +00:00
|
|
|
|
"github.com/bouk/httprouter"
|
2017-02-22 03:36:23 +00:00
|
|
|
|
"github.com/influxdata/chronograf"
|
|
|
|
|
"github.com/influxdata/chronograf/log"
|
|
|
|
|
"github.com/influxdata/chronograf/mocks"
|
2017-11-03 20:32:05 +00:00
|
|
|
|
"github.com/influxdata/chronograf/roles"
|
2017-02-22 03:36:23 +00:00
|
|
|
|
)
|
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
func TestService_UserID(t *testing.T) {
|
2017-02-22 03:36:23 +00:00
|
|
|
|
type fields struct {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
UsersStore chronograf.UsersStore
|
|
|
|
|
Logger chronograf.Logger
|
2017-02-22 03:36:23 +00:00
|
|
|
|
}
|
|
|
|
|
type args struct {
|
|
|
|
|
w *httptest.ResponseRecorder
|
|
|
|
|
r *http.Request
|
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
fields fields
|
|
|
|
|
args args
|
2017-10-09 21:16:24 +00:00
|
|
|
|
id string
|
2017-02-22 03:36:23 +00:00
|
|
|
|
wantStatus int
|
|
|
|
|
wantContentType string
|
|
|
|
|
wantBody string
|
|
|
|
|
}{
|
|
|
|
|
{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
name: "Get Single Chronograf User",
|
2017-02-22 03:36:23 +00:00
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
2017-03-10 19:24:48 +00:00
|
|
|
|
r: httptest.NewRequest(
|
2017-10-09 21:16:24 +00:00
|
|
|
|
"GET",
|
|
|
|
|
"http://any.url", // can be any valid URL as we are bypassing mux
|
|
|
|
|
nil,
|
|
|
|
|
),
|
2017-03-10 19:24:48 +00:00
|
|
|
|
},
|
|
|
|
|
fields: fields{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
2017-10-18 18:17:42 +00:00
|
|
|
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
|
|
|
|
switch *q.ID {
|
|
|
|
|
case 1337:
|
2017-10-09 21:16:24 +00:00
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1337,
|
|
|
|
|
Name: "billysteve",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "google",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-13 00:42:30 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.ViewerRole,
|
2017-10-13 00:42:30 +00:00
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}, nil
|
|
|
|
|
default:
|
2017-10-24 21:21:29 +00:00
|
|
|
|
return nil, fmt.Errorf("User with ID %d not found", *q.ID)
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
id: "1337",
|
|
|
|
|
wantStatus: http.StatusOK,
|
2017-03-10 19:24:48 +00:00
|
|
|
|
wantContentType: "application/json",
|
2017-11-01 13:12:19 +00:00
|
|
|
|
wantBody: `{"id":"1337","superAdmin":false,"name":"billysteve","provider":"google","scheme":"oauth2","links":{"self":"/chronograf/v1/users/1337"},"roles":[{"name":"viewer"}]}`,
|
2017-03-10 19:24:48 +00:00
|
|
|
|
},
|
|
|
|
|
}
|
2017-10-09 21:16:24 +00:00
|
|
|
|
|
2017-03-10 19:24:48 +00:00
|
|
|
|
for _, tt := range tests {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
s := &Service{
|
2017-10-31 20:41:17 +00:00
|
|
|
|
Store: &mocks.Store{
|
|
|
|
|
UsersStore: tt.fields.UsersStore,
|
|
|
|
|
},
|
|
|
|
|
Logger: tt.fields.Logger,
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}
|
2017-03-10 19:24:48 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
tt.args.r = tt.args.r.WithContext(httprouter.WithParams(
|
|
|
|
|
context.Background(),
|
|
|
|
|
httprouter.Params{
|
|
|
|
|
{
|
|
|
|
|
Key: "id",
|
|
|
|
|
Value: tt.id,
|
|
|
|
|
},
|
|
|
|
|
}))
|
2017-03-10 19:24:48 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
s.UserID(tt.args.w, tt.args.r)
|
2017-03-10 19:24:48 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
resp := tt.args.w.Result()
|
|
|
|
|
content := resp.Header.Get("Content-Type")
|
|
|
|
|
body, _ := ioutil.ReadAll(resp.Body)
|
2017-03-10 19:24:48 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
if resp.StatusCode != tt.wantStatus {
|
|
|
|
|
t.Errorf("%q. UserID() = %v, want %v", tt.name, resp.StatusCode, tt.wantStatus)
|
|
|
|
|
}
|
|
|
|
|
if tt.wantContentType != "" && content != tt.wantContentType {
|
|
|
|
|
t.Errorf("%q. UserID() = %v, want %v", tt.name, content, tt.wantContentType)
|
|
|
|
|
}
|
|
|
|
|
if eq, _ := jsonEqual(string(body), tt.wantBody); tt.wantBody != "" && !eq {
|
|
|
|
|
t.Errorf("%q. UserID() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wantBody)
|
|
|
|
|
}
|
|
|
|
|
})
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
func TestService_NewUser(t *testing.T) {
|
2017-03-10 19:24:48 +00:00
|
|
|
|
type fields struct {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
UsersStore chronograf.UsersStore
|
|
|
|
|
Logger chronograf.Logger
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
type args struct {
|
2017-11-03 16:51:33 +00:00
|
|
|
|
w *httptest.ResponseRecorder
|
|
|
|
|
r *http.Request
|
|
|
|
|
user *userRequest
|
|
|
|
|
withSuperAdminContext bool
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
fields fields
|
|
|
|
|
args args
|
|
|
|
|
wantStatus int
|
|
|
|
|
wantContentType string
|
|
|
|
|
wantBody string
|
|
|
|
|
}{
|
|
|
|
|
{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
name: "Create a new Chronograf User",
|
2017-03-10 19:24:48 +00:00
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
2017-10-09 21:16:24 +00:00
|
|
|
|
"POST",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
2017-10-13 19:34:30 +00:00
|
|
|
|
user: &userRequest{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
Name: "bob",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
2017-03-10 19:24:48 +00:00
|
|
|
|
},
|
2017-02-24 05:26:09 +00:00
|
|
|
|
},
|
2017-02-22 03:36:23 +00:00
|
|
|
|
fields: fields{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
AddF: func(ctx context.Context, user *chronograf.User) (*chronograf.User, error) {
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1338,
|
|
|
|
|
Name: "bob",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-13 19:34:30 +00:00
|
|
|
|
Roles: []chronograf.Role{},
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
},
|
2017-02-24 05:26:09 +00:00
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
wantStatus: http.StatusCreated,
|
2017-02-22 03:36:23 +00:00
|
|
|
|
wantContentType: "application/json",
|
2017-11-01 13:12:19 +00:00
|
|
|
|
wantBody: `{"id":"1338","superAdmin":false,"name":"bob","provider":"github","scheme":"oauth2","roles":[],"links":{"self":"/chronograf/v1/users/1338"}}`,
|
2017-02-22 03:36:23 +00:00
|
|
|
|
},
|
2017-11-03 16:06:18 +00:00
|
|
|
|
{
|
|
|
|
|
name: "Create a new Chronograf User with multiple roles",
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"POST",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
{
|
|
|
|
|
Name: AdminRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: ViewerRoleName,
|
|
|
|
|
Organization: "billieta org",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
AddF: func(ctx context.Context, user *chronograf.User) (*chronograf.User, error) {
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1338,
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
{
|
|
|
|
|
Name: AdminRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: ViewerRoleName,
|
|
|
|
|
Organization: "billieta org",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantStatus: http.StatusCreated,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"id":"1338","superAdmin":false,"name":"bob","provider":"github","scheme":"oauth2","roles":[{"name":"admin","organization":"bobbetta org"},{"name":"viewer","organization":"billieta org"}],"links":{"self":"/chronograf/v1/users/1338"}}`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Create a new Chronograf User with multiple roles same org",
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"POST",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
{
|
|
|
|
|
Name: AdminRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: ViewerRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
AddF: func(ctx context.Context, user *chronograf.User) (*chronograf.User, error) {
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1338,
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
{
|
|
|
|
|
Name: AdminRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: ViewerRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantStatus: http.StatusUnprocessableEntity,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"code":422,"message":"duplicate organization \"bobbetta org\" in roles"}`,
|
|
|
|
|
},
|
2017-11-03 16:51:33 +00:00
|
|
|
|
{
|
|
|
|
|
name: "Create a new SuperAdmin User - Not as superadmin",
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"POST",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
SuperAdmin: true,
|
|
|
|
|
},
|
|
|
|
|
withSuperAdminContext: false,
|
|
|
|
|
},
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
AddF: func(ctx context.Context, user *chronograf.User) (*chronograf.User, error) {
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1338,
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantStatus: http.StatusUnauthorized,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"code":401,"message":"Cannot set SuperAdmin"}`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Create a new SuperAdmin User - as superadmin",
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"POST",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
SuperAdmin: true,
|
|
|
|
|
},
|
|
|
|
|
withSuperAdminContext: true,
|
|
|
|
|
},
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
AddF: func(ctx context.Context, user *chronograf.User) (*chronograf.User, error) {
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1338,
|
|
|
|
|
Name: "bob",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantStatus: http.StatusCreated,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"id":"1338","superAdmin":false,"name":"bob","provider":"github","scheme":"oauth2","roles":[],"links":{"self":"/chronograf/v1/users/1338"}}`,
|
|
|
|
|
},
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
2017-10-09 21:16:24 +00:00
|
|
|
|
|
2017-03-10 19:24:48 +00:00
|
|
|
|
for _, tt := range tests {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
s := &Service{
|
2017-10-31 20:41:17 +00:00
|
|
|
|
Store: &mocks.Store{
|
|
|
|
|
UsersStore: tt.fields.UsersStore,
|
|
|
|
|
},
|
|
|
|
|
Logger: tt.fields.Logger,
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf, _ := json.Marshal(tt.args.user)
|
|
|
|
|
tt.args.r.Body = ioutil.NopCloser(bytes.NewReader(buf))
|
|
|
|
|
|
2017-11-03 16:51:33 +00:00
|
|
|
|
ctx := tt.args.r.Context()
|
|
|
|
|
if tt.args.withSuperAdminContext {
|
|
|
|
|
ctx = context.WithValue(ctx, SuperAdminKey, true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tt.args.r = tt.args.r.WithContext(ctx)
|
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
s.NewUser(tt.args.w, tt.args.r)
|
2017-03-10 19:24:48 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
resp := tt.args.w.Result()
|
|
|
|
|
content := resp.Header.Get("Content-Type")
|
|
|
|
|
body, _ := ioutil.ReadAll(resp.Body)
|
2017-03-10 19:24:48 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
if resp.StatusCode != tt.wantStatus {
|
|
|
|
|
t.Errorf("%q. UserID() = %v, want %v", tt.name, resp.StatusCode, tt.wantStatus)
|
|
|
|
|
}
|
|
|
|
|
if tt.wantContentType != "" && content != tt.wantContentType {
|
|
|
|
|
t.Errorf("%q. UserID() = %v, want %v", tt.name, content, tt.wantContentType)
|
|
|
|
|
}
|
|
|
|
|
if eq, _ := jsonEqual(string(body), tt.wantBody); tt.wantBody != "" && !eq {
|
|
|
|
|
t.Errorf("%q. UserID() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wantBody)
|
|
|
|
|
}
|
|
|
|
|
})
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
func TestService_RemoveUser(t *testing.T) {
|
2017-03-10 19:24:48 +00:00
|
|
|
|
type fields struct {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
UsersStore chronograf.UsersStore
|
|
|
|
|
Logger chronograf.Logger
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
type args struct {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
w *httptest.ResponseRecorder
|
|
|
|
|
r *http.Request
|
2017-10-13 19:34:30 +00:00
|
|
|
|
user *userRequest
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
name string
|
|
|
|
|
fields fields
|
|
|
|
|
args args
|
|
|
|
|
user *chronograf.User
|
|
|
|
|
id string
|
|
|
|
|
wantStatus int
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}{
|
2017-02-22 03:36:23 +00:00
|
|
|
|
{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
name: "Delete a Chronograf User",
|
2017-02-22 03:36:23 +00:00
|
|
|
|
fields: fields{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
2017-10-18 18:17:42 +00:00
|
|
|
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
|
|
|
|
switch *q.ID {
|
|
|
|
|
case 1339:
|
2017-10-09 21:16:24 +00:00
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1339,
|
|
|
|
|
Name: "helena",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "heroku",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}, nil
|
|
|
|
|
default:
|
2017-10-24 21:21:29 +00:00
|
|
|
|
return nil, fmt.Errorf("User with ID %d not found", *q.ID)
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
DeleteF: func(ctx context.Context, user *chronograf.User) error {
|
2017-03-10 19:24:48 +00:00
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
2017-10-09 21:16:24 +00:00
|
|
|
|
"DELETE",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
2017-10-13 19:34:30 +00:00
|
|
|
|
user: &userRequest{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
ID: 1339,
|
|
|
|
|
Name: "helena",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "heroku",
|
|
|
|
|
Scheme: "oauth2",
|
2017-03-10 19:24:48 +00:00
|
|
|
|
},
|
2017-02-24 05:26:09 +00:00
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
id: "1339",
|
2017-03-10 19:24:48 +00:00
|
|
|
|
wantStatus: http.StatusNoContent,
|
2017-02-22 03:36:23 +00:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tt := range tests {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
s := &Service{
|
2017-10-31 20:41:17 +00:00
|
|
|
|
Store: &mocks.Store{
|
|
|
|
|
UsersStore: tt.fields.UsersStore,
|
|
|
|
|
},
|
|
|
|
|
Logger: tt.fields.Logger,
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tt.args.r = tt.args.r.WithContext(httprouter.WithParams(
|
|
|
|
|
context.Background(),
|
|
|
|
|
httprouter.Params{
|
|
|
|
|
{
|
|
|
|
|
Key: "id",
|
|
|
|
|
Value: tt.id,
|
|
|
|
|
},
|
2017-03-10 19:24:48 +00:00
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
))
|
2017-02-22 03:36:23 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
s.RemoveUser(tt.args.w, tt.args.r)
|
|
|
|
|
|
|
|
|
|
resp := tt.args.w.Result()
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode != tt.wantStatus {
|
|
|
|
|
t.Errorf("%q. RemoveUser() = %v, want %v", tt.name, resp.StatusCode, tt.wantStatus)
|
|
|
|
|
}
|
|
|
|
|
})
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-22 03:36:23 +00:00
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
func TestService_UpdateUser(t *testing.T) {
|
2017-03-10 19:24:48 +00:00
|
|
|
|
type fields struct {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
UsersStore chronograf.UsersStore
|
|
|
|
|
Logger chronograf.Logger
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
type args struct {
|
2017-11-03 16:51:33 +00:00
|
|
|
|
w *httptest.ResponseRecorder
|
|
|
|
|
r *http.Request
|
|
|
|
|
user *userRequest
|
|
|
|
|
withSuperAdminContext bool
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
fields fields
|
|
|
|
|
args args
|
2017-10-09 21:16:24 +00:00
|
|
|
|
id string
|
2017-03-10 19:24:48 +00:00
|
|
|
|
wantStatus int
|
|
|
|
|
wantContentType string
|
|
|
|
|
wantBody string
|
|
|
|
|
}{
|
|
|
|
|
{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
name: "Update a Chronograf user",
|
2017-03-10 19:24:48 +00:00
|
|
|
|
fields: fields{
|
2017-10-09 21:16:24 +00:00
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
UpdateF: func(ctx context.Context, user *chronograf.User) error {
|
2017-03-10 19:24:48 +00:00
|
|
|
|
return nil
|
|
|
|
|
},
|
2017-10-18 18:17:42 +00:00
|
|
|
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
|
|
|
|
switch *q.ID {
|
|
|
|
|
case 1336:
|
2017-10-09 21:16:24 +00:00
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1336,
|
2017-10-24 21:20:24 +00:00
|
|
|
|
Name: "bobbetta",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-13 00:42:30 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-13 00:42:30 +00:00
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}, nil
|
|
|
|
|
default:
|
2017-10-24 21:21:29 +00:00
|
|
|
|
return nil, fmt.Errorf("User with ID %d not found", *q.ID)
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
2017-10-09 21:16:24 +00:00
|
|
|
|
"PATCH",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
2017-10-13 19:34:30 +00:00
|
|
|
|
user: &userRequest{
|
2017-10-24 21:20:24 +00:00
|
|
|
|
ID: 1336,
|
2017-10-16 23:26:08 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.AdminRole,
|
2017-10-13 00:42:30 +00:00
|
|
|
|
},
|
2017-03-10 19:24:48 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
2017-10-09 21:16:24 +00:00
|
|
|
|
id: "1336",
|
2017-03-10 19:24:48 +00:00
|
|
|
|
wantStatus: http.StatusOK,
|
|
|
|
|
wantContentType: "application/json",
|
2017-11-01 13:12:19 +00:00
|
|
|
|
wantBody: `{"id":"1336","superAdmin":false,"name":"bobbetta","provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/1336"},"roles":[{"name":"admin"}]}`,
|
2017-10-10 18:40:33 +00:00
|
|
|
|
},
|
2017-11-03 16:06:18 +00:00
|
|
|
|
{
|
|
|
|
|
name: "Update a Chronograf user roles different orgs",
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
UpdateF: func(ctx context.Context, user *chronograf.User) error {
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
|
|
|
|
switch *q.ID {
|
|
|
|
|
case 1336:
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
Name: "bobbetta",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
EditorRole,
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("User with ID %d not found", *q.ID)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"PATCH",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
{
|
|
|
|
|
Name: AdminRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: ViewerRoleName,
|
|
|
|
|
Organization: "billieta org",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
id: "1336",
|
|
|
|
|
wantStatus: http.StatusOK,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"id":"1336","superAdmin":false,"name":"bobbetta","provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/1336"},"roles":[{"name":"admin","organization":"bobbetta org"},{"name":"viewer","organization":"billieta org"}]}`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Update a Chronograf user roles same org",
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
UpdateF: func(ctx context.Context, user *chronograf.User) error {
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
|
|
|
|
switch *q.ID {
|
|
|
|
|
case 1336:
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
Name: "bobbetta",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
EditorRole,
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("User with ID %d not found", *q.ID)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"PATCH",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
{
|
|
|
|
|
Name: AdminRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: ViewerRoleName,
|
|
|
|
|
Organization: "bobbetta org",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
id: "1336",
|
|
|
|
|
wantStatus: http.StatusUnprocessableEntity,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"code":422,"message":"duplicate organization \"bobbetta org\" in roles"}`,
|
|
|
|
|
},
|
2017-11-03 16:51:33 +00:00
|
|
|
|
{
|
|
|
|
|
name: "Update a Chronograf user to super admin - without super admin context",
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
UpdateF: func(ctx context.Context, user *chronograf.User) error {
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
|
|
|
|
switch *q.ID {
|
|
|
|
|
case 1336:
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
Name: "bobbetta",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
EditorRole,
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("User with ID %d not found", *q.ID)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"PATCH",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
withSuperAdminContext: false,
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
SuperAdmin: true,
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
AdminRole,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
id: "1336",
|
|
|
|
|
wantStatus: http.StatusUnauthorized,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"code":401,"message":"Cannot set SuperAdmin"}`,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Update a Chronograf user to super admin - with super admin context",
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
UpdateF: func(ctx context.Context, user *chronograf.User) error {
|
|
|
|
|
return nil
|
|
|
|
|
},
|
|
|
|
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
|
|
|
|
switch *q.ID {
|
|
|
|
|
case 1336:
|
|
|
|
|
return &chronograf.User{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
Name: "bobbetta",
|
|
|
|
|
Provider: "github",
|
|
|
|
|
Scheme: "oauth2",
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
EditorRole,
|
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("User with ID %d not found", *q.ID)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"PATCH",
|
|
|
|
|
"http://any.url",
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
withSuperAdminContext: true,
|
|
|
|
|
user: &userRequest{
|
|
|
|
|
ID: 1336,
|
|
|
|
|
SuperAdmin: true,
|
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
AdminRole,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
id: "1336",
|
|
|
|
|
wantStatus: http.StatusOK,
|
|
|
|
|
wantContentType: "application/json",
|
|
|
|
|
wantBody: `{"id":"1336","superAdmin":true,"name":"bobbetta","provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/1336"},"roles":[{"name":"admin"}]}`,
|
|
|
|
|
},
|
2017-03-10 19:24:48 +00:00
|
|
|
|
}
|
|
|
|
|
for _, tt := range tests {
|
2017-10-09 21:16:24 +00:00
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
s := &Service{
|
2017-10-31 20:41:17 +00:00
|
|
|
|
Store: &mocks.Store{
|
|
|
|
|
UsersStore: tt.fields.UsersStore,
|
|
|
|
|
},
|
|
|
|
|
Logger: tt.fields.Logger,
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tt.args.r = tt.args.r.WithContext(httprouter.WithParams(context.Background(),
|
|
|
|
|
httprouter.Params{
|
|
|
|
|
{
|
|
|
|
|
Key: "id",
|
|
|
|
|
Value: tt.id,
|
|
|
|
|
},
|
|
|
|
|
}))
|
|
|
|
|
buf, _ := json.Marshal(tt.args.user)
|
|
|
|
|
tt.args.r.Body = ioutil.NopCloser(bytes.NewReader(buf))
|
2017-02-22 03:36:23 +00:00
|
|
|
|
|
2017-11-03 16:51:33 +00:00
|
|
|
|
ctx := tt.args.r.Context()
|
|
|
|
|
if tt.args.withSuperAdminContext {
|
|
|
|
|
ctx = context.WithValue(ctx, SuperAdminKey, true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tt.args.r = tt.args.r.WithContext(ctx)
|
|
|
|
|
|
2017-10-09 21:16:24 +00:00
|
|
|
|
s.UpdateUser(tt.args.w, tt.args.r)
|
|
|
|
|
|
|
|
|
|
resp := tt.args.w.Result()
|
|
|
|
|
content := resp.Header.Get("Content-Type")
|
|
|
|
|
body, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode != tt.wantStatus {
|
|
|
|
|
t.Errorf("%q. UpdateUser() = %v, want %v", tt.name, resp.StatusCode, tt.wantStatus)
|
|
|
|
|
}
|
|
|
|
|
if tt.wantContentType != "" && content != tt.wantContentType {
|
|
|
|
|
t.Errorf("%q. UpdateUser() = %v, want %v", tt.name, content, tt.wantContentType)
|
|
|
|
|
}
|
|
|
|
|
if eq, _ := jsonEqual(string(body), tt.wantBody); tt.wantBody != "" && !eq {
|
2017-10-24 21:20:24 +00:00
|
|
|
|
t.Errorf("%q. UpdateUser()\ngot:%v\n,\nwant:%v", tt.name, string(body), tt.wantBody)
|
2017-10-09 21:16:24 +00:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-09 22:03:50 +00:00
|
|
|
|
func TestService_Users(t *testing.T) {
|
|
|
|
|
type fields struct {
|
|
|
|
|
UsersStore chronograf.UsersStore
|
|
|
|
|
Logger chronograf.Logger
|
|
|
|
|
}
|
|
|
|
|
type args struct {
|
|
|
|
|
w *httptest.ResponseRecorder
|
|
|
|
|
r *http.Request
|
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
fields fields
|
|
|
|
|
args args
|
|
|
|
|
wantStatus int
|
|
|
|
|
wantContentType string
|
|
|
|
|
wantBody string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "Get all Chronograf users",
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
AllF: func(ctx context.Context) ([]chronograf.User, error) {
|
|
|
|
|
return []chronograf.User{
|
|
|
|
|
{
|
|
|
|
|
ID: 1337,
|
|
|
|
|
Name: "billysteve",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "google",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-13 00:42:30 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-13 00:42:30 +00:00
|
|
|
|
},
|
2017-10-09 22:03:50 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
ID: 1338,
|
|
|
|
|
Name: "bobbettastuhvetta",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "auth0",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-09 22:03:50 +00:00
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"GET",
|
|
|
|
|
"http://any.url", // can be any valid URL as we are bypassing mux
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
wantStatus: http.StatusOK,
|
|
|
|
|
wantContentType: "application/json",
|
2017-11-01 13:12:19 +00:00
|
|
|
|
wantBody: `{"users":[{"id":"1337","superAdmin":false,"name":"billysteve","provider":"google","scheme":"oauth2","roles":[{"name":"editor"}],"links":{"self":"/chronograf/v1/users/1337"}},{"id":"1338","superAdmin":false,"name":"bobbettastuhvetta","provider":"auth0","scheme":"oauth2","roles":[],"links":{"self":"/chronograf/v1/users/1338"}}],"links":{"self":"/chronograf/v1/users"}}`,
|
2017-10-09 22:03:50 +00:00
|
|
|
|
},
|
2017-10-09 22:19:46 +00:00
|
|
|
|
{
|
|
|
|
|
name: "Get all Chronograf users, ensuring order of users in response",
|
|
|
|
|
fields: fields{
|
|
|
|
|
Logger: log.New(log.DebugLevel),
|
|
|
|
|
UsersStore: &mocks.UsersStore{
|
|
|
|
|
AllF: func(ctx context.Context) ([]chronograf.User, error) {
|
|
|
|
|
return []chronograf.User{
|
|
|
|
|
{
|
|
|
|
|
ID: 1338,
|
|
|
|
|
Name: "bobbettastuhvetta",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "auth0",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-09 22:19:46 +00:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
ID: 1337,
|
|
|
|
|
Name: "billysteve",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "google",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-13 00:42:30 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-13 00:42:30 +00:00
|
|
|
|
},
|
2017-10-09 22:19:46 +00:00
|
|
|
|
},
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
args: args{
|
|
|
|
|
w: httptest.NewRecorder(),
|
|
|
|
|
r: httptest.NewRequest(
|
|
|
|
|
"GET",
|
|
|
|
|
"http://any.url", // can be any valid URL as we are bypassing mux
|
|
|
|
|
nil,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
wantStatus: http.StatusOK,
|
|
|
|
|
wantContentType: "application/json",
|
2017-11-01 13:12:19 +00:00
|
|
|
|
wantBody: `{"users":[{"id":"1337","superAdmin":false,"name":"billysteve","provider":"google","scheme":"oauth2","roles":[{"name":"editor"}],"links":{"self":"/chronograf/v1/users/1337"}},{"id":"1338","superAdmin":false,"name":"bobbettastuhvetta","provider":"auth0","scheme":"oauth2","roles":[],"links":{"self":"/chronograf/v1/users/1338"}}],"links":{"self":"/chronograf/v1/users"}}`,
|
2017-10-09 22:19:46 +00:00
|
|
|
|
},
|
2017-10-09 22:03:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
s := &Service{
|
2017-10-31 20:41:17 +00:00
|
|
|
|
Store: &mocks.Store{
|
|
|
|
|
UsersStore: tt.fields.UsersStore,
|
|
|
|
|
},
|
|
|
|
|
Logger: tt.fields.Logger,
|
2017-10-09 22:03:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.Users(tt.args.w, tt.args.r)
|
|
|
|
|
|
|
|
|
|
resp := tt.args.w.Result()
|
|
|
|
|
content := resp.Header.Get("Content-Type")
|
|
|
|
|
body, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode != tt.wantStatus {
|
|
|
|
|
t.Errorf("%q. Users() = %v, want %v", tt.name, resp.StatusCode, tt.wantStatus)
|
|
|
|
|
}
|
|
|
|
|
if tt.wantContentType != "" && content != tt.wantContentType {
|
|
|
|
|
t.Errorf("%q. Users() = %v, want %v", tt.name, content, tt.wantContentType)
|
|
|
|
|
}
|
|
|
|
|
if eq, _ := jsonEqual(string(body), tt.wantBody); tt.wantBody != "" && !eq {
|
|
|
|
|
t.Errorf("%q. Users() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wantBody)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-16 19:28:15 +00:00
|
|
|
|
|
|
|
|
|
func TestUserRequest_ValidCreate(t *testing.T) {
|
|
|
|
|
type args struct {
|
|
|
|
|
u *userRequest
|
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
args args
|
|
|
|
|
wantErr bool
|
|
|
|
|
err error
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "Valid",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
|
|
|
|
ID: 1337,
|
|
|
|
|
Name: "billietta",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "auth0",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-16 23:26:08 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-16 23:26:08 +00:00
|
|
|
|
},
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: false,
|
|
|
|
|
err: nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid – Name missing",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
|
|
|
|
ID: 1337,
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "auth0",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-16 23:26:08 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-16 23:26:08 +00:00
|
|
|
|
},
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
err: fmt.Errorf("Name required on Chronograf User request body"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid – Provider missing",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
|
|
|
|
ID: 1337,
|
|
|
|
|
Name: "billietta",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Scheme: "oauth2",
|
2017-10-16 23:26:08 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-16 23:26:08 +00:00
|
|
|
|
},
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
err: fmt.Errorf("Provider required on Chronograf User request body"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid – Scheme missing",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
|
|
|
|
ID: 1337,
|
|
|
|
|
Name: "billietta",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "auth0",
|
2017-10-16 23:26:08 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-16 23:26:08 +00:00
|
|
|
|
},
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
err: fmt.Errorf("Scheme required on Chronograf User request body"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid roles",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
|
|
|
|
ID: 1337,
|
|
|
|
|
Name: "billietta",
|
2017-10-24 23:17:59 +00:00
|
|
|
|
Provider: "auth0",
|
|
|
|
|
Scheme: "oauth2",
|
2017-10-16 23:26:08 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
|
|
|
|
{
|
|
|
|
|
Name: "BilliettaSpecialRole",
|
|
|
|
|
},
|
|
|
|
|
},
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
2017-11-03 20:32:05 +00:00
|
|
|
|
err: fmt.Errorf("Unknown role BilliettaSpecialRole. Valid roles are 'member', 'viewer', 'editor', 'admin', and 'superadmin'"),
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
err := tt.args.u.ValidCreate()
|
|
|
|
|
|
|
|
|
|
if tt.wantErr {
|
|
|
|
|
if err == nil || err.Error() != tt.err.Error() {
|
|
|
|
|
t.Errorf("%q. ValidCreate(): wantErr %v,\nwant %v,\ngot %v", tt.name, tt.wantErr, tt.err, err)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Errorf("%q. ValidCreate(): wantErr %v,\nwant %v,\ngot %v", tt.name, tt.wantErr, tt.err, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestUserRequest_ValidUpdate(t *testing.T) {
|
|
|
|
|
type args struct {
|
|
|
|
|
u *userRequest
|
|
|
|
|
}
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
args args
|
|
|
|
|
wantErr bool
|
|
|
|
|
err error
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "Valid",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
2017-10-24 21:20:24 +00:00
|
|
|
|
ID: 1337,
|
2017-10-16 23:26:08 +00:00
|
|
|
|
Roles: []chronograf.Role{
|
2017-11-03 20:32:05 +00:00
|
|
|
|
roles.EditorRole,
|
2017-10-16 23:26:08 +00:00
|
|
|
|
},
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: false,
|
|
|
|
|
err: nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
2017-10-24 21:20:24 +00:00
|
|
|
|
name: "Invalid – roles missing",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
err: fmt.Errorf("No Roles to update"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid: field missing",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
err: fmt.Errorf("No Roles to update"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid: Name attempted",
|
2017-10-16 19:28:15 +00:00
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
2017-10-24 21:20:24 +00:00
|
|
|
|
Name: "bob",
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
2017-10-24 21:20:24 +00:00
|
|
|
|
err: fmt.Errorf("Cannot update Name"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid: Provider attempted",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
|
|
|
|
Provider: "Goggles",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
err: fmt.Errorf("Cannot update Provider"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Invalid: Scheme attempted",
|
|
|
|
|
args: args{
|
|
|
|
|
u: &userRequest{
|
|
|
|
|
Scheme: "leDAP",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
err: fmt.Errorf("Cannot update Scheme"),
|
2017-10-16 19:28:15 +00:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
err := tt.args.u.ValidUpdate()
|
|
|
|
|
|
|
|
|
|
if tt.wantErr {
|
|
|
|
|
if err == nil || err.Error() != tt.err.Error() {
|
2017-10-24 21:20:24 +00:00
|
|
|
|
t.Errorf("%q. ValidUpdate(): wantErr %v,\nwant %v,\ngot %v", tt.name, tt.wantErr, tt.err, err)
|
2017-10-16 19:28:15 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if err != nil {
|
2017-10-24 21:20:24 +00:00
|
|
|
|
t.Errorf("%q. ValidUpdate(): wantErr %v,\nwant %v,\ngot %v", tt.name, tt.wantErr, tt.err, err)
|
2017-10-16 19:28:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|