From 483da7e2b5e09b851b75851ba369fd74b5a6ab70 Mon Sep 17 00:00:00 2001 From: Jordan Labrosse Date: Tue, 22 Aug 2023 12:13:10 +0200 Subject: [PATCH] feat: oidc provider epic games --- embedx/config.schema.json | 3 +- selfservice/strategy/oidc/provider_config.go | 2 + .../strategy/oidc/provider_epic_games.go | 73 +++++++++++++++++++ .../oidc/provider_private_net_test.go | 1 + test/e2e/cypress/support/config.d.ts | 3 +- 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 selfservice/strategy/oidc/provider_epic_games.go diff --git a/embedx/config.schema.json b/embedx/config.schema.json index 930e7b34e95c..a1ff44f6dd00 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -436,7 +436,8 @@ "dingtalk", "patreon", "linkedin", - "lark" + "lark", + "epic-games" ], "examples": ["google"] }, diff --git a/selfservice/strategy/oidc/provider_config.go b/selfservice/strategy/oidc/provider_config.go index 512a5ecc6fa2..294ede722a7a 100644 --- a/selfservice/strategy/oidc/provider_config.go +++ b/selfservice/strategy/oidc/provider_config.go @@ -39,6 +39,7 @@ type Configuration struct { // - dingtalk // - linkedin // - patreon + // - epic-games Provider string `json:"provider"` // Label represents an optional label which can be used in the UI generation. @@ -160,6 +161,7 @@ var supportedProviders = map[string]func(config *Configuration, reg Dependencies "linkedin": NewProviderLinkedIn, "patreon": NewProviderPatreon, "lark": NewProviderLark, + "epic-games": NewProviderEpicGames, } func (c ConfigurationCollection) Provider(id string, reg Dependencies) (Provider, error) { diff --git a/selfservice/strategy/oidc/provider_epic_games.go b/selfservice/strategy/oidc/provider_epic_games.go new file mode 100644 index 000000000000..8fc72f61d3be --- /dev/null +++ b/selfservice/strategy/oidc/provider_epic_games.go @@ -0,0 +1,73 @@ +// Copyright © 2023 Ory Corp +// SPDX-License-Identifier: Apache-2.0 + +package oidc + +import ( + "context" + "net/url" + + "golang.org/x/oauth2" +) + +type ProviderEpicGames struct { + *ProviderGenericOIDC +} + +type EpicGamesIdentityResponse struct { + Data struct { + Sub string `json:"sub"` + } `json:"data"` +} + +func NewProviderEpicGames( + config *Configuration, + reg Dependencies, +) Provider { + return &ProviderEpicGames{ + ProviderGenericOIDC: &ProviderGenericOIDC{ + config: config, + reg: reg, + }, + } +} + +func (e *ProviderEpicGames) Config() *Configuration { + return e.config +} + +func (e *ProviderEpicGames) oauth2(ctx context.Context) (*oauth2.Config, error) { + return &oauth2.Config{ + ClientID: e.config.ClientID, + ClientSecret: e.config.ClientSecret, + Scopes: e.config.Scope, + Endpoint: oauth2.Endpoint{ + AuthURL: "https://www.epicgames.com/id/authorize", + TokenURL: "https://api.epicgames.dev/epic/oauth/v2/token", + AuthStyle: oauth2.AuthStyleInHeader, + }, + RedirectURL: e.config.Redir(e.reg.Config().OIDCRedirectURIBase(ctx)), + }, nil +} + +func (e *ProviderEpicGames) OAuth2(ctx context.Context) (*oauth2.Config, error) { + e.reg.Logger().WithField("provider", "epic-games").Trace("ProviderCreating new oauth2 configuration in OAuth2 method.") + return e.oauth2(ctx) +} + +func (e *ProviderEpicGames) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) { + rawClaims := make(map[string]interface{}) + rawClaims["access_token"] = exchange.AccessToken + rawClaims["refresh_token"] = exchange.RefreshToken + claims := &Claims{ + Issuer: "https://api.epicgames.dev/epic/oauth/v2", + Subject: exchange.Extra("account_id").(string), + RawClaims: rawClaims, + } + + return claims, nil +} + +func (e *ProviderEpicGames) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption { + return []oauth2.AuthCodeOption{} +} diff --git a/selfservice/strategy/oidc/provider_private_net_test.go b/selfservice/strategy/oidc/provider_private_net_test.go index 878b8622e993..a24071291c54 100644 --- a/selfservice/strategy/oidc/provider_private_net_test.go +++ b/selfservice/strategy/oidc/provider_private_net_test.go @@ -84,6 +84,7 @@ func TestProviderPrivateIP(t *testing.T) { // VK uses a fixed token URL and does not use the issuer. // Yandex uses a fixed token URL and does not use the issuer. // NetID uses a fixed token URL and does not use the issuer. + // Epic Games uses a fixed token URL and does not use the issuer. } { t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) { p := tc.p(tc.c) diff --git a/test/e2e/cypress/support/config.d.ts b/test/e2e/cypress/support/config.d.ts index c7e9742aed39..bdd5da38edaf 100644 --- a/test/e2e/cypress/support/config.d.ts +++ b/test/e2e/cypress/support/config.d.ts @@ -209,7 +209,7 @@ export type SelfServiceOIDCProvider1 = { [k: string]: unknown | undefined } /** - * Can be one of github, github-app, gitlab, generic, google, microsoft, discord, slack, facebook, auth0, vk, yandex, apple, spotify, netid, dingtalk, patreon. + * Can be one of github, github-app, gitlab, generic, google, microsoft, discord, slack, facebook, auth0, vk, yandex, apple, spotify, netid, dingtalk, patreon, epic-games. */ export type Provider = | "github" @@ -231,6 +231,7 @@ export type Provider = | "patreon" | "linkedin" | "lark" + | "epic-games" export type OptionalStringWhichWillBeUsedWhenGeneratingLabelsForUIButtons = string /**