2017-10-31 20:41:17 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/influxdata/chronograf"
|
2017-10-31 22:07:42 +00:00
|
|
|
"github.com/influxdata/chronograf/noop"
|
2017-10-31 20:41:17 +00:00
|
|
|
"github.com/influxdata/chronograf/organizations"
|
|
|
|
)
|
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// hasOrganizationContext retrieves organization specified on context
|
|
|
|
// under the organizations.ContextKey
|
2017-10-31 21:40:58 +00:00
|
|
|
func hasOrganizationContext(ctx context.Context) (string, bool) {
|
|
|
|
// prevents panic in case of nil context
|
|
|
|
if ctx == nil {
|
|
|
|
return "", false
|
|
|
|
}
|
2017-11-01 13:49:02 +00:00
|
|
|
orgID, ok := ctx.Value(organizations.ContextKey).(string)
|
2017-10-31 21:40:58 +00:00
|
|
|
// should never happen
|
|
|
|
if !ok {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
if orgID == "" {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
return orgID, true
|
|
|
|
}
|
|
|
|
|
2017-11-01 13:49:02 +00:00
|
|
|
type superAdminKey string
|
|
|
|
|
2017-11-01 20:43:31 +00:00
|
|
|
// SuperAdminKey is the context key for retrieving is the context
|
|
|
|
// is for a super admin
|
2017-11-01 13:49:02 +00:00
|
|
|
const SuperAdminKey = superAdminKey("superadmin")
|
2017-10-31 21:49:35 +00:00
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// hasSuperAdminContext speficies if the context contains
|
|
|
|
// the SuperAdminKey and that the value stored there is true
|
2017-11-01 14:39:09 +00:00
|
|
|
func hasSuperAdminContext(ctx context.Context) bool {
|
2017-10-31 21:49:35 +00:00
|
|
|
// prevents panic in case of nil context
|
|
|
|
if ctx == nil {
|
2017-11-01 14:39:09 +00:00
|
|
|
return false
|
2017-10-31 21:49:35 +00:00
|
|
|
}
|
2017-11-01 13:49:02 +00:00
|
|
|
sa, ok := ctx.Value(SuperAdminKey).(bool)
|
2017-10-31 21:49:35 +00:00
|
|
|
// should never happen
|
|
|
|
if !ok {
|
2017-11-01 14:39:09 +00:00
|
|
|
return false
|
2017-10-31 21:49:35 +00:00
|
|
|
}
|
2017-11-01 14:39:09 +00:00
|
|
|
return sa
|
2017-10-31 21:49:35 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 20:43:31 +00:00
|
|
|
// DataStore is collection of resources that are used by the Service
|
2017-11-01 18:24:40 +00:00
|
|
|
// Abstracting this into an interface was useful for isolated testing
|
2017-10-31 20:41:17 +00:00
|
|
|
type DataStore interface {
|
|
|
|
Sources(ctx context.Context) chronograf.SourcesStore
|
|
|
|
Servers(ctx context.Context) chronograf.ServersStore
|
|
|
|
Layouts(ctx context.Context) chronograf.LayoutsStore
|
|
|
|
Users(ctx context.Context) chronograf.UsersStore
|
|
|
|
Organizations(ctx context.Context) chronograf.OrganizationsStore
|
|
|
|
Dashboards(ctx context.Context) chronograf.DashboardsStore
|
|
|
|
}
|
|
|
|
|
|
|
|
// ensure that Store implements a DataStore
|
|
|
|
var _ DataStore = &Store{}
|
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// Store implements the DataStore interface
|
2017-10-31 20:41:17 +00:00
|
|
|
type Store struct {
|
|
|
|
SourcesStore chronograf.SourcesStore
|
|
|
|
ServersStore chronograf.ServersStore
|
|
|
|
LayoutsStore chronograf.LayoutsStore
|
|
|
|
UsersStore chronograf.UsersStore
|
|
|
|
DashboardsStore chronograf.DashboardsStore
|
|
|
|
OrganizationsStore chronograf.OrganizationsStore
|
|
|
|
}
|
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// Sources returns a noop.SourcesStore if the context has no organization specified
|
|
|
|
// and a organization.SourcesStore otherwise.
|
2017-10-31 20:41:17 +00:00
|
|
|
func (s *Store) Sources(ctx context.Context) chronograf.SourcesStore {
|
2017-10-31 21:40:58 +00:00
|
|
|
if org, ok := hasOrganizationContext(ctx); ok {
|
|
|
|
return organizations.NewSourcesStore(s.SourcesStore, org)
|
|
|
|
}
|
|
|
|
|
2017-10-31 22:07:42 +00:00
|
|
|
return &noop.SourcesStore{}
|
2017-10-31 20:41:17 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// Servers returns a noop.ServersStore if the context has no organization specified
|
|
|
|
// and a organization.ServersStore otherwise.
|
2017-10-31 20:41:17 +00:00
|
|
|
func (s *Store) Servers(ctx context.Context) chronograf.ServersStore {
|
2017-10-31 21:40:58 +00:00
|
|
|
if org, ok := hasOrganizationContext(ctx); ok {
|
|
|
|
return organizations.NewServersStore(s.ServersStore, org)
|
|
|
|
}
|
|
|
|
|
2017-10-31 22:07:42 +00:00
|
|
|
return &noop.ServersStore{}
|
2017-10-31 20:41:17 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// Layouts returns a noop.LayoutsStore if the context has no organization specified
|
|
|
|
// and a organization.LayoutsStore otherwise.
|
2017-10-31 20:41:17 +00:00
|
|
|
func (s *Store) Layouts(ctx context.Context) chronograf.LayoutsStore {
|
2017-10-31 21:40:58 +00:00
|
|
|
if org, ok := hasOrganizationContext(ctx); ok {
|
|
|
|
return organizations.NewLayoutsStore(s.LayoutsStore, org)
|
|
|
|
}
|
|
|
|
|
2017-10-31 22:07:42 +00:00
|
|
|
return &noop.LayoutsStore{}
|
2017-10-31 20:41:17 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// Users returns a chronograf.UsersStore.
|
|
|
|
// If the context is a super admin context, then the underlying chronograf.UsersStore
|
|
|
|
// is returned.
|
|
|
|
// If there is an organization specified on context, then an organizations.UsersStore
|
|
|
|
// is returned.
|
|
|
|
// If niether are specified, a noop.UsersStore is returned.
|
2017-10-31 20:41:17 +00:00
|
|
|
func (s *Store) Users(ctx context.Context) chronograf.UsersStore {
|
2017-11-01 14:39:09 +00:00
|
|
|
if superAdmin := hasSuperAdminContext(ctx); superAdmin {
|
2017-10-31 21:49:35 +00:00
|
|
|
return s.UsersStore
|
|
|
|
}
|
2017-10-31 21:40:58 +00:00
|
|
|
if org, ok := hasOrganizationContext(ctx); ok {
|
|
|
|
return organizations.NewUsersStore(s.UsersStore, org)
|
|
|
|
}
|
|
|
|
|
2017-10-31 22:07:42 +00:00
|
|
|
return &noop.UsersStore{}
|
2017-10-31 21:40:58 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 18:24:40 +00:00
|
|
|
// Dashboards returns a noop.DashboardsStore if the context has no organization specified
|
|
|
|
// and a organization.DashboardsStore otherwise.
|
2017-10-31 21:40:58 +00:00
|
|
|
func (s *Store) Dashboards(ctx context.Context) chronograf.DashboardsStore {
|
|
|
|
if org, ok := hasOrganizationContext(ctx); ok {
|
|
|
|
return organizations.NewDashboardsStore(s.DashboardsStore, org)
|
|
|
|
}
|
|
|
|
|
2017-10-31 22:07:42 +00:00
|
|
|
return &noop.DashboardsStore{}
|
2017-10-31 20:41:17 +00:00
|
|
|
}
|
|
|
|
|
2017-11-01 20:43:31 +00:00
|
|
|
// Organizations returns the underlying OrganizationsStore.
|
2017-10-31 20:41:17 +00:00
|
|
|
func (s *Store) Organizations(ctx context.Context) chronograf.OrganizationsStore {
|
|
|
|
return s.OrganizationsStore
|
|
|
|
}
|