Grant user role in default org if added via API
When users are created via the API they are only given roles in orgs that are explicitly set. Additionally the roles must be roles that belong to the current organization (unless they are a super admin). This leads to a situation where a user may not be a part of the default organization. If this is the case, we detect it when the user hits /me and add the user to the default org.pull/2220/head
parent
45f1410fd6
commit
3ddd253d68
26
server/me.go
26
server/me.go
|
@ -197,6 +197,20 @@ func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
|
|||
unknownErrorWithMessage(w, err, s.Logger)
|
||||
return
|
||||
}
|
||||
// If a user was added via the API, they might not yet be a member of the default organization
|
||||
// Here we check to verify that they are a user in the default organization
|
||||
// TODO(desa): when https://github.com/influxdata/chronograf/pull/2219 is merge, refactor this to use
|
||||
// the default organization logic rather than hard coding valies here.
|
||||
if !hasRoleInDefaultOrganization(usr) {
|
||||
usr.Roles = append(usr.Roles, chronograf.Role{
|
||||
Organization: "0",
|
||||
Name: MemberRoleName,
|
||||
})
|
||||
if err := s.Store.Users(ctx).Update(ctx, usr); err != nil {
|
||||
unknownErrorWithMessage(w, err, s.Logger)
|
||||
return
|
||||
}
|
||||
}
|
||||
res := newMeResponse(usr)
|
||||
res.Organizations = orgs
|
||||
res.CurrentOrganization = currentOrg
|
||||
|
@ -284,3 +298,15 @@ func (s *Service) usersOrganizations(ctx context.Context, u *chronograf.User) ([
|
|||
|
||||
return orgs, nil
|
||||
}
|
||||
|
||||
// TODO(desa): when https://github.com/influxdata/chronograf/pull/2219 is merge, refactor this to use
|
||||
// the default organization logic rather than hard coding valies here.
|
||||
func hasRoleInDefaultOrganization(u *chronograf.User) bool {
|
||||
for _, role := range u.Roles {
|
||||
if role.Organization == "0" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -70,6 +70,9 @@ func TestService_Me(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
}, nil
|
||||
},
|
||||
UpdateF: func(ctx context.Context, u *chronograf.User) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
principal: oauth2.Principal{
|
||||
|
@ -78,7 +81,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/0"},"currentOrganization":{"id":"0","name":"The Bad Place"}}
|
||||
wantBody: `{"name":"me","provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"currentOrganization":{"id":"0","name":"The Bad Place"},"roles":[{"name":"member","organization":"0"}]}
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
@ -112,6 +115,9 @@ func TestService_Me(t *testing.T) {
|
|||
AddF: func(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
|
||||
return u, nil
|
||||
},
|
||||
UpdateF: func(ctx context.Context, u *chronograf.User) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
principal: oauth2.Principal{
|
||||
|
@ -150,6 +156,9 @@ func TestService_Me(t *testing.T) {
|
|||
AddF: func(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
|
||||
return nil, fmt.Errorf("Why Heavy?")
|
||||
},
|
||||
UpdateF: func(ctx context.Context, u *chronograf.User) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
Logger: log.New(log.DebugLevel),
|
||||
},
|
||||
|
@ -216,7 +225,10 @@ func TestService_Me(t *testing.T) {
|
|||
if tt.wantContentType != "" && content != tt.wantContentType {
|
||||
t.Errorf("%q. Me() = %v, want %v", tt.name, content, tt.wantContentType)
|
||||
}
|
||||
if tt.wantBody != "" && string(body) != tt.wantBody {
|
||||
if tt.wantBody == "" {
|
||||
continue
|
||||
}
|
||||
if eq, err := jsonEqual(tt.wantBody, string(body)); err != nil || !eq {
|
||||
t.Errorf("%q. Me() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wantBody)
|
||||
}
|
||||
}
|
||||
|
@ -274,6 +286,9 @@ func TestService_MeOrganizations(t *testing.T) {
|
|||
},
|
||||
}, nil
|
||||
},
|
||||
UpdateF: func(ctx context.Context, u *chronograf.User) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -293,7 +308,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","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"1337","name":"The ShillBillThrilliettas"}],"currentOrganization":{"id":"1337","name":"The ShillBillThrilliettas"}}`,
|
||||
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"1337"},{"name":"member","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"1337","name":"The ShillBillThrilliettas"}],"currentOrganization":{"id":"1337","name":"The ShillBillThrilliettas"}}`,
|
||||
},
|
||||
{
|
||||
name: "Change the current User's organization",
|
||||
|
@ -325,6 +340,9 @@ func TestService_MeOrganizations(t *testing.T) {
|
|||
},
|
||||
}, nil
|
||||
},
|
||||
UpdateF: func(ctx context.Context, u *chronograf.User) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -345,7 +363,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","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"1337","name":"The ThrillShilliettos"}],"currentOrganization":{"id":"1337","name":"The ThrillShilliettos"}}
|
||||
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"1337"},{"name":"member","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"1337","name":"The ThrillShilliettos"}],"currentOrganization":{"id":"1337","name":"The ThrillShilliettos"}}
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
@ -368,6 +386,9 @@ func TestService_MeOrganizations(t *testing.T) {
|
|||
}
|
||||
return nil, chronograf.ErrUserNotFound
|
||||
},
|
||||
UpdateF: func(ctx context.Context, u *chronograf.User) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -420,6 +441,9 @@ func TestService_MeOrganizations(t *testing.T) {
|
|||
},
|
||||
}, nil
|
||||
},
|
||||
UpdateF: func(ctx context.Context, u *chronograf.User) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
|
Loading…
Reference in New Issue