feat(server): add reader role
parent
d698c2b9ae
commit
15dbecfb0f
|
@ -9,6 +9,7 @@ const ContextKey = contextKey("role")
|
||||||
// Chronograf User Roles
|
// Chronograf User Roles
|
||||||
const (
|
const (
|
||||||
MemberRoleName = "member"
|
MemberRoleName = "member"
|
||||||
|
ReaderRoleName = "reader"
|
||||||
ViewerRoleName = "viewer"
|
ViewerRoleName = "viewer"
|
||||||
EditorRoleName = "editor"
|
EditorRoleName = "editor"
|
||||||
AdminRoleName = "admin"
|
AdminRoleName = "admin"
|
||||||
|
|
|
@ -293,7 +293,6 @@ func AuthorizedUser(
|
||||||
}
|
}
|
||||||
|
|
||||||
Error(w, http.StatusForbidden, "User is not authorized", logger)
|
Error(w, http.StatusForbidden, "User is not authorized", logger)
|
||||||
return
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +305,14 @@ func hasAuthorizedRole(u *chronograf.User, role string) bool {
|
||||||
case roles.MemberRoleName:
|
case roles.MemberRoleName:
|
||||||
for _, r := range u.Roles {
|
for _, r := range u.Roles {
|
||||||
switch r.Name {
|
switch r.Name {
|
||||||
case roles.MemberRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
case roles.MemberRoleName, roles.ReaderRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case roles.ReaderRoleName:
|
||||||
|
for _, r := range u.Roles {
|
||||||
|
switch r.Name {
|
||||||
|
case roles.ReaderRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,62 @@ func TestAuthorizedUser(t *testing.T) {
|
||||||
hasRoleContext: true,
|
hasRoleContext: true,
|
||||||
hasServerContext: false,
|
hasServerContext: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "User with reader role is member authorized",
|
||||||
|
fields: fields{
|
||||||
|
UsersStore: &mocks.UsersStore{
|
||||||
|
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
|
||||||
|
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
|
||||||
|
return nil, fmt.Errorf("Invalid user query: missing Name, Provider, and/or Scheme")
|
||||||
|
}
|
||||||
|
return &chronograf.User{
|
||||||
|
ID: 1337,
|
||||||
|
Name: "billysteve",
|
||||||
|
Provider: "google",
|
||||||
|
Scheme: "oauth2",
|
||||||
|
Roles: []chronograf.Role{
|
||||||
|
{
|
||||||
|
Name: roles.ReaderRoleName,
|
||||||
|
Organization: "1337",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
OrganizationsStore: &mocks.OrganizationsStore{
|
||||||
|
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||||
|
return &chronograf.Organization{
|
||||||
|
ID: "0",
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||||
|
if q.ID == nil {
|
||||||
|
return nil, fmt.Errorf("Invalid organization query: missing ID")
|
||||||
|
}
|
||||||
|
return &chronograf.Organization{
|
||||||
|
ID: "1337",
|
||||||
|
Name: "The ShillBillThrilliettas",
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Logger: clog.New(clog.DebugLevel),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
principal: &oauth2.Principal{
|
||||||
|
Subject: "billysteve",
|
||||||
|
Issuer: "google",
|
||||||
|
Organization: "1337",
|
||||||
|
},
|
||||||
|
scheme: "oauth2",
|
||||||
|
role: "member",
|
||||||
|
useAuth: true,
|
||||||
|
},
|
||||||
|
authorized: true,
|
||||||
|
hasOrganizationContext: true,
|
||||||
|
hasSuperAdminContext: false,
|
||||||
|
hasRoleContext: true,
|
||||||
|
hasServerContext: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "User with viewer role is member authorized",
|
name: "User with viewer role is member authorized",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
|
|
|
@ -43,10 +43,10 @@ func (r *organizationRequest) ValidDefaultRole() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r.DefaultRole {
|
switch r.DefaultRole {
|
||||||
case roles.MemberRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
case roles.MemberRoleName, roles.ReaderRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("default role must be member, viewer, editor, or admin")
|
return fmt.Errorf("default role must be member, reader, viewer, editor, or admin")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -385,7 +385,7 @@ func TestService_UpdateOrganization(t *testing.T) {
|
||||||
id: "1337",
|
id: "1337",
|
||||||
wantStatus: http.StatusUnprocessableEntity,
|
wantStatus: http.StatusUnprocessableEntity,
|
||||||
wantContentType: "application/json",
|
wantContentType: "application/json",
|
||||||
wantBody: `{"code":422,"message":"default role must be member, viewer, editor, or admin"}`,
|
wantBody: `{"code":422,"message":"default role must be member, reader, viewer, editor, or admin"}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ func hasRoleContext(ctx context.Context) (string, bool) {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
switch role {
|
switch role {
|
||||||
case roles.MemberRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
case roles.MemberRoleName, roles.ReaderRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||||
return role, true
|
return role, true
|
||||||
default:
|
default:
|
||||||
return "", false
|
return "", false
|
||||||
|
|
|
@ -59,10 +59,10 @@ func (r *userRequest) ValidRoles() error {
|
||||||
}
|
}
|
||||||
orgs[r.Organization] = true
|
orgs[r.Organization] = true
|
||||||
switch r.Name {
|
switch r.Name {
|
||||||
case roles.MemberRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName, roles.WildcardRoleName:
|
case roles.MemberRoleName, roles.ReaderRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName, roles.WildcardRoleName:
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unknown role %s. Valid roles are 'member', 'viewer', 'editor', 'admin', and '*'", r.Name)
|
return fmt.Errorf("Unknown role %s. Valid roles are 'member', 'reader', 'viewer', 'editor', 'admin', and '*'", r.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1702,7 +1702,7 @@ func TestUserRequest_ValidCreate(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
err: fmt.Errorf("Unknown role BilliettaSpecialRole. Valid roles are 'member', 'viewer', 'editor', 'admin', and '*'"),
|
err: fmt.Errorf("Unknown role BilliettaSpecialRole. Valid roles are 'member', 'reader', 'viewer', 'editor', 'admin', and '*'"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid roles - missing organization",
|
name: "Invalid roles - missing organization",
|
||||||
|
@ -1792,7 +1792,7 @@ func TestUserRequest_ValidUpdate(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
err: fmt.Errorf("Unknown role BillietaSpecialOrg. Valid roles are 'member', 'viewer', 'editor', 'admin', and '*'"),
|
err: fmt.Errorf("Unknown role BillietaSpecialOrg. Valid roles are 'member', 'reader', 'viewer', 'editor', 'admin', and '*'"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Valid – roles empty",
|
name: "Valid – roles empty",
|
||||||
|
@ -1824,7 +1824,7 @@ func TestUserRequest_ValidUpdate(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
err: fmt.Errorf("Unknown role BillietaSpecialOrg. Valid roles are 'member', 'viewer', 'editor', 'admin', and '*'"),
|
err: fmt.Errorf("Unknown role BillietaSpecialOrg. Valid roles are 'member', 'reader', 'viewer', 'editor', 'admin', and '*'"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid - duplicate organization",
|
name: "Invalid - duplicate organization",
|
||||||
|
|
Loading…
Reference in New Issue