diff --git a/go.mod b/go.mod index 2d80106..fedeb7a 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/dustin/go-humanize v1.0.0 github.com/go-co-op/gocron v1.9.0 + github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/go-redis/redis/v8 v8.11.4 github.com/gorilla/mux v1.8.0 github.com/heroku/x v0.0.32 diff --git a/go.sum b/go.sum index 9556f7d..a6898e4 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-proxyproto v0.0.0-20190211145416-68259f75880e/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/aws/aws-sdk-go v1.13.10/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= github.com/axiomhq/hyperloglog v0.0.0-20180317131949-fe9507de0228/go.mod h1:IOXAcuKIFq/mDyuQ4wyJuJ79XLMsmLM+5RdQ+vWrL7o= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -120,6 +122,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= +github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= github.com/go-redis/redis/v8 v8.3.2/go.mod h1:jszGxBCez8QA1HWSmQxJO9Y82kNibbUmeYhKWrBejTU= github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= diff --git a/internal/cmd/worker.go b/internal/cmd/worker.go index beb1b55..907e3f8 100644 --- a/internal/cmd/worker.go +++ b/internal/cmd/worker.go @@ -35,7 +35,8 @@ func WorkerCmd(ctx context.Context) *cobra.Command { logger := cmdutil.NewLogrusLogger(false) - statsd, err := cmdutil.NewStatsdClient() + tag := fmt.Sprintf("worker:%s", queueID) + statsd, err := cmdutil.NewStatsdClient(tag) if err != nil { return err } diff --git a/internal/domain/account.go b/internal/domain/account.go index bf74b98..5aef7bb 100644 --- a/internal/domain/account.go +++ b/internal/domain/account.go @@ -3,6 +3,8 @@ package domain import ( "context" "strings" + + validation "github.com/go-ozzo/ozzo-validation/v4" ) // Account represents an account we need to periodically check in the notifications worker. @@ -25,6 +27,13 @@ func (acct *Account) NormalizedUsername() string { return strings.ToLower(acct.Username) } +func (acct *Account) Validate() error { + return validation.ValidateStruct(acct, + validation.Field(&acct.Username, validation.Required, validation.Length(3, 32)), + validation.Field(&acct.AccountID, validation.Required, validation.Length(5, 7)), + ) +} + // AccountRepository represents the account's repository contract type AccountRepository interface { GetByID(ctx context.Context, id int64) (Account, error) diff --git a/internal/domain/device.go b/internal/domain/device.go index d7fbc74..d7f2e11 100644 --- a/internal/domain/device.go +++ b/internal/domain/device.go @@ -1,6 +1,10 @@ package domain -import "context" +import ( + "context" + + validation "github.com/go-ozzo/ozzo-validation/v4" +) const ( DeviceGracePeriodDuration = 3600 // 1 hour @@ -14,6 +18,12 @@ type Device struct { ActiveUntil int64 } +func (dev *Device) Validate() error { + return validation.ValidateStruct(dev, + validation.Field(&dev.APNSToken, validation.Required, validation.Length(64, 200)), + ) +} + type DeviceRepository interface { GetByID(ctx context.Context, id int64) (Device, error) GetByAPNSToken(ctx context.Context, token string) (Device, error) diff --git a/internal/domain/subreddit.go b/internal/domain/subreddit.go index 4563f22..fd0fd8e 100644 --- a/internal/domain/subreddit.go +++ b/internal/domain/subreddit.go @@ -3,6 +3,8 @@ package domain import ( "context" "strings" + + validation "github.com/go-ozzo/ozzo-validation/v4" ) type Subreddit struct { @@ -18,6 +20,13 @@ func (sr *Subreddit) NormalizedName() string { return strings.ToLower(sr.Name) } +func (sr *Subreddit) Validate() error { + return validation.ValidateStruct(sr, + validation.Field(&sr.Name, validation.Required, validation.Length(3, 32)), + validation.Field(&sr.SubredditID, validation.Required, validation.Length(5, 7)), + ) +} + type SubredditRepository interface { GetByID(ctx context.Context, id int64) (Subreddit, error) GetByName(ctx context.Context, name string) (Subreddit, error) diff --git a/internal/domain/user.go b/internal/domain/user.go index 44dabc0..f855640 100644 --- a/internal/domain/user.go +++ b/internal/domain/user.go @@ -3,6 +3,8 @@ package domain import ( "context" "strings" + + validation "github.com/go-ozzo/ozzo-validation/v4" ) type User struct { @@ -18,6 +20,13 @@ func (u *User) NormalizedName() string { return strings.ToLower(u.Name) } +func (u *User) Validate() error { + return validation.ValidateStruct(u, + validation.Field(&u.Name, validation.Required, validation.Length(3, 32)), + validation.Field(&u.UserID, validation.Required, validation.Length(5, 7)), + ) +} + type UserRepository interface { GetByID(context.Context, int64) (User, error) GetByName(context.Context, string) (User, error) diff --git a/internal/repository/postgres_device.go b/internal/repository/postgres_device.go index 14eb75b..5f3252e 100644 --- a/internal/repository/postgres_device.go +++ b/internal/repository/postgres_device.go @@ -102,6 +102,10 @@ func (p *postgresDeviceRepository) CreateOrUpdate(ctx context.Context, dev *doma } func (p *postgresDeviceRepository) Create(ctx context.Context, dev *domain.Device) error { + if err := dev.Validate(); err != nil { + return err + } + query := ` INSERT INTO devices (apns_token, sandbox, active_until) @@ -118,6 +122,10 @@ func (p *postgresDeviceRepository) Create(ctx context.Context, dev *domain.Devic } func (p *postgresDeviceRepository) Update(ctx context.Context, dev *domain.Device) error { + if err := dev.Validate(); err != nil { + return err + } + query := ` UPDATE devices SET active_until = $2 diff --git a/internal/repository/postgres_subreddit.go b/internal/repository/postgres_subreddit.go index 3a7e88e..663f92e 100644 --- a/internal/repository/postgres_subreddit.go +++ b/internal/repository/postgres_subreddit.go @@ -76,6 +76,10 @@ func (p *postgresSubredditRepository) GetByName(ctx context.Context, name string } func (p *postgresSubredditRepository) CreateOrUpdate(ctx context.Context, sr *domain.Subreddit) error { + if err := sr.Validate(); err != nil { + return err + } + query := ` INSERT INTO subreddits (subreddit_id, name) VALUES ($1, $2) diff --git a/internal/repository/postgres_user.go b/internal/repository/postgres_user.go index 5f038ad..fdf9eab 100644 --- a/internal/repository/postgres_user.go +++ b/internal/repository/postgres_user.go @@ -5,8 +5,9 @@ import ( "fmt" "strings" - "github.com/christianselig/apollo-backend/internal/domain" "github.com/jackc/pgx/v4/pgxpool" + + "github.com/christianselig/apollo-backend/internal/domain" ) type postgresUserRepository struct { @@ -77,6 +78,10 @@ func (p *postgresUserRepository) GetByName(ctx context.Context, name string) (do } func (p *postgresUserRepository) CreateOrUpdate(ctx context.Context, u *domain.User) error { + if err := u.Validate(); err != nil { + return err + } + query := ` INSERT INTO users (user_id, name) VALUES ($1, $2)