Skip to content

Commit

Permalink
feat: oidc provider epic games
Browse files Browse the repository at this point in the history
  • Loading branch information
Jorgagu committed Nov 13, 2023
1 parent f7c6767 commit f05b56a
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 2 deletions.
4 changes: 3 additions & 1 deletion embedx/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,9 @@
"dingtalk",
"patreon",
"linkedin",
"lark"
"lark",
"epic-games"

],
"examples": ["google"]
},
Expand Down
2 changes: 2 additions & 0 deletions selfservice/strategy/oidc/provider_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -150,6 +151,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) {
Expand Down
118 changes: 118 additions & 0 deletions selfservice/strategy/oidc/provider_epic_games.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

package oidc

import (
"context"
"encoding/json"
"net/url"

"github.com/hashicorp/go-retryablehttp"

"github.com/ory/x/httpx"

"github.com/pkg/errors"
"golang.org/x/oauth2"

"github.com/ory/herodot"
)

type ProviderEpicGames struct {
config *Configuration
reg Dependencies
}

type EpicGamesIdentityResponse struct {
Data struct {
Attributes struct {
Email string `json:"email"`
FirstName string `json:"first_name"`
FullName string `json:"full_name"`
ImageUrl string `json:"image_url"`
LastName string `json:"last_name"`
} `json:"attributes"`
Id string `json:"id"`
Type string `json:"type"`
} `json:"data"`
}

func NewProviderEpicGames(
config *Configuration,
reg Dependencies,
) Provider {
return &ProviderEpicGames{
config: config,
reg: reg,
}
}

func (d *ProviderEpicGames) Config() *Configuration {
return d.config
}

func (d *ProviderEpicGames) oauth2(ctx context.Context) *oauth2.Config {
return &oauth2.Config{
ClientID: d.config.ClientID,
ClientSecret: d.config.ClientSecret,
Endpoint: oauth2.Endpoint{
AuthURL: "https://www.epicgames.com/id/authorize",
TokenURL: "https://api.epicgames.dev/epic/oauth/v1/token",
AuthStyle: oauth2.AuthStyleInHeader,
},
RedirectURL: d.config.Redir(d.reg.Config().OIDCRedirectURIBase(ctx)),
Scopes: d.config.Scope,
}
}

func (d *ProviderEpicGames) OAuth2(ctx context.Context) (*oauth2.Config, error) {
d.reg.Logger().WithField("provider", "epic-games").Trace("ProviderCreating new oauth2 configuration in OAuth2 method.")
return d.oauth2(ctx), nil
}

func (d *ProviderEpicGames) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
identityUrl := "https://api.epicgames.dev/epic/oauth/v1/userInfo"

o := d.oauth2(ctx)
client := d.reg.HTTPClient(ctx, httpx.ResilientClientWithClient(o.Client(ctx, exchange)))

req, err := retryablehttp.NewRequest("GET", identityUrl, nil)
if err != nil {
return nil, errors.WithStack(herodot.ErrInternalServerError.WithReasonf("%s", err))
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer "+exchange.AccessToken)

res, err := client.Do(req)
if err != nil {
return nil, errors.WithStack(herodot.ErrInternalServerError.WithReasonf("%s", err))
}
defer res.Body.Close()

if err := logUpstreamError(d.reg.Logger(), res); err != nil {
return nil, err
}

data := EpicGamesIdentityResponse{}
jsonErr := json.NewDecoder(res.Body).Decode(&data)
if jsonErr != nil {
return nil, errors.WithStack(herodot.ErrInternalServerError.WithReasonf("%s", jsonErr))
}

claims := &Claims{
Issuer: "https://api.epicgames.dev/epic/oauth/v1",
Subject: data.Data.Id,
Name: data.Data.Attributes.FullName,
Email: data.Data.Attributes.Email,
GivenName: data.Data.Attributes.FirstName,
FamilyName: data.Data.Attributes.LastName,
LastName: data.Data.Attributes.LastName,
Picture: data.Data.Attributes.ImageUrl,
}

return claims, nil
}

func (g *ProviderEpicGames) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
}
1 change: 1 addition & 0 deletions selfservice/strategy/oidc/provider_private_net_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,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)
Expand Down
3 changes: 2 additions & 1 deletion test/e2e/cypress/support/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,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"
Expand All @@ -213,6 +213,7 @@ export type Provider =
| "patreon"
| "linkedin"
| "lark"
| "epic-games"
export type OptionalStringWhichWillBeUsedWhenGeneratingLabelsForUIButtons =
string
/**
Expand Down

0 comments on commit f05b56a

Please sign in to comment.