Skip to content
Merged
Changes from 1 commit
Commits
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
Next Next commit
Add locking to goth and gothic calls with a RWMutex
Signed-off-by: Andrew Thornton <[email protected]>
  • Loading branch information
zeripath committed Jul 27, 2021
commit 73c03f5e727d9b3f7292c6edd2b629b322dcc453
21 changes: 21 additions & 0 deletions modules/auth/oauth2/oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package oauth2
import (
"net/http"
"net/url"
"sync"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
Expand Down Expand Up @@ -34,6 +35,7 @@ import (
var (
sessionUsersStoreKey = "gitea-oauth2-sessions"
providerHeaderKey = "gitea-oauth2-provider"
gothRWMutex = sync.RWMutex{}
)

// CustomURLMapping describes the urls values to use when customizing OAuth2 provider URLs
Expand All @@ -60,6 +62,10 @@ func Init(x *xorm.Engine) 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)

gothRWMutex.Lock()
defer gothRWMutex.Unlock()

gothic.Store = store

gothic.SetState = func(req *http.Request) string {
Expand All @@ -82,6 +88,9 @@ func Auth(provider string, request *http.Request, response http.ResponseWriter)
// normally the gothic library will write some custom stuff to the response instead of our own nice error page
//gothic.BeginAuthHandler(response, request)

gothRWMutex.RLock()
defer gothRWMutex.RUnlock()

url, err := gothic.GetAuthURL(response, request)
if err == nil {
http.Redirect(response, request, url, http.StatusTemporaryRedirect)
Expand All @@ -95,6 +104,9 @@ func ProviderCallback(provider string, request *http.Request, response http.Resp
// not sure if goth is thread safe (?) when using multiple providers
request.Header.Set(providerHeaderKey, provider)

gothRWMutex.RLock()
defer gothRWMutex.RUnlock()

user, err := gothic.CompleteUserAuth(response, request)
if err != nil {
return user, err
Expand All @@ -108,6 +120,9 @@ func RegisterProvider(providerName, providerType, clientID, clientSecret, openID
provider, err := createProvider(providerName, providerType, clientID, clientSecret, openIDConnectAutoDiscoveryURL, customURLMapping)

if err == nil && provider != nil {
gothRWMutex.Lock()
defer gothRWMutex.Unlock()

goth.UseProviders(provider)
}

Expand All @@ -116,11 +131,17 @@ func RegisterProvider(providerName, providerType, clientID, clientSecret, openID

// RemoveProvider removes the given OAuth2 provider from the goth lib
func RemoveProvider(providerName string) {
gothRWMutex.Lock()
defer gothRWMutex.Unlock()

delete(goth.GetProviders(), providerName)
}

// ClearProviders clears all OAuth2 providers from the goth lib
func ClearProviders() {
gothRWMutex.Lock()
defer gothRWMutex.Unlock()

goth.ClearProviders()
}

Expand Down