Skip to content
Open
2 changes: 2 additions & 0 deletions auth/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var _ = Describe("Client", func() {
Expect(config).ToNot(BeNil())
Expect(config.Config).ToNot(BeNil())
config.Config.Address = testHttp.NewAddress()
config.ExternalConfig.PathPrefix = "auth"
config.Config.UserAgent = testHttp.NewUserAgent()
config.Config.ServiceSecret = authTest.NewServiceSecret()
config.ExternalConfig.Address = testHttp.NewAddress()
Expand Down Expand Up @@ -112,6 +113,7 @@ var _ = Describe("Client", func() {
Expect(config).ToNot(BeNil())
Expect(config.Config).ToNot(BeNil())
config.Config.Address = server.URL()
config.ExternalConfig.PathPrefix = "auth"
config.Config.UserAgent = testHttp.NewUserAgent()
config.Config.ServiceSecret = authTest.NewServiceSecret()
config.ExternalConfig.Address = server.URL()
Expand Down
9 changes: 7 additions & 2 deletions auth/client/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ type ExternalConfig struct {
*platform.Config
ServerSessionTokenSecret string
ServerSessionTokenTimeout time.Duration
// PathPrefix is the prefix to include in all calls to the external service, if any.
PathPrefix string
}

func NewExternalConfig() *ExternalConfig {
Expand All @@ -83,6 +85,7 @@ func (e *ExternalConfig) Load(configReporter config.Reporter) error {
}
e.ServerSessionTokenTimeout = time.Duration(serverSessionTokenTimeoutInteger) * time.Second
}
e.PathPrefix = configReporter.GetWithDefault("path_prefix", "auth")

return nil
}
Expand Down Expand Up @@ -110,6 +113,7 @@ type External struct {
serverSessionTokenTimeout time.Duration
serverSessionTokenMutex sync.Mutex
serverSessionTokenSafe string
pathPrefix string
closingChannel chan chan bool
}

Expand Down Expand Up @@ -139,6 +143,7 @@ func NewExternal(cfg *ExternalConfig, authorizeAs platform.AuthorizeAs, name str
name: name,
serverSessionTokenSecret: cfg.ServerSessionTokenSecret,
serverSessionTokenTimeout: cfg.ServerSessionTokenTimeout,
pathPrefix: cfg.PathPrefix,
}, nil
}

Expand Down Expand Up @@ -204,7 +209,7 @@ func (e *External) ValidateSessionToken(ctx context.Context, token string) (requ
IsServer bool
UserID string
}
if err := e.client.RequestData(ctx, "GET", e.client.ConstructURL("auth", "token", token), nil, nil, &result); err != nil {
if err := e.client.RequestData(ctx, "GET", e.client.ConstructURL(e.pathPrefix, "token", token), nil, nil, &result); err != nil {
return nil, err
}

Expand Down Expand Up @@ -305,7 +310,7 @@ func (e *External) refreshServerSessionToken() error {
e.logger.Debug("Refreshing server session token")

requestMethod := "POST"
requestURL := e.client.ConstructURL("auth", "serverlogin")
requestURL := e.client.ConstructURL(e.pathPrefix, "serverlogin")
request, err := http.NewRequest(requestMethod, requestURL, nil)
if err != nil {
return errors.Wrapf(err, "unable to create new request for %s %s", requestMethod, requestURL)
Expand Down
19 changes: 13 additions & 6 deletions auth/service/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (s *Service) Initialize(provider application.Provider) error {
if err := s.initializeDeviceCheck(); err != nil {
return err
}
return s.initializeUserEventsHandler()
return s.initializeUserEventsHandler(provider)
}

func (s *Service) Terminate() {
Expand Down Expand Up @@ -394,13 +394,20 @@ func (s *Service) terminateAuthClient() {
}
}

func (s *Service) initializeUserEventsHandler() error {
func (s *Service) initializeUserEventsHandler(provider application.Provider) error {
s.Logger().Debug("Initializing user events handler")

ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger())
handler := authEvents.NewUserDataDeletionHandler(ctx, s.authClient)
handlers := []eventsCommon.EventHandler{handler}
runner := events.NewRunner(handlers)
var runner events.Runner

configReporter := provider.ConfigReporter().WithScopes("user", "events", "handler")
if configReporter.GetWithDefault("disable", "") != "true" {
ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger())
handler := authEvents.NewUserDataDeletionHandler(ctx, s.authClient)
handlers := []eventsCommon.EventHandler{handler}
runner = events.NewRunner(handlers)
} else {
runner = events.NewNoopRunner()
}

if err := runner.Initialize(); err != nil {
return errors.Wrap(err, "unable to initialize events runner")
Expand Down
19 changes: 13 additions & 6 deletions blob/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (s *Service) Initialize(provider application.Provider) error {
if err := s.initializeBlobClient(); err != nil {
return err
}
if err := s.initializeUserEventsHandler(); err != nil {
if err := s.initializeUserEventsHandler(provider); err != nil {
return err
}
return s.initializeRouter()
Expand Down Expand Up @@ -174,13 +174,20 @@ func (s *Service) terminateBlobUnstructuredStore() {
}
}

func (s *Service) initializeUserEventsHandler() error {
func (s *Service) initializeUserEventsHandler(provider application.Provider) error {
s.Logger().Debug("Initializing user events handler")

ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger())
handler := blobEvents.NewUserDataDeletionHandler(ctx, s.blobClient)
handlers := []eventsCommon.EventHandler{handler}
runner := events.NewRunner(handlers)
var runner events.Runner

configReporter := provider.ConfigReporter().WithScopes("user", "events", "handler")
if configReporter.GetWithDefault("disable", "") != "true" {
ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger())
handler := blobEvents.NewUserDataDeletionHandler(ctx, s.blobClient)
handlers := []eventsCommon.EventHandler{handler}
runner = events.NewRunner(handlers)
} else {
runner = events.NewNoopRunner()
}

if err := runner.Initialize(); err != nil {
return errors.Wrap(err, "unable to initialize events runner")
Expand Down
6 changes: 5 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ func New(cfg *Config) (*Client, error) {
func (c *Client) ConstructURL(paths ...string) string {
segments := []string{}
for _, path := range paths {
segments = append(segments, url.PathEscape(strings.Trim(path, "/")))
escapedPath := url.PathEscape(strings.Trim(path, "/"))
if escapedPath == "" {
continue
}
segments = append(segments, escapedPath)
}
return fmt.Sprintf("%s/%s", strings.TrimRight(c.address, "/"), strings.Join(segments, "/"))
}
Expand Down
3 changes: 2 additions & 1 deletion client/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

import (
"fmt"
"net/url"
"time"

Expand Down Expand Up @@ -33,7 +34,7 @@ func (c *Config) Validate() error {
if c.Address == "" {
return errors.New("address is missing")
} else if _, err := url.Parse(c.Address); err != nil {
return errors.New("address is invalid")
return fmt.Errorf("address is invalid: %w", err)
}
if c.UserAgent == "" {
return errors.New("user agent is missing")
Expand Down
2 changes: 1 addition & 1 deletion client/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ var _ = Describe("Config", func() {

It("returns an error if the address is not a parseable URL", func() {
cfg.Address = "Not%Parseable"
Expect(cfg.Validate()).To(MatchError("address is invalid"))
Expect(cfg.Validate()).To(MatchError("address is invalid: parse \"Not%Parseable\": invalid URL escape \"%Pa\""))
})

It("returns an error if the user agent is missing", func() {
Expand Down
20 changes: 14 additions & 6 deletions data/service/service/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (s *Standard) Initialize(provider application.Provider) error {
if err := s.initializeDataSourceClient(); err != nil {
return err
}
if err := s.initializeUserEventsHandler(); err != nil {
if err := s.initializeUserEventsHandler(provider); err != nil {
return err
}
if err := s.initializeAPI(); err != nil {
Expand Down Expand Up @@ -382,14 +382,22 @@ func (s *Standard) initializeServer() error {
return nil
}

func (s *Standard) initializeUserEventsHandler() error {
func (s *Standard) initializeUserEventsHandler(provider application.Provider) error {
s.Logger().Debug("Initializing user events handler")
sarama.Logger = log.New(os.Stdout, "SARAMA ", log.LstdFlags|log.Lshortfile)

ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger())
handler := dataEvents.NewUserDataDeletionHandler(ctx, s.dataStore, s.dataSourceStructuredStore)
handlers := []eventsCommon.EventHandler{handler}
runner := events.NewRunner(handlers)
var runner events.Runner

configReporter := provider.ConfigReporter().WithScopes("user", "events", "handler")
if configReporter.GetWithDefault("disable", "") != "true" {
ctx := logInternal.NewContextWithLogger(context.Background(), s.Logger())
handler := dataEvents.NewUserDataDeletionHandler(ctx, s.dataStore, s.dataSourceStructuredStore)
handlers := []eventsCommon.EventHandler{handler}
runner = events.NewRunner(handlers)
} else {
runner = events.NewNoopRunner()
}

if err := runner.Initialize(); err != nil {
return errors.Wrap(err, "unable to initialize user events handler runner")
}
Expand Down
1 change: 1 addition & 0 deletions env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export TIDEPOOL_PERMISSION_CLIENT_ADDRESS="http://localhost:8009"
export TIDEPOOL_TASK_CLIENT_ADDRESS="http://localhost:8009"
export TIDEPOOL_USER_CLIENT_ADDRESS="http://localhost:8009"

export TIDEPOOL_AUTH_CLIENT_EXTERNAL_PATH_PREFIX="auth"
export TIDEPOOL_AUTH_CLIENT_EXTERNAL_ADDRESS="http://localhost:8009"
export TIDEPOOL_AUTH_CLIENT_EXTERNAL_SERVER_SESSION_TOKEN_SECRET="This needs to be the same secret everywhere. YaHut75NsK1f9UKUXuWqxNN0RUwHFBCy"

Expand Down
25 changes: 25 additions & 0 deletions events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,28 @@ func (r *runner) Terminate() error {
}
return nil
}

type noopRunner struct {
terminate chan struct{}
}

func (n *noopRunner) Initialize() error {
n.terminate = make(chan struct{}, 0)
return nil
}

func (n *noopRunner) Run() error {
<-n.terminate
return nil
}

func (n *noopRunner) Terminate() error {
n.terminate <- struct{}{}
return nil
}

var _ Runner = &noopRunner{}

func NewNoopRunner() Runner {
return &noopRunner{}
}
2 changes: 1 addition & 1 deletion platform/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ var _ = Describe("Config", func() {

It("returns an error if the address is not a parseable URL", func() {
cfg.Address = "Not%Parseable"
Expect(cfg.Validate()).To(MatchError("address is invalid"))
Expect(cfg.Validate()).To(MatchError("address is invalid: parse \"Not%Parseable\": invalid URL escape \"%Pa\""))
})

It("returns an error if the user agent is missing", func() {
Expand Down
19 changes: 10 additions & 9 deletions store/structured/mongo/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ func LoadConfig() (*Config, error) {

// Config describe parameters need to make a connection to a Mongo database
type Config struct {
Scheme string `json:"scheme" envconfig:"TIDEPOOL_STORE_SCHEME"`
Addresses []string `json:"addresses" envconfig:"TIDEPOOL_STORE_ADDRESSES" required:"true"`
TLS bool `json:"tls" envconfig:"TIDEPOOL_STORE_TLS" default:"true"`
Database string `json:"database" envconfig:"TIDEPOOL_STORE_DATABASE" required:"true"`
CollectionPrefix string `json:"collectionPrefix" envconfig:"TIDEPOOL_STORE_COLLECTION_PREFIX"`
Username *string `json:"-" envconfig:"TIDEPOOL_STORE_USERNAME"`
Password *string `json:"-" envconfig:"TIDEPOOL_STORE_PASSWORD"`
Timeout time.Duration `json:"timeout" envconfig:"TIDEPOOL_STORE_TIMEOUT" default:"60s"`
OptParams *string `json:"optParams" envconfig:"TIDEPOOL_STORE_OPT_PARAMS"`
Scheme string `json:"scheme" envconfig:"TIDEPOOL_STORE_SCHEME"`
Addresses []string `json:"addresses" envconfig:"TIDEPOOL_STORE_ADDRESSES" required:"true"`
TLS bool `json:"tls" envconfig:"TIDEPOOL_STORE_TLS" default:"true"`
Database string `json:"database" envconfig:"TIDEPOOL_STORE_DATABASE" required:"true"`
CollectionPrefix string `json:"collectionPrefix" envconfig:"TIDEPOOL_STORE_COLLECTION_PREFIX"`
Username *string `json:"-" envconfig:"TIDEPOOL_STORE_USERNAME"`
Password *string `json:"-" envconfig:"TIDEPOOL_STORE_PASSWORD"`
Timeout time.Duration `json:"timeout" envconfig:"TIDEPOOL_STORE_TIMEOUT" default:"60s"`
OptParams *string `json:"optParams" envconfig:"TIDEPOOL_STORE_OPT_PARAMS"`
DisableIndexCreation bool `json:"disableIndexCreation" envconfig:"TIDEPOOL_DISABLE_INDEX_CREATION"`
}

// AsConnectionString constructs a MongoDB connection string from a Config
Expand Down
12 changes: 11 additions & 1 deletion store/structured/mongo/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,25 @@ import (

type Repository struct {
*mongo.Collection
config RepositoryConfig
}

func NewRepository(collection *mongo.Collection) *Repository {
type RepositoryConfig struct {
DisableIndexCreation bool
}

func NewRepository(collection *mongo.Collection, config RepositoryConfig) *Repository {
return &Repository{
collection,
config,
}
}

func (r *Repository) CreateAllIndexes(ctx context.Context, indexes []mongo.IndexModel) error {
if r.config.DisableIndexCreation {
return nil
}

if ctx == nil {
ctx = context.Background()
}
Expand Down
5 changes: 4 additions & 1 deletion store/structured/mongo/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ func AppendLifecycleHooksToStore(store *Store, lifecycle fx.Lifecycle) {
}

func (o *Store) GetRepository(collection string) *Repository {
return NewRepository(o.GetCollection(collection))
config := RepositoryConfig{
DisableIndexCreation: o.config.DisableIndexCreation,
}
return NewRepository(o.GetCollection(collection), config)
}

func (o *Store) GetCollection(collection string) *mongoDriver.Collection {
Expand Down