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

Oauth2 consumer #679

Merged
merged 47 commits into from
Feb 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
ded3513
initial stuff for oauth2 login, fails on:
willemvd Jan 10, 2017
1f94c85
login button on the signIn page to start the OAuth2 flow and a callba…
willemvd Jan 15, 2017
642f36e
Merge branch 'upstream-master' into oauth2-consumer
willemvd Jan 15, 2017
f93aad8
fix indentation
willemvd Jan 16, 2017
280913b
prevent macaron.Context in models
willemvd Jan 16, 2017
b597a86
show login button only when the OAuth2 consumer is configured (and ac…
willemvd Jan 16, 2017
8c2be7a
move overrides of goth functions to init
willemvd Jan 16, 2017
f392ce9
Merge remote-tracking branch 'upstream/master' into oauth2-consumer
willemvd Jan 16, 2017
2ba7833
create macaron group for oauth2 urls
willemvd Jan 16, 2017
8e1ea96
fix the broken url (dubble oauth2)
willemvd Jan 16, 2017
6c98fa7
no support at this moment to use this and we should only consider imp…
willemvd Jan 17, 2017
caeb911
prevent net/http in modules (other then oauth2)
willemvd Jan 23, 2017
f3f3866
use a new data sessions oauth2 folder for storing the oauth2 session …
willemvd Jan 23, 2017
047d50b
update resolving, naming and security settings of sessions oauth2 dir…
willemvd Jan 23, 2017
ab31c24
add missing 2FA when this is enabled on the user
willemvd Jan 23, 2017
fe88e87
add password option for OAuth2 user , for use with git over http and …
willemvd Jan 24, 2017
827c512
Merge remote-tracking branch 'upstream/master' into oauth2-consumer
willemvd Jan 25, 2017
83c238b
merge vendor.json incl goth library
willemvd Jan 25, 2017
c65a216
set a default provider instead of a empty option
willemvd Jan 25, 2017
914f56a
add tip for registering a GitHub OAuth application
willemvd Jan 25, 2017
b4eb93c
remove unused redirectURL
willemvd Jan 26, 2017
7a6757f
at startup of Gitea register all configured providers and also on add…
willemvd Jan 27, 2017
aae5f80
always use source.Name as provider key
willemvd Jan 27, 2017
9151dc8
custom handling of errors in oauth2 request init + show better tip
willemvd Jan 27, 2017
96d1af5
more checks if provider exists and is active (less calls to db to che…
willemvd Jan 27, 2017
c3f5d36
add ExternalLoginUser model and migration script to add it to database
willemvd Jan 27, 2017
2bf6b34
remove unused IsSocialLogin code
willemvd Jan 27, 2017
7ccbc44
create initial flow for linkAccount, todo: handle the POST of LinkAcc…
willemvd Jan 27, 2017
084c45f
link a external account to an existing account (still need to handle …
willemvd Jan 27, 2017
6594d76
remove the linked external account from the user his settings
willemvd Jan 30, 2017
19ddb15
make clear why we don't do anything here
willemvd Jan 30, 2017
57dbb74
add license header
willemvd Jan 30, 2017
32a4c58
if user is unknown we allow him to register a new account or link it …
willemvd Jan 31, 2017
770ba31
we are in 2017...
willemvd Jan 31, 2017
527d6e1
sign up with button on signin page (als change OAuth2Provider structu…
willemvd Feb 2, 2017
a7381b5
prevent panic when non-existing provider is in database or cannot be …
willemvd Feb 2, 2017
b64ee7d
fix err check so update of source is working
willemvd Feb 2, 2017
5c5214a
Merge remote-tracking branch 'upstream/master' into oauth2-consumer
willemvd Feb 5, 2017
769c747
merge master forces update of database to newer version
willemvd Feb 5, 2017
6b16f42
from gorilla/sessions docs:
willemvd Feb 6, 2017
0fa2e40
fix missed password reset
willemvd Feb 8, 2017
f54f07a
use updated goth lib that now supports getting the OAuth2 user if the…
willemvd Feb 8, 2017
873e5b7
Merge branch 'upstream-master' into oauth2-consumer
willemvd Feb 8, 2017
779e84b
manual merge the changes in signup.tmpl to signup_inner.tmpl
willemvd Feb 8, 2017
61fe261
prepare merge
willemvd Feb 21, 2017
66e28df
Merge branch 'upstream-master' into oauth2-consumer
willemvd Feb 21, 2017
2c11c44
Merge branch 'oauth2-consumer' of github.com:willemvd/gitea into oaut…
willemvd Feb 21, 2017
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
17 changes: 13 additions & 4 deletions cmd/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/go-macaron/toolbox"
"github.com/urfave/cli"
macaron "gopkg.in/macaron.v1"
context2 "github.com/gorilla/context"
)

// CmdWeb represents the available web sub-command.
Expand Down Expand Up @@ -210,6 +211,13 @@ func runWeb(ctx *cli.Context) error {
m.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
m.Get("/reset_password", user.ResetPasswd)
m.Post("/reset_password", user.ResetPasswdPost)
m.Group("/oauth2", func() {
m.Get("/:provider", user.SignInOAuth)
m.Get("/:provider/callback", user.SignInOAuthCallback)
})
m.Get("/link_account", user.LinkAccount)
m.Post("/link_account_signin", bindIgnErr(auth.SignInForm{}), user.LinkAccountPostSignIn)
m.Post("/link_account_signup", bindIgnErr(auth.RegisterForm{}), user.LinkAccountPostRegister)
m.Group("/two_factor", func() {
m.Get("", user.TwoFactor)
m.Post("", bindIgnErr(auth.TwoFactorAuthForm{}), user.TwoFactorPost)
Expand All @@ -236,6 +244,7 @@ func runWeb(ctx *cli.Context) error {
Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
m.Post("/applications/delete", user.SettingsDeleteApplication)
m.Route("/delete", "GET,POST", user.SettingsDelete)
m.Combo("/account_link").Get(user.SettingsAccountLinks).Post(user.SettingsDeleteAccountLink)
m.Group("/two_factor", func() {
m.Get("", user.SettingsTwoFactor)
m.Post("/regenerate_scratch", user.SettingsTwoFactorRegenerateScratch)
Expand Down Expand Up @@ -671,11 +680,11 @@ func runWeb(ctx *cli.Context) error {
var err error
switch setting.Protocol {
case setting.HTTP:
err = runHTTP(listenAddr, m)
err = runHTTP(listenAddr, context2.ClearHandler(m))
case setting.HTTPS:
err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, m)
err = runHTTPS(listenAddr, setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
case setting.FCGI:
err = fcgi.Serve(nil, m)
err = fcgi.Serve(nil, context2.ClearHandler(m))
case setting.UnixSocket:
if err := os.Remove(listenAddr); err != nil && !os.IsNotExist(err) {
log.Fatal(4, "Failed to remove unix socket directory %s: %v", listenAddr, err)
Expand All @@ -691,7 +700,7 @@ func runWeb(ctx *cli.Context) error {
if err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission)); err != nil {
log.Fatal(4, "Failed to set permission of unix socket: %v", err)
}
err = http.Serve(listener, m)
err = http.Serve(listener, context2.ClearHandler(m))
default:
log.Fatal(4, "Invalid protocol: %s", setting.Protocol)
}
Expand Down
40 changes: 40 additions & 0 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -847,3 +847,43 @@ func IsErrUploadNotExist(err error) bool {
func (err ErrUploadNotExist) Error() string {
return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID)
}

// ___________ __ .__ .____ .__ ____ ___
// \_ _____/__ ____/ |_ ___________ ____ _____ | | | | ____ ____ |__| ____ | | \______ ___________
// | __)_\ \/ /\ __\/ __ \_ __ \/ \\__ \ | | | | / _ \ / ___\| |/ \ | | / ___// __ \_ __ \
// | \> < | | \ ___/| | \/ | \/ __ \| |__ | |__( <_> ) /_/ > | | \ | | /\___ \\ ___/| | \/
// /_______ /__/\_ \ |__| \___ >__| |___| (____ /____/ |_______ \____/\___ /|__|___| / |______//____ >\___ >__|
// \/ \/ \/ \/ \/ \/ /_____/ \/ \/ \/

// ErrExternalLoginUserAlreadyExist represents a "ExternalLoginUserAlreadyExist" kind of error.
type ErrExternalLoginUserAlreadyExist struct {
ExternalID string
UserID int64
LoginSourceID int64
}

// IsErrExternalLoginUserAlreadyExist checks if an error is a ExternalLoginUserAlreadyExist.
func IsErrExternalLoginUserAlreadyExist(err error) bool {
_, ok := err.(ErrExternalLoginUserAlreadyExist)
return ok
}

func (err ErrExternalLoginUserAlreadyExist) Error() string {
return fmt.Sprintf("external login user already exists [externalID: %s, userID: %d, loginSourceID: %d]", err.ExternalID, err.UserID, err.LoginSourceID)
}

// ErrExternalLoginUserNotExist represents a "ExternalLoginUserNotExist" kind of error.
type ErrExternalLoginUserNotExist struct {
UserID int64
LoginSourceID int64
}

// IsErrExternalLoginUserNotExist checks if an error is a ExternalLoginUserNotExist.
func IsErrExternalLoginUserNotExist(err error) bool {
_, ok := err.(ErrExternalLoginUserNotExist)
return ok
}

func (err ErrExternalLoginUserNotExist) Error() string {
return fmt.Sprintf("external login user link does not exists [userID: %d, loginSourceID: %d]", err.UserID, err.LoginSourceID)
}
74 changes: 74 additions & 0 deletions models/external_login_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// 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 "github.com/markbates/goth"

// ExternalLoginUser makes the connecting between some existing user and additional external login sources
type ExternalLoginUser struct {
ExternalID string `xorm:"NOT NULL"`
UserID int64 `xorm:"NOT NULL"`
LoginSourceID int64 `xorm:"NOT NULL"`
}

// GetExternalLogin checks if a externalID in loginSourceID scope already exists
func GetExternalLogin(externalLoginUser *ExternalLoginUser) (bool, error) {
return x.Get(externalLoginUser)
}

// ListAccountLinks returns a map with the ExternalLoginUser and its LoginSource
func ListAccountLinks(user *User) ([]*ExternalLoginUser, error) {
externalAccounts := make([]*ExternalLoginUser, 0, 5)
err := x.Where("user_id=?", user.ID).
Desc("login_source_id").
Find(&externalAccounts)

if err != nil {
return nil, err
}

return externalAccounts, nil
}

// LinkAccountToUser link the gothUser to the user
func LinkAccountToUser(user *User, gothUser goth.User) error {
loginSource, err := GetActiveOAuth2LoginSourceByName(gothUser.Provider)
if err != nil {
return err
}

externalLoginUser := &ExternalLoginUser{
ExternalID: gothUser.UserID,
UserID: user.ID,
LoginSourceID: loginSource.ID,
}
has, err := x.Get(externalLoginUser)
if err != nil {
return err
} else if has {
return ErrExternalLoginUserAlreadyExist{gothUser.UserID, user.ID, loginSource.ID}
}

_, err = x.Insert(externalLoginUser)
return err
}

// RemoveAccountLink will remove all external login sources for the given user
func RemoveAccountLink(user *User, loginSourceID int64) (int64, error) {
deleted, err := x.Delete(&ExternalLoginUser{UserID: user.ID, LoginSourceID: loginSourceID})
if err != nil {
return deleted, err
}
if deleted < 1 {
return deleted, ErrExternalLoginUserNotExist{user.ID, loginSourceID}
}
return deleted, err
}

// RemoveAllAccountLinks will remove all external login sources for the given user
func RemoveAllAccountLinks(user *User) error {
_, err := x.Delete(&ExternalLoginUser{UserID: user.ID})
return err
}
Loading