parent
a645765d43
commit
ab2b04c3cd
@ -22,7 +22,10 @@ func addAuthorization(
|
||||
email string,
|
||||
duration time.Duration,
|
||||
) {
|
||||
token, payload, err := tokenMaker.CreateToken(email, duration)
|
||||
id, err := tokenMaker.NewTokenID()
|
||||
require.NoError(t, err)
|
||||
|
||||
token, payload, err := tokenMaker.CreateToken(email, id, duration)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, payload)
|
||||
|
||||
|
@ -50,19 +50,22 @@ func (server *Server) loginAccount(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
accessToken, accessPayload, err := server.tokenMaker.CreateToken(
|
||||
account.Email,
|
||||
server.config.AccessTokenDuration,
|
||||
)
|
||||
id, err := server.tokenMaker.NewTokenID()
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, errorResponse(err))
|
||||
return
|
||||
ctx.JSON(http.StatusInternalServerError, errorResponse(errors.New("failed to create session token")))
|
||||
}
|
||||
|
||||
refreshToken, refreshPayload, err := server.tokenMaker.CreateToken(
|
||||
account.Email,
|
||||
id,
|
||||
server.config.RefreshTokenDuration,
|
||||
)
|
||||
|
||||
accessToken, accessPayload, err := server.tokenMaker.CreateToken(
|
||||
account.Email,
|
||||
id,
|
||||
server.config.AccessTokenDuration,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, errorResponse(err))
|
||||
return
|
||||
|
@ -66,10 +66,16 @@ func (server *Server) renewAccessToken(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
id, err := server.tokenMaker.NewTokenID()
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, errorResponse(errors.New("failed to create session token")))
|
||||
}
|
||||
accessToken, accessPayload, err := server.tokenMaker.CreateToken(
|
||||
refreshPayload.Email,
|
||||
id,
|
||||
server.config.AccessTokenDuration,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, errorResponse(err))
|
||||
return
|
||||
|
@ -2,8 +2,10 @@ package gapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/itsscb/df/bff/token"
|
||||
"google.golang.org/grpc/metadata"
|
||||
@ -42,18 +44,17 @@ func (server *Server) authorizeUser(ctx context.Context) (*token.Payload, error)
|
||||
return nil, fmt.Errorf("invalid access token: %s", err)
|
||||
}
|
||||
|
||||
// TODO: #76 Add check on db if session is expired
|
||||
// session, err := server.store.GetSession(ctx, payload.ID)
|
||||
// if err != nil {
|
||||
// if err == sql.ErrNoRows {
|
||||
// return nil, fmt.Errorf("no valid session found")
|
||||
// }
|
||||
// return nil, fmt.Errorf("could not get session")
|
||||
// }
|
||||
session, err := server.store.GetSession(ctx, payload.ID)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, fmt.Errorf("no valid session found")
|
||||
}
|
||||
return nil, fmt.Errorf("could not get session")
|
||||
}
|
||||
|
||||
// if session.IsBlocked || time.Now().After(session.ExpiresAt) {
|
||||
// return nil, fmt.Errorf("blocked or expired")
|
||||
// }
|
||||
if session.IsBlocked || time.Now().After(session.ExpiresAt) {
|
||||
return nil, fmt.Errorf("session blocked or expired")
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
|
@ -35,16 +35,14 @@ func (server *Server) Login(ctx context.Context, req *pb.LoginRequest) (*pb.Logi
|
||||
return nil, status.Error(codes.PermissionDenied, "invalid password")
|
||||
}
|
||||
|
||||
accessToken, accessPayload, err := server.tokenMaker.CreateToken(
|
||||
account.Email,
|
||||
server.config.AccessTokenDuration,
|
||||
)
|
||||
id, err := server.tokenMaker.NewTokenID()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "failed to create access token")
|
||||
return nil, status.Error(codes.Internal, "failed to create token id")
|
||||
}
|
||||
|
||||
refreshToken, refreshPayload, err := server.tokenMaker.CreateToken(
|
||||
account.Email,
|
||||
id,
|
||||
server.config.RefreshTokenDuration,
|
||||
)
|
||||
if err != nil {
|
||||
@ -52,9 +50,18 @@ func (server *Server) Login(ctx context.Context, req *pb.LoginRequest) (*pb.Logi
|
||||
|
||||
}
|
||||
|
||||
accessToken, accessPayload, err := server.tokenMaker.CreateToken(
|
||||
account.Email,
|
||||
id,
|
||||
server.config.AccessTokenDuration,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "failed to create access token")
|
||||
}
|
||||
|
||||
mtdt := server.extractMetadata(ctx)
|
||||
|
||||
session, err := server.store.CreateSession(ctx, db.CreateSessionParams{
|
||||
_, err = server.store.CreateSession(ctx, db.CreateSessionParams{
|
||||
ID: refreshPayload.ID,
|
||||
Email: account.Email,
|
||||
RefreshToken: refreshToken,
|
||||
@ -69,7 +76,7 @@ func (server *Server) Login(ctx context.Context, req *pb.LoginRequest) (*pb.Logi
|
||||
}
|
||||
|
||||
rsp := &pb.LoginResponse{
|
||||
SessionId: session.ID.String(),
|
||||
SessionId: refreshPayload.ID.String(),
|
||||
AccessToken: accessToken,
|
||||
AccessTokenExpiresAt: timestamppb.New(accessPayload.ExpiredAt),
|
||||
RefreshToken: refreshToken,
|
||||
|
@ -52,12 +52,17 @@ func (server *Server) RefreshToken(ctx context.Context, req *pb.RefreshTokenRequ
|
||||
return nil, status.Error(codes.PermissionDenied, "session expired")
|
||||
}
|
||||
|
||||
id, err := server.tokenMaker.NewTokenID()
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "failed to create session token")
|
||||
}
|
||||
accessToken, accessPayload, err := server.tokenMaker.CreateToken(
|
||||
refreshPayload.Email,
|
||||
id,
|
||||
server.config.AccessTokenDuration,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "cannot create session token")
|
||||
return nil, status.Error(codes.Internal, "failed to create session token")
|
||||
}
|
||||
|
||||
rsp := &pb.RefreshTokenResponse{
|
||||
|
@ -2,12 +2,15 @@ package token
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Maker is an interface for managing tokens
|
||||
type Maker interface {
|
||||
NewTokenID() (uuid.UUID, error)
|
||||
// CreateToken creates a new token for a specific username and duration
|
||||
CreateToken(email string, duration time.Duration) (string, *Payload, error)
|
||||
CreateToken(email string, id uuid.UUID, duration time.Duration) (string, *Payload, error)
|
||||
|
||||
// VerifyToken checks if the token is valid or not
|
||||
VerifyToken(token string) (*Payload, error)
|
||||
|
@ -30,9 +30,13 @@ func NewPasetoMaker(privateKeyHex string) (Maker, error) {
|
||||
return maker, nil
|
||||
}
|
||||
|
||||
func (maker *PasetoMaker) NewTokenID() (uuid.UUID, error) {
|
||||
return uuid.NewRandom()
|
||||
}
|
||||
|
||||
// CreateToken creates a new token for a specific username and duration
|
||||
func (maker *PasetoMaker) CreateToken(email string, duration time.Duration) (string, *Payload, error) {
|
||||
payload, err := NewPayload(email, duration)
|
||||
func (maker *PasetoMaker) CreateToken(email string, id uuid.UUID, duration time.Duration) (string, *Payload, error) {
|
||||
payload, err := NewPayload(email, id, duration)
|
||||
if err != nil {
|
||||
return "", payload, err
|
||||
}
|
||||
@ -41,7 +45,7 @@ func (maker *PasetoMaker) CreateToken(email string, duration time.Duration) (str
|
||||
token.SetNotBefore(time.Now())
|
||||
token.SetIssuedAt(payload.IssuedAt)
|
||||
token.SetExpiration(payload.ExpiredAt)
|
||||
token.SetString("id", payload.ID.String())
|
||||
token.SetString("id", id.String())
|
||||
token.SetString("email", payload.Email)
|
||||
|
||||
signed := token.V4Sign(maker.privateKey, nil)
|
||||
|
@ -18,7 +18,9 @@ func TestPasetoMaker(t *testing.T) {
|
||||
issuedAt := time.Now()
|
||||
expiredAt := issuedAt.Add(duration)
|
||||
|
||||
token, payload, err := maker.CreateToken(email, duration)
|
||||
id, err := maker.NewTokenID()
|
||||
require.NoError(t, err)
|
||||
token, payload, err := maker.CreateToken(email, id, duration)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, token)
|
||||
require.NotEmpty(t, payload)
|
||||
@ -37,7 +39,9 @@ func TestExpiredPasetoToken(t *testing.T) {
|
||||
maker, err := NewPasetoMaker(devPrivateKeyHex)
|
||||
require.NoError(t, err)
|
||||
|
||||
token, payload, err := maker.CreateToken(util.RandomEmail(), -time.Minute)
|
||||
id, err := maker.NewTokenID()
|
||||
require.NoError(t, err)
|
||||
token, payload, err := maker.CreateToken(util.RandomEmail(), id, -time.Minute)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, token)
|
||||
require.NotEmpty(t, payload)
|
||||
|
@ -22,12 +22,7 @@ type Payload struct {
|
||||
}
|
||||
|
||||
// NewPayload creates a new token payload with a specific accountID and duration
|
||||
func NewPayload(email string, duration time.Duration) (*Payload, error) {
|
||||
tokenID, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func NewPayload(email string, tokenID uuid.UUID, duration time.Duration) (*Payload, error) {
|
||||
payload := &Payload{
|
||||
ID: tokenID,
|
||||
Email: email,
|
||||
|
Loading…
x
Reference in New Issue
Block a user