[#335] added Discord OAuth2 provider

This commit is contained in:
Gani Georgiev
2022-08-21 19:38:42 +03:00
parent 0b8c7f6883
commit 49b084cf50
18 changed files with 246 additions and 149 deletions
+2
View File
@@ -90,6 +90,8 @@ func NewProviderByName(name string) (Provider, error) {
return NewGithubProvider(), nil
case NameGitlab:
return NewGitlabProvider(), nil
case NameDiscord:
return NewDiscordProvider(), nil
default:
return nil, errors.New("Missing provider " + name)
}
+9
View File
@@ -54,4 +54,13 @@ func TestNewProviderByName(t *testing.T) {
if _, ok := p.(*auth.Gitlab); !ok {
t.Error("Expected to be instance of *auth.Gitlab")
}
// discord
p, err = auth.NewProviderByName(auth.NameDiscord)
if err != nil {
t.Errorf("Expected nil, got error %v", err)
}
if _, ok := p.(*auth.Discord); !ok {
t.Error("Expected to be instance of *auth.Discord")
}
}
+61
View File
@@ -0,0 +1,61 @@
package auth
import (
"fmt"
"golang.org/x/oauth2"
)
var _ Provider = (*Discord)(nil)
// NameDiscord is the unique name of the Discord provider.
const NameDiscord string = "discord"
// Discord allows authentication via Discord OAuth2.
type Discord struct {
*baseProvider
}
// NewDiscordProvider creates a new Discord provider instance with some defaults.
func NewDiscordProvider() *Discord {
// https://discord.com/developers/docs/topics/oauth2
// https://discord.com/developers/docs/resources/user#get-current-user
return &Discord{&baseProvider{
scopes: []string{"identify", "email"},
authUrl: "https://discord.com/api/oauth2/authorize",
tokenUrl: "https://discord.com/api/oauth2/token",
userApiUrl: "https://discord.com/api/users/@me",
}}
}
// FetchAuthUser returns an AuthUser instance from Discord's user api.
func (p *Discord) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
// https://discord.com/developers/docs/resources/user#user-object
rawData := struct {
Id string `json:"id"`
Username string `json:"username"`
Discriminator string `json:"discriminator"`
Email string `json:"email"`
Avatar string `json:"avatar"`
}{}
if err := p.FetchRawUserData(token, &rawData); err != nil {
return nil, err
}
// Build a full avatar URL using the avatar hash provided in the API response
// https://discord.com/developers/docs/reference#image-formatting
avatarUrl := fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.png", rawData.Id, rawData.Avatar)
// Concatenate the user's username and discriminator into a single username string
username := fmt.Sprintf("%s#%s", rawData.Username, rawData.Discriminator)
user := &AuthUser{
Id: rawData.Id,
Name: username,
Email: rawData.Email,
AvatarUrl: avatarUrl,
}
return user, nil
}