|
|
|
package users
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"gitea.ravianand.me/Dan6erbond/listy/core"
|
|
|
|
"gitea.ravianand.me/Dan6erbond/listy/models"
|
|
|
|
"github.com/zmb3/spotify/v2"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
|
|
"golang.org/x/oauth2"
|
|
|
|
)
|
|
|
|
|
|
|
|
func GetUsers(ctx context.Context, app *core.App) ([]*models.User, error) {
|
|
|
|
coll := app.MongoClient.Database("listy").Collection("users")
|
|
|
|
|
|
|
|
filter := bson.D{}
|
|
|
|
opts := options.Find()
|
|
|
|
|
|
|
|
cursor, err := coll.Find(context.TODO(), filter, opts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("couldn't fetch users %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var results []*models.User
|
|
|
|
if err = cursor.All(ctx, &results); err != nil {
|
|
|
|
return nil, fmt.Errorf("couldn't fetch users %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return results, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetUser(ctx context.Context, app *core.App, spotifyID string) (*models.User, error) {
|
|
|
|
coll := app.MongoClient.Database("listy").Collection("users")
|
|
|
|
|
|
|
|
filter := bson.D{{"spotifyid", spotifyID}}
|
|
|
|
opts := options.FindOne()
|
|
|
|
|
|
|
|
var result models.User
|
|
|
|
err := coll.FindOne(context.TODO(), filter, opts).Decode(&result)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("couldn't fetch user %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetSpotifyClient(ctx context.Context, app *core.App, user *models.User) (*spotify.Client, error) {
|
|
|
|
coll := app.MongoClient.Database("listy").Collection("users")
|
|
|
|
|
|
|
|
if user.Token.Expiry.Before(time.Now()) { // expired so let's update it
|
|
|
|
src := app.SpotifyOAuthConfig.TokenSource(ctx, &user.Token)
|
|
|
|
newToken, err := src.Token() // this actually goes and renews the tokens
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
if newToken.AccessToken != user.Token.AccessToken {
|
|
|
|
_, err := coll.UpdateByID(ctx, user.ID, bson.D{{"$set", bson.D{{"token", *newToken}}}})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("couldn't update token %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
user.Token = *newToken
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
client := spotify.New(app.SpotifyAuth.Client(ctx, &user.Token))
|
|
|
|
|
|
|
|
return client, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func SaveUserToken(ctx context.Context, app *core.App, spotifyID string, token *oauth2.Token) (*models.User, error) {
|
|
|
|
coll := app.MongoClient.Database("listy").Collection("users")
|
|
|
|
|
|
|
|
result, err := GetUser(ctx, app, spotifyID)
|
|
|
|
if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
|
|
|
|
return nil, fmt.Errorf("couldn't fetch user %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err == mongo.ErrNoDocuments {
|
|
|
|
doc := models.User{Token: *token, SpotifyID: spotifyID}
|
|
|
|
_, err = coll.InsertOne(context.TODO(), doc)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("couldn't write user %w", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_, err := coll.UpdateByID(ctx, result.ID, bson.D{{"$set", bson.D{{"token", *token}}}})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("couldn't write user %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
result.Token = *token
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|