Squelette Symfony, entités Server et Action
This commit is contained in:
commit
52ecb4204c
46 changed files with 4308 additions and 0 deletions
0
src/Repository/.gitignore
vendored
Normal file
0
src/Repository/.gitignore
vendored
Normal file
66
src/Repository/ActionLogRepository.php
Normal file
66
src/Repository/ActionLogRepository.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\ActionLog;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @class ActionLogRepository
|
||||
* @brief Repository pour les logs d'actions SSH avec filtres
|
||||
*
|
||||
* @extends ServiceEntityRepository<ActionLog>
|
||||
*/
|
||||
class ActionLogRepository extends ServiceEntityRepository
|
||||
{
|
||||
/**
|
||||
* @brief Constructeur standard du repository Doctrine
|
||||
* @param ManagerRegistry $registry
|
||||
*/
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, ActionLog::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construit une requete filtrée pour l'historique des actions
|
||||
*
|
||||
* Tout les filtres sont optionels, si aucun filtre n'est fourni
|
||||
* on retourne tout les logs trié par date decroissante.
|
||||
* Les jointures sur user et server sont faites en LEFT JOIN pour
|
||||
* inclure les logs sans utilisateur (actions systeme).
|
||||
*
|
||||
* @param int|null $serverId Filtrer par serveur
|
||||
* @param int|null $userId Filtrer par utilisateur
|
||||
* @param string|null $dateFrom Date de debut (format Y-m-d)
|
||||
* @param string|null $dateTo Date de fin (format Y-m-d), inclus jusqu'a 23:59:59
|
||||
* @return QueryBuilder Le query builder pour la pagination
|
||||
*/
|
||||
public function findByFilters(?int $serverId, ?int $userId, ?string $dateFrom, ?string $dateTo): QueryBuilder
|
||||
{
|
||||
$qb = $this->createQueryBuilder('a')
|
||||
->leftJoin('a.user', 'u')
|
||||
->leftJoin('a.server', 's')
|
||||
->addSelect('u', 's')
|
||||
->orderBy('a.executedAt', 'DESC');
|
||||
|
||||
if ($serverId) {
|
||||
$qb->andWhere('s.id = :serverId')->setParameter('serverId', $serverId);
|
||||
}
|
||||
if ($userId) {
|
||||
$qb->andWhere('u.id = :userId')->setParameter('userId', $userId);
|
||||
}
|
||||
if ($dateFrom) {
|
||||
$qb->andWhere('a.executedAt >= :dateFrom')
|
||||
->setParameter('dateFrom', new \DateTimeImmutable($dateFrom));
|
||||
}
|
||||
if ($dateTo) {
|
||||
$qb->andWhere('a.executedAt <= :dateTo')
|
||||
->setParameter('dateTo', new \DateTimeImmutable($dateTo . ' 23:59:59'));
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
}
|
||||
28
src/Repository/ServerAccessRepository.php
Normal file
28
src/Repository/ServerAccessRepository.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\ServerAccess;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @class ServerAccessRepository
|
||||
* @brief Repository pour la gestion des acces operateurs aux serveurs
|
||||
*
|
||||
* Utilise principalement findOneBy(['server' => ..., 'user' => ...])
|
||||
* pour verifier si un acces existe deja avant d'en creer un nouveau.
|
||||
*
|
||||
* @extends ServiceEntityRepository<ServerAccess>
|
||||
*/
|
||||
class ServerAccessRepository extends ServiceEntityRepository
|
||||
{
|
||||
/**
|
||||
* @brief Constructeur standard du repository Doctrine
|
||||
* @param ManagerRegistry $registry
|
||||
*/
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, ServerAccess::class);
|
||||
}
|
||||
}
|
||||
73
src/Repository/ServerRepository.php
Normal file
73
src/Repository/ServerRepository.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file ServerRepository.php
|
||||
* @brief Repository Doctrine pour les requetes sur les serveurs
|
||||
*
|
||||
* @package App\Repository
|
||||
* @author Yasser
|
||||
*/
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Server;
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @class ServerRepository
|
||||
* @brief Repository pour l'entité Server avec methodes de recherche personnalisées
|
||||
*
|
||||
* @extends ServiceEntityRepository<Server>
|
||||
*/
|
||||
class ServerRepository extends ServiceEntityRepository
|
||||
{
|
||||
/**
|
||||
* @brief Constructeur standard du repository Doctrine
|
||||
* @param ManagerRegistry $registry
|
||||
*/
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Server::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construit une requete filtrée pour la liste des serveurs
|
||||
*
|
||||
* Filtre par nom/IP (recherche partielle), statut et utilisateur courant.
|
||||
* Pour les opérateurs (non admin), filtre avec un JOIN sur ServerAccess
|
||||
* pour n'afficher que les serveurs auxquels ils ont acces.
|
||||
*
|
||||
* @param string|null $search Terme de recherche sur le nom ou l'IP
|
||||
* @param string|null $status Filtre sur le statut ('online', 'offline', 'unknown')
|
||||
* @param User|null $currentUser L'utilisateur courant pour filtrer selon son role
|
||||
* @return QueryBuilder Le query builder pret a etre paginé
|
||||
*/
|
||||
public function findByFilters(?string $search, ?string $status, ?User $currentUser = null): QueryBuilder
|
||||
{
|
||||
$qb = $this->createQueryBuilder('s')
|
||||
->leftJoin('s.owner', 'o')
|
||||
->addSelect('o')
|
||||
->orderBy('s.createdAt', 'DESC');
|
||||
|
||||
if ($currentUser !== null && !$currentUser->isAdmin()) {
|
||||
$qb->innerJoin('s.serverAccesses', 'sa')
|
||||
->andWhere('sa.user = :currentUser')
|
||||
->setParameter('currentUser', $currentUser);
|
||||
}
|
||||
|
||||
if ($search) {
|
||||
$qb->andWhere('s.name LIKE :search OR s.ipAddress LIKE :search')
|
||||
->setParameter('search', '%' . $search . '%');
|
||||
}
|
||||
|
||||
if ($status && in_array($status, ['online', 'offline', 'unknown'])) {
|
||||
$qb->andWhere('s.lastStatus = :status')
|
||||
->setParameter('status', $status);
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
}
|
||||
28
src/Repository/ServiceRepository.php
Normal file
28
src/Repository/ServiceRepository.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Service;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @class ServiceRepository
|
||||
* @brief Repository pour l'entité Service (services systemd)
|
||||
*
|
||||
* Pas de methodes personnalisées pour l'instant, on utilise les methodes
|
||||
* de base de ServiceEntityRepository (findBy, findOneBy, etc).
|
||||
*
|
||||
* @extends ServiceEntityRepository<Service>
|
||||
*/
|
||||
class ServiceRepository extends ServiceEntityRepository
|
||||
{
|
||||
/**
|
||||
* @brief Constructeur standard du repository Doctrine
|
||||
* @param ManagerRegistry $registry
|
||||
*/
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Service::class);
|
||||
}
|
||||
}
|
||||
100
src/Repository/UserRepository.php
Normal file
100
src/Repository/UserRepository.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file UserRepository.php
|
||||
* @brief Repository Doctrine pour les requetes sur les utilisateurs
|
||||
*
|
||||
* @package App\Repository
|
||||
* @author Yasser
|
||||
*/
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||
|
||||
/**
|
||||
* @class UserRepository
|
||||
* @brief Repository pour l'entité User avec methodes de recherche personnalisées
|
||||
*
|
||||
* Implémente PasswordUpgraderInterface pour que Symfony puisse mettre a jour
|
||||
* automatiquement le hash du mot de passe si l'algorithme change.
|
||||
*
|
||||
* @extends ServiceEntityRepository<User>
|
||||
*/
|
||||
class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface
|
||||
{
|
||||
/**
|
||||
* @brief Constructeur standard du repository Doctrine
|
||||
* @param ManagerRegistry $registry
|
||||
*/
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Met a jour le hash du mot de passe d'un utilisateur
|
||||
*
|
||||
* Appelé automatiquement par Symfony si le hash du mot de passe
|
||||
* doit etre mis a jour (ex: changement d'algorithme). Requis par
|
||||
* l'interface PasswordUpgraderInterface.
|
||||
*
|
||||
* @param PasswordAuthenticatedUserInterface $user L'utilisateur dont on met a jour le mdp
|
||||
* @param string $newHashedPassword Le nouveau hash a stocker
|
||||
* @throws UnsupportedUserException Si l'utilisateur n'est pas une instance de User
|
||||
*/
|
||||
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class));
|
||||
}
|
||||
$user->setPassword($newHashedPassword);
|
||||
$this->getEntityManager()->persist($user);
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retourne tout les utilisateurs avec un compte actif
|
||||
*
|
||||
* @return array Tableau d'objets User trié par date d'inscription (plus recent en premier)
|
||||
*/
|
||||
public function findAllActiveUsers(): array
|
||||
{
|
||||
return $this->createQueryBuilder('u')
|
||||
->andWhere('u.isActive = true')
|
||||
->orderBy('u.createdAt', 'DESC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retourne les operateurs actifs en excluant ceux deja assignés a un serveur
|
||||
*
|
||||
* Utilisé dans la page de detail d'un serveur pour afficher la liste
|
||||
* des operateurs qui peuvent encore etre assignés (ceux pas encore dans
|
||||
* ServerAccess pour ce serveur). Les admins sont aussi exclus.
|
||||
*
|
||||
* @param array $excludeIds Tableau des ids d'utilisateurs a exclure
|
||||
* @return array Tableau d'objets User (operateurs uniquement, pas admins)
|
||||
*/
|
||||
public function findOperatorsExcluding(array $excludeIds): array
|
||||
{
|
||||
$qb = $this->createQueryBuilder('u')
|
||||
->andWhere('u.isActive = true')
|
||||
->orderBy('u.pseudo', 'ASC');
|
||||
|
||||
if (!empty($excludeIds)) {
|
||||
$qb->andWhere('u.id NOT IN (:ids)')->setParameter('ids', $excludeIds);
|
||||
}
|
||||
|
||||
return array_values(array_filter(
|
||||
$qb->getQuery()->getResult(),
|
||||
fn($u) => !$u->isAdmin()
|
||||
));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue