-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Oauth2 consumer #679
Conversation
import cycle not allowed package main imports code.gitea.io/gitea/cmd imports code.gitea.io/gitea/models imports code.gitea.io/gitea/modules/auth/oauth2 imports code.gitea.io/gitea/modules/context imports code.gitea.io/gitea/models
…ck for each provider Only GitHub is implemented for now
# Conflicts: # public/js/index.js
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.
A couple of things. macaron.Context
does not belong in models/
, if it's in there that's a bug that we should not encourage 🙂
Otherwise AWESOME
models/login_source.go
Outdated
@@ -217,6 +247,8 @@ func (source *LoginSource) UseTLS() bool { | |||
return source.LDAP().SecurityProtocol != ldap.SecurityProtocolUnencrypted | |||
case LoginSMTP: | |||
return source.SMTP().TLS | |||
case LoginOAuth2: | |||
return true |
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.
You need to verify this...
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 sure how to use this property correct if we are doing a call to the OAuth2 provider, suggestions?
@@ -266,7 +303,7 @@ func CreateLoginSource(source *LoginSource) error { | |||
|
|||
// LoginSources returns a slice of all login sources found in DB. | |||
func LoginSources() ([]*LoginSource, error) { | |||
auths := make([]*LoginSource, 0, 5) | |||
auths := make([]*LoginSource, 0, 6) |
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.
Can we maybe use len(LoginNames)
instead of a hard-coded value?
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 can be any value, since it will look for all the configured login sources (and so depends on the environment how many this will be)
@@ -444,7 +481,7 @@ func LoginViaSMTP(user *User, login, password string, sourceID int64, cfg *SMTPC | |||
idx := strings.Index(login, "@") | |||
if idx == -1 { | |||
return nil, ErrUserNotExist{0, login, 0} | |||
} else if !com.IsSliceContainsStr(strings.Split(cfg.AllowedDomains, ","), login[idx+1:]) { | |||
} else if !com.IsSliceContainsStr(strings.Split(cfg.AllowedDomains, ","), login[idx + 1:]) { |
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.
Is this done by gofmt
? otherwise revert this line
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.
gofmt did this
models/login_source.go
Outdated
|
||
// LoginViaOAuth2 queries if login/password is valid against the OAuth2.0 provider, | ||
// and create a local user if success when enabled. | ||
func LoginViaOAuth2(cfg *OAuth2Config, ctx *macaron.Context, sess session.Store) { |
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.
macaron.Context
does not belong in models/
...
models/login_source.go
Outdated
// ExternalUserLogin attempts a login using external source types. | ||
func ExternalUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool) (*User, error) { | ||
func ExternalUserLogin(user *User, login, password string, source *LoginSource, autoRegister bool, ctx *macaron.Context, sess session.Store) (*User, error) { |
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.
same as above...
} | ||
} | ||
|
||
sources := make([]*LoginSource, 0, 3) | ||
sources := make([]*LoginSource, 0, 5) |
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.
len(...) - 1
?
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 will lookup all activated loginSources, so this cannot be determined up front
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.
You added a single LoginSource but you incremented this number by 2, either there's a bug in current code (short count) or in your patch (long count) ?
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.
see comment above, this can be any value because it is fetched from the database and so unpredictable, so what ever you want 😄
modules/auth/oauth2/oauth2.go
Outdated
) | ||
|
||
func init() { | ||
gothic.Store = sessions.NewFilesystemStore(os.TempDir(), []byte(sessionUsersStoreKey)) |
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.
Gitea has a defined session-dir and a temp-dir :)
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.
will use that!
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.
Think you mean : setting.SessionConfig.ProviderConfig = "data/sessions" ?
But this seems only valid when the session provider is file and not for instance memory
modules/auth/oauth2/oauth2.go
Outdated
request := ctx.Req.Request | ||
response := ctx.Resp | ||
|
||
/* |
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.
Commented out code?
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.
yes part that I still need to have a look at. Need to check if it is required to do custom storing to determine valid requests in the callback
templates/admin/auth/edit.tmpl
Outdated
<!-- OAuth2 --> | ||
{{if .Source.IsOAuth2}} | ||
{{ $cfg:=.Source.OAuth2 }} | ||
<div class="inline required field"> |
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.
Indentation
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.
will use proper tabs :)
templates/admin/auth/new.tmpl
Outdated
<!-- OAuth2 --> | ||
<div class="oauth2 field {{if not (eq .type 6)}}hide{{end}}"> | ||
<div class="inline required field"> | ||
<label>{{.i18n.Tr "admin.auths.oauth2_provider"}}</label> |
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.
Indentation
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.
will use proper tabs
macaron.Context is indeed a parameter that I added at some early stage, looked like the request was not properly filled in our own context when handling the callback. I will check if that is still needed |
@bkcsoft found out why I needed the macaron.Context instead of our own context: Maybe I can fix it by making a new oauth2 context in modules/auth/oauth2 and have the request and session in that as well? |
Changed the code a bit, so now the request, response and session are sent into the oauth2 module. This will prevent the import cycle and no macaron.Context is send around |
…tivated) remove the use of sessions in our own code for validating request
# Conflicts: # cmd/web.go
…lementing SkipVerify (waiting for markbates/goth#87)
@bkcsoft resolved issues and did some cleanup of the code, could you please have another look (also on my comments on you previous review) |
@willemvd I'm still not exactly happy about passing around request/response either (essentially the same as passing around context...) what are they used? can't you just get what you need from them (variables) and pass that? |
It seems not totally right, I agree.. Point is that the goth library requires the original request in it's method signatures and uses it for redirecting the client to the OAuth2 provider (http.Redirect : https://github.com/markbates/goth/blob/master/gothic/gothic.go#L55) |
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.
that should fix it
models/login_source.go
Outdated
|
||
// LoginViaOAuth2 queries if login/password is valid against the OAuth2.0 provider, | ||
// and create a local user if success when enabled. | ||
func LoginViaOAuth2(cfg *OAuth2Config, request *http.Request, response http.ResponseWriter) { |
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.
Move this to modules to fix one request/response-issue
models/login_source.go
Outdated
@@ -596,3 +650,90 @@ func UserSignIn(username, password string) (*User, error) { | |||
|
|||
return nil, ErrUserNotExist{user.ID, user.Name, 0} | |||
} | |||
|
|||
// OAuth2UserLogin attempts a login using a OAuth2 source type | |||
func OAuth2UserLogin(provider string, request *http.Request, response http.ResponseWriter) (*User, error) { |
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.
Same with this
models/login_source.go
Outdated
|
||
// OAuth2UserLoginCallback attempts to handle the callback from the OAuth2 provider and if successful | ||
// login the user | ||
func OAuth2UserLoginCallback(provider string, request *http.Request, response http.ResponseWriter) (*User, string, error) { |
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.
And this
Changed it from WIP to final , please review 😄 |
modules/auth/oauth2/oauth2.go
Outdated
) | ||
|
||
func init() { | ||
gothic.Store = sessions.NewFilesystemStore(os.TempDir(), []byte(sessionUsersStoreKey)) |
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.
Please prefix the directory with gitea-
:)
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.
changed it to use a new data/sessions/oauth2 folder based on the setting.WorkDir method
I just noticed another nasty consequence of having User.LoginType set to OAuth2: the User.IsLocal method would return I keep thinking that User.LoginType should still only refer to the LoginSource to which the username/password pairs are to be sent, if anywhere (probably "LoginPlain" for these external-login-associated accounts, or "LoginNone" once it'll be supported) |
… AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider)
# Conflicts: # templates/user/auth/signup.tmpl
Added the missed password reset and added an enhancement from goth where you can get the user if the OAuth2 AccessToken is still valid instead of re-authenticating (prevent flooding the OAuth2 provider with grant access requests) |
Also fixed a merge conflict |
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.
I think a rebase/merge was messed up. The new migration has to go at the end.
models/migrations/migrations.go
Outdated
@@ -80,7 +80,9 @@ var migrations = []Migration{ | |||
NewMigration("create user column diff view style", createUserColumnDiffViewStyle), | |||
// v15 -> v16 | |||
NewMigration("create user column allow create organization", createAllowCreateOrganizationColumn), | |||
// v16 | |||
// V16 -> v17 | |||
NewMigration("create repo unit table and add units for all repos", addUnitsToTables), |
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 has to go at the end of the list
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.
there was a new one added in master, mine is after this one
https://github.com/go-gitea/gitea/pull/679/files#diff-7366023de6e87b891be868e3b8cf68e6R85-R86
models/migrations/v16.go
Outdated
// Copyright 2016 Gitea. All rights reserved. | ||
// Use of this source code is governed by a MIT-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package migrations |
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.
Why was the copyright-header removed?
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.
it seems to be missing in master (https://github.com/go-gitea/gitea/blob/master/models/migrations/v16.go) and merged removed this, mine is v17.go
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.
Created #992 to fix this missing header in master
@bkcsoft please look at my comments, code from master is "broken" so that's why the merge looks messed up but isn't |
When the changed are done you have my LGTM 😄 |
@bkcsoft what do you mean? For the missing copyright header in v16.go, I will create a new PR (since this is already wrong in the master) Agree? |
@willemvd That explains it 😄 Fix the conflicts and you have my LGTM |
hint: rename v17 to v18 before rebasing again to master |
# Conflicts: # models/migrations/migrations.go
LGTM :) |
make L-G-T-M work! |
This is a WIP PR for issue #26
The OAuth2 login is configured as a new LoginSource, but with an alternative flow since this also involves callbacks from the OAuth2 provider.
For now the only implemented OAuth2 provider is GitHub
Outstanding points are the TODO's like fixing the login button to be only displayed when a OAuth2 provider is specified.