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 }