Merge pull request #2249 from influxdata/multitenancy_scoped_sources
Sources are scoped by users role in organizationmultitenancy_admin_no_delete_superadmin
commit
355649b885
|
@ -24,6 +24,7 @@ func MarshalSource(s chronograf.Source) ([]byte, error) {
|
|||
Default: s.Default,
|
||||
Telegraf: s.Telegraf,
|
||||
Organization: s.Organization,
|
||||
Role: s.Role,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -46,6 +47,7 @@ func UnmarshalSource(data []byte, s *chronograf.Source) error {
|
|||
s.Default = pb.Default
|
||||
s.Telegraf = pb.Telegraf
|
||||
s.Organization = pb.Organization
|
||||
s.Role = pb.Role
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ type Source struct {
|
|||
MetaURL string `protobuf:"bytes,10,opt,name=MetaURL,proto3" json:"MetaURL,omitempty"`
|
||||
SharedSecret string `protobuf:"bytes,11,opt,name=SharedSecret,proto3" json:"SharedSecret,omitempty"`
|
||||
Organization string `protobuf:"bytes,12,opt,name=Organization,proto3" json:"Organization,omitempty"`
|
||||
Role string `protobuf:"bytes,13,opt,name=Role,proto3" json:"Role,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Source) Reset() { *m = Source{} }
|
||||
|
@ -63,6 +64,97 @@ func (m *Source) String() string { return proto.CompactTextString(m)
|
|||
func (*Source) ProtoMessage() {}
|
||||
func (*Source) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{0} }
|
||||
|
||||
func (m *Source) GetID() int64 {
|
||||
if m != nil {
|
||||
return m.ID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Source) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetType() string {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetUsername() string {
|
||||
if m != nil {
|
||||
return m.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetPassword() string {
|
||||
if m != nil {
|
||||
return m.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetURL() string {
|
||||
if m != nil {
|
||||
return m.URL
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetDefault() bool {
|
||||
if m != nil {
|
||||
return m.Default
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Source) GetTelegraf() string {
|
||||
if m != nil {
|
||||
return m.Telegraf
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetInsecureSkipVerify() bool {
|
||||
if m != nil {
|
||||
return m.InsecureSkipVerify
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Source) GetMetaURL() string {
|
||||
if m != nil {
|
||||
return m.MetaURL
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetSharedSecret() string {
|
||||
if m != nil {
|
||||
return m.SharedSecret
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetOrganization() string {
|
||||
if m != nil {
|
||||
return m.Organization
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Source) GetRole() string {
|
||||
if m != nil {
|
||||
return m.Role
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Dashboard struct {
|
||||
ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
|
@ -76,6 +168,20 @@ func (m *Dashboard) String() string { return proto.CompactTextString(
|
|||
func (*Dashboard) ProtoMessage() {}
|
||||
func (*Dashboard) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{1} }
|
||||
|
||||
func (m *Dashboard) GetID() int64 {
|
||||
if m != nil {
|
||||
return m.ID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Dashboard) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Dashboard) GetCells() []*DashboardCell {
|
||||
if m != nil {
|
||||
return m.Cells
|
||||
|
@ -90,6 +196,13 @@ func (m *Dashboard) GetTemplates() []*Template {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Dashboard) GetOrganization() string {
|
||||
if m != nil {
|
||||
return m.Organization
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DashboardCell struct {
|
||||
X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"`
|
||||
Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"`
|
||||
|
@ -107,6 +220,34 @@ func (m *DashboardCell) String() string { return proto.CompactTextStr
|
|||
func (*DashboardCell) ProtoMessage() {}
|
||||
func (*DashboardCell) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{2} }
|
||||
|
||||
func (m *DashboardCell) GetX() int32 {
|
||||
if m != nil {
|
||||
return m.X
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetY() int32 {
|
||||
if m != nil {
|
||||
return m.Y
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetW() int32 {
|
||||
if m != nil {
|
||||
return m.W
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetH() int32 {
|
||||
if m != nil {
|
||||
return m.H
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetQueries() []*Query {
|
||||
if m != nil {
|
||||
return m.Queries
|
||||
|
@ -114,6 +255,27 @@ func (m *DashboardCell) GetQueries() []*Query {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetType() string {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetID() string {
|
||||
if m != nil {
|
||||
return m.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DashboardCell) GetAxes() map[string]*Axis {
|
||||
if m != nil {
|
||||
return m.Axes
|
||||
|
@ -122,7 +284,7 @@ func (m *DashboardCell) GetAxes() map[string]*Axis {
|
|||
}
|
||||
|
||||
type Axis struct {
|
||||
LegacyBounds []int64 `protobuf:"varint,1,rep,name=legacyBounds" json:"legacyBounds,omitempty"`
|
||||
LegacyBounds []int64 `protobuf:"varint,1,rep,packed,name=legacyBounds" json:"legacyBounds,omitempty"`
|
||||
Bounds []string `protobuf:"bytes,2,rep,name=bounds" json:"bounds,omitempty"`
|
||||
Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"`
|
||||
Prefix string `protobuf:"bytes,4,opt,name=prefix,proto3" json:"prefix,omitempty"`
|
||||
|
@ -136,6 +298,55 @@ func (m *Axis) String() string { return proto.CompactTextString(m) }
|
|||
func (*Axis) ProtoMessage() {}
|
||||
func (*Axis) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{3} }
|
||||
|
||||
func (m *Axis) GetLegacyBounds() []int64 {
|
||||
if m != nil {
|
||||
return m.LegacyBounds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Axis) GetBounds() []string {
|
||||
if m != nil {
|
||||
return m.Bounds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Axis) GetLabel() string {
|
||||
if m != nil {
|
||||
return m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Axis) GetPrefix() string {
|
||||
if m != nil {
|
||||
return m.Prefix
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Axis) GetSuffix() string {
|
||||
if m != nil {
|
||||
return m.Suffix
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Axis) GetBase() string {
|
||||
if m != nil {
|
||||
return m.Base
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Axis) GetScale() string {
|
||||
if m != nil {
|
||||
return m.Scale
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
TempVar string `protobuf:"bytes,2,opt,name=temp_var,json=tempVar,proto3" json:"temp_var,omitempty"`
|
||||
|
@ -150,6 +361,20 @@ func (m *Template) String() string { return proto.CompactTextString(m
|
|||
func (*Template) ProtoMessage() {}
|
||||
func (*Template) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{4} }
|
||||
|
||||
func (m *Template) GetID() string {
|
||||
if m != nil {
|
||||
return m.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Template) GetTempVar() string {
|
||||
if m != nil {
|
||||
return m.TempVar
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Template) GetValues() []*TemplateValue {
|
||||
if m != nil {
|
||||
return m.Values
|
||||
|
@ -157,6 +382,20 @@ func (m *Template) GetValues() []*TemplateValue {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Template) GetType() string {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Template) GetLabel() string {
|
||||
if m != nil {
|
||||
return m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Template) GetQuery() *TemplateQuery {
|
||||
if m != nil {
|
||||
return m.Query
|
||||
|
@ -175,6 +414,27 @@ func (m *TemplateValue) String() string { return proto.CompactTextStr
|
|||
func (*TemplateValue) ProtoMessage() {}
|
||||
func (*TemplateValue) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{5} }
|
||||
|
||||
func (m *TemplateValue) GetType() string {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TemplateValue) GetValue() string {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TemplateValue) GetSelected() bool {
|
||||
if m != nil {
|
||||
return m.Selected
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type TemplateQuery struct {
|
||||
Command string `protobuf:"bytes,1,opt,name=command,proto3" json:"command,omitempty"`
|
||||
Db string `protobuf:"bytes,2,opt,name=db,proto3" json:"db,omitempty"`
|
||||
|
@ -189,6 +449,48 @@ func (m *TemplateQuery) String() string { return proto.CompactTextStr
|
|||
func (*TemplateQuery) ProtoMessage() {}
|
||||
func (*TemplateQuery) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{6} }
|
||||
|
||||
func (m *TemplateQuery) GetCommand() string {
|
||||
if m != nil {
|
||||
return m.Command
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TemplateQuery) GetDb() string {
|
||||
if m != nil {
|
||||
return m.Db
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TemplateQuery) GetRp() string {
|
||||
if m != nil {
|
||||
return m.Rp
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TemplateQuery) GetMeasurement() string {
|
||||
if m != nil {
|
||||
return m.Measurement
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TemplateQuery) GetTagKey() string {
|
||||
if m != nil {
|
||||
return m.TagKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TemplateQuery) GetFieldKey() string {
|
||||
if m != nil {
|
||||
return m.FieldKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
|
@ -205,13 +507,69 @@ func (m *Server) String() string { return proto.CompactTextString(m)
|
|||
func (*Server) ProtoMessage() {}
|
||||
func (*Server) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{7} }
|
||||
|
||||
func (m *Server) GetID() int64 {
|
||||
if m != nil {
|
||||
return m.ID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Server) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Server) GetUsername() string {
|
||||
if m != nil {
|
||||
return m.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Server) GetPassword() string {
|
||||
if m != nil {
|
||||
return m.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Server) GetURL() string {
|
||||
if m != nil {
|
||||
return m.URL
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Server) GetSrcID() int64 {
|
||||
if m != nil {
|
||||
return m.SrcID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Server) GetActive() bool {
|
||||
if m != nil {
|
||||
return m.Active
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Server) GetOrganization() string {
|
||||
if m != nil {
|
||||
return m.Organization
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Layout struct {
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Application string `protobuf:"bytes,2,opt,name=Application,proto3" json:"Application,omitempty"`
|
||||
Measurement string `protobuf:"bytes,3,opt,name=Measurement,proto3" json:"Measurement,omitempty"`
|
||||
Cells []*Cell `protobuf:"bytes,4,rep,name=Cells" json:"Cells,omitempty"`
|
||||
Autoflow bool `protobuf:"varint,5,opt,name=Autoflow,proto3" json:"Autoflow,omitempty"`
|
||||
Organization string `protobuf:"bytes,7,opt,name=Organization,proto3" json:"Organization,omitempty"`
|
||||
Organization string `protobuf:"bytes,6,opt,name=Organization,proto3" json:"Organization,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Layout) Reset() { *m = Layout{} }
|
||||
|
@ -219,6 +577,27 @@ func (m *Layout) String() string { return proto.CompactTextString(m)
|
|||
func (*Layout) ProtoMessage() {}
|
||||
func (*Layout) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{8} }
|
||||
|
||||
func (m *Layout) GetID() string {
|
||||
if m != nil {
|
||||
return m.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Layout) GetApplication() string {
|
||||
if m != nil {
|
||||
return m.Application
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Layout) GetMeasurement() string {
|
||||
if m != nil {
|
||||
return m.Measurement
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Layout) GetCells() []*Cell {
|
||||
if m != nil {
|
||||
return m.Cells
|
||||
|
@ -226,6 +605,20 @@ func (m *Layout) GetCells() []*Cell {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Layout) GetAutoflow() bool {
|
||||
if m != nil {
|
||||
return m.Autoflow
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Layout) GetOrganization() string {
|
||||
if m != nil {
|
||||
return m.Organization
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Cell struct {
|
||||
X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"`
|
||||
Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"`
|
||||
|
@ -234,7 +627,7 @@ type Cell struct {
|
|||
Queries []*Query `protobuf:"bytes,5,rep,name=queries" json:"queries,omitempty"`
|
||||
I string `protobuf:"bytes,6,opt,name=i,proto3" json:"i,omitempty"`
|
||||
Name string `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Yranges []int64 `protobuf:"varint,8,rep,name=yranges" json:"yranges,omitempty"`
|
||||
Yranges []int64 `protobuf:"varint,8,rep,packed,name=yranges" json:"yranges,omitempty"`
|
||||
Ylabels []string `protobuf:"bytes,9,rep,name=ylabels" json:"ylabels,omitempty"`
|
||||
Type string `protobuf:"bytes,10,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Axes map[string]*Axis `protobuf:"bytes,11,rep,name=axes" json:"axes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"`
|
||||
|
@ -245,6 +638,34 @@ func (m *Cell) String() string { return proto.CompactTextString(m) }
|
|||
func (*Cell) ProtoMessage() {}
|
||||
func (*Cell) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{9} }
|
||||
|
||||
func (m *Cell) GetX() int32 {
|
||||
if m != nil {
|
||||
return m.X
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Cell) GetY() int32 {
|
||||
if m != nil {
|
||||
return m.Y
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Cell) GetW() int32 {
|
||||
if m != nil {
|
||||
return m.W
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Cell) GetH() int32 {
|
||||
if m != nil {
|
||||
return m.H
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Cell) GetQueries() []*Query {
|
||||
if m != nil {
|
||||
return m.Queries
|
||||
|
@ -252,6 +673,41 @@ func (m *Cell) GetQueries() []*Query {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Cell) GetI() string {
|
||||
if m != nil {
|
||||
return m.I
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Cell) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Cell) GetYranges() []int64 {
|
||||
if m != nil {
|
||||
return m.Yranges
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Cell) GetYlabels() []string {
|
||||
if m != nil {
|
||||
return m.Ylabels
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Cell) GetType() string {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Cell) GetAxes() map[string]*Axis {
|
||||
if m != nil {
|
||||
return m.Axes
|
||||
|
@ -275,6 +731,48 @@ func (m *Query) String() string { return proto.CompactTextString(m) }
|
|||
func (*Query) ProtoMessage() {}
|
||||
func (*Query) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{10} }
|
||||
|
||||
func (m *Query) GetCommand() string {
|
||||
if m != nil {
|
||||
return m.Command
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Query) GetDB() string {
|
||||
if m != nil {
|
||||
return m.DB
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Query) GetRP() string {
|
||||
if m != nil {
|
||||
return m.RP
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Query) GetGroupBys() []string {
|
||||
if m != nil {
|
||||
return m.GroupBys
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Query) GetWheres() []string {
|
||||
if m != nil {
|
||||
return m.Wheres
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Query) GetLabel() string {
|
||||
if m != nil {
|
||||
return m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Query) GetRange() *Range {
|
||||
if m != nil {
|
||||
return m.Range
|
||||
|
@ -282,6 +780,13 @@ func (m *Query) GetRange() *Range {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Query) GetSource() string {
|
||||
if m != nil {
|
||||
return m.Source
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Range struct {
|
||||
Upper int64 `protobuf:"varint,1,opt,name=Upper,proto3" json:"Upper,omitempty"`
|
||||
Lower int64 `protobuf:"varint,2,opt,name=Lower,proto3" json:"Lower,omitempty"`
|
||||
|
@ -292,6 +797,20 @@ func (m *Range) String() string { return proto.CompactTextString(m) }
|
|||
func (*Range) ProtoMessage() {}
|
||||
func (*Range) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{11} }
|
||||
|
||||
func (m *Range) GetUpper() int64 {
|
||||
if m != nil {
|
||||
return m.Upper
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Range) GetLower() int64 {
|
||||
if m != nil {
|
||||
return m.Lower
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type AlertRule struct {
|
||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
JSON string `protobuf:"bytes,2,opt,name=JSON,proto3" json:"JSON,omitempty"`
|
||||
|
@ -304,6 +823,34 @@ func (m *AlertRule) String() string { return proto.CompactTextString(
|
|||
func (*AlertRule) ProtoMessage() {}
|
||||
func (*AlertRule) Descriptor() ([]byte, []int) { return fileDescriptorInternal, []int{12} }
|
||||
|
||||
func (m *AlertRule) GetID() string {
|
||||
if m != nil {
|
||||
return m.ID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *AlertRule) GetJSON() string {
|
||||
if m != nil {
|
||||
return m.JSON
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *AlertRule) GetSrcID() int64 {
|
||||
if m != nil {
|
||||
return m.SrcID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *AlertRule) GetKapaID() int64 {
|
||||
if m != nil {
|
||||
return m.KapaID
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
|
||||
|
@ -438,76 +985,77 @@ func init() {
|
|||
func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) }
|
||||
|
||||
var fileDescriptorInternal = []byte{
|
||||
// 1133 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x8f, 0xdb, 0x44,
|
||||
0x14, 0x96, 0x63, 0x3b, 0x89, 0x5f, 0xb6, 0x0b, 0x1a, 0x55, 0xd4, 0x14, 0x09, 0x05, 0x0b, 0xa4,
|
||||
0x20, 0xd1, 0x05, 0xb5, 0x42, 0x42, 0x1c, 0x90, 0xb2, 0x1b, 0x54, 0x2d, 0xbb, 0x6d, 0x97, 0xc9,
|
||||
0xee, 0x72, 0x42, 0xd5, 0xc4, 0x79, 0x49, 0xac, 0x3a, 0xb1, 0x19, 0xdb, 0xbb, 0x31, 0xff, 0x0d,
|
||||
0x12, 0x27, 0x8e, 0x88, 0x3b, 0x12, 0x27, 0xd4, 0x23, 0x7f, 0x11, 0x7a, 0x33, 0x63, 0xc7, 0x21,
|
||||
0xa1, 0xda, 0x0b, 0xdc, 0xe6, 0x7b, 0x6f, 0xfc, 0xe6, 0xfd, 0xfa, 0x3e, 0x19, 0x0e, 0xa3, 0x55,
|
||||
0x8e, 0x72, 0x25, 0xe2, 0xa3, 0x54, 0x26, 0x79, 0xc2, 0xba, 0x15, 0x0e, 0xfe, 0x6a, 0x41, 0x7b,
|
||||
0x9c, 0x14, 0x32, 0x44, 0x76, 0x08, 0xad, 0xd3, 0x91, 0x6f, 0xf5, 0xad, 0x81, 0xcd, 0x5b, 0xa7,
|
||||
0x23, 0xc6, 0xc0, 0x79, 0x2e, 0x96, 0xe8, 0xb7, 0xfa, 0xd6, 0xc0, 0xe3, 0xea, 0x4c, 0xb6, 0xcb,
|
||||
0x32, 0x45, 0xdf, 0xd6, 0x36, 0x3a, 0xb3, 0x87, 0xd0, 0xbd, 0xca, 0x28, 0xda, 0x12, 0x7d, 0x47,
|
||||
0xd9, 0x6b, 0x4c, 0xbe, 0x0b, 0x91, 0x65, 0xb7, 0x89, 0x9c, 0xfa, 0xae, 0xf6, 0x55, 0x98, 0xbd,
|
||||
0x0d, 0xf6, 0x15, 0x3f, 0xf7, 0xdb, 0xca, 0x4c, 0x47, 0xe6, 0x43, 0x67, 0x84, 0x33, 0x51, 0xc4,
|
||||
0xb9, 0xdf, 0xe9, 0x5b, 0x83, 0x2e, 0xaf, 0x20, 0xc5, 0xb9, 0xc4, 0x18, 0xe7, 0x52, 0xcc, 0xfc,
|
||||
0xae, 0x8e, 0x53, 0x61, 0x76, 0x04, 0xec, 0x74, 0x95, 0x61, 0x58, 0x48, 0x1c, 0xbf, 0x8a, 0xd2,
|
||||
0x6b, 0x94, 0xd1, 0xac, 0xf4, 0x3d, 0x15, 0x60, 0x8f, 0x87, 0x5e, 0x79, 0x86, 0xb9, 0xa0, 0xb7,
|
||||
0x41, 0x85, 0xaa, 0x20, 0x0b, 0xe0, 0x60, 0xbc, 0x10, 0x12, 0xa7, 0x63, 0x0c, 0x25, 0xe6, 0x7e,
|
||||
0x4f, 0xb9, 0xb7, 0x6c, 0x74, 0xe7, 0x85, 0x9c, 0x8b, 0x55, 0xf4, 0xa3, 0xc8, 0xa3, 0x64, 0xe5,
|
||||
0x1f, 0xe8, 0x3b, 0x4d, 0x5b, 0xf0, 0x9b, 0x05, 0xde, 0x48, 0x64, 0x8b, 0x49, 0x22, 0xe4, 0xf4,
|
||||
0x4e, 0x7d, 0x7d, 0x04, 0x6e, 0x88, 0x71, 0x9c, 0xf9, 0x76, 0xdf, 0x1e, 0xf4, 0x1e, 0x3f, 0x38,
|
||||
0xaa, 0x07, 0x56, 0xc7, 0x39, 0xc1, 0x38, 0xe6, 0xfa, 0x16, 0xfb, 0x0c, 0xbc, 0x1c, 0x97, 0x69,
|
||||
0x2c, 0x72, 0xcc, 0x7c, 0x47, 0x7d, 0xc2, 0x36, 0x9f, 0x5c, 0x1a, 0x17, 0xdf, 0x5c, 0xda, 0x49,
|
||||
0xdb, 0xdd, 0x93, 0xf6, 0x2f, 0x2d, 0xb8, 0xb7, 0xf5, 0x1c, 0x3b, 0x00, 0x6b, 0xad, 0x32, 0x77,
|
||||
0xb9, 0xb5, 0x26, 0x54, 0xaa, 0xac, 0x5d, 0x6e, 0x95, 0x84, 0x6e, 0xd5, 0x1e, 0xb8, 0xdc, 0xba,
|
||||
0x25, 0xb4, 0x50, 0xd3, 0x77, 0xb9, 0xb5, 0x60, 0x1f, 0x43, 0xe7, 0x87, 0x02, 0x65, 0x84, 0x99,
|
||||
0xef, 0xaa, 0xec, 0xde, 0xda, 0x64, 0xf7, 0x6d, 0x81, 0xb2, 0xe4, 0x95, 0x9f, 0xba, 0xa1, 0x36,
|
||||
0x47, 0xaf, 0x81, 0x3a, 0x93, 0x2d, 0xa7, 0x2d, 0xeb, 0x68, 0x1b, 0x9d, 0x4d, 0x17, 0xf5, 0xec,
|
||||
0xa9, 0x8b, 0x9f, 0x83, 0x23, 0xd6, 0x98, 0xf9, 0x9e, 0x8a, 0xff, 0xc1, 0xbf, 0x34, 0xec, 0x68,
|
||||
0xb8, 0xc6, 0xec, 0xeb, 0x55, 0x2e, 0x4b, 0xae, 0xae, 0x3f, 0x7c, 0x0a, 0x5e, 0x6d, 0xa2, 0x0d,
|
||||
0x7c, 0x85, 0xa5, 0x2a, 0xd0, 0xe3, 0x74, 0x64, 0x1f, 0x82, 0x7b, 0x23, 0xe2, 0x42, 0x0f, 0xa7,
|
||||
0xf7, 0xf8, 0x70, 0x13, 0x76, 0xb8, 0x8e, 0x32, 0xae, 0x9d, 0x5f, 0xb6, 0xbe, 0xb0, 0x82, 0x5f,
|
||||
0x2d, 0x70, 0xc8, 0x46, 0x9d, 0x8d, 0x71, 0x2e, 0xc2, 0xf2, 0x38, 0x29, 0x56, 0xd3, 0xcc, 0xb7,
|
||||
0xfa, 0xf6, 0xc0, 0xe6, 0x5b, 0x36, 0xf6, 0x0e, 0xb4, 0x27, 0xda, 0xdb, 0xea, 0xdb, 0x03, 0x8f,
|
||||
0x1b, 0xc4, 0xee, 0x83, 0x1b, 0x8b, 0x09, 0xc6, 0x86, 0x4f, 0x1a, 0xd0, 0xed, 0x54, 0xe2, 0x2c,
|
||||
0x5a, 0x1b, 0x3a, 0x19, 0x44, 0xf6, 0xac, 0x98, 0x91, 0x5d, 0x4f, 0xcf, 0x20, 0x6a, 0xd7, 0x44,
|
||||
0x64, 0x75, 0x0b, 0xe9, 0x4c, 0x91, 0xb3, 0x50, 0xc4, 0x55, 0x0f, 0x35, 0x08, 0x7e, 0xb7, 0x88,
|
||||
0x47, 0x7a, 0x27, 0x1a, 0x7b, 0xa9, 0x3b, 0xfa, 0x2e, 0x74, 0x69, 0x5f, 0x5e, 0xde, 0x08, 0x69,
|
||||
0x76, 0xb3, 0x43, 0xf8, 0x5a, 0x48, 0xf6, 0x29, 0xb4, 0x55, 0xe5, 0x7b, 0xf6, 0xb3, 0x0a, 0x77,
|
||||
0x4d, 0x7e, 0x6e, 0xae, 0xd5, 0x13, 0x74, 0x1a, 0x13, 0xac, 0x8b, 0x75, 0x9b, 0xc5, 0x3e, 0x02,
|
||||
0x97, 0x56, 0xa1, 0x54, 0xd9, 0xef, 0x8d, 0xac, 0x17, 0x46, 0xdf, 0x0a, 0xae, 0xe0, 0xde, 0xd6,
|
||||
0x8b, 0xf5, 0x4b, 0xd6, 0xf6, 0x4b, 0x9b, 0x29, 0x7a, 0x66, 0x6a, 0xa4, 0x21, 0x19, 0xc6, 0x18,
|
||||
0xe6, 0x38, 0x55, 0xfd, 0xee, 0xf2, 0x1a, 0x07, 0x3f, 0x59, 0x9b, 0xb8, 0xea, 0x3d, 0x52, 0x89,
|
||||
0x30, 0x59, 0x2e, 0xc5, 0x6a, 0x6a, 0x42, 0x57, 0x90, 0xfa, 0x36, 0x9d, 0x98, 0xd0, 0xad, 0xe9,
|
||||
0x84, 0xb0, 0x4c, 0xcd, 0x04, 0x5b, 0x32, 0x65, 0x7d, 0xe8, 0x2d, 0x51, 0x64, 0x85, 0xc4, 0x25,
|
||||
0xae, 0x72, 0xd3, 0x82, 0xa6, 0x89, 0x3d, 0x80, 0x4e, 0x2e, 0xe6, 0x2f, 0x69, 0xf7, 0xcc, 0x24,
|
||||
0x73, 0x31, 0x3f, 0xc3, 0x92, 0xbd, 0x07, 0xde, 0x2c, 0xc2, 0x78, 0xaa, 0x5c, 0x7a, 0x9c, 0x5d,
|
||||
0x65, 0x38, 0xc3, 0x32, 0xf8, 0xd3, 0x82, 0xf6, 0x18, 0xe5, 0x0d, 0xca, 0x3b, 0x49, 0x4a, 0x53,
|
||||
0x96, 0xed, 0x37, 0xc8, 0xb2, 0xb3, 0x5f, 0x96, 0xdd, 0x8d, 0x2c, 0xdf, 0x07, 0x77, 0x2c, 0xc3,
|
||||
0xd3, 0x91, 0xca, 0xc8, 0xe6, 0x1a, 0xd0, 0x36, 0x0e, 0xc3, 0x3c, 0xba, 0x41, 0xa3, 0xd5, 0x06,
|
||||
0xed, 0x28, 0x4d, 0x77, 0x8f, 0xd2, 0xfc, 0x61, 0x41, 0xfb, 0x5c, 0x94, 0x49, 0x91, 0xef, 0x6c,
|
||||
0x61, 0x1f, 0x7a, 0xc3, 0x34, 0x8d, 0xa3, 0x50, 0x7f, 0xad, 0x2b, 0x6a, 0x9a, 0xe8, 0xc6, 0xb3,
|
||||
0x46, 0x7f, 0x75, 0x6d, 0x4d, 0x13, 0xb1, 0xf8, 0x44, 0xa9, 0xa9, 0x96, 0xc6, 0x06, 0x8b, 0xb5,
|
||||
0x88, 0x2a, 0x27, 0x35, 0x61, 0x58, 0xe4, 0xc9, 0x2c, 0x4e, 0x6e, 0x55, 0xb5, 0x5d, 0x5e, 0xe3,
|
||||
0x9d, 0x22, 0xda, 0x7b, 0x8a, 0x78, 0xdd, 0x02, 0xe7, 0xff, 0x52, 0xc9, 0x03, 0xb0, 0x22, 0x93,
|
||||
0x84, 0x15, 0xd5, 0x9a, 0xd9, 0x69, 0x68, 0xa6, 0x0f, 0x9d, 0x52, 0x8a, 0xd5, 0x1c, 0x33, 0xbf,
|
||||
0xab, 0x14, 0xa8, 0x82, 0xca, 0xa3, 0xb8, 0xa6, 0xc5, 0xd2, 0xe3, 0x15, 0xac, 0xb9, 0x03, 0x0d,
|
||||
0xee, 0x7c, 0x62, 0x74, 0xb5, 0xa7, 0x32, 0xf2, 0xb7, 0x5b, 0xf7, 0xdf, 0xc9, 0xe9, 0x6b, 0x0b,
|
||||
0xdc, 0x9a, 0x78, 0x27, 0xdb, 0xc4, 0x3b, 0xd9, 0x10, 0x6f, 0x74, 0x5c, 0x11, 0x6f, 0x74, 0x4c,
|
||||
0x98, 0x5f, 0x54, 0xc4, 0xe3, 0x17, 0x34, 0xd0, 0xa7, 0x32, 0x29, 0xd2, 0xe3, 0x52, 0x4f, 0xde,
|
||||
0xe3, 0x35, 0xa6, 0x6d, 0xfd, 0x6e, 0x81, 0xd2, 0xb4, 0xda, 0xe3, 0x06, 0xd1, 0x6e, 0x9f, 0x2b,
|
||||
0x51, 0xd2, 0xcd, 0xd5, 0x80, 0x7d, 0x04, 0x2e, 0xa7, 0xe6, 0xa9, 0x0e, 0x6f, 0xcd, 0x45, 0x99,
|
||||
0xb9, 0xf6, 0x52, 0x50, 0xfd, 0xef, 0x64, 0x96, 0xdc, 0xa0, 0xe0, 0x89, 0xf9, 0x9c, 0xa2, 0x5f,
|
||||
0xa5, 0x29, 0x4a, 0x43, 0x55, 0x0d, 0xd4, 0x9b, 0xc9, 0x2d, 0x6a, 0x95, 0xb5, 0xb9, 0x06, 0xc1,
|
||||
0xf7, 0xe0, 0x0d, 0x63, 0x94, 0x39, 0x2f, 0xe2, 0x5d, 0x6d, 0x66, 0xe0, 0x7c, 0x33, 0x7e, 0xf1,
|
||||
0xbc, 0x22, 0x38, 0x9d, 0x37, 0xb4, 0xb4, 0xff, 0x41, 0xcb, 0x33, 0x91, 0x8a, 0xd3, 0x91, 0xda,
|
||||
0x33, 0x9b, 0x1b, 0x14, 0xfc, 0x6c, 0x81, 0x43, 0xfc, 0x6f, 0x84, 0x76, 0xde, 0xa4, 0x1d, 0x17,
|
||||
0x32, 0xb9, 0x89, 0xa6, 0x28, 0x2b, 0xed, 0xa8, 0xb0, 0x2a, 0x3a, 0x5c, 0x60, 0xfd, 0xb3, 0x67,
|
||||
0x10, 0xcd, 0x9a, 0x27, 0x71, 0xbd, 0xcb, 0x8d, 0x59, 0x93, 0x99, 0x6b, 0x27, 0x7b, 0x1f, 0x60,
|
||||
0x5c, 0xa4, 0x28, 0x87, 0xd3, 0x65, 0xa4, 0x69, 0xd5, 0xe5, 0x0d, 0x4b, 0xf0, 0x15, 0x38, 0x74,
|
||||
0x71, 0x87, 0x80, 0xd6, 0x2e, 0x01, 0xf7, 0x65, 0x1e, 0x5c, 0x6e, 0x7f, 0x77, 0xa7, 0x6a, 0xfb,
|
||||
0xd0, 0x33, 0xff, 0x99, 0xf4, 0x74, 0x25, 0x28, 0x0d, 0xd3, 0xa4, 0xad, 0x7e, 0x9b, 0x9f, 0xfc,
|
||||
0x1d, 0x00, 0x00, 0xff, 0xff, 0x65, 0x9d, 0x67, 0xe0, 0x48, 0x0b, 0x00, 0x00,
|
||||
// 1148 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x8e, 0xe3, 0xc4,
|
||||
0x13, 0x56, 0xc7, 0x71, 0x12, 0x57, 0x66, 0xf7, 0xf7, 0x53, 0x6b, 0xc5, 0x9a, 0x45, 0x42, 0xc1,
|
||||
0x02, 0x29, 0x48, 0xec, 0x80, 0x76, 0x85, 0x84, 0x38, 0x20, 0x65, 0x26, 0x68, 0x35, 0xec, 0xbf,
|
||||
0xa1, 0x33, 0xb3, 0x9c, 0xd0, 0xaa, 0xe3, 0x54, 0x12, 0x6b, 0x9d, 0xd8, 0xb4, 0xed, 0x99, 0x98,
|
||||
0xb7, 0x41, 0xe2, 0xc4, 0x11, 0x71, 0x47, 0xe2, 0x84, 0xf6, 0x41, 0x78, 0x0e, 0x54, 0xdd, 0x6d,
|
||||
0xc7, 0xd9, 0x84, 0xd5, 0x5c, 0xe0, 0xd6, 0x5f, 0x55, 0x77, 0x75, 0x57, 0xd5, 0x57, 0x9f, 0x1a,
|
||||
0x6e, 0x47, 0xeb, 0x1c, 0xd5, 0x5a, 0xc6, 0xc7, 0xa9, 0x4a, 0xf2, 0x84, 0xf7, 0x2a, 0x1c, 0xfc,
|
||||
0xd5, 0x82, 0xce, 0x24, 0x29, 0x54, 0x88, 0xfc, 0x36, 0xb4, 0xce, 0xc6, 0x3e, 0x1b, 0xb0, 0xa1,
|
||||
0x23, 0x5a, 0x67, 0x63, 0xce, 0xa1, 0xfd, 0x4c, 0xae, 0xd0, 0x6f, 0x0d, 0xd8, 0xd0, 0x13, 0x7a,
|
||||
0x4d, 0xb6, 0x8b, 0x32, 0x45, 0xdf, 0x31, 0x36, 0x5a, 0xf3, 0x7b, 0xd0, 0xbb, 0xcc, 0x28, 0xda,
|
||||
0x0a, 0xfd, 0xb6, 0xb6, 0xd7, 0x98, 0x7c, 0xe7, 0x32, 0xcb, 0xae, 0x13, 0x35, 0xf3, 0x5d, 0xe3,
|
||||
0xab, 0x30, 0xff, 0x3f, 0x38, 0x97, 0xe2, 0x89, 0xdf, 0xd1, 0x66, 0x5a, 0x72, 0x1f, 0xba, 0x63,
|
||||
0x9c, 0xcb, 0x22, 0xce, 0xfd, 0xee, 0x80, 0x0d, 0x7b, 0xa2, 0x82, 0x14, 0xe7, 0x02, 0x63, 0x5c,
|
||||
0x28, 0x39, 0xf7, 0x7b, 0x26, 0x4e, 0x85, 0xf9, 0x31, 0xf0, 0xb3, 0x75, 0x86, 0x61, 0xa1, 0x70,
|
||||
0xf2, 0x2a, 0x4a, 0x5f, 0xa0, 0x8a, 0xe6, 0xa5, 0xef, 0xe9, 0x00, 0x07, 0x3c, 0x74, 0xcb, 0x53,
|
||||
0xcc, 0x25, 0xdd, 0x0d, 0x3a, 0x54, 0x05, 0x79, 0x00, 0x47, 0x93, 0xa5, 0x54, 0x38, 0x9b, 0x60,
|
||||
0xa8, 0x30, 0xf7, 0xfb, 0xda, 0xbd, 0x63, 0xa3, 0x3d, 0xcf, 0xd5, 0x42, 0xae, 0xa3, 0x1f, 0x65,
|
||||
0x1e, 0x25, 0x6b, 0xff, 0xc8, 0xec, 0x69, 0xda, 0xa8, 0x4a, 0x22, 0x89, 0xd1, 0xbf, 0x65, 0xaa,
|
||||
0x44, 0xeb, 0xe0, 0x37, 0x06, 0xde, 0x58, 0x66, 0xcb, 0x69, 0x22, 0xd5, 0xec, 0x46, 0xb5, 0xbe,
|
||||
0x0f, 0x6e, 0x88, 0x71, 0x9c, 0xf9, 0xce, 0xc0, 0x19, 0xf6, 0x1f, 0xdc, 0x3d, 0xae, 0x9b, 0x58,
|
||||
0xc7, 0x39, 0xc5, 0x38, 0x16, 0x66, 0x17, 0xff, 0x0c, 0xbc, 0x1c, 0x57, 0x69, 0x2c, 0x73, 0xcc,
|
||||
0xfc, 0xb6, 0x3e, 0xc2, 0xb7, 0x47, 0x2e, 0xac, 0x4b, 0x6c, 0x37, 0xed, 0xa5, 0xe2, 0xee, 0xa7,
|
||||
0x12, 0xfc, 0xd2, 0x82, 0x5b, 0x3b, 0xd7, 0xf1, 0x23, 0x60, 0x1b, 0xfd, 0x72, 0x57, 0xb0, 0x0d,
|
||||
0xa1, 0x52, 0xbf, 0xda, 0x15, 0xac, 0x24, 0x74, 0xad, 0xb9, 0xe1, 0x0a, 0x76, 0x4d, 0x68, 0xa9,
|
||||
0x19, 0xe1, 0x0a, 0xb6, 0xe4, 0x1f, 0x43, 0xf7, 0x87, 0x02, 0x55, 0x84, 0x99, 0xef, 0xea, 0xd7,
|
||||
0xfd, 0x6f, 0xfb, 0xba, 0x6f, 0x0b, 0x54, 0xa5, 0xa8, 0xfc, 0x54, 0x0d, 0xcd, 0x26, 0x43, 0x0d,
|
||||
0xbd, 0x26, 0x5b, 0x4e, 0xcc, 0xeb, 0x1a, 0x1b, 0xad, 0x6d, 0x15, 0x0d, 0x1f, 0xa8, 0x8a, 0x9f,
|
||||
0x43, 0x5b, 0x6e, 0x30, 0xf3, 0x3d, 0x1d, 0xff, 0x83, 0x7f, 0x28, 0xd8, 0xf1, 0x68, 0x83, 0xd9,
|
||||
0xd7, 0xeb, 0x5c, 0x95, 0x42, 0x6f, 0xbf, 0xf7, 0x08, 0xbc, 0xda, 0x44, 0xac, 0x7c, 0x85, 0xa5,
|
||||
0x4e, 0xd0, 0x13, 0xb4, 0xe4, 0x1f, 0x82, 0x7b, 0x25, 0xe3, 0xc2, 0x34, 0xa7, 0xff, 0xe0, 0xf6,
|
||||
0x36, 0xec, 0x68, 0x13, 0x65, 0xc2, 0x38, 0xbf, 0x6c, 0x7d, 0xc1, 0x82, 0x5f, 0x19, 0xb4, 0xc9,
|
||||
0x46, 0x95, 0x8d, 0x71, 0x21, 0xc3, 0xf2, 0x24, 0x29, 0xd6, 0xb3, 0xcc, 0x67, 0x03, 0x67, 0xe8,
|
||||
0x88, 0x1d, 0x1b, 0x7f, 0x07, 0x3a, 0x53, 0xe3, 0x6d, 0x0d, 0x9c, 0xa1, 0x27, 0x2c, 0xe2, 0x77,
|
||||
0xc0, 0x8d, 0xe5, 0x14, 0x63, 0x3b, 0x63, 0x06, 0xd0, 0xee, 0x54, 0xe1, 0x3c, 0xda, 0xd8, 0x11,
|
||||
0xb3, 0x88, 0xec, 0x59, 0x31, 0x27, 0xbb, 0xe9, 0x9e, 0x45, 0x54, 0xae, 0xa9, 0xcc, 0xea, 0x12,
|
||||
0xd2, 0x9a, 0x22, 0x67, 0xa1, 0x8c, 0xab, 0x1a, 0x1a, 0x10, 0xfc, 0xce, 0x68, 0xb6, 0x0c, 0x27,
|
||||
0x1a, 0xbc, 0x34, 0x15, 0x7d, 0x17, 0x7a, 0xc4, 0x97, 0x97, 0x57, 0x52, 0x59, 0x6e, 0x76, 0x09,
|
||||
0xbf, 0x90, 0x8a, 0x7f, 0x0a, 0x1d, 0x9d, 0xf9, 0x01, 0x7e, 0x56, 0xe1, 0x5e, 0x90, 0x5f, 0xd8,
|
||||
0x6d, 0x75, 0x07, 0xdb, 0x8d, 0x0e, 0xd6, 0xc9, 0xba, 0xcd, 0x64, 0xef, 0x83, 0x4b, 0x54, 0x28,
|
||||
0xf5, 0xeb, 0x0f, 0x46, 0x36, 0x84, 0x31, 0xbb, 0x82, 0x4b, 0xb8, 0xb5, 0x73, 0x63, 0x7d, 0x13,
|
||||
0xdb, 0xbd, 0x69, 0xdb, 0x45, 0xcf, 0x76, 0x8d, 0x74, 0x25, 0xc3, 0x18, 0xc3, 0x1c, 0x67, 0xba,
|
||||
0xde, 0x3d, 0x51, 0xe3, 0xe0, 0x27, 0xb6, 0x8d, 0xab, 0xef, 0x23, 0xe5, 0x08, 0x93, 0xd5, 0x4a,
|
||||
0xae, 0x67, 0x36, 0x74, 0x05, 0xa9, 0x6e, 0xb3, 0xa9, 0x0d, 0xdd, 0x9a, 0x4d, 0x09, 0xab, 0xd4,
|
||||
0x76, 0xb0, 0xa5, 0x52, 0x3e, 0x80, 0xfe, 0x0a, 0x65, 0x56, 0x28, 0x5c, 0xe1, 0x3a, 0xb7, 0x25,
|
||||
0x68, 0x9a, 0xf8, 0x5d, 0xe8, 0xe6, 0x72, 0xf1, 0x92, 0xb8, 0x67, 0x3b, 0x99, 0xcb, 0xc5, 0x63,
|
||||
0x2c, 0xf9, 0x7b, 0xe0, 0xcd, 0x23, 0x8c, 0x67, 0xda, 0x65, 0xda, 0xd9, 0xd3, 0x86, 0xc7, 0x58,
|
||||
0x06, 0x7f, 0x32, 0xe8, 0x4c, 0x50, 0x5d, 0xa1, 0xba, 0x91, 0xa4, 0x34, 0xa5, 0xda, 0x79, 0x8b,
|
||||
0x54, 0xb7, 0x0f, 0x4b, 0xb5, 0xbb, 0x95, 0xea, 0x3b, 0xe0, 0x4e, 0x54, 0x78, 0x36, 0xd6, 0x2f,
|
||||
0x72, 0x84, 0x01, 0xc4, 0xc6, 0x51, 0x98, 0x47, 0x57, 0x68, 0xf5, 0xdb, 0xa2, 0x3d, 0xa5, 0xe9,
|
||||
0x1d, 0x50, 0x9a, 0x3f, 0x18, 0x74, 0x9e, 0xc8, 0x32, 0x29, 0xf2, 0x3d, 0x16, 0x0e, 0xa0, 0x3f,
|
||||
0x4a, 0xd3, 0x38, 0x0a, 0xcd, 0x69, 0x93, 0x51, 0xd3, 0x44, 0x3b, 0x9e, 0x36, 0xea, 0x6b, 0x72,
|
||||
0x6b, 0x9a, 0x68, 0x8a, 0x4f, 0xb5, 0x9a, 0x1a, 0x69, 0x6c, 0x4c, 0xb1, 0x11, 0x51, 0xed, 0xa4,
|
||||
0x22, 0x8c, 0x8a, 0x3c, 0x99, 0xc7, 0xc9, 0xb5, 0xce, 0xb6, 0x27, 0x6a, 0xbc, 0x97, 0x44, 0xe7,
|
||||
0x40, 0x12, 0xaf, 0x5b, 0xd0, 0xfe, 0xaf, 0x54, 0xf2, 0x08, 0x58, 0x64, 0x1f, 0xc1, 0xa2, 0x5a,
|
||||
0x33, 0xbb, 0x0d, 0xcd, 0xf4, 0xa1, 0x5b, 0x2a, 0xb9, 0x5e, 0x60, 0xe6, 0xf7, 0xb4, 0x02, 0x55,
|
||||
0x50, 0x7b, 0xf4, 0xac, 0x19, 0xb1, 0xf4, 0x44, 0x05, 0xeb, 0xd9, 0x81, 0xc6, 0xec, 0x7c, 0x62,
|
||||
0x75, 0xb5, 0xaf, 0x5f, 0xe4, 0xef, 0x96, 0xee, 0xdf, 0x93, 0xd3, 0xd7, 0x0c, 0xdc, 0x7a, 0xf0,
|
||||
0x4e, 0x77, 0x07, 0xef, 0x74, 0x3b, 0x78, 0xe3, 0x93, 0x6a, 0xf0, 0xc6, 0x27, 0x84, 0xc5, 0x79,
|
||||
0x35, 0x78, 0xe2, 0x9c, 0x1a, 0xfa, 0x48, 0x25, 0x45, 0x7a, 0x52, 0x9a, 0xce, 0x7b, 0xa2, 0xc6,
|
||||
0xc4, 0xd6, 0xef, 0x96, 0xa8, 0x6c, 0xa9, 0x3d, 0x61, 0x11, 0x71, 0xfb, 0x89, 0x16, 0x25, 0x53,
|
||||
0x5c, 0x03, 0xf8, 0x47, 0xe0, 0x0a, 0x2a, 0x9e, 0xae, 0xf0, 0x4e, 0x5f, 0xb4, 0x59, 0x18, 0x2f,
|
||||
0x05, 0x35, 0xff, 0x29, 0x4b, 0x72, 0x8b, 0x82, 0x87, 0xf6, 0x38, 0x45, 0xbf, 0x4c, 0x53, 0x54,
|
||||
0x76, 0x54, 0x0d, 0xd0, 0x77, 0x26, 0xd7, 0x68, 0x54, 0xd6, 0x11, 0x06, 0x04, 0xdf, 0x83, 0x37,
|
||||
0x8a, 0x51, 0xe5, 0xa2, 0x88, 0xf7, 0xb5, 0x99, 0x43, 0xfb, 0x9b, 0xc9, 0xf3, 0x67, 0xd5, 0x80,
|
||||
0xd3, 0x7a, 0x3b, 0x96, 0xce, 0x1b, 0x63, 0xf9, 0x58, 0xa6, 0xf2, 0x6c, 0xac, 0x79, 0xe6, 0x08,
|
||||
0x8b, 0x82, 0x9f, 0x19, 0xb4, 0x69, 0xfe, 0x1b, 0xa1, 0xdb, 0x6f, 0xd3, 0x8e, 0x73, 0x95, 0x5c,
|
||||
0x45, 0x33, 0x54, 0x95, 0x76, 0x54, 0x58, 0x27, 0x1d, 0x2e, 0xb1, 0xfe, 0x00, 0x5a, 0x44, 0xbd,
|
||||
0xa6, 0xcf, 0x4f, 0xc5, 0xe5, 0x46, 0xaf, 0xc9, 0x2c, 0x8c, 0x93, 0xbf, 0x0f, 0x30, 0x29, 0x52,
|
||||
0x54, 0xa3, 0xd9, 0x2a, 0x32, 0x63, 0xd5, 0x13, 0x0d, 0x4b, 0xf0, 0x95, 0xf9, 0x4e, 0xed, 0x0d,
|
||||
0x20, 0x3b, 0xfc, 0xf5, 0x7a, 0xf3, 0xe5, 0xc1, 0xc5, 0xee, 0xb9, 0x1b, 0x65, 0x3b, 0x80, 0xbe,
|
||||
0xfd, 0x7b, 0xea, 0x9f, 0x9c, 0x15, 0x94, 0x86, 0x69, 0xda, 0xd1, 0x5f, 0xe9, 0x87, 0x7f, 0x07,
|
||||
0x00, 0x00, 0xff, 0xff, 0x90, 0x83, 0x07, 0x1e, 0x5c, 0x0b, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ message Source {
|
|||
string MetaURL = 10; // MetaURL is the connection URL for the meta node.
|
||||
string SharedSecret = 11; // SharedSecret signs the optional InfluxDB JWT Authorization
|
||||
string Organization = 12; // Organization is the organization ID that resource belongs to
|
||||
string Role = 13; // Role is the name of the miniumum role that a user must possess to access the resource
|
||||
}
|
||||
|
||||
message Dashboard {
|
||||
|
|
|
@ -30,6 +30,7 @@ func TestSourceStore(t *testing.T) {
|
|||
URL: "toyota-hilux.lyon-estates.local",
|
||||
Default: true,
|
||||
Organization: "1337",
|
||||
Role: "member",
|
||||
},
|
||||
chronograf.Source{
|
||||
Name: "HipToBeSquare",
|
||||
|
@ -39,6 +40,7 @@ func TestSourceStore(t *testing.T) {
|
|||
URL: "toyota-hilux.lyon-estates.local",
|
||||
Default: true,
|
||||
Organization: "1337",
|
||||
Role: "admin",
|
||||
},
|
||||
chronograf.Source{
|
||||
Name: "HipToBeSquare",
|
||||
|
@ -49,6 +51,7 @@ func TestSourceStore(t *testing.T) {
|
|||
InsecureSkipVerify: true,
|
||||
Default: false,
|
||||
Organization: "1337",
|
||||
Role: "viewer",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -450,6 +450,7 @@ type Source struct {
|
|||
Default bool `json:"default"` // Default specifies the default source for the application
|
||||
Telegraf string `json:"telegraf"` // Telegraf is the db telegraf is written to. By default it is "telegraf"
|
||||
Organization string `json:"organization"` // Organization is the organization ID that resource belongs to
|
||||
Role string `json:"role"` // Role is the name of the minimum role that a user must possess to access the resource.
|
||||
}
|
||||
|
||||
// SourcesStore stores connection information for a `TimeSeries`
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
// ContextKey is the key used to specify the
|
||||
// role via context
|
||||
const ContextKey = contextKey("role")
|
||||
|
||||
func validRole(ctx context.Context) error {
|
||||
// prevents panic in case of nil context
|
||||
if ctx == nil {
|
||||
return fmt.Errorf("expect non nil context")
|
||||
}
|
||||
role, ok := ctx.Value(ContextKey).(string)
|
||||
// should never happen
|
||||
if !ok {
|
||||
return fmt.Errorf("expected role key to be a string")
|
||||
}
|
||||
switch role {
|
||||
case MemberRoleName, ViewerRoleName, EditorRoleName, AdminRoleName:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("expected role key to be set")
|
||||
}
|
||||
}
|
||||
|
||||
// Chronograf User Roles
|
||||
const (
|
||||
MemberRoleName = "member"
|
||||
ViewerRoleName = "viewer"
|
||||
EditorRoleName = "editor"
|
||||
AdminRoleName = "admin"
|
||||
SuperAdminStatus = "superadmin"
|
||||
)
|
||||
|
||||
var (
|
||||
// MemberRole is the role for a user who can only perform No operations.
|
||||
MemberRole = chronograf.Role{
|
||||
Name: MemberRoleName,
|
||||
}
|
||||
|
||||
// ViewerRole is the role for a user who can only perform READ operations on Dashboards, Rules, Sources, and Servers,
|
||||
ViewerRole = chronograf.Role{
|
||||
Name: ViewerRoleName,
|
||||
}
|
||||
|
||||
// EditorRole is the role for a user who can perform READ and WRITE operations on Dashboards, Rules, Sources, and Servers.
|
||||
EditorRole = chronograf.Role{
|
||||
Name: EditorRoleName,
|
||||
}
|
||||
|
||||
// AdminRole is the role for a user who can perform READ and WRITE operations on Dashboards, Rules, Sources, Servers, and Users
|
||||
AdminRole = chronograf.Role{
|
||||
Name: AdminRoleName,
|
||||
}
|
||||
)
|
|
@ -0,0 +1,138 @@
|
|||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/influxdata/chronograf"
|
||||
)
|
||||
|
||||
// ensure that SourcesStore implements chronograf.SourceStore
|
||||
var _ chronograf.SourcesStore = &SourcesStore{}
|
||||
|
||||
// SourcesStore facade on a SourceStore that filters sources
|
||||
// by minimum role required to access the source.
|
||||
//
|
||||
// The role is passed around on the context and set when the
|
||||
// SourcesStore is instantiated.
|
||||
type SourcesStore struct {
|
||||
store chronograf.SourcesStore
|
||||
role string
|
||||
}
|
||||
|
||||
// NewSourcesStore creates a new SourcesStore from an existing
|
||||
// chronograf.SourceStore and an role string
|
||||
func NewSourcesStore(s chronograf.SourcesStore, role string) *SourcesStore {
|
||||
return &SourcesStore{
|
||||
store: s,
|
||||
role: role,
|
||||
}
|
||||
}
|
||||
|
||||
// All retrieves all sources from the underlying SourceStore and filters them
|
||||
// by role.
|
||||
func (s *SourcesStore) All(ctx context.Context) ([]chronograf.Source, error) {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds, err := s.store.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This filters sources without allocating
|
||||
// https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating
|
||||
sources := ds[:0]
|
||||
for _, d := range ds {
|
||||
if hasAuthorizedRole(d.Role, s.role) {
|
||||
sources = append(sources, d)
|
||||
}
|
||||
}
|
||||
|
||||
return sources, nil
|
||||
}
|
||||
|
||||
// Add creates a new Source in the SourcesStore with source.Role set to be the
|
||||
// role from the source store.
|
||||
func (s *SourcesStore) Add(ctx context.Context, d chronograf.Source) (chronograf.Source, error) {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return chronograf.Source{}, err
|
||||
}
|
||||
|
||||
return s.store.Add(ctx, d)
|
||||
}
|
||||
|
||||
// Delete the source from SourcesStore
|
||||
func (s *SourcesStore) Delete(ctx context.Context, d chronograf.Source) error {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d, err = s.store.Get(ctx, d.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.store.Delete(ctx, d)
|
||||
}
|
||||
|
||||
// Get returns a Source if the id exists and belongs to the role that is set.
|
||||
func (s *SourcesStore) Get(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return chronograf.Source{}, err
|
||||
}
|
||||
|
||||
d, err := s.store.Get(ctx, id)
|
||||
if err != nil {
|
||||
return chronograf.Source{}, err
|
||||
}
|
||||
|
||||
if !hasAuthorizedRole(d.Role, s.role) {
|
||||
return chronograf.Source{}, chronograf.ErrSourceNotFound
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Update the source in SourcesStore.
|
||||
func (s *SourcesStore) Update(ctx context.Context, d chronograf.Source) error {
|
||||
err := validRole(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = s.store.Get(ctx, d.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.store.Update(ctx, d)
|
||||
}
|
||||
|
||||
// hasAuthorizedRole checks that the role provided has at least
|
||||
// the minimum role required.
|
||||
func hasAuthorizedRole(sourceRole, providedRole string) bool {
|
||||
switch sourceRole {
|
||||
case ViewerRoleName:
|
||||
switch providedRole {
|
||||
case ViewerRoleName, EditorRoleName, AdminRoleName:
|
||||
return true
|
||||
}
|
||||
case EditorRoleName:
|
||||
switch providedRole {
|
||||
case EditorRoleName, AdminRoleName:
|
||||
return true
|
||||
}
|
||||
case AdminRoleName:
|
||||
switch providedRole {
|
||||
case AdminRoleName:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,489 @@
|
|||
package roles
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
)
|
||||
|
||||
func TestSources_Get(t *testing.T) {
|
||||
type fields struct {
|
||||
SourcesStore chronograf.SourcesStore
|
||||
}
|
||||
type args struct {
|
||||
role string
|
||||
id int
|
||||
}
|
||||
type wants struct {
|
||||
source chronograf.Source
|
||||
err bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "Get viewer source as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get viewer source as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get viewer source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as viewer - want error",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as viewer - want error",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as editor - want error",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get source bad context",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "random role",
|
||||
id: 1,
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := NewSourcesStore(tt.fields.SourcesStore, tt.args.role)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if tt.args.role != "" {
|
||||
ctx = context.WithValue(ctx, ContextKey, tt.args.role)
|
||||
}
|
||||
|
||||
source, err := store.Get(ctx, tt.args.id)
|
||||
if (err != nil) != tt.wants.err {
|
||||
t.Errorf("%q. Store.Sources().Get() error = %v, wantErr %v", tt.name, err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(source, tt.wants.source); diff != "" {
|
||||
t.Errorf("%q. Store.Sources().Get():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSources_All(t *testing.T) {
|
||||
type fields struct {
|
||||
SourcesStore chronograf.SourcesStore
|
||||
}
|
||||
type args struct {
|
||||
role string
|
||||
}
|
||||
type wants struct {
|
||||
sources []chronograf.Source
|
||||
err bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "Get viewer sources as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Source, error) {
|
||||
return []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
sources: []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor sources as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Source, error) {
|
||||
return []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
},
|
||||
wants: wants{
|
||||
sources: []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin sources as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
AllF: func(ctx context.Context) ([]chronograf.Source, error) {
|
||||
return []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
},
|
||||
wants: wants{
|
||||
sources: []chronograf.Source{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := NewSourcesStore(tt.fields.SourcesStore, tt.args.role)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if tt.args.role != "" {
|
||||
ctx = context.WithValue(ctx, ContextKey, tt.args.role)
|
||||
}
|
||||
|
||||
sources, err := store.All(ctx)
|
||||
if (err != nil) != tt.wants.err {
|
||||
t.Errorf("%q. Store.Sources().Get() error = %v, wantErr %v", tt.name, err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(sources, tt.wants.sources); diff != "" {
|
||||
t.Errorf("%q. Store.Sources().Get():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/organizations"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
// AuthorizedToken extracts the token and validates; if valid the next handler
|
||||
|
@ -67,7 +68,18 @@ func AuthorizedUser(
|
|||
unknownErrorWithMessage(w, err, logger)
|
||||
return
|
||||
}
|
||||
// To access resources (servers, sources, databases, layouts) within a DataStore,
|
||||
// an organization and a role are required even if you are a super admin or are
|
||||
// not using auth. Every user's current organization is set on context to filter
|
||||
// the resources accessed within a DataStore, including for super admin or when
|
||||
// not using auth. In this way, a DataStore can treat all requests the same,
|
||||
// including those from a super admin and when not using auth.
|
||||
//
|
||||
// As for roles, in the case of super admin or when not using auth, the user's
|
||||
// role on context (though not on their JWT or user) is set to be admin. In order
|
||||
// to access all resources belonging to their current organization.
|
||||
ctx = context.WithValue(ctx, organizations.ContextKey, fmt.Sprintf("%d", defaultOrg.ID))
|
||||
ctx = context.WithValue(ctx, roles.ContextKey, roles.AdminRoleName)
|
||||
r = r.WithContext(ctx)
|
||||
next(w, r)
|
||||
return
|
||||
|
@ -120,6 +132,17 @@ func AuthorizedUser(
|
|||
|
||||
ctx = context.WithValue(ctx, organizations.ContextKey, p.Organization)
|
||||
serverCtx := context.WithValue(ctx, SuperAdminKey, true)
|
||||
// To access resources (servers, sources, databases, layouts) within a DataStore,
|
||||
// an organization and a role are required even if you are a super admin or are
|
||||
// not using auth. Every user's current organization is set on context to filter
|
||||
// the resources accessed within a DataStore, including for super admin or when
|
||||
// not using auth. In this way, a DataStore can treat all requests the same,
|
||||
// including those from a super admin and when not using auth.
|
||||
//
|
||||
// As for roles, in the case of super admin or when not using auth, the user's
|
||||
// role on context (though not on their JWT or user) is set to be admin. In order
|
||||
// to access all resources belonging to their current organization.
|
||||
serverCtx = context.WithValue(serverCtx, roles.ContextKey, roles.AdminRoleName)
|
||||
// TODO: seems silly to look up a user twice
|
||||
u, err := store.Users(serverCtx).Get(serverCtx, chronograf.UserQuery{
|
||||
Name: &p.Subject,
|
||||
|
@ -152,6 +175,16 @@ func AuthorizedUser(
|
|||
}
|
||||
|
||||
if hasAuthorizedRole(u, role) {
|
||||
if len(u.Roles) != 1 {
|
||||
msg := `User %d has too many role in organization. User: %#v.Please report this log at https://github.com/influxdata/chronograf/issues/new"`
|
||||
log.Error(fmt.Sprint(msg, u.ID, u))
|
||||
unknownErrorWithMessage(w, fmt.Errorf("please have administrator check logs and report error"), logger)
|
||||
return
|
||||
}
|
||||
// use the first role, since there should only ever be one
|
||||
// for any particular organization and hasAuthorizedRole
|
||||
// should ensure that at least one role for the org exists
|
||||
ctx = context.WithValue(ctx, roles.ContextKey, u.Roles[0].Name)
|
||||
r = r.WithContext(ctx)
|
||||
next(w, r)
|
||||
return
|
||||
|
@ -168,28 +201,28 @@ func hasAuthorizedRole(u *chronograf.User, role string) bool {
|
|||
}
|
||||
|
||||
switch role {
|
||||
case ViewerRoleName:
|
||||
case roles.ViewerRoleName:
|
||||
for _, r := range u.Roles {
|
||||
switch r.Name {
|
||||
case ViewerRoleName, EditorRoleName, AdminRoleName:
|
||||
case roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||
return true
|
||||
}
|
||||
}
|
||||
case EditorRoleName:
|
||||
case roles.EditorRoleName:
|
||||
for _, r := range u.Roles {
|
||||
switch r.Name {
|
||||
case EditorRoleName, AdminRoleName:
|
||||
case roles.EditorRoleName, roles.AdminRoleName:
|
||||
return true
|
||||
}
|
||||
}
|
||||
case AdminRoleName:
|
||||
case roles.AdminRoleName:
|
||||
for _, r := range u.Roles {
|
||||
switch r.Name {
|
||||
case AdminRoleName:
|
||||
case roles.AdminRoleName:
|
||||
return true
|
||||
}
|
||||
}
|
||||
case SuperAdminRoleName:
|
||||
case roles.SuperAdminStatus:
|
||||
// SuperAdmins should have been authorized before this.
|
||||
// This is only meant to restrict access for non-superadmins.
|
||||
return false
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
clog "github.com/influxdata/chronograf/log"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
"github.com/influxdata/chronograf/server"
|
||||
)
|
||||
|
||||
|
@ -115,7 +116,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -167,7 +168,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.EditorRoleName,
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -219,7 +220,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -271,7 +272,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -323,7 +324,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.EditorRoleName,
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -375,7 +376,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -427,7 +428,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -479,7 +480,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.EditorRoleName,
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -531,7 +532,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -872,7 +873,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -924,7 +925,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.EditorRoleName,
|
||||
Name: roles.EditorRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -976,7 +977,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1029,7 +1030,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.MemberRoleName,
|
||||
Name: roles.MemberRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1082,7 +1083,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.MemberRoleName,
|
||||
Name: roles.MemberRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1135,7 +1136,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.MemberRoleName,
|
||||
Name: roles.MemberRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1188,7 +1189,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.MemberRoleName,
|
||||
Name: roles.MemberRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1240,7 +1241,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1288,7 +1289,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1339,7 +1340,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1391,7 +1392,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -1450,7 +1451,7 @@ func TestAuthorizedUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: server.AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/organizations"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
type meLinks struct {
|
||||
|
@ -219,7 +220,7 @@ func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
|
|||
if !hasRoleInDefaultOrganization(usr) {
|
||||
usr.Roles = append(usr.Roles, chronograf.Role{
|
||||
Organization: "0",
|
||||
Name: MemberRoleName,
|
||||
Name: roles.MemberRoleName,
|
||||
})
|
||||
if err := s.Store.Users(ctx).Update(ctx, usr); err != nil {
|
||||
unknownErrorWithMessage(w, err, s.Logger)
|
||||
|
@ -249,7 +250,7 @@ func (s *Service) Me(w http.ResponseWriter, r *http.Request) {
|
|||
Scheme: scheme,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: MemberRoleName,
|
||||
Name: roles.MemberRoleName,
|
||||
// This is the ID of the default organization
|
||||
Organization: fmt.Sprintf("%d", defaultOrg.ID),
|
||||
},
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/influxdata/chronograf/log"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
type MockUsers struct{}
|
||||
|
@ -295,7 +296,7 @@ func TestService_MeOrganizations(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -354,7 +355,7 @@ func TestService_MeOrganizations(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
@ -465,7 +466,7 @@ func TestService_MeOrganizations(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "1337",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/bouk/httprouter"
|
||||
"github.com/influxdata/chronograf" // When julienschmidt/httprouter v2 w/ context is out, switch
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -71,7 +72,7 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
|
|||
return AuthorizedUser(
|
||||
service.Store,
|
||||
opts.UseAuth,
|
||||
ViewerRoleName,
|
||||
roles.ViewerRoleName,
|
||||
opts.Logger,
|
||||
next,
|
||||
)
|
||||
|
@ -80,7 +81,7 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
|
|||
return AuthorizedUser(
|
||||
service.Store,
|
||||
opts.UseAuth,
|
||||
EditorRoleName,
|
||||
roles.EditorRoleName,
|
||||
opts.Logger,
|
||||
next,
|
||||
)
|
||||
|
@ -89,7 +90,7 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
|
|||
return AuthorizedUser(
|
||||
service.Store,
|
||||
opts.UseAuth,
|
||||
AdminRoleName,
|
||||
roles.AdminRoleName,
|
||||
opts.Logger,
|
||||
next,
|
||||
)
|
||||
|
@ -98,7 +99,7 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
|
|||
return AuthorizedUser(
|
||||
service.Store,
|
||||
opts.UseAuth,
|
||||
SuperAdminRoleName,
|
||||
roles.SuperAdminStatus,
|
||||
opts.Logger,
|
||||
next,
|
||||
)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/bouk/httprouter"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
func parseOrganizationID(id string) (uint64, error) {
|
||||
|
@ -36,11 +37,11 @@ func (r *organizationRequest) ValidUpdate() error {
|
|||
|
||||
func (r *organizationRequest) ValidDefaultRole() error {
|
||||
if r.DefaultRole == "" {
|
||||
r.DefaultRole = MemberRoleName
|
||||
r.DefaultRole = roles.MemberRoleName
|
||||
}
|
||||
|
||||
switch r.DefaultRole {
|
||||
case MemberRoleName, ViewerRoleName, EditorRoleName, AdminRoleName:
|
||||
case roles.MemberRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("default role must be member, viewer, editor, or admin")
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/bouk/httprouter"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/influx"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
type sourceLinks struct {
|
||||
|
@ -259,6 +260,9 @@ func (s *Service) UpdateSource(w http.ResponseWriter, r *http.Request) {
|
|||
if req.Telegraf != "" {
|
||||
src.Telegraf = req.Telegraf
|
||||
}
|
||||
if req.Role != "" {
|
||||
src.Role = req.Role
|
||||
}
|
||||
|
||||
defaultOrg, err := s.Store.Organizations(ctx).DefaultOrganization(ctx)
|
||||
if err != nil {
|
||||
|
@ -310,6 +314,10 @@ func ValidSourceRequest(s chronograf.Source, defaultOrgID string) error {
|
|||
if len(url.Scheme) == 0 {
|
||||
return fmt.Errorf("Invalid URL; no URL scheme defined")
|
||||
}
|
||||
|
||||
if s.Role == "" {
|
||||
s.Role = roles.ViewerRoleName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/noop"
|
||||
"github.com/influxdata/chronograf/organizations"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
// hasOrganizationContext retrieves organization specified on context
|
||||
|
@ -26,6 +27,26 @@ func hasOrganizationContext(ctx context.Context) (string, bool) {
|
|||
return orgID, true
|
||||
}
|
||||
|
||||
// hasRoleContext retrieves organization specified on context
|
||||
// under the organizations.ContextKey
|
||||
func hasRoleContext(ctx context.Context) (string, bool) {
|
||||
// prevents panic in case of nil context
|
||||
if ctx == nil {
|
||||
return "", false
|
||||
}
|
||||
role, ok := ctx.Value(roles.ContextKey).(string)
|
||||
// should never happen
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
switch role {
|
||||
case roles.MemberRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||
return role, true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
type superAdminKey string
|
||||
|
||||
// SuperAdminKey is the context key for retrieving is the context
|
||||
|
@ -75,7 +96,10 @@ type Store struct {
|
|||
// and a organization.SourcesStore otherwise.
|
||||
func (s *Store) Sources(ctx context.Context) chronograf.SourcesStore {
|
||||
if org, ok := hasOrganizationContext(ctx); ok {
|
||||
return organizations.NewSourcesStore(s.SourcesStore, org)
|
||||
store := organizations.NewSourcesStore(s.SourcesStore, org)
|
||||
if role, ok := hasRoleContext(ctx); ok {
|
||||
return roles.NewSourcesStore(store, role)
|
||||
}
|
||||
}
|
||||
|
||||
return &noop.SourcesStore{}
|
||||
|
|
|
@ -0,0 +1,372 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
"github.com/influxdata/chronograf/organizations"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
func TestStore_SourcesGet(t *testing.T) {
|
||||
type fields struct {
|
||||
SourcesStore chronograf.SourcesStore
|
||||
}
|
||||
type args struct {
|
||||
organization string
|
||||
role string
|
||||
id int
|
||||
}
|
||||
type wants struct {
|
||||
source chronograf.Source
|
||||
err bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wants wants
|
||||
}{
|
||||
{
|
||||
name: "Get viewer source as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get viewer source as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "editor",
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get viewer source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "admin",
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as editor",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "editor",
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "admin",
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get editor source as viewer",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "editor",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get admin source as admin",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
organization: "0",
|
||||
role: "admin",
|
||||
},
|
||||
wants: wants{
|
||||
source: chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "admin",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "No organization or role set on context",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get source as viewer - no organization specified on context",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "viewer",
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get source as editor - no organization specified on context",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "editor",
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Get source as admin - no organization specified on context",
|
||||
fields: fields{
|
||||
SourcesStore: &mocks.SourcesStore{
|
||||
GetF: func(ctx context.Context, id int) (chronograf.Source, error) {
|
||||
return chronograf.Source{
|
||||
ID: 1,
|
||||
Name: "my sweet name",
|
||||
Organization: "0",
|
||||
Role: "viewer",
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
role: "admin",
|
||||
},
|
||||
wants: wants{
|
||||
err: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
store := &Store{
|
||||
SourcesStore: tt.fields.SourcesStore,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if tt.args.organization != "" {
|
||||
ctx = context.WithValue(ctx, organizations.ContextKey, tt.args.organization)
|
||||
}
|
||||
|
||||
if tt.args.role != "" {
|
||||
ctx = context.WithValue(ctx, roles.ContextKey, tt.args.role)
|
||||
}
|
||||
|
||||
source, err := store.Sources(ctx).Get(ctx, tt.args.id)
|
||||
if (err != nil) != tt.wants.err {
|
||||
t.Errorf("%q. Store.Sources().Get() error = %v, wantErr %v", tt.name, err, tt.wants.err)
|
||||
return
|
||||
}
|
||||
if diff := cmp.Diff(source, tt.wants.source); diff != "" {
|
||||
t.Errorf("%q. Store.Sources().Get():\n-got/+want\ndiff %s", tt.name, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/bouk/httprouter"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
type userRequest struct {
|
||||
|
@ -64,10 +65,10 @@ func (r *userRequest) ValidRoles() error {
|
|||
}
|
||||
orgs[r.Organization] = true
|
||||
switch r.Name {
|
||||
case MemberRoleName, ViewerRoleName, EditorRoleName, AdminRoleName:
|
||||
case roles.MemberRoleName, roles.ViewerRoleName, roles.EditorRoleName, roles.AdminRoleName:
|
||||
continue
|
||||
default:
|
||||
return fmt.Errorf("Unknown role %s. Valid roles are 'viewer', 'editor', 'admin', and 'superadmin'", r.Name)
|
||||
return fmt.Errorf("Unknown role %s. Valid roles are 'member', 'viewer', 'editor', and 'admin'", r.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,37 +126,6 @@ func newUsersResponse(users []chronograf.User) *usersResponse {
|
|||
}
|
||||
}
|
||||
|
||||
// Chronograf User Roles
|
||||
const (
|
||||
MemberRoleName = "member"
|
||||
ViewerRoleName = "viewer"
|
||||
EditorRoleName = "editor"
|
||||
AdminRoleName = "admin"
|
||||
SuperAdminRoleName = "superadmin"
|
||||
)
|
||||
|
||||
var (
|
||||
// MemberRole is the role for a user who can only perform No operations.
|
||||
MemberRole = chronograf.Role{
|
||||
Name: MemberRoleName,
|
||||
}
|
||||
|
||||
// ViewerRole is the role for a user who can only perform READ operations on Dashboards, Rules, and Sources
|
||||
ViewerRole = chronograf.Role{
|
||||
Name: ViewerRoleName,
|
||||
}
|
||||
|
||||
// EditorRole is the role for a user who can perform READ and WRITE operations on Dashboards, Rules, and Sources
|
||||
EditorRole = chronograf.Role{
|
||||
Name: EditorRoleName,
|
||||
}
|
||||
|
||||
// AdminRole is the role for a user who can perform READ and WRITE operations on Dashboards, Rules, Sources, and Users
|
||||
AdminRole = chronograf.Role{
|
||||
Name: AdminRoleName,
|
||||
}
|
||||
)
|
||||
|
||||
// UserID retrieves a Chronograf user with ID from store
|
||||
func (s *Service) UserID(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/log"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
"github.com/influxdata/chronograf/roles"
|
||||
)
|
||||
|
||||
func TestService_UserID(t *testing.T) {
|
||||
|
@ -56,7 +57,7 @@ func TestService_UserID(t *testing.T) {
|
|||
Provider: "google",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
ViewerRole,
|
||||
roles.ViewerRole,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
|
@ -176,11 +177,11 @@ func TestService_NewUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
{
|
||||
Name: ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "billieta org",
|
||||
},
|
||||
},
|
||||
|
@ -197,11 +198,11 @@ func TestService_NewUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
{
|
||||
Name: ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "billieta org",
|
||||
},
|
||||
},
|
||||
|
@ -228,11 +229,11 @@ func TestService_NewUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
{
|
||||
Name: ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
},
|
||||
|
@ -249,11 +250,11 @@ func TestService_NewUser(t *testing.T) {
|
|||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
{
|
||||
Name: ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
},
|
||||
|
@ -502,7 +503,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
|
@ -521,7 +522,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
user: &userRequest{
|
||||
ID: 1336,
|
||||
Roles: []chronograf.Role{
|
||||
AdminRole,
|
||||
roles.AdminRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -547,7 +548,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
|
@ -567,11 +568,11 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
ID: 1336,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
{
|
||||
Name: ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "billieta org",
|
||||
},
|
||||
},
|
||||
|
@ -599,7 +600,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
|
@ -619,11 +620,11 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
ID: 1336,
|
||||
Roles: []chronograf.Role{
|
||||
{
|
||||
Name: AdminRoleName,
|
||||
Name: roles.AdminRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
{
|
||||
Name: ViewerRoleName,
|
||||
Name: roles.ViewerRoleName,
|
||||
Organization: "bobbetta org",
|
||||
},
|
||||
},
|
||||
|
@ -651,7 +652,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
|
@ -672,7 +673,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
ID: 1336,
|
||||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{
|
||||
AdminRole,
|
||||
roles.AdminRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -698,7 +699,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
Provider: "github",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
|
@ -719,7 +720,7 @@ func TestService_UpdateUser(t *testing.T) {
|
|||
ID: 1336,
|
||||
SuperAdmin: true,
|
||||
Roles: []chronograf.Role{
|
||||
AdminRole,
|
||||
roles.AdminRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -804,7 +805,7 @@ func TestService_Users(t *testing.T) {
|
|||
Provider: "google",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -848,7 +849,7 @@ func TestService_Users(t *testing.T) {
|
|||
Provider: "google",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
|
@ -916,7 +917,7 @@ func TestUserRequest_ValidCreate(t *testing.T) {
|
|||
Provider: "auth0",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -931,7 +932,7 @@ func TestUserRequest_ValidCreate(t *testing.T) {
|
|||
Provider: "auth0",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -946,7 +947,7 @@ func TestUserRequest_ValidCreate(t *testing.T) {
|
|||
Name: "billietta",
|
||||
Scheme: "oauth2",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -961,7 +962,7 @@ func TestUserRequest_ValidCreate(t *testing.T) {
|
|||
Name: "billietta",
|
||||
Provider: "auth0",
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -984,7 +985,7 @@ func TestUserRequest_ValidCreate(t *testing.T) {
|
|||
},
|
||||
},
|
||||
wantErr: true,
|
||||
err: fmt.Errorf("Unknown role BilliettaSpecialRole. Valid roles are 'viewer', 'editor', 'admin', and 'superadmin'"),
|
||||
err: fmt.Errorf("Unknown role BilliettaSpecialRole. Valid roles are 'member', 'viewer', 'editor', and 'admin'"),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1021,7 +1022,7 @@ func TestUserRequest_ValidUpdate(t *testing.T) {
|
|||
u: &userRequest{
|
||||
ID: 1337,
|
||||
Roles: []chronograf.Role{
|
||||
EditorRole,
|
||||
roles.EditorRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue