You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.8 KiB
Go

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) {
if token == nil {
return nil, fmt.Errorf("token is nil")
}
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
}