Skip to content

Commit 78537e6

Browse files
mgkbadolabadolamgk
andauthored
feature: Discord OAuth2 Provider (#223)
* feature: add discord integration * fix: linting issue on NewDiscord * fixes: add provider to v2, remove email scope and cleanup indent in README * fix: comment on token validator * fix: changes involving email removal in test script * fix: changes involving email removal in test script (v1) --------- Co-authored-by: badolamgk <mrigank.badola@essentiallysports.com>
1 parent 08bfdf2 commit 78537e6

11 files changed

Lines changed: 101 additions & 6 deletions

File tree

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# auth - authentication via oauth2, direct and email
22
[![Build Status](https://github.com/go-pkgz/auth/workflows/build/badge.svg)](https://github.com/go-pkgz/auth/actions) [![Coverage Status](https://coveralls.io/repos/github/go-pkgz/auth/badge.svg?branch=master)](https://coveralls.io/github/go-pkgz/auth?branch=master) [![godoc](https://godoc.org/github.com/go-pkgz/auth?status.svg)](https://pkg.go.dev/github.com/go-pkgz/auth?tab=doc)
33

4-
This library provides "social login" with Github, Google, Facebook, Microsoft, Twitter, Yandex, Battle.net, Apple, Patreon and Telegram as well as custom auth providers and email verification.
4+
This library provides "social login" with Github, Google, Facebook, Microsoft, Twitter, Yandex, Battle.net, Apple, Patreon, Discord and Telegram as well as custom auth providers and email verification.
55

66
- Multiple oauth2 providers can be used at the same time
77
- Special `dev` provider allows local testing and development
@@ -604,6 +604,13 @@ For more details refer to [Complete Guide of Battle.net OAuth API and Login Butt
604604
1. Under **"Redirect URIs"** enter the correct url constructed as domain + `/auth/patreon/callback`. ie `https://example.mysite.com/auth/patreon/callback`
605605
1. Take note of the **Client ID** and **Client Secret**
606606

607+
#### Discord Auth Provider ####
608+
1. Log into Discord Developer Portal https://discord.com/developers/applications
609+
2. Click on **New Application** to create the application required for Oauth
610+
3. After filling **"NAME"**, navigate to **"OAuth2"** option on the left sidebar
611+
4. Under **"Redirects"** enter the correct url constructed as domain + `/auth/discord/callback`. ie `https://remark42.mysite.com/auth/discord/callback`
612+
5. Take note of the **CLIENT ID** and **CLIENT SECRET**
613+
607614
#### Twitter Auth Provider
608615
1. Create a new twitter application https://developer.twitter.com/en/apps
609616
1. Fill **App name** and **Description** and **URL** of your site

_example/frontend/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<body>
1111
<header class="main-header">
1212
<h1 class="title"><a href="https://github.com/go-pkgz/auth">GO-PKGZ/AUTH</a><span class="pretitle">Example page</span></h1>
13-
<p class="description">This library provides “social login” with Github, Google, Microsoft, Facebook, Yandex, Battle.net, Patreon and Telegram.</p>
13+
<p class="description">This library provides “social login” with Github, Google, Microsoft, Facebook, Yandex, Battle.net, Patreon, Discord and Telegram.</p>
1414
<div class="login"></div>
1515
</header>
1616
<div class="status"><span class="minititle">Status:</span> <span class="status__label">unauthorized</span></div>
@@ -25,4 +25,4 @@ <h1 class="title"><a href="https://github.com/go-pkgz/auth">GO-PKGZ/AUTH</a><spa
2525
<a href="https://github.com/go-pkgz/auth">go-pkgz/auth</a></div>
2626
<script src="./main.js?v=2"></script>
2727
</body>
28-
</html>
28+
</html>

_example/main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ func main() {
6363
if strings.HasPrefix(claims.User.ID, "microsoft_") { // allow all users with ms auth
6464
return true
6565
}
66-
if strings.HasPrefix(claims.User.ID, "patreon_") { // allow all users with ms auth
66+
if strings.HasPrefix(claims.User.ID, "patreon_") { // allow all users with patreon auth
67+
return true
68+
}
69+
if strings.HasPrefix(claims.User.ID, "discord_") { // allow all users with discord auth
6770
return true
6871
}
6972
if strings.HasPrefix(claims.User.Name, "dev_") { // non-guthub allow only dev_* names
@@ -84,6 +87,7 @@ func main() {
8487
service.AddProvider("twitter", os.Getenv("AEXMPL_TWITTER_APIKEY"), os.Getenv("AEXMPL_TWITTER_APISEC"))
8588
service.AddProvider("microsoft", os.Getenv("AEXMPL_MS_APIKEY"), os.Getenv("AEXMPL_MS_APISEC"))
8689
service.AddProvider("patreon", os.Getenv("AEXMPL_PATREON_CID"), os.Getenv("AEXMPL_PATREON_CSEC"))
90+
service.AddProvider("discord", os.Getenv("AEXMPL_DISCORD_CID"), os.Getenv("AEXMPL_DISCORD_CSEC"))
8791

8892
// allow sign with apple id
8993
appleCfg := provider.AppleConfig{

auth.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ func (s *Service) addProviderByName(name string, p provider.Params) {
257257
prov = provider.NewTwitter(p)
258258
case "patreon":
259259
prov = provider.NewPatreon(p)
260+
case "discord":
261+
prov = provider.NewDiscord(p)
260262
case "dev":
261263
prov = provider.NewDev(p)
262264
default:

auth_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func TestProvider(t *testing.T) {
6161
svc.AddProvider("twitter", "cid", "csecret")
6262
svc.AddProvider("battlenet", "cid", "csecret")
6363
svc.AddProvider("patreon", "cid", "csecret")
64+
svc.AddProvider("discord", "cid", "csecret")
6465
svc.AddProvider("bad", "cid", "csecret")
6566

6667
c := customHandler{}
@@ -81,7 +82,7 @@ func TestProvider(t *testing.T) {
8182
assert.Equal(t, "github", op.Name())
8283

8384
pp := svc.Providers()
84-
assert.Equal(t, 10, len(pp))
85+
assert.Equal(t, 11, len(pp))
8586

8687
ch, err := svc.Provider("telegramBotMySiteCom")
8788
assert.NoError(t, err)

provider/providers.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,29 @@ func NewPatreon(p Params) Oauth2Handler {
265265
},
266266
})
267267
}
268+
269+
// NewDiscord makes discord oauth2 provider
270+
func NewDiscord(p Params) Oauth2Handler {
271+
return initOauth2Handler(p, Oauth2Handler{
272+
name: "discord",
273+
// see https://discord.com/developers/docs/topics/oauth2
274+
endpoint: oauth2.Endpoint{
275+
AuthURL: "https://discord.com/oauth2/authorize",
276+
TokenURL: "https://discord.com/api/oauth2/token",
277+
},
278+
infoURL: "https://discord.com/api/v10/users/@me",
279+
scopes: []string{"identify"},
280+
mapUser: func(data UserData, _ []byte) token.User {
281+
userInfo := token.User{
282+
ID: "discord_" + token.HashID(sha1.New(), data.Value("id")),
283+
Name: data.Value("username"),
284+
Picture: fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.webp", data.Value("id"), data.Value("avatar")),
285+
}
286+
287+
for k, v := range p.UserAttributes {
288+
userInfo.SetStrAttr(v, data.Value(k))
289+
}
290+
return userInfo
291+
},
292+
})
293+
}

provider/providers_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,16 @@ func TestProviders_NewPatreon(t *testing.T) {
208208
user,
209209
)
210210
}
211+
212+
func TestProviders_NewDiscord(t *testing.T) {
213+
r := NewDiscord(Params{URL: "http://demo.remark42.com", Cid: "cid", Csecret: "cs"})
214+
assert.Equal(t, "discord", r.Name())
215+
216+
t.Run("With all data", func(t *testing.T) {
217+
udata := UserData{"id": "248533295981532", "username": "test_user", "avatar": "374384984773"}
218+
user := r.mapUser(udata, nil)
219+
assert.Equal(t, token.User{Name: "test_user", ID: "discord_9b472605c1318483fb4b88f9acf22cdd4219f9a0",
220+
Picture: "https://cdn.discordapp.com/avatars/248533295981532/374384984773.webp"}, user, "got %+v", user)
221+
})
222+
223+
}

v2/auth.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ func (s *Service) addProviderByName(name string, p provider.Params) {
257257
prov = provider.NewTwitter(p)
258258
case "patreon":
259259
prov = provider.NewPatreon(p)
260+
case "discord":
261+
prov = provider.NewDiscord(p)
260262
case "dev":
261263
prov = provider.NewDev(p)
262264
default:

v2/auth_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func TestProvider(t *testing.T) {
6161
svc.AddProvider("twitter", "cid", "csecret")
6262
svc.AddProvider("battlenet", "cid", "csecret")
6363
svc.AddProvider("patreon", "cid", "csecret")
64+
svc.AddProvider("discord", "cid", "csecret")
6465
svc.AddProvider("bad", "cid", "csecret")
6566

6667
c := customHandler{}
@@ -81,7 +82,7 @@ func TestProvider(t *testing.T) {
8182
assert.Equal(t, "github", op.Name())
8283

8384
pp := svc.Providers()
84-
assert.Equal(t, 10, len(pp))
85+
assert.Equal(t, 11, len(pp))
8586

8687
ch, err := svc.Provider("telegramBotMySiteCom")
8788
assert.NoError(t, err)

v2/provider/providers.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,29 @@ func NewPatreon(p Params) Oauth2Handler {
265265
},
266266
})
267267
}
268+
269+
// NewDiscord makes discord oauth2 provider
270+
func NewDiscord(p Params) Oauth2Handler {
271+
return initOauth2Handler(p, Oauth2Handler{
272+
name: "discord",
273+
// see https://discord.com/developers/docs/topics/oauth2
274+
endpoint: oauth2.Endpoint{
275+
AuthURL: "https://discord.com/oauth2/authorize",
276+
TokenURL: "https://discord.com/api/oauth2/token",
277+
},
278+
infoURL: "https://discord.com/api/v10/users/@me",
279+
scopes: []string{"identify"},
280+
mapUser: func(data UserData, _ []byte) token.User {
281+
userInfo := token.User{
282+
ID: "discord_" + token.HashID(sha1.New(), data.Value("id")),
283+
Name: data.Value("username"),
284+
Picture: fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.webp", data.Value("id"), data.Value("avatar")),
285+
}
286+
287+
for k, v := range p.UserAttributes {
288+
userInfo.SetStrAttr(v, data.Value(k))
289+
}
290+
return userInfo
291+
},
292+
})
293+
}

0 commit comments

Comments
 (0)