mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:27:42 +00:00
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:
@@ -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
|
||||
|
@@ -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",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -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")
|
||||
|
Reference in New Issue
Block a user