snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
209
selfservice/strategy/oidc/provider_linkedin_test.go
Normal file
209
selfservice/strategy/oidc/provider_linkedin_test.go
Normal file
@@ -0,0 +1,209 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package oidc_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-retryablehttp"
|
||||
"github.com/jarcoal/httpmock"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/ory/kratos/pkg"
|
||||
"github.com/ory/kratos/selfservice/strategy/oidc"
|
||||
)
|
||||
|
||||
func TestProviderLinkedin_Claims(t *testing.T) {
|
||||
_, base := pkg.NewFastRegistryWithMocks(t)
|
||||
reg := &mockRegistry{base, retryablehttp.NewClient()}
|
||||
httpmock.ActivateNonDefault(reg.cl.HTTPClient)
|
||||
t.Cleanup(httpmock.DeactivateAndReset)
|
||||
|
||||
httpmock.RegisterResponder("GET", "https://api.linkedin.com/v2/me?projection=(id,localizedFirstName,localizedLastName,profilePicture(displayImage~digitalmediaAsset:playableStreams))",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, map[string]interface{}{
|
||||
"localizedLastName": "Doe",
|
||||
"profilePicture": map[string]interface{}{
|
||||
"displayImage": "urn:li:digitalmediaAsset:D5F04AQG1h-anJtsLeA",
|
||||
"displayImage~": map[string]interface{}{
|
||||
"elements": []map[string]interface{}{
|
||||
{
|
||||
"identifiers": []map[string]interface{}{
|
||||
{
|
||||
"identifier": "https://media-exp1.licdn.com/dms/image/D5F04AQG1h-anJtsLeA/profile-displayphoto-shrink_100_100/0/1661502148285?e=1674086400&v=beta&t=5zdsvAqGS1idrfNAai-zwp01K4hApGeJyRV8zBTjZck",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"identifiers": []map[string]interface{}{
|
||||
{
|
||||
"identifier": "https://media-exp1.licdn.com/dms/image/D5F04AQG1h-anJtsLeA/profile-displayphoto-shrink_200_200/0/1661502148285?e=1674086400&v=beta&t=fbHprGci4vEpeQdzRTyt9YJjNXTgv-14h9ROr_DE5R4",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"identifiers": []map[string]interface{}{
|
||||
{
|
||||
"identifier": "https://media-exp1.licdn.com/dms/image/D5F04AQG1h-anJtsLeA/profile-displayphoto-shrink_400_400/0/1661502148285?e=1674086400&v=beta&t=SMgXuiZ5DiiPf4iMrTPQWoCnFRh4Y-DfoWjopUZ0qCo",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"identifiers": []map[string]interface{}{
|
||||
{
|
||||
"identifier": "https://media-exp1.licdn.com/dms/image/D5F04AQG1h-anJtsLeA/profile-displayphoto-shrink_800_800/0/1661502148285?e=1674086400&v=beta&t=QzC9b32DmLRIwU7P27LfJUqglXsJm056WkA_TTOHxHU",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"localizedFirstName": "John",
|
||||
"id": "5foOWOiYXD",
|
||||
})
|
||||
return resp, err
|
||||
})
|
||||
|
||||
httpmock.RegisterResponder("GET", "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, map[string]interface{}{
|
||||
"elements": []map[string]interface{}{
|
||||
{
|
||||
"handle~": map[string]interface{}{
|
||||
"emailAddress": "john.doe@gmail.com",
|
||||
},
|
||||
"handle": "urn:li:emailAddress:-1810278278",
|
||||
},
|
||||
},
|
||||
})
|
||||
return resp, err
|
||||
},
|
||||
)
|
||||
|
||||
httpmock.RegisterResponder("POST", "https://www.linkedin.com/oauth/v2/introspectToken",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, map[string]interface{}{
|
||||
"active": true,
|
||||
"client_id": "78e533g1dq0rs5",
|
||||
"authorized_at": 1668518671,
|
||||
"created_at": 1668518671,
|
||||
"status": "active",
|
||||
"expires_at": 2673702676,
|
||||
"scope": "r_emailaddress,r_liteprofile",
|
||||
"auth_type": "3L",
|
||||
})
|
||||
return resp, err
|
||||
},
|
||||
)
|
||||
|
||||
c := &oidc.Configuration{
|
||||
ID: "linkedin",
|
||||
Provider: "linkedin",
|
||||
ClientID: "abcd",
|
||||
ClientSecret: "secret",
|
||||
Mapper: "file://./stub/oidc.linkedin.jsonnet",
|
||||
Scope: []string{"r_emailaddress", "r_liteprofile"},
|
||||
}
|
||||
linkedin := oidc.NewProviderLinkedIn(c, reg)
|
||||
|
||||
const fakeLinkedinIDToken = "id_token_mock_" // #nosec G101 test code
|
||||
actual, err := linkedin.(oidc.OAuth2Provider).Claims(
|
||||
context.Background(),
|
||||
(&oauth2.Token{AccessToken: "foo", Expiry: time.Now().Add(time.Hour)}).WithExtra(map[string]interface{}{"id_token": fakeLinkedinIDToken}),
|
||||
url.Values{},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, &oidc.Claims{
|
||||
Issuer: "https://login.linkedin.com/",
|
||||
Subject: "5foOWOiYXD",
|
||||
GivenName: "John",
|
||||
LastName: "Doe",
|
||||
Email: "john.doe@gmail.com",
|
||||
Picture: "https://media-exp1.licdn.com/dms/image/D5F04AQG1h-anJtsLeA/profile-displayphoto-shrink_400_400/0/1661502148285?e=1674086400&v=beta&t=SMgXuiZ5DiiPf4iMrTPQWoCnFRh4Y-DfoWjopUZ0qCo",
|
||||
}, actual)
|
||||
}
|
||||
|
||||
func TestProviderLinkedin_No_Picture(t *testing.T) {
|
||||
_, base := pkg.NewFastRegistryWithMocks(t)
|
||||
reg := &mockRegistry{base, retryablehttp.NewClient()}
|
||||
httpmock.ActivateNonDefault(reg.cl.HTTPClient)
|
||||
t.Cleanup(httpmock.DeactivateAndReset)
|
||||
|
||||
httpmock.RegisterResponder("GET", "https://api.linkedin.com/v2/me?projection=(id,localizedFirstName,localizedLastName,profilePicture(displayImage~digitalmediaAsset:playableStreams))",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, map[string]interface{}{
|
||||
"localizedLastName": "Doe",
|
||||
"localizedFirstName": "John",
|
||||
"id": "5foOWOiYXD",
|
||||
})
|
||||
return resp, err
|
||||
})
|
||||
|
||||
httpmock.RegisterResponder("GET", "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, map[string]interface{}{
|
||||
"elements": []map[string]interface{}{
|
||||
{
|
||||
"handle~": map[string]interface{}{
|
||||
"emailAddress": "john.doe@gmail.com",
|
||||
},
|
||||
"handle": "urn:li:emailAddress:-1810278278",
|
||||
},
|
||||
},
|
||||
})
|
||||
return resp, err
|
||||
},
|
||||
)
|
||||
|
||||
httpmock.RegisterResponder("POST", "https://www.linkedin.com/oauth/v2/introspectToken",
|
||||
func(req *http.Request) (*http.Response, error) {
|
||||
resp, err := httpmock.NewJsonResponse(200, map[string]interface{}{
|
||||
"active": true,
|
||||
"client_id": "78e533g1dq0rs5",
|
||||
"authorized_at": 1668518671,
|
||||
"created_at": 1668518671,
|
||||
"status": "active",
|
||||
"expires_at": 2673702676,
|
||||
"scope": "r_emailaddress,r_liteprofile",
|
||||
"auth_type": "3L",
|
||||
})
|
||||
return resp, err
|
||||
},
|
||||
)
|
||||
|
||||
c := &oidc.Configuration{
|
||||
ID: "linkedin",
|
||||
Provider: "linkedin",
|
||||
ClientID: "abcd",
|
||||
ClientSecret: "secret",
|
||||
Mapper: "file://./stub/oidc.linkedin.jsonnet",
|
||||
Scope: []string{"r_emailaddress", "r_liteprofile"},
|
||||
}
|
||||
linkedin := oidc.NewProviderLinkedIn(c, reg)
|
||||
|
||||
const fakeLinkedinIDToken = "id_token_mock_" // #nosec G101 test code
|
||||
actual, err := linkedin.(oidc.OAuth2Provider).Claims(
|
||||
context.Background(),
|
||||
(&oauth2.Token{AccessToken: "foo", Expiry: time.Now().Add(time.Hour)}).WithExtra(map[string]interface{}{"id_token": fakeLinkedinIDToken}),
|
||||
url.Values{},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, &oidc.Claims{
|
||||
Issuer: "https://login.linkedin.com/",
|
||||
Subject: "5foOWOiYXD",
|
||||
GivenName: "John",
|
||||
LastName: "Doe",
|
||||
Email: "john.doe@gmail.com",
|
||||
Picture: "",
|
||||
}, actual)
|
||||
}
|
||||
Reference in New Issue
Block a user