feat(observabillity): #153 instrument sqlx
All checks were successful
Build Docker Image / Build-Docker-Image (push) Successful in 2m29s
Build and Push Docker Image / Build-And-Push-Docker-Image (push) Successful in 2m49s

This commit was merged in pull request #160.
This commit is contained in:
2025-06-07 21:55:59 +02:00
parent c4aca2778f
commit 11f3bcc89f
25 changed files with 434 additions and 409 deletions

View File

@@ -26,24 +26,24 @@ var (
)
type Auth interface {
SignUp(email string, password string) (*types.User, error)
SendVerificationMail(userId uuid.UUID, email string)
VerifyUserEmail(token string) error
SignUp(ctx context.Context, email string, password string) (*types.User, error)
SendVerificationMail(ctx context.Context, userId uuid.UUID, email string)
VerifyUserEmail(ctx context.Context, token string) error
SignIn(session *types.Session, email string, password string) (*types.Session, *types.User, error)
SignInSession(sessionId string) (*types.Session, *types.User, error)
SignInAnonymous() (*types.Session, error)
SignOut(sessionId string) error
SignIn(ctx context.Context, session *types.Session, email string, password string) (*types.Session, *types.User, error)
SignInSession(ctx context.Context, sessionId string) (*types.Session, *types.User, error)
SignInAnonymous(ctx context.Context) (*types.Session, error)
SignOut(ctx context.Context, sessionId string) error
DeleteAccount(user *types.User, currPass string) error
DeleteAccount(ctx context.Context, user *types.User, currPass string) error
ChangePassword(user *types.User, sessionId string, currPass, newPass string) error
ChangePassword(ctx context.Context, user *types.User, sessionId string, currPass, newPass string) error
SendForgotPasswordMail(email string) error
ForgotPassword(token string, newPass string) error
SendForgotPasswordMail(ctx context.Context, email string) error
ForgotPassword(ctx context.Context, token string, newPass string) error
IsCsrfTokenValid(tokenStr string, sessionId string) bool
GetCsrfToken(session *types.Session) (string, error)
IsCsrfTokenValid(ctx context.Context, tokenStr string, sessionId string) bool
GetCsrfToken(ctx context.Context, session *types.Session) (string, error)
}
type AuthImpl struct {
@@ -64,8 +64,8 @@ func NewAuth(db db.Auth, random Random, clock Clock, mail Mail, serverSettings *
}
}
func (service AuthImpl) SignIn(session *types.Session, email string, password string) (*types.Session, *types.User, error) {
user, err := service.db.GetUserByEmail(email)
func (service AuthImpl) SignIn(ctx context.Context, session *types.Session, email string, password string) (*types.Session, *types.User, error) {
user, err := service.db.GetUserByEmail(ctx, email)
if err != nil {
if errors.Is(err, db.ErrNotFound) {
return nil, nil, ErrInvalidCredentials
@@ -80,12 +80,12 @@ func (service AuthImpl) SignIn(session *types.Session, email string, password st
return nil, nil, ErrInvalidCredentials
}
err = service.cleanUpSessionWithTokens(session)
err = service.cleanUpSessionWithTokens(ctx, session)
if err != nil {
return nil, nil, types.ErrInternal
}
session, err = service.createSession(user.Id)
session, err = service.createSession(ctx, user.Id)
if err != nil {
return nil, nil, types.ErrInternal
}
@@ -93,17 +93,17 @@ func (service AuthImpl) SignIn(session *types.Session, email string, password st
return session, user, nil
}
func (service AuthImpl) SignInSession(sessionId string) (*types.Session, *types.User, error) {
func (service AuthImpl) SignInSession(ctx context.Context, sessionId string) (*types.Session, *types.User, error) {
if sessionId == "" {
return nil, nil, ErrSessionIdInvalid
}
session, err := service.db.GetSession(sessionId)
session, err := service.db.GetSession(ctx, sessionId)
if err != nil {
return nil, nil, types.ErrInternal
}
if session.ExpiresAt.Before(service.clock.Now()) {
_ = service.db.DeleteSession(sessionId)
_ = service.db.DeleteSession(ctx, sessionId)
return nil, nil, nil
}
@@ -111,7 +111,7 @@ func (service AuthImpl) SignInSession(sessionId string) (*types.Session, *types.
return session, nil, nil
}
user, err := service.db.GetUser(session.UserId)
user, err := service.db.GetUser(ctx, session.UserId)
if err != nil {
return nil, nil, types.ErrInternal
}
@@ -119,8 +119,8 @@ func (service AuthImpl) SignInSession(sessionId string) (*types.Session, *types.
return session, user, nil
}
func (service AuthImpl) SignInAnonymous() (*types.Session, error) {
session, err := service.createSession(uuid.Nil)
func (service AuthImpl) SignInAnonymous(ctx context.Context) (*types.Session, error) {
session, err := service.createSession(ctx, uuid.Nil)
if err != nil {
return nil, types.ErrInternal
}
@@ -130,7 +130,7 @@ func (service AuthImpl) SignInAnonymous() (*types.Session, error) {
return session, nil
}
func (service AuthImpl) SignUp(email string, password string) (*types.User, error) {
func (service AuthImpl) SignUp(ctx context.Context, email string, password string) (*types.User, error) {
_, err := mail.ParseAddress(email)
if err != nil {
return nil, ErrInvalidEmail
@@ -154,7 +154,7 @@ func (service AuthImpl) SignUp(email string, password string) (*types.User, erro
user := types.NewUser(userId, email, false, nil, false, hash, salt, service.clock.Now())
err = service.db.InsertUser(user)
err = service.db.InsertUser(ctx, user)
if err != nil {
if errors.Is(err, db.ErrAlreadyExists) {
return nil, ErrAccountExists
@@ -166,8 +166,8 @@ func (service AuthImpl) SignUp(email string, password string) (*types.User, erro
return user, nil
}
func (service AuthImpl) SendVerificationMail(userId uuid.UUID, email string) {
tokens, err := service.db.GetTokensByUserIdAndType(userId, types.TokenTypeEmailVerify)
func (service AuthImpl) SendVerificationMail(ctx context.Context, userId uuid.UUID, email string) {
tokens, err := service.db.GetTokensByUserIdAndType(ctx, userId, types.TokenTypeEmailVerify)
if err != nil && !errors.Is(err, db.ErrNotFound) {
return
}
@@ -192,7 +192,7 @@ func (service AuthImpl) SendVerificationMail(userId uuid.UUID, email string) {
service.clock.Now(),
service.clock.Now().Add(24*time.Hour))
err = service.db.InsertToken(token)
err = service.db.InsertToken(ctx, token)
if err != nil {
return
}
@@ -208,17 +208,17 @@ func (service AuthImpl) SendVerificationMail(userId uuid.UUID, email string) {
service.mail.SendMail(email, "Welcome to spend-sparrow", w.String())
}
func (service AuthImpl) VerifyUserEmail(tokenStr string) error {
func (service AuthImpl) VerifyUserEmail(ctx context.Context, tokenStr string) error {
if tokenStr == "" {
return types.ErrInternal
}
token, err := service.db.GetToken(tokenStr)
token, err := service.db.GetToken(ctx, tokenStr)
if err != nil {
return types.ErrInternal
}
user, err := service.db.GetUser(token.UserId)
user, err := service.db.GetUser(ctx, token.UserId)
if err != nil {
return types.ErrInternal
}
@@ -236,21 +236,21 @@ func (service AuthImpl) VerifyUserEmail(tokenStr string) error {
user.EmailVerified = true
user.EmailVerifiedAt = &now
err = service.db.UpdateUser(user)
err = service.db.UpdateUser(ctx, user)
if err != nil {
return types.ErrInternal
}
_ = service.db.DeleteToken(token.Token)
_ = service.db.DeleteToken(ctx, token.Token)
return nil
}
func (service AuthImpl) SignOut(sessionId string) error {
return service.db.DeleteSession(sessionId)
func (service AuthImpl) SignOut(ctx context.Context, sessionId string) error {
return service.db.DeleteSession(ctx, sessionId)
}
func (service AuthImpl) DeleteAccount(user *types.User, currPass string) error {
userDb, err := service.db.GetUser(user.Id)
func (service AuthImpl) DeleteAccount(ctx context.Context, user *types.User, currPass string) error {
userDb, err := service.db.GetUser(ctx, user.Id)
if err != nil {
return types.ErrInternal
}
@@ -260,7 +260,7 @@ func (service AuthImpl) DeleteAccount(user *types.User, currPass string) error {
return ErrInvalidCredentials
}
err = service.db.DeleteUser(user.Id)
err = service.db.DeleteUser(ctx, user.Id)
if err != nil {
return err
}
@@ -270,7 +270,7 @@ func (service AuthImpl) DeleteAccount(user *types.User, currPass string) error {
return nil
}
func (service AuthImpl) ChangePassword(user *types.User, sessionId string, currPass, newPass string) error {
func (service AuthImpl) ChangePassword(ctx context.Context, user *types.User, sessionId string, currPass, newPass string) error {
if !isPasswordValid(newPass) {
return ErrInvalidPassword
}
@@ -288,18 +288,18 @@ func (service AuthImpl) ChangePassword(user *types.User, sessionId string, currP
newHash := GetHashPassword(newPass, user.Salt)
user.Password = newHash
err := service.db.UpdateUser(user)
err := service.db.UpdateUser(ctx, user)
if err != nil {
return err
}
sessions, err := service.db.GetSessions(user.Id)
sessions, err := service.db.GetSessions(ctx, user.Id)
if err != nil {
return types.ErrInternal
}
for _, s := range sessions {
if s.Id != sessionId {
err = service.db.DeleteSession(s.Id)
err = service.db.DeleteSession(ctx, s.Id)
if err != nil {
return types.ErrInternal
}
@@ -309,13 +309,13 @@ func (service AuthImpl) ChangePassword(user *types.User, sessionId string, currP
return nil
}
func (service AuthImpl) SendForgotPasswordMail(email string) error {
func (service AuthImpl) SendForgotPasswordMail(ctx context.Context, email string) error {
tokenStr, err := service.random.String(32)
if err != nil {
return err
}
user, err := service.db.GetUserByEmail(email)
user, err := service.db.GetUserByEmail(ctx, email)
if err != nil {
if errors.Is(err, db.ErrNotFound) {
return nil
@@ -332,7 +332,7 @@ func (service AuthImpl) SendForgotPasswordMail(email string) error {
service.clock.Now(),
service.clock.Now().Add(15*time.Minute))
err = service.db.InsertToken(token)
err = service.db.InsertToken(ctx, token)
if err != nil {
return types.ErrInternal
}
@@ -348,17 +348,17 @@ func (service AuthImpl) SendForgotPasswordMail(email string) error {
return nil
}
func (service AuthImpl) ForgotPassword(tokenStr string, newPass string) error {
func (service AuthImpl) ForgotPassword(ctx context.Context, tokenStr string, newPass string) error {
if !isPasswordValid(newPass) {
return ErrInvalidPassword
}
token, err := service.db.GetToken(tokenStr)
token, err := service.db.GetToken(ctx, tokenStr)
if err != nil {
return ErrTokenInvalid
}
err = service.db.DeleteToken(tokenStr)
err = service.db.DeleteToken(ctx, tokenStr)
if err != nil {
return err
}
@@ -368,7 +368,7 @@ func (service AuthImpl) ForgotPassword(tokenStr string, newPass string) error {
return ErrTokenInvalid
}
user, err := service.db.GetUser(token.UserId)
user, err := service.db.GetUser(ctx, token.UserId)
if err != nil {
slog.Error("Could not get user from token", "err", err)
return types.ErrInternal
@@ -377,18 +377,18 @@ func (service AuthImpl) ForgotPassword(tokenStr string, newPass string) error {
passHash := GetHashPassword(newPass, user.Salt)
user.Password = passHash
err = service.db.UpdateUser(user)
err = service.db.UpdateUser(ctx, user)
if err != nil {
return err
}
sessions, err := service.db.GetSessions(user.Id)
sessions, err := service.db.GetSessions(ctx, user.Id)
if err != nil {
return types.ErrInternal
}
for _, session := range sessions {
err = service.db.DeleteSession(session.Id)
err = service.db.DeleteSession(ctx, session.Id)
if err != nil {
return types.ErrInternal
}
@@ -397,8 +397,8 @@ func (service AuthImpl) ForgotPassword(tokenStr string, newPass string) error {
return nil
}
func (service AuthImpl) IsCsrfTokenValid(tokenStr string, sessionId string) bool {
token, err := service.db.GetToken(tokenStr)
func (service AuthImpl) IsCsrfTokenValid(ctx context.Context, tokenStr string, sessionId string) bool {
token, err := service.db.GetToken(ctx, tokenStr)
if err != nil {
return false
}
@@ -412,12 +412,12 @@ func (service AuthImpl) IsCsrfTokenValid(tokenStr string, sessionId string) bool
return true
}
func (service AuthImpl) GetCsrfToken(session *types.Session) (string, error) {
func (service AuthImpl) GetCsrfToken(ctx context.Context, session *types.Session) (string, error) {
if session == nil {
return "", types.ErrInternal
}
tokens, _ := service.db.GetTokensBySessionIdAndType(session.Id, types.TokenTypeCsrf)
tokens, _ := service.db.GetTokensBySessionIdAndType(ctx, session.Id, types.TokenTypeCsrf)
if len(tokens) > 0 {
return tokens[0].Token, nil
@@ -435,7 +435,7 @@ func (service AuthImpl) GetCsrfToken(session *types.Session) (string, error) {
types.TokenTypeCsrf,
service.clock.Now(),
service.clock.Now().Add(8*time.Hour))
err = service.db.InsertToken(token)
err = service.db.InsertToken(ctx, token)
if err != nil {
return "", types.ErrInternal
}
@@ -445,22 +445,22 @@ func (service AuthImpl) GetCsrfToken(session *types.Session) (string, error) {
return tokenStr, nil
}
func (service AuthImpl) cleanUpSessionWithTokens(session *types.Session) error {
func (service AuthImpl) cleanUpSessionWithTokens(ctx context.Context, session *types.Session) error {
if session == nil {
return nil
}
err := service.db.DeleteSession(session.Id)
err := service.db.DeleteSession(ctx, session.Id)
if err != nil {
return types.ErrInternal
}
tokens, err := service.db.GetTokensBySessionIdAndType(session.Id, types.TokenTypeCsrf)
tokens, err := service.db.GetTokensBySessionIdAndType(ctx, session.Id, types.TokenTypeCsrf)
if err != nil {
return types.ErrInternal
}
for _, token := range tokens {
err = service.db.DeleteToken(token.Token)
err = service.db.DeleteToken(ctx, token.Token)
if err != nil {
return types.ErrInternal
}
@@ -469,13 +469,13 @@ func (service AuthImpl) cleanUpSessionWithTokens(session *types.Session) error {
return nil
}
func (service AuthImpl) createSession(userId uuid.UUID) (*types.Session, error) {
func (service AuthImpl) createSession(ctx context.Context, userId uuid.UUID) (*types.Session, error) {
sessionId, err := service.random.String(32)
if err != nil {
return nil, types.ErrInternal
}
err = service.db.DeleteOldSessions(userId)
err = service.db.DeleteOldSessions(ctx, userId)
if err != nil {
return nil, types.ErrInternal
}
@@ -485,7 +485,7 @@ func (service AuthImpl) createSession(userId uuid.UUID) (*types.Session, error)
session := types.NewSession(sessionId, userId, createAt, expiresAt)
err = service.db.InsertSession(session)
err = service.db.InsertSession(ctx, session)
if err != nil {
return nil, types.ErrInternal
}