security fix and fix parent pages
API CI/CD / Validate (composer + pint) (push) Successful in 3m7s
API CI/CD / Test (PHPUnit) (push) Failing after 5m46s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 49s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped

This commit is contained in:
root
2026-07-06 02:14:16 -04:00
parent 39228168c8
commit 90f9857b06
43 changed files with 4323 additions and 132 deletions
@@ -43,7 +43,12 @@ class SchoolCalendarController extends BaseApiController
public function index(SchoolCalendarIndexRequest $request): JsonResponse
{
return $this->respondWithEvents($request->validated());
$filters = $request->validated();
if (! $this->canListEventsForAudience($filters['audience'] ?? null)) {
return $this->error('Forbidden.', Response::HTTP_FORBIDDEN);
}
return $this->respondWithEvents($filters);
}
/**
@@ -52,6 +57,10 @@ class SchoolCalendarController extends BaseApiController
*/
public function teacherCalendarLegacy(SchoolCalendarIndexRequest $request): JsonResponse
{
if (! $this->canListEventsForAudience('teacher')) {
return $this->error('Forbidden.', Response::HTTP_FORBIDDEN);
}
return $this->respondWithEvents([
...$request->validated(),
'audience' => 'teacher',
@@ -187,4 +196,56 @@ class SchoolCalendarController extends BaseApiController
return $userId;
}
private function canListEventsForAudience(?string $audience): bool
{
if ($this->hasAnyRole(['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'])) {
return true;
}
$audience = strtolower(trim((string) $audience));
if ($audience === 'parent') {
return $this->hasAnyRole(['parent']) || $this->hasUserType(['secondary', 'tertiary']);
}
if ($audience === 'teacher') {
return $this->hasAnyRole(['teacher']);
}
return false;
}
/**
* @param list<string> $roles
*/
private function hasAnyRole(array $roles): bool
{
$user = auth()->user();
if (! $user) {
return false;
}
$actual = $user->roles()
->pluck('roles.name')
->map(fn ($name) => strtolower((string) $name))
->toArray();
foreach ($roles as $role) {
if (in_array(strtolower($role), $actual, true)) {
return true;
}
}
return false;
}
/**
* @param list<string> $types
*/
private function hasUserType(array $types): bool
{
$type = strtolower(trim((string) (auth()->user()?->user_type ?? '')));
return in_array($type, array_map('strtolower', $types), true);
}
}