Skip to content

Commit

Permalink
fix: block pending users from seeing approved user only content (#1937)
Browse files Browse the repository at this point in the history
* fix: block pending users from seeing approved user only content

* fix: update logic for who can view published content

* fix: add more tests and update actingAs usages

* fix: fix a mistake

* fix: add new policy for viewing owned content and update projects view policy

* fix: update canViewOwnedContent rule to block individuals

* fix: update canViewOwnedContent rule for individuals

* fix: update based on PR feedback

* fix: remove view all projects from my-project when not approved

* fix: add some test cases for the changes
  • Loading branch information
chosww authored Oct 24, 2023
1 parent 5c9e4a0 commit 477e901
Show file tree
Hide file tree
Showing 12 changed files with 846 additions and 821 deletions.
7 changes: 7 additions & 0 deletions app/Policies/ProjectPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

use App\Models\Project;
use App\Models\User;
use App\Traits\UserCanViewOwnedContent;
use App\Traits\UserCanViewPublishedContent;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;

class ProjectPolicy
{
use HandlesAuthorization;
use UserCanViewOwnedContent;
use UserCanViewPublishedContent;

public function before(User $user, string $ability): ?Response
Expand All @@ -27,6 +29,11 @@ public function viewAny(User $user): bool
return $this->canViewPublishedContent($user);
}

public function viewOwned(User $user): bool
{
return $this->canViewOwnedContent($user);
}

public function view(User $user, Project $project): Response
{
// User can't view project by organization or regulated organization which they have blocked.
Expand Down
31 changes: 31 additions & 0 deletions app/Traits/UserCanViewOwnedContent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Traits;

use App\Enums\UserContext;
use App\Models\User;

trait UserCanViewOwnedContent
{
public function canViewOwnedContent(User $user): bool
{
if ($user->isAdministrator()) {
return true;
}

if ($user->context === 'individual' && ! $user->oriented_at) {
return false;
}

return
$user->hasVerifiedEmail() &&
in_array(
$user->context,
[
UserContext::Individual->value,
UserContext::Organization->value,
UserContext::RegulatedOrganization->value,
]
);
}
}
8 changes: 7 additions & 1 deletion app/Traits/UserCanViewPublishedContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ trait UserCanViewPublishedContent
{
public function canViewPublishedContent(User $user): bool
{
if ($user->isAdministrator()) {
return true;
}

$isOriented = $user->organization?->checkStatus('approved') || $user->regulatedOrganization?->checkStatus('approved') || $user->oriented_at != null;

return
$user->hasVerifiedEmail() &&
$isOriented &&
in_array(
$user->context,
[
UserContext::Administrator->value,
UserContext::Individual->value,
UserContext::Organization->value,
UserContext::RegulatedOrganization->value,
Expand Down
2 changes: 1 addition & 1 deletion resources/css/_tokens.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* VARIABLES GENERATED WITH TAILWIND CONFIG ON 10/16/2023.
/* VARIABLES GENERATED WITH TAILWIND CONFIG ON 10/17/2023.
Tokens location: ./tailwind.config.js */
:root {
--space-0: 0;
Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/navigation.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{{ __('Dashboard') }}
</x-nav-link>
</li>
@if (Auth::user()->hasVerifiedEmail() && Auth::user()->can('viewAny', 'App\Models\Project'))
@if (Auth::user()->hasVerifiedEmail() && Auth::user()->can('viewOwned', 'App\Models\Project'))
<li>
<x-nav-link :href="Auth::user()->isAdministrator()
? localized_route('projects.all-projects')
Expand Down
77 changes: 42 additions & 35 deletions resources/views/projects/my-projects.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,26 @@
<h1 id="projects" itemprop="name">
{{ __('Projects') }}
</h1>
<a class="cta secondary"
href="{{ localized_route('projects.all-projects') }}">{{ __('Browse all projects') }}</a>
@if (Auth::user()->can('viewAny', 'App\Models\Project'))
<a class="cta secondary"
href="{{ localized_route('projects.all-projects') }}">{{ __('Browse all projects') }}</a>
@endif
</div>
</div>
</x-slot>
@if (($user->context === \App\Enums\UserContext::Organization->value &&
($user->organization->isConsultant() ||
$user->organization->isConnector() ||
$user->organization->isParticipant())) ||
($user->context === \App\Enums\UserContext::Individual->value &&
($user->individual->isConsultant() || $user->individual->isConnector()) &&
($user->individual->isParticipant() || $user->individual->inProgressParticipatingProjects()->count())))
@if ($user->context === \App\Enums\UserContext::Organization->value ||
($user->context === \App\Enums\UserContext::Individual->value && count($user->individual?->roles ?? []) > 1) ||
($user->individual?->inProgressContractedProjects()->count() &&
$user->individual?->inProgressParticipatingProjects()->count()))
@if (
($user->context === \App\Enums\UserContext::Organization->value &&
($user->organization->isConsultant() ||
$user->organization->isConnector() ||
$user->organization->isParticipant())) ||
($user->context === \App\Enums\UserContext::Individual->value &&
($user->individual->isConsultant() || $user->individual->isConnector()) &&
($user->individual->isParticipant() || $user->individual->inProgressParticipatingProjects()->count())))
@if (
$user->context === \App\Enums\UserContext::Organization->value ||
($user->context === \App\Enums\UserContext::Individual->value && count($user->individual?->roles ?? []) > 1) ||
($user->individual?->inProgressContractedProjects()->count() &&
$user->individual?->inProgressParticipatingProjects()->count()))
<nav class="nav--tabbed" aria-labelledby="projects">
<div class="center center:wide">
<ul class="-mt-4 flex gap-6" role="list">
Expand All @@ -36,15 +40,15 @@
</li>
@endif
--}}
@if ($user->organization->isConnector())
@if ($user->organization->isConnector() && Auth::user()->can('viewAny', 'App\Models\Project'))
<li class="w-full">
<x-nav-link class="inline-flex w-full items-center justify-center border-t-0"
:href="localized_route('projects.my-contracted-projects')" :active="$section === App\Enums\ProjectInvolvement::Contracted->value">
{{ __('Involved in as a Community Connector') }}
</x-nav-link>
</li>
@endif
@if ($user->organization->isParticipant())
@if ($user->organization->isParticipant() && Auth::user()->can('viewAny', 'App\Models\Project'))
<li class="w-full">
<x-nav-link class="inline-flex w-full items-center justify-center border-t-0"
:href="localized_route('projects.my-participating-projects')" :active="$section === App\Enums\ProjectInvolvement::Participating->value">
Expand All @@ -59,7 +63,7 @@
</x-nav-link>
</li>
@endif
@if ($user->context === \App\Enums\UserContext::Individual->value)
@if ($user->context === \App\Enums\UserContext::Individual->value && Auth::user()->can('viewAny', 'App\Models\Project'))
<li class="w-full">
<x-nav-link class="inline-flex w-full items-center justify-center border-t-0"
:href="localized_route('projects.my-participating-projects')" :active="$section === App\Enums\ProjectInvolvement::Participating->value">
Expand All @@ -79,26 +83,29 @@
@endif
@endif

@switch($user->context)
@case('organization')
@include(isset($section) ? 'projects.my-projects.' . $section : 'projects.my-projects.running')
@break
@if (Auth::user()->can('viewAny', 'App\Models\Project'))
@switch($user->context)
@case('organization')
@include(isset($section) ? 'projects.my-projects.' . $section : 'projects.my-projects.running')
@break

@case('regulated-organization')
@includeWhen($projectable, 'projects.my-projects.running')
@break
@case('regulated-organization')
@includeWhen($projectable, 'projects.my-projects.running')
@break

@default
@include(isset($section) ? 'projects.my-projects.' . $section : 'projects.my-projects.participating')
@endswitch

<div class="full accent--color -mb-8 mt-12 py-12">
<div class="center center:wide stack text-center">
<h2>{{ __('Browse all projects') }}</h2>
<p>{{ __('This includes projects by Regulated Organizations and Community Organizations.') }}</p>
<p class="mt-8"><a class="cta"
href="{{ localized_route('projects.all-projects') }}">{{ __('Browse all projects') }}</a>
</p>
@default
@include(isset($section) ? 'projects.my-projects.' . $section : 'projects.my-projects.participating')
@endswitch
<div class="full accent--color -mb-8 mt-12 py-12">
<div class="center center:wide stack text-center">
<h2>{{ __('Browse all projects') }}</h2>
<p>{{ __('This includes projects by Regulated Organizations and Community Organizations.') }}</p>
<p class="mt-8"><a class="cta"
href="{{ localized_route('projects.all-projects') }}">{{ __('Browse all projects') }}</a>
</p>
</div>
</div>
</div>
@else
@includeWhen($projectable, 'projects.my-projects.running')
@endif
</x-app-layout>
28 changes: 16 additions & 12 deletions resources/views/projects/my-projects/running.blade.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
<div class="flex flex-wrap items-center justify-between gap-4">
<h2>{{ __('Projects I am running') }}</h2>
@if (!$projectable->draftProjects->isEmpty() ||
!$projectable->inProgressProjects->isEmpty() ||
!$projectable->upcomingProjects->isEmpty() ||
!$projectable->completedProjects->isEmpty())
@if (
$projectable &&
(!$projectable->draftProjects->isEmpty() ||
!$projectable->inProgressProjects->isEmpty() ||
!$projectable->upcomingProjects->isEmpty() ||
!$projectable->completedProjects->isEmpty()))
<a class="cta"
href="{{ $user->projectable->projects->count() > 0 ? localized_route('projects.show-context-selection') : localized_route('projects.show-language-selection') }}">{{ __('Create new project') }}</a>
@endif
</div>

@if ($projectable->draftProjects->isEmpty() &&
$projectable->inProgressProjects->isEmpty() &&
$projectable->upcomingProjects->isEmpty() &&
$projectable->completedProjects->isEmpty())
@if (
$projectable &&
$projectable->draftProjects->isEmpty() &&
$projectable->inProgressProjects->isEmpty() &&
$projectable->upcomingProjects->isEmpty() &&
$projectable->completedProjects->isEmpty())
<div class="box stack">
<p>{{ __('It seems as though you have not created any projects yet.') }}</p>

Expand All @@ -24,28 +28,28 @@
</div>
@endif

@if (!$projectable->draftProjects->isEmpty())
@if ($projectable && !$projectable->draftProjects->isEmpty())
<h3>{{ __('Draft') }}</h3>
@foreach ($projectable->draftProjects as $project)
@include('projects.partials.project-and-engagements')
@endforeach
@endif

@if (!$projectable->inProgressProjects->isEmpty())
@if ($projectable && !$projectable->inProgressProjects->isEmpty())
<h3>{{ __('In progress') }}</h3>
@foreach ($projectable->inProgressProjects as $project)
@include('projects.partials.project-and-engagements')
@endforeach
@endif

@if (!$projectable->upcomingProjects->isEmpty())
@if ($projectable && !$projectable->upcomingProjects->isEmpty())
<h3>{{ __('In progress') }}</h3>
@foreach ($projectable->upcomingProjects as $project)
@include('projects.partials.project-and-engagements')
@endforeach
@endif

@if (!$projectable->completedProjects->isEmpty())
@if ($projectable && !$projectable->completedProjects->isEmpty())
<x-expander level="3" :summary="__('Completed')">
@forelse ($projectable->completedProjects as $project)
@include('projects.partials.project-and-engagements')
Expand Down
4 changes: 2 additions & 2 deletions routes/projects.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use App\Livewire\AllProjects;

Route::multilingual('/projects', [UserProjectsController::class, 'show'])
->middleware(['auth', 'verified', 'can:viewAny,App\Models\Project'])
->middleware(['auth', 'verified', 'can:viewOwned,App\Models\Project'])
->name('projects.my-projects');

Route::multilingual('/projects/contracted', [UserProjectsController::class, 'showContracted'])
Expand All @@ -17,7 +17,7 @@
->name('projects.my-participating-projects');

Route::multilingual('/projects/running', [UserProjectsController::class, 'showRunning'])
->middleware(['auth', 'verified', 'can:viewAny,App\Models\Project'])
->middleware(['auth', 'verified', 'can:viewOwned,App\Models\Project'])
->name('projects.my-running-projects');

Route::controller(ProjectController::class)
Expand Down
Loading

0 comments on commit 477e901

Please sign in to comment.