Skip to content

Commit

Permalink
fix: get session token from header for passcode finalization (#1124)
Browse files Browse the repository at this point in the history
  • Loading branch information
FreddyDevelop authored Nov 1, 2023
1 parent 41126f8 commit 4f3adb1
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 8 deletions.
9 changes: 9 additions & 0 deletions backend/handler/passcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"golang.org/x/crypto/bcrypt"
"gopkg.in/gomail.v2"
"net/http"
"strings"
"time"
)

Expand Down Expand Up @@ -399,5 +400,13 @@ func (h *PasscodeHandler) GetSessionToken(c echo.Context) jwt.Token {
// we don't need to check the error, because when the token is not returned, the user is not logged in
}

if token == nil {
authorizationHeader := c.Request().Header.Get("Authorization")
sessionToken := strings.TrimPrefix(authorizationHeader, "Bearer")
if strings.TrimSpace(sessionToken) != "" {
token, _ = h.sessionManager.Verify(sessionToken)
}
}

return token
}
98 changes: 90 additions & 8 deletions backend/handler/passcode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package handler
import (
"bytes"
"encoding/json"
"fmt"
"github.com/gofrs/uuid"
"github.com/stretchr/testify/suite"
"github.com/teamhanko/hanko/backend/config"
"github.com/teamhanko/hanko/backend/crypto/jwk"
"github.com/teamhanko/hanko/backend/dto"
"github.com/teamhanko/hanko/backend/persistence/models"
"github.com/teamhanko/hanko/backend/session"
"github.com/teamhanko/hanko/backend/test"
"golang.org/x/crypto/bcrypt"
"net/http"
Expand Down Expand Up @@ -141,18 +144,32 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
UpdatedAt: now,
}

passcodeForNonAssignedEmail := models.Passcode{
ID: uuid.FromStringOrNil("494129d5-76de-4fae-b07d-f2a521e1804d"),
UserId: uuid.FromStringOrNil("b5dd5267-b462-48be-b70d-bcd6f1bbe7a5"),
EmailID: uuid.FromStringOrNil("7c4473b8-ddcc-480b-b01f-df89e99f74c9"),
Ttl: 300,
Code: string(hashedPasscode),
TryCount: 0,
CreatedAt: now,
UpdatedAt: now,
}

cfg := func() *config.Config {
return &test.DefaultConfig
}

tests := []struct {
name string
passcodeId string
retryCount int
passcode models.Passcode
code string
expectedStatusCode int
cfg func() *config.Config
name string
passcodeId string
retryCount int
passcode models.Passcode
code string
expectedStatusCode int
cfg func() *config.Config
userId string
sendSessionTokenInCookie bool
sendSessionTokenInAuthHeader bool
}{
{
name: "finish successful",
Expand Down Expand Up @@ -207,14 +224,64 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
expectedStatusCode: http.StatusRequestTimeout,
cfg: cfg,
},
{
name: "create email with session in cookie",
passcodeId: "494129d5-76de-4fae-b07d-f2a521e1804d",
passcode: passcodeForNonAssignedEmail,
code: "123456",
expectedStatusCode: http.StatusOK,
cfg: cfg,
userId: "b5dd5267-b462-48be-b70d-bcd6f1bbe7a5",
sendSessionTokenInCookie: true,
},
{
name: "do not create email with wrong session in cookie",
passcodeId: "494129d5-76de-4fae-b07d-f2a521e1804d",
passcode: passcodeForNonAssignedEmail,
code: "123456",
expectedStatusCode: http.StatusForbidden,
cfg: cfg,
userId: "851842a9-db50-49b5-aa00-1c447c31d819",
sendSessionTokenInCookie: true,
},
{
name: "create email with session in Authorization header",
passcodeId: "494129d5-76de-4fae-b07d-f2a521e1804d",
passcode: passcodeForNonAssignedEmail,
code: "123456",
expectedStatusCode: http.StatusOK,
cfg: cfg,
userId: "b5dd5267-b462-48be-b70d-bcd6f1bbe7a5",
sendSessionTokenInAuthHeader: true,
},
{
name: "do not create email with wrong session in Authorization header",
passcodeId: "494129d5-76de-4fae-b07d-f2a521e1804d",
passcode: passcodeForNonAssignedEmail,
code: "123456",
expectedStatusCode: http.StatusForbidden,
cfg: cfg,
userId: "851842a9-db50-49b5-aa00-1c447c31d819",
sendSessionTokenInAuthHeader: true,
},
}

for _, currentTest := range tests {
s.Run(currentTest.name, func() {
s.SetupTest()

err := s.LoadFixtures("../test/fixtures/passcode")
s.Require().NoError(err)

jwkManager, err := jwk.NewDefaultManager(test.DefaultConfig.Secrets.Keys, s.Storage.GetJwkPersister())
s.Require().NoError(err)
sessionManager, err := session.NewManager(jwkManager, test.DefaultConfig)
s.Require().NoError(err)

e := NewPublicRouter(currentTest.cfg(), s.Storage, nil)

// Setup passcode
err := s.Storage.GetPasscodePersister().Create(currentTest.passcode)
err = s.Storage.GetPasscodePersister().Create(currentTest.passcode)
s.Require().NoError(err)

body := dto.PasscodeFinishRequest{
Expand All @@ -230,6 +297,20 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
for i := 0; i <= currentTest.retryCount; i++ {
req := httptest.NewRequest(http.MethodPost, "/passcode/login/finalize", bytes.NewReader(bodyJson))
req.Header.Set("Content-Type", "application/json")
if currentTest.sendSessionTokenInAuthHeader {
sessionToken, err := sessionManager.GenerateJWT(uuid.FromStringOrNil(currentTest.userId))
s.Require().NoError(err)
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", sessionToken))
}

if currentTest.sendSessionTokenInCookie {
sessionToken, err := sessionManager.GenerateJWT(uuid.FromStringOrNil(currentTest.userId))
s.Require().NoError(err)

sessionCookie, err := sessionManager.GenerateCookie(sessionToken)
s.Require().NoError(err)
req.AddCookie(sessionCookie)
}
rec := httptest.NewRecorder()

e.ServeHTTP(rec, req)
Expand All @@ -249,6 +330,7 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {

// remove passcode
_ = s.Storage.GetPasscodePersister().Delete(currentTest.passcode)
s.TearDownTest()
})
}
}
5 changes: 5 additions & 0 deletions backend/test/fixtures/passcode/emails.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@
verified: true
created_at: 2020-12-31 23:59:59
updated_at: 2020-12-31 23:59:59
- id: 7c4473b8-ddcc-480b-b01f-df89e99f74c9
address: [email protected]
verified: false
created_at: 2020-12-31 23:59:59
updated_at: 2020-12-31 23:59:59

0 comments on commit 4f3adb1

Please sign in to comment.