Skip to content

Commit 9a1799c

Browse files
authored
RedirectURL defaults, URL composition (#2283)
* add defaults * config generate
1 parent 83c4da9 commit 9a1799c

10 files changed

Lines changed: 40 additions & 21 deletions

File tree

config/.env.example

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,16 +290,16 @@ CORE_INTEGRATIONS_GITHUBAPP_WEBHOOKSECRET=""
290290
CORE_INTEGRATIONS_GITHUBAPP_APPSLUG=""
291291
CORE_INTEGRATIONS_SLACK_CLIENTID=""
292292
CORE_INTEGRATIONS_SLACK_CLIENTSECRET=""
293-
CORE_INTEGRATIONS_SLACK_REDIRECTURL=""
293+
CORE_INTEGRATIONS_SLACK_REDIRECTURL="https://api.theopenlane.io/v1/integrations/auth/callback"
294294
CORE_INTEGRATIONS_GOOGLEWORKSPACE_CLIENTID=""
295295
CORE_INTEGRATIONS_GOOGLEWORKSPACE_CLIENTSECRET=""
296-
CORE_INTEGRATIONS_GOOGLEWORKSPACE_REDIRECTURL=""
296+
CORE_INTEGRATIONS_GOOGLEWORKSPACE_REDIRECTURL="https://api.theopenlane.io/v1/integrations/auth/callback"
297297
CORE_INTEGRATIONS_AZUREENTRAID_CLIENTID=""
298298
CORE_INTEGRATIONS_AZUREENTRAID_CLIENTSECRET=""
299-
CORE_INTEGRATIONS_AZUREENTRAID_REDIRECTURL=""
299+
CORE_INTEGRATIONS_AZUREENTRAID_REDIRECTURL="https://api.theopenlane.io/v1/integrations/auth/callback"
300300
CORE_INTEGRATIONS_MICROSOFTTEAMS_CLIENTID=""
301301
CORE_INTEGRATIONS_MICROSOFTTEAMS_CLIENTSECRET=""
302-
CORE_INTEGRATIONS_MICROSOFTTEAMS_REDIRECTURL=""
302+
CORE_INTEGRATIONS_MICROSOFTTEAMS_REDIRECTURL="https://api.theopenlane.io/v1/integrations/auth/callback"
303303
CORE_INTEGRATIONS_OIDCLOCAL_ENABLED="false"
304304
CORE_INTEGRATIONS_OIDCLOCAL_CLIENTID="local-core-oidc"
305305
CORE_INTEGRATIONS_OIDCLOCAL_CLIENTSECRET="local-core-oidc-secret"

config/config.example.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ integrations:
170170
azureentraid:
171171
clientid: ""
172172
clientsecret: ""
173-
redirecturl: ""
173+
redirecturl: https://api.theopenlane.io/v1/integrations/auth/callback
174174
githubapp:
175175
appid: ""
176176
appslug: ""
@@ -179,11 +179,11 @@ integrations:
179179
googleworkspace:
180180
clientid: ""
181181
clientsecret: ""
182-
redirecturl: ""
182+
redirecturl: https://api.theopenlane.io/v1/integrations/auth/callback
183183
microsoftteams:
184184
clientid: ""
185185
clientsecret: ""
186-
redirecturl: ""
186+
redirecturl: https://api.theopenlane.io/v1/integrations/auth/callback
187187
oidclocal:
188188
clientid: local-core-oidc
189189
clientsecret: local-core-oidc-secret
@@ -193,7 +193,7 @@ integrations:
193193
slack:
194194
clientid: ""
195195
clientsecret: ""
196-
redirecturl: ""
196+
redirecturl: https://api.theopenlane.io/v1/integrations/auth/callback
197197
jobqueue:
198198
connectionuri: postgres://postgres:password@0.0.0.0:5432/jobs?sslmode=disable
199199
metrics:

config/helm-values.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,16 +536,16 @@ coreConfiguration:
536536
appslug: "" # @schema type:string
537537
slack:
538538
clientid: "" # @schema type:string
539-
redirecturl: "" # @schema type:string
539+
redirecturl: "https://api.theopenlane.io/v1/integrations/auth/callback" # @schema type:string; default:https://api.theopenlane.io/v1/integrations/auth/callback
540540
googleworkspace:
541541
clientid: "" # @schema type:string
542-
redirecturl: "" # @schema type:string
542+
redirecturl: "https://api.theopenlane.io/v1/integrations/auth/callback" # @schema type:string; default:https://api.theopenlane.io/v1/integrations/auth/callback
543543
azureentraid:
544544
clientid: "" # @schema type:string
545-
redirecturl: "" # @schema type:string
545+
redirecturl: "https://api.theopenlane.io/v1/integrations/auth/callback" # @schema type:string; default:https://api.theopenlane.io/v1/integrations/auth/callback
546546
microsoftteams:
547547
clientid: "" # @schema type:string
548-
redirecturl: "" # @schema type:string
548+
redirecturl: "https://api.theopenlane.io/v1/integrations/auth/callback" # @schema type:string; default:https://api.theopenlane.io/v1/integrations/auth/callback
549549
oidclocal:
550550
enabled: false # @schema type:boolean; default:false
551551
clientid: "local-core-oidc" # @schema type:string; default:local-core-oidc

internal/httpserve/handlers/integration_flow.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"maps"
55
"net/http"
66
"slices"
7+
"strings"
78

89
echo "github.com/theopenlane/echox"
910

@@ -88,8 +89,8 @@ func (h *Handler) StartIntegrationAuth(ctx echo.Context, openapiCtx *OpenAPICont
8889
}
8990

9091
// ConsoleURL is the full base URL for the frontend (e.g. https://console.theopenlane.io).
91-
// The redirect path is derived from the definition ID so the browser lands on the integration detail page.
92-
redirectTo := h.ConsoleURL + "/organization-settings/integrations/" + def.ID
92+
// Accept either form with or without a trailing slash.
93+
redirectTo := strings.TrimRight(h.ConsoleURL, "/") + "/organization-settings/integrations/" + def.ID
9394
cookies["redirect_to"] = redirectTo
9495

9596
sessions.SetCookies(ctx.Response().Writer, cfg, cookies)

internal/httpserve/handlers/integration_flow_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,23 @@ func (suite *HandlerTestSuite) TestStartOAuthFlow_SetsDefinitionBasedRedirectCoo
209209
require.Equal(t, "http://console.example/organization-settings/integrations/"+testAuthDefinitionID, cookies["redirect_to"].Value)
210210
}
211211

212+
func (suite *HandlerTestSuite) TestStartOAuthFlow_SetsDefinitionBasedRedirectCookie_WithTrailingSlashConsoleURL() {
213+
t := suite.T()
214+
215+
suite.h.ConsoleURL = "http://console.example/"
216+
217+
op := suite.createImpersonationOperation("StartIntegrationOAuthRedirectCookieTrailingSlash", "Start integration OAuth flow")
218+
suite.registerRouteOnce(http.MethodPost, integrationStartPath, op, suite.h.StartIntegrationAuth)
219+
220+
requestCtx := privacy.DecisionContext(echocontext.NewTestEchoContext().Request().Context(), privacy.Allow)
221+
user := suite.userBuilderWithInput(requestCtx, &userInput{confirmedUser: true})
222+
223+
startRec, _ := suite.startIntegrationAuth(t, user.UserCtx, handlers.IntegrationAuthStartRequest{DefinitionID: testAuthDefinitionID})
224+
cookies := cookieMap(startRec.Result().Cookies())
225+
226+
require.Equal(t, "http://console.example/organization-settings/integrations/"+testAuthDefinitionID, cookies["redirect_to"].Value)
227+
}
228+
212229
func (suite *HandlerTestSuite) TestStartOAuthFlow_MissingProvider() {
213230
t := suite.T()
214231

internal/integrations/auth/oauth.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package auth
33
import (
44
"context"
55
"encoding/json"
6+
"fmt"
67
"maps"
78
"slices"
89
"time"
@@ -107,7 +108,7 @@ func CompleteOAuth(ctx context.Context, cfg OAuthConfig, state json.RawMessage,
107108

108109
tokens, err := rp.CodeExchange[*oidc.IDTokenClaims](ctx, code, rparty, mapAuthCodeOptions[rp.CodeExchangeOpt](cfg.TokenParams)...)
109110
if err != nil {
110-
return OAuthMaterial{}, ErrOAuthCodeExchange
111+
return OAuthMaterial{}, fmt.Errorf("%w: %w", ErrOAuthCodeExchange, err)
111112
}
112113

113114
return buildOAuthMaterial(tokens.Token, tokens.IDTokenClaims)
@@ -118,7 +119,7 @@ func buildRelyingParty(ctx context.Context, cfg OAuthConfig) (rp.RelyingParty, e
118119
if cfg.DiscoveryURL != "" {
119120
rparty, err := rp.NewRelyingPartyOIDC(ctx, cfg.DiscoveryURL, cfg.ClientID, cfg.ClientSecret, cfg.RedirectURL, cfg.Scopes)
120121
if err != nil {
121-
return nil, ErrOAuthRelyingPartyInit
122+
return nil, fmt.Errorf("%w: %w", ErrOAuthRelyingPartyInit, err)
122123
}
123124

124125
return rparty, nil
@@ -137,7 +138,7 @@ func buildRelyingParty(ctx context.Context, cfg OAuthConfig) (rp.RelyingParty, e
137138

138139
rparty, err := rp.NewRelyingPartyOAuth(oauthCfg)
139140
if err != nil {
140-
return nil, ErrOAuthRelyingPartyInit
141+
return nil, fmt.Errorf("%w: %w", ErrOAuthRelyingPartyInit, err)
141142
}
142143

143144
return rparty, nil

internal/integrations/definitions/azureentraid/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ type Config struct {
77
// ClientSecret is the Azure application client secret used for client credentials auth
88
ClientSecret string `json:"clientsecret" koanf:"clientsecret" sensitive:"true"`
99
// RedirectURL is the OAuth callback URL registered with the Azure application
10-
RedirectURL string `json:"redirecturl" koanf:"redirecturl"`
10+
RedirectURL string `json:"redirecturl" koanf:"redirecturl" default:"https://api.theopenlane.io/v1/integrations/auth/callback"`
1111
}

internal/integrations/definitions/googleworkspace/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ type Config struct {
77
// ClientSecret is the Google OAuth application client secret
88
ClientSecret string `json:"clientsecret" koanf:"clientsecret" sensitive:"true"`
99
// RedirectURL is the OAuth callback URL registered with the Google application
10-
RedirectURL string `json:"redirecturl" koanf:"redirecturl"`
10+
RedirectURL string `json:"redirecturl" koanf:"redirecturl" default:"https://api.theopenlane.io/v1/integrations/auth/callback"`
1111
}

internal/integrations/definitions/microsoftteams/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ type Config struct {
77
// ClientSecret is the Azure OAuth application client secret
88
ClientSecret string `json:"clientsecret" koanf:"clientsecret" sensitive:"true"`
99
// RedirectURL is the OAuth callback URL registered with the Azure application
10-
RedirectURL string `json:"redirecturl" koanf:"redirecturl"`
10+
RedirectURL string `json:"redirecturl" koanf:"redirecturl" default:"https://api.theopenlane.io/v1/integrations/auth/callback"`
1111
}

internal/integrations/definitions/slack/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ type Config struct {
77
// ClientSecret is the Slack OAuth application client secret
88
ClientSecret string `json:"clientsecret" koanf:"clientsecret" sensitive:"true"`
99
// RedirectURL is the OAuth callback URL registered with the Slack application
10-
RedirectURL string `json:"redirecturl" koanf:"redirecturl"`
10+
RedirectURL string `json:"redirecturl" koanf:"redirecturl" default:"https://api.theopenlane.io/v1/integrations/auth/callback"`
1111
}

0 commit comments

Comments
 (0)