feat: add gitlab provider templates (#5405)

* feat(api): add google provider template

* refactor reduce functions

* handle removed event

* linting

* fix projection

* feat(api): add generic oauth provider template

* feat(api): add github provider templates

* feat(api): add github provider templates

* fixes

* proto comment

* fix filtering

* requested changes

* feat(api): add generic oauth provider template

* remove wrongly committed message

* increase budget for angular build

* fix linting

* fixes

* fix merge

* fix merge

* fix projection

* fix merge

* updates from previous PRs

* enable github providers in login

* fix merge

* fix test and add github styling in login

* cleanup

* feat(api): add gitlab provider templates

* fix: merge

* fix display of providers in login

* implement gitlab in login and make prompt `select_account` optional since gitlab can't handle it

* fix merge

* fix merge and add tests for command side

* requested changes

* requested changes

* Update internal/query/idp_template.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* fix merge

* requested changes

---------

Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
Livio Spring
2023-03-13 17:34:29 +01:00
committed by GitHub
parent f55877eb70
commit c0843e6b4c
41 changed files with 5617 additions and 227 deletions

View File

@@ -1,6 +1,8 @@
package gitlab
import (
openid "github.com/zitadel/oidc/v2/pkg/oidc"
"github.com/zitadel/zitadel/internal/idp"
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
)
@@ -25,6 +27,14 @@ func New(clientID, clientSecret, redirectURI string, scopes []string, options ..
// NewCustomIssuer creates a GitLab provider using the [oidc.Provider] (OIDC generic provider)
// with a custom issuer for self-managed instances
func NewCustomIssuer(name, issuer, clientID, clientSecret, redirectURI string, scopes []string, options ...oidc.ProviderOpts) (*Provider, error) {
if len(scopes) == 0 {
// the OIDC provider would set `openid profile email phone` as default scope,
// but since gitlab does not handle unknown scopes correctly (phone) and returns an error,
// we will just set a separate default list
scopes = []string{openid.ScopeOpenID, openid.ScopeProfile, openid.ScopeEmail}
}
// gitlab is currently not able to handle the prompt `select_account`:
// https://gitlab.com/gitlab-org/gitlab/-/issues/377368
rp, err := oidc.New(name, issuer, clientID, clientSecret, redirectURI, scopes, oidc.DefaultMapper, options...)
if err != nil {
return nil, err

View File

@@ -33,7 +33,18 @@ func TestProvider_BeginAuth(t *testing.T) {
scopes: []string{"openid"},
},
want: &oidc.Session{
AuthURL: "https://gitlab.com/oauth/authorize?client_id=clientID&prompt=select_account&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
AuthURL: "https://gitlab.com/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
},
},
{
name: "successful auth default scopes",
fields: fields{
clientID: "clientID",
clientSecret: "clientSecret",
redirectURI: "redirectURI",
},
want: &oidc.Session{
AuthURL: "https://gitlab.com/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid+profile+email&state=testState",
},
},
}

View File

@@ -21,7 +21,7 @@ type Provider struct {
// New creates a Google provider using the [oidc.Provider] (OIDC generic provider)
func New(clientID, clientSecret, redirectURI string, scopes []string, opts ...oidc.ProviderOpts) (*Provider, error) {
rp, err := oidc.New(name, issuer, clientID, clientSecret, redirectURI, scopes, userMapper, opts...)
rp, err := oidc.New(name, issuer, clientID, clientSecret, redirectURI, scopes, userMapper, append(opts, oidc.WithSelectAccount())...)
if err != nil {
return nil, err
}

View File

@@ -21,6 +21,7 @@ type Provider struct {
isAutoCreation bool
isAutoUpdate bool
userInfoMapper func(info oidc.UserInfo) idp.User
authOptions []rp.AuthURLOpt
}
type ProviderOpts func(provider *Provider)
@@ -61,6 +62,13 @@ func WithRelyingPartyOption(option rp.Option) ProviderOpts {
}
}
// WithSelectAccount adds the select_account prompt to the auth request
func WithSelectAccount() ProviderOpts {
return func(p *Provider) {
p.authOptions = append(p.authOptions, rp.WithPrompt(oidc.PromptSelectAccount))
}
}
type UserInfoMapper func(info oidc.UserInfo) idp.User
var DefaultMapper UserInfoMapper = func(info oidc.UserInfo) idp.User {
@@ -105,7 +113,7 @@ func (p *Provider) Name() string {
// BeginAuth implements the [idp.Provider] interface.
// It will create a [Session] with an OIDC authorization request as AuthURL.
func (p *Provider) BeginAuth(ctx context.Context, state string, _ ...any) (idp.Session, error) {
url := rp.AuthURL(state, p.RelyingParty, rp.WithPrompt(oidc.PromptSelectAccount))
url := rp.AuthURL(state, p.RelyingParty, p.authOptions...)
return &Session{AuthURL: url, Provider: p}, nil
}

View File

@@ -23,6 +23,7 @@ func TestProvider_BeginAuth(t *testing.T) {
scopes []string
userMapper func(info oidc.UserInfo) idp.User
httpMock func(issuer string)
opts []ProviderOpts
}
tests := []struct {
name string
@@ -50,6 +51,7 @@ func TestProvider_BeginAuth(t *testing.T) {
UserinfoEndpoint: issuer + "/userinfo",
})
},
opts: []ProviderOpts{WithSelectAccount()},
},
want: &Session{AuthURL: "https://issuer.com/authorize?client_id=clientID&prompt=select_account&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState"},
},
@@ -61,7 +63,7 @@ func TestProvider_BeginAuth(t *testing.T) {
a := assert.New(t)
r := require.New(t)
provider, err := New(tt.fields.name, tt.fields.issuer, tt.fields.clientID, tt.fields.clientSecret, tt.fields.redirectURI, tt.fields.scopes, tt.fields.userMapper)
provider, err := New(tt.fields.name, tt.fields.issuer, tt.fields.clientID, tt.fields.clientSecret, tt.fields.redirectURI, tt.fields.scopes, tt.fields.userMapper, tt.fields.opts...)
r.NoError(err)
session, err := provider.BeginAuth(context.Background(), "testState")