Add: Discord Login Provider (#135)

This commit is contained in:
爱克狮 2024-04-25 21:11:47 +08:00 committed by GitHub
parent 789e4ec9ce
commit b2b00ca3c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 86 additions and 0 deletions

View File

@ -0,0 +1,86 @@
package providers
import (
"context"
"fmt"
"net/http"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/internal/provider"
"golang.org/x/oauth2"
)
type DiscordProvider struct {
config oauth2.Config
}
func newDiscordProvider() provider.ProviderInterface {
return &DiscordProvider{
config: oauth2.Config{
Scopes: []string{"identify"},
Endpoint: oauth2.Endpoint{
AuthURL: "https://discord.com/oauth2/authorize",
TokenURL: "https://discord.com/api/oauth2/token",
},
},
}
}
func (p *DiscordProvider) Init(c provider.Oauth2Option) {
p.config.ClientID = c.ClientID
p.config.ClientSecret = c.ClientSecret
p.config.RedirectURL = c.RedirectURL
}
func (p *DiscordProvider) Provider() provider.OAuth2Provider {
return "discord"
}
func (p *DiscordProvider) NewAuthURL(ctx context.Context, state string) (string, error) {
return p.config.AuthCodeURL(state, oauth2.AccessTypeOnline), nil
}
func (p *DiscordProvider) GetToken(ctx context.Context, code string) (*oauth2.Token, error) {
return p.config.Exchange(ctx, code)
}
func (p *DiscordProvider) RefreshToken(ctx context.Context, tk string) (*oauth2.Token, error) {
return p.config.TokenSource(ctx, &oauth2.Token{RefreshToken: tk}).Token()
}
func (p *DiscordProvider) GetUserInfo(ctx context.Context, code string) (*provider.UserInfo, error) {
tk, err := p.config.Exchange(ctx, code)
if err != nil {
return nil, err
}
client := p.config.Client(ctx, tk)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://discord.com/api/v10/oauth2/@me"), nil)
if err != nil {
return nil, err
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
ui := discordUserInfo{}
err = json.NewDecoder(resp.Body).Decode(&ui)
if err != nil {
return nil, err
}
return &provider.UserInfo{
Username: ui.Data.Name,
ProviderUserID: ui.Data.Id,
}, nil
}
type discordUserInfo struct {
Data struct {
Id string `json:"id"`
Name string `json:"username"`
} `json:"user"`
}
func init() {
RegisterProvider(newDiscordProvider())
}