summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorWillem van Dreumel <willemvd@users.noreply.github.com>2017-05-01 15:26:53 +0200
committerLunny Xiao <xiaolunwen@gmail.com>2017-05-01 21:26:53 +0800
commit950f2e207413551b868252a1bced6ce9263d16d4 (patch)
treeb01a330af11c7f8b9e2d1461685d9afb2ae9e485 /modules
parent2368bbb6727ea5497743c0fdade723b49693cb4c (diff)
downloadgitea-950f2e207413551b868252a1bced6ce9263d16d4.tar.gz
gitea-950f2e207413551b868252a1bced6ce9263d16d4.zip
Additional OAuth2 providers (#1010)
* add google+ * sort signin oauth2 providers based on the name so order is always the same * update auth tip for google+ * add gitlab provider * add bitbucket provider (and some go fmt) * add twitter provider * add facebook provider * add dropbox provider * add openid connect provider incl. new format of tips section in "Add New Source" * lower the amount of disk storage for each session to prevent issues while building cross platform (and disk overflow) * imports according to goimport and code style * make it possible to set custom urls to gitlab and github provider (only these could have a different host) * split up oauth2 into multiple files * small typo in comment * fix indention * fix indentation * fix new line before external import * fix layout of signin part * update "broken" dependency
Diffstat (limited to 'modules')
-rw-r--r--modules/auth/auth_form.go62
-rw-r--r--modules/auth/oauth2/oauth2.go133
2 files changed, 159 insertions, 36 deletions
diff --git a/modules/auth/auth_form.go b/modules/auth/auth_form.go
index 338be53457..8dc039835f 100644
--- a/modules/auth/auth_form.go
+++ b/modules/auth/auth_form.go
@@ -11,34 +11,40 @@ import (
// AuthenticationForm form for authentication
type AuthenticationForm struct {
- ID int64
- Type int `binding:"Range(2,6)"`
- Name string `binding:"Required;MaxSize(30)"`
- Host string
- Port int
- BindDN string
- BindPassword string
- UserBase string
- UserDN string
- AttributeUsername string
- AttributeName string
- AttributeSurname string
- AttributeMail string
- AttributesInBind bool
- Filter string
- AdminFilter string
- IsActive bool
- SMTPAuth string
- SMTPHost string
- SMTPPort int
- AllowedDomains string
- SecurityProtocol int `binding:"Range(0,2)"`
- TLS bool
- SkipVerify bool
- PAMServiceName string
- Oauth2Provider string
- Oauth2Key string
- Oauth2Secret string
+ ID int64
+ Type int `binding:"Range(2,6)"`
+ Name string `binding:"Required;MaxSize(30)"`
+ Host string
+ Port int
+ BindDN string
+ BindPassword string
+ UserBase string
+ UserDN string
+ AttributeUsername string
+ AttributeName string
+ AttributeSurname string
+ AttributeMail string
+ AttributesInBind bool
+ Filter string
+ AdminFilter string
+ IsActive bool
+ SMTPAuth string
+ SMTPHost string
+ SMTPPort int
+ AllowedDomains string
+ SecurityProtocol int `binding:"Range(0,2)"`
+ TLS bool
+ SkipVerify bool
+ PAMServiceName string
+ Oauth2Provider string
+ Oauth2Key string
+ Oauth2Secret string
+ OpenIDConnectAutoDiscoveryURL string
+ Oauth2UseCustomURL bool
+ Oauth2TokenURL string
+ Oauth2AuthURL string
+ Oauth2ProfileURL string
+ Oauth2EmailURL string
}
// Validate validates fields
diff --git a/modules/auth/oauth2/oauth2.go b/modules/auth/oauth2/oauth2.go
index ca4cde73b6..4584c48db7 100644
--- a/modules/auth/oauth2/oauth2.go
+++ b/modules/auth/oauth2/oauth2.go
@@ -5,6 +5,7 @@
package oauth2
import (
+ "math"
"net/http"
"os"
"path/filepath"
@@ -15,7 +16,14 @@ import (
"github.com/gorilla/sessions"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
+ "github.com/markbates/goth/providers/bitbucket"
+ "github.com/markbates/goth/providers/dropbox"
+ "github.com/markbates/goth/providers/facebook"
"github.com/markbates/goth/providers/github"
+ "github.com/markbates/goth/providers/gitlab"
+ "github.com/markbates/goth/providers/gplus"
+ "github.com/markbates/goth/providers/openidConnect"
+ "github.com/markbates/goth/providers/twitter"
"github.com/satori/go.uuid"
)
@@ -24,6 +32,14 @@ var (
providerHeaderKey = "gitea-oauth2-provider"
)
+// CustomURLMapping describes the urls values to use when customizing OAuth2 provider URLs
+type CustomURLMapping struct {
+ AuthURL string
+ TokenURL string
+ ProfileURL string
+ EmailURL string
+}
+
// Init initialize the setup of the OAuth2 library
func Init() {
sessionDir := filepath.Join(setting.AppDataPath, "sessions", "oauth2")
@@ -31,7 +47,15 @@ func Init() {
log.Fatal(4, "Fail to create dir %s: %v", sessionDir, err)
}
- gothic.Store = sessions.NewFilesystemStore(sessionDir, []byte(sessionUsersStoreKey))
+ store := sessions.NewFilesystemStore(sessionDir, []byte(sessionUsersStoreKey))
+ // according to the Goth lib:
+ // set the maxLength of the cookies stored on the disk to a larger number to prevent issues with:
+ // securecookie: the value is too long
+ // when using OpenID Connect , since this can contain a large amount of extra information in the id_token
+
+ // Note, when using the FilesystemStore only the session.ID is written to a browser cookie, so this is explicit for the storage on disk
+ store.MaxLength(math.MaxInt16)
+ gothic.Store = store
gothic.SetState = func(req *http.Request) string {
return uuid.NewV4().String()
@@ -74,12 +98,14 @@ func ProviderCallback(provider string, request *http.Request, response http.Resp
}
// RegisterProvider register a OAuth2 provider in goth lib
-func RegisterProvider(providerName, providerType, clientID, clientSecret string) {
- provider := createProvider(providerName, providerType, clientID, clientSecret)
+func RegisterProvider(providerName, providerType, clientID, clientSecret, openIDConnectAutoDiscoveryURL string, customURLMapping *CustomURLMapping) error {
+ provider, err := createProvider(providerName, providerType, clientID, clientSecret, openIDConnectAutoDiscoveryURL, customURLMapping)
- if provider != nil {
+ if err == nil && provider != nil {
goth.UseProviders(provider)
}
+
+ return err
}
// RemoveProvider removes the given OAuth2 provider from the goth lib
@@ -88,20 +114,111 @@ func RemoveProvider(providerName string) {
}
// used to create different types of goth providers
-func createProvider(providerName, providerType, clientID, clientSecret string) goth.Provider {
+func createProvider(providerName, providerType, clientID, clientSecret, openIDConnectAutoDiscoveryURL string, customURLMapping *CustomURLMapping) (goth.Provider, error) {
callbackURL := setting.AppURL + "user/oauth2/" + providerName + "/callback"
var provider goth.Provider
+ var err error
switch providerType {
+ case "bitbucket":
+ provider = bitbucket.New(clientID, clientSecret, callbackURL, "account")
+ case "dropbox":
+ provider = dropbox.New(clientID, clientSecret, callbackURL)
+ case "facebook":
+ provider = facebook.New(clientID, clientSecret, callbackURL, "email")
case "github":
- provider = github.New(clientID, clientSecret, callbackURL, "user:email")
+ authURL := github.AuthURL
+ tokenURL := github.TokenURL
+ profileURL := github.ProfileURL
+ emailURL := github.EmailURL
+ if customURLMapping != nil {
+ if len(customURLMapping.AuthURL) > 0 {
+ authURL = customURLMapping.AuthURL
+ }
+ if len(customURLMapping.TokenURL) > 0 {
+ tokenURL = customURLMapping.TokenURL
+ }
+ if len(customURLMapping.ProfileURL) > 0 {
+ profileURL = customURLMapping.ProfileURL
+ }
+ if len(customURLMapping.EmailURL) > 0 {
+ emailURL = customURLMapping.EmailURL
+ }
+ }
+ provider = github.NewCustomisedURL(clientID, clientSecret, callbackURL, authURL, tokenURL, profileURL, emailURL)
+ case "gitlab":
+ authURL := gitlab.AuthURL
+ tokenURL := gitlab.TokenURL
+ profileURL := gitlab.ProfileURL
+ if customURLMapping != nil {
+ if len(customURLMapping.AuthURL) > 0 {
+ authURL = customURLMapping.AuthURL
+ }
+ if len(customURLMapping.TokenURL) > 0 {
+ tokenURL = customURLMapping.TokenURL
+ }
+ if len(customURLMapping.ProfileURL) > 0 {
+ profileURL = customURLMapping.ProfileURL
+ }
+ }
+ provider = gitlab.NewCustomisedURL(clientID, clientSecret, callbackURL, authURL, tokenURL, profileURL)
+ case "gplus":
+ provider = gplus.New(clientID, clientSecret, callbackURL, "email")
+ case "openidConnect":
+ if provider, err = openidConnect.New(clientID, clientSecret, callbackURL, openIDConnectAutoDiscoveryURL); err != nil {
+ log.Warn("Failed to create OpenID Connect Provider with name '%s' with url '%s': %v", providerName, openIDConnectAutoDiscoveryURL, err)
+ }
+ case "twitter":
+ provider = twitter.NewAuthenticate(clientID, clientSecret, callbackURL)
}
// always set the name if provider is created so we can support multiple setups of 1 provider
- if provider != nil {
+ if err == nil && provider != nil {
provider.SetName(providerName)
}
- return provider
+ return provider, err
+}
+
+// GetDefaultTokenURL return the default token url for the given provider
+func GetDefaultTokenURL(provider string) string {
+ switch provider {
+ case "github":
+ return github.TokenURL
+ case "gitlab":
+ return gitlab.TokenURL
+ }
+ return ""
+}
+
+// GetDefaultAuthURL return the default authorize url for the given provider
+func GetDefaultAuthURL(provider string) string {
+ switch provider {
+ case "github":
+ return github.AuthURL
+ case "gitlab":
+ return gitlab.AuthURL
+ }
+ return ""
+}
+
+// GetDefaultProfileURL return the default profile url for the given provider
+func GetDefaultProfileURL(provider string) string {
+ switch provider {
+ case "github":
+ return github.ProfileURL
+ case "gitlab":
+ return gitlab.ProfileURL
+ }
+ return ""
+}
+
+// GetDefaultEmailURL return the default email url for the given provider
+func GetDefaultEmailURL(provider string) string {
+ switch provider {
+ case "github":
+ return github.EmailURL
+ }
+ return ""
}