refactor: use permission system instead of direct session checks in admin pages

This commit is contained in:
2026-03-30 21:30:50 -07:00
parent 5748e416be
commit 6feada4fd8
2 changed files with 24 additions and 44 deletions
+8 -13
View File
@@ -2,7 +2,7 @@ import { prisma } from "@/lib/prisma"
import Navigation from "@/components/Navigation" import Navigation from "@/components/Navigation"
import Link from "next/link" import Link from "next/link"
import { notFound, redirect } from "next/navigation" import { notFound, redirect } from "next/navigation"
import { getSession } from "@/lib/auth-simple" import { canManageTournament, hasRole } from "@/lib/permissions"
import { getTournamentStatus } from "@/lib/tournamentUtils" import { getTournamentStatus } from "@/lib/tournamentUtils"
interface PageProps { interface PageProps {
@@ -12,21 +12,16 @@ interface PageProps {
} }
export default async function TournamentDetailPage({ params }: PageProps) { export default async function TournamentDetailPage({ params }: PageProps) {
const session = await getSession() const tournamentId = parseInt(params.id)
if (!session) { // Check if user can manage this tournament
const permission = await canManageTournament(tournamentId)
if (!permission.allowed) {
redirect("/auth/login") redirect("/auth/login")
} }
// Fetch user role from database // Check if user can create tournaments (tournament_admin or club_admin)
const user = await prisma.user.findUnique({ const canCreate = await hasRole('tournament_admin')
where: { id: session.user.id },
select: { role: true },
});
const isAdmin = user?.role === "club_admin"
const tournamentId = parseInt(params.id)
let tournament = await prisma.event.findUnique({ let tournament = await prisma.event.findUnique({
where: { id: tournamentId }, where: { id: tournamentId },
@@ -158,7 +153,7 @@ export default async function TournamentDetailPage({ params }: PageProps) {
)} )}
</div> </div>
<div className="flex space-x-2"> <div className="flex space-x-2">
{isAdmin && ( {permission.allowed && (
<> <>
<Link <Link
href={`/admin/tournaments/${tournament.id}/edit`} href={`/admin/tournaments/${tournament.id}/edit`}
+9 -24
View File
@@ -4,6 +4,7 @@ import Link from "next/link"
import { getSession } from "@/lib/auth-simple" import { getSession } from "@/lib/auth-simple"
import { redirect } from "next/navigation" import { redirect } from "next/navigation"
import { getTournamentStatus } from "@/lib/tournamentUtils" import { getTournamentStatus } from "@/lib/tournamentUtils"
import { hasRole, getManageableTournaments } from "@/lib/permissions"
export default async function AdminTournamentsPage() { export default async function AdminTournamentsPage() {
const session = await getSession() const session = await getSession()
@@ -12,26 +13,12 @@ export default async function AdminTournamentsPage() {
redirect("/auth/login") redirect("/auth/login")
} }
// Fetch user role from database // Check if user can create tournaments (tournament_admin or club_admin)
const user = await prisma.user.findUnique({ const canCreateResult = await hasRole('tournament_admin')
where: { id: session.user.id }, const canCreate = canCreateResult.allowed
select: { role: true },
});
const isAdmin = user?.role === "club_admin" // Get tournaments manageable by the current user
const tournaments = await getManageableTournaments()
const tournaments = await prisma.event.findMany({
orderBy: { createdAt: "desc" },
include: {
participants: true,
teams: {
include: {
player1: true,
player2: true,
},
},
},
})
// Update tournament statuses based on event date // Update tournament statuses based on event date
const updatedTournaments = await Promise.all( const updatedTournaments = await Promise.all(
@@ -59,9 +46,9 @@ export default async function AdminTournamentsPage() {
<div className="px-4 py-6 sm:px-0"> <div className="px-4 py-6 sm:px-0">
<div className="flex justify-between items-center mb-6"> <div className="flex justify-between items-center mb-6">
<h1 className="text-3xl font-bold text-gray-900"> <h1 className="text-3xl font-bold text-gray-900">
{isAdmin ? 'Tournament Management' : 'Tournaments'} {canCreate ? 'Tournament Management' : 'Tournaments'}
</h1> </h1>
{isAdmin && ( {canCreate && (
<Link <Link
href="/admin/tournaments/new" href="/admin/tournaments/new"
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700" className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700"
@@ -132,14 +119,12 @@ export default async function AdminTournamentsPage() {
> >
View View
</Link> </Link>
{isAdmin && (
<Link <Link
href={`/admin/tournaments/${tournament.id}/edit`} href={`/admin/tournaments/${tournament.id}/edit`}
className="text-blue-600 hover:text-blue-900" className="text-blue-600 hover:text-blue-900"
> >
Edit Edit
</Link> </Link>
)}
</td> </td>
</tr> </tr>
))} ))}
@@ -149,7 +134,7 @@ export default async function AdminTournamentsPage() {
{updatedTournaments.length === 0 && ( {updatedTournaments.length === 0 && (
<div className="text-center py-12"> <div className="text-center py-12">
<p className="text-gray-500">No tournaments found.</p> <p className="text-gray-500">No tournaments found.</p>
{isAdmin && ( {canCreate && (
<Link <Link
href="/admin/tournaments/new" href="/admin/tournaments/new"
className="text-green-600 hover:text-green-900 mt-2 inline-block" className="text-green-600 hover:text-green-900 mt-2 inline-block"