1951 lines
55 KiB
Go
1951 lines
55 KiB
Go
package server
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"fmt"
|
||
"net/http"
|
||
"net/http/httptest"
|
||
"testing"
|
||
|
||
"github.com/influxdata/influxdb/v2/chronograf"
|
||
"github.com/influxdata/influxdb/v2/chronograf/mocks"
|
||
"github.com/influxdata/influxdb/v2/chronograf/oauth2"
|
||
"github.com/influxdata/influxdb/v2/chronograf/roles"
|
||
)
|
||
|
||
func TestAuthorizedToken(t *testing.T) {
|
||
var tests = []struct {
|
||
Desc string
|
||
Code int
|
||
Principal oauth2.Principal
|
||
ValidateErr error
|
||
Expected string
|
||
}{
|
||
{
|
||
Desc: "Error in validate",
|
||
Code: http.StatusForbidden,
|
||
ValidateErr: errors.New("error"),
|
||
},
|
||
{
|
||
Desc: "Authorized ok",
|
||
Code: http.StatusOK,
|
||
Principal: oauth2.Principal{
|
||
Subject: "Principal Strickland",
|
||
},
|
||
Expected: "Principal Strickland",
|
||
},
|
||
}
|
||
for _, test := range tests {
|
||
// next is a sentinel StatusOK and
|
||
// principal recorder.
|
||
var principal oauth2.Principal
|
||
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
w.WriteHeader(http.StatusOK)
|
||
principal = r.Context().Value(oauth2.PrincipalKey).(oauth2.Principal)
|
||
})
|
||
req, _ := http.NewRequest("GET", "", nil)
|
||
w := httptest.NewRecorder()
|
||
|
||
a := &mocks.Authenticator{
|
||
Principal: test.Principal,
|
||
ValidateErr: test.ValidateErr,
|
||
}
|
||
|
||
logger := &chronograf.NoopLogger{}
|
||
handler := AuthorizedToken(a, logger, next)
|
||
handler.ServeHTTP(w, req)
|
||
if w.Code != test.Code {
|
||
t.Errorf("Status code expected: %d actual %d", test.Code, w.Code)
|
||
} else if principal != test.Principal {
|
||
t.Errorf("Principal mismatch expected: %s actual %s", test.Principal, principal)
|
||
}
|
||
}
|
||
}
|
||
func TestAuthorizedUser(t *testing.T) {
|
||
type fields struct {
|
||
UsersStore chronograf.UsersStore
|
||
OrganizationsStore chronograf.OrganizationsStore
|
||
Logger chronograf.Logger
|
||
}
|
||
type args struct {
|
||
principal *oauth2.Principal
|
||
scheme string
|
||
useAuth bool
|
||
role string
|
||
}
|
||
tests := []struct {
|
||
name string
|
||
fields fields
|
||
args args
|
||
hasOrganizationContext bool
|
||
hasSuperAdminContext bool
|
||
hasRoleContext bool
|
||
hasServerContext bool
|
||
authorized bool
|
||
}{
|
||
{
|
||
name: "Not using auth",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
useAuth: false,
|
||
},
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: false,
|
||
hasServerContext: true,
|
||
authorized: true,
|
||
},
|
||
{
|
||
name: "User with member role is member authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.MemberRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "member",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with viewer role is member authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.ViewerRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "member",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with editor role is member authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.EditorRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "member",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with admin role is member authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "member",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with viewer role is viewer authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.ViewerRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "viewer",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with editor role is viewer authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.EditorRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "viewer",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with admin role is viewer authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "viewer",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with viewer role is editor unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.ViewerRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "editor",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with editor role is editor authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.EditorRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "editor",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with admin role is editor authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "editor",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with viewer role is admin unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.ViewerRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with editor role is admin unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.EditorRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with admin role is admin authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: false,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "User with no role is viewer unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "view",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with no role is editor unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "editor",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with no role is admin unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with unknown role is viewer unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: "sweet_role",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "viewer",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with unknown role is editor unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: "sweet_role",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "editor",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with unknown role is admin unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: "sweet_role",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with viewer role is SuperAdmin unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.ViewerRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "superadmin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with editor role is SuperAdmin unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.EditorRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "superadmin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "User with admin role is SuperAdmin unauthorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "superadmin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "SuperAdmin is Viewer authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
SuperAdmin: true,
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.MemberRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "viewer",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: true,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "SuperAdmin is Editor authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
SuperAdmin: true,
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.MemberRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "editor",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: true,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "SuperAdmin is Admin authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
SuperAdmin: true,
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.MemberRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: true,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "SuperAdmin is SuperAdmin authorized",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
SuperAdmin: true,
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.MemberRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "superadmin",
|
||
useAuth: true,
|
||
},
|
||
authorized: true,
|
||
hasOrganizationContext: true,
|
||
hasSuperAdminContext: true,
|
||
hasRoleContext: true,
|
||
hasServerContext: false,
|
||
},
|
||
{
|
||
name: "Invalid principal – principal is nil",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: nil,
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "Invalid principal - missing organization",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "Invalid principal - organization id not uint64",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1ee7",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "Failed to retrieve organization",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
switch *q.ID {
|
||
case "1338":
|
||
return &chronograf.Organization{
|
||
ID: "1338",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
default:
|
||
return nil, chronograf.ErrOrganizationNotFound
|
||
}
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billysteve",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
{
|
||
name: "Failed to retrieve user",
|
||
fields: fields{
|
||
UsersStore: &mocks.UsersStore{
|
||
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||
return nil, fmt.Errorf("invalid user query: missing Name, Provider, and/or Scheme")
|
||
}
|
||
switch *q.Name {
|
||
case "billysteve":
|
||
return &chronograf.User{
|
||
ID: 1337,
|
||
Name: "billysteve",
|
||
Provider: "google",
|
||
Scheme: "oauth2",
|
||
Roles: []chronograf.Role{
|
||
{
|
||
Name: roles.AdminRoleName,
|
||
Organization: "1337",
|
||
},
|
||
},
|
||
}, nil
|
||
default:
|
||
return nil, chronograf.ErrUserNotFound
|
||
}
|
||
},
|
||
},
|
||
OrganizationsStore: &mocks.OrganizationsStore{
|
||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||
return &chronograf.Organization{
|
||
ID: "0",
|
||
}, nil
|
||
},
|
||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||
if q.ID == nil {
|
||
return nil, fmt.Errorf("invalid organization query: missing ID")
|
||
}
|
||
return &chronograf.Organization{
|
||
ID: "1337",
|
||
Name: "The ShillBillThrilliettas",
|
||
}, nil
|
||
},
|
||
},
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
principal: &oauth2.Principal{
|
||
Subject: "billietta",
|
||
Issuer: "google",
|
||
Organization: "1337",
|
||
},
|
||
scheme: "oauth2",
|
||
role: "admin",
|
||
useAuth: true,
|
||
},
|
||
authorized: false,
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
var authorized bool
|
||
var hasServerCtx bool
|
||
var hasSuperAdminCtx bool
|
||
var hasOrganizationCtx bool
|
||
var hasRoleCtx bool
|
||
next := func(w http.ResponseWriter, r *http.Request) {
|
||
ctx := r.Context()
|
||
hasServerCtx = hasServerContext(ctx)
|
||
hasSuperAdminCtx = hasSuperAdminContext(ctx)
|
||
_, hasOrganizationCtx = hasOrganizationContext(ctx)
|
||
_, hasRoleCtx = hasRoleContext(ctx)
|
||
authorized = true
|
||
}
|
||
fn := AuthorizedUser(
|
||
&Store{
|
||
UsersStore: tt.fields.UsersStore,
|
||
OrganizationsStore: tt.fields.OrganizationsStore,
|
||
},
|
||
tt.args.useAuth,
|
||
tt.args.role,
|
||
tt.fields.Logger,
|
||
next,
|
||
)
|
||
|
||
w := httptest.NewRecorder()
|
||
r := httptest.NewRequest(
|
||
"GET",
|
||
"http://any.url", // can be any valid URL as we are bypassing mux
|
||
nil,
|
||
)
|
||
if tt.args.principal == nil {
|
||
r = r.WithContext(context.WithValue(r.Context(), oauth2.PrincipalKey, nil))
|
||
} else {
|
||
r = r.WithContext(context.WithValue(r.Context(), oauth2.PrincipalKey, *tt.args.principal))
|
||
}
|
||
fn(w, r)
|
||
|
||
if authorized != tt.authorized {
|
||
t.Errorf("%q. AuthorizedUser() = %v, expected %v", tt.name, authorized, tt.authorized)
|
||
}
|
||
|
||
if !authorized && w.Code != http.StatusForbidden {
|
||
t.Errorf("%q. AuthorizedUser() Status Code = %v, expected %v", tt.name, w.Code, http.StatusForbidden)
|
||
}
|
||
|
||
if hasServerCtx != tt.hasServerContext {
|
||
t.Errorf("%q. AuthorizedUser().Context().Server = %v, expected %v", tt.name, hasServerCtx, tt.hasServerContext)
|
||
}
|
||
|
||
if hasSuperAdminCtx != tt.hasSuperAdminContext {
|
||
t.Errorf("%q. AuthorizedUser().Context().SuperAdmin = %v, expected %v", tt.name, hasSuperAdminCtx, tt.hasSuperAdminContext)
|
||
}
|
||
|
||
if hasOrganizationCtx != tt.hasOrganizationContext {
|
||
t.Errorf("%q. AuthorizedUser.Context().Organization = %v, expected %v", tt.name, hasOrganizationCtx, tt.hasOrganizationContext)
|
||
}
|
||
|
||
if hasRoleCtx != tt.hasRoleContext {
|
||
t.Errorf("%q. AuthorizedUser().Context().Role = %v, expected %v", tt.name, hasRoleCtx, tt.hasRoleContext)
|
||
}
|
||
|
||
})
|
||
}
|
||
}
|
||
|
||
func TestRawStoreAccess(t *testing.T) {
|
||
type fields struct {
|
||
Logger chronograf.Logger
|
||
}
|
||
type args struct {
|
||
principal *oauth2.Principal
|
||
serverContext bool
|
||
user *chronograf.User
|
||
}
|
||
type wants struct {
|
||
authorized bool
|
||
hasServerContext bool
|
||
}
|
||
tests := []struct {
|
||
name string
|
||
fields fields
|
||
args args
|
||
wants wants
|
||
}{
|
||
{
|
||
name: "middleware already has server context",
|
||
fields: fields{
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
serverContext: true,
|
||
},
|
||
wants: wants{
|
||
authorized: true,
|
||
hasServerContext: true,
|
||
},
|
||
},
|
||
{
|
||
name: "user on context is a SuperAdmin",
|
||
fields: fields{
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
user: &chronograf.User{
|
||
SuperAdmin: true,
|
||
},
|
||
},
|
||
wants: wants{
|
||
authorized: true,
|
||
hasServerContext: true,
|
||
},
|
||
},
|
||
{
|
||
name: "user on context is a not SuperAdmin",
|
||
fields: fields{
|
||
Logger: &chronograf.NoopLogger{},
|
||
},
|
||
args: args{
|
||
user: &chronograf.User{
|
||
SuperAdmin: false,
|
||
},
|
||
},
|
||
wants: wants{
|
||
authorized: false,
|
||
hasServerContext: false,
|
||
},
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
var authorized bool
|
||
var hasServerCtx bool
|
||
next := func(w http.ResponseWriter, r *http.Request) {
|
||
ctx := r.Context()
|
||
hasServerCtx = hasServerContext(ctx)
|
||
authorized = true
|
||
}
|
||
fn := RawStoreAccess(
|
||
tt.fields.Logger,
|
||
next,
|
||
)
|
||
|
||
w := httptest.NewRecorder()
|
||
url := "http://any.url"
|
||
r := httptest.NewRequest(
|
||
"GET",
|
||
url,
|
||
nil,
|
||
)
|
||
if tt.args.principal == nil {
|
||
r = r.WithContext(context.WithValue(r.Context(), oauth2.PrincipalKey, nil))
|
||
} else {
|
||
r = r.WithContext(context.WithValue(r.Context(), oauth2.PrincipalKey, *tt.args.principal))
|
||
}
|
||
|
||
if tt.args.serverContext {
|
||
r = r.WithContext(serverContext(r.Context()))
|
||
}
|
||
if tt.args.user != nil {
|
||
r = r.WithContext(context.WithValue(r.Context(), UserContextKey, tt.args.user))
|
||
}
|
||
fn(w, r)
|
||
|
||
if authorized != tt.wants.authorized {
|
||
t.Errorf("%q. RawStoreAccess() = %v, expected %v", tt.name, authorized, tt.wants.authorized)
|
||
}
|
||
|
||
if !authorized && w.Code != http.StatusForbidden {
|
||
t.Errorf("%q. RawStoreAccess() Status Code = %v, expected %v", tt.name, w.Code, http.StatusForbidden)
|
||
}
|
||
|
||
if hasServerCtx != tt.wants.hasServerContext {
|
||
t.Errorf("%q. RawStoreAccess().Context().Server = %v, expected %v", tt.name, hasServerCtx, tt.wants.hasServerContext)
|
||
}
|
||
|
||
})
|
||
}
|
||
}
|