mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-13 19:44:21 +00:00
598a4d2d4b
add basic structure and implement first providers for IDP templates to be able to manage and use them in the future
211 lines
5.6 KiB
Go
211 lines
5.6 KiB
Go
package google
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/h2non/gock"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
|
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
|
"golang.org/x/oauth2"
|
|
"golang.org/x/text/language"
|
|
|
|
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
|
)
|
|
|
|
func TestSession_FetchUser(t *testing.T) {
|
|
type fields struct {
|
|
clientID string
|
|
clientSecret string
|
|
redirectURI string
|
|
httpMock func()
|
|
authURL string
|
|
code string
|
|
tokens *openid.Tokens
|
|
}
|
|
type want struct {
|
|
err error
|
|
id string
|
|
firstName string
|
|
lastName string
|
|
displayName string
|
|
nickName string
|
|
preferredUsername string
|
|
email string
|
|
isEmailVerified bool
|
|
phone string
|
|
isPhoneVerified bool
|
|
preferredLanguage language.Tag
|
|
avatarURL string
|
|
profile string
|
|
hostedDomain string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
want want
|
|
}{
|
|
{
|
|
name: "unauthenticated session, error",
|
|
fields: fields{
|
|
clientID: "clientID",
|
|
clientSecret: "clientSecret",
|
|
redirectURI: "redirectURI",
|
|
httpMock: func() {
|
|
gock.New("https://openidconnect.googleapis.com").
|
|
Get("/v1/userinfo").
|
|
Reply(200).
|
|
JSON(userinfo())
|
|
},
|
|
authURL: "https://accounts.google.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
|
|
tokens: nil,
|
|
},
|
|
want: want{
|
|
err: oidc.ErrCodeMissing,
|
|
},
|
|
},
|
|
{
|
|
name: "userinfo error",
|
|
fields: fields{
|
|
clientID: "clientID",
|
|
clientSecret: "clientSecret",
|
|
redirectURI: "redirectURI",
|
|
httpMock: func() {
|
|
gock.New("https://openidconnect.googleapis.com").
|
|
Get("/v1/userinfo").
|
|
Reply(200).
|
|
JSON(userinfo())
|
|
},
|
|
authURL: "https://accounts.google.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
|
|
tokens: &openid.Tokens{
|
|
Token: &oauth2.Token{
|
|
AccessToken: "accessToken",
|
|
TokenType: openid.BearerToken,
|
|
},
|
|
IDTokenClaims: openid.NewIDTokenClaims(
|
|
issuer,
|
|
"sub2",
|
|
[]string{"clientID"},
|
|
time.Now().Add(1*time.Hour),
|
|
time.Now().Add(-1*time.Second),
|
|
"nonce",
|
|
"",
|
|
nil,
|
|
"clientID",
|
|
0,
|
|
),
|
|
},
|
|
},
|
|
want: want{
|
|
err: rp.ErrUserInfoSubNotMatching,
|
|
},
|
|
},
|
|
{
|
|
name: "successful fetch",
|
|
fields: fields{
|
|
clientID: "clientID",
|
|
clientSecret: "clientSecret",
|
|
redirectURI: "redirectURI",
|
|
httpMock: func() {
|
|
gock.New("https://openidconnect.googleapis.com").
|
|
Get("/v1/userinfo").
|
|
Reply(200).
|
|
JSON(userinfo())
|
|
},
|
|
authURL: "https://accounts.google.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
|
|
tokens: &openid.Tokens{
|
|
Token: &oauth2.Token{
|
|
AccessToken: "accessToken",
|
|
TokenType: openid.BearerToken,
|
|
},
|
|
IDTokenClaims: openid.NewIDTokenClaims(
|
|
issuer,
|
|
"sub",
|
|
[]string{"clientID"},
|
|
time.Now().Add(1*time.Hour),
|
|
time.Now().Add(-1*time.Second),
|
|
"nonce",
|
|
"",
|
|
nil,
|
|
"clientID",
|
|
0,
|
|
),
|
|
},
|
|
},
|
|
want: want{
|
|
id: "sub",
|
|
firstName: "firstname",
|
|
lastName: "lastname",
|
|
displayName: "firstname lastname",
|
|
nickName: "",
|
|
preferredUsername: "email",
|
|
email: "email",
|
|
isEmailVerified: true,
|
|
phone: "",
|
|
isPhoneVerified: false,
|
|
preferredLanguage: language.English,
|
|
avatarURL: "picture",
|
|
profile: "",
|
|
hostedDomain: "hosted domain",
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
defer gock.Off()
|
|
tt.fields.httpMock()
|
|
a := assert.New(t)
|
|
|
|
// call the real discovery endpoint
|
|
gock.New(issuer).Get(openid.DiscoveryEndpoint).EnableNetworking()
|
|
provider, err := New(tt.fields.clientID, tt.fields.clientSecret, tt.fields.redirectURI)
|
|
require.NoError(t, err)
|
|
|
|
session := &oidc.Session{
|
|
Provider: provider.Provider,
|
|
AuthURL: tt.fields.authURL,
|
|
Code: tt.fields.code,
|
|
Tokens: tt.fields.tokens,
|
|
}
|
|
|
|
user, err := session.FetchUser(context.Background())
|
|
if tt.want.err != nil && !errors.Is(err, tt.want.err) {
|
|
a.Fail("invalid error", "expected %v, got %v", tt.want.err, err)
|
|
}
|
|
if tt.want.err == nil {
|
|
a.NoError(err)
|
|
a.Equal(tt.want.id, user.GetID())
|
|
a.Equal(tt.want.firstName, user.GetFirstName())
|
|
a.Equal(tt.want.lastName, user.GetLastName())
|
|
a.Equal(tt.want.displayName, user.GetDisplayName())
|
|
a.Equal(tt.want.nickName, user.GetNickname())
|
|
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
|
a.Equal(tt.want.email, user.GetEmail())
|
|
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
|
a.Equal(tt.want.phone, user.GetPhone())
|
|
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
|
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
|
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
|
a.Equal(tt.want.profile, user.GetProfile())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func userinfo() openid.UserInfoSetter {
|
|
info := openid.NewUserInfo()
|
|
info.SetSubject("sub")
|
|
info.SetGivenName("firstname")
|
|
info.SetFamilyName("lastname")
|
|
info.SetName("firstname lastname")
|
|
info.SetEmail("email", true)
|
|
info.SetLocale(language.English)
|
|
info.SetPicture("picture")
|
|
info.AppendClaims("hd", "hosted domain")
|
|
return info
|
|
}
|