diff --git a/bolt/client.go b/bolt/client.go index 091e43429f..2395e92a58 100644 --- a/bolt/client.go +++ b/bolt/client.go @@ -30,7 +30,7 @@ func NewClient() *Client { c.SourcesStore = &SourcesStore{client: c} c.ServersStore = &ServersStore{client: c} c.UsersStore = &UsersStore{client: c} - c.RolesStore = &RolesStore{client: c} + c.RolesStore = newRolesStore(c.UsersStore) c.LayoutStore = &LayoutStore{ client: c, IDs: &uuid.V4{}, @@ -72,10 +72,6 @@ func (c *Client) Open(ctx context.Context) error { if _, err := tx.CreateBucketIfNotExists(UsersBucket); err != nil { return err } - // Always create Roles bucket. - if _, err := tx.CreateBucketIfNotExists(RolesBucket); err != nil { - return err - } return nil }); err != nil { return err diff --git a/bolt/roles.go b/bolt/roles.go index 93564a21c9..7f950b4836 100644 --- a/bolt/roles.go +++ b/bolt/roles.go @@ -1,6 +1,8 @@ package bolt import ( + "context" + "fmt" "sync" "github.com/influxdata/chronograf" @@ -15,3 +17,43 @@ type RolesStore struct { roles map[string]chronograf.Role usersStore *UsersStore } + +// NewRolesStore returns a *RolesStore populated with the +// default Chonograf User Roles +func newRolesStore(u *UsersStore) *RolesStore { + s := &RolesStore{ + usersStore: u, + roles: map[string]chronograf.Role{}, + } + + for _, role := range chronograf.DefaultUserRoles { + s.roles[role.Name] = role + } + + return s +} + +// All returns all roles and all users associated with each role. +func (s *RolesStore) All(context.Context) ([]chronograf.Role, error) { + panic("not implemented") +} + +// Add returns an error and a nil users. It is not intended to be used currently. +func (s *RolesStore) Add(context.Context, *chronograf.Role) (*chronograf.Role, error) { + return nil, fmt.Errorf("Add not supported for boltdb roles store") +} + +// Delete returns an error. It is not intended to be used currently. +func (s *RolesStore) Delete(context.Context, *chronograf.Role) error { + return fmt.Errorf("Delete not supported for boltdb roles store") +} + +// Get retrieves a role and all users associated with it. +func (s *RolesStore) Get(ctx context.Context, name string) (*chronograf.Role, error) { + panic("not implemented") +} + +// Update returns an error. It is not intended to be used currently. +func (s *RolesStore) Update(context.Context, *chronograf.Role) error { + return fmt.Errorf("Update not supported for boltdb roles store") +} diff --git a/bolt/roles_test.go b/bolt/roles_test.go deleted file mode 100644 index fe9bb17651..0000000000 --- a/bolt/roles_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package bolt_test - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/influxdata/chronograf" -) - -func TestRolesStore_Get(t *testing.T) { - type args struct { - ctx context.Context - name string - } - tests := []struct { - name string - args args - want *chronograf.Role - wantErr bool - }{ - { - name: "Role not found", - args: args{ - ctx: context.Background(), - name: "unknown", - }, - wantErr: true, - }, - } - for _, tt := range tests { - client, err := NewTestClient() - if err != nil { - t.Fatal(err) - } - if err := client.Open(context.TODO()); err != nil { - t.Fatal(err) - } - defer client.Close() - - s := client.RolesStore - got, err := s.Get(tt.args.ctx, tt.args.name) - if (err != nil) != tt.wantErr { - t.Errorf("%q. RolesStore.Get() error = %v, wantErr %v", tt.name, err, tt.wantErr) - continue - } - if !cmp.Equal(got, tt.want) { - t.Errorf("%q. RolesStore.Get() = %v, want %v", tt.name, got, tt.want) - } - } -} diff --git a/chronograf.go b/chronograf.go index d912929a59..6fc7d2183a 100644 --- a/chronograf.go +++ b/chronograf.go @@ -18,6 +18,96 @@ import ( "github.com/influxdata/influxdb/influxql" ) +// Chronograf User Roles +const ( + ViewerRole = "Viewer" + EditorRole = "Editor" + AdminRole = "Admin" +) + +// Chronograf User Permissions +var ( + // Read Permissions + ReadDashboardsPermission = Permission{ + Scope: "dashboards", + Name: "Read Dashboards", + Allowed: Allowances{"read"}, + } + ReadSourcesPermission = Permission{ + Scope: "sources", + Name: "Read Sources", + Allowed: Allowances{"read"}, + } + ReadRulesPermission = Permission{ + Scope: "rules", + Name: "Read Rules", + Allowed: Allowances{"read"}, + } + ReadUsersPermission = Permission{ + Scope: "users", + Name: "Read Users", + Allowed: Allowances{"read"}, + } + + // Write Permissions + WriteDashboardsPermission = Permission{ + Scope: "dashboards", + Name: "Write Dashboards", + Allowed: Allowances{"write"}, + } + WriteSourcesPermission = Permission{ + Scope: "sources", + Name: "Write Sources", + Allowed: Allowances{"write"}, + } + WriteRulesPermission = Permission{ + Scope: "rules", + Name: "Write Rules", + Allowed: Allowances{"write"}, + } + WriteUsersPermission = Permission{ + Scope: "users", + Name: "Write Users", + Allowed: Allowances{"write"}, + } +) + +// Default roles for chronograf Users +var DefaultUserRoles = [5]Role{ + { + Name: ViewerRole, + Permissions: Permissions{ + ReadDashboardsPermission, + ReadSourcesPermission, + ReadRulesPermission, + }, + }, + { + Name: EditorRole, + Permissions: Permissions{ + ReadDashboardsPermission, + ReadSourcesPermission, + ReadRulesPermission, + WriteDashboardsPermission, + WriteSourcesPermission, + WriteRulesPermission, + }, + }, + { + Name: AdminRole, + Permissions: Permissions{ + ReadDashboardsPermission, + ReadSourcesPermission, + ReadRulesPermission, + ReadUsersPermission, + WriteDashboardsPermission, + WriteSourcesPermission, + WriteRulesPermission, + WriteUsersPermission, + }, + }, +} + // General errors. const ( ErrUpstreamTimeout = Error("request to backend timed out")