342 lines
9.5 KiB
Go
342 lines
9.5 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"veza-backend-api/internal/models"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// setupTestPermissionServiceDB crée une base de données de test pour PermissionService
|
|
func setupTestPermissionServiceDB(t *testing.T) *gorm.DB {
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
|
|
// Enable foreign keys for SQLite
|
|
db.Exec("PRAGMA foreign_keys = ON")
|
|
|
|
// Create tables manually to ensure all columns exist (AutoMigrate might miss some in SQLite)
|
|
db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS roles (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL UNIQUE,
|
|
display_name TEXT NOT NULL,
|
|
description TEXT,
|
|
is_system INTEGER DEFAULT 0,
|
|
is_active INTEGER DEFAULT 1,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`)
|
|
|
|
db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS permissions (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL UNIQUE,
|
|
resource TEXT,
|
|
action TEXT,
|
|
description TEXT,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`)
|
|
|
|
db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS user_roles (
|
|
id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
role_id TEXT NOT NULL,
|
|
role TEXT NOT NULL,
|
|
assigned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
assigned_by TEXT,
|
|
expires_at DATETIME,
|
|
is_active INTEGER DEFAULT 1,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(user_id, role)
|
|
)
|
|
`)
|
|
|
|
db.Exec(`
|
|
CREATE TABLE IF NOT EXISTS role_permissions (
|
|
id TEXT PRIMARY KEY,
|
|
role_id TEXT NOT NULL,
|
|
permission_id TEXT NOT NULL,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(role_id, permission_id)
|
|
)
|
|
`)
|
|
|
|
return db
|
|
}
|
|
|
|
// TestPermissionService_HasRole teste HasRole
|
|
// GO-007, GO-025: Test critique pour RBAC
|
|
func TestPermissionService_HasRole(t *testing.T) {
|
|
db := setupTestPermissionServiceDB(t)
|
|
service := NewPermissionService(db)
|
|
ctx := context.Background()
|
|
|
|
// Créer un rôle admin
|
|
adminRole := &models.Role{
|
|
ID: uuid.New(),
|
|
Name: "admin",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(adminRole).Error)
|
|
|
|
// Créer un rôle user
|
|
userRole := &models.Role{
|
|
ID: uuid.New(),
|
|
Name: "user",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(userRole).Error)
|
|
|
|
// Créer un utilisateur
|
|
userID := uuid.New()
|
|
|
|
// Test 1: Utilisateur sans rôle
|
|
hasRole, err := service.HasRole(ctx, userID, "admin")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasRole, "User without role should not have admin role")
|
|
|
|
// Test 2: Utilisateur avec rôle admin
|
|
userRoleRecord := &models.UserRole{
|
|
ID: uuid.New(),
|
|
UserID: userID,
|
|
RoleID: adminRole.ID,
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(userRoleRecord).Error)
|
|
|
|
hasRole, err = service.HasRole(ctx, userID, "admin")
|
|
require.NoError(t, err)
|
|
assert.True(t, hasRole, "User with admin role should have admin role")
|
|
|
|
// Test 3: Utilisateur avec rôle user (pas admin)
|
|
hasRole, err = service.HasRole(ctx, userID, "user")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasRole, "User with admin role should not have user role")
|
|
|
|
// Test 4: Rôle inactif
|
|
userRoleRecord.IsActive = false
|
|
require.NoError(t, db.Save(userRoleRecord).Error)
|
|
|
|
hasRole, err = service.HasRole(ctx, userID, "admin")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasRole, "User with inactive role should not have role")
|
|
|
|
// Test 5: Rôle expiré
|
|
userRoleRecord.IsActive = true
|
|
expiredTime := time.Now().Add(-1 * time.Hour)
|
|
userRoleRecord.ExpiresAt = &expiredTime
|
|
require.NoError(t, db.Save(userRoleRecord).Error)
|
|
|
|
hasRole, err = service.HasRole(ctx, userID, "admin")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasRole, "User with expired role should not have role")
|
|
}
|
|
|
|
// TestPermissionService_HasPermission teste HasPermission
|
|
// GO-007, GO-025: Test critique pour RBAC
|
|
func TestPermissionService_HasPermission(t *testing.T) {
|
|
db := setupTestPermissionServiceDB(t)
|
|
service := NewPermissionService(db)
|
|
ctx := context.Background()
|
|
|
|
// Créer un rôle
|
|
role := &models.Role{
|
|
ID: uuid.New(),
|
|
Name: "admin",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(role).Error)
|
|
|
|
// Créer une permission
|
|
permission := &models.Permission{
|
|
ID: uuid.New(),
|
|
Name: "manage_users",
|
|
Resource: "users",
|
|
Action: "manage",
|
|
}
|
|
require.NoError(t, db.Create(permission).Error)
|
|
|
|
// Créer un utilisateur
|
|
userID := uuid.New()
|
|
|
|
// Test 1: Utilisateur sans permission
|
|
hasPermission, err := service.HasPermission(ctx, userID, "manage_users")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasPermission, "User without permission should not have permission")
|
|
|
|
// Test 2: Assigner rôle à l'utilisateur
|
|
userRole := &models.UserRole{
|
|
ID: uuid.New(),
|
|
UserID: userID,
|
|
RoleID: role.ID,
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(userRole).Error)
|
|
|
|
// Test 3: Permission non assignée au rôle
|
|
hasPermission, err = service.HasPermission(ctx, userID, "manage_users")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasPermission, "User with role but without permission should not have permission")
|
|
|
|
// Test 4: Assigner permission au rôle
|
|
rolePermission := &models.RolePermission{
|
|
RoleID: role.ID,
|
|
PermissionID: permission.ID,
|
|
}
|
|
require.NoError(t, db.Create(rolePermission).Error)
|
|
|
|
hasPermission, err = service.HasPermission(ctx, userID, "manage_users")
|
|
require.NoError(t, err)
|
|
assert.True(t, hasPermission, "User with role and permission should have permission")
|
|
|
|
// Test 5: Permission inexistante
|
|
hasPermission, err = service.HasPermission(ctx, userID, "nonexistent_permission")
|
|
require.NoError(t, err)
|
|
assert.False(t, hasPermission, "User should not have nonexistent permission")
|
|
}
|
|
|
|
// TestPermissionService_GetRolePermissions teste GetRolePermissions
|
|
func TestPermissionService_GetRolePermissions(t *testing.T) {
|
|
db := setupTestPermissionServiceDB(t)
|
|
service := NewPermissionService(db)
|
|
ctx := context.Background()
|
|
|
|
// Créer un rôle
|
|
role := &models.Role{
|
|
ID: uuid.New(),
|
|
Name: "admin",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(role).Error)
|
|
|
|
// Créer des permissions
|
|
perm1 := &models.Permission{
|
|
ID: uuid.New(),
|
|
Name: "manage_users",
|
|
Resource: "users",
|
|
Action: "manage",
|
|
}
|
|
require.NoError(t, db.Create(perm1).Error)
|
|
|
|
perm2 := &models.Permission{
|
|
ID: uuid.New(),
|
|
Name: "manage_tracks",
|
|
Resource: "tracks",
|
|
Action: "manage",
|
|
}
|
|
require.NoError(t, db.Create(perm2).Error)
|
|
|
|
// Test 1: Rôle sans permissions
|
|
permissions, err := service.GetRolePermissions(ctx, role.ID)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, permissions, "Role without permissions should return empty list")
|
|
|
|
// Test 2: Assigner permissions au rôle
|
|
rolePerm1 := &models.RolePermission{
|
|
RoleID: role.ID,
|
|
PermissionID: perm1.ID,
|
|
}
|
|
require.NoError(t, db.Create(rolePerm1).Error)
|
|
|
|
rolePerm2 := &models.RolePermission{
|
|
RoleID: role.ID,
|
|
PermissionID: perm2.ID,
|
|
}
|
|
require.NoError(t, db.Create(rolePerm2).Error)
|
|
|
|
permissions, err = service.GetRolePermissions(ctx, role.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, permissions, 2, "Role should have 2 permissions")
|
|
}
|
|
|
|
// TestPermissionService_AssignPermissionToRole teste AssignPermissionToRole
|
|
func TestPermissionService_AssignPermissionToRole(t *testing.T) {
|
|
db := setupTestPermissionServiceDB(t)
|
|
service := NewPermissionService(db)
|
|
ctx := context.Background()
|
|
|
|
// Créer un rôle et une permission
|
|
role := &models.Role{
|
|
ID: uuid.New(),
|
|
Name: "admin",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(role).Error)
|
|
|
|
permission := &models.Permission{
|
|
ID: uuid.New(),
|
|
Name: "manage_users",
|
|
Resource: "users",
|
|
Action: "manage",
|
|
}
|
|
require.NoError(t, db.Create(permission).Error)
|
|
|
|
// Assigner permission au rôle
|
|
err := service.AssignPermissionToRole(ctx, role.ID, permission.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Vérifier que l'assignation existe
|
|
var rolePermission models.RolePermission
|
|
err = db.Where("role_id = ? AND permission_id = ?", role.ID, permission.ID).First(&rolePermission).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, role.ID, rolePermission.RoleID)
|
|
assert.Equal(t, permission.ID, rolePermission.PermissionID)
|
|
}
|
|
|
|
// TestPermissionService_RevokePermissionFromRole teste RevokePermissionFromRole
|
|
func TestPermissionService_RevokePermissionFromRole(t *testing.T) {
|
|
db := setupTestPermissionServiceDB(t)
|
|
service := NewPermissionService(db)
|
|
ctx := context.Background()
|
|
|
|
// Créer un rôle et une permission
|
|
role := &models.Role{
|
|
ID: uuid.New(),
|
|
Name: "admin",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(role).Error)
|
|
|
|
permission := &models.Permission{
|
|
ID: uuid.New(),
|
|
Name: "manage_users",
|
|
Resource: "users",
|
|
Action: "manage",
|
|
}
|
|
require.NoError(t, db.Create(permission).Error)
|
|
|
|
// Assigner permission au rôle
|
|
rolePermission := &models.RolePermission{
|
|
RoleID: role.ID,
|
|
PermissionID: permission.ID,
|
|
}
|
|
require.NoError(t, db.Create(rolePermission).Error)
|
|
|
|
// Révoquer permission
|
|
err := service.RevokePermissionFromRole(ctx, role.ID, permission.ID)
|
|
require.NoError(t, err)
|
|
|
|
// Vérifier que l'assignation n'existe plus
|
|
var count int64
|
|
db.Model(&models.RolePermission{}).
|
|
Where("role_id = ? AND permission_id = ?", role.ID, permission.ID).
|
|
Count(&count)
|
|
assert.Equal(t, int64(0), count, "Permission should be revoked")
|
|
|
|
// Test: Révoquer une permission inexistante
|
|
err = service.RevokePermissionFromRole(ctx, role.ID, permission.ID)
|
|
assert.Error(t, err, "Revoking nonexistent permission should return error")
|
|
assert.Contains(t, err.Error(), "not found")
|
|
}
|