mirror of
https://github.com/christianselig/apollo-backend
synced 2024-11-13 07:27:43 +00:00
fix up API to include account ID and refresh token
This commit is contained in:
parent
a431c4ff5b
commit
7a89d5503c
5 changed files with 66 additions and 24 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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"}),
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue