commit
3628a9d05d
219
handler.go
219
handler.go
|
@ -232,7 +232,7 @@ func (h *Handler) serveCreateDatabase(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *Handler) serveDeleteDatabase(w http.ResponseWriter, r *http.Request) {
|
||||
name := r.URL.Query().Get(":name")
|
||||
if err := h.server.DeleteDatabase(name); err == ErrDatabaseNotFound {
|
||||
h.error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
|
||||
h.error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
} else if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
|
@ -245,33 +245,90 @@ func (h *Handler) serveDeleteDatabase(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *Handler) serveAuthenticateClusterAdmin(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
// serveClusterAdmins returns data about a single cluster admin.
|
||||
func (h *Handler) serveClusterAdmins(w http.ResponseWriter, r *http.Request) {}
|
||||
func (h *Handler) serveClusterAdmins(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
||||
type adminPublic struct {
|
||||
Name string `json:"name"`
|
||||
IsUserDeleted bool `json:"isUserDeleted"`
|
||||
}
|
||||
|
||||
// Get the cluster admins from the server.
|
||||
admins := h.server.ClusterAdmins()
|
||||
|
||||
// Create a list of cluster admins containing only the fields
|
||||
// we want to publish.
|
||||
adminsPublic := make([]*adminPublic, 0, len(admins))
|
||||
for _, admin := range admins {
|
||||
adminPublic := &adminPublic{
|
||||
Name: admin.Name,
|
||||
IsUserDeleted: admin.IsUserDeleted,
|
||||
}
|
||||
adminsPublic = append(adminsPublic, adminPublic)
|
||||
}
|
||||
|
||||
w.Header().Add("content-type", "application/json")
|
||||
if err := json.NewEncoder(w).Encode(adminsPublic); err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// serveCreateClusterAdmin creates a new cluster admin.
|
||||
func (h *Handler) serveCreateClusterAdmin(w http.ResponseWriter, r *http.Request) {}
|
||||
func (h *Handler) serveCreateClusterAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
||||
u := &dbUserPub{}
|
||||
if err := json.NewDecoder(r.Body).Decode(u); err != nil {
|
||||
h.error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.server.CreateClusterAdmin(u.Name, u.Password); err == ErrClusterAdminExists {
|
||||
h.error(w, err.Error(), http.StatusConflict)
|
||||
return
|
||||
} else if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// serveUpdateClusterAdmin updates an existing cluster admin.
|
||||
func (h *Handler) serveUpdateClusterAdmin(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
// serveDeleteClusterAdmin removes an existing cluster admin.
|
||||
func (h *Handler) serveDeleteClusterAdmin(w http.ResponseWriter, r *http.Request) {}
|
||||
func (h *Handler) serveDeleteClusterAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
||||
urlQry := r.URL.Query()
|
||||
|
||||
if err := h.server.DeleteClusterAdmin(urlQry.Get(":user")); err == ErrClusterAdminNotFound {
|
||||
h.error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
} else if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// serveAuthenticateDBUser authenticates a user as a database user.
|
||||
func (h *Handler) serveAuthenticateDBUser(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
// serveDBUsers returns data about a single database user.
|
||||
func (h *Handler) serveDBUsers(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
type userJSON struct {
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
IsAdmin bool `json:"isAdmin"`
|
||||
ReadFrom []*Matcher `json:"readFrom"`
|
||||
WriteTo []*Matcher `json:"writeTo"`
|
||||
// dbUserPub represents the externally available DB user fields.
|
||||
type dbUserPub struct {
|
||||
Name string `json:"name",omitempty`
|
||||
Password string `json:"password",omitempty`
|
||||
IsAdmin bool `json:"isAdmin",omitempty`
|
||||
ReadFrom []*Matcher `json:"readFrom",omitempty`
|
||||
WriteTo []*Matcher `json:"writeTo",omitempty`
|
||||
}
|
||||
|
||||
func newUserJSONFromDBUser(dbu *DBUser) *userJSON {
|
||||
return &userJSON{
|
||||
// newDBUserPubFromDBUser takes a DBUser and returns a dbUserPub, which
|
||||
// contains only whitelisted fields.
|
||||
func newDBUserPubFromDBUser(dbu *DBUser) *dbUserPub {
|
||||
return &dbUserPub{
|
||||
Name: dbu.Name,
|
||||
IsAdmin: dbu.IsAdmin,
|
||||
WriteTo: dbu.WriteTo,
|
||||
|
@ -279,6 +336,58 @@ func newUserJSONFromDBUser(dbu *DBUser) *userJSON {
|
|||
}
|
||||
}
|
||||
|
||||
// serveDBUsers returns data about a single database user.
|
||||
func (h *Handler) serveDBUsers(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
||||
urlQry := r.URL.Query()
|
||||
|
||||
db := h.server.Database(urlQry.Get(":db"))
|
||||
if db == nil {
|
||||
h.error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
users := db.Users()
|
||||
usersPub := make([]*dbUserPub, 0, len(users))
|
||||
for _, user := range users {
|
||||
usersPub = append(usersPub, newDBUserPubFromDBUser(user))
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(usersPub); err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// serveDBUser returns data about a single database user.
|
||||
func (h *Handler) serveDBUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
||||
urlQry := r.URL.Query()
|
||||
|
||||
db := h.server.Database(urlQry.Get(":db"))
|
||||
if db == nil {
|
||||
h.error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
user := db.User(urlQry.Get(":user"))
|
||||
if user == nil {
|
||||
h.error(w, ErrUserNotFound.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
userPub := newDBUserPubFromDBUser(user)
|
||||
|
||||
w.Header().Add("content-type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(userPub)
|
||||
if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// serveCreateDBUser creates a new database user.
|
||||
func (h *Handler) serveCreateDBUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
@ -291,22 +400,23 @@ func (h *Handler) serveCreateDBUser(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
nu := &userJSON{}
|
||||
if err := json.NewDecoder(r.Body).Decode(nu); err != nil {
|
||||
u := &dbUserPub{}
|
||||
if err := json.NewDecoder(r.Body).Decode(u); err != nil {
|
||||
h.error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.CreateUser(nu.Name, nu.Password, nu.ReadFrom, nu.WriteTo); err != nil {
|
||||
if err := db.CreateUser(u.Name, u.Password, u.ReadFrom, u.WriteTo); err == ErrUserExists {
|
||||
h.error(w, err.Error(), http.StatusConflict)
|
||||
return
|
||||
} else if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: handle IsAdmin
|
||||
}
|
||||
|
||||
// serveDBUser returns data about a single database user.
|
||||
func (h *Handler) serveDBUser(w http.ResponseWriter, r *http.Request) {
|
||||
// serveUpdateDBUser updates an existing database user.
|
||||
func (h *Handler) serveUpdateDBUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
||||
urlQry := r.URL.Query()
|
||||
|
@ -317,27 +427,66 @@ func (h *Handler) serveDBUser(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
dbUser := db.User(urlQry.Get(":user"))
|
||||
if dbUser == nil {
|
||||
user := db.User(urlQry.Get(":user"))
|
||||
if user == nil {
|
||||
h.error(w, ErrUserNotFound.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
userJSON := newUserJSONFromDBUser(dbUser)
|
||||
var update struct {
|
||||
Password *string `json:"password"`
|
||||
ReadFrom *[]*Matcher `json:"readFrom"`
|
||||
WriteTo *[]*Matcher `json:"writeTo"`
|
||||
IsAdmin *bool `json:"isAdmin"`
|
||||
}
|
||||
|
||||
w.Header().Add("content-type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(userJSON)
|
||||
if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
if err := json.NewDecoder(r.Body).Decode(&update); err != nil {
|
||||
h.error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if update.Password != nil {
|
||||
if err := db.ChangePassword(user.Name, *update.Password); err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if update.ReadFrom != nil {
|
||||
user.ReadFrom = *update.ReadFrom
|
||||
}
|
||||
|
||||
if update.WriteTo != nil {
|
||||
user.WriteTo = *update.WriteTo
|
||||
}
|
||||
|
||||
if update.IsAdmin != nil {
|
||||
user.IsAdmin = *update.IsAdmin
|
||||
}
|
||||
}
|
||||
|
||||
// serveUpdateDBUser updates an existing database user.
|
||||
func (h *Handler) serveUpdateDBUser(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
// serveDeleteDBUser removes an existing database user.
|
||||
func (h *Handler) serveDeleteDBUser(w http.ResponseWriter, r *http.Request) {}
|
||||
func (h *Handler) serveDeleteDBUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO: Authentication
|
||||
|
||||
urlQry := r.URL.Query()
|
||||
|
||||
db := h.server.Database(urlQry.Get(":db"))
|
||||
if db == nil {
|
||||
h.error(w, ErrDatabaseNotFound.Error(), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.DeleteUser(urlQry.Get(":user")); err == ErrUserNotFound {
|
||||
h.error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
} else if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// servePing returns a simple response to let the client know the server is running.
|
||||
func (h *Handler) servePing(w http.ResponseWriter, r *http.Request) {}
|
||||
|
@ -361,6 +510,7 @@ func (h *Handler) serveShards(w http.ResponseWriter, r *http.Request) {
|
|||
err := json.NewEncoder(w).Encode(shards)
|
||||
if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,6 +536,7 @@ func (h *Handler) serveShardsByRetentionPolicy(w http.ResponseWriter, r *http.Re
|
|||
err := json.NewEncoder(w).Encode(policy.Shards)
|
||||
if err != nil {
|
||||
h.error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,8 +620,6 @@ func (h *Handler) serveUpdateRetentionPolicy(w http.ResponseWriter, r *http.Requ
|
|||
|
||||
// Update the policy
|
||||
*policy = *newPolicy
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// serveDeleteRetentionPolicy removes an existing retention policy.
|
||||
|
|
610
handler_test.go
610
handler_test.go
|
@ -12,17 +12,22 @@ import (
|
|||
"github.com/influxdb/influxdb"
|
||||
)
|
||||
|
||||
func init() {
|
||||
influxdb.BcryptCost = 4
|
||||
}
|
||||
|
||||
func TestHandler_Databases(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
srvr.CreateDatabase("bar")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `[{"name":"bar"},{"name":"foo"}]` {
|
||||
} else if body != `[{"name":"bar"},{"name":"foo"}]` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -31,11 +36,12 @@ func TestHandler_CreateDatabase(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("POST", s.URL+`/db`, `{"name": "foo"}`)
|
||||
|
||||
if status != http.StatusCreated {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `` {
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -44,11 +50,12 @@ func TestHandler_CreateDatabase_BadRequest_NoName(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("POST", s.URL+`/db`, `{"BadRequest": 1}`)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `database name required` {
|
||||
} else if body != `database name required` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -57,11 +64,12 @@ func TestHandler_CreateDatabase_BadRequest_InvalidJSON(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("POST", s.URL+`/db`, `"BadRequest": 1`)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `json: cannot unmarshal string into Go value of type struct { Name string "json:\"name\"" }` {
|
||||
} else if body != `json: cannot unmarshal string into Go value of type struct { Name string "json:\"name\"" }` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -71,11 +79,12 @@ func TestHandler_CreateDatabase_Conflict(t *testing.T) {
|
|||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("POST", s.URL+`/db`, `{"name": "foo"}`)
|
||||
|
||||
if status != http.StatusConflict {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `database exists` {
|
||||
} else if body != `database exists` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -85,11 +94,12 @@ func TestHandler_DeleteDatabase(t *testing.T) {
|
|||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo`, "")
|
||||
|
||||
if status != http.StatusNoContent {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "" {
|
||||
} else if body != "" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -98,11 +108,12 @@ func TestHandler_DeleteDatabase_NotFound(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `database not found` {
|
||||
} else if body != `database not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -115,11 +126,12 @@ func TestHandler_Shards(t *testing.T) {
|
|||
db.CreateShardsIfNotExists("bar", time.Time{})
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/shards`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `[{"id":3,"startTime":"0001-01-01T00:00:00Z","endTime":"0001-01-01T00:00:00Z"}]` {
|
||||
} else if body != `[{"id":3,"startTime":"0001-01-01T00:00:00Z","endTime":"0001-01-01T00:00:00Z"}]` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -128,11 +140,12 @@ func TestHandler_Shards_DatabaseNotFound(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/shards`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `database not found` {
|
||||
} else if body != `database not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -144,11 +157,12 @@ func TestHandler_RetentionPolicies(t *testing.T) {
|
|||
db.CreateRetentionPolicy(influxdb.NewRetentionPolicy("bar"))
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/retention_policies`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `[{"name":"bar","replicaN":1,"splitN":1}]` {
|
||||
} else if body != `[{"name":"bar","replicaN":1,"splitN":1}]` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -157,11 +171,12 @@ func TestHandler_RetentionPolicies_DatabaseNotFound(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/retention_policies`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `database not found` {
|
||||
} else if body != `database not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -171,12 +186,13 @@ func TestHandler_CreateRetentionPolicy(t *testing.T) {
|
|||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
policy := `{"name": "bar", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
||||
|
||||
if status != http.StatusCreated {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "" {
|
||||
} else if body != "" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -185,12 +201,13 @@ func TestHandler_CreateRetentionPolicy_DatabaseNotFound(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
policy := `{"name": "bar", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "database not found" {
|
||||
} else if body != "database not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -202,11 +219,12 @@ func TestHandler_CreateRetentionPolicy_Conflict(t *testing.T) {
|
|||
defer s.Close()
|
||||
policy := `{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
||||
MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
||||
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
||||
|
||||
if status != http.StatusConflict {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "retention policy exists" {
|
||||
} else if body != "retention policy exists" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -216,12 +234,13 @@ func TestHandler_CreateRetentionPolicy_BadRequest(t *testing.T) {
|
|||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
policy := `{"name": "bar", "duration": "**BAD**", "replicaN": 1, "splitN": 2}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies`, policy)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "json: cannot unmarshal string into Go value of type time.Duration" {
|
||||
} else if body != "json: cannot unmarshal string into Go value of type time.Duration" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -238,13 +257,12 @@ func TestHandler_UpdateRetentionPolicy(t *testing.T) {
|
|||
|
||||
newPolicy := `{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies/bar`, newPolicy)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "" {
|
||||
} else if body != "" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
if policy.Name != "newName" {
|
||||
} else if policy.Name != "newName" {
|
||||
t.Fatalf("unexpected policy name: %s", policy.Name)
|
||||
}
|
||||
}
|
||||
|
@ -261,10 +279,10 @@ func TestHandler_UpdateRetentionPolicy_BadRequest(t *testing.T) {
|
|||
|
||||
newPolicy := `{"name": "newName", "duration": "BadRequest", "replicaN": 1, "splitN": 2}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies/bar`, newPolicy)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "json: cannot unmarshal string into Go value of type time.Duration" {
|
||||
} else if body != "json: cannot unmarshal string into Go value of type time.Duration" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -276,10 +294,10 @@ func TestHandler_UpdateRetentionPolicy_DatabaseNotFound(t *testing.T) {
|
|||
|
||||
newPolicy := `{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies/bar`, newPolicy)
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "database not found" {
|
||||
} else if body != "database not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -292,10 +310,10 @@ func TestHandler_UpdateRetentionPolicy_NotFound(t *testing.T) {
|
|||
|
||||
newPolicy := `{"name": "newName", "duration": 1000000, "replicaN": 1, "splitN": 2}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/retention_policies/bar`, newPolicy)
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "retention policy not found" {
|
||||
} else if body != "retention policy not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -307,11 +325,12 @@ func TestHandler_DeleteRetentionPolicy(t *testing.T) {
|
|||
db.CreateRetentionPolicy(influxdb.NewRetentionPolicy("bar"))
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo/retention_policies/bar`, "")
|
||||
|
||||
if status != http.StatusNoContent {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "" {
|
||||
} else if body != "" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -320,11 +339,12 @@ func TestHandler_DeleteRetentionPolicy_DatabaseNotFound(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo/retention_policies/bar`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "database not found" {
|
||||
} else if body != "database not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -334,11 +354,12 @@ func TestHandler_DeleteRetentionPolicy_NotFound(t *testing.T) {
|
|||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo/retention_policies/bar`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "retention policy not found" {
|
||||
} else if body != "retention policy not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -352,11 +373,12 @@ func TestHandler_ShardsByRetentionPolicy(t *testing.T) {
|
|||
policy.Shards = append(policy.Shards, &influxdb.Shard{ID: 42})
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/retention_policies/bar/shards`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `[{"id":42,"startTime":"0001-01-01T00:00:00Z","endTime":"0001-01-01T00:00:00Z"}]` {
|
||||
} else if body != `[{"id":42,"startTime":"0001-01-01T00:00:00Z","endTime":"0001-01-01T00:00:00Z"}]` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -365,11 +387,12 @@ func TestHandler_ShardsByRetentionPolicy_DatabaseNotFound(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/retention_policies/bar/shards`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "database not found" {
|
||||
} else if body != "database not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -379,11 +402,12 @@ func TestHandler_ShardsByRetentionPolicy_PolicyNotFound(t *testing.T) {
|
|||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/retention_policies/bar/shards`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "retention policy not found" {
|
||||
} else if body != "retention policy not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -392,12 +416,69 @@ func TestHandler_Ping(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, _ := MustHTTP("GET", s.URL+`/ping`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_Users_NoUsers(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/users`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != "[]" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_Users_OneUser(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/users`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `[{"name":"jdoe","password":"","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}]` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_Users_MultipleUsers(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
db.CreateUser("mclark", "1337", readFrom, writeTo)
|
||||
db.CreateUser("csmith", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/users`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `[{"name":"csmith","password":"","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]},{"name":"jdoe","password":"","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]},{"name":"mclark","password":"","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}]` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_CreateDBUser(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
|
@ -406,10 +487,10 @@ func TestHandler_CreateDBUser(t *testing.T) {
|
|||
|
||||
newUser := `{"name":"jdoe","password":"1337","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users`, newUser)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "" {
|
||||
} else if body != "" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -421,10 +502,10 @@ func TestHandler_CreateDBUser_DatabaseNotFound(t *testing.T) {
|
|||
|
||||
newUser := `{"name":"jdoe","password":"1337","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users`, newUser)
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != "database not found" {
|
||||
} else if body != "database not found" {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -437,10 +518,10 @@ func TestHandler_CreateDBUser_BadRequest(t *testing.T) {
|
|||
|
||||
newUser := `{"name":0xBAD,"password":"1337","isAdmin":true,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users`, newUser)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `invalid character 'x' after object key:value pair` {
|
||||
} else if body != `invalid character 'x' after object key:value pair` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -453,10 +534,10 @@ func TestHandler_CreateDBUser_InternalServerError(t *testing.T) {
|
|||
|
||||
newUser := `{"name":"","password":"1337","isAdmin":true,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users`, newUser)
|
||||
|
||||
if status != http.StatusInternalServerError {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `username required` {
|
||||
} else if body != `username required` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -470,11 +551,12 @@ func TestHandler_DBUser(t *testing.T) {
|
|||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/users/jdoe`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `{"name":"jdoe","password":"","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}` {
|
||||
} else if body != `{"name":"jdoe","password":"","isAdmin":false,"readFrom":[{"IsRegex":true,"Name":".*"}],"writeTo":[{"IsRegex":true,"Name":".*"}]}` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -483,11 +565,12 @@ func TestHandler_DBUser_DatabaseNotFound(t *testing.T) {
|
|||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/users/jdoe`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
}
|
||||
if body != `database not found` {
|
||||
} else if body != `database not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
@ -501,11 +584,408 @@ func TestHandler_DBUser_UserNotFound(t *testing.T) {
|
|||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/db/foo/users/jane`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `user not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
if body != `user not found` {
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_DatabaseNotFound(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `database not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_UserNotFound(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `user not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_BadRequest(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
badRequest := `{10: "7331"}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, badRequest)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `invalid character '1' looking for beginning of object key string` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_Password(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
origHash := db.User("jdoe").Hash
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
updatedUser := `{"password": "7331"}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, updatedUser)
|
||||
|
||||
newHash := db.User("jdoe").Hash
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
} else if newHash == origHash {
|
||||
t.Fatalf("expected password hash to change")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_PasswordBadRequest(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
updatedUser := `{"password": 10}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, updatedUser)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `json: cannot unmarshal number into Go value of type string` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_Password_InternalServerError(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
updatedUser := `{"password": ""}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, updatedUser)
|
||||
|
||||
if status != http.StatusInternalServerError {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `Password must be more than 4 and less than 56 characters` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_ReadFrom(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
updatedUser := `{"readFrom":[{"IsRegex":true,"Name":"changed"}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, updatedUser)
|
||||
newReadFrom := db.User("jdoe").ReadFrom[0].Name
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
} else if newReadFrom != "changed" {
|
||||
t.Fatalf("unexpected readFrom: %s", newReadFrom)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_ReadFrom_BadRequest(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
badRequest := `{"readFrom":10}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, badRequest)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `json: cannot unmarshal number into Go value of type []*influxdb.Matcher` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_WriteTo(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
updatedUser := `{"writeTo":[{"IsRegex":true,"Name":"changed"}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, updatedUser)
|
||||
|
||||
newWriteTo := db.User("jdoe").WriteTo[0].Name
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
} else if newWriteTo != "changed" {
|
||||
t.Fatalf("unexpected writeTo: %s", newWriteTo)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_WriteTo_BadRequest(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
badRequest := `{"writeTo":10}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, badRequest)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `json: cannot unmarshal number into Go value of type []*influxdb.Matcher` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_IsAdmin(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
updatedUser := `{"isAdmin": true}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, updatedUser)
|
||||
|
||||
newIsAdmin := db.User("jdoe").IsAdmin
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
} else if newIsAdmin == false {
|
||||
t.Fatalf("unexpected newIsAdmin: %s", newIsAdmin)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_UpdateDBUser_IsAdmin_BadRequest(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
badRequest := `{"isAdmin": "BadRequest"}]}`
|
||||
status, body := MustHTTP("POST", s.URL+`/db/foo/users/jdoe`, badRequest)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `json: cannot unmarshal string into Go value of type bool` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_DeleteDBUser(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
db := srvr.Database("foo")
|
||||
readFrom := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
writeTo := []*influxdb.Matcher{{IsRegex: true, Name: ".*"}}
|
||||
db.CreateUser("jdoe", "1337", readFrom, writeTo)
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo/users/jdoe`, "")
|
||||
|
||||
if status != http.StatusNoContent {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_DeleteDBUser_DatabaseNotFound(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo/users/jdoe`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `database not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_DeleteDBUser_UserNotFound(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateDatabase("foo")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/db/foo/users/jdoe`, "")
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `user not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_ClusterAdmins(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateClusterAdmin("jdoe", "1337")
|
||||
srvr.CreateClusterAdmin("mclark", "7331")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("GET", s.URL+`/cluster_admins`, "")
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `[{"name":"jdoe","isUserDeleted":false},{"name":"mclark","isUserDeleted":false}]` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_CreateClusterAdmin(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
newAdmin := `{"name":"jdoe","password":"1337"}`
|
||||
status, body := MustHTTP("POST", s.URL+`/cluster_admins`, newAdmin)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_CreateClusterAdmin_BadRequest(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
newAdmin := `{BadRequest:"jdoe","password":"1337"}`
|
||||
status, body := MustHTTP("POST", s.URL+`/cluster_admins`, newAdmin)
|
||||
|
||||
if status != http.StatusBadRequest {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `invalid character 'B' looking for beginning of object key string` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_CreateClusterAdmin_Conflict(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateClusterAdmin("jdoe", "1337")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
newAdmin := `{"name":"jdoe","password":"1337"}`
|
||||
status, body := MustHTTP("POST", s.URL+`/cluster_admins`, newAdmin)
|
||||
|
||||
if status != http.StatusConflict {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `cluster admin exists` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_CreateClusterAdmin_InternalServerError(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
newAdmin := `{"name":"jdoe","password":""}`
|
||||
status, body := MustHTTP("POST", s.URL+`/cluster_admins`, newAdmin)
|
||||
|
||||
if status != http.StatusInternalServerError {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `Password must be more than 4 and less than 56 characters` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_DeleteClusterAdmin(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
srvr.CreateClusterAdmin("jdoe", "1337")
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/cluster_admins/jdoe`, ``)
|
||||
|
||||
if status != http.StatusNoContent {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandler_DeleteClusterAdmin_NotFound(t *testing.T) {
|
||||
srvr := OpenServer(NewMessagingClient())
|
||||
s := NewHTTPServer(srvr)
|
||||
defer s.Close()
|
||||
|
||||
status, body := MustHTTP("DELETE", s.URL+`/cluster_admins/jdoe`, ``)
|
||||
|
||||
if status != http.StatusNotFound {
|
||||
t.Fatalf("unexpected status: %d", status)
|
||||
} else if body != `cluster admin not found` {
|
||||
t.Fatalf("unexpected body: %s", body)
|
||||
}
|
||||
}
|
||||
|
|
3
user.go
3
user.go
|
@ -10,6 +10,7 @@ import (
|
|||
)
|
||||
|
||||
var userCache = cache.New(0, 0)
|
||||
var BcryptCost = 10
|
||||
|
||||
type Matcher struct {
|
||||
IsRegex bool
|
||||
|
@ -146,7 +147,7 @@ func HashPassword(password string) ([]byte, error) {
|
|||
|
||||
// The second arg is the cost of the hashing, higher is slower but makes it harder
|
||||
// to brute force, since it will be really slow and impractical
|
||||
return bcrypt.GenerateFromPassword([]byte(password), 10)
|
||||
return bcrypt.GenerateFromPassword([]byte(password), BcryptCost)
|
||||
}
|
||||
|
||||
// isValidName returns true if the name contains no invalid characters.
|
||||
|
|
Loading…
Reference in New Issue