Skip to content

Commit

Permalink
feat: use authenticate endpoint for x
Browse files Browse the repository at this point in the history
Improves the "Log in with X" experience by not asking the user to re-authenticate every time.
  • Loading branch information
aeneasr committed Mar 20, 2024
1 parent fa5a112 commit 270622e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
1 change: 1 addition & 0 deletions internal/client-go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
15 changes: 11 additions & 4 deletions selfservice/strategy/oidc/provider_x.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"fmt"
"net/http"

"github.com/ory/x/otelx"

"github.com/dghubble/oauth1"
"github.com/dghubble/oauth1/twitter"
"github.com/pkg/errors"
Expand Down Expand Up @@ -54,20 +56,25 @@ func (p *ProviderX) ExchangeToken(ctx context.Context, req *http.Request) (*oaut
return oauth1.NewToken(accessToken, accessSecret), nil
}

func (p *ProviderX) AuthURL(ctx context.Context, state string) (string, error) {
func (p *ProviderX) AuthURL(ctx context.Context, state string) (_ string, err error) {
ctx, span := p.reg.Tracer(ctx).Tracer().Start(ctx, "selfservice.strategy.oidc.ProviderLinkedIn.fetch")
defer otelx.End(span, &err)

c := p.OAuth1(ctx)

// We need to cheat so that callback validates on return
c.CallbackURL = c.CallbackURL + fmt.Sprintf("?state=%s&code=unused", state)

requestToken, _, err := c.RequestToken()
if err != nil {
return "", errors.WithStack(herodot.ErrInternalServerError.WithReasonf(`Unable to sign in with X because the OAuth1 request token could not be initialized.`))
span.RecordError(err)
return "", errors.WithStack(herodot.ErrInternalServerError.WithWrap(err).WithReasonf(`Unable to sign in with X because the OAuth1 request token could not be initialized: %s`, err))
}

authzURL, err := c.AuthorizationURL(requestToken)
if err != nil {
return "", errors.WithStack(herodot.ErrInternalServerError.WithReasonf(`Unable to sign in with X because the OAuth1 authorization URL could not be parsed.`))
span.RecordError(err)
return "", errors.WithStack(herodot.ErrInternalServerError.WithWrap(err).WithReasonf(`Unable to sign in with X because the OAuth1 authorization URL could not be parsed: %s`, err))
}

return authzURL.String(), nil
Expand All @@ -85,7 +92,7 @@ func (p *ProviderX) OAuth1(ctx context.Context) *oauth1.Config {
return &oauth1.Config{
ConsumerKey: p.config.ClientID,
ConsumerSecret: p.config.ClientSecret,
Endpoint: twitter.AuthorizeEndpoint,
Endpoint: twitter.AuthenticateEndpoint,
CallbackURL: p.config.Redir(p.reg.Config().OIDCRedirectURIBase(ctx)),
}
}
Expand Down
4 changes: 4 additions & 0 deletions test/e2e/profiles/oidc/identity.traits.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
},
"webauthn": {
"identifier": true
},
"code": {
"identifier": true,
"via": "email"
}
},
"verification": {
Expand Down
17 changes: 17 additions & 0 deletions test/e2e/profiles/oidc/microsoft.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
local claims = std.extVar('claims');
{
identity: {
traits: {
// Allowing unverified email addresses enables account
// enumeration attacks, if the value is used for
// verification or as a password login identifier.
//
// If connecting only to your organization (one tenant), claims.email is safe to use
// if you haven't actively disabled e-mail verification during sign-up.
//
// The email might be empty if the account isn't linked to an email address.
// For a human readable identifier, consider using the "preferred_username" claim.
[if 'email' in claims then 'email' else null]: claims.email,
},
},
}
4 changes: 4 additions & 0 deletions test/e2e/profiles/passkey/identity.traits.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
},
"passkey": {
"display_name": true
},
"code": {
"identifier": true,
"via": "email"
}
}
}
Expand Down

0 comments on commit 270622e

Please sign in to comment.