File size: 3,701 Bytes
a095c00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
-- 008_log_analysis_challenges.sql
-- Creates the log-analysis challenge table + storage bucket for blue team

-- =========================================================================
-- 1. Challenge table
-- =========================================================================
CREATE TABLE IF NOT EXISTS public.log_analysis_challenges (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  team_role text NOT NULL DEFAULT 'blue' CHECK (team_role IN ('blue')),
  log_type text NOT NULL CHECK (log_type IN ('apache','nginx','syslog','auth','firewall','waf','iis')),
  module text NOT NULL DEFAULT 'forensics',
  title text NOT NULL,
  story text NOT NULL,
  task_outline text NOT NULL,
  -- Storage (Supabase Storage bucket "log-analysis-files")
  storage_path text NOT NULL,
  file_size_bytes integer,
  log_metadata jsonb DEFAULT '{}'::jsonb,
  -- Expected answers (for grading)
  expected_attack_type text NOT NULL,
  expected_attacker_ip text,
  expected_timestamp text,
  expected_ioc text,
  vulnerability_description text NOT NULL,
  hints jsonb DEFAULT '[]'::jsonb,
  difficulty text CHECK (difficulty IN ('مبتدئ','متوسط','قوي')),
  xp_reward integer DEFAULT 150,
  created_at timestamptz DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_log_analysis_team_type ON public.log_analysis_challenges(team_role, log_type);
CREATE INDEX IF NOT EXISTS idx_log_analysis_difficulty ON public.log_analysis_challenges(difficulty);

ALTER TABLE public.log_analysis_challenges ENABLE ROW LEVEL SECURITY;

-- Public read for anon
DROP POLICY IF EXISTS "Open read for anon" ON public.log_analysis_challenges;
CREATE POLICY "Open read for anon" ON public.log_analysis_challenges
  FOR SELECT USING (true);

-- Backend can write (anon key bypass via service-role OR via API key with elevated perms)
DROP POLICY IF EXISTS "Service role insert" ON public.log_analysis_challenges;
CREATE POLICY "Service role insert" ON public.log_analysis_challenges
  FOR INSERT WITH CHECK (true);

DROP POLICY IF EXISTS "Service role delete" ON public.log_analysis_challenges;
CREATE POLICY "Service role delete" ON public.log_analysis_challenges
  FOR DELETE USING (true);

-- =========================================================================
-- 2. Supabase Storage bucket
-- =========================================================================
INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
VALUES (
  'log-analysis-files',
  'log-analysis-files',
  true,
  2097152,  -- 2 MB max
  ARRAY['text/plain', 'text/x-log', 'application/octet-stream']
)
ON CONFLICT (id) DO UPDATE SET
  public = EXCLUDED.public,
  file_size_limit = EXCLUDED.file_size_limit,
  allowed_mime_types = EXCLUDED.allowed_mime_types;

-- =========================================================================
-- 3. Storage RLS — public read for the log-analysis bucket
-- =========================================================================
DROP POLICY IF EXISTS "Public read log-analysis-files" ON storage.objects;
CREATE POLICY "Public read log-analysis-files"
  ON storage.objects
  FOR SELECT
  USING (bucket_id = 'log-analysis-files');

-- Allow uploads to log-analysis-files (backend uses service-role key, which bypasses RLS anyway)
DROP POLICY IF EXISTS "Service role upload log-analysis-files" ON storage.objects;
CREATE POLICY "Service role upload log-analysis-files"
  ON storage.objects
  FOR INSERT
  WITH CHECK (bucket_id = 'log-analysis-files');

DROP POLICY IF EXISTS "Service role delete log-analysis-files" ON storage.objects;
CREATE POLICY "Service role delete log-analysis-files"
  ON storage.objects
  FOR DELETE
  USING (bucket_id = 'log-analysis-files');