Skip to content

Commit

Permalink
chore: updated webhook to log redirect logic and updated status codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Goldziher committed Jan 15, 2024
1 parent 669b6b6 commit aa5425b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 37 deletions.
70 changes: 39 additions & 31 deletions services/dashboard-backend/internal/api/webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/basemind-ai/monorepo/shared/go/db/models"
"github.com/basemind-ai/monorepo/shared/go/exc"
"github.com/basemind-ai/monorepo/shared/go/urlutils"
"github.com/rs/zerolog/log"
"net/http"
)

Expand All @@ -25,24 +26,19 @@ func handleUserInvitationWebhook(w http.ResponseWriter, r *http.Request) {
return
}

invitation, retrievalErr := db.GetQueries().
RetrieveProjectInvitationByID(r.Context(), *invitationID)
if retrievalErr != nil {
apierror.BadRequest("invitation does not exist").Render(w)
return
}

cfg := config.Get(r.Context())
// TODO: when we support localisation, we should pass locale as a query param as well.
redirectURL := fmt.Sprintf("%s/en/sign-in", cfg.FrontendBaseURL)

if exc.MustResult(
db.GetQueries().CheckUserProjectExists(r.Context(), models.CheckUserProjectExistsParams{
Email: invitation.Email,
ProjectID: invitation.ProjectID,
}),
) {
http.Redirect(w, r, redirectURL, http.StatusSeeOther)
invitation, retrievalErr := db.GetQueries().
RetrieveProjectInvitationByID(r.Context(), *invitationID)

if retrievalErr != nil {
log.Debug().
Err(retrievalErr).
Str("redirectURL", redirectURL).
Msg("failed to retrieve invitation, redirecting to sign in page")
http.Redirect(w, r, redirectURL, http.StatusPermanentRedirect)
return
}

Expand All @@ -51,26 +47,38 @@ func handleUserInvitationWebhook(w http.ResponseWriter, r *http.Request) {

queries := db.GetQueries().WithTx(tx)

userAccount, userRetrievalErr := queries.RetrieveUserAccountByEmail(
r.Context(),
invitation.Email,
)
if userRetrievalErr != nil {
createdUserAccount := exc.MustResult(
queries.CreateUserAccount(r.Context(), models.CreateUserAccountParams{
Email: invitation.Email,
}),
if !exc.MustResult(
db.GetQueries().CheckUserProjectExists(r.Context(), models.CheckUserProjectExistsParams{
Email: invitation.Email,
ProjectID: invitation.ProjectID,
}),
) {
userAccount, userRetrievalErr := queries.RetrieveUserAccountByEmail(
r.Context(),
invitation.Email,
)
userAccount = createdUserAccount
if userRetrievalErr != nil {
createdUserAccount := exc.MustResult(
queries.CreateUserAccount(r.Context(), models.CreateUserAccountParams{
Email: invitation.Email,
}),
)
userAccount = createdUserAccount
}

exc.MustResult(queries.CreateUserProject(r.Context(), models.CreateUserProjectParams{
ProjectID: invitation.ProjectID,
UserID: userAccount.ID,
Permission: invitation.Permission,
}))
}

exc.MustResult(queries.CreateUserProject(r.Context(), models.CreateUserProjectParams{
ProjectID: invitation.ProjectID,
UserID: userAccount.ID,
Permission: invitation.Permission,
}))
exc.Must(queries.DeleteProjectInvitation(r.Context(), invitation.ID))
exc.Must(tx.Commit(r.Context()))

http.Redirect(w, r, redirectURL, http.StatusSeeOther)
http.Redirect(w, r, redirectURL, http.StatusPermanentRedirect)
log.Debug().
Str("redirectURL", redirectURL).
Str("email", invitation.Email).
Str("projectId", db.UUIDToString(&invitation.ProjectID)).
Msg("user invitation handled")
}
10 changes: 5 additions & 5 deletions services/dashboard-backend/internal/api/webhooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestWebhooksAPI(t *testing.T) {
signedURL,
)
assert.NoError(t, requestErr)
assert.Equal(t, http.StatusOK, response.StatusCode)
assert.Equal(t, http.StatusPermanentRedirect, response.StatusCode)

userAccount, retrievalErr := db.GetQueries().
RetrieveUserAccountByEmail(context.TODO(), email)
Expand Down Expand Up @@ -112,7 +112,7 @@ func TestWebhooksAPI(t *testing.T) {
signedURL,
)
assert.NoError(t, requestErr)
assert.Equal(t, http.StatusOK, response.StatusCode)
assert.Equal(t, http.StatusPermanentRedirect, response.StatusCode)

exists, checkErr := db.GetQueries().
CheckUserProjectExists(context.TODO(), models.CheckUserProjectExistsParams{
Expand Down Expand Up @@ -149,7 +149,7 @@ func TestWebhooksAPI(t *testing.T) {
signedURL,
)
assert.NoError(t, requestErr)
assert.Equal(t, http.StatusOK, response.StatusCode)
assert.Equal(t, http.StatusPermanentRedirect, response.StatusCode)
})

t.Run(
Expand All @@ -167,7 +167,7 @@ func TestWebhooksAPI(t *testing.T) {
)

t.Run(
"responds with 400 BAD REQUEST when no invite exists with the given ID",
"responds with 308 Permanent Redirect and redirect the user when no invite exists with the given ID",
func(t *testing.T) {
signedURL := createSignedURL(
"b50e5477-f74a-4e80-be29-ae67eb6ada95",
Expand All @@ -178,7 +178,7 @@ func TestWebhooksAPI(t *testing.T) {
signedURL,
)
assert.NoError(t, requestErr)
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
assert.Equal(t, http.StatusPermanentRedirect, response.StatusCode)
},
)

Expand Down
8 changes: 7 additions & 1 deletion shared/go/testutils/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,11 @@ func CreateTestHTTPClient(t *testing.T, handler http.Handler) httpclient.Client
server.Close()
})

return httpclient.New(server.URL, server.Client())
client := server.Client()
// we want to test that redirects are returned correctly by the API
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}

return httpclient.New(server.URL, client)
}

0 comments on commit aa5425b

Please sign in to comment.