code.gitea.io/gitea@v1.21.7/services/auth/source/oauth2/providers_custom.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package oauth2
     5  
     6  import (
     7  	"code.gitea.io/gitea/modules/setting"
     8  
     9  	"github.com/markbates/goth"
    10  	"github.com/markbates/goth/providers/azureadv2"
    11  	"github.com/markbates/goth/providers/gitea"
    12  	"github.com/markbates/goth/providers/github"
    13  	"github.com/markbates/goth/providers/gitlab"
    14  	"github.com/markbates/goth/providers/mastodon"
    15  	"github.com/markbates/goth/providers/nextcloud"
    16  )
    17  
    18  // CustomProviderNewFn creates a goth.Provider using a custom url mapping
    19  type CustomProviderNewFn func(clientID, secret, callbackURL string, custom *CustomURLMapping, scopes []string) (goth.Provider, error)
    20  
    21  // CustomProvider is a GothProvider that has CustomURL features
    22  type CustomProvider struct {
    23  	BaseProvider
    24  	customURLSettings *CustomURLSettings
    25  	newFn             CustomProviderNewFn
    26  }
    27  
    28  // CustomURLSettings returns the CustomURLSettings for this provider
    29  func (c *CustomProvider) CustomURLSettings() *CustomURLSettings {
    30  	return c.customURLSettings
    31  }
    32  
    33  // CreateGothProvider creates a GothProvider from this Provider
    34  func (c *CustomProvider) CreateGothProvider(providerName, callbackURL string, source *Source) (goth.Provider, error) {
    35  	custom := c.customURLSettings.OverrideWith(source.CustomURLMapping)
    36  
    37  	return c.newFn(source.ClientID, source.ClientSecret, callbackURL, custom, source.Scopes)
    38  }
    39  
    40  // NewCustomProvider is a constructor function for custom providers
    41  func NewCustomProvider(name, displayName string, customURLSetting *CustomURLSettings, newFn CustomProviderNewFn) *CustomProvider {
    42  	return &CustomProvider{
    43  		BaseProvider: BaseProvider{
    44  			name:        name,
    45  			displayName: displayName,
    46  		},
    47  		customURLSettings: customURLSetting,
    48  		newFn:             newFn,
    49  	}
    50  }
    51  
    52  var _ GothProvider = &CustomProvider{}
    53  
    54  func init() {
    55  	RegisterGothProvider(NewCustomProvider(
    56  		"github", "GitHub", &CustomURLSettings{
    57  			TokenURL:   availableAttribute(github.TokenURL),
    58  			AuthURL:    availableAttribute(github.AuthURL),
    59  			ProfileURL: availableAttribute(github.ProfileURL),
    60  			EmailURL:   availableAttribute(github.EmailURL),
    61  		},
    62  		func(clientID, secret, callbackURL string, custom *CustomURLMapping, scopes []string) (goth.Provider, error) {
    63  			if setting.OAuth2Client.EnableAutoRegistration {
    64  				scopes = append(scopes, "user:email")
    65  			}
    66  			return github.NewCustomisedURL(clientID, secret, callbackURL, custom.AuthURL, custom.TokenURL, custom.ProfileURL, custom.EmailURL, scopes...), nil
    67  		}))
    68  
    69  	RegisterGothProvider(NewCustomProvider(
    70  		"gitlab", "GitLab", &CustomURLSettings{
    71  			AuthURL:    availableAttribute(gitlab.AuthURL),
    72  			TokenURL:   availableAttribute(gitlab.TokenURL),
    73  			ProfileURL: availableAttribute(gitlab.ProfileURL),
    74  		}, func(clientID, secret, callbackURL string, custom *CustomURLMapping, scopes []string) (goth.Provider, error) {
    75  			scopes = append(scopes, "read_user")
    76  			return gitlab.NewCustomisedURL(clientID, secret, callbackURL, custom.AuthURL, custom.TokenURL, custom.ProfileURL, scopes...), nil
    77  		}))
    78  
    79  	RegisterGothProvider(NewCustomProvider(
    80  		"gitea", "Gitea", &CustomURLSettings{
    81  			TokenURL:   requiredAttribute(gitea.TokenURL),
    82  			AuthURL:    requiredAttribute(gitea.AuthURL),
    83  			ProfileURL: requiredAttribute(gitea.ProfileURL),
    84  		},
    85  		func(clientID, secret, callbackURL string, custom *CustomURLMapping, scopes []string) (goth.Provider, error) {
    86  			return gitea.NewCustomisedURL(clientID, secret, callbackURL, custom.AuthURL, custom.TokenURL, custom.ProfileURL, scopes...), nil
    87  		}))
    88  
    89  	RegisterGothProvider(NewCustomProvider(
    90  		"nextcloud", "Nextcloud", &CustomURLSettings{
    91  			TokenURL:   requiredAttribute(nextcloud.TokenURL),
    92  			AuthURL:    requiredAttribute(nextcloud.AuthURL),
    93  			ProfileURL: requiredAttribute(nextcloud.ProfileURL),
    94  		},
    95  		func(clientID, secret, callbackURL string, custom *CustomURLMapping, scopes []string) (goth.Provider, error) {
    96  			return nextcloud.NewCustomisedURL(clientID, secret, callbackURL, custom.AuthURL, custom.TokenURL, custom.ProfileURL, scopes...), nil
    97  		}))
    98  
    99  	RegisterGothProvider(NewCustomProvider(
   100  		"mastodon", "Mastodon", &CustomURLSettings{
   101  			AuthURL: requiredAttribute(mastodon.InstanceURL),
   102  		},
   103  		func(clientID, secret, callbackURL string, custom *CustomURLMapping, scopes []string) (goth.Provider, error) {
   104  			return mastodon.NewCustomisedURL(clientID, secret, callbackURL, custom.AuthURL, scopes...), nil
   105  		}))
   106  
   107  	RegisterGothProvider(NewCustomProvider(
   108  		"azureadv2", "Azure AD v2", &CustomURLSettings{
   109  			Tenant: requiredAttribute("organizations"),
   110  		},
   111  		func(clientID, secret, callbackURL string, custom *CustomURLMapping, scopes []string) (goth.Provider, error) {
   112  			azureScopes := make([]azureadv2.ScopeType, len(scopes))
   113  			for i, scope := range scopes {
   114  				azureScopes[i] = azureadv2.ScopeType(scope)
   115  			}
   116  
   117  			return azureadv2.New(clientID, secret, callbackURL, azureadv2.ProviderOptions{
   118  				Tenant: azureadv2.TenantType(custom.Tenant),
   119  				Scopes: azureScopes,
   120  			}), nil
   121  		},
   122  	))
   123  }