Skip to content
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

add providers resolver #539

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 3 additions & 24 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,41 +1,20 @@
module github.com/markbates/goth
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for updating this PR. It looks like somethings have been reverted from master in go.mod. Could you bump the version to 1.18, and run go mod tidy?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be ok now.


go 1.18
go 1.15

require (
github.com/golang-jwt/jwt/v4 v4.2.0
github.com/gorilla/mux v1.6.2
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1
github.com/gorilla/sessions v1.1.1
github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da
github.com/kr/pretty v0.3.1 // indirect
github.com/lestrrat-go/jwx v1.2.28
github.com/markbates/going v1.0.0
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/stretchr/testify v1.8.4
golang.org/x/oauth2 v0.17.0
)

require (
cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
50 changes: 40 additions & 10 deletions provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,66 @@ const NoAuthUrlErrorMessage = "an AuthURL has not been set"
// Providers is list of known/available providers.
type Providers map[string]Provider

var providers = Providers{}
// ProviderResolver an interface to resolve a provider by name
type ProviderResolver interface {
Get(name string) (Provider, error)
GetAll() Providers
}

// DefaultProviderResolver default implementation of ProviderResolver to resolve a provider from a static map
type DefaultProviderResolver struct {
providers map[string]Provider
}

var resolver ProviderResolver

// ResolveProvider returns a previously created provider. If Goth has not
// been told to use the named provider it will return an error.
func (r DefaultProviderResolver) Get(name string) (Provider, error) {
provider := r.providers[name]
if provider == nil {
return nil, fmt.Errorf("no provider for %s exists", name)
}
return provider, nil
}

// ResolveProvider returns a previously created provider. If Goth has not
// been told to use the named provider it will return an error.
func (r DefaultProviderResolver) GetAll() Providers {
return r.providers
}

// UseProviders adds a list of available providers for use with Goth.
// Can be called multiple times. If you pass the same provider more
// than once, the last will be used.
func UseProviders(viders ...Provider) {
for _, provider := range viders {
providers[provider.Name()] = provider
providers := Providers{}
for _, p := range viders {
providers[p.Name()] = p
}
resolver = DefaultProviderResolver{providers: providers}
}

// SetProviderResolver set the active resolver.
func SetProviderResolver(r ProviderResolver) {
resolver = r
}

// GetProviders returns a list of all the providers currently in use.
func GetProviders() Providers {
return providers
return resolver.GetAll()
}

// GetProvider returns a previously created provider. If Goth has not
// been told to use the named provider it will return an error.
func GetProvider(name string) (Provider, error) {
provider := providers[name]
if provider == nil {
return nil, fmt.Errorf("no provider for %s exists", name)
}
return provider, nil
return resolver.Get(name)
}

// ClearProviders will remove all providers currently in use.
// This is useful, mostly, for testing purposes.
func ClearProviders() {
providers = Providers{}
resolver = nil
}

// ContextForClient provides a context for use with oauth2.
Expand Down
33 changes: 33 additions & 0 deletions provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,36 @@ func Test_GetProvider(t *testing.T) {
a.Equal(err.Error(), "no provider for unknown exists")
goth.ClearProviders()
}

func Test_CustomResolver(t *testing.T) {
a := assert.New(t)
resolver := &CustomResolver{}
goth.SetProviderResolver(resolver)
p, err := goth.GetProvider("faux")
a.NoError(err)
a.Equal(len(goth.GetProviders()), 1)
a.NotNil(p)

p, err = goth.GetProvider("unknown")
a.NoError(err)
a.Nil(p)

goth.ClearProviders()
}

type CustomResolver struct{}

func (r CustomResolver) Get(name string) (goth.Provider, error) {
// you can load this from a database or something
if name != "faux" {
return nil, nil
}
return &faux.Provider{}, nil
}

func (r CustomResolver) GetAll() goth.Providers {
// you can load this from a database or something
return goth.Providers{
"faux": &faux.Provider{},
}
}