1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-03-19 22:19:23 +02:00
pocketbase/tools/auth/patreon.go

88 lines
2.3 KiB
Go
Raw Permalink Normal View History

package auth
import (
"context"
"encoding/json"
"github.com/pocketbase/pocketbase/tools/types"
"golang.org/x/oauth2"
)
2024-09-29 19:23:19 +03:00
func init() {
Providers[NamePatreon] = wrapFactory(NewPatreonProvider)
}
var _ Provider = (*Patreon)(nil)
// NamePatreon is the unique name of the Patreon provider.
const NamePatreon string = "patreon"
// Patreon allows authentication via Patreon OAuth2.
type Patreon struct {
2024-09-29 19:23:19 +03:00
BaseProvider
}
// NewPatreonProvider creates new Patreon provider instance with some defaults.
func NewPatreonProvider() *Patreon {
2024-09-29 19:23:19 +03:00
return &Patreon{BaseProvider{
ctx: context.Background(),
displayName: "Patreon",
pkce: true,
scopes: []string{"identity", "identity[email]"},
2024-09-29 19:23:19 +03:00
authURL: "https://www.patreon.com/oauth2/authorize",
tokenURL: "https://www.patreon.com/api/oauth2/token",
userInfoURL: "https://www.patreon.com/api/oauth2/v2/identity?fields%5Buser%5D=full_name,email,vanity,image_url,is_email_verified",
}}
}
// FetchAuthUser returns an AuthUser instance based on the Patreons's identity api.
//
// API reference:
// https://docs.patreon.com/#get-api-oauth2-v2-identity
// https://docs.patreon.com/#user-v2
func (p *Patreon) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
2024-09-29 19:23:19 +03:00
data, err := p.FetchRawUserInfo(token)
if err != nil {
return nil, err
}
rawUser := map[string]any{}
if err := json.Unmarshal(data, &rawUser); err != nil {
return nil, err
}
extracted := struct {
Data struct {
Id string `json:"id"`
Attributes struct {
Email string `json:"email"`
Name string `json:"full_name"`
Username string `json:"vanity"`
2024-09-29 19:23:19 +03:00
AvatarURL string `json:"image_url"`
IsEmailVerified bool `json:"is_email_verified"`
} `json:"attributes"`
} `json:"data"`
}{}
if err := json.Unmarshal(data, &extracted); err != nil {
return nil, err
}
user := &AuthUser{
Id: extracted.Data.Id,
Username: extracted.Data.Attributes.Username,
Name: extracted.Data.Attributes.Name,
2024-09-29 19:23:19 +03:00
AvatarURL: extracted.Data.Attributes.AvatarURL,
RawUser: rawUser,
AccessToken: token.AccessToken,
RefreshToken: token.RefreshToken,
}
user.Expiry, _ = types.ParseDateTime(token.Expiry)
if extracted.Data.Attributes.IsEmailVerified {
user.Email = extracted.Data.Attributes.Email
}
return user, nil
}