Skip to content

Commit

Permalink
chore: use same auth config as in Kratos
Browse files Browse the repository at this point in the history
  • Loading branch information
zepatrik committed Sep 21, 2023
1 parent 5422ce5 commit 76c9f43
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 37 deletions.
15 changes: 11 additions & 4 deletions driver/config/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package config

import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
Expand Down Expand Up @@ -467,10 +468,16 @@ func (p *DefaultProvider) AccessTokenStrategy(ctx context.Context, additionalSou
return s
}

type HookConfig struct {
URL string `json:"url"`
Headers map[string]string `json:"headers"`
}
type (
Auth struct {
Type string `json:"type"`
Config json.RawMessage `json:"config"`
}
HookConfig struct {
URL string `json:"url"`
Auth *Auth `json:"auth"`
}
)

func (p *DefaultProvider) getHookConfig(ctx context.Context, key string) *HookConfig {
if hookURL := p.getProvider(ctx).RequestURIF(key, nil); hookURL != nil {
Expand Down
9 changes: 6 additions & 3 deletions driver/config/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package config

import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -444,14 +445,16 @@ func TestHookConfigs(t *testing.T) {

c.MustSet(ctx, key, map[string]any{
"url": "http://localhost:8080/hook2",
"headers": map[string]any{
"My-Headers": "my-value",
"auth": map[string]any{
"type": "api_key",
"config": json.RawMessage(`{"in":"header","name":"my-header","value":"my-value"}`),
},
})
hc = getFunc(ctx)
require.NotNil(t, hc)
assert.EqualValues(t, "http://localhost:8080/hook2", hc.URL)
assert.EqualValues(t, "my-value", hc.Headers["My-Headers"])
assert.EqualValues(t, "api_key", hc.Auth.Type)
assert.JSONEq(t, `{"in":"header","name":"my-header","value":"my-value"}`, string(hc.Auth.Config))
}
}

Expand Down
44 changes: 42 additions & 2 deletions oauth2/token_hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"encoding/json"
"net/http"

"github.com/pkg/errors"

"github.com/hashicorp/go-retryablehttp"

"github.com/ory/hydra/v2/flow"
Expand Down Expand Up @@ -56,6 +58,40 @@ type TokenHookResponse struct {
Session flow.AcceptOAuth2ConsentRequestSession `json:"session"`
}

type APIKeyAuthConfig struct {
In string `json:"in"`
Name string `json:"name"`
Value string `json:"value"`
}

func applyAuth(req *retryablehttp.Request, auth *config.Auth) error {
if auth == nil {
return nil
}

switch auth.Type {
case "api_key":
c := struct {
In string `json:"in"`
Name string `json:"name"`
Value string `json:"value"`
}{}
if err := json.Unmarshal(auth.Config, &c); err != nil {
return err
}

switch c.In {
case "header":
req.Header.Set(c.Name, c.Value)
case "cookie":
req.AddCookie(&http.Cookie{Name: c.Name, Value: c.Value})
}
default:
return errors.Errorf("unsupported auth type %q", auth.Type)
}
return nil
}

func executeHookAndUpdateSession(ctx context.Context, reg x.HTTPClientProvider, hookConfig *config.HookConfig, reqBodyBytes []byte, session *Session) error {
req, err := retryablehttp.NewRequestWithContext(ctx, http.MethodPost, hookConfig.URL, bytes.NewReader(reqBodyBytes))
if err != nil {
Expand All @@ -66,8 +102,12 @@ func executeHookAndUpdateSession(ctx context.Context, reg x.HTTPClientProvider,
WithDebugf("Unable to prepare the HTTP Request: %s", err),
)
}
for k, v := range hookConfig.Headers {
req.Header.Set(k, v)
if err := applyAuth(req, hookConfig.Auth); err != nil {
return errorsx.WithStack(
fosite.ErrServerError.
WithWrap(err).
WithDescription("An error occurred while applying the token hook authentication.").
WithDebugf("Unable to apply the token hook authentication: %s", err))
}
req.Header.Set("Content-Type", "application/json; charset=UTF-8")

Expand Down
72 changes: 44 additions & 28 deletions spec/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,48 @@
}
}
}
},
"webhook_config": {
"type": "object",
"additionalProperties": false,
"description": "Configures a webhook.",
"required": ["url"],
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "The URL to send the webhook to."
},
"auth": {
"type": "object",
"additionalProperties": false,
"required": ["type", "config"],
"properties": {
"type": {
"const": "api_key"
},
"config": {
"type": "object",
"additionalProperties": false,
"required": ["name", "value"],
"properties": {
"in": {
"enum": ["header", "cookie"],
"default": "header"
},
"name": {
"description": "The header or cookie name.",
"type": "string"
},
"value": {
"description": "The header or cookie value.",
"type": "string"
}
}
}
}
}
}
}
},
"properties": {
Expand Down Expand Up @@ -1047,20 +1089,7 @@
"format": "uri"
},
{
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"headers": {
"description": "Sets the header to be used when calling the refresh token hook endpoint.",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
"$ref": "#/definitions/webhook_config"
}
]
},
Expand All @@ -1073,20 +1102,7 @@
"format": "uri"
},
{
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"headers": {
"description": "Sets the header to be used when calling the token hook endpoint.",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
"$ref": "#/definitions/webhook_config"
}
]
}
Expand Down

0 comments on commit 76c9f43

Please sign in to comment.