mirror of
https://github.com/teamhanko/hanko.git
synced 2025-10-29 15:49:41 +08:00
fix: get session token from header for passcode finalization (#1124)
This commit is contained in:
@ -20,6 +20,7 @@ import (
|
|||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"gopkg.in/gomail.v2"
|
"gopkg.in/gomail.v2"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -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
|
// 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
|
return token
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,11 +3,14 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/teamhanko/hanko/backend/config"
|
"github.com/teamhanko/hanko/backend/config"
|
||||||
|
"github.com/teamhanko/hanko/backend/crypto/jwk"
|
||||||
"github.com/teamhanko/hanko/backend/dto"
|
"github.com/teamhanko/hanko/backend/dto"
|
||||||
"github.com/teamhanko/hanko/backend/persistence/models"
|
"github.com/teamhanko/hanko/backend/persistence/models"
|
||||||
|
"github.com/teamhanko/hanko/backend/session"
|
||||||
"github.com/teamhanko/hanko/backend/test"
|
"github.com/teamhanko/hanko/backend/test"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -141,6 +144,17 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
|
|||||||
UpdatedAt: now,
|
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 {
|
cfg := func() *config.Config {
|
||||||
return &test.DefaultConfig
|
return &test.DefaultConfig
|
||||||
}
|
}
|
||||||
@ -153,6 +167,9 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
|
|||||||
code string
|
code string
|
||||||
expectedStatusCode int
|
expectedStatusCode int
|
||||||
cfg func() *config.Config
|
cfg func() *config.Config
|
||||||
|
userId string
|
||||||
|
sendSessionTokenInCookie bool
|
||||||
|
sendSessionTokenInAuthHeader bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "finish successful",
|
name: "finish successful",
|
||||||
@ -207,14 +224,64 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
|
|||||||
expectedStatusCode: http.StatusRequestTimeout,
|
expectedStatusCode: http.StatusRequestTimeout,
|
||||||
cfg: cfg,
|
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 {
|
for _, currentTest := range tests {
|
||||||
s.Run(currentTest.name, func() {
|
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)
|
e := NewPublicRouter(currentTest.cfg(), s.Storage, nil)
|
||||||
|
|
||||||
// Setup passcode
|
// Setup passcode
|
||||||
err := s.Storage.GetPasscodePersister().Create(currentTest.passcode)
|
err = s.Storage.GetPasscodePersister().Create(currentTest.passcode)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
body := dto.PasscodeFinishRequest{
|
body := dto.PasscodeFinishRequest{
|
||||||
@ -230,6 +297,20 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
|
|||||||
for i := 0; i <= currentTest.retryCount; i++ {
|
for i := 0; i <= currentTest.retryCount; i++ {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/passcode/login/finalize", bytes.NewReader(bodyJson))
|
req := httptest.NewRequest(http.MethodPost, "/passcode/login/finalize", bytes.NewReader(bodyJson))
|
||||||
req.Header.Set("Content-Type", "application/json")
|
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()
|
rec := httptest.NewRecorder()
|
||||||
|
|
||||||
e.ServeHTTP(rec, req)
|
e.ServeHTTP(rec, req)
|
||||||
@ -249,6 +330,7 @@ func (s *passcodeSuite) TestPasscodeHandler_Finish() {
|
|||||||
|
|
||||||
// remove passcode
|
// remove passcode
|
||||||
_ = s.Storage.GetPasscodePersister().Delete(currentTest.passcode)
|
_ = s.Storage.GetPasscodePersister().Delete(currentTest.passcode)
|
||||||
|
s.TearDownTest()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
backend/test/fixtures/passcode/emails.yaml
vendored
5
backend/test/fixtures/passcode/emails.yaml
vendored
@ -34,3 +34,8 @@
|
|||||||
verified: true
|
verified: true
|
||||||
created_at: 2020-12-31 23:59:59
|
created_at: 2020-12-31 23:59:59
|
||||||
updated_at: 2020-12-31 23:59:59
|
updated_at: 2020-12-31 23:59:59
|
||||||
|
- id: 7c4473b8-ddcc-480b-b01f-df89e99f74c9
|
||||||
|
address: john.doe+6@example.com
|
||||||
|
verified: false
|
||||||
|
created_at: 2020-12-31 23:59:59
|
||||||
|
updated_at: 2020-12-31 23:59:59
|
||||||
|
|||||||
Reference in New Issue
Block a user