feat(authz): redirect deleted accounts to /login
detect soft-deleted users during authorization lookup return a dedicated deleted-user result from auth services redirect deleted accounts to /login in the handler update repository, service, and handler tests for the new flow
This commit is contained in:
@@ -4,10 +4,13 @@ import (
|
||||
"authorization/db"
|
||||
"authorization/models"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
var ErrUserDeleted = errors.New("user is deleted")
|
||||
|
||||
func GetPermissionByResourceActionAndRole(resource, action string, roleID int) (*models.Permission, error) {
|
||||
log.Printf("[Repository] GetPermissionByResourceActionAndRole - resource=%s, action=%s, roleID=%d",
|
||||
resource, action, roleID)
|
||||
@@ -128,13 +131,13 @@ func GetUserByID(userID string) (*models.User, error) {
|
||||
log.Printf("[Repository] GetUserByID - userID=%s", userID)
|
||||
|
||||
query := `
|
||||
SELECT users_id, email_address
|
||||
SELECT users_id, email_address, role_id, is_deleted
|
||||
FROM uess_user_management.users
|
||||
WHERE users_id = ?
|
||||
`
|
||||
|
||||
var user models.User
|
||||
err := db.DB.QueryRow(query, userID).Scan(&user.UsersID, &user.EmailAddress)
|
||||
err := db.DB.QueryRow(query, userID).Scan(&user.UsersID, &user.EmailAddress, &user.RoleID, &user.IsDeleted)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
log.Printf("[Repository] ✗ User not found: %s", userID)
|
||||
@@ -144,6 +147,11 @@ func GetUserByID(userID string) (*models.User, error) {
|
||||
return nil, fmt.Errorf("error querying user: %w", err)
|
||||
}
|
||||
|
||||
if user.IsDeleted == "1" {
|
||||
log.Printf("[Repository] ✗ User is deleted: %s", userID)
|
||||
return nil, ErrUserDeleted
|
||||
}
|
||||
|
||||
log.Printf("[Repository] ✓ User found: UsersID=%s", user.UsersID)
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
@@ -104,8 +104,8 @@ func TestGetUserByIDSuccess(t *testing.T) {
|
||||
mock, cleanup := setupMockDB(t)
|
||||
defer cleanup()
|
||||
|
||||
rows := sqlmock.NewRows([]string{"users_id", "email_address"}).
|
||||
AddRow("user123", "john@example.com")
|
||||
rows := sqlmock.NewRows([]string{"users_id", "email_address", "role_id", "is_deleted"}).
|
||||
AddRow("user123", "john@example.com", 7, "0")
|
||||
|
||||
mock.ExpectQuery("SELECT users_id, email_address").
|
||||
WithArgs("user123").
|
||||
@@ -125,6 +125,9 @@ func TestGetUserByIDSuccess(t *testing.T) {
|
||||
if user.EmailAddress != "john@example.com" {
|
||||
t.Errorf("Expected EmailAddress 'john@example.com', got '%s'", user.EmailAddress)
|
||||
}
|
||||
if user.RoleID != 7 {
|
||||
t.Errorf("Expected RoleID 7, got %d", user.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUserByIDNotFound(t *testing.T) {
|
||||
@@ -145,6 +148,27 @@ func TestGetUserByIDNotFound(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUserByIDDeletedUserFilteredOut(t *testing.T) {
|
||||
mock, cleanup := setupMockDB(t)
|
||||
defer cleanup()
|
||||
|
||||
rows := sqlmock.NewRows([]string{"users_id", "email_address", "role_id", "is_deleted"}).
|
||||
AddRow("deleted-user", "deleted@example.com", 3, "1")
|
||||
|
||||
mock.ExpectQuery("SELECT users_id, email_address").
|
||||
WithArgs("deleted-user").
|
||||
WillReturnRows(rows)
|
||||
|
||||
user, err := GetUserByID("deleted-user")
|
||||
|
||||
if !errors.Is(err, ErrUserDeleted) {
|
||||
t.Errorf("Expected ErrUserDeleted, got %v", err)
|
||||
}
|
||||
if user != nil {
|
||||
t.Error("Expected nil user for deleted user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllPermissionsSuccess(t *testing.T) {
|
||||
mock, cleanup := setupMockDB(t)
|
||||
defer cleanup()
|
||||
|
||||
Reference in New Issue
Block a user