Add get of all users for a data source
parent
3fac8f2707
commit
b304ac256e
|
@ -120,3 +120,25 @@ func (s *UsersStore) Update(ctx context.Context, usr *chronograf.User) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All returns all users
|
||||||
|
func (s *UsersStore) All(ctx context.Context) ([]chronograf.User, error) {
|
||||||
|
var users []chronograf.User
|
||||||
|
if err := s.client.db.View(func(tx *bolt.Tx) error {
|
||||||
|
if err := tx.Bucket(UsersBucket).ForEach(func(k, v []byte) error {
|
||||||
|
var user chronograf.User
|
||||||
|
if err := internal.UnmarshalUser(v, &user); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
users = append(users, user)
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
|
@ -229,6 +229,8 @@ type User struct {
|
||||||
|
|
||||||
// UsersStore is the Storage and retrieval of authentication information
|
// UsersStore is the Storage and retrieval of authentication information
|
||||||
type UsersStore interface {
|
type UsersStore interface {
|
||||||
|
// All lists all users from the UsersStore
|
||||||
|
All(context.Context) ([]User, error)
|
||||||
// Create a new User in the UsersStore
|
// Create a new User in the UsersStore
|
||||||
Add(context.Context, *User) (*User, error)
|
Add(context.Context, *User) (*User, error)
|
||||||
// Delete the User from the UsersStore
|
// Delete the User from the UsersStore
|
||||||
|
|
|
@ -24,6 +24,7 @@ type Client struct {
|
||||||
CreateUser(ctx context.Context, name, passwd string) error
|
CreateUser(ctx context.Context, name, passwd string) error
|
||||||
DeleteUser(ctx context.Context, name string) error
|
DeleteUser(ctx context.Context, name string) error
|
||||||
ChangePassword(ctx context.Context, name, passwd string) error
|
ChangePassword(ctx context.Context, name, passwd string) error
|
||||||
|
Users(ctx context.Context, name *string) (*Users, error)
|
||||||
}
|
}
|
||||||
Logger chronograf.Logger
|
Logger chronograf.Logger
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,23 @@ func (cc *ControlClient) ShowCluster(context.Context) (*enterprise.Cluster, erro
|
||||||
func (cc *ControlClient) User(ctx context.Context, name string) (*enterprise.User, error) {
|
func (cc *ControlClient) User(ctx context.Context, name string) (*enterprise.User, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ControlClient) CreateUser(ctx context.Context, name, passwd string) error {
|
func (cc *ControlClient) CreateUser(ctx context.Context, name, passwd string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ControlClient) DeleteUser(ctx context.Context, name string) error {
|
func (cc *ControlClient) DeleteUser(ctx context.Context, name string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *ControlClient) ChangePassword(ctx context.Context, name, passwd string) error {
|
func (cc *ControlClient) ChangePassword(ctx context.Context, name, passwd string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cc *ControlClient) Users(ctx context.Context, name *string) (*enterprise.Users, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
type TimeSeries struct {
|
type TimeSeries struct {
|
||||||
URLs []string
|
URLs []string
|
||||||
Response Response
|
Response Response
|
||||||
|
|
|
@ -35,3 +35,19 @@ func (c *Client) Update(ctx context.Context, u *chronograf.User) error {
|
||||||
// TODO: Update permissions
|
// TODO: Update permissions
|
||||||
return c.Ctrl.ChangePassword(ctx, u.Name, u.Passwd)
|
return c.Ctrl.ChangePassword(ctx, u.Name, u.Passwd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All is all users in influx
|
||||||
|
func (c *Client) All(ctx context.Context) ([]chronograf.User, error) {
|
||||||
|
all, err := c.Ctrl.Users(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([]chronograf.User, len(all.Users))
|
||||||
|
for i, user := range all.Users {
|
||||||
|
res[i] = chronograf.User{
|
||||||
|
Name: user.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
"github.com/influxdata/chronograf"
|
"github.com/influxdata/chronograf"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create a new User in Influx Enterprise
|
// Create a new User in InfluxDB
|
||||||
func (c *Client) Add(context.Context, *chronograf.User) (*chronograf.User, error) { return nil, nil }
|
func (c *Client) Add(context.Context, *chronograf.User) (*chronograf.User, error) { return nil, nil }
|
||||||
|
|
||||||
// Delete the User from Influx Enterprise
|
// Delete the User from InfluxDB
|
||||||
func (c *Client) Delete(context.Context, *chronograf.User) error { return nil }
|
func (c *Client) Delete(context.Context, *chronograf.User) error { return nil }
|
||||||
|
|
||||||
// Get retrieves a user if name exists.
|
// Get retrieves a user if name exists.
|
||||||
|
@ -19,3 +19,6 @@ func (c *Client) Get(ctx context.Context, name string) (*chronograf.User, error)
|
||||||
|
|
||||||
// Update the user's permissions or roles
|
// Update the user's permissions or roles
|
||||||
func (c *Client) Update(context.Context, *chronograf.User) error { return nil }
|
func (c *Client) Update(context.Context, *chronograf.User) error { return nil }
|
||||||
|
|
||||||
|
// All is all users in influx
|
||||||
|
func (c *Client) All(context.Context) ([]chronograf.User, error) { return nil, nil }
|
||||||
|
|
108
server/admin.go
108
server/admin.go
|
@ -1,6 +1,7 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -48,21 +49,8 @@ type sourceUserLinks struct {
|
||||||
|
|
||||||
// NewSourceUser adds user to source
|
// NewSourceUser adds user to source
|
||||||
func (h *Service) NewSourceUser(w http.ResponseWriter, r *http.Request) {
|
func (h *Service) NewSourceUser(w http.ResponseWriter, r *http.Request) {
|
||||||
srcID, err := paramID("id", r)
|
|
||||||
if err != nil {
|
|
||||||
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := r.Context()
|
|
||||||
src, err := h.SourcesStore.Get(ctx, srcID)
|
|
||||||
if err != nil {
|
|
||||||
notFound(w, srcID, h.Logger)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var req newSourceUserRequest
|
var req newSourceUserRequest
|
||||||
if err = json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
invalidJSON(w, h.Logger)
|
invalidJSON(w, h.Logger)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -71,13 +59,13 @@ func (h *Service) NewSourceUser(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = h.TimeSeries.Connect(ctx, &src); err != nil {
|
ctx := r.Context()
|
||||||
msg := fmt.Sprintf("Unable to connect to source %d", srcID)
|
|
||||||
Error(w, http.StatusBadRequest, msg, h.Logger)
|
srcID, store, err := h.sourceUsersStore(ctx, w, r)
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
store := h.TimeSeries.Users(ctx)
|
|
||||||
user := &chronograf.User{
|
user := &chronograf.User{
|
||||||
Name: req.Username,
|
Name: req.Username,
|
||||||
Passwd: req.Password,
|
Passwd: req.Password,
|
||||||
|
@ -93,31 +81,93 @@ func (h *Service) NewSourceUser(w http.ResponseWriter, r *http.Request) {
|
||||||
encodeJSON(w, http.StatusCreated, su, h.Logger)
|
encodeJSON(w, http.StatusCreated, su, h.Logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SourceUserID retrieves a user with ID from store.
|
type sourceUsers struct {
|
||||||
func (h *Service) SourceUserID(w http.ResponseWriter, r *http.Request) {
|
Users []sourceUser `json:"users"`
|
||||||
srcID, err := paramID("id", r)
|
}
|
||||||
|
|
||||||
|
// SourceUsers retrieves all users from source.
|
||||||
|
func (h *Service) SourceUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
|
||||||
|
srcID, store, err := h.sourceUsersStore(ctx, w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
users, err := store.All(ctx)
|
||||||
|
if err != nil {
|
||||||
|
Error(w, http.StatusBadRequest, err.Error(), h.Logger)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
su := []sourceUser{}
|
||||||
|
for _, u := range users {
|
||||||
|
su = append(su, NewSourceUser(srcID, u.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
res := sourceUsers{
|
||||||
|
Users: su,
|
||||||
|
}
|
||||||
|
|
||||||
|
encodeJSON(w, http.StatusOK, res, h.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SourceUserID retrieves a user with ID from store.
|
||||||
|
func (h *Service) SourceUserID(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
uid := httprouter.GetParamFromContext(ctx, "uid")
|
||||||
|
|
||||||
|
srcID, store, err := h.sourceUsersStore(ctx, w, r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := store.Get(ctx, uid)
|
||||||
|
if err != nil {
|
||||||
|
Error(w, http.StatusBadRequest, err.Error(), h.Logger)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := NewSourceUser(srcID, u.Name)
|
||||||
|
encodeJSON(w, http.StatusOK, res, h.Logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Service) RemoveSourceUser(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
uid := httprouter.GetParamFromContext(ctx, "uid")
|
||||||
|
|
||||||
|
_, store, err := h.sourceUsersStore(ctx, w, r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := store.Delete(ctx, &chronograf.User{Name: uid}); err != nil {
|
||||||
|
Error(w, http.StatusBadRequest, err.Error(), h.Logger)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Service) sourceUsersStore(ctx context.Context, w http.ResponseWriter, r *http.Request) (int, chronograf.UsersStore, error) {
|
||||||
|
srcID, err := paramID("id", r)
|
||||||
|
if err != nil {
|
||||||
|
Error(w, http.StatusUnprocessableEntity, err.Error(), h.Logger)
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
src, err := h.SourcesStore.Get(ctx, srcID)
|
src, err := h.SourcesStore.Get(ctx, srcID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
notFound(w, srcID, h.Logger)
|
notFound(w, srcID, h.Logger)
|
||||||
return
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = h.TimeSeries.Connect(ctx, &src); err != nil {
|
if err = h.TimeSeries.Connect(ctx, &src); err != nil {
|
||||||
msg := fmt.Sprintf("Unable to connect to source %d", srcID)
|
msg := fmt.Sprintf("Unable to connect to source %d", srcID)
|
||||||
Error(w, http.StatusBadRequest, msg, h.Logger)
|
Error(w, http.StatusBadRequest, msg, h.Logger)
|
||||||
return
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
uid := httprouter.GetParamFromContext(ctx, "uid")
|
|
||||||
store := h.TimeSeries.Users(ctx)
|
store := h.TimeSeries.Users(ctx)
|
||||||
u, err := store.Get(ctx, uid)
|
return srcID, store, nil
|
||||||
|
|
||||||
res := NewSourceUser(srcID, u.Name)
|
|
||||||
encodeJSON(w, http.StatusOK, res, h.Logger)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue