Add correct implementation of mappings
parent
343f417474
commit
64f670e819
|
@ -41,6 +41,7 @@ type Client struct {
|
|||
UsersStore *UsersStore
|
||||
OrganizationsStore *OrganizationsStore
|
||||
ConfigStore *ConfigStore
|
||||
MappingsStore *MappingsStore
|
||||
}
|
||||
|
||||
// NewClient initializes all stores
|
||||
|
@ -60,6 +61,7 @@ func NewClient() *Client {
|
|||
c.UsersStore = &UsersStore{client: c}
|
||||
c.OrganizationsStore = &OrganizationsStore{client: c}
|
||||
c.ConfigStore = &ConfigStore{client: c}
|
||||
c.MappingsStore = &MappingsStore{client: c}
|
||||
return c
|
||||
}
|
||||
|
||||
|
@ -151,6 +153,10 @@ func (c *Client) initialize(ctx context.Context) error {
|
|||
if _, err := tx.CreateBucketIfNotExists(BuildBucket); err != nil {
|
||||
return err
|
||||
}
|
||||
// Always create Mapping bucket.
|
||||
if _, err := tx.CreateBucketIfNotExists(MappingsBucket); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
|
@ -184,6 +190,9 @@ func (c *Client) migrate(ctx context.Context, build chronograf.BuildInfo) error
|
|||
if err := c.BuildStore.Migrate(ctx, build); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.MappingsStore.Migrate(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -578,23 +578,12 @@ func UnmarshalRolePB(data []byte, r *Role) error {
|
|||
|
||||
// MarshalOrganization encodes a organization to binary protobuf format.
|
||||
func MarshalOrganization(o *chronograf.Organization) ([]byte, error) {
|
||||
mappings := make([]*Mapping, len(o.Mappings))
|
||||
|
||||
for i, m := range o.Mappings {
|
||||
mappings[i] = &Mapping{
|
||||
Provider: m.Provider,
|
||||
Scheme: m.Scheme,
|
||||
Group: m.Group,
|
||||
GrantedRole: m.GrantedRole,
|
||||
}
|
||||
}
|
||||
|
||||
return MarshalOrganizationPB(&Organization{
|
||||
ID: o.ID,
|
||||
Name: o.Name,
|
||||
DefaultRole: o.DefaultRole,
|
||||
Public: o.Public,
|
||||
Mappings: mappings,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -614,19 +603,6 @@ func UnmarshalOrganization(data []byte, o *chronograf.Organization) error {
|
|||
o.DefaultRole = pb.DefaultRole
|
||||
o.Public = pb.Public
|
||||
|
||||
mappings := make([]chronograf.Mapping, len(pb.Mappings))
|
||||
|
||||
for i, m := range pb.Mappings {
|
||||
mappings[i] = chronograf.Mapping{
|
||||
Provider: m.Provider,
|
||||
Scheme: m.Scheme,
|
||||
Group: m.Group,
|
||||
GrantedRole: m.GrantedRole,
|
||||
}
|
||||
}
|
||||
|
||||
o.Mappings = mappings
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -673,3 +649,44 @@ func UnmarshalConfigPB(data []byte, c *Config) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalMapping encodes a mapping to binary protobuf format.
|
||||
func MarshalMapping(m *chronograf.Mapping) ([]byte, error) {
|
||||
|
||||
return MarshalMappingPB(&Mapping{
|
||||
Provider: m.Provider,
|
||||
Scheme: m.Scheme,
|
||||
Group: m.Group,
|
||||
ID: m.ID,
|
||||
Organization: m.Organization,
|
||||
})
|
||||
}
|
||||
|
||||
// MarshalMappingPB encodes a mapping to binary protobuf format.
|
||||
func MarshalMappingPB(m *Mapping) ([]byte, error) {
|
||||
return proto.Marshal(m)
|
||||
}
|
||||
|
||||
// UnmarshalMapping decodes a mapping from binary protobuf data.
|
||||
func UnmarshalMapping(data []byte, m *chronograf.Mapping) error {
|
||||
var pb Mapping
|
||||
if err := UnmarshalMappingPB(data, &pb); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.Provider = pb.Provider
|
||||
m.Scheme = pb.Scheme
|
||||
m.Group = pb.Group
|
||||
m.Organization = pb.Organization
|
||||
m.ID = pb.ID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalMappingPB decodes a mapping from binary protobuf data.
|
||||
func UnmarshalMappingPB(data []byte, m *Mapping) error {
|
||||
if err := proto.Unmarshal(data, m); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1026,10 +1026,12 @@ func (m *Role) GetName() string {
|
|||
}
|
||||
|
||||
type Mapping struct {
|
||||
Provider string `protobuf:"bytes,1,opt,name=Provider,proto3" json:"Provider,omitempty"`
|
||||
Scheme string `protobuf:"bytes,2,opt,name=Scheme,proto3" json:"Scheme,omitempty"`
|
||||
Group string `protobuf:"bytes,3,opt,name=Group,proto3" json:"Group,omitempty"`
|
||||
GrantedRole string `protobuf:"bytes,4,opt,name=GrantedRole,proto3" json:"GrantedRole,omitempty"`
|
||||
Provider string `protobuf:"bytes,1,opt,name=Provider,proto3" json:"Provider,omitempty"`
|
||||
Scheme string `protobuf:"bytes,2,opt,name=Scheme,proto3" json:"Scheme,omitempty"`
|
||||
Group string `protobuf:"bytes,3,opt,name=Group,proto3" json:"Group,omitempty"`
|
||||
// string GrantedRole = 4; // GrantedRole is the name of the role that you will be granted if you match the mapping
|
||||
ID string `protobuf:"bytes,4,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Organization string `protobuf:"bytes,5,opt,name=Organization,proto3" json:"Organization,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Mapping) Reset() { *m = Mapping{} }
|
||||
|
@ -1058,19 +1060,25 @@ func (m *Mapping) GetGroup() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (m *Mapping) GetGrantedRole() string {
|
||||
func (m *Mapping) GetID() string {
|
||||
if m != nil {
|
||||
return m.GrantedRole
|
||||
return m.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Mapping) GetOrganization() string {
|
||||
if m != nil {
|
||||
return m.Organization
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Organization struct {
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
DefaultRole string `protobuf:"bytes,3,opt,name=DefaultRole,proto3" json:"DefaultRole,omitempty"`
|
||||
Public bool `protobuf:"varint,4,opt,name=Public,proto3" json:"Public,omitempty"`
|
||||
Mappings []*Mapping `protobuf:"bytes,5,rep,name=Mappings" json:"Mappings,omitempty"`
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
DefaultRole string `protobuf:"bytes,3,opt,name=DefaultRole,proto3" json:"DefaultRole,omitempty"`
|
||||
Public bool `protobuf:"varint,4,opt,name=Public,proto3" json:"Public,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Organization) Reset() { *m = Organization{} }
|
||||
|
@ -1106,13 +1114,6 @@ func (m *Organization) GetPublic() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (m *Organization) GetMappings() []*Mapping {
|
||||
if m != nil {
|
||||
return m.Mappings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Auth *AuthConfig `protobuf:"bytes,1,opt,name=Auth" json:"Auth,omitempty"`
|
||||
}
|
||||
|
@ -1197,93 +1198,92 @@ func init() {
|
|||
func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) }
|
||||
|
||||
var fileDescriptorInternal = []byte{
|
||||
// 1396 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x5f, 0x8f, 0xdb, 0x44,
|
||||
0x10, 0x97, 0xe3, 0x38, 0xb1, 0x27, 0xd7, 0x52, 0xcc, 0x89, 0x9a, 0x22, 0xa1, 0x60, 0x81, 0x38,
|
||||
0x04, 0x3d, 0xd0, 0x55, 0x48, 0x08, 0x01, 0x52, 0xee, 0x82, 0xca, 0xd1, 0x7f, 0xd7, 0x4d, 0xef,
|
||||
0x78, 0x42, 0xd5, 0xc6, 0x99, 0x24, 0x56, 0x1d, 0xdb, 0xac, 0xed, 0xbb, 0x33, 0x5f, 0x05, 0x09,
|
||||
0x09, 0x89, 0x4f, 0x80, 0x78, 0xe7, 0x15, 0xf1, 0xca, 0x77, 0xe0, 0x2b, 0xf0, 0x8a, 0x66, 0x77,
|
||||
0xfd, 0x27, 0x97, 0xb4, 0xea, 0x03, 0xe2, 0x6d, 0x7f, 0x33, 0x9b, 0xd9, 0xd9, 0x99, 0xdf, 0xfc,
|
||||
0xd6, 0x81, 0xeb, 0x61, 0x9c, 0xa3, 0x88, 0x79, 0xb4, 0x9f, 0x8a, 0x24, 0x4f, 0x5c, 0xbb, 0xc2,
|
||||
0xfe, 0xdf, 0x1d, 0xe8, 0x4d, 0x92, 0x42, 0x04, 0xe8, 0x5e, 0x87, 0xce, 0xf1, 0xd8, 0x33, 0x86,
|
||||
0xc6, 0x9e, 0xc9, 0x3a, 0xc7, 0x63, 0xd7, 0x85, 0xee, 0x43, 0xbe, 0x42, 0xaf, 0x33, 0x34, 0xf6,
|
||||
0x1c, 0x26, 0xd7, 0x64, 0x7b, 0x52, 0xa6, 0xe8, 0x99, 0xca, 0x46, 0x6b, 0xf7, 0x16, 0xd8, 0xa7,
|
||||
0x19, 0x45, 0x5b, 0xa1, 0xd7, 0x95, 0xf6, 0x1a, 0x93, 0xef, 0x84, 0x67, 0xd9, 0x45, 0x22, 0x66,
|
||||
0x9e, 0xa5, 0x7c, 0x15, 0x76, 0x6f, 0x80, 0x79, 0xca, 0xee, 0x7b, 0x3d, 0x69, 0xa6, 0xa5, 0xeb,
|
||||
0x41, 0x7f, 0x8c, 0x73, 0x5e, 0x44, 0xb9, 0xd7, 0x1f, 0x1a, 0x7b, 0x36, 0xab, 0x20, 0xc5, 0x79,
|
||||
0x82, 0x11, 0x2e, 0x04, 0x9f, 0x7b, 0xb6, 0x8a, 0x53, 0x61, 0x77, 0x1f, 0xdc, 0xe3, 0x38, 0xc3,
|
||||
0xa0, 0x10, 0x38, 0x79, 0x16, 0xa6, 0x67, 0x28, 0xc2, 0x79, 0xe9, 0x39, 0x32, 0xc0, 0x16, 0x0f,
|
||||
0x9d, 0xf2, 0x00, 0x73, 0x4e, 0x67, 0x83, 0x0c, 0x55, 0x41, 0xd7, 0x87, 0x9d, 0xc9, 0x92, 0x0b,
|
||||
0x9c, 0x4d, 0x30, 0x10, 0x98, 0x7b, 0x03, 0xe9, 0x5e, 0xb3, 0xd1, 0x9e, 0x47, 0x62, 0xc1, 0xe3,
|
||||
0xf0, 0x07, 0x9e, 0x87, 0x49, 0xec, 0xed, 0xa8, 0x3d, 0x6d, 0x1b, 0x55, 0x89, 0x25, 0x11, 0x7a,
|
||||
0xd7, 0x54, 0x95, 0x68, 0xed, 0xff, 0x66, 0x80, 0x33, 0xe6, 0xd9, 0x72, 0x9a, 0x70, 0x31, 0x7b,
|
||||
0xa9, 0x5a, 0xdf, 0x06, 0x2b, 0xc0, 0x28, 0xca, 0x3c, 0x73, 0x68, 0xee, 0x0d, 0x0e, 0x6e, 0xee,
|
||||
0xd7, 0x4d, 0xac, 0xe3, 0x1c, 0x61, 0x14, 0x31, 0xb5, 0xcb, 0xfd, 0x18, 0x9c, 0x1c, 0x57, 0x69,
|
||||
0xc4, 0x73, 0xcc, 0xbc, 0xae, 0xfc, 0x89, 0xdb, 0xfc, 0xe4, 0x89, 0x76, 0xb1, 0x66, 0xd3, 0xc6,
|
||||
0x55, 0xac, 0xcd, 0xab, 0xf8, 0x7f, 0x75, 0xe0, 0xda, 0xda, 0x71, 0xee, 0x0e, 0x18, 0x97, 0x32,
|
||||
0x73, 0x8b, 0x19, 0x97, 0x84, 0x4a, 0x99, 0xb5, 0xc5, 0x8c, 0x92, 0xd0, 0x85, 0xe4, 0x86, 0xc5,
|
||||
0x8c, 0x0b, 0x42, 0x4b, 0xc9, 0x08, 0x8b, 0x19, 0x4b, 0xf7, 0x7d, 0xe8, 0x7f, 0x5f, 0xa0, 0x08,
|
||||
0x31, 0xf3, 0x2c, 0x99, 0xdd, 0x2b, 0x4d, 0x76, 0x8f, 0x0b, 0x14, 0x25, 0xab, 0xfc, 0x54, 0x0d,
|
||||
0xc9, 0x26, 0x45, 0x0d, 0xb9, 0x26, 0x5b, 0x4e, 0xcc, 0xeb, 0x2b, 0x1b, 0xad, 0x75, 0x15, 0x15,
|
||||
0x1f, 0xa8, 0x8a, 0x9f, 0x40, 0x97, 0x5f, 0x62, 0xe6, 0x39, 0x32, 0xfe, 0xdb, 0xcf, 0x29, 0xd8,
|
||||
0xfe, 0xe8, 0x12, 0xb3, 0xaf, 0xe2, 0x5c, 0x94, 0x4c, 0x6e, 0x77, 0xdf, 0x83, 0x5e, 0x90, 0x44,
|
||||
0x89, 0xc8, 0x3c, 0xb8, 0x9a, 0xd8, 0x11, 0xd9, 0x99, 0x76, 0xdf, 0xba, 0x0b, 0x4e, 0xfd, 0x5b,
|
||||
0xa2, 0xef, 0x33, 0x2c, 0x65, 0x25, 0x1c, 0x46, 0x4b, 0xf7, 0x1d, 0xb0, 0xce, 0x79, 0x54, 0xa8,
|
||||
0x2e, 0x0e, 0x0e, 0xae, 0x37, 0x61, 0x46, 0x97, 0x61, 0xc6, 0x94, 0xf3, 0xb3, 0xce, 0xa7, 0x86,
|
||||
0xbf, 0x00, 0x4b, 0x46, 0x6e, 0xf1, 0xc0, 0xa9, 0x78, 0x20, 0xe7, 0xab, 0xd3, 0x9a, 0xaf, 0x1b,
|
||||
0x60, 0x7e, 0x8d, 0x97, 0x7a, 0xe4, 0x68, 0x59, 0xb3, 0xa5, 0xdb, 0x62, 0xcb, 0x2e, 0x58, 0x67,
|
||||
0xf2, 0x70, 0xd5, 0x45, 0x05, 0xfc, 0x5f, 0x0d, 0xe8, 0xd2, 0xe1, 0xd4, 0xeb, 0x08, 0x17, 0x3c,
|
||||
0x28, 0x0f, 0x93, 0x22, 0x9e, 0x65, 0x9e, 0x31, 0x34, 0xf7, 0x4c, 0xb6, 0x66, 0x73, 0x5f, 0x87,
|
||||
0xde, 0x54, 0x79, 0x3b, 0x43, 0x73, 0xcf, 0x61, 0x1a, 0x51, 0xe8, 0x88, 0x4f, 0x31, 0xd2, 0x29,
|
||||
0x28, 0x40, 0xbb, 0x53, 0x81, 0xf3, 0xf0, 0x52, 0xa7, 0xa1, 0x11, 0xd9, 0xb3, 0x62, 0x4e, 0x76,
|
||||
0x95, 0x89, 0x46, 0x94, 0xf4, 0x94, 0x67, 0x75, 0x53, 0x69, 0x4d, 0x91, 0xb3, 0x80, 0x47, 0x55,
|
||||
0x57, 0x15, 0xf0, 0x7f, 0x37, 0x68, 0xda, 0x15, 0x4b, 0x37, 0x2a, 0xf4, 0x06, 0xd8, 0xc4, 0xe0,
|
||||
0xa7, 0xe7, 0x5c, 0xe8, 0x2a, 0xf5, 0x09, 0x9f, 0x71, 0xe1, 0x7e, 0x04, 0x3d, 0x59, 0xe2, 0x2d,
|
||||
0x13, 0x53, 0x85, 0x93, 0x55, 0x61, 0x7a, 0x5b, 0xcd, 0xa9, 0x6e, 0x8b, 0x53, 0xf5, 0x65, 0xad,
|
||||
0xf6, 0x65, 0x6f, 0x83, 0x45, 0xe4, 0x2c, 0x65, 0xf6, 0x5b, 0x23, 0x2b, 0x0a, 0xab, 0x5d, 0xfe,
|
||||
0x29, 0x5c, 0x5b, 0x3b, 0xb1, 0x3e, 0xc9, 0x58, 0x3f, 0xa9, 0xa1, 0x8b, 0xa3, 0xe9, 0x41, 0x4a,
|
||||
0x97, 0x61, 0x84, 0x41, 0x8e, 0x33, 0x59, 0x6f, 0x9b, 0xd5, 0xd8, 0xff, 0xd9, 0x68, 0xe2, 0xca,
|
||||
0xf3, 0x48, 0xcb, 0x82, 0x64, 0xb5, 0xe2, 0xf1, 0x4c, 0x87, 0xae, 0x20, 0xd5, 0x6d, 0x36, 0xd5,
|
||||
0xa1, 0x3b, 0xb3, 0x29, 0x61, 0x91, 0xea, 0x0e, 0x76, 0x44, 0xea, 0x0e, 0x61, 0xb0, 0x42, 0x9e,
|
||||
0x15, 0x02, 0x57, 0x18, 0xe7, 0xba, 0x04, 0x6d, 0x93, 0x7b, 0x13, 0xfa, 0x39, 0x5f, 0x3c, 0x25,
|
||||
0x92, 0xeb, 0x4e, 0xe6, 0x7c, 0x71, 0x0f, 0x4b, 0xf7, 0x4d, 0x70, 0xe6, 0x21, 0x46, 0x33, 0xe9,
|
||||
0x52, 0xed, 0xb4, 0xa5, 0xe1, 0x1e, 0x96, 0xfe, 0x1f, 0x06, 0xf4, 0x26, 0x28, 0xce, 0x51, 0xbc,
|
||||
0x94, 0xc8, 0xb5, 0x1f, 0x0f, 0xf3, 0x05, 0x8f, 0x47, 0x77, 0xfb, 0xe3, 0x61, 0x35, 0x8f, 0xc7,
|
||||
0x2e, 0x58, 0x13, 0x11, 0x1c, 0x8f, 0x65, 0x46, 0x26, 0x53, 0x80, 0xd8, 0x38, 0x0a, 0xf2, 0xf0,
|
||||
0x1c, 0xf5, 0x8b, 0xa2, 0xd1, 0x86, 0xf6, 0xd9, 0x5b, 0xb4, 0xef, 0x27, 0x03, 0x7a, 0xf7, 0x79,
|
||||
0x99, 0x14, 0xf9, 0x06, 0x0b, 0x87, 0x30, 0x18, 0xa5, 0x69, 0x14, 0x06, 0xea, 0xd7, 0xea, 0x46,
|
||||
0x6d, 0x13, 0xed, 0x78, 0xd0, 0xaa, 0xaf, 0xba, 0x5b, 0xdb, 0x44, 0x72, 0x71, 0x24, 0xf5, 0x5d,
|
||||
0x89, 0x75, 0x4b, 0x2e, 0x94, 0xac, 0x4b, 0x27, 0x15, 0x61, 0x54, 0xe4, 0xc9, 0x3c, 0x4a, 0x2e,
|
||||
0xe4, 0x6d, 0x6d, 0x56, 0x63, 0xff, 0xcf, 0x0e, 0x74, 0xff, 0x2f, 0x4d, 0xde, 0x01, 0x23, 0xd4,
|
||||
0xcd, 0x36, 0xc2, 0x5a, 0xa1, 0xfb, 0x2d, 0x85, 0xf6, 0xa0, 0x5f, 0x0a, 0x1e, 0x2f, 0x30, 0xf3,
|
||||
0x6c, 0xa9, 0x2e, 0x15, 0x94, 0x1e, 0x39, 0x47, 0x4a, 0x9a, 0x1d, 0x56, 0xc1, 0x7a, 0x2e, 0xa0,
|
||||
0x35, 0x17, 0x1f, 0x6a, 0x15, 0x1f, 0xc8, 0x8c, 0xbc, 0xf5, 0xb2, 0x5c, 0x15, 0xef, 0xff, 0x4e,
|
||||
0x93, 0xff, 0x31, 0xc0, 0xaa, 0x87, 0xea, 0x68, 0x7d, 0xa8, 0x8e, 0x9a, 0xa1, 0x1a, 0x1f, 0x56,
|
||||
0x43, 0x35, 0x3e, 0x24, 0xcc, 0x4e, 0xaa, 0xa1, 0x62, 0x27, 0xd4, 0xac, 0xbb, 0x22, 0x29, 0xd2,
|
||||
0xc3, 0x52, 0x75, 0xd5, 0x61, 0x35, 0x26, 0x26, 0x7e, 0xbb, 0x44, 0xa1, 0x4b, 0xed, 0x30, 0x8d,
|
||||
0x88, 0xb7, 0xf7, 0xa5, 0xe0, 0xa8, 0xe2, 0x2a, 0xe0, 0xbe, 0x0b, 0x16, 0xa3, 0xe2, 0xc9, 0x0a,
|
||||
0xaf, 0xf5, 0x45, 0x9a, 0x99, 0xf2, 0x52, 0x50, 0xf5, 0xf5, 0xa6, 0x09, 0x5c, 0x7d, 0xcb, 0x7d,
|
||||
0x00, 0xbd, 0xc9, 0x32, 0x9c, 0xe7, 0xd5, 0x5b, 0xf8, 0x5a, 0x4b, 0xb0, 0xc2, 0x15, 0x4a, 0x1f,
|
||||
0xd3, 0x5b, 0xfc, 0xc7, 0xe0, 0xd4, 0xc6, 0x26, 0x1d, 0xa3, 0x9d, 0x8e, 0x0b, 0xdd, 0xd3, 0x38,
|
||||
0xcc, 0xab, 0xd1, 0xa5, 0x35, 0x5d, 0xf6, 0x71, 0xc1, 0xe3, 0x3c, 0xcc, 0xcb, 0x6a, 0x74, 0x2b,
|
||||
0xec, 0xdf, 0xd1, 0xe9, 0x53, 0xb8, 0xd3, 0x34, 0x45, 0xa1, 0x65, 0x40, 0x01, 0x79, 0x48, 0x72,
|
||||
0x81, 0x4a, 0xc1, 0x4d, 0xa6, 0x80, 0xff, 0x1d, 0x38, 0xa3, 0x08, 0x45, 0xce, 0x8a, 0x08, 0xb7,
|
||||
0xbd, 0x8c, 0xdf, 0x4c, 0x1e, 0x3d, 0xac, 0x32, 0xa0, 0x75, 0x33, 0xf2, 0xe6, 0x95, 0x91, 0xbf,
|
||||
0xc7, 0x53, 0x7e, 0x3c, 0x96, 0x3c, 0x37, 0x99, 0x46, 0xfe, 0x2f, 0x06, 0x74, 0x49, 0x5b, 0x5a,
|
||||
0xa1, 0xbb, 0x2f, 0xd2, 0xa5, 0x13, 0x91, 0x9c, 0x87, 0x33, 0x14, 0xd5, 0xe5, 0x2a, 0x2c, 0x8b,
|
||||
0x1e, 0x2c, 0xb1, 0x7e, 0x80, 0x35, 0x22, 0xae, 0xd1, 0xa7, 0x5e, 0x35, 0x4b, 0x2d, 0xae, 0x91,
|
||||
0x99, 0x29, 0xa7, 0xfb, 0x16, 0xc0, 0xa4, 0x48, 0x51, 0x8c, 0x66, 0xab, 0x30, 0x96, 0x4d, 0xb7,
|
||||
0x59, 0xcb, 0xe2, 0x7f, 0xa9, 0x3e, 0x1e, 0x37, 0x14, 0xca, 0xd8, 0xfe, 0xa1, 0x79, 0x35, 0x73,
|
||||
0xbf, 0x80, 0xfe, 0x03, 0x9e, 0xa6, 0x61, 0xbc, 0x58, 0xbb, 0x84, 0xf1, 0xdc, 0x4b, 0x74, 0xd6,
|
||||
0x2e, 0xb1, 0x0b, 0x96, 0xa4, 0x6c, 0xf5, 0xd8, 0x4b, 0x40, 0x6a, 0x76, 0x57, 0xf0, 0x38, 0xc7,
|
||||
0x99, 0xfc, 0xb0, 0xd5, 0xaf, 0x45, 0xcb, 0xe4, 0xff, 0x68, 0xac, 0xe7, 0xbb, 0xad, 0x81, 0x1b,
|
||||
0x55, 0x1e, 0xc2, 0x40, 0x7f, 0xe1, 0xcb, 0xb0, 0x5a, 0x24, 0x5b, 0x26, 0x4a, 0xf3, 0xa4, 0x98,
|
||||
0x46, 0x61, 0x20, 0xcf, 0xb4, 0x99, 0x46, 0xee, 0x6d, 0xb0, 0xf5, 0x2d, 0xab, 0x72, 0xbf, 0xda,
|
||||
0x94, 0x5b, 0x7b, 0x58, 0xbd, 0xc5, 0x3f, 0x80, 0xde, 0x51, 0x12, 0xcf, 0xc3, 0x85, 0xbb, 0x07,
|
||||
0xdd, 0x51, 0x91, 0x2f, 0x65, 0x62, 0x83, 0x83, 0xdd, 0x96, 0x1e, 0x14, 0xf9, 0x52, 0xed, 0x61,
|
||||
0x72, 0x87, 0xff, 0x39, 0x40, 0x63, 0xa3, 0x7f, 0x19, 0x4d, 0x93, 0x1e, 0xe2, 0x05, 0x31, 0x29,
|
||||
0x93, 0x51, 0x6c, 0xb6, 0xc5, 0xe3, 0x7f, 0x01, 0xce, 0x61, 0x11, 0x46, 0xb3, 0xe3, 0x78, 0x9e,
|
||||
0x90, 0xa2, 0x9c, 0xa1, 0xc8, 0x9a, 0x36, 0x56, 0x90, 0xee, 0x47, 0xe2, 0x52, 0x8f, 0x96, 0x46,
|
||||
0xd3, 0x9e, 0xfc, 0xa3, 0x76, 0xe7, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e, 0x6a, 0xf4, 0x02,
|
||||
0xba, 0x0d, 0x00, 0x00,
|
||||
// 1377 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x8e, 0xe3, 0xc4,
|
||||
0x13, 0x96, 0x63, 0x3b, 0x89, 0x2b, 0xb3, 0xfb, 0x5b, 0xf9, 0x37, 0x62, 0xcd, 0x22, 0xa1, 0x60,
|
||||
0x81, 0x08, 0x82, 0x1d, 0xd0, 0xac, 0x90, 0x10, 0x02, 0xa4, 0xcc, 0x04, 0x2d, 0xc3, 0xfe, 0x9b,
|
||||
0xed, 0xec, 0x0c, 0x27, 0xb4, 0xea, 0x38, 0x95, 0xc4, 0x5a, 0xc7, 0x36, 0x6d, 0x7b, 0x26, 0xe6,
|
||||
0x05, 0x78, 0x0b, 0x24, 0x24, 0x9e, 0x00, 0x71, 0xe7, 0x8a, 0xb8, 0xf2, 0x0e, 0xbc, 0x02, 0x57,
|
||||
0x54, 0xdd, 0x6d, 0xc7, 0x99, 0x64, 0x57, 0x73, 0x40, 0xdc, 0xfa, 0xab, 0xea, 0x54, 0x57, 0x57,
|
||||
0x7d, 0xf5, 0xb5, 0x03, 0x37, 0xc3, 0x38, 0x47, 0x11, 0xf3, 0xe8, 0x20, 0x15, 0x49, 0x9e, 0xb8,
|
||||
0xdd, 0x0a, 0xfb, 0x7f, 0xb5, 0xa0, 0x3d, 0x4e, 0x0a, 0x11, 0xa0, 0x7b, 0x13, 0x5a, 0x27, 0x23,
|
||||
0xcf, 0xe8, 0x1b, 0x03, 0x93, 0xb5, 0x4e, 0x46, 0xae, 0x0b, 0xd6, 0x63, 0xbe, 0x44, 0xaf, 0xd5,
|
||||
0x37, 0x06, 0x0e, 0x93, 0x6b, 0xb2, 0x3d, 0x2b, 0x53, 0xf4, 0x4c, 0x65, 0xa3, 0xb5, 0x7b, 0x07,
|
||||
0xba, 0x67, 0x19, 0x45, 0x5b, 0xa2, 0x67, 0x49, 0x7b, 0x8d, 0xc9, 0x77, 0xca, 0xb3, 0xec, 0x32,
|
||||
0x11, 0x53, 0xcf, 0x56, 0xbe, 0x0a, 0xbb, 0xb7, 0xc0, 0x3c, 0x63, 0x0f, 0xbd, 0xb6, 0x34, 0xd3,
|
||||
0xd2, 0xf5, 0xa0, 0x33, 0xc2, 0x19, 0x2f, 0xa2, 0xdc, 0xeb, 0xf4, 0x8d, 0x41, 0x97, 0x55, 0x90,
|
||||
0xe2, 0x3c, 0xc3, 0x08, 0xe7, 0x82, 0xcf, 0xbc, 0xae, 0x8a, 0x53, 0x61, 0xf7, 0x00, 0xdc, 0x93,
|
||||
0x38, 0xc3, 0xa0, 0x10, 0x38, 0x7e, 0x11, 0xa6, 0xe7, 0x28, 0xc2, 0x59, 0xe9, 0x39, 0x32, 0xc0,
|
||||
0x0e, 0x0f, 0x9d, 0xf2, 0x08, 0x73, 0x4e, 0x67, 0x83, 0x0c, 0x55, 0x41, 0xd7, 0x87, 0xbd, 0xf1,
|
||||
0x82, 0x0b, 0x9c, 0x8e, 0x31, 0x10, 0x98, 0x7b, 0x3d, 0xe9, 0xde, 0xb0, 0xd1, 0x9e, 0x27, 0x62,
|
||||
0xce, 0xe3, 0xf0, 0x7b, 0x9e, 0x87, 0x49, 0xec, 0xed, 0xa9, 0x3d, 0x4d, 0x1b, 0x55, 0x89, 0x25,
|
||||
0x11, 0x7a, 0x37, 0x54, 0x95, 0x68, 0xed, 0xff, 0x6a, 0x80, 0x33, 0xe2, 0xd9, 0x62, 0x92, 0x70,
|
||||
0x31, 0xbd, 0x56, 0xad, 0xef, 0x82, 0x1d, 0x60, 0x14, 0x65, 0x9e, 0xd9, 0x37, 0x07, 0xbd, 0xc3,
|
||||
0xdb, 0x07, 0x75, 0x13, 0xeb, 0x38, 0xc7, 0x18, 0x45, 0x4c, 0xed, 0x72, 0x3f, 0x02, 0x27, 0xc7,
|
||||
0x65, 0x1a, 0xf1, 0x1c, 0x33, 0xcf, 0x92, 0x3f, 0x71, 0xd7, 0x3f, 0x79, 0xa6, 0x5d, 0x6c, 0xbd,
|
||||
0x69, 0xeb, 0x2a, 0xf6, 0xf6, 0x55, 0xfc, 0x3f, 0x5b, 0x70, 0x63, 0xe3, 0x38, 0x77, 0x0f, 0x8c,
|
||||
0x95, 0xcc, 0xdc, 0x66, 0xc6, 0x8a, 0x50, 0x29, 0xb3, 0xb6, 0x99, 0x51, 0x12, 0xba, 0x94, 0xdc,
|
||||
0xb0, 0x99, 0x71, 0x49, 0x68, 0x21, 0x19, 0x61, 0x33, 0x63, 0xe1, 0xbe, 0x07, 0x9d, 0xef, 0x0a,
|
||||
0x14, 0x21, 0x66, 0x9e, 0x2d, 0xb3, 0xfb, 0xdf, 0x3a, 0xbb, 0xa7, 0x05, 0x8a, 0x92, 0x55, 0x7e,
|
||||
0xaa, 0x86, 0x64, 0x93, 0xa2, 0x86, 0x5c, 0x93, 0x2d, 0x27, 0xe6, 0x75, 0x94, 0x8d, 0xd6, 0xba,
|
||||
0x8a, 0x8a, 0x0f, 0x54, 0xc5, 0x8f, 0xc1, 0xe2, 0x2b, 0xcc, 0x3c, 0x47, 0xc6, 0x7f, 0xeb, 0x25,
|
||||
0x05, 0x3b, 0x18, 0xae, 0x30, 0xfb, 0x32, 0xce, 0x45, 0xc9, 0xe4, 0x76, 0xf7, 0x5d, 0x68, 0x07,
|
||||
0x49, 0x94, 0x88, 0xcc, 0x83, 0xab, 0x89, 0x1d, 0x93, 0x9d, 0x69, 0xf7, 0x9d, 0xfb, 0xe0, 0xd4,
|
||||
0xbf, 0x25, 0xfa, 0xbe, 0xc0, 0x52, 0x56, 0xc2, 0x61, 0xb4, 0x74, 0xdf, 0x06, 0xfb, 0x82, 0x47,
|
||||
0x85, 0xea, 0x62, 0xef, 0xf0, 0xe6, 0x3a, 0xcc, 0x70, 0x15, 0x66, 0x4c, 0x39, 0x3f, 0x6d, 0x7d,
|
||||
0x62, 0xf8, 0x73, 0xb0, 0x65, 0xe4, 0x06, 0x0f, 0x9c, 0x8a, 0x07, 0x72, 0xbe, 0x5a, 0x8d, 0xf9,
|
||||
0xba, 0x05, 0xe6, 0x57, 0xb8, 0xd2, 0x23, 0x47, 0xcb, 0x9a, 0x2d, 0x56, 0x83, 0x2d, 0xfb, 0x60,
|
||||
0x9f, 0xcb, 0xc3, 0x55, 0x17, 0x15, 0xf0, 0x7f, 0x31, 0xc0, 0xa2, 0xc3, 0xa9, 0xd7, 0x11, 0xce,
|
||||
0x79, 0x50, 0x1e, 0x25, 0x45, 0x3c, 0xcd, 0x3c, 0xa3, 0x6f, 0x0e, 0x4c, 0xb6, 0x61, 0x73, 0x5f,
|
||||
0x83, 0xf6, 0x44, 0x79, 0x5b, 0x7d, 0x73, 0xe0, 0x30, 0x8d, 0x28, 0x74, 0xc4, 0x27, 0x18, 0xe9,
|
||||
0x14, 0x14, 0xa0, 0xdd, 0xa9, 0xc0, 0x59, 0xb8, 0xd2, 0x69, 0x68, 0x44, 0xf6, 0xac, 0x98, 0x91,
|
||||
0x5d, 0x65, 0xa2, 0x11, 0x25, 0x3d, 0xe1, 0x59, 0xdd, 0x54, 0x5a, 0x53, 0xe4, 0x2c, 0xe0, 0x51,
|
||||
0xd5, 0x55, 0x05, 0xfc, 0xdf, 0x0c, 0x9a, 0x76, 0xc5, 0xd2, 0xad, 0x0a, 0xbd, 0x0e, 0x5d, 0x62,
|
||||
0xf0, 0xf3, 0x0b, 0x2e, 0x74, 0x95, 0x3a, 0x84, 0xcf, 0xb9, 0x70, 0x3f, 0x84, 0xb6, 0x2c, 0xf1,
|
||||
0x8e, 0x89, 0xa9, 0xc2, 0xc9, 0xaa, 0x30, 0xbd, 0xad, 0xe6, 0x94, 0xd5, 0xe0, 0x54, 0x7d, 0x59,
|
||||
0xbb, 0x79, 0xd9, 0xbb, 0x60, 0x13, 0x39, 0x4b, 0x99, 0xfd, 0xce, 0xc8, 0x8a, 0xc2, 0x6a, 0x97,
|
||||
0x7f, 0x06, 0x37, 0x36, 0x4e, 0xac, 0x4f, 0x32, 0x36, 0x4f, 0x5a, 0xd3, 0xc5, 0xd1, 0xf4, 0x20,
|
||||
0xa5, 0xcb, 0x30, 0xc2, 0x20, 0xc7, 0xa9, 0xac, 0x77, 0x97, 0xd5, 0xd8, 0xff, 0xc9, 0x58, 0xc7,
|
||||
0x95, 0xe7, 0x91, 0x96, 0x05, 0xc9, 0x72, 0xc9, 0xe3, 0xa9, 0x0e, 0x5d, 0x41, 0xaa, 0xdb, 0x74,
|
||||
0xa2, 0x43, 0xb7, 0xa6, 0x13, 0xc2, 0x22, 0xd5, 0x1d, 0x6c, 0x89, 0xd4, 0xed, 0x43, 0x6f, 0x89,
|
||||
0x3c, 0x2b, 0x04, 0x2e, 0x31, 0xce, 0x75, 0x09, 0x9a, 0x26, 0xf7, 0x36, 0x74, 0x72, 0x3e, 0x7f,
|
||||
0x4e, 0x24, 0xd7, 0x9d, 0xcc, 0xf9, 0xfc, 0x01, 0x96, 0xee, 0x1b, 0xe0, 0xcc, 0x42, 0x8c, 0xa6,
|
||||
0xd2, 0xa5, 0xda, 0xd9, 0x95, 0x86, 0x07, 0x58, 0xfa, 0xbf, 0x1b, 0xd0, 0x1e, 0xa3, 0xb8, 0x40,
|
||||
0x71, 0x2d, 0x91, 0x6b, 0x3e, 0x1e, 0xe6, 0x2b, 0x1e, 0x0f, 0x6b, 0xf7, 0xe3, 0x61, 0xaf, 0x1f,
|
||||
0x8f, 0x7d, 0xb0, 0xc7, 0x22, 0x38, 0x19, 0xc9, 0x8c, 0x4c, 0xa6, 0x00, 0xb1, 0x71, 0x18, 0xe4,
|
||||
0xe1, 0x05, 0xea, 0x17, 0x45, 0xa3, 0x2d, 0xed, 0xeb, 0xee, 0xd0, 0xbe, 0x1f, 0x0d, 0x68, 0x3f,
|
||||
0xe4, 0x65, 0x52, 0xe4, 0x5b, 0x2c, 0xec, 0x43, 0x6f, 0x98, 0xa6, 0x51, 0x18, 0xa8, 0x5f, 0xab,
|
||||
0x1b, 0x35, 0x4d, 0xb4, 0xe3, 0x51, 0xa3, 0xbe, 0xea, 0x6e, 0x4d, 0x13, 0xc9, 0xc5, 0xb1, 0xd4,
|
||||
0x77, 0x25, 0xd6, 0x0d, 0xb9, 0x50, 0xb2, 0x2e, 0x9d, 0x54, 0x84, 0x61, 0x91, 0x27, 0xb3, 0x28,
|
||||
0xb9, 0x94, 0xb7, 0xed, 0xb2, 0x1a, 0xfb, 0x7f, 0xb4, 0xc0, 0xfa, 0xaf, 0x34, 0x79, 0x0f, 0x8c,
|
||||
0x50, 0x37, 0xdb, 0x08, 0x6b, 0x85, 0xee, 0x34, 0x14, 0xda, 0x83, 0x4e, 0x29, 0x78, 0x3c, 0xc7,
|
||||
0xcc, 0xeb, 0x4a, 0x75, 0xa9, 0xa0, 0xf4, 0xc8, 0x39, 0x52, 0xd2, 0xec, 0xb0, 0x0a, 0xd6, 0x73,
|
||||
0x01, 0x8d, 0xb9, 0xf8, 0x40, 0xab, 0x78, 0x4f, 0x66, 0xe4, 0x6d, 0x96, 0xe5, 0xaa, 0x78, 0xff,
|
||||
0x7b, 0x9a, 0xfc, 0xb7, 0x01, 0x76, 0x3d, 0x54, 0xc7, 0x9b, 0x43, 0x75, 0xbc, 0x1e, 0xaa, 0xd1,
|
||||
0x51, 0x35, 0x54, 0xa3, 0x23, 0xc2, 0xec, 0xb4, 0x1a, 0x2a, 0x76, 0x4a, 0xcd, 0xba, 0x2f, 0x92,
|
||||
0x22, 0x3d, 0x2a, 0x55, 0x57, 0x1d, 0x56, 0x63, 0x62, 0xe2, 0x37, 0x0b, 0x14, 0xba, 0xd4, 0x0e,
|
||||
0xd3, 0x88, 0x78, 0xfb, 0x50, 0x0a, 0x8e, 0x2a, 0xae, 0x02, 0xee, 0x3b, 0x60, 0x33, 0x2a, 0x9e,
|
||||
0xac, 0xf0, 0x46, 0x5f, 0xa4, 0x99, 0x29, 0x2f, 0x05, 0x55, 0x5f, 0x6f, 0x9a, 0xc0, 0xd5, 0xb7,
|
||||
0xdc, 0xfb, 0xd0, 0x1e, 0x2f, 0xc2, 0x59, 0x5e, 0xbd, 0x85, 0xff, 0x6f, 0x08, 0x56, 0xb8, 0x44,
|
||||
0xe9, 0x63, 0x7a, 0x8b, 0xff, 0x14, 0x9c, 0xda, 0xb8, 0x4e, 0xc7, 0x68, 0xa6, 0xe3, 0x82, 0x75,
|
||||
0x16, 0x87, 0x79, 0x35, 0xba, 0xb4, 0xa6, 0xcb, 0x3e, 0x2d, 0x78, 0x9c, 0x87, 0x79, 0x59, 0x8d,
|
||||
0x6e, 0x85, 0xfd, 0x7b, 0x3a, 0x7d, 0x0a, 0x77, 0x96, 0xa6, 0x28, 0xb4, 0x0c, 0x28, 0x20, 0x0f,
|
||||
0x49, 0x2e, 0x51, 0x29, 0xb8, 0xc9, 0x14, 0xf0, 0xbf, 0x05, 0x67, 0x18, 0xa1, 0xc8, 0x59, 0x11,
|
||||
0xe1, 0xae, 0x97, 0xf1, 0xeb, 0xf1, 0x93, 0xc7, 0x55, 0x06, 0xb4, 0x5e, 0x8f, 0xbc, 0x79, 0x65,
|
||||
0xe4, 0x1f, 0xf0, 0x94, 0x9f, 0x8c, 0x24, 0xcf, 0x4d, 0xa6, 0x91, 0xff, 0xb3, 0x01, 0x16, 0x69,
|
||||
0x4b, 0x23, 0xb4, 0xf5, 0x2a, 0x5d, 0x3a, 0x15, 0xc9, 0x45, 0x38, 0x45, 0x51, 0x5d, 0xae, 0xc2,
|
||||
0xb2, 0xe8, 0xc1, 0x02, 0xeb, 0x07, 0x58, 0x23, 0xe2, 0x1a, 0x7d, 0xea, 0x55, 0xb3, 0xd4, 0xe0,
|
||||
0x1a, 0x99, 0x99, 0x72, 0xba, 0x6f, 0x02, 0x8c, 0x8b, 0x14, 0xc5, 0x70, 0xba, 0x0c, 0x63, 0xd9,
|
||||
0xf4, 0x2e, 0x6b, 0x58, 0xfc, 0x2f, 0xd4, 0xc7, 0xe3, 0x96, 0x42, 0x19, 0xbb, 0x3f, 0x34, 0xaf,
|
||||
0x66, 0xee, 0xff, 0x60, 0x40, 0xe7, 0x11, 0x4f, 0xd3, 0x30, 0x9e, 0x6f, 0xdc, 0xc2, 0x78, 0xe9,
|
||||
0x2d, 0x5a, 0x1b, 0xb7, 0xd8, 0x07, 0x5b, 0x72, 0xb6, 0x7a, 0xed, 0x25, 0xd0, 0x35, 0xb3, 0xea,
|
||||
0x76, 0x5c, 0xe7, 0xdb, 0x31, 0xda, 0xdc, 0xb3, 0xab, 0xa5, 0x5b, 0x75, 0xef, 0x43, 0x4f, 0x7f,
|
||||
0xf3, 0xcb, 0x2f, 0x68, 0x2d, 0x9b, 0x0d, 0x13, 0xe5, 0x7d, 0x5a, 0x4c, 0xa2, 0x30, 0x90, 0xd9,
|
||||
0x74, 0x99, 0x46, 0xfe, 0x21, 0xb4, 0x8f, 0x93, 0x78, 0x16, 0xce, 0xdd, 0x01, 0x58, 0xc3, 0x22,
|
||||
0x5f, 0xc8, 0x93, 0x7a, 0x87, 0xfb, 0x8d, 0x91, 0x2f, 0xf2, 0x85, 0xda, 0xc3, 0xe4, 0x0e, 0xff,
|
||||
0x33, 0x80, 0xb5, 0x8d, 0xfe, 0x48, 0xac, 0xfb, 0xf0, 0x18, 0x2f, 0x89, 0x2c, 0x99, 0x8c, 0xd2,
|
||||
0x65, 0x3b, 0x3c, 0xfe, 0xe7, 0xe0, 0x1c, 0x15, 0x61, 0x34, 0x3d, 0x89, 0x67, 0x09, 0x89, 0xc6,
|
||||
0x39, 0x8a, 0x6c, 0xdd, 0xa9, 0x0a, 0x52, 0xc2, 0xa4, 0x1f, 0xf5, 0xf4, 0x68, 0x34, 0x69, 0xcb,
|
||||
0xff, 0x62, 0xf7, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x82, 0x96, 0xb8, 0xb3, 0x9d, 0x0d, 0x00,
|
||||
0x00,
|
||||
}
|
||||
|
|
|
@ -161,7 +161,8 @@ message Mapping {
|
|||
string Provider = 1; // Provider is the provider that certifies and issues this user's authentication, e.g. GitHub
|
||||
string Scheme = 2; // Scheme is the scheme used to perform this user's authentication, e.g. OAuth2 or LDAP
|
||||
string Group = 3; // Group is the group or organizations that you are a part of in an auth provider
|
||||
string GrantedRole = 4; // GrantedRole is the name of the role that you will be granted if you match the mapping
|
||||
string ID = 4; // ID is the unique ID for the mapping
|
||||
string Organization = 5; // Organization is the organization ID that resource belongs to
|
||||
}
|
||||
|
||||
message Organization {
|
||||
|
@ -169,7 +170,6 @@ message Organization {
|
|||
string Name = 2; // Name is the organization's name
|
||||
string DefaultRole = 3; // DefaultRole is the name of the role that is the default for any users added to the organization
|
||||
bool Public = 4; // Public specifies that users must be explicitly added to the organization
|
||||
repeated Mapping Mappings = 5; // Mappings is set of mappings a organization has
|
||||
}
|
||||
|
||||
message Config {
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package bolt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/bolt/internal"
|
||||
)
|
||||
|
||||
// Ensure MappingsStore implements chronograf.MappingsStore.
|
||||
var _ chronograf.MappingsStore = &MappingsStore{}
|
||||
|
||||
var (
|
||||
// MappingsBucket is the bucket where organizations are stored.
|
||||
MappingsBucket = []byte("MappingsV1")
|
||||
)
|
||||
|
||||
// MappingsStore uses bolt to store and retrieve Mappings
|
||||
type MappingsStore struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Migrate sets the default organization at runtime
|
||||
func (s *MappingsStore) Migrate(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Add creates a new Mapping in the MappingsStore
|
||||
func (s *MappingsStore) Add(ctx context.Context, o *chronograf.Mapping) (*chronograf.Mapping, error) {
|
||||
err := s.client.db.Update(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(MappingsBucket)
|
||||
seq, err := b.NextSequence()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.ID = fmt.Sprintf("%d", seq)
|
||||
|
||||
v, err := internal.MarshalMapping(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return b.Put([]byte(o.ID), v)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// All returns all known organizations
|
||||
func (s *MappingsStore) All(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
var orgs []chronograf.Mapping
|
||||
err := s.each(ctx, func(o *chronograf.Mapping) {
|
||||
orgs = append(orgs, *o)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return orgs, nil
|
||||
}
|
||||
|
||||
// Delete the organization from MappingsStore
|
||||
func (s *MappingsStore) Delete(ctx context.Context, o *chronograf.Mapping) error {
|
||||
_, err := s.get(ctx, o.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.client.db.Update(func(tx *bolt.Tx) error {
|
||||
return tx.Bucket(MappingsBucket).Delete([]byte(o.ID))
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MappingsStore) get(ctx context.Context, id string) (*chronograf.Mapping, error) {
|
||||
var o chronograf.Mapping
|
||||
err := s.client.db.View(func(tx *bolt.Tx) error {
|
||||
v := tx.Bucket(MappingsBucket).Get([]byte(id))
|
||||
if v == nil {
|
||||
return chronograf.ErrMappingNotFound
|
||||
}
|
||||
return internal.UnmarshalMapping(v, &o)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &o, nil
|
||||
}
|
||||
|
||||
func (s *MappingsStore) each(ctx context.Context, fn func(*chronograf.Mapping)) error {
|
||||
return s.client.db.View(func(tx *bolt.Tx) error {
|
||||
return tx.Bucket(MappingsBucket).ForEach(func(k, v []byte) error {
|
||||
var org chronograf.Mapping
|
||||
if err := internal.UnmarshalMapping(v, &org); err != nil {
|
||||
return err
|
||||
}
|
||||
fn(&org)
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Get returns a Mapping if the id exists.
|
||||
func (s *MappingsStore) Get(ctx context.Context, id string) (*chronograf.Mapping, error) {
|
||||
return s.get(ctx, id)
|
||||
}
|
||||
|
||||
// Update the organization in MappingsStore
|
||||
func (s *MappingsStore) Update(ctx context.Context, o *chronograf.Mapping) error {
|
||||
return s.client.db.Update(func(tx *bolt.Tx) error {
|
||||
if v, err := internal.MarshalMapping(o); err != nil {
|
||||
return err
|
||||
} else if err := tx.Bucket(MappingsBucket).Put([]byte(o.ID), v); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
|
@ -0,0 +1,489 @@
|
|||
package bolt_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"github.com/influxdata/chronograf"
|
||||
)
|
||||
|
||||
var mappingCmpOptions = cmp.Options{
|
||||
cmpopts.IgnoreFields(chronograf.Mapping{}, "ID"),
|
||||
cmpopts.EquateEmpty(),
|
||||
}
|
||||
|
||||
func TestMappingStore_Add(t *testing.T) {
|
||||
type fields struct {
|
||||
mappings []*chronograf.Mapping
|
||||
}
|
||||
type args struct {
|
||||
mapping *chronograf.Mapping
|
||||
}
|
||||
type wants struct {
|
||||
mapping *chronograf.Mapping
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "default with wildcards",
|
||||
args: args{
|
||||
mapping: &chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
mapping: &chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "simple",
|
||||
args: args{
|
||||
mapping: &chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
Group: "idk",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
mapping: &chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
Group: "idk",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client, err := NewTestClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
s := client.MappingsStore
|
||||
ctx := context.Background()
|
||||
|
||||
for _, mapping := range tt.fields.mappings {
|
||||
// YOLO database prepopulation
|
||||
_, _ = s.Add(ctx, mapping)
|
||||
}
|
||||
|
||||
tt.args.mapping, err = s.Add(ctx, tt.args.mapping)
|
||||
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Errorf("MappingsStore.Add() error = %v, want error %v", err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
|
||||
got, err := s.Get(ctx, tt.args.mapping.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get mapping: %v", err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(got, tt.wants.mapping, mappingCmpOptions...); diff != "" {
|
||||
t.Errorf("MappingStore.Add():\n-got/+want\ndiff %s", diff)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingStore_All(t *testing.T) {
|
||||
type fields struct {
|
||||
mappings []*chronograf.Mapping
|
||||
}
|
||||
type args struct {
|
||||
}
|
||||
type wants struct {
|
||||
mappings []chronograf.Mapping
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
fields: fields{
|
||||
mappings: []*chronograf.Mapping{
|
||||
&chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
&chronograf.Mapping{
|
||||
Organization: "0",
|
||||
Provider: "google",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Organization: "0",
|
||||
Provider: "google",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client, err := NewTestClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
s := client.MappingsStore
|
||||
ctx := context.Background()
|
||||
|
||||
for _, mapping := range tt.fields.mappings {
|
||||
// YOLO database prepopulation
|
||||
_, _ = s.Add(ctx, mapping)
|
||||
}
|
||||
|
||||
got, err := s.All(ctx)
|
||||
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Errorf("MappingsStore.All() error = %v, want error %v", err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(got, tt.wants.mappings, mappingCmpOptions...); diff != "" {
|
||||
t.Errorf("MappingStore.All():\n-got/+want\ndiff %s", diff)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingStore_Delete(t *testing.T) {
|
||||
type fields struct {
|
||||
mappings []*chronograf.Mapping
|
||||
}
|
||||
type args struct {
|
||||
mapping *chronograf.Mapping
|
||||
}
|
||||
type wants struct {
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
fields: fields{
|
||||
mappings: []*chronograf.Mapping{
|
||||
&chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
&chronograf.Mapping{
|
||||
Organization: "0",
|
||||
Provider: "google",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
mapping: &chronograf.Mapping{
|
||||
ID: "1",
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mapping not found",
|
||||
fields: fields{
|
||||
mappings: []*chronograf.Mapping{
|
||||
&chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
&chronograf.Mapping{
|
||||
Organization: "0",
|
||||
Provider: "google",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
mapping: &chronograf.Mapping{
|
||||
ID: "0",
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
err: chronograf.ErrMappingNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client, err := NewTestClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
s := client.MappingsStore
|
||||
ctx := context.Background()
|
||||
|
||||
for _, mapping := range tt.fields.mappings {
|
||||
// YOLO database prepopulation
|
||||
_, _ = s.Add(ctx, mapping)
|
||||
}
|
||||
|
||||
err = s.Delete(ctx, tt.args.mapping)
|
||||
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Errorf("MappingsStore.Delete() error = %v, want error %v", err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingStore_Get(t *testing.T) {
|
||||
type fields struct {
|
||||
mappings []*chronograf.Mapping
|
||||
}
|
||||
type args struct {
|
||||
mappingID string
|
||||
}
|
||||
type wants struct {
|
||||
mapping *chronograf.Mapping
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
fields: fields{
|
||||
mappings: []*chronograf.Mapping{
|
||||
&chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
&chronograf.Mapping{
|
||||
Organization: "0",
|
||||
Provider: "google",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
mappingID: "1",
|
||||
},
|
||||
wants: wants{
|
||||
mapping: &chronograf.Mapping{
|
||||
ID: "1",
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "mapping not found",
|
||||
fields: fields{
|
||||
mappings: []*chronograf.Mapping{
|
||||
&chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
&chronograf.Mapping{
|
||||
Organization: "0",
|
||||
Provider: "google",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
mappingID: "0",
|
||||
},
|
||||
wants: wants{
|
||||
err: chronograf.ErrMappingNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client, err := NewTestClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
s := client.MappingsStore
|
||||
ctx := context.Background()
|
||||
|
||||
for _, mapping := range tt.fields.mappings {
|
||||
// YOLO database prepopulation
|
||||
_, _ = s.Add(ctx, mapping)
|
||||
}
|
||||
|
||||
got, err := s.Get(ctx, tt.args.mappingID)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Errorf("MappingsStore.Get() error = %v, want error %v", err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(got, tt.wants.mapping, mappingCmpOptions...); diff != "" {
|
||||
t.Errorf("MappingStore.Get():\n-got/+want\ndiff %s", diff)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMappingStore_Update(t *testing.T) {
|
||||
type fields struct {
|
||||
mappings []*chronograf.Mapping
|
||||
}
|
||||
type args struct {
|
||||
mapping *chronograf.Mapping
|
||||
}
|
||||
type wants struct {
|
||||
mapping *chronograf.Mapping
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
fields: fields{
|
||||
mappings: []*chronograf.Mapping{
|
||||
&chronograf.Mapping{
|
||||
Organization: "default",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
&chronograf.Mapping{
|
||||
Organization: "0",
|
||||
Provider: "google",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
mapping: &chronograf.Mapping{
|
||||
ID: "1",
|
||||
Organization: "default",
|
||||
Provider: "cool",
|
||||
Scheme: "it",
|
||||
Group: "works",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
mapping: &chronograf.Mapping{
|
||||
ID: "1",
|
||||
Organization: "default",
|
||||
Provider: "cool",
|
||||
Scheme: "it",
|
||||
Group: "works",
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client, err := NewTestClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
s := client.MappingsStore
|
||||
ctx := context.Background()
|
||||
|
||||
for _, mapping := range tt.fields.mappings {
|
||||
// YOLO database prepopulation
|
||||
_, _ = s.Add(ctx, mapping)
|
||||
}
|
||||
|
||||
err = s.Update(ctx, tt.args.mapping)
|
||||
if (err != nil) != (tt.wants.err != nil) {
|
||||
t.Errorf("MappingsStore.Update() error = %v, want error %v", err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(tt.args.mapping, tt.wants.mapping, mappingCmpOptions...); diff != "" {
|
||||
t.Errorf("MappingStore.Update():\n-got/+want\ndiff %s", diff)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -29,14 +29,6 @@ const (
|
|||
DefaultOrganizationPublic bool = true
|
||||
)
|
||||
|
||||
// DefaultOrganizationMapping is the mapping for the default organization
|
||||
var DefaultOrganizationMapping = chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: DefaultOrganizationRole,
|
||||
}
|
||||
|
||||
// OrganizationsStore uses bolt to store and retrieve Organizations
|
||||
type OrganizationsStore struct {
|
||||
client *Client
|
||||
|
@ -54,9 +46,14 @@ func (s *OrganizationsStore) CreateDefault(ctx context.Context) error {
|
|||
Name: DefaultOrganizationName,
|
||||
DefaultRole: DefaultOrganizationRole,
|
||||
Public: DefaultOrganizationPublic,
|
||||
Mappings: []chronograf.Mapping{
|
||||
DefaultOrganizationMapping,
|
||||
},
|
||||
}
|
||||
|
||||
m := chronograf.Mapping{
|
||||
ID: string(DefaultOrganizationID),
|
||||
Organization: string(DefaultOrganizationID),
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
}
|
||||
return s.client.db.Update(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(OrganizationsBucket)
|
||||
|
@ -70,6 +67,17 @@ func (s *OrganizationsStore) CreateDefault(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
b = tx.Bucket(MappingsBucket)
|
||||
v = b.Get(DefaultOrganizationID)
|
||||
if v != nil {
|
||||
return nil
|
||||
}
|
||||
if v, err := internal.MarshalMapping(&m); err != nil {
|
||||
return err
|
||||
} else if err := b.Put(DefaultOrganizationID, v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
@ -42,26 +42,10 @@ func TestOrganizationsStore_GetWithName(t *testing.T) {
|
|||
ctx: context.Background(),
|
||||
org: &chronograf.Organization{
|
||||
Name: "EE - Evil Empire",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &chronograf.Organization{
|
||||
Name: "EE - Evil Empire",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
addFirst: true,
|
||||
},
|
||||
|
@ -187,9 +171,6 @@ func TestOrganizationsStore_All(t *testing.T) {
|
|||
Name: "EE - Evil Empire",
|
||||
DefaultRole: roles.MemberRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
bolt.DefaultOrganizationMapping,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "The Good Place",
|
||||
|
@ -203,9 +184,6 @@ func TestOrganizationsStore_All(t *testing.T) {
|
|||
Name: "EE - Evil Empire",
|
||||
DefaultRole: roles.MemberRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
bolt.DefaultOrganizationMapping,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "The Good Place",
|
||||
|
@ -216,9 +194,6 @@ func TestOrganizationsStore_All(t *testing.T) {
|
|||
Name: bolt.DefaultOrganizationName,
|
||||
DefaultRole: bolt.DefaultOrganizationRole,
|
||||
Public: bolt.DefaultOrganizationPublic,
|
||||
Mappings: []chronograf.Mapping{
|
||||
bolt.DefaultOrganizationMapping,
|
||||
},
|
||||
},
|
||||
},
|
||||
addFirst: true,
|
||||
|
@ -260,10 +235,9 @@ func TestOrganizationsStore_Update(t *testing.T) {
|
|||
orgs []chronograf.Organization
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
initial *chronograf.Organization
|
||||
updates *chronograf.Organization
|
||||
mappings []chronograf.Mapping
|
||||
ctx context.Context
|
||||
initial *chronograf.Organization
|
||||
updates *chronograf.Organization
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
@ -387,7 +361,7 @@ func TestOrganizationsStore_Update(t *testing.T) {
|
|||
addFirst: true,
|
||||
},
|
||||
{
|
||||
name: "Update organization name and mappings",
|
||||
name: "Update organization name",
|
||||
fields: fields{},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
|
@ -397,26 +371,10 @@ func TestOrganizationsStore_Update(t *testing.T) {
|
|||
},
|
||||
updates: &chronograf.Organization{
|
||||
Name: "The Bad Place",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &chronograf.Organization{
|
||||
Name: "The Bad Place",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
addFirst: true,
|
||||
},
|
||||
|
@ -468,9 +426,6 @@ func TestOrganizationsStore_Update(t *testing.T) {
|
|||
if tt.args.updates.DefaultRole != "" {
|
||||
tt.args.initial.DefaultRole = tt.args.updates.DefaultRole
|
||||
}
|
||||
if tt.args.updates.Mappings != nil {
|
||||
tt.args.initial.Mappings = tt.args.updates.Mappings
|
||||
}
|
||||
|
||||
if tt.args.updates.Public != tt.args.initial.Public {
|
||||
tt.args.initial.Public = tt.args.updates.Public
|
||||
|
@ -682,9 +637,6 @@ func TestOrganizationsStore_DefaultOrganization(t *testing.T) {
|
|||
Name: bolt.DefaultOrganizationName,
|
||||
DefaultRole: bolt.DefaultOrganizationRole,
|
||||
Public: bolt.DefaultOrganizationPublic,
|
||||
Mappings: []chronograf.Mapping{
|
||||
bolt.DefaultOrganizationMapping,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
|
|
|
@ -27,6 +27,7 @@ const (
|
|||
ErrInvalidColor = Error("Invalid color. Accepted color format is #RRGGBB")
|
||||
ErrUserAlreadyExists = Error("user already exists")
|
||||
ErrOrganizationNotFound = Error("organization not found")
|
||||
ErrMappingNotFound = Error("mapping not found")
|
||||
ErrOrganizationAlreadyExists = Error("organization already exists")
|
||||
ErrCannotDeleteDefaultOrganization = Error("cannot delete default organization")
|
||||
ErrConfigNotFound = Error("cannot find configuration")
|
||||
|
@ -563,18 +564,6 @@ type LayoutsStore interface {
|
|||
Update(context.Context, Layout) error
|
||||
}
|
||||
|
||||
// Organization is a group of resources under a common name
|
||||
type Organization struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
// DefaultRole is the name of the role that is the default for any users added to the organization
|
||||
DefaultRole string `json:"defaultRole,omitempty"`
|
||||
// Public specifies whether users must be explicitly added to the organization.
|
||||
// It is currently only used by the default organization, but that may change in the future.
|
||||
Public bool `json:"public"`
|
||||
Mappings []Mapping `json:"mappings"`
|
||||
}
|
||||
|
||||
// MappingWildcard is the wildcard value for mappings
|
||||
const MappingWildcard string = "*"
|
||||
|
||||
|
@ -584,19 +573,47 @@ const MappingWildcard string = "*"
|
|||
// explicit role within the organization.
|
||||
//
|
||||
// One can think of a mapping like so:
|
||||
// Provider:Scheme:Group -> GrantedRole
|
||||
// github:oauth2:influxdata -> Viewer
|
||||
// beyondcorp:ldap:influxdata -> Admin
|
||||
// Provider:Scheme:Group -> Organization
|
||||
// github:oauth2:influxdata -> Happy
|
||||
// beyondcorp:ldap:influxdata -> TheBillHilliettas
|
||||
//
|
||||
// Any of Provider, Scheme, or Group may be provided as a wildcard *
|
||||
// github:oauth2:* -> Editor
|
||||
// *:*:* -> Member
|
||||
// github:oauth2:* -> MyOrg
|
||||
// *:*:* -> AllOrg
|
||||
type Mapping struct {
|
||||
ID string `json:"id"`
|
||||
Organization string `json:"organization"`
|
||||
|
||||
Provider string `json:"provider"`
|
||||
Scheme string `json:"scheme"`
|
||||
Group string `json:"group"`
|
||||
}
|
||||
|
||||
GrantedRole string `json:"grantedRole"`
|
||||
// MappingsStore is the storage and retrieval of Mappings
|
||||
type MappingsStore interface {
|
||||
// Add creates a new Mapping.
|
||||
// The Created mapping is returned back to the user with the
|
||||
// ID field populated.
|
||||
Add(context.Context, *Mapping) (*Mapping, error)
|
||||
// All lists all Mapping in the MappingsStore
|
||||
All(context.Context) ([]Mapping, error)
|
||||
// Delete removes an Mapping from the MappingsStore
|
||||
Delete(context.Context, *Mapping) error
|
||||
// Get retrieves an Mapping from the MappingsStore
|
||||
Get(context.Context, string) (*Mapping, error)
|
||||
// Update updates an Mapping in the MappingsStore
|
||||
Update(context.Context, *Mapping) error
|
||||
}
|
||||
|
||||
// Organization is a group of resources under a common name
|
||||
type Organization struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
// DefaultRole is the name of the role that is the default for any users added to the organization
|
||||
DefaultRole string `json:"defaultRole,omitempty"`
|
||||
// Public specifies whether users must be explicitly added to the organization.
|
||||
// It is currently only used by the default organization, but that may change in the future.
|
||||
Public bool `json:"public"`
|
||||
}
|
||||
|
||||
// OrganizationQuery represents the attributes that a organization may be retrieved by.
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
func TestServer(t *testing.T) {
|
||||
type fields struct {
|
||||
Organizations []chronograf.Organization
|
||||
Mappings []chronograf.Mapping
|
||||
Users []chronograf.User
|
||||
Sources []chronograf.Source
|
||||
Servers []chronograf.Server
|
||||
|
@ -351,15 +352,7 @@ func TestServer(t *testing.T) {
|
|||
"id": "default",
|
||||
"name": "Default",
|
||||
"defaultRole": "member",
|
||||
"public": true,
|
||||
"mappings": [
|
||||
{
|
||||
"provider": "*",
|
||||
"scheme": "*",
|
||||
"group": "*",
|
||||
"grantedRole": "member"
|
||||
}
|
||||
]
|
||||
"public": true
|
||||
},
|
||||
{
|
||||
"links": {
|
||||
|
@ -368,9 +361,7 @@ func TestServer(t *testing.T) {
|
|||
"id": "howdy",
|
||||
"name": "An Organization",
|
||||
"defaultRole": "viewer",
|
||||
"public": false,
|
||||
"mappings": [
|
||||
]
|
||||
"public": false
|
||||
}
|
||||
]
|
||||
}`,
|
||||
|
@ -419,9 +410,7 @@ func TestServer(t *testing.T) {
|
|||
"id": "howdy",
|
||||
"name": "An Organization",
|
||||
"defaultRole": "viewer",
|
||||
"public": false,
|
||||
"mappings": [
|
||||
]
|
||||
"public": false
|
||||
}`,
|
||||
},
|
||||
},
|
||||
|
@ -1303,201 +1292,6 @@ func TestServer(t *testing.T) {
|
|||
"code": 401,
|
||||
"message": "user cannot modify their own SuperAdmin status"
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GET /me",
|
||||
subName: "New user hits me for the first time",
|
||||
fields: fields{
|
||||
Config: &chronograf.Config{
|
||||
Auth: chronograf.AuthConfig{
|
||||
SuperAdminNewUsers: false,
|
||||
},
|
||||
},
|
||||
Organizations: []chronograf.Organization{
|
||||
{
|
||||
ID: "1",
|
||||
Name: "Sweet",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "influxdata",
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "mimi",
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Name: "What",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "mimi",
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Name: "Okay",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
},
|
||||
},
|
||||
Users: []chronograf.User{
|
||||
{
|
||||
ID: 1, // This is artificial, but should be reflective of the users actual ID
|
||||
Name: "billibob",
|
||||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: "admin",
|
||||
Organization: "default",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
server: &server.Server{
|
||||
GithubClientID: "not empty",
|
||||
GithubClientSecret: "not empty",
|
||||
},
|
||||
method: "GET",
|
||||
path: "/chronograf/v1/me",
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billietta",
|
||||
Issuer: "github",
|
||||
Group: "influxdata,idk,mimi",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: 200,
|
||||
body: `
|
||||
{
|
||||
"id": "2",
|
||||
"name": "billietta",
|
||||
"roles": [
|
||||
{
|
||||
"name": "admin",
|
||||
"organization": "1"
|
||||
},
|
||||
{
|
||||
"name": "viewer",
|
||||
"organization": "2"
|
||||
},
|
||||
{
|
||||
"name": "member",
|
||||
"organization": "default"
|
||||
}
|
||||
],
|
||||
"provider": "github",
|
||||
"scheme": "oauth2",
|
||||
"links": {
|
||||
"self": "/chronograf/v1/users/2"
|
||||
},
|
||||
"organizations": [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Sweet",
|
||||
"defaultRole": "viewer",
|
||||
"public": false,
|
||||
"mappings": [
|
||||
{
|
||||
"provider": "*",
|
||||
"scheme": "*",
|
||||
"group": "*",
|
||||
"grantedRole": "editor"
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"scheme": "*",
|
||||
"group": "influxdata",
|
||||
"grantedRole": "admin"
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"scheme": "*",
|
||||
"group": "mimi",
|
||||
"grantedRole": "viewer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "What",
|
||||
"defaultRole": "viewer",
|
||||
"public": false,
|
||||
"mappings": [
|
||||
{
|
||||
"provider": "*",
|
||||
"scheme": "*",
|
||||
"group": "*",
|
||||
"grantedRole": "member"
|
||||
},
|
||||
{
|
||||
"provider": "github",
|
||||
"scheme": "*",
|
||||
"group": "mimi",
|
||||
"grantedRole": "viewer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "default",
|
||||
"name": "Default",
|
||||
"defaultRole": "member",
|
||||
"public": true,
|
||||
"mappings": [
|
||||
{
|
||||
"provider": "*",
|
||||
"scheme": "*",
|
||||
"group": "*",
|
||||
"grantedRole": "member"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"currentOrganization": {
|
||||
"id": "default",
|
||||
"name": "Default",
|
||||
"defaultRole": "member",
|
||||
"public": true,
|
||||
"mappings": [
|
||||
{
|
||||
"provider": "*",
|
||||
"scheme": "*",
|
||||
"group": "*",
|
||||
"grantedRole": "member"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
|
@ -1576,32 +1370,20 @@ func TestServer(t *testing.T) {
|
|||
"id": "1",
|
||||
"name": "Sweet",
|
||||
"defaultRole": "viewer",
|
||||
"public": false,
|
||||
"mappings": [
|
||||
]
|
||||
"public": false
|
||||
},
|
||||
{
|
||||
"id": "default",
|
||||
"name": "Default",
|
||||
"defaultRole": "member",
|
||||
"public": true,
|
||||
"mappings": [
|
||||
{
|
||||
"provider": "*",
|
||||
"scheme": "*",
|
||||
"group": "*",
|
||||
"grantedRole": "member"
|
||||
}
|
||||
]
|
||||
"public": true
|
||||
}
|
||||
],
|
||||
"currentOrganization": {
|
||||
"id": "1",
|
||||
"name": "Sweet",
|
||||
"defaultRole": "viewer",
|
||||
"public": false,
|
||||
"mappings": [
|
||||
]
|
||||
"public": false
|
||||
}
|
||||
}`,
|
||||
},
|
||||
|
@ -1663,6 +1445,141 @@ func TestServer(t *testing.T) {
|
|||
}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GET /me",
|
||||
subName: "New user hits me for the first time",
|
||||
fields: fields{
|
||||
Config: &chronograf.Config{
|
||||
Auth: chronograf.AuthConfig{
|
||||
SuperAdminNewUsers: false,
|
||||
},
|
||||
},
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
ID: "1",
|
||||
Organization: "1",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "influxdata",
|
||||
},
|
||||
{
|
||||
ID: "1",
|
||||
Organization: "1",
|
||||
Provider: "*",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Organization: "2",
|
||||
Provider: "github",
|
||||
Scheme: "*",
|
||||
Group: "*",
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Organization: "3",
|
||||
Provider: "auth0",
|
||||
Scheme: "ldap",
|
||||
Group: "*",
|
||||
},
|
||||
},
|
||||
Organizations: []chronograf.Organization{
|
||||
{
|
||||
ID: "1",
|
||||
Name: "Sweet",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Name: "What",
|
||||
DefaultRole: roles.EditorRoleName,
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
Name: "Okay",
|
||||
DefaultRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
Users: []chronograf.User{
|
||||
{
|
||||
ID: 1, // This is artificial, but should be reflective of the users actual ID
|
||||
Name: "billibob",
|
||||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{},
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
server: &server.Server{
|
||||
GithubClientID: "not empty",
|
||||
GithubClientSecret: "not empty",
|
||||
},
|
||||
method: "GET",
|
||||
path: "/chronograf/v1/me",
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billietta",
|
||||
Issuer: "github",
|
||||
Group: "influxdata,idk,mimi",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
statusCode: 200,
|
||||
body: `
|
||||
{
|
||||
"id": "2",
|
||||
"name": "billietta",
|
||||
"roles": [
|
||||
{
|
||||
"name": "viewer",
|
||||
"organization": "1"
|
||||
},
|
||||
{
|
||||
"name": "editor",
|
||||
"organization": "2"
|
||||
},
|
||||
{
|
||||
"name": "member",
|
||||
"organization": "default"
|
||||
}
|
||||
],
|
||||
"provider": "github",
|
||||
"scheme": "oauth2",
|
||||
"links": {
|
||||
"self": "/chronograf/v1/users/2"
|
||||
},
|
||||
"organizations": [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Sweet",
|
||||
"defaultRole": "viewer",
|
||||
"public": false
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "What",
|
||||
"defaultRole": "editor",
|
||||
"public": false
|
||||
},
|
||||
{
|
||||
"id": "default",
|
||||
"name": "Default",
|
||||
"defaultRole": "member",
|
||||
"public": true
|
||||
}
|
||||
],
|
||||
"currentOrganization": {
|
||||
"id": "default",
|
||||
"name": "Default",
|
||||
"defaultRole": "member",
|
||||
"public": true
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -1702,6 +1619,16 @@ func TestServer(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Populate Organizations
|
||||
for i, mapping := range tt.fields.Mappings {
|
||||
o, err := boltdb.MappingsStore.Add(ctx, &mapping)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to add mapping: %v", err)
|
||||
return
|
||||
}
|
||||
tt.fields.Mappings[i] = *o
|
||||
}
|
||||
|
||||
// Populate Organizations
|
||||
for i, organization := range tt.fields.Organizations {
|
||||
o, err := boltdb.OrganizationsStore.Add(ctx, &organization)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package mocks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
)
|
||||
|
||||
type MappingsStore struct {
|
||||
AddF func(context.Context, *chronograf.Mapping) (*chronograf.Mapping, error)
|
||||
AllF func(context.Context) ([]chronograf.Mapping, error)
|
||||
DeleteF func(context.Context, *chronograf.Mapping) error
|
||||
UpdateF func(context.Context, *chronograf.Mapping) error
|
||||
GetF func(context.Context, string) (*chronograf.Mapping, error)
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Add(ctx context.Context, m *chronograf.Mapping) (*chronograf.Mapping, error) {
|
||||
return s.AddF(ctx, m)
|
||||
}
|
||||
|
||||
func (s *MappingsStore) All(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return s.AllF(ctx)
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Delete(ctx context.Context, m *chronograf.Mapping) error {
|
||||
return s.DeleteF(ctx, m)
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Get(ctx context.Context, id string) (*chronograf.Mapping, error) {
|
||||
return s.GetF(ctx, id)
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Update(ctx context.Context, m *chronograf.Mapping) error {
|
||||
return s.UpdateF(ctx, m)
|
||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||
// Store is a server.DataStore
|
||||
type Store struct {
|
||||
SourcesStore chronograf.SourcesStore
|
||||
MappingsStore chronograf.MappingsStore
|
||||
ServersStore chronograf.ServersStore
|
||||
LayoutsStore chronograf.LayoutsStore
|
||||
UsersStore chronograf.UsersStore
|
||||
|
@ -36,6 +37,9 @@ func (s *Store) Users(ctx context.Context) chronograf.UsersStore {
|
|||
func (s *Store) Organizations(ctx context.Context) chronograf.OrganizationsStore {
|
||||
return s.OrganizationsStore
|
||||
}
|
||||
func (s *Store) Mappings(ctx context.Context) chronograf.MappingsStore {
|
||||
return s.MappingsStore
|
||||
}
|
||||
|
||||
func (s *Store) Dashboards(ctx context.Context) chronograf.DashboardsStore {
|
||||
return s.DashboardsStore
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package noop
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
)
|
||||
|
||||
// ensure MappingsStore implements chronograf.MappingsStore
|
||||
var _ chronograf.MappingsStore = &MappingsStore{}
|
||||
|
||||
type MappingsStore struct{}
|
||||
|
||||
func (s *MappingsStore) All(context.Context) ([]chronograf.Mapping, error) {
|
||||
return nil, fmt.Errorf("no mappings found")
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Add(context.Context, *chronograf.Mapping) (*chronograf.Mapping, error) {
|
||||
return nil, fmt.Errorf("failed to add mapping")
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Delete(context.Context, *chronograf.Mapping) error {
|
||||
return fmt.Errorf("failed to delete mapping")
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Get(ctx context.Context, ID string) (*chronograf.Mapping, error) {
|
||||
return nil, chronograf.ErrMappingNotFound
|
||||
}
|
||||
|
||||
func (s *MappingsStore) Update(context.Context, *chronograf.Mapping) error {
|
||||
return fmt.Errorf("failed to update mapping")
|
||||
}
|
|
@ -1,56 +1,61 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
func MappedRole(o chronograf.Organization, p oauth2.Principal) *chronograf.Role {
|
||||
roles := []*chronograf.Role{}
|
||||
for _, mapping := range o.Mappings {
|
||||
role := applyMapping(mapping, p)
|
||||
if role != nil {
|
||||
role.Organization = o.ID
|
||||
roles = append(roles, role)
|
||||
func (s *Service) mapPrincipalToRoles(ctx context.Context, p oauth2.Principal) ([]chronograf.Role, error) {
|
||||
mappings, err := s.Store.Mappings(ctx).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roles := []chronograf.Role{}
|
||||
MappingsLoop:
|
||||
for _, mapping := range mappings {
|
||||
if applyMapping(mapping, p) {
|
||||
org, err := s.Store.Organizations(ctx).Get(ctx, chronograf.OrganizationQuery{ID: &mapping.Organization})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, role := range roles {
|
||||
if role.Organization == org.ID {
|
||||
continue MappingsLoop
|
||||
}
|
||||
}
|
||||
roles = append(roles, chronograf.Role{Organization: org.ID, Name: org.DefaultRole})
|
||||
}
|
||||
}
|
||||
fmt.Println("Here 2")
|
||||
|
||||
return maxRole(roles)
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func applyMapping(m chronograf.Mapping, p oauth2.Principal) *chronograf.Role {
|
||||
func applyMapping(m chronograf.Mapping, p oauth2.Principal) bool {
|
||||
switch m.Provider {
|
||||
case chronograf.MappingWildcard, p.Issuer:
|
||||
default:
|
||||
return nil
|
||||
return false
|
||||
}
|
||||
|
||||
switch m.Scheme {
|
||||
case chronograf.MappingWildcard, "oauth2":
|
||||
default:
|
||||
return nil
|
||||
return false
|
||||
}
|
||||
|
||||
if m.Group == chronograf.MappingWildcard {
|
||||
return &chronograf.Role{
|
||||
Name: m.GrantedRole,
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
groups := strings.Split(p.Group, ",")
|
||||
|
||||
match := matchGroup(m.Group, groups)
|
||||
|
||||
if match {
|
||||
return &chronograf.Role{
|
||||
Name: m.GrantedRole,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return matchGroup(m.Group, groups)
|
||||
}
|
||||
|
||||
func matchGroup(match string, groups []string) bool {
|
||||
|
@ -63,49 +68,21 @@ func matchGroup(match string, groups []string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func maxRole(roles []*chronograf.Role) *chronograf.Role {
|
||||
var max *chronograf.Role
|
||||
for _, role := range roles {
|
||||
max = maximumRole(max, role)
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
||||
|
||||
func maximumRole(r1, r2 *chronograf.Role) *chronograf.Role {
|
||||
if r1 == nil {
|
||||
return r2
|
||||
}
|
||||
if r2 == nil {
|
||||
return r2
|
||||
}
|
||||
if r1.Name == roles.AdminRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.AdminRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
if r1.Name == roles.EditorRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.EditorRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
if r1.Name == roles.ViewerRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.ViewerRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
if r1.Name == roles.MemberRoleName {
|
||||
return r1
|
||||
}
|
||||
if r2.Name == roles.MemberRoleName {
|
||||
return r2
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
//func (r *organizationRequest) ValidMappings() error {
|
||||
// for _, m := range r.Mappings {
|
||||
// if m.Provider == "" {
|
||||
// return fmt.Errorf("mapping must specify provider")
|
||||
// }
|
||||
// if m.Scheme == "" {
|
||||
// return fmt.Errorf("mapping must specify scheme")
|
||||
// }
|
||||
// if m.Group == "" {
|
||||
// return fmt.Errorf("mapping must specify group")
|
||||
// }
|
||||
// if m.GrantedRole == "" {
|
||||
// return fmt.Errorf("mapping must specify grantedRole")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
|
|
|
@ -1,391 +1,381 @@
|
|||
package server_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
"github.com/influxdata/chronograf/server"
|
||||
)
|
||||
|
||||
func TestMappedRole(t *testing.T) {
|
||||
type args struct {
|
||||
org chronograf.Organization
|
||||
principal oauth2.Principal
|
||||
}
|
||||
type wants struct {
|
||||
role *chronograf.Role
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "single mapping all wildcards",
|
||||
args: args{
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two mapping all wildcards",
|
||||
args: args{
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two mapping all wildcards, different order",
|
||||
args: args{
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two mappings with explicit principal",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: "oauth2",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.MemberRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "different two mapping all wildcards",
|
||||
args: args{
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "different two mapping all wildcards, different ordering",
|
||||
args: args{
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "three mapping all wildcards",
|
||||
args: args{
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "three mapping only one match",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "influxdata.com",
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "not_influxdata",
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: "ldap",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "three mapping only two matches",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "influxdata.com",
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "google",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: "ldap",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing provider",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "google",
|
||||
Group: "influxdata.com",
|
||||
},
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "",
|
||||
Scheme: "ldap",
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user is in multiple github groups",
|
||||
args: args{
|
||||
principal: oauth2.Principal{
|
||||
Subject: "billieta@influxdata.com",
|
||||
Issuer: "github",
|
||||
Group: "influxdata,another,mimi",
|
||||
},
|
||||
org: chronograf.Organization{
|
||||
ID: "cool",
|
||||
Name: "Cool Org",
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "influxdata",
|
||||
GrantedRole: roles.MemberRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "mimi",
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
chronograf.Mapping{
|
||||
Provider: "github",
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: "another",
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
role: &chronograf.Role{
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "cool",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
role := server.MappedRole(tt.args.org, tt.args.principal)
|
||||
|
||||
if diff := cmp.Diff(role, tt.wants.role); diff != "" {
|
||||
t.Errorf("%q. MappedRole():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
//func TestMappedRole(t *testing.T) {
|
||||
// type args struct {
|
||||
// org chronograf.Organization
|
||||
// principal oauth2.Principal
|
||||
// }
|
||||
// type wants struct {
|
||||
// role *chronograf.Role
|
||||
// }
|
||||
//
|
||||
// tests := []struct {
|
||||
// name string
|
||||
// args args
|
||||
// wants wants
|
||||
// }{
|
||||
// {
|
||||
// name: "single mapping all wildcards",
|
||||
// args: args{
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.ViewerRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.ViewerRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "two mapping all wildcards",
|
||||
// args: args{
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.ViewerRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.EditorRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.EditorRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "two mapping all wildcards, different order",
|
||||
// args: args{
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.EditorRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.ViewerRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.EditorRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "two mappings with explicit principal",
|
||||
// args: args{
|
||||
// principal: oauth2.Principal{
|
||||
// Subject: "billieta@influxdata.com",
|
||||
// Issuer: "google",
|
||||
// Group: "influxdata.com",
|
||||
// },
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: "oauth2",
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.MemberRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.MemberRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.MemberRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "different two mapping all wildcards",
|
||||
// args: args{
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.ViewerRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.MemberRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.ViewerRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "different two mapping all wildcards, different ordering",
|
||||
// args: args{
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.MemberRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.ViewerRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.ViewerRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "three mapping all wildcards",
|
||||
// args: args{
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.EditorRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.ViewerRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.AdminRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.AdminRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "three mapping only one match",
|
||||
// args: args{
|
||||
// principal: oauth2.Principal{
|
||||
// Subject: "billieta@influxdata.com",
|
||||
// Issuer: "google",
|
||||
// Group: "influxdata.com",
|
||||
// },
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: "google",
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: "influxdata.com",
|
||||
// GrantedRole: roles.EditorRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: "google",
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: "not_influxdata",
|
||||
// GrantedRole: roles.AdminRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: "ldap",
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.AdminRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.EditorRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "three mapping only two matches",
|
||||
// args: args{
|
||||
// principal: oauth2.Principal{
|
||||
// Subject: "billieta@influxdata.com",
|
||||
// Issuer: "google",
|
||||
// Group: "influxdata.com",
|
||||
// },
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: "google",
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: "influxdata.com",
|
||||
// GrantedRole: roles.AdminRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: "google",
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.EditorRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: chronograf.MappingWildcard,
|
||||
// Scheme: "ldap",
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.AdminRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.AdminRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "missing provider",
|
||||
// args: args{
|
||||
// principal: oauth2.Principal{
|
||||
// Subject: "billieta@influxdata.com",
|
||||
// Issuer: "google",
|
||||
// Group: "influxdata.com",
|
||||
// },
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: "",
|
||||
// Scheme: "ldap",
|
||||
// Group: chronograf.MappingWildcard,
|
||||
// GrantedRole: roles.AdminRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: nil,
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "user is in multiple github groups",
|
||||
// args: args{
|
||||
// principal: oauth2.Principal{
|
||||
// Subject: "billieta@influxdata.com",
|
||||
// Issuer: "github",
|
||||
// Group: "influxdata,another,mimi",
|
||||
// },
|
||||
// org: chronograf.Organization{
|
||||
// ID: "cool",
|
||||
// Name: "Cool Org",
|
||||
// Mappings: []chronograf.Mapping{
|
||||
// chronograf.Mapping{
|
||||
// Provider: "github",
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: "influxdata",
|
||||
// GrantedRole: roles.MemberRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: "github",
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: "mimi",
|
||||
// GrantedRole: roles.EditorRoleName,
|
||||
// },
|
||||
// chronograf.Mapping{
|
||||
// Provider: "github",
|
||||
// Scheme: chronograf.MappingWildcard,
|
||||
// Group: "another",
|
||||
// GrantedRole: roles.AdminRoleName,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// wants: wants{
|
||||
// role: &chronograf.Role{
|
||||
// Name: roles.AdminRoleName,
|
||||
// Organization: "cool",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// for _, tt := range tests {
|
||||
// t.Run(tt.name, func(t *testing.T) {
|
||||
// role := server.MappedRole(tt.args.org, tt.args.principal)
|
||||
//
|
||||
// if diff := cmp.Diff(role, tt.wants.role); diff != "" {
|
||||
// t.Errorf("%q. MappedRole():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//}
|
||||
|
|
10
server/me.go
10
server/me.go
|
@ -270,6 +270,7 @@ func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO(desa) get rid of this
|
||||
// If users must be explicitly added to the default organization, respond with 403
|
||||
// forbidden
|
||||
if !defaultOrg.Public {
|
||||
|
@ -288,18 +289,11 @@ func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
|
|||
SuperAdmin: s.newUsersAreSuperAdmin(),
|
||||
}
|
||||
|
||||
allOrgs, err := s.Store.Organizations(serverCtx).All(serverCtx)
|
||||
roles, err := s.mapPrincipalToRoles(serverCtx, p)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, err.Error(), s.Logger)
|
||||
return
|
||||
}
|
||||
roles := []chronograf.Role{}
|
||||
for _, org := range allOrgs {
|
||||
role := MappedRole(org, p)
|
||||
if role != nil {
|
||||
roles = append(roles, *role)
|
||||
}
|
||||
}
|
||||
|
||||
user.Roles = roles
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ func TestService_Me(t *testing.T) {
|
|||
type fields struct {
|
||||
UsersStore chronograf.UsersStore
|
||||
OrganizationsStore chronograf.OrganizationsStore
|
||||
MappingsStore chronograf.MappingsStore
|
||||
ConfigStore chronograf.ConfigStore
|
||||
Logger chronograf.Logger
|
||||
UseAuth bool
|
||||
|
@ -56,6 +57,18 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{
|
||||
{
|
||||
Organization: "0",
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -63,7 +76,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -74,14 +86,12 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
case "1":
|
||||
return &chronograf.Organization{
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: false,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -124,6 +134,11 @@ func TestService_Me(t *testing.T) {
|
|||
fields: fields{
|
||||
UseAuth: true,
|
||||
Logger: log.New(log.DebugLevel),
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -131,7 +146,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -142,14 +156,12 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
case "1":
|
||||
return &chronograf.Organization{
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -182,7 +194,7 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"me","roles":[{"name":"viewer","organization":"0"}],"provider":"github","scheme":"oauth2","superAdmin":true,"links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"viewer","public":true,"mappings":[]}],"currentOrganization":{"id":"0","name":"Default","defaultRole":"viewer","public":true,"mappings":[]}}`,
|
||||
wantBody: `{"name":"me","roles":[{"name":"viewer","organization":"0"}],"provider":"github","scheme":"oauth2","superAdmin":true,"links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"viewer","public":true}],"currentOrganization":{"id":"0","name":"Default","defaultRole":"viewer","public":true}}`,
|
||||
},
|
||||
{
|
||||
name: "Existing user - private default org",
|
||||
|
@ -193,6 +205,11 @@ func TestService_Me(t *testing.T) {
|
|||
fields: fields{
|
||||
UseAuth: true,
|
||||
Logger: log.New(log.DebugLevel),
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -200,7 +217,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -211,14 +227,12 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
case "1":
|
||||
return &chronograf.Organization{
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -261,6 +275,11 @@ func TestService_Me(t *testing.T) {
|
|||
fields: fields{
|
||||
UseAuth: true,
|
||||
Logger: log.New(log.DebugLevel),
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -268,7 +287,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -279,14 +297,12 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
case "1":
|
||||
return &chronograf.Organization{
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "1",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -318,7 +334,7 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"me","roles":[{"name":"viewer","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"viewer","public":true,"mappings":[]}],"currentOrganization":{"id":"0","name":"Default","defaultRole":"viewer","public":true,"mappings":[]}}`,
|
||||
wantBody: `{"name":"me","roles":[{"name":"viewer","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"viewer","public":true}],"currentOrganization":{"id":"0","name":"Default","defaultRole":"viewer","public":true}}`,
|
||||
},
|
||||
{
|
||||
name: "Existing user - organization doesn't exist",
|
||||
|
@ -329,6 +345,11 @@ func TestService_Me(t *testing.T) {
|
|||
fields: fields{
|
||||
UseAuth: true,
|
||||
Logger: log.New(log.DebugLevel),
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -336,7 +357,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -347,7 +367,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
}
|
||||
return nil, chronograf.ErrOrganizationNotFound
|
||||
|
@ -394,6 +413,18 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{
|
||||
{
|
||||
Organization: "0",
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -401,7 +432,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -410,7 +440,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
AllF: func(ctx context.Context) ([]chronograf.Organization, error) {
|
||||
|
@ -420,14 +449,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
@ -457,7 +478,7 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"secret","roles":[{"name":"viewer","organization":"0"}],"provider":"auth0","scheme":"oauth2","superAdmin":true,"links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}],"currentOrganization":{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}}`,
|
||||
wantBody: `{"name":"secret","roles":[{"name":"viewer","organization":"0"}],"provider":"auth0","scheme":"oauth2","superAdmin":true,"links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true}],"currentOrganization":{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true}}`,
|
||||
},
|
||||
{
|
||||
name: "New user - New users not super admin, not first user",
|
||||
|
@ -475,6 +496,18 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{
|
||||
{
|
||||
Organization: "0",
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -482,7 +515,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -491,7 +523,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
AllF: func(ctx context.Context) ([]chronograf.Organization, error) {
|
||||
|
@ -501,14 +532,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
@ -538,7 +561,7 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"secret","roles":[{"name":"viewer","organization":"0"}],"provider":"auth0","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}],"currentOrganization":{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}}`,
|
||||
wantBody: `{"name":"secret","roles":[{"name":"viewer","organization":"0"}],"provider":"auth0","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true}],"currentOrganization":{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true}}`,
|
||||
},
|
||||
{
|
||||
name: "New user - New users not super admin, first user",
|
||||
|
@ -556,6 +579,18 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{
|
||||
{
|
||||
Organization: "0",
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -563,7 +598,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -572,7 +606,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
AllF: func(ctx context.Context) ([]chronograf.Organization, error) {
|
||||
|
@ -582,14 +615,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
@ -619,7 +644,7 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"secret","roles":[{"name":"viewer","organization":"0"}],"provider":"auth0","scheme":"oauth2","superAdmin":true,"links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}],"currentOrganization":{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}}`,
|
||||
wantBody: `{"name":"secret","roles":[{"name":"viewer","organization":"0"}],"provider":"auth0","scheme":"oauth2","superAdmin":true,"links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true}],"currentOrganization":{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true}}`,
|
||||
},
|
||||
{
|
||||
name: "Error adding user",
|
||||
|
@ -636,21 +661,24 @@ func TestService_Me(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "0",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "0",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "0",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "0",
|
||||
Name: "The Bad Place",
|
||||
Public: true,
|
||||
}, nil
|
||||
},
|
||||
AllF: func(ctx context.Context) ([]chronograf.Organization, error) {
|
||||
|
@ -660,14 +688,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Bad Place",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
@ -751,6 +771,11 @@ func TestService_Me(t *testing.T) {
|
|||
fields: fields{
|
||||
UseAuth: true,
|
||||
Logger: log.New(log.DebugLevel),
|
||||
MappingsStore: &mocks.MappingsStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
|
||||
return []chronograf.Mapping{}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
|
@ -758,7 +783,6 @@ func TestService_Me(t *testing.T) {
|
|||
Name: "The Bad Place",
|
||||
DefaultRole: roles.MemberRoleName,
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
|
@ -789,101 +813,6 @@ func TestService_Me(t *testing.T) {
|
|||
wantContentType: "application/json",
|
||||
wantBody: `{"code":403,"message":"This organization is private. To gain access, you must be explicitly added by an administrator."}`,
|
||||
},
|
||||
{
|
||||
name: "New user multiple mappings",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest("GET", "http://example.com/foo", nil),
|
||||
},
|
||||
fields: fields{
|
||||
UseAuth: true,
|
||||
Logger: log.New(log.DebugLevel),
|
||||
ConfigStore: &mocks.ConfigStore{
|
||||
Config: &chronograf.Config{
|
||||
Auth: chronograf.AuthConfig{
|
||||
SuperAdminNewUsers: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "0",
|
||||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "0",
|
||||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
AllF: func(ctx context.Context) ([]chronograf.Organization, error) {
|
||||
return []chronograf.Organization{
|
||||
chronograf.Organization{
|
||||
ID: "0",
|
||||
Name: "The Gnarly Default",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
chronograf.Organization{
|
||||
ID: "1",
|
||||
Name: "another org",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{
|
||||
chronograf.Mapping{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.EditorRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
UsersStore: &mocks.UsersStore{
|
||||
NumF: func(ctx context.Context) (int, error) {
|
||||
// This function gets to verify that there is at least one first user
|
||||
return 1, nil
|
||||
},
|
||||
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 nil, chronograf.ErrUserNotFound
|
||||
},
|
||||
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{
|
||||
Subject: "secret",
|
||||
Issuer: "auth0",
|
||||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"secret","roles":[{"name":"viewer","organization":"0"},{"name":"editor","organization":"1"}],"provider":"auth0","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]},{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}],"currentOrganization":{"id":"0","name":"The Gnarly Default","defaultRole":"viewer","public":true,"mappings":[]}}`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt.args.r = tt.args.r.WithContext(context.WithValue(context.Background(), oauth2.PrincipalKey, tt.principal))
|
||||
|
@ -891,6 +820,7 @@ func TestService_Me(t *testing.T) {
|
|||
Store: &mocks.Store{
|
||||
UsersStore: tt.fields.UsersStore,
|
||||
OrganizationsStore: tt.fields.OrganizationsStore,
|
||||
MappingsStore: tt.fields.MappingsStore,
|
||||
ConfigStore: tt.fields.ConfigStore,
|
||||
},
|
||||
Logger: tt.fields.Logger,
|
||||
|
@ -981,7 +911,6 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.AdminRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -995,14 +924,12 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.AdminRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
case "1337":
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The ShillBillThrilliettas",
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "1337",
|
||||
Name: "The ShillBillThrilliettas",
|
||||
Public: true,
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -1015,7 +942,7 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"1337"},{"name":"admin","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"admin","public":true,"mappings":[]},{"id":"1337","name":"The ShillBillThrilliettas","public":true,"mappings":[]}],"currentOrganization":{"id":"1337","name":"The ShillBillThrilliettas","public":true,"mappings":[]}}`,
|
||||
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"1337"},{"name":"admin","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"admin","public":true},{"id":"1337","name":"The ShillBillThrilliettas","public":true}],"currentOrganization":{"id":"1337","name":"The ShillBillThrilliettas","public":true}}`,
|
||||
},
|
||||
{
|
||||
name: "Change the current User's organization",
|
||||
|
@ -1058,7 +985,6 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.EditorRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -1068,10 +994,9 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
switch *q.ID {
|
||||
case "1337":
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The ThrillShilliettos",
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "1337",
|
||||
Name: "The ThrillShilliettos",
|
||||
Public: false,
|
||||
}, nil
|
||||
case "0":
|
||||
return &chronograf.Organization{
|
||||
|
@ -1079,7 +1004,6 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
Name: "Default",
|
||||
DefaultRole: roles.EditorRoleName,
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -1093,7 +1017,7 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"1337"},{"name":"editor","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"editor","public":true,"mappings":[]},{"id":"1337","name":"The ThrillShilliettos","public":false,"mappings":[]}],"currentOrganization":{"id":"1337","name":"The ThrillShilliettos","public":false,"mappings":[]}}`,
|
||||
wantBody: `{"name":"me","roles":[{"name":"admin","organization":"1337"},{"name":"editor","organization":"0"}],"provider":"github","scheme":"oauth2","links":{"self":"/chronograf/v1/users/0"},"organizations":[{"id":"0","name":"Default","defaultRole":"editor","public":true},{"id":"1337","name":"The ThrillShilliettos","public":false}],"currentOrganization":{"id":"1337","name":"The ThrillShilliettos","public":false}}`,
|
||||
},
|
||||
{
|
||||
name: "Unable to find requested user in valid organization",
|
||||
|
@ -1132,8 +1056,7 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "0",
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "0",
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
@ -1141,10 +1064,9 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
return nil, fmt.Errorf("Invalid organization query: missing ID")
|
||||
}
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The ShillBillThrilliettas",
|
||||
Public: true,
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "1337",
|
||||
Name: "The ShillBillThrilliettas",
|
||||
Public: true,
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
|
@ -1195,8 +1117,7 @@ func TestService_UpdateMe(t *testing.T) {
|
|||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "0",
|
||||
Mappings: []chronograf.Mapping{},
|
||||
ID: "0",
|
||||
}, nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
|
|
|
@ -118,6 +118,13 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
|
|||
router.PATCH("/chronograf/v1/organizations/:id", EnsureSuperAdmin(service.UpdateOrganization))
|
||||
router.DELETE("/chronograf/v1/organizations/:id", EnsureSuperAdmin(service.RemoveOrganization))
|
||||
|
||||
// Mappings
|
||||
//router.GET("/chronograf/v1/mappings", EnsureSuperAdmin(service.Mappings))
|
||||
//router.POST("/chronograf/v1/mappings", EnsureSuperAdmin(service.NewMapping))
|
||||
|
||||
//router.PUT("/chronograf/v1/mappings/:id", EnsureSuperAdmin(service.UpdateMappings))
|
||||
//router.DELETE("/chronograf/v1/mappings/:id", EnsureSuperAdmin(service.RemoveMappings))
|
||||
|
||||
// Sources
|
||||
router.GET("/chronograf/v1/sources", EnsureViewer(service.Sources))
|
||||
router.POST("/chronograf/v1/sources", EnsureEditor(service.NewSource))
|
||||
|
|
|
@ -13,10 +13,9 @@ import (
|
|||
)
|
||||
|
||||
type organizationRequest struct {
|
||||
Name string `json:"name"`
|
||||
DefaultRole string `json:"defaultRole"`
|
||||
Public *bool `json:"public"`
|
||||
Mappings []chronograf.Mapping `json:"mappings"`
|
||||
Name string `json:"name"`
|
||||
DefaultRole string `json:"defaultRole"`
|
||||
Public *bool `json:"public"`
|
||||
}
|
||||
|
||||
func (r *organizationRequest) ValidCreate() error {
|
||||
|
@ -24,36 +23,11 @@ func (r *organizationRequest) ValidCreate() error {
|
|||
return fmt.Errorf("Name required on Chronograf Organization request body")
|
||||
}
|
||||
|
||||
if len(r.Mappings) > 0 {
|
||||
if err := r.ValidMappings(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return r.ValidDefaultRole()
|
||||
}
|
||||
|
||||
func (r *organizationRequest) ValidMappings() error {
|
||||
for _, m := range r.Mappings {
|
||||
if m.Provider == "" {
|
||||
return fmt.Errorf("mapping must specify provider")
|
||||
}
|
||||
if m.Scheme == "" {
|
||||
return fmt.Errorf("mapping must specify scheme")
|
||||
}
|
||||
if m.Group == "" {
|
||||
return fmt.Errorf("mapping must specify group")
|
||||
}
|
||||
if m.GrantedRole == "" {
|
||||
return fmt.Errorf("mapping must specify grantedRole")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *organizationRequest) ValidUpdate() error {
|
||||
if r.Name == "" && r.DefaultRole == "" && r.Public == nil && len(r.Mappings) == 0 {
|
||||
if r.Name == "" && r.DefaultRole == "" && r.Public == nil {
|
||||
return fmt.Errorf("No fields to update")
|
||||
}
|
||||
|
||||
|
@ -61,12 +35,6 @@ func (r *organizationRequest) ValidUpdate() error {
|
|||
return r.ValidDefaultRole()
|
||||
}
|
||||
|
||||
if len(r.Mappings) > 0 {
|
||||
if err := r.ValidMappings(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -92,12 +60,6 @@ func newOrganizationResponse(o *chronograf.Organization) *organizationResponse {
|
|||
if o == nil {
|
||||
o = &chronograf.Organization{}
|
||||
}
|
||||
// This ensures that any user response with no roles returns an empty array instead of
|
||||
// null when marshaled into JSON. That way, JavaScript doesn't need any guard on the
|
||||
// key existing and it can simply be iterated over.
|
||||
if o.Mappings == nil {
|
||||
o.Mappings = []chronograf.Mapping{}
|
||||
}
|
||||
return &organizationResponse{
|
||||
Organization: *o,
|
||||
Links: selfLinks{
|
||||
|
@ -249,10 +211,6 @@ func (s *Service) UpdateOrganization(w http.ResponseWriter, r *http.Request) {
|
|||
org.Public = *req.Public
|
||||
}
|
||||
|
||||
if req.Mappings != nil {
|
||||
org.Mappings = req.Mappings
|
||||
}
|
||||
|
||||
err = s.Store.Organizations(ctx).Update(ctx, org)
|
||||
if err != nil {
|
||||
Error(w, http.StatusBadRequest, err.Error(), s.Logger)
|
||||
|
|
|
@ -65,10 +65,10 @@ func TestService_OrganizationID(t *testing.T) {
|
|||
id: "1337",
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"links":{"self":"/chronograf/v1/organizations/1337"},"id":"1337","name":"The Good Place","public":false,"mappings":[]}`,
|
||||
wantBody: `{"links":{"self":"/chronograf/v1/organizations/1337"},"id":"1337","name":"The Good Place","public":false}`,
|
||||
},
|
||||
{
|
||||
name: "Get Single Organization - with mappings",
|
||||
name: "Get Single Organization",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest(
|
||||
|
@ -86,14 +86,6 @@ func TestService_OrganizationID(t *testing.T) {
|
|||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The Good Place",
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Organization with ID %s not found", *q.ID)
|
||||
|
@ -104,7 +96,7 @@ func TestService_OrganizationID(t *testing.T) {
|
|||
id: "1337",
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"id":"1337","name":"The Good Place","public":false,"mappings":[{"provider":"*","scheme":"*","group":"*","grantedRole":"viewer"}],"links":{"self":"/chronograf/v1/organizations/1337"}}`,
|
||||
wantBody: `{"id":"1337","name":"The Good Place","public":false,"links":{"self":"/chronograf/v1/organizations/1337"}}`,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -186,14 +178,6 @@ func TestService_Organizations(t *testing.T) {
|
|||
ID: "100",
|
||||
Name: "The Bad Place",
|
||||
Public: false,
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
@ -201,7 +185,7 @@ func TestService_Organizations(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"links":{"self":"/chronograf/v1/organizations"},"organizations":[{"links":{"self":"/chronograf/v1/organizations/1337"},"mappings":[],"id":"1337","name":"The Good Place","public":false},{"links":{"self":"/chronograf/v1/organizations/100"},"id":"100","name":"The Bad Place","public":false,"mappings":[{"provider":"*","scheme":"*","group":"*","grantedRole":"viewer"}]}]}`,
|
||||
wantBody: `{"links":{"self":"/chronograf/v1/organizations"},"organizations":[{"links":{"self":"/chronograf/v1/organizations/1337"},"id":"1337","name":"The Good Place","public":false},{"links":{"self":"/chronograf/v1/organizations/100"},"id":"100","name":"The Bad Place","public":false}]}`,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -286,243 +270,7 @@ func TestService_UpdateOrganization(t *testing.T) {
|
|||
id: "1337",
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"id":"1337","mappings":[],"name":"The Bad Place","defaultRole":"viewer","links":{"self":"/chronograf/v1/organizations/1337"},"public":false}`,
|
||||
},
|
||||
{
|
||||
name: "Update Organization mappings",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest(
|
||||
"GET",
|
||||
"http://any.url", // can be any valid URL as we are bypassing mux
|
||||
nil,
|
||||
),
|
||||
org: &organizationRequest{
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fields: fields{
|
||||
Logger: log.New(log.DebugLevel),
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
|
||||
return nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The Good Place",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
id: "1337",
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"id":"1337","public":false,"mappings":[{"provider":"*","scheme":"*","group":"*","grantedRole":"admin"}],"name":"The Good Place","defaultRole":"viewer","links":{"self":"/chronograf/v1/organizations/1337"}}`,
|
||||
},
|
||||
{
|
||||
name: "Fail to update Organization mappings - no provider",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest(
|
||||
"GET",
|
||||
"http://any.url", // can be any valid URL as we are bypassing mux
|
||||
nil,
|
||||
),
|
||||
org: &organizationRequest{
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fields: fields{
|
||||
Logger: log.New(log.DebugLevel),
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
|
||||
return nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The Good Place",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
id: "1337",
|
||||
wantStatus: http.StatusUnprocessableEntity,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"code":422,"message":"mapping must specify provider"}`,
|
||||
},
|
||||
{
|
||||
name: "Fail to update Organization mappings - no scheme",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest(
|
||||
"GET",
|
||||
"http://any.url", // can be any valid URL as we are bypassing mux
|
||||
nil,
|
||||
),
|
||||
org: &organizationRequest{
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fields: fields{
|
||||
Logger: log.New(log.DebugLevel),
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
|
||||
return nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The Good Place",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
id: "1337",
|
||||
wantStatus: http.StatusUnprocessableEntity,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"code":422,"message":"mapping must specify scheme"}`,
|
||||
},
|
||||
{
|
||||
name: "Fail to update Organization mappings - no group",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest(
|
||||
"GET",
|
||||
"http://any.url", // can be any valid URL as we are bypassing mux
|
||||
nil,
|
||||
),
|
||||
org: &organizationRequest{
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.AdminRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fields: fields{
|
||||
Logger: log.New(log.DebugLevel),
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
|
||||
return nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The Good Place",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
id: "1337",
|
||||
wantStatus: http.StatusUnprocessableEntity,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"code":422,"message":"mapping must specify group"}`,
|
||||
},
|
||||
{
|
||||
name: "Fail to update Organization mappings - no granted role",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest(
|
||||
"GET",
|
||||
"http://any.url", // can be any valid URL as we are bypassing mux
|
||||
nil,
|
||||
),
|
||||
org: &organizationRequest{
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fields: fields{
|
||||
Logger: log.New(log.DebugLevel),
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
|
||||
return nil
|
||||
},
|
||||
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
|
||||
return &chronograf.Organization{
|
||||
ID: "1337",
|
||||
Name: "The Good Place",
|
||||
DefaultRole: roles.ViewerRoleName,
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
id: "1337",
|
||||
wantStatus: http.StatusUnprocessableEntity,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"code":422,"message":"mapping must specify grantedRole"}`,
|
||||
wantBody: `{"id":"1337","name":"The Bad Place","defaultRole":"viewer","links":{"self":"/chronograf/v1/organizations/1337"},"public":false}`,
|
||||
},
|
||||
{
|
||||
name: "Update Organization public",
|
||||
|
@ -556,7 +304,7 @@ func TestService_UpdateOrganization(t *testing.T) {
|
|||
id: "0",
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"id":"0","mappings":[],"name":"The Good Place","defaultRole":"viewer","public":false,"links":{"self":"/chronograf/v1/organizations/0"}}`,
|
||||
wantBody: `{"id":"0","name":"The Good Place","defaultRole":"viewer","public":false,"links":{"self":"/chronograf/v1/organizations/0"}}`,
|
||||
},
|
||||
{
|
||||
name: "Update Organization - nothing to update",
|
||||
|
@ -622,7 +370,7 @@ func TestService_UpdateOrganization(t *testing.T) {
|
|||
id: "1337",
|
||||
wantStatus: http.StatusOK,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"links":{"self":"/chronograf/v1/organizations/1337"},"mappings":[],"id":"1337","name":"The Good Place","defaultRole":"viewer","public":false}`,
|
||||
wantBody: `{"links":{"self":"/chronograf/v1/organizations/1337"},"id":"1337","name":"The Good Place","defaultRole":"viewer","public":false}`,
|
||||
},
|
||||
{
|
||||
name: "Update Organization - invalid update",
|
||||
|
@ -865,7 +613,7 @@ func TestService_NewOrganization(t *testing.T) {
|
|||
},
|
||||
wantStatus: http.StatusCreated,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"id":"1337","mappings":[],"public":false,"name":"The Good Place","links":{"self":"/chronograf/v1/organizations/1337"}}`,
|
||||
wantBody: `{"id":"1337","public":false,"name":"The Good Place","links":{"self":"/chronograf/v1/organizations/1337"}}`,
|
||||
},
|
||||
{
|
||||
name: "Fail to create Organization - no org name",
|
||||
|
@ -906,54 +654,6 @@ func TestService_NewOrganization(t *testing.T) {
|
|||
wantContentType: "application/json",
|
||||
wantBody: `{"code":422,"message":"Name required on Chronograf Organization request body"}`,
|
||||
},
|
||||
{
|
||||
name: "Fail to create Organization - mappings missing provider",
|
||||
args: args{
|
||||
w: httptest.NewRecorder(),
|
||||
r: httptest.NewRequest(
|
||||
"GET",
|
||||
"http://any.url", // can be any valid URL as we are bypassing mux
|
||||
nil,
|
||||
),
|
||||
user: &chronograf.User{
|
||||
ID: 1,
|
||||
Name: "bobetta",
|
||||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
},
|
||||
org: &organizationRequest{
|
||||
Name: "The Good Place",
|
||||
Mappings: []chronograf.Mapping{
|
||||
{
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
Group: chronograf.MappingWildcard,
|
||||
GrantedRole: roles.ViewerRoleName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
fields: fields{
|
||||
Logger: log.New(log.DebugLevel),
|
||||
UsersStore: &mocks.UsersStore{
|
||||
AddF: func(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
|
||||
return &chronograf.User{
|
||||
ID: 1,
|
||||
Name: "bobetta",
|
||||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
OrganizationsStore: &mocks.OrganizationsStore{
|
||||
AddF: func(ctx context.Context, o *chronograf.Organization) (*chronograf.Organization, error) {
|
||||
return nil, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
wantStatus: http.StatusUnprocessableEntity,
|
||||
wantContentType: "application/json",
|
||||
wantBody: `{"code":422,"message":"mapping must specify provider"}`,
|
||||
},
|
||||
{
|
||||
name: "Create Organization - no user on context",
|
||||
args: args{
|
||||
|
|
|
@ -484,6 +484,7 @@ func openService(ctx context.Context, buildInfo chronograf.BuildInfo, boltPath s
|
|||
OrganizationsStore: organizations,
|
||||
UsersStore: db.UsersStore,
|
||||
ConfigStore: db.ConfigStore,
|
||||
MappingsStore: db.MappingsStore,
|
||||
},
|
||||
Logger: logger,
|
||||
UseAuth: useAuth,
|
||||
|
|
|
@ -88,6 +88,7 @@ type DataStore interface {
|
|||
Layouts(ctx context.Context) chronograf.LayoutsStore
|
||||
Users(ctx context.Context) chronograf.UsersStore
|
||||
Organizations(ctx context.Context) chronograf.OrganizationsStore
|
||||
Mappings(ctx context.Context) chronograf.MappingsStore
|
||||
Dashboards(ctx context.Context) chronograf.DashboardsStore
|
||||
Config(ctx context.Context) chronograf.ConfigStore
|
||||
}
|
||||
|
@ -102,6 +103,7 @@ type Store struct {
|
|||
LayoutsStore chronograf.LayoutsStore
|
||||
UsersStore chronograf.UsersStore
|
||||
DashboardsStore chronograf.DashboardsStore
|
||||
MappingsStore chronograf.MappingsStore
|
||||
OrganizationsStore chronograf.OrganizationsStore
|
||||
ConfigStore chronograf.ConfigStore
|
||||
}
|
||||
|
@ -191,3 +193,14 @@ func (s *Store) Config(ctx context.Context) chronograf.ConfigStore {
|
|||
}
|
||||
return &noop.ConfigStore{}
|
||||
}
|
||||
|
||||
// Mappings returns the underlying MappingsStore.
|
||||
func (s *Store) Mappings(ctx context.Context) chronograf.MappingsStore {
|
||||
if isServer := hasServerContext(ctx); isServer {
|
||||
return s.MappingsStore
|
||||
}
|
||||
if isSuperAdmin := hasSuperAdminContext(ctx); isSuperAdmin {
|
||||
return s.MappingsStore
|
||||
}
|
||||
return &noop.MappingsStore{}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue