Add tests for influx OSS user permissions
parent
19018c97ca
commit
6d287723a2
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/influxdata/chronograf"
|
"github.com/influxdata/chronograf"
|
||||||
|
@ -90,6 +91,7 @@ func TestClient_userPermissions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_Add(t *testing.T) {
|
func TestClient_Add(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
u *chronograf.User
|
u *chronograf.User
|
||||||
|
@ -161,3 +163,733 @@ func TestClient_Add(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClient_Delete(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
u *chronograf.User
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
status int
|
||||||
|
dropUser []byte
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Drop User",
|
||||||
|
dropUser: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
status: http.StatusOK,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "No such user",
|
||||||
|
dropUser: []byte(`{"results":[{"error":"user not found"}]}`),
|
||||||
|
status: http.StatusOK,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bad InfluxQL",
|
||||||
|
dropUser: []byte(`{"error":"error parsing query: found doody, expected ; at line 1, char 17"}`),
|
||||||
|
status: http.StatusBadRequest,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bad JSON",
|
||||||
|
dropUser: []byte(`{"results":[{"error":breakhere}]}`),
|
||||||
|
status: http.StatusOK,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if path := r.URL.Path; path != "/query" {
|
||||||
|
t.Error("Expected the path to contain `/query` but was", path)
|
||||||
|
}
|
||||||
|
rw.WriteHeader(tt.status)
|
||||||
|
rw.Write(tt.dropUser)
|
||||||
|
}))
|
||||||
|
u, _ := url.Parse(ts.URL)
|
||||||
|
c := &Client{
|
||||||
|
URL: u,
|
||||||
|
Logger: log.New(log.DebugLevel),
|
||||||
|
}
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
if err := c.Delete(tt.args.ctx, tt.args.u); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("%q. Client.Delete() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_Get(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
statusUsers int
|
||||||
|
showUsers []byte
|
||||||
|
statusGrants int
|
||||||
|
showGrants []byte
|
||||||
|
want *chronograf.User
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Get User",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
name: "docbrown",
|
||||||
|
},
|
||||||
|
want: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
chronograf.Permission{
|
||||||
|
Scope: "all",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fail show users",
|
||||||
|
statusUsers: http.StatusBadRequest,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
name: "docbrown",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fail show grants",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusBadRequest,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
name: "docbrown",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fail no such user",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true]]}]}]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
name: "docbrown",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if path := r.URL.Path; path != "/query" {
|
||||||
|
t.Error("Expected the path to contain `/query` but was", path)
|
||||||
|
}
|
||||||
|
query := r.URL.Query().Get("q")
|
||||||
|
if strings.Contains(query, "GRANTS") {
|
||||||
|
rw.WriteHeader(tt.statusGrants)
|
||||||
|
rw.Write(tt.showGrants)
|
||||||
|
} else if strings.Contains(query, "USERS") {
|
||||||
|
rw.WriteHeader(tt.statusUsers)
|
||||||
|
rw.Write(tt.showUsers)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
u, _ := url.Parse(ts.URL)
|
||||||
|
c := &Client{
|
||||||
|
URL: u,
|
||||||
|
Logger: log.New(log.DebugLevel),
|
||||||
|
}
|
||||||
|
defer ts.Close()
|
||||||
|
got, err := c.Get(tt.args.ctx, tt.args.name)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("%q. Client.Get() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("%q. Client.Get() = %v, want %v", tt.name, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_grantPermission(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
username string
|
||||||
|
perm chronograf.Permission
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
status int
|
||||||
|
results []byte
|
||||||
|
wantQuery string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "simple grants",
|
||||||
|
status: http.StatusOK,
|
||||||
|
results: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
username: "docbrown",
|
||||||
|
perm: chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantQuery: `GRANT ALL ON "mydb" TO "docbrown"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bad grants",
|
||||||
|
status: http.StatusOK,
|
||||||
|
results: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
username: "docbrown",
|
||||||
|
perm: chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"howdy"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantQuery: ``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no grants",
|
||||||
|
status: http.StatusOK,
|
||||||
|
results: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
username: "docbrown",
|
||||||
|
perm: chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantQuery: ``,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
query := ""
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if path := r.URL.Path; path != "/query" {
|
||||||
|
t.Error("Expected the path to contain `/query` but was", path)
|
||||||
|
}
|
||||||
|
query = r.URL.Query().Get("q")
|
||||||
|
rw.WriteHeader(tt.status)
|
||||||
|
rw.Write(tt.results)
|
||||||
|
}))
|
||||||
|
u, _ := url.Parse(ts.URL)
|
||||||
|
c := &Client{
|
||||||
|
URL: u,
|
||||||
|
Logger: log.New(log.DebugLevel),
|
||||||
|
}
|
||||||
|
defer ts.Close()
|
||||||
|
if err := c.grantPermission(tt.args.ctx, tt.args.username, tt.args.perm); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("%q. Client.grantPermission() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
}
|
||||||
|
if query != tt.wantQuery {
|
||||||
|
t.Errorf("%q. Client.grantPermission() = %v, want %v", tt.name, query, tt.wantQuery)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_revokePermission(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
username string
|
||||||
|
perm chronograf.Permission
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
status int
|
||||||
|
results []byte
|
||||||
|
wantQuery string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "simple revoke",
|
||||||
|
status: http.StatusOK,
|
||||||
|
results: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
username: "docbrown",
|
||||||
|
perm: chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantQuery: `REVOKE ALL ON "mydb" FROM "docbrown"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bad revoke",
|
||||||
|
status: http.StatusOK,
|
||||||
|
results: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
username: "docbrown",
|
||||||
|
perm: chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"howdy"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantQuery: ``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no permissions",
|
||||||
|
status: http.StatusOK,
|
||||||
|
results: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
username: "docbrown",
|
||||||
|
perm: chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantQuery: `REVOKE ALL PRIVILEGES ON "mydb" FROM "docbrown"`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
query := ""
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if path := r.URL.Path; path != "/query" {
|
||||||
|
t.Error("Expected the path to contain `/query` but was", path)
|
||||||
|
}
|
||||||
|
query = r.URL.Query().Get("q")
|
||||||
|
rw.WriteHeader(tt.status)
|
||||||
|
rw.Write(tt.results)
|
||||||
|
}))
|
||||||
|
u, _ := url.Parse(ts.URL)
|
||||||
|
c := &Client{
|
||||||
|
URL: u,
|
||||||
|
Logger: log.New(log.DebugLevel),
|
||||||
|
}
|
||||||
|
defer ts.Close()
|
||||||
|
if err := c.revokePermission(tt.args.ctx, tt.args.username, tt.args.perm); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("%q. Client.revokePermission() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
}
|
||||||
|
if query != tt.wantQuery {
|
||||||
|
t.Errorf("%q. Client.revokePermission() = %v, want %v", tt.name, query, tt.wantQuery)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_All(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
statusUsers int
|
||||||
|
showUsers []byte
|
||||||
|
statusGrants int
|
||||||
|
showGrants []byte
|
||||||
|
want []chronograf.User
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "All Users",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
},
|
||||||
|
want: []chronograf.User{
|
||||||
|
{
|
||||||
|
Name: "admin",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
chronograf.Permission{
|
||||||
|
Scope: "all",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "docbrown",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
chronograf.Permission{
|
||||||
|
Scope: "all",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "reader",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
chronograf.Permission{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unauthorized",
|
||||||
|
statusUsers: http.StatusUnauthorized,
|
||||||
|
showUsers: []byte(`{}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Permission error",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusBadRequest,
|
||||||
|
showGrants: []byte(`{}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if path := r.URL.Path; path != "/query" {
|
||||||
|
t.Error("Expected the path to contain `/query` but was", path)
|
||||||
|
}
|
||||||
|
query := r.URL.Query().Get("q")
|
||||||
|
if strings.Contains(query, "GRANTS") {
|
||||||
|
rw.WriteHeader(tt.statusGrants)
|
||||||
|
rw.Write(tt.showGrants)
|
||||||
|
} else if strings.Contains(query, "USERS") {
|
||||||
|
rw.WriteHeader(tt.statusUsers)
|
||||||
|
rw.Write(tt.showUsers)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
u, _ := url.Parse(ts.URL)
|
||||||
|
c := &Client{
|
||||||
|
URL: u,
|
||||||
|
Logger: log.New(log.DebugLevel),
|
||||||
|
}
|
||||||
|
defer ts.Close()
|
||||||
|
got, err := c.All(tt.args.ctx)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("%q. Client.All() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("%q. Client.All() = %v, want %v", tt.name, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_Update(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
u *chronograf.User
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
statusUsers int
|
||||||
|
showUsers []byte
|
||||||
|
statusGrants int
|
||||||
|
showGrants []byte
|
||||||
|
statusRevoke int
|
||||||
|
revoke []byte
|
||||||
|
statusGrant int
|
||||||
|
grant []byte
|
||||||
|
args args
|
||||||
|
want []string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Revoke all permissions",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
statusRevoke: http.StatusOK,
|
||||||
|
revoke: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
`SHOW USERS`,
|
||||||
|
`SHOW GRANTS FOR "docbrown"`,
|
||||||
|
`REVOKE ALL PRIVILEGES FROM "docbrown"`,
|
||||||
|
`REVOKE ALL ON "mydb" FROM "docbrown"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Grant all permissions",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
statusRevoke: http.StatusOK,
|
||||||
|
revoke: []byte(`{"results":[]}`),
|
||||||
|
statusGrant: http.StatusOK,
|
||||||
|
grant: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
{
|
||||||
|
Scope: "all",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
`SHOW USERS`,
|
||||||
|
`SHOW GRANTS FOR "docbrown"`,
|
||||||
|
`GRANT ALL PRIVILEGES TO "docbrown"`,
|
||||||
|
`GRANT ALL ON "mydb" TO "docbrown"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Revoke some add some",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
statusRevoke: http.StatusOK,
|
||||||
|
revoke: []byte(`{"results":[]}`),
|
||||||
|
statusGrant: http.StatusOK,
|
||||||
|
grant: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
{
|
||||||
|
Scope: "all",
|
||||||
|
Allowed: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "newdb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
`SHOW USERS`,
|
||||||
|
`SHOW GRANTS FOR "docbrown"`,
|
||||||
|
`GRANT WRITE ON "mydb" TO "docbrown"`,
|
||||||
|
`GRANT ALL ON "newdb" TO "docbrown"`,
|
||||||
|
`REVOKE ALL PRIVILEGES FROM "docbrown"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Fail users",
|
||||||
|
statusUsers: http.StatusBadRequest,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
statusRevoke: http.StatusOK,
|
||||||
|
revoke: []byte(`{"results":[]}`),
|
||||||
|
statusGrant: http.StatusOK,
|
||||||
|
grant: []byte(`{"results":[]}`),
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
want: []string{
|
||||||
|
`SHOW USERS`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail grants",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
statusRevoke: http.StatusOK,
|
||||||
|
revoke: []byte(`{"results":[]}`),
|
||||||
|
statusGrant: http.StatusBadRequest,
|
||||||
|
grant: []byte(`{"results":[]}`),
|
||||||
|
wantErr: true,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
{
|
||||||
|
Scope: "all",
|
||||||
|
Allowed: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "newdb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
`SHOW USERS`,
|
||||||
|
`SHOW GRANTS FOR "docbrown"`,
|
||||||
|
`GRANT WRITE ON "mydb" TO "docbrown"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fail revoke",
|
||||||
|
statusUsers: http.StatusOK,
|
||||||
|
showUsers: []byte(`{"results":[{"series":[{"columns":["user","admin"],"values":[["admin",true],["docbrown",true],["reader",false]]}]}]}`),
|
||||||
|
statusGrants: http.StatusOK,
|
||||||
|
showGrants: []byte(`{"results":[{"series":[{"columns":["database","privilege"],"values":[["mydb","ALL PRIVILEGES"]]}]}]}`),
|
||||||
|
statusRevoke: http.StatusBadRequest,
|
||||||
|
revoke: []byte(`{"results":[]}`),
|
||||||
|
statusGrant: http.StatusOK,
|
||||||
|
grant: []byte(`{"results":[]}`),
|
||||||
|
wantErr: true,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
u: &chronograf.User{
|
||||||
|
Name: "docbrown",
|
||||||
|
Permissions: chronograf.Permissions{
|
||||||
|
{
|
||||||
|
Scope: "all",
|
||||||
|
Allowed: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "mydb",
|
||||||
|
Allowed: []string{"WRITE"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Scope: "database",
|
||||||
|
Name: "newdb",
|
||||||
|
Allowed: []string{"WRITE", "READ"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []string{
|
||||||
|
`SHOW USERS`,
|
||||||
|
`SHOW GRANTS FOR "docbrown"`,
|
||||||
|
`GRANT WRITE ON "mydb" TO "docbrown"`,
|
||||||
|
`GRANT ALL ON "newdb" TO "docbrown"`,
|
||||||
|
`REVOKE ALL PRIVILEGES FROM "docbrown"`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
queries := []string{}
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if path := r.URL.Path; path != "/query" {
|
||||||
|
t.Error("Expected the path to contain `/query` but was", path)
|
||||||
|
}
|
||||||
|
query := r.URL.Query().Get("q")
|
||||||
|
if strings.Contains(query, "GRANTS") {
|
||||||
|
rw.WriteHeader(tt.statusGrants)
|
||||||
|
rw.Write(tt.showGrants)
|
||||||
|
} else if strings.Contains(query, "USERS") {
|
||||||
|
rw.WriteHeader(tt.statusUsers)
|
||||||
|
rw.Write(tt.showUsers)
|
||||||
|
} else if strings.Contains(query, "REVOKE") {
|
||||||
|
rw.WriteHeader(tt.statusRevoke)
|
||||||
|
rw.Write(tt.revoke)
|
||||||
|
} else if strings.Contains(query, "GRANT") {
|
||||||
|
rw.WriteHeader(tt.statusGrant)
|
||||||
|
rw.Write(tt.grant)
|
||||||
|
}
|
||||||
|
queries = append(queries, query)
|
||||||
|
}))
|
||||||
|
u, _ := url.Parse(ts.URL)
|
||||||
|
c := &Client{
|
||||||
|
URL: u,
|
||||||
|
Logger: log.New(log.DebugLevel),
|
||||||
|
}
|
||||||
|
defer ts.Close()
|
||||||
|
if err := c.Update(tt.args.ctx, tt.args.u); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("%q. Client.Update() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(queries, tt.want) {
|
||||||
|
t.Errorf("%q. Client.Update() = %v, want %v", tt.name, queries, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue