Skip to content

Commit

Permalink
cluster/http: use params for tenantID
Browse files Browse the repository at this point in the history
  • Loading branch information
gernest committed Feb 26, 2024
1 parent fe4f9ad commit d6412be
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 33 deletions.
31 changes: 15 additions & 16 deletions internal/cluster/http/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package http

import (
"context"
"net/url"
"strings"
"time"

Expand All @@ -18,8 +17,8 @@ import (
// is returned back to the client.
var InternalError = status.Error(codes.Internal, "Something went wrong")

func PeriodToRange(ctx context.Context, now func() time.Time, period *v1.TimePeriod, query url.Values) (start, end time.Time) {
date := parseDate(ctx, query, now)
func (p QueryParams) PeriodToRange(ctx context.Context, now func() time.Time, period *v1.TimePeriod) (start, end time.Time) {
date := p.parseDate(ctx, now)
switch e := period.Value.(type) {
case *v1.TimePeriod_Base_:
switch e.Base {
Expand Down Expand Up @@ -76,8 +75,8 @@ func ValidByPeriod(period *v1.TimePeriod, i v1.Interval) bool {
}
}

func ParsePeriod(ctx context.Context, query url.Values) *v1.TimePeriod {
value := query.Get("period")
func (p QueryParams) Period(ctx context.Context) *v1.TimePeriod {
value := p["period"]
switch value {
case "12mo":
return &v1.TimePeriod{Value: &v1.TimePeriod_Base_{Base: v1.TimePeriod__12mo}}
Expand All @@ -92,7 +91,7 @@ func ParsePeriod(ctx context.Context, query url.Values) *v1.TimePeriod {
case "day":
return &v1.TimePeriod{Value: &v1.TimePeriod_Base_{Base: v1.TimePeriod_day}}
case "custom":
date := query.Get("date")
date := p["date"]
if date == "" {
logger.Get(ctx).Error("custom period specified with missing date")
return nil
Expand Down Expand Up @@ -124,8 +123,8 @@ func ParsePeriod(ctx context.Context, query url.Values) *v1.TimePeriod {
}
}

func parseDate(ctx context.Context, query url.Values, now func() time.Time) time.Time {
date := query.Get("date")
func (p QueryParams) parseDate(ctx context.Context, now func() time.Time) time.Time {
date := p["date"]
if date == "" {
return timeutil.EndDay(now())
}
Expand All @@ -139,8 +138,8 @@ func parseDate(ctx context.Context, query url.Values, now func() time.Time) time
return v
}

func ParseMetrics(ctx context.Context, query url.Values) (o []v1.Metric) {
metrics := query.Get("metrics")
func (p QueryParams) Metrics(ctx context.Context) (o []v1.Metric) {
metrics := p["metrics"]
if metrics == "" {
return []v1.Metric{v1.Metric_visitors}
}
Expand All @@ -155,8 +154,8 @@ func ParseMetrics(ctx context.Context, query url.Values) (o []v1.Metric) {
return
}

func ParseProperty(ctx context.Context, query url.Values) (o []v1.Property) {
props := query.Get("property")
func (p QueryParams) Property(ctx context.Context) (o []v1.Property) {
props := p["property"]
for _, m := range strings.Split(props, ",") {
v, ok := v1.Property_value[m]
if !ok {
Expand All @@ -168,8 +167,8 @@ func ParseProperty(ctx context.Context, query url.Values) (o []v1.Property) {
return
}

func ParseInterval(ctx context.Context, query url.Values) v1.Interval {
i := query.Get("interval")
func (p QueryParams) Interval(ctx context.Context) v1.Interval {
i := p["interval"]
if i == "" {
return v1.Interval_date
}
Expand All @@ -182,8 +181,8 @@ func ParseInterval(ctx context.Context, query url.Values) v1.Interval {
return v1.Interval(v)
}

func ParseFilters(ctx context.Context, query url.Values) (o []*v1.Filter) {
fs := query.Get("filters")
func (p QueryParams) Filters(ctx context.Context) (o []*v1.Filter) {
fs := p["filters"]
if fs == "" {
return
}
Expand Down
59 changes: 42 additions & 17 deletions internal/cluster/http/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/vinceanalytics/vince/internal/cluster/rtls"
"github.com/vinceanalytics/vince/internal/cluster/store"
"github.com/vinceanalytics/vince/internal/defaults"
"github.com/vinceanalytics/vince/internal/guard"
"github.com/vinceanalytics/vince/internal/tenant"
"github.com/vinceanalytics/vince/version"
"google.golang.org/protobuf/encoding/protojson"
Expand Down Expand Up @@ -134,6 +135,8 @@ type Service struct {

store Store
cluster Cluster
guard guard.Guard
tenants tenant.Loader

AllowOrigin string // Value to set for Access-Control-Allow-Origin

Expand All @@ -155,11 +158,13 @@ type Service struct {

// New returns an uninitialized HTTP service. If credentials is nil, then
// the service performs no authentication and authorization checks.
func New(addr string, store Store, cluster Cluster, credentials CredentialStore) *Service {
func New(addr string, store Store, cluster Cluster, credentials CredentialStore, guard guard.Guard, tenants tenant.Loader) *Service {
return &Service{
addr: addr,
store: store,
cluster: cluster,
guard: guard,
tenants: tenants,
start: time.Now(),
creds: credentials,
log: slog.Default().With("component", "http-service"),
Expand Down Expand Up @@ -246,6 +251,26 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v1/") {
if !s.guard.Allow() {
w.WriteHeader(http.StatusTooManyRequests)
return
}
if !s.guard.Accept(params.SiteID()) {
w.WriteHeader(http.StatusUnauthorized)
return
}
// Make sure tenant is in the params
tenantId := params.TenantID()
if tenantId == "" {
tenantId = s.tenants.TenantBySiteID(r.Context(), params.SiteID())
}
if tenantId == "" {
w.WriteHeader(http.StatusUnauthorized)
return
}
params["tenant_id"] = tenantId
}
switch {
case r.URL.Path == "/" || r.URL.Path == "":
http.Redirect(w, r, "/status", http.StatusFound)
Expand Down Expand Up @@ -294,7 +319,7 @@ func (s *Service) handleRealtime(w http.ResponseWriter, r *http.Request, params
ctx := r.Context()
req := &v1.Realtime_Request{
SiteId: params.SiteID(),
TenantId: tenant.Get(ctx),
TenantId: params.TenantID(),
}
defaults.Set(req)
res, err := s.store.Realtime(ctx, req)
Expand Down Expand Up @@ -361,12 +386,12 @@ func (s *Service) handleAggregate(w http.ResponseWriter, r *http.Request, params
return
}
ctx := r.Context()
query := r.URL.Query()
req := &v1.Aggregate_Request{
SiteId: params.SiteID(),
Period: ParsePeriod(ctx, query),
Metrics: ParseMetrics(ctx, query),
Filters: ParseFilters(ctx, query),
SiteId: params.SiteID(),
TenantId: params.TenantID(),
Period: params.Period(ctx),
Metrics: params.Metrics(ctx),
Filters: params.Filters(ctx),
}
defaults.Set(req)
res, err := s.store.Aggregate(ctx, req)
Expand Down Expand Up @@ -424,13 +449,13 @@ func (s *Service) handleTimeseries(w http.ResponseWriter, r *http.Request, param
return
}
ctx := r.Context()
query := r.URL.Query()
req := &v1.Timeseries_Request{
SiteId: params.SiteID(),
Period: ParsePeriod(ctx, query),
Metrics: ParseMetrics(ctx, query),
Interval: ParseInterval(ctx, query),
Filters: ParseFilters(ctx, query),
TenantId: params.TenantID(),
Period: params.Period(ctx),
Metrics: params.Metrics(ctx),
Interval: params.Interval(ctx),
Filters: params.Filters(ctx),
}
defaults.Set(req)
res, err := s.store.Timeseries(ctx, req)
Expand Down Expand Up @@ -488,13 +513,13 @@ func (s *Service) handleBreakdown(w http.ResponseWriter, r *http.Request, params
return
}
ctx := r.Context()
query := r.URL.Query()
req := &v1.BreakDown_Request{
SiteId: params.SiteID(),
Period: ParsePeriod(ctx, query),
Metrics: ParseMetrics(ctx, query),
Filters: ParseFilters(ctx, query),
Property: ParseProperty(ctx, query),
TenantId: params.TenantID(),
Period: params.Period(ctx),
Metrics: params.Metrics(ctx),
Filters: params.Filters(ctx),
Property: params.Property(ctx),
}
defaults.Set(req)
res, err := s.store.Breakdown(ctx, req)
Expand Down
4 changes: 4 additions & 0 deletions internal/tenant/tenants.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (

const Default = "staples"

type Loader interface {
TenantBySiteID(ctx context.Context, siteId string) (tenantId string)
}

func Config(o *v1.Config, domains []string) *v1.Config {
t := &v1.Tenant{
Id: Default,
Expand Down

0 comments on commit d6412be

Please sign in to comment.