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