Lock goth/gothic and Re-attempt OAuth2 registration on login if registration failed at startup (#16564)

This PR has two parts:

* Add locking to goth and gothic calls with a RWMutex

The goth and gothic calls are currently unlocked and thus are a cause of multiple potential races

* Reattempt OAuth2 registration on login if registration failed

If OAuth2 registration fails at startup we currently disable the login_source however an alternative approach could be to reattempt registration on login attempt.
    
Fix #16096

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2021-07-29 18:53:18 +01:00 committed by GitHub
parent b9a0e33238
commit 72738f0cb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 6 deletions

View file

@ -6,6 +6,7 @@ package oauth2
import (
"net/http"
"sync"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
@ -15,6 +16,8 @@ import (
"github.com/markbates/goth/gothic"
)
var gothRWMutex = sync.RWMutex{}
// SessionTableName is the table name that OAuth2 will use to store things
const SessionTableName = "oauth2_session"
@ -42,6 +45,10 @@ func Init() error {
// 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(setting.OAuth2.MaxTokenLength)
// Lock our mutex
gothRWMutex.Lock()
gothic.Store = store
gothic.SetState = func(req *http.Request) string {
@ -52,6 +59,9 @@ func Init() error {
return req.Header.Get(ProviderHeaderKey), nil
}
// Unlock our mutex
gothRWMutex.Unlock()
return initOAuth2LoginSources()
}
@ -71,12 +81,7 @@ func initOAuth2LoginSources() error {
}
err := oauth2Source.RegisterSource()
if err != nil {
log.Critical("Unable to register source: %s due to Error: %v. This source will be disabled.", source.Name, err)
source.IsActive = false
if err = models.UpdateSource(source); err != nil {
log.Critical("Unable to update source %s to disable it. Error: %v", err)
return err
}
log.Critical("Unable to register source: %s due to Error: %v.", source.Name, err)
}
}
return nil