Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

twitter oauth #263

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ func initializeOAuthProviders(cfg *Config) (map[string]oauth.Provider, error) {
if cfg.FacebookOauthCredentials != nil {
oauthProviders["facebook"] = *oauth.NewFacebookProvider(cfg.FacebookOauthCredentials)
}
if cfg.TwitterOauthCredentials != nil {
oauthProviders["twitter"] = *oauth.NewTwitterProvider(cfg.TwitterOauthCredentials)
}
if cfg.DiscordOauthCredentials != nil {
oauthProviders["discord"] = *oauth.NewDiscordProvider(cfg.DiscordOauthCredentials)
}
Expand Down
15 changes: 15 additions & 0 deletions app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type Config struct {
GoogleOauthCredentials *oauth.Credentials
GitHubOauthCredentials *oauth.Credentials
FacebookOauthCredentials *oauth.Credentials
TwitterOauthCredentials *oauth.Credentials
DiscordOauthCredentials *oauth.Credentials
MicrosoftOauthCredentials *oauth.Credentials
AppleOAuthCredentials *oauth.Credentials
Expand All @@ -85,6 +86,7 @@ func (c *Config) OAuthEnabled() bool {
return c.GoogleOauthCredentials != nil ||
c.GitHubOauthCredentials != nil ||
c.FacebookOauthCredentials != nil ||
c.TwitterOauthCredentials != nil ||
c.DiscordOauthCredentials != nil ||
c.MicrosoftOauthCredentials != nil ||
c.AppleOAuthCredentials != nil
Expand Down Expand Up @@ -626,6 +628,19 @@ var configurers = []configurer{
return nil
},

// TWITTER_OAUTH_CREDENTIALS is a credential pair in the format `id:secret`. When specified,
// AuthN will enable routes for Twitter OAuth signin.
func(c *Config) error {
if val, ok := os.LookupEnv("TWITTER_OAUTH_CREDENTIALS"); ok {
credentials, err := oauth.NewCredentials(val)
if err == nil {
c.TwitterOauthCredentials = credentials
}
return err
}
return nil
},

// DISCORD_OAUTH_CREDENTIALS is a credential pair in the format `id:secret`. When specified,
// AuthN will enable routes for Discord OAuth signin.
func(c *Config) error {
Expand Down
1 change: 1 addition & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ Visibility: Public
* google
* github
* facebook |
* twitter |

This is the return URL that must be registered with a provider when provisioning credentials. From here, a user will proceed to the `redirect_uri` specified at the [Begin OAuth](#begin-oauth) step.

Expand Down
14 changes: 13 additions & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Databases: [`DATABASE_URL`](#database_url) • [`REDIS_URL`](#redis_url) • [`REDIS_IS_SENTINEL_MODE`](#redis_is_sentinel_mode) • [`REDIS_SENTINEL_MASTER`](#redis_sentinel_master) • [`REDIS_SENTINEL_NODES`](#redis_sentinel_nodes) • [`REDIS_SENTINEL_PASSWORD`](#redis_sentinel_password)
* Sessions:
[`ACCESS_TOKEN_TTL`](#access_token_ttl) • [`REFRESH_TOKEN_TTL`](#refresh_token_ttl)• [`REFRESH_TOKEN_EXPLICIT_EXPIRY`](#refresh_token_explicit_expiry) • [`SESSION_KEY_SALT`](#session_key_salt) • [`DB_ENCRYPTION_KEY_SALT`](#db_encryption_key_salt) • [`RSA_PRIVATE_KEY`](#rsa_private_key) • [`SAME_SITE`](#same_site)
* OAuth Clients: [`FACEBOOK_OAUTH_CREDENTIALS`](#facebook_oauth_credentials) • [`GITHUB_OAUTH_CREDENTIALS`](#github_oauth_credentials) • [`GOOGLE_OAUTH_CREDENTIALS`](#google_oauth_credentials) • [`DISCORD_OAUTH_CREDENTIALS`](#discord_oauth_credentials) • [`MICROSOFT_OAUTH_CREDENTIALS`](#microsoft_oauth_credentials)
* OAuth Clients: [`FACEBOOK_OAUTH_CREDENTIALS`](#facebook_oauth_credentials) • [`TWITTER_OAUTH_CREDENTIALS`](#twitter_oauth_credentials) • [`GITHUB_OAUTH_CREDENTIALS`](#github_oauth_credentials) • [`GOOGLE_OAUTH_CREDENTIALS`](#google_oauth_credentials) • [`DISCORD_OAUTH_CREDENTIALS`](#discord_oauth_credentials) • [`MICROSOFT_OAUTH_CREDENTIALS`](#microsoft_oauth_credentials)
* Username Policy: [`USERNAME_IS_EMAIL`](#username_is_email) • [`EMAIL_USERNAME_DOMAINS`](#email_username_domains)
* Password Policy: [`PASSWORD_POLICY_SCORE`](#password_policy_score) • [`PASSWORD_CHANGE_LOGOUT`](#password_change_logout) • [`BCRYPT_COST`](#bcrypt_cost)
* Password Resets: [`APP_PASSWORD_RESET_URL`](#app_password_reset_url) • [`PASSWORD_RESET_TOKEN_TTL`](#password_reset_token_ttl) • [`APP_PASSWORD_CHANGED_URL`](#app_password_changed_url)
Expand Down Expand Up @@ -286,6 +286,18 @@ The configured client secret is a private key used to sign the JWT. This should

Create a Facebook app at https://developers.facebook.com and enable the Facebook Login product. In the Quickstart, enter [AuthN's OAuth Return](api.md#oauth-return) as the Site URL. Then switch over to Settings and find the App ID and Secret. Join those together with a `:` and provide them to AuthN as a single variable.

### `TWITTER_OAUTH_CREDENTIALS`

| | |
|-----------|-----------------|
| Required? | No |
| Value | AppID:AppSecret |
| Default | nil |

Log in and see your apps in the [X developer portal](https://developer.x.com/en/portal/projects-and-apps). Go to app settings and set up user authentication. Enter [AuthN's OAuth Return](api.md#oauth-return) as the redirect URL. Save `Client ID` and `Client Secret`. Join those together with a `:` and provide them to AuthN as a single variable.

<https://developer.x.com/en/docs/authentication/guides/log-in-with-twitter>

### `GITHUB_OAUTH_CREDENTIALS`

| | |
Expand Down
40 changes: 40 additions & 0 deletions lib/oauth/twitter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package oauth

import (
"context"
"encoding/json"
"io"

"golang.org/x/oauth2"
)

// NewTwitterProvider returns a AuthN integration for Twitter OAuth
func NewTwitterProvider(credentials *Credentials) *Provider {
config := &oauth2.Config{
ClientID: credentials.ID,
ClientSecret: credentials.Secret,
Scopes: []string{"email"},
Endpoint: oauth2.Endpoint{
AuthURL: "https://twitter.com/i/oauth2/authorize",
TokenURL: "https://api.twitter.com/2/oauth2/token",
},
}

return NewProvider(config, func(t *oauth2.Token) (*UserInfo, error) {
client := config.Client(context.TODO(), t)
resp, err := client.Get("https://api.twitter.com/2/me")
if err != nil {
return nil, err
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

var user UserInfo
err = json.Unmarshal(body, &user)
return &user, err
})
}