Skip to content

Commit

Permalink
Merge pull request #369 from code4romania/fix-permissions-and-institu…
Browse files Browse the repository at this point in the history
…tion-status

Fix user permissions and restrict access to inactivated institution
  • Loading branch information
gheorghelupu17 authored Dec 5, 2024
2 parents 5c00df6 + 697e4a8 commit d053165
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 34 deletions.
3 changes: 2 additions & 1 deletion app/Concerns/HasPermissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Enums\AdminPermission;
use App\Enums\CasePermission;
use App\Models\Beneficiary;
use Filament\Facades\Filament;

trait HasPermissions
{
Expand All @@ -17,7 +18,7 @@ public function isAdmin(): bool

public function isNgoAdmin(): bool
{
return $this->ngo_admin;
return $this->ngo_admin && $this->institution_id === Filament::getTenant()->institution_id;
}

public function hasAccessToAllCases(): bool
Expand Down
73 changes: 40 additions & 33 deletions app/Http/Middleware/EnsureUserIsActive.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@

namespace App\Http\Middleware;

use App\Enums\InstitutionStatus;
use App\Enums\UserStatus as UserStatusEnum;
use App\Filament\Organizations\Pages\Dashboard;
use App\Models\Scopes\BelongsToCurrentTenant;
use App\Models\User;
use App\Models\UserStatus;
use Closure;
use Filament\Facades\Filament;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

Expand All @@ -21,6 +25,27 @@ public function handle(Request $request, Closure $next): Response
return $next($request);
}

if (Filament::getCurrentPanel()->getId() === 'organization') {
$activeOrganization = UserStatus::query()
->withoutGlobalScopes([BelongsToCurrentTenant::class])
->where('user_id', auth()->id())
->whereIn('status', [UserStatusEnum::PENDING->value, UserStatusEnum::ACTIVE->value])
->whereHas(
'institution',
fn (Builder $query) => $query->whereIn('status', [
InstitutionStatus::ACTIVE->value,
InstitutionStatus::PENDING->value,
])
)
->first();

if ($activeOrganization) {
auth()->user()->update(['latest_organization_id' => $activeOrganization->organization_id]);

return redirect()->to(Dashboard::getUrl(['tenant' => $activeOrganization->organization]));
}
}

Filament::auth()->logout();

$request->session()->invalidate();
Expand All @@ -30,47 +55,29 @@ public function handle(Request $request, Closure $next): Response
->with('error', __('user.inactive_error'));
}

public function userAndInstitutionIsActive(): bool
public function userAndInstitutionIsActive(): bool|RedirectResponse
{
$userActiveOrganizations = UserStatus::query()
$query = UserStatus::query()
->where('user_id', auth()->id())
->withoutGlobalScopes([BelongsToCurrentTenant::class])
->with('organization.institution')
->whereIn('status', [UserStatusEnum::PENDING->value, UserStatusEnum::ACTIVE->value])
->get()
->filter(fn (UserStatus $userStatus) => ! $userStatus->organization?->institution->isInactivated());

if ($userActiveOrganizations->isEmpty()) {
return false;
}
->whereIn('status', [UserStatusEnum::PENDING->value, UserStatusEnum::ACTIVE->value]);

/** @var User $user */
$user = auth()->user();

if ($user->isAdmin() && Filament::getCurrentPanel()->getId() === 'admin')
{
return UserStatus::query()
->where('user_id', auth()->id())
->whereNull('organization_id')
->withoutGlobalScopes([BelongsToCurrentTenant::class])
->whereIn('status', [UserStatusEnum::PENDING->value, UserStatusEnum::ACTIVE->value])
->exists();
}

if ($userActiveOrganizations->pluck('organization_id')->contains($user->latest_organization_id)) {
return true;
}

$user->latest_organization_id = $userActiveOrganizations
->first()
?->organization_id;

$user->save();

if ($user->latest_organization_id) {
return $this->userAndInstitutionIsActive();
if ($user->isAdmin() && Filament::getCurrentPanel()->getId() === 'admin') {
$query->whereNull('organization_id');
} else {
$query->where('organization_id', $user->latest_organization_id)
->whereHas(
'institution',
fn (Builder $query) => $query->whereIn('status', [
InstitutionStatus::ACTIVE->value,
InstitutionStatus::PENDING->value,
])
);
}

return false;
return $query->exists();
}
}
5 changes: 5 additions & 0 deletions app/Http/Middleware/UpdateDefaultTenant.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace App\Http\Middleware;

use App\Enums\UserStatus;
use App\Filament\Organizations\Pages\Dashboard;
use Closure;
use Filament\Facades\Filament;
use Illuminate\Http\Request;
Expand All @@ -27,6 +28,10 @@ public function handle(Request $request, Closure $next): Response
'latest_organization_id' => $tenant->id,
]);

if ($tenant->institution->isInactivated()) {
return redirect()->to(Dashboard::getUrl());
}

if (! $user->userStatus) {
$user->initializeStatus();
$user->load('userStatus');
Expand Down
8 changes: 8 additions & 0 deletions app/Models/UserStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
use App\Concerns\HasUserStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Znck\Eloquent\Relations\BelongsToThrough;
use Znck\Eloquent\Traits\BelongsToThrough as BelongsToThroughTrait;

class UserStatus extends Model
{
use HasFactory;
use HasUserStatus;
use BelongsToOrganization;
use BelongsToThroughTrait;

protected $fillable = [
'user_id',
Expand All @@ -23,4 +26,9 @@ class UserStatus extends Model
protected $casts = [
'status' => \App\Enums\UserStatus::class,
];

public function institution(): BelongsToThrough
{
return $this->belongsToThrough(Institution::class, Organization::class);
}
}

0 comments on commit d053165

Please sign in to comment.