-
-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Additional OAuth2 providers #1010
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
Changes from all commits
b98777f
a24e238
02638f0
6c48e16
6a5b0c3
213e67b
92aec11
9e797b2
107eeea
94c8a48
8b8b5f4
e2544ae
ab95945
1c030e9
cb3b4e7
6aeea3f
da3a2b9
e0ad523
675e61e
33ad313
92e802d
7c63b03
5f0067e
922c5d4
e18dfe5
2342225
fe450e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright 2017 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package models | ||
|
||
import "fmt" | ||
|
||
// ErrOpenIDConnectInitialize represents a "OpenIDConnectInitialize" kind of error. | ||
type ErrOpenIDConnectInitialize struct { | ||
OpenIDConnectAutoDiscoveryURL string | ||
ProviderName string | ||
Cause error | ||
} | ||
|
||
// IsErrOpenIDConnectInitialize checks if an error is a ExternalLoginUserAlreadyExist. | ||
func IsErrOpenIDConnectInitialize(err error) bool { | ||
_, ok := err.(ErrOpenIDConnectInitialize) | ||
return ok | ||
} | ||
|
||
func (err ErrOpenIDConnectInitialize) Error() string { | ||
return fmt.Sprintf("Failed to initialize OpenID Connect Provider with name '%s' with url '%s': %v", err.ProviderName, err.OpenIDConnectAutoDiscoveryURL, err.Cause) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Copyright 2017 The Gitea Authors. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package models | ||
|
||
import ( | ||
"sort" | ||
"code.gitea.io/gitea/modules/auth/oauth2" | ||
) | ||
|
||
// OAuth2Provider describes the display values of a single OAuth2 provider | ||
type OAuth2Provider struct { | ||
Name string | ||
DisplayName string | ||
Image string | ||
CustomURLMapping *oauth2.CustomURLMapping | ||
} | ||
|
||
// OAuth2Providers contains the map of registered OAuth2 providers in Gitea (based on goth) | ||
// key is used to map the OAuth2Provider with the goth provider type (also in LoginSource.OAuth2Config.Provider) | ||
// value is used to store display data | ||
var OAuth2Providers = map[string]OAuth2Provider{ | ||
"bitbucket": {Name: "bitbucket", DisplayName: "Bitbucket", Image: "/img/auth/bitbucket.png"}, | ||
"dropbox": {Name: "dropbox", DisplayName: "Dropbox", Image: "/img/auth/dropbox.png"}, | ||
"facebook": {Name: "facebook", DisplayName: "Facebook", Image: "/img/auth/facebook.png"}, | ||
"github": {Name: "github", DisplayName: "GitHub", Image: "/img/auth/github.png", | ||
CustomURLMapping: &oauth2.CustomURLMapping{ | ||
TokenURL: oauth2.GetDefaultTokenURL("github"), | ||
AuthURL: oauth2.GetDefaultAuthURL("github"), | ||
ProfileURL: oauth2.GetDefaultProfileURL("github"), | ||
EmailURL: oauth2.GetDefaultEmailURL("github"), | ||
}, | ||
}, | ||
"gitlab": {Name: "gitlab", DisplayName: "GitLab", Image: "/img/auth/gitlab.png", | ||
CustomURLMapping: &oauth2.CustomURLMapping{ | ||
TokenURL: oauth2.GetDefaultTokenURL("gitlab"), | ||
AuthURL: oauth2.GetDefaultAuthURL("gitlab"), | ||
ProfileURL: oauth2.GetDefaultProfileURL("gitlab"), | ||
}, | ||
}, | ||
"gplus": {Name: "gplus", DisplayName: "Google+", Image: "/img/auth/google_plus.png"}, | ||
"openidConnect": {Name: "openidConnect", DisplayName: "OpenID Connect", Image: "/img/auth/openid_connect.png"}, | ||
"twitter": {Name: "twitter", DisplayName: "Twitter", Image: "/img/auth/twitter.png"}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add stack exchange as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think this is not yet available in https://github.com/markbates/goth/#supported-providers or is it named differently? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for the record; stackexchange (also?) supports OpenID-2.0, and you can use |
||
} | ||
|
||
// OAuth2DefaultCustomURLMappings contains the map of default URL's for OAuth2 providers that are allowed to have custom urls | ||
// key is used to map the OAuth2Provider | ||
// value is the mapping as defined for the OAuth2Provider | ||
var OAuth2DefaultCustomURLMappings = map[string]*oauth2.CustomURLMapping { | ||
"github": OAuth2Providers["github"].CustomURLMapping, | ||
"gitlab": OAuth2Providers["gitlab"].CustomURLMapping, | ||
} | ||
|
||
// GetActiveOAuth2ProviderLoginSources returns all actived LoginOAuth2 sources | ||
func GetActiveOAuth2ProviderLoginSources() ([]*LoginSource, error) { | ||
sources := make([]*LoginSource, 0, 1) | ||
if err := x.UseBool().Find(&sources, &LoginSource{IsActived: true, Type: LoginOAuth2}); err != nil { | ||
return nil, err | ||
} | ||
return sources, nil | ||
} | ||
|
||
// GetActiveOAuth2LoginSourceByName returns a OAuth2 LoginSource based on the given name | ||
func GetActiveOAuth2LoginSourceByName(name string) (*LoginSource, error) { | ||
loginSource := &LoginSource{ | ||
Name: name, | ||
Type: LoginOAuth2, | ||
IsActived: true, | ||
} | ||
|
||
has, err := x.UseBool().Get(loginSource) | ||
if !has || err != nil { | ||
return nil, err | ||
} | ||
|
||
return loginSource, nil | ||
} | ||
|
||
// GetActiveOAuth2Providers returns the map of configured active OAuth2 providers | ||
// key is used as technical name (like in the callbackURL) | ||
// values to display | ||
func GetActiveOAuth2Providers() ([]string, map[string]OAuth2Provider, error) { | ||
// Maybe also separate used and unused providers so we can force the registration of only 1 active provider for each type | ||
|
||
loginSources, err := GetActiveOAuth2ProviderLoginSources() | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
var orderedKeys []string | ||
providers := make(map[string]OAuth2Provider) | ||
for _, source := range loginSources { | ||
providers[source.Name] = OAuth2Providers[source.OAuth2().Provider] | ||
orderedKeys = append(orderedKeys, source.Name) | ||
} | ||
|
||
sort.Strings(orderedKeys) | ||
|
||
return orderedKeys, providers, nil | ||
} | ||
|
||
// InitOAuth2 initialize the OAuth2 lib and register all active OAuth2 providers in the library | ||
func InitOAuth2() { | ||
oauth2.Init() | ||
loginSources, _ := GetActiveOAuth2ProviderLoginSources() | ||
|
||
for _, source := range loginSources { | ||
oAuth2Config := source.OAuth2() | ||
oauth2.RegisterProvider(source.Name, oAuth2Config.Provider, oAuth2Config.ClientID, oAuth2Config.ClientSecret, oAuth2Config.OpenIDConnectAutoDiscoveryURL, oAuth2Config.CustomURLMapping) | ||
} | ||
} | ||
|
||
// wrapOpenIDConnectInitializeError is used to wrap the error but this cannot be done in modules/auth/oauth2 | ||
// inside oauth2: import cycle not allowed models -> modules/auth/oauth2 -> models | ||
func wrapOpenIDConnectInitializeError(err error, providerName string, oAuth2Config *OAuth2Config) error { | ||
if err != nil && "openidConnect" == oAuth2Config.Provider { | ||
err = ErrOpenIDConnectInitialize{ProviderName: providerName, OpenIDConnectAutoDiscoveryURL: oAuth2Config.OpenIDConnectAutoDiscoveryURL, Cause: err} | ||
} | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling: source.IsActive , this needs to be renamed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is reuse of existing code, so I think out of scope for this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not only that, it's also in a DB model so changing that field would require a migration :/