mirror of
https://github.com/evroon/bracket.git
synced 2026-01-18 02:58:49 -05:00
Dashboard auth fixes (#90)
This commit is contained in:
@@ -25,6 +25,10 @@ class ClubsResponse(DataResponse[list[Club]]):
|
||||
pass
|
||||
|
||||
|
||||
class TournamentResponse(DataResponse[Tournament]):
|
||||
pass
|
||||
|
||||
|
||||
class TournamentsResponse(DataResponse[list[Tournament]]):
|
||||
pass
|
||||
|
||||
|
||||
@@ -10,20 +10,46 @@ from bracket.models.db.tournament import (
|
||||
TournamentUpdateBody,
|
||||
)
|
||||
from bracket.models.db.user import UserPublic
|
||||
from bracket.routes.auth import user_authenticated, user_authenticated_for_tournament
|
||||
from bracket.routes.models import SuccessResponse, TournamentsResponse
|
||||
from bracket.routes.auth import (
|
||||
user_authenticated,
|
||||
user_authenticated_for_tournament,
|
||||
user_authenticated_or_public_dashboard,
|
||||
)
|
||||
from bracket.routes.models import SuccessResponse, TournamentResponse, TournamentsResponse
|
||||
from bracket.schema import tournaments
|
||||
from bracket.utils.db import fetch_all_parsed
|
||||
from bracket.utils.sql import get_user_access_to_club
|
||||
from bracket.utils.db import fetch_all_parsed, fetch_one_parsed, fetch_one_parsed_certain
|
||||
from bracket.utils.sql import get_user_access_to_club, get_which_clubs_has_user_access_to
|
||||
from bracket.utils.types import assert_some
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/tournaments/{tournament_id}", response_model=TournamentResponse)
|
||||
async def get_tournament(
|
||||
tournament_id: int, user: UserPublic | None = Depends(user_authenticated_or_public_dashboard)
|
||||
) -> TournamentResponse:
|
||||
tournament = await fetch_one_parsed_certain(
|
||||
database, Tournament, tournaments.select().where(tournaments.c.id == tournament_id)
|
||||
)
|
||||
if user is None and not tournament.dashboard_public:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="You don't have access to this tournament",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
return TournamentResponse(data=tournament)
|
||||
|
||||
|
||||
@router.get("/tournaments", response_model=TournamentsResponse)
|
||||
async def get_tournaments(_: UserPublic = Depends(user_authenticated)) -> TournamentsResponse:
|
||||
async def get_tournaments(user: UserPublic = Depends(user_authenticated)) -> TournamentsResponse:
|
||||
user_clubs = await get_which_clubs_has_user_access_to(assert_some(user.id))
|
||||
return TournamentsResponse(
|
||||
data=await fetch_all_parsed(database, Tournament, tournaments.select())
|
||||
data=await fetch_all_parsed(
|
||||
database,
|
||||
Tournament,
|
||||
tournaments.select().where(tournaments.c.club_id.in_(tuple(user_clubs))),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -87,11 +87,15 @@ async def get_user_access_to_tournament(tournament_id: int, user_id: int) -> boo
|
||||
return tournament_id in {tournament.id for tournament in result} # type: ignore[attr-defined]
|
||||
|
||||
|
||||
async def get_user_access_to_club(club_id: int, user_id: int) -> bool:
|
||||
async def get_which_clubs_has_user_access_to(user_id: int) -> set[int]:
|
||||
query = f'''
|
||||
SELECT club_id
|
||||
FROM users_x_clubs
|
||||
WHERE user_id = :user_id
|
||||
'''
|
||||
result = await database.fetch_all(query=query, values={'user_id': user_id})
|
||||
return club_id in {club.club_id for club in result} # type: ignore[attr-defined]
|
||||
return {club.club_id for club in result} # type: ignore[attr-defined]
|
||||
|
||||
|
||||
async def get_user_access_to_club(club_id: int, user_id: int) -> bool:
|
||||
return club_id in await get_which_clubs_has_user_access_to(user_id)
|
||||
|
||||
@@ -6,7 +6,7 @@ import NotFoundTitle from '../../404';
|
||||
import Brackets from '../../../components/brackets/brackets';
|
||||
import { getTournamentIdFromRouter } from '../../../components/utils/util';
|
||||
import { Tournament } from '../../../interfaces/tournament';
|
||||
import { getBaseApiUrl, getRounds, getTournaments } from '../../../services/adapter';
|
||||
import { getBaseApiUrl, getRounds, getTournament } from '../../../services/adapter';
|
||||
|
||||
function TournamentLogo({ tournamentDataFull }: { tournamentDataFull: Tournament }) {
|
||||
return tournamentDataFull.logo_path ? (
|
||||
@@ -17,13 +17,10 @@ function TournamentLogo({ tournamentDataFull }: { tournamentDataFull: Tournament
|
||||
export default function Dashboard() {
|
||||
const { tournamentData } = getTournamentIdFromRouter();
|
||||
const swrRoundsResponse: SWRResponse = getRounds(tournamentData.id, true);
|
||||
const swrTournamentsResponse = getTournaments();
|
||||
const swrTournamentsResponse = getTournament(tournamentData.id);
|
||||
|
||||
const tournaments: Tournament[] =
|
||||
swrTournamentsResponse.data != null ? swrTournamentsResponse.data.data : [];
|
||||
const tournamentDataFull = tournaments.filter(
|
||||
(tournament) => tournament.id === tournamentData.id
|
||||
)[0];
|
||||
const tournamentDataFull: Tournament =
|
||||
swrTournamentsResponse.data != null ? swrTournamentsResponse.data.data : null;
|
||||
|
||||
if (tournamentDataFull == null) {
|
||||
return <NotFoundTitle />;
|
||||
|
||||
@@ -52,6 +52,10 @@ export function getClubs(): SWRResponse {
|
||||
return useSWR('clubs', fetcher);
|
||||
}
|
||||
|
||||
export function getTournament(tournament_id: number): SWRResponse {
|
||||
return useSWR(`tournaments/${tournament_id}`, fetcher);
|
||||
}
|
||||
|
||||
export function getTournaments(): SWRResponse {
|
||||
return useSWR('tournaments', fetcher);
|
||||
}
|
||||
@@ -65,7 +69,9 @@ export function getTeams(tournament_id: number): SWRResponse {
|
||||
}
|
||||
|
||||
export function getRounds(tournament_id: number, no_draft_rounds: boolean = false): SWRResponse {
|
||||
return useSWR(`tournaments/${tournament_id}/rounds?no_draft_rounds=${no_draft_rounds}`, fetcher);
|
||||
return useSWR(`tournaments/${tournament_id}/rounds?no_draft_rounds=${no_draft_rounds}`, fetcher, {
|
||||
refreshInterval: 3000,
|
||||
});
|
||||
}
|
||||
|
||||
export function getUpcomingMatches(tournament_id: number): SWRResponse {
|
||||
|
||||
Reference in New Issue
Block a user