diff --git a/cmd/api/auth/login.go b/cmd/api/auth/login.go index be1a461..97240d3 100644 --- a/cmd/api/auth/login.go +++ b/cmd/api/auth/login.go @@ -10,10 +10,12 @@ import ( "ahbcc/internal/log" ) -// LogIn logs the user in +// LogIn logs the user in. It first verifies if the user exists in the database and then compares its password hash with +// a hashed version of the password given throw parameter, if they match, the user is allowed to log in. +// Lastly, it creates the user session and returns it with its expiration time. type LogIn func(ctx context.Context, user user.DTO) (string, time.Time, error) -// MakeLogIn creates a new LogIn function +// MakeLogIn creates a new LogIn func MakeLogIn(selectUserByUsername user.SelectByUsername, createSessionToken session.CreateToken) LogIn { return func(ctx context.Context, user user.DTO) (string, time.Time, error) { userDAO, err := selectUserByUsername(ctx, user.Username) diff --git a/cmd/api/user/session/delete.go b/cmd/api/user/session/delete.go new file mode 100644 index 0000000..1259245 --- /dev/null +++ b/cmd/api/user/session/delete.go @@ -0,0 +1,29 @@ +package session + +import ( + "context" + + "ahbcc/internal/database" + "ahbcc/internal/log" +) + +// Delete deletes a session +type Delete func(ctx context.Context, token string) error + +// MakeDelete creates a new Delete +func MakeDelete(db database.Connection) Delete { + const query string = ` + DELETE FROM users_sessions + WHERE token = $1 + ` + + return func(ctx context.Context, token string) error { + _, err := db.Exec(ctx, query, token) + if err != nil { + log.Error(ctx, err.Error()) + return FailedToDeleteUserSession + } + + return nil + } +} diff --git a/cmd/api/user/session/delete_test.go b/cmd/api/user/session/delete_test.go new file mode 100644 index 0000000..6d53e70 --- /dev/null +++ b/cmd/api/user/session/delete_test.go @@ -0,0 +1,39 @@ +package session_test + +import ( + "context" + "errors" + "testing" + + "github.com/jackc/pgx/v5/pgconn" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "ahbcc/cmd/api/user/session" + "ahbcc/internal/database" +) + +func TestDelete_success(t *testing.T) { + mockPostgresConnection := new(database.MockPostgresConnection) + mockPostgresConnection.On("Exec", mock.Anything, mock.Anything, mock.Anything).Return(pgconn.CommandTag{}, nil) + + deleteSession := session.MakeDelete(mockPostgresConnection) + + got := deleteSession(context.Background(), "token") + + assert.Nil(t, got) + mockPostgresConnection.AssertExpectations(t) +} + +func TestDelete_failsWhenDeleteOperationThrowsError(t *testing.T) { + mockPostgresConnection := new(database.MockPostgresConnection) + mockPostgresConnection.On("Exec", mock.Anything, mock.Anything, mock.Anything).Return(pgconn.CommandTag{}, errors.New("failed to delete user session")) + + deleteSession := session.MakeDelete(mockPostgresConnection) + + want := session.FailedToDeleteUserSession + got := deleteSession(context.Background(), "token") + + assert.Equal(t, want, got) + mockPostgresConnection.AssertExpectations(t) +} diff --git a/cmd/api/user/session/errors.go b/cmd/api/user/session/errors.go index cf9b739..2c32886 100644 --- a/cmd/api/user/session/errors.go +++ b/cmd/api/user/session/errors.go @@ -5,4 +5,5 @@ import "errors" var ( FailedToInsertUserSession = errors.New("failed to insert user session") FailedToCreatUserSessionToken = errors.New("failed to create user session token") + FailedToDeleteUserSession = errors.New("failed to delete user session") )