69 lines
2.0 KiB
Go
69 lines
2.0 KiB
Go
package deezer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// resolveARL returns a usable ARL cookie from the stored credentials, logging
|
|
// in again if the stored one has expired.
|
|
//
|
|
// validate is supplied by the caller so the check can be the real
|
|
// authentication rather than a throwaway probe. Only ErrInvalidARL triggers a
|
|
// re-login: any other validation failure is most likely the network or Deezer
|
|
// being down, and silently re-sending the password in that case would turn a
|
|
// transient outage into a spurious login attempt.
|
|
func resolveARL(ctx context.Context, validate func(ctx context.Context, arl string) error) (string, error) {
|
|
creds, err := loadCredentials()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if creds != nil && creds.ARL != "" {
|
|
verr := validate(ctx, creds.ARL)
|
|
if verr == nil {
|
|
return creds.ARL, nil
|
|
}
|
|
|
|
if !errors.Is(verr, ErrInvalidARL) {
|
|
return "", fmt.Errorf("stored session could not be validated: %w", verr)
|
|
}
|
|
}
|
|
|
|
if creds != nil && creds.Email != "" && creds.Password != "" {
|
|
arl, _, err := Login(ctx, creds.Email, creds.Password)
|
|
if err != nil {
|
|
return "", fmt.Errorf("stored session expired and could not be renewed automatically: %w", err)
|
|
}
|
|
|
|
return arl, nil
|
|
}
|
|
|
|
return "", errors.New("run 'godeez login' or export DEEZER_ARL environment variable")
|
|
}
|
|
|
|
// Login authenticates with email and password through the mobile gateway,
|
|
// persists the credentials to the system keyring, and returns the resulting
|
|
// ARL cookie and the account's display name.
|
|
//
|
|
// The password is stored, not just the ARL, because ARLs expire and renewing
|
|
// one without prompting the user again requires replaying the login.
|
|
func Login(ctx context.Context, email, password string) (string, string, error) {
|
|
client, err := newMobileClient()
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
creds, username, err := client.login(ctx, email, password)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
if err := saveCredentials(creds); err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
return creds.ARL, username, nil
|
|
}
|