mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 00:20:25 +08:00 
			
		
		
		
	Refactor Find Sources and fix bug when view a user who belongs to an unactive auth source (#27798)
The steps to reproduce it. First, create a new oauth2 source. Then, a user login with this oauth2 source. Disable the oauth2 source. Visit users -> settings -> security, 500 will be displayed. This is because this page only load active Oauth2 sources but not all Oauth2 sources.
This commit is contained in:
		@@ -11,6 +11,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/models/db"
 | 
			
		||||
	user_model "code.gitea.io/gitea/models/user"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	"code.gitea.io/gitea/services/auth/source/oauth2"
 | 
			
		||||
	"code.gitea.io/gitea/services/auth/source/smtp"
 | 
			
		||||
 | 
			
		||||
@@ -85,7 +86,9 @@ func UserSignIn(ctx context.Context, username, password string) (*user_model.Use
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sources, err := auth.AllActiveSources(ctx)
 | 
			
		||||
	sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
 | 
			
		||||
		IsActive: util.OptionalBoolTrue,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/models/auth"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
	"github.com/gorilla/sessions"
 | 
			
		||||
@@ -63,7 +64,13 @@ func ResetOAuth2(ctx context.Context) error {
 | 
			
		||||
 | 
			
		||||
// initOAuth2Sources is used to load and register all active OAuth2 providers
 | 
			
		||||
func initOAuth2Sources(ctx context.Context) error {
 | 
			
		||||
	authSources, _ := auth.GetActiveOAuth2ProviderSources(ctx)
 | 
			
		||||
	authSources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
 | 
			
		||||
		IsActive:  util.OptionalBoolTrue,
 | 
			
		||||
		LoginType: auth.OAuth2,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for _, source := range authSources {
 | 
			
		||||
		oauth2Source, ok := source.Cfg.(*Source)
 | 
			
		||||
		if !ok {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/models/auth"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/markbates/goth"
 | 
			
		||||
)
 | 
			
		||||
@@ -80,10 +81,10 @@ func RegisterGothProvider(provider GothProvider) {
 | 
			
		||||
	gothProviders[provider.Name()] = provider
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetOAuth2Providers returns the map of unconfigured OAuth2 providers
 | 
			
		||||
// GetSupportedOAuth2Providers returns the map of unconfigured OAuth2 providers
 | 
			
		||||
// key is used as technical name (like in the callbackURL)
 | 
			
		||||
// values to display
 | 
			
		||||
func GetOAuth2Providers() []Provider {
 | 
			
		||||
func GetSupportedOAuth2Providers() []Provider {
 | 
			
		||||
	providers := make([]Provider, 0, len(gothProviders))
 | 
			
		||||
 | 
			
		||||
	for _, provider := range gothProviders {
 | 
			
		||||
@@ -95,33 +96,39 @@ func GetOAuth2Providers() []Provider {
 | 
			
		||||
	return providers
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetActiveOAuth2Providers returns the map of configured active OAuth2 providers
 | 
			
		||||
// key is used as technical name (like in the callbackURL)
 | 
			
		||||
// values to display
 | 
			
		||||
func GetActiveOAuth2Providers(ctx context.Context) ([]string, map[string]Provider, error) {
 | 
			
		||||
	// Maybe also separate used and unused providers so we can force the registration of only 1 active provider for each type
 | 
			
		||||
func CreateProviderFromSource(source *auth.Source) (Provider, error) {
 | 
			
		||||
	oauth2Cfg, ok := source.Cfg.(*Source)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, fmt.Errorf("invalid OAuth2 source config: %v", oauth2Cfg)
 | 
			
		||||
	}
 | 
			
		||||
	gothProv := gothProviders[oauth2Cfg.Provider]
 | 
			
		||||
	return &AuthSourceProvider{GothProvider: gothProv, sourceName: source.Name, iconURL: oauth2Cfg.IconURL}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	authSources, err := auth.GetActiveOAuth2ProviderSources(ctx)
 | 
			
		||||
// GetOAuth2Providers returns the list of configured OAuth2 providers
 | 
			
		||||
func GetOAuth2Providers(ctx context.Context, isActive util.OptionalBool) ([]Provider, error) {
 | 
			
		||||
	authSources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
 | 
			
		||||
		IsActive:  isActive,
 | 
			
		||||
		LoginType: auth.OAuth2,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var orderedKeys []string
 | 
			
		||||
	providers := make(map[string]Provider)
 | 
			
		||||
	providers := make([]Provider, 0, len(authSources))
 | 
			
		||||
	for _, source := range authSources {
 | 
			
		||||
		oauth2Cfg, ok := source.Cfg.(*Source)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			log.Error("Invalid OAuth2 source config: %v", oauth2Cfg)
 | 
			
		||||
			continue
 | 
			
		||||
		provider, err := CreateProviderFromSource(source)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		gothProv := gothProviders[oauth2Cfg.Provider]
 | 
			
		||||
		providers[source.Name] = &AuthSourceProvider{GothProvider: gothProv, sourceName: source.Name, iconURL: oauth2Cfg.IconURL}
 | 
			
		||||
		orderedKeys = append(orderedKeys, source.Name)
 | 
			
		||||
		providers = append(providers, provider)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sort.Strings(orderedKeys)
 | 
			
		||||
	sort.Slice(providers, func(i, j int) bool {
 | 
			
		||||
		return providers[i].Name() < providers[j].Name()
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return orderedKeys, providers, nil
 | 
			
		||||
	return providers, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RegisterProviderWithGothic register a OAuth2 provider in goth lib
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,10 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore,
 | 
			
		||||
 | 
			
		||||
// getConfig retrieves the SSPI configuration from login sources
 | 
			
		||||
func (s *SSPI) getConfig(ctx context.Context) (*sspi.Source, error) {
 | 
			
		||||
	sources, err := auth.ActiveSources(ctx, auth.SSPI)
 | 
			
		||||
	sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
 | 
			
		||||
		IsActive:  util.OptionalBoolTrue,
 | 
			
		||||
		LoginType: auth.SSPI,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import (
 | 
			
		||||
func SyncExternalUsers(ctx context.Context, updateExisting bool) error {
 | 
			
		||||
	log.Trace("Doing: SyncExternalUsers")
 | 
			
		||||
 | 
			
		||||
	ls, err := auth.Sources(ctx)
 | 
			
		||||
	ls, err := auth.FindSources(ctx, auth.FindSourcesOptions{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("SyncExternalUsers: %v", err)
 | 
			
		||||
		return err
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user