Skip to content

Commit

Permalink
Merge branch 'master' into mfa
Browse files Browse the repository at this point in the history
  • Loading branch information
J0 committed Oct 18, 2022
2 parents 204bb87 + 85cff37 commit 2ad2737
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 49 deletions.
14 changes: 14 additions & 0 deletions api/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ func (a *API) adminUserUpdate(w http.ResponseWriter, r *http.Request) error {
return err
}

if params.Email != "" {
params.Email, err = a.validateEmail(ctx, params.Email)
if err != nil {
return err
}
}

if params.Phone != "" {
params.Phone, err = a.validatePhone(params.Phone)
if err != nil {
return err
}
}

err = db.Transaction(func(tx *storage.Connection) error {
if params.Role != "" {
if terr := user.SetRole(tx, params.Role); terr != nil {
Expand Down
9 changes: 4 additions & 5 deletions api/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package api

import (
"context"
"errors"
"fmt"
"net/http"
"time"
Expand Down Expand Up @@ -73,7 +72,7 @@ func (a *API) parseJWTClaims(bearer string, r *http.Request, w http.ResponseWrit
})
if err != nil {
a.clearCookieTokens(config, w)
return nil, unauthorizedError("Invalid token: %v", err)
return nil, unauthorizedError("invalid JWT: unable to parse or verify signature").WithInternalError(err)
}

return withToken(ctx, token), nil
Expand All @@ -84,18 +83,18 @@ func (a *API) maybeLoadUserOrSession(ctx context.Context) (context.Context, erro
claims := getClaims(ctx)

if claims == nil {
return ctx, errors.New("invalid token")
return ctx, unauthorizedError("invalid token: missing claims")
}

if claims.Subject == "" {
return nil, errors.New("invalid claim: subject missing")
return nil, unauthorizedError("invalid claim: missing sub claim")
}

var user *models.User
if claims.Subject != "" {
userId, err := uuid.FromString(claims.Subject)
if err != nil {
return ctx, err
return ctx, badRequestError("invalid claim: sub claim must be a UUID").WithInternalError(err)
}
user, err = models.FindUserByID(db, userId)
if err != nil {
Expand Down
20 changes: 17 additions & 3 deletions api/auth_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package api

import (
"errors"
"net/http"
"net/http/httptest"
"testing"
Expand Down Expand Up @@ -101,7 +100,7 @@ func (ts *AuthTestSuite) TestMaybeLoadUserOrSession() {
},
Role: "authenticated",
},
ExpectedError: errors.New("invalid claim: subject missing"),
ExpectedError: unauthorizedError("invalid claim: missing sub claim"),
ExpectedUser: nil,
},
{
Expand All @@ -115,6 +114,17 @@ func (ts *AuthTestSuite) TestMaybeLoadUserOrSession() {
ExpectedError: nil,
ExpectedUser: u,
},
{
Desc: "Invalid Subject Claim",
UserJwtClaims: &GoTrueClaims{
StandardClaims: jwt.StandardClaims{
Subject: "invalid-subject-claim",
},
Role: "authenticated",
},
ExpectedError: badRequestError("invalid claim: sub claim must be a UUID"),
ExpectedUser: nil,
},
{
Desc: "Empty Session ID Claim",
UserJwtClaims: &GoTrueClaims{
Expand Down Expand Up @@ -166,7 +176,11 @@ func (ts *AuthTestSuite) TestMaybeLoadUserOrSession() {
ctx, err := ts.API.parseJWTClaims(userJwt, req, w)
require.NoError(ts.T(), err)
ctx, err = ts.API.maybeLoadUserOrSession(ctx)
require.Equal(ts.T(), c.ExpectedError, err)
if c.ExpectedError != nil {
require.Equal(ts.T(), c.ExpectedError.Error(), err.Error())
} else {
require.Equal(ts.T(), c.ExpectedError, err)
}
require.Equal(ts.T(), c.ExpectedUser, getUser(ctx))
require.Equal(ts.T(), c.ExpectedSession, getSession(ctx))
})
Expand Down
12 changes: 6 additions & 6 deletions api/otp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ func (ts *OtpTestSuite) TestOtp() {
}
}{
{
"Test Success Magiclink Otp",
OtpParams{
desc: "Test Success Magiclink Otp",
params: OtpParams{
Email: "test@example.com",
CreateUser: true,
Data: map[string]interface{}{
"somedata": "metadata",
},
},
struct {
expected: struct {
code int
response map[string]interface{}
}{
Expand All @@ -64,13 +64,13 @@ func (ts *OtpTestSuite) TestOtp() {
},
},
{
"Test Failure Pass Both Email & Phone",
OtpParams{
desc: "Test Failure Pass Both Email & Phone",
params: OtpParams{
Email: "test@example.com",
Phone: "123456789",
CreateUser: true,
},
struct {
expected: struct {
code int
response map[string]interface{}
}{
Expand Down
48 changes: 24 additions & 24 deletions api/token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,44 +170,44 @@ func (ts *TokenTestSuite) TestTokenRefreshTokenRotation() {
expectedBody map[string]interface{}
}{
{
"Valid refresh within reuse interval",
true,
30,
second.Token,
http.StatusOK,
map[string]interface{}{
desc: "Valid refresh within reuse interval",
refreshTokenRotationEnabled: true,
reuseInterval: 30,
refreshToken: second.Token,
expectedCode: http.StatusOK,
expectedBody: map[string]interface{}{
"refresh_token": third.Token,
},
},
{
"Invalid refresh, first token is not the previous revoked token",
true,
0,
first.Token,
http.StatusBadRequest,
map[string]interface{}{
desc: "Invalid refresh, first token is not the previous revoked token",
refreshTokenRotationEnabled: true,
reuseInterval: 0,
refreshToken: first.Token,
expectedCode: http.StatusBadRequest,
expectedBody: map[string]interface{}{
"error": "invalid_grant",
"error_description": "Invalid Refresh Token",
},
},
{
"Invalid refresh, revoked third token",
true,
0,
second.Token,
http.StatusBadRequest,
map[string]interface{}{
desc: "Invalid refresh, revoked third token",
refreshTokenRotationEnabled: true,
reuseInterval: 0,
refreshToken: second.Token,
expectedCode: http.StatusBadRequest,
expectedBody: map[string]interface{}{
"error": "invalid_grant",
"error_description": "Invalid Refresh Token",
},
},
{
"Invalid refresh, third token revoked by previous case",
true,
30,
third.Token,
http.StatusBadRequest,
map[string]interface{}{
desc: "Invalid refresh, third token revoked by previous case",
refreshTokenRotationEnabled: true,
reuseInterval: 30,
refreshToken: third.Token,
expectedCode: http.StatusBadRequest,
expectedBody: map[string]interface{}{
"error": "invalid_grant",
"error_description": "Invalid Refresh Token",
},
Expand Down
20 changes: 10 additions & 10 deletions api/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,36 +549,36 @@ func (ts *VerifyTestSuite) TestVerifyBannedUser() {
payload *VerifyParams
}{
{
"Verify banned user on signup",
&VerifyParams{
desc: "Verify banned user on signup",
payload: &VerifyParams{
Type: "signup",
Token: u.ConfirmationToken,
},
},
{
"Verify banned user on invite",
&VerifyParams{
desc: "Verify banned user on invite",
payload: &VerifyParams{
Type: "invite",
Token: u.ConfirmationToken,
},
},
{
"Verify banned user on recover",
&VerifyParams{
desc: "Verify banned user on recover",
payload: &VerifyParams{
Type: "recovery",
Token: u.RecoveryToken,
},
},
{
"Verify banned user on magiclink",
&VerifyParams{
desc: "Verify banned user on magiclink",
payload: &VerifyParams{
Type: "magiclink",
Token: u.RecoveryToken,
},
},
{
"Verify banned user on email change",
&VerifyParams{
desc: "Verify banned user on email change",
payload: &VerifyParams{
Type: "email_change",
Token: u.EmailChangeTokenCurrent,
},
Expand Down
2 changes: 1 addition & 1 deletion migrations/20221011041400_add_mfa_indexes.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ alter table {{ index .Options "Namespace" }}.mfa_amr_claims

create index if not exists user_id_created_at_idx on {{ index .Options "Namespace" }}.sessions (user_id, created_at);
create index if not exists factor_id_created_at_idx on {{ index .Options "Namespace" }}.mfa_factors (user_id, created_at);
-- Add Index which handles the clause below

0 comments on commit 2ad2737

Please sign in to comment.