Add CurrentOrganization & Organizations to me resp

Remove CurrentOrganization from chronograf.User
pull/10616/head
Michael Desa 2017-11-02 11:59:53 -04:00
parent 92466975a2
commit 311c68f457
3 changed files with 109 additions and 21 deletions

View File

@ -625,7 +625,6 @@ type User struct {
Roles []Role `json:"roles,omitempty"`
Provider string `json:"provider,omitempty"`
Scheme string `json:"scheme,omitempty"`
CurrentOrganization string `json:"currentOrganization,omitempty"`
SuperAdmin bool `json:"superAdmin,omitempty"`
}
@ -771,7 +770,7 @@ type LayoutsStore interface {
// Organization is a group of resources under a common name
type Organization struct {
ID uint64 `json:"id"`
ID uint64 `json:"id,string"`
Name string `json:"name"`
}

View File

@ -19,6 +19,8 @@ type meLinks struct {
type meResponse struct {
*chronograf.User
Links meLinks `json:"links"`
Organizations []chronograf.Organization `json:"organizations,omitempty"`
CurrentOrganization *chronograf.Organization `json:"currentOrganization,omitempty"`
}
// If new user response is nil, return an empty meResponse because it
@ -65,6 +67,10 @@ func getValidPrincipal(ctx context.Context) (oauth2.Principal, error) {
if p.Issuer == "" {
return oauth2.Principal{}, fmt.Errorf("Token not found")
}
// TODO(desa): make this default org
if p.Organization == "" {
p.Organization = "0"
}
return p, nil
}
@ -176,8 +182,24 @@ func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
}
if usr != nil {
usr.CurrentOrganization = p.Organization
orgs, err := s.usersOrganizations(ctx, usr)
if err != nil {
unknownErrorWithMessage(w, err, s.Logger)
return
}
orgID, err := parseOrganizationID(p.Organization)
if err != nil {
unknownErrorWithMessage(w, err, s.Logger)
return
}
currentOrg, err := s.Store.Organizations(ctx).Get(ctx, chronograf.OrganizationQuery{ID: &orgID})
if err != nil {
unknownErrorWithMessage(w, err, s.Logger)
return
}
res := newMeResponse(usr)
res.Organizations = orgs
res.CurrentOrganization = currentOrg
encodeJSON(w, http.StatusOK, res, s.Logger)
return
}
@ -207,8 +229,24 @@ func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
return
}
newUser.CurrentOrganization = p.Organization
orgs, err := s.usersOrganizations(ctx, newUser)
if err != nil {
unknownErrorWithMessage(w, err, s.Logger)
return
}
orgID, err := parseOrganizationID(p.Organization)
if err != nil {
unknownErrorWithMessage(w, err, s.Logger)
return
}
currentOrg, err := s.Store.Organizations(ctx).Get(ctx, chronograf.OrganizationQuery{ID: &orgID})
if err != nil {
unknownErrorWithMessage(w, err, s.Logger)
return
}
res := newMeResponse(newUser)
res.Organizations = orgs
res.CurrentOrganization = currentOrg
encodeJSON(w, http.StatusOK, res, s.Logger)
}
@ -222,3 +260,27 @@ func (s *Service) firstUser() bool {
return len(users) == 0
}
func (s *Service) usersOrganizations(ctx context.Context, u *chronograf.User) ([]chronograf.Organization, error) {
if u == nil {
// TODO(desa): better error
return nil, fmt.Errorf("user was nil")
}
orgIDs := map[string]bool{}
for _, role := range u.Roles {
orgIDs[role.Organization] = true
}
orgs := []chronograf.Organization{}
for orgID, _ := range orgIDs {
id, err := parseOrganizationID(orgID)
org, err := s.Store.Organizations(ctx).Get(ctx, chronograf.OrganizationQuery{ID: &id})
if err != nil {
return nil, err
}
orgs = append(orgs, *org)
}
return orgs, nil
}

View File

@ -21,6 +21,7 @@ type MockUsers struct{}
func TestService_Me(t *testing.T) {
type fields struct {
UsersStore chronograf.UsersStore
OrganizationsStore chronograf.OrganizationsStore
Logger chronograf.Logger
UseAuth bool
}
@ -46,6 +47,14 @@ func TestService_Me(t *testing.T) {
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
return &chronograf.Organization{
ID: 0,
Name: "The Bad Place",
}, nil
},
},
UsersStore: &mocks.UsersStore{
AllF: func(ctx context.Context) ([]chronograf.User, error) {
// This function gets to verify that there is at least one first user
@ -69,7 +78,7 @@ func TestService_Me(t *testing.T) {
},
wantStatus: http.StatusOK,
wantContentType: "application/json",
wantBody: `{"name":"me","provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/me"}}
wantBody: `{"name":"me","provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/me"},"currentOrganization":{"id":"0","name":"The Bad Place"}}
`,
},
{
@ -81,6 +90,14 @@ func TestService_Me(t *testing.T) {
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
return &chronograf.Organization{
ID: 0,
Name: "The Bad Place",
}, nil
},
},
UsersStore: &mocks.UsersStore{
AllF: func(ctx context.Context) ([]chronograf.User, error) {
// This function gets to verify that there is at least one first user
@ -103,7 +120,7 @@ func TestService_Me(t *testing.T) {
},
wantStatus: http.StatusOK,
wantContentType: "application/json",
wantBody: `{"name":"secret","roles":[{"name":"member","organization":"\"0\""}],"provider":"auth0","scheme":"oauth2","links":{"self":"/chronograf/v1/users/secret"}}
wantBody: `{"name":"secret","roles":[{"name":"member","organization":"\"0\""}],"provider":"auth0","scheme":"oauth2","links":{"self":"/chronograf/v1/users/secret"},"organizations":[{"id":"0","name":"The Bad Place"}],"currentOrganization":{"id":"0","name":"The Bad Place"}}
`,
},
{
@ -114,6 +131,14 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
return &chronograf.Organization{
ID: 0,
Name: "The Bad Place",
}, nil
},
},
UsersStore: &mocks.UsersStore{
AllF: func(ctx context.Context) ([]chronograf.User, error) {
// This function gets to verify that there is at least one first user
@ -173,6 +198,7 @@ func TestService_Me(t *testing.T) {
s := &Service{
Store: &mocks.Store{
UsersStore: tt.fields.UsersStore,
OrganizationsStore: tt.fields.OrganizationsStore,
},
Logger: tt.fields.Logger,
UseAuth: tt.fields.UseAuth,
@ -267,7 +293,7 @@ func TestService_MeOrganizations(t *testing.T) {
},
wantStatus: http.StatusOK,
wantContentType: "application/json",
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"\"1337\""}],"provider":"github","scheme":"oauth2","currentOrganization":"1337","links":{"self":"/chronograf/v1/users/me"}}`,
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"\"1337\""}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/me"},"organizations":[{"id":"1337","name":"The ShillBillThrilliettas"}],"currentOrganization":{"id":"1337","name":"The ShillBillThrilliettas"}}`,
},
{
name: "Change the current User's organization",
@ -319,7 +345,8 @@ func TestService_MeOrganizations(t *testing.T) {
},
wantStatus: http.StatusOK,
wantContentType: "application/json",
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"\"1337\""}],"provider":"github","scheme":"oauth2","currentOrganization":"1337","links":{"self":"/chronograf/v1/users/me"}}`,
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"\"1337\""}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/me"},"organizations":[{"id":"1337","name":"The ThrillShilliettos"}],"currentOrganization":{"id":"1337","name":"The ThrillShilliettos"}}
`,
},
{
name: "Unable to find requested user in valid organization",