Skip to content

Commit 2258138

Browse files
committed
fix: enforce Admin cancel mode role check and clean up nested DECLARE
- can_cancel_match: gate cancel button on privileged roles for Admin mode - tbu_matches: raise exception for unprivileged cancel in Admin mode - tournament_brackets: remove nested DECLARE/BEGIN/END, reuse existing var
1 parent 85a5c5d commit 2258138

3 files changed

Lines changed: 40 additions & 20 deletions

File tree

hasura/functions/match/can_cancel_match.sql

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,28 @@ RETURNS boolean
33
LANGUAGE plpgsql STABLE
44
AS $$
55
DECLARE
6+
_auto_cancel_mode text;
7+
_user_role text;
68
BEGIN
7-
IF is_match_organizer(match, hasura_session) AND (
8-
match.status != 'Finished' AND
9-
match.status != 'Tie' AND
10-
match.status != 'Canceled' AND
11-
match.status != 'Forfeit' AND
12-
match.status != 'Surrendered'
13-
) THEN
14-
RETURN true;
9+
IF NOT is_match_organizer(match, hasura_session) THEN
10+
RETURN false;
1511
END IF;
1612

17-
RETURN false;
13+
IF match.status IN ('Finished', 'Tie', 'Canceled', 'Forfeit', 'Surrendered') THEN
14+
RETURN false;
15+
END IF;
16+
17+
-- Admin-only cancel: restrict to privileged roles
18+
SELECT mo.auto_cancel_mode INTO _auto_cancel_mode
19+
FROM match_options mo WHERE mo.id = match.match_options_id;
20+
21+
IF _auto_cancel_mode = 'Admin' THEN
22+
_user_role := hasura_session ->> 'x-hasura-role';
23+
IF _user_role NOT IN ('admin', 'administrator', 'tournament_organizer', 'match_organizer') THEN
24+
RETURN false;
25+
END IF;
26+
END IF;
27+
28+
RETURN true;
1829
END;
1930
$$;

hasura/triggers/matches.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ DECLARE
242242
_match_map_count int;
243243
_match_options match_options%ROWTYPE;
244244
_auto_cancel_mode text;
245+
_hasura_session jsonb;
246+
_user_role text;
245247
BEGIN
246248
auto_cancel_duration := get_setting('auto_cancel_duration', '15') || ' minutes';
247249
SELECT auto_cancel_mode INTO _auto_cancel_mode FROM match_options WHERE id = NEW.match_options_id;
@@ -340,6 +342,17 @@ BEGIN
340342
END IF;
341343

342344
IF (NEW.status = 'Canceled' AND OLD.status != 'Canceled') THEN
345+
-- Admin-only cancel: only privileged roles can cancel
346+
IF _auto_cancel_mode = 'Admin' THEN
347+
_hasura_session := current_setting('hasura.user', true)::jsonb;
348+
IF _hasura_session IS NOT NULL THEN
349+
_user_role := _hasura_session ->> 'x-hasura-role';
350+
IF _user_role NOT IN ('admin', 'administrator', 'tournament_organizer', 'match_organizer') THEN
351+
RAISE EXCEPTION 'Only administrators and organizers can cancel matches in Admin cancel mode' USING ERRCODE = '22000';
352+
END IF;
353+
END IF;
354+
-- NULL session = system/API context, allow through
355+
END IF;
343356
NEW.cancels_at = NOW();
344357
NEW.ended_at = null;
345358
END IF;

hasura/triggers/tournament_brackets.sql

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,14 @@ BEGIN
3030
raise notice 'Scheduling match for bracket %', NEW.id;
3131
IF NEW.tournament_team_id_1 IS NOT NULL AND NEW.tournament_team_id_2 IS NOT NULL THEN
3232
-- Skip auto-scheduling if tournament is paused
33-
DECLARE
34-
_tournament_status text;
35-
BEGIN
36-
SELECT t.status INTO _tournament_status
37-
FROM tournaments t
38-
JOIN tournament_stages ts ON ts.tournament_id = t.id
39-
WHERE ts.id = NEW.tournament_stage_id;
33+
SELECT t.status INTO tournament_status
34+
FROM tournaments t
35+
JOIN tournament_stages ts ON ts.tournament_id = t.id
36+
WHERE ts.id = NEW.tournament_stage_id;
4037

41-
IF _tournament_status != 'Paused' THEN
42-
PERFORM schedule_tournament_match(NEW);
43-
END IF;
44-
END;
38+
IF tournament_status != 'Paused' THEN
39+
PERFORM schedule_tournament_match(NEW);
40+
END IF;
4541
END IF;
4642
END IF;
4743

0 commit comments

Comments
 (0)