From 7a89d5503cdce561d0a401e07308c563dccef30c Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Mon, 12 Jul 2021 14:46:28 -0400 Subject: [PATCH] fix up API to include account ID and refresh token --- cmd/apollo-api/accounts.go | 48 +++++++++++++++++++++++++++++--------- cmd/apollo-api/main.go | 16 +++++++++++-- internal/data/accounts.go | 4 ++-- internal/reddit/client.go | 8 ------- internal/reddit/types.go | 14 ++++++++++- 5 files changed, 66 insertions(+), 24 deletions(-) diff --git a/cmd/apollo-api/accounts.go b/cmd/apollo-api/accounts.go index 29fa20c..f727cdc 100644 --- a/cmd/apollo-api/accounts.go +++ b/cmd/apollo-api/accounts.go @@ -2,11 +2,11 @@ package main import ( "encoding/json" - "fmt" "net/http" "time" "github.com/julienschmidt/httprouter" + "github.com/sirupsen/logrus" "github.com/christianselig/apollo-backend/internal/data" ) @@ -14,32 +14,54 @@ import ( func (app *application) upsertAccountHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { a := &data.Account{} if err := json.NewDecoder(r.Body).Decode(a); err != nil { - fmt.Println("failing on decoding json") + app.logger.WithFields(logrus.Fields{ + "err": err, + }).Info("failed to parse request json") + app.errorResponse(w, r, 422, err.Error()) + return + } + + // Here we check whether the account is supplied with a valid token. + ac := app.client.NewAuthenticatedClient(a.RefreshToken, a.AccessToken) + tokens, err := ac.RefreshTokens() + if err != nil { + app.logger.WithFields(logrus.Fields{ + "err": err, + }).Info("failed to refresh token") app.errorResponse(w, r, 500, err.Error()) return } - a.ExpiresAt = time.Now().Unix() + 3300 + // Reset expiration timer + a.ExpiresAt = time.Now().Unix() + 3540 - // Here we check whether the account is supplied with a valid token. - ac := app.client.NewAuthenticatedClient(a.RefreshToken, a.AccessToken) + ac = app.client.NewAuthenticatedClient(tokens.RefreshToken, tokens.AccessToken) me, err := ac.Me() if err != nil { - fmt.Println("failing on fetching remote user") + app.logger.WithFields(logrus.Fields{ + "err": err, + }).Info("failed to grab user details") app.errorResponse(w, r, 500, err.Error()) return } if me.NormalizedUsername() != a.NormalizedUsername() { - fmt.Println("failing on account username comparison") - app.errorResponse(w, r, 500, "nice try") + app.logger.WithFields(logrus.Fields{ + "err": err, + }).Info("user is not who they say they are") + app.errorResponse(w, r, 422, "nice try") return } + // Set account ID from Reddit + a.AccountID = me.ID + // Upsert account if err := app.models.Accounts.Upsert(a); err != nil { - fmt.Println("failing on account upsert") + app.logger.WithFields(logrus.Fields{ + "err": err, + }).Info("failed updating account in database") app.errorResponse(w, r, 500, err.Error()) return } @@ -47,13 +69,17 @@ func (app *application) upsertAccountHandler(w http.ResponseWriter, r *http.Requ // Associate d, err := app.models.Devices.GetByAPNSToken(ps.ByName("apns")) if err != nil { - fmt.Println("failing on apns") + app.logger.WithFields(logrus.Fields{ + "err": err, + }).Info("failed fetching account devices") app.errorResponse(w, r, 500, err.Error()) return } if err := app.models.DevicesAccounts.Associate(a.ID, d.ID); err != nil { - fmt.Println("failing on associate") + app.logger.WithFields(logrus.Fields{ + "err": err, + }).Info("failed associating account with device") app.errorResponse(w, r, 500, err.Error()) return } diff --git a/cmd/apollo-api/main.go b/cmd/apollo-api/main.go index 72b1909..af343b7 100644 --- a/cmd/apollo-api/main.go +++ b/cmd/apollo-api/main.go @@ -10,6 +10,7 @@ import ( "github.com/DataDog/datadog-go/statsd" "github.com/joho/godotenv" _ "github.com/lib/pq" + "github.com/sirupsen/logrus" "github.com/christianselig/apollo-backend/internal/data" "github.com/christianselig/apollo-backend/internal/reddit" @@ -21,14 +22,25 @@ type config struct { type application struct { cfg config - logger *log.Logger + logger *logrus.Logger db *sql.DB models *data.Models client *reddit.Client } func main() { - logger := log.New(os.Stdout, "", log.Ldate|log.Ltime) + var logger *logrus.Logger + { + logger = logrus.New() + if os.Getenv("ENV") == "" { + logger.SetLevel(logrus.DebugLevel) + } else { + logger.SetFormatter(&logrus.TextFormatter{ + DisableColors: true, + FullTimestamp: true, + }) + } + } if err := godotenv.Load(); err != nil { logger.Printf("Couldn't find .env so I will read from existing ENV.") diff --git a/internal/data/accounts.go b/internal/data/accounts.go index ea7ba04..ea15b51 100644 --- a/internal/data/accounts.go +++ b/internal/data/accounts.go @@ -26,14 +26,14 @@ type AccountModel struct { func (am *AccountModel) Upsert(a *Account) error { query := ` - INSERT INTO accounts (username, access_token, refresh_token, expires_at, last_message_id, device_count, last_checked_at) + INSERT INTO accounts (username, account_id, access_token, refresh_token, expires_at, last_message_id, device_count, last_checked_at) VALUES ($1, $2, $3, $4, '', 0, 0) ON CONFLICT(username) DO UPDATE SET access_token = $2, refresh_token = $3, expires_at = $4, last_message_id = $5, last_checked_at = $6 RETURNING id` - args := []interface{}{a.NormalizedUsername(), a.AccessToken, a.RefreshToken, a.ExpiresAt, a.LastMessageID, a.LastCheckedAt} + args := []interface{}{a.NormalizedUsername(), a.AccountID, a.AccessToken, a.RefreshToken, a.ExpiresAt, a.LastMessageID, a.LastCheckedAt} return am.DB.QueryRow(query, args...).Scan(&a.ID) } diff --git a/internal/reddit/client.go b/internal/reddit/client.go index 02cc3b4..4b7c1c8 100644 --- a/internal/reddit/client.go +++ b/internal/reddit/client.go @@ -154,14 +154,6 @@ func (rac *AuthenticatedClient) MessageInbox(from string) (*MessageListingRespon return mlr, nil } -type MeResponse struct { - Name string -} - -func (mr *MeResponse) NormalizedUsername() string { - return strings.ToLower(mr.Name) -} - func (rac *AuthenticatedClient) Me() (*MeResponse, error) { req := NewRequest( WithTags([]string{"url:/api/v1/me"}), diff --git a/internal/reddit/types.go b/internal/reddit/types.go index d87eaa2..e2754a7 100644 --- a/internal/reddit/types.go +++ b/internal/reddit/types.go @@ -1,6 +1,9 @@ package reddit -import "fmt" +import ( + "fmt" + "strings" +) type Error struct { Message string `json:"message"` @@ -47,3 +50,12 @@ type RefreshTokenResponse struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` } + +type MeResponse struct { + ID string `json:"id"` + Name string +} + +func (mr *MeResponse) NormalizedUsername() string { + return strings.ToLower(mr.Name) +}