Skip to content

Commit

Permalink
imp: Make sure users can always create tickets in their default organ…
Browse files Browse the repository at this point in the history
…ization
  • Loading branch information
marien-probesys committed Nov 20, 2024
1 parent 565e10c commit aa3d2e1
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 266 deletions.
19 changes: 12 additions & 7 deletions src/Controller/PagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,36 @@

namespace App\Controller;

use App\Entity\Ticket;
use App\Repository\AuthorizationRepository;
use App\Repository\OrganizationRepository;
use App\Entity;
use App\Repository;
use App\SearchEngine;
use App\Service;
use App\Service\Sorter\OrganizationSorter;
use App\Service\Sorter;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class PagesController extends BaseController
{
#[Route('/', name: 'home', methods: ['GET', 'HEAD'])]
public function home(
AuthorizationRepository $authorizationRepository,
OrganizationRepository $orgaRepository,
OrganizationSorter $orgaSorter,
Repository\AuthorizationRepository $authorizationRepository,
Repository\OrganizationRepository $orgaRepository,
Sorter\OrganizationSorter $orgaSorter,
SearchEngine\Ticket\Searcher $ticketSearcher,
Service\UserService $userService,
): Response {
$ticketsPagination = $ticketSearcher->getTickets(SearchEngine\Ticket\Searcher::queryOwned(), 'updated-desc', [
'page' => 1,
'maxResults' => 5,
]);

/** @var Entity\User */
$user = $this->getUser();
$defaultOrganization = $userService->getDefaultOrganization($user);

return $this->render('pages/home.html.twig', [
'ticketsPagination' => $ticketsPagination,
'defaultOrganization' => $defaultOrganization,
]);
}

Expand Down
70 changes: 4 additions & 66 deletions src/Controller/TicketsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function index(
Repository\OrganizationRepository $organizationRepository,
SearchEngine\Ticket\Searcher $ticketSearcher,
SearchEngine\Ticket\QuickSearchFilterBuilder $ticketQuickSearchFilterBuilder,
Service\UserService $userService,
): Response {
$page = $request->query->getInt('page', 1);
$view = $request->query->getString('view', 'all');
Expand Down Expand Up @@ -72,6 +73,8 @@ public function index(
$ticketsPagination = Utils\Pagination::empty();
}

$defaultOrganization = $userService->getDefaultOrganization($user);

return $this->render('tickets/index.html.twig', [
'ticketsPagination' => $ticketsPagination,
'countToAssign' => $ticketSearcher->countTickets(SearchEngine\Ticket\Searcher::queryUnassigned()),
Expand All @@ -82,72 +85,7 @@ public function index(
'searchMode' => $searchMode,
'quickSearchForm' => $quickSearchForm,
'advancedSearchForm' => $advancedSearchForm,
]);
}

#[Route('/tickets/new', name: 'new ticket', methods: ['GET', 'HEAD'])]
public function new(
Request $request,
Repository\AuthorizationRepository $authorizationRepository,
Repository\OrganizationRepository $organizationRepository,
Service\UserService $userService,
Service\Sorter\OrganizationSorter $organizationSorter,
Security\Authorizer $authorizer,
): Response {
$this->denyAccessUnlessGranted('orga:create:tickets', 'any');

/** @var \App\Entity\User */
$user = $this->getUser();

$selectedOrganizationUid = $request->query->get('organization');

// If the user has a default organization and can create tickets in it,
// just redirect to the "new ticket" form of this organization.
$defaultOrganization = $userService->getDefaultOrganization($user);

if ($defaultOrganization && $authorizer->isGranted('orga:create:tickets', $defaultOrganization)) {
return $this->redirectToRoute('new organization ticket', [
'uid' => $defaultOrganization->getUid(),
]);
}

// Otherwise, load the list of organizations they have access to (or
// only the selected organization, i.e. once the user has submitted the
// form).
if ($selectedOrganizationUid) {
$organization = $organizationRepository->findOneBy([
'uid' => $selectedOrganizationUid,
]);

if (!$organization) {
throw $this->createNotFoundException('The organization does not exist.');
}

$organizations = [$organization];
} else {
$organizations = $organizationRepository->findAuthorizedOrganizations($user);
}

// Keep only the organizations in which the user can create tickets
$organizations = array_filter($organizations, function ($organization) use ($authorizer): bool {
return $authorizer->isGranted('orga:create:tickets', $organization);
});
$organizations = array_values($organizations); // reset the keys of the array

if (count($organizations) === 1) {
// The user has the permission to create tickets in only one
// organization, so let's redirect to it.
return $this->redirectToRoute('new organization ticket', [
'uid' => $organizations[0]->getUid(),
]);
}

// Finally, let the user choose in which organization they want to
// create a ticket.
$organizationSorter->sort($organizations);

return $this->render('tickets/new.html.twig', [
'organizations' => $organizations,
'defaultOrganization' => $defaultOrganization,
]);
}

Expand Down
15 changes: 2 additions & 13 deletions src/MessageHandler/CreateTicketsFromMailboxEmailsHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ private function processMailboxEmail(MailboxEmail $mailboxEmail): void
$requesterOrganization = $this->userService->getDefaultOrganization($requester);

if (!$requesterOrganization) {
$this->markError($mailboxEmail, 'sender is not attached to an organization');
$this->markError($mailboxEmail, 'sender has not permission to create tickets');
$this->activeUser->change(null);
return;
}

Expand All @@ -141,18 +142,6 @@ private function processMailboxEmail(MailboxEmail $mailboxEmail): void
$isNewTicket = false;

if (!$ticket) {
$canCreateTicket = $this->authorizer->isGrantedToUser(
$requester,
'orga:create:tickets',
$requesterOrganization,
);

if (!$canCreateTicket) {
$this->markError($mailboxEmail, 'sender has not permission to create tickets');
$this->activeUser->change(null);
return;
}

$subject = $mailboxEmail->getSubject();

$ticket = new Ticket();
Expand Down
17 changes: 15 additions & 2 deletions src/Service/UserCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
class UserCreator
{
public function __construct(
private Repository\OrganizationRepository $organizationRepository,
private Repository\RoleRepository $roleRepository,
private Repository\UserRepository $userRepository,
private Security\Authorizer $authorizer,
private Service\Locales $locales,
private Service\UserService $userService,
private ValidatorInterface $validator,
private UserPasswordHasherInterface $passwordHasher,
) {
Expand All @@ -43,7 +43,7 @@ public function createUser(Entity\User $user, bool $flush = true): void

$defaultRole = $this->roleRepository->findDefault();
if ($defaultRole) {
$defaultOrganization = $this->userService->getDefaultOrganization($user);
$defaultOrganization = $this->getDefaultOrganization($user);

if ($defaultOrganization) {
$this->authorizer->grant(
Expand Down Expand Up @@ -80,4 +80,17 @@ public function create(

return $user;
}

public function getDefaultOrganization(Entity\User $user): ?Entity\Organization
{
$organization = $user->getOrganization();

if ($organization) {
return $organization;
}

$domain = Utils\Email::extractDomain($user->getEmail());

return $this->organizationRepository->findOneByDomainOrDefault($domain);
}
}
10 changes: 8 additions & 2 deletions src/Service/UserService.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ public function getDefaultOrganization(Entity\User $user): ?Entity\Organization
{
$organization = $user->getOrganization();

if ($organization) {
if (
$organization &&
$this->authorizer->isGrantedToUser($user, 'orga:create:tickets', $organization)
) {
return $organization;
}

$domain = Utils\Email::extractDomain($user->getEmail());
$domainOrganization = $this->organizationRepository->findOneByDomainOrDefault($domain);

if ($domainOrganization) {
if (
$domainOrganization &&
$this->authorizer->isGrantedToUser($user, 'orga:create:tickets', $domainOrganization)
) {
return $domainOrganization;
}

Expand Down
7 changes: 5 additions & 2 deletions templates/pages/home.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
<div class="cols cols--center flow">
<h2 class="col--extend">{{ 'home.your_tickets' | trans }}</h2>

{% if is_granted('orga:create:tickets', 'any') %}
<a class="button button--primary button--uppercase" href="{{ path('new ticket') }}">
{% if defaultOrganization %}
<a
class="button button--primary button--uppercase"
href="{{ path('new organization ticket', { uid: defaultOrganization.uid }) }}"
>
{{ icon('plus') }}
{{ 'home.new_ticket' | trans }}
</a>
Expand Down
7 changes: 5 additions & 2 deletions templates/tickets/index.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,11 @@
) }}
</div>

{% if is_granted('orga:create:tickets', 'any') %}
<a class="button button--primary button--uppercase" href="{{ path('new ticket') }}">
{% if defaultOrganization %}
<a
class="button button--primary button--uppercase"
href="{{ path('new organization ticket', { uid: defaultOrganization.uid }) }}"
>
{{ icon('plus') }}
{{ 'tickets.index.new_ticket' | trans }}
</a>
Expand Down
61 changes: 0 additions & 61 deletions templates/tickets/new.html.twig

This file was deleted.

Loading

0 comments on commit aa3d2e1

Please sign in to comment.