Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 30 additions & 9 deletions docs/submissions.MD
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,18 @@ curl -X PUT http://localhost:8000/submission/a1b2c3d4-5678-90ab-cdef-1234567890a
**認證**: 必須(Bearer Token)

**查詢參數**:
- `page` (可選): 頁碼預設 1
- `page_size` (可選): 每頁數量預設 20
- `page` (可選): 頁碼,預設 1
- `page_size` (可選): 每頁數量,預設 20
- `problem_id` (可選): 篩選特定題目的提交
- `username` (可選): 篩選特定使用者的提交
- `status` (可選): 篩選判題狀態如 "0"=AC, "1"=WA, "2"=CE, "3"=TLE, "4"=MLE, "5"=RE
- `status` (可選): 篩選判題狀態(如 "0"=AC, "1"=WA, "2"=CE, "3"=TLE, "4"=MLE, "5"=RE)
- `course_id` (可選): 篩選特定課程的所有提交
- `language_type` (可選): 篩選程式語言(0=C, 1=C++, 2=Python, 3=Java, 4=JavaScript)
- `before` (可選): 篩選某時間之前的提交(Unix 時間戳記,單位:秒)
- `after` (可選): 篩選某時間之後的提交(Unix 時間戳記,單位:秒)
- `language_type` (可選): 篩選程式語言(0=C, 1=C++, 2=Python, 3=Java, 4=JavaScript)
- `before` (可選): 篩選某時間之前的提交(Unix 時間戳記,單位:秒)
- `after` (可選): 篩選某時間之後的提交(Unix 時間戳記,單位:秒)
- `ip_prefix` (可選): 篩選 IP 網段前綴,支援以下格式:
- 簡單前綴: `192.168.` 匹配所有 192.168.x.x
- CIDR 表示法: `192.168.1.0/24` 匹配 192.168.1.0-255 範圍

**權限說明**:
- 學生:只能查看自己的提交
Expand Down Expand Up @@ -316,6 +319,18 @@ curl -X GET "http://localhost:8000/submission/?after=1735286400&before=173537279
# 組合多個篩選條件
curl -X GET "http://localhost:8000/submission/?problem_id=123&status=0&language_type=2" \
-H "Authorization: Bearer YOUR_TOKEN"

# 查詢特定 IP 網段的提交(簡單前綴)
curl -X GET "http://localhost:8000/submission/?ip_prefix=192.168." \
-H "Authorization: Bearer YOUR_TOKEN"

# 查詢特定 IP 網段的提交(CIDR 表示法)
curl -X GET "http://localhost:8000/submission/?ip_prefix=192.168.1.0/24" \
-H "Authorization: Bearer YOUR_TOKEN"

# 組合 IP 網段與其他條件
curl -X GET "http://localhost:8000/submission/?ip_prefix=10.0.0.0/8&status=0" \
-H "Authorization: Bearer YOUR_TOKEN"
```

---
Expand Down Expand Up @@ -662,9 +677,9 @@ submissionId: "a1b2c3d4-5678-90ab-cdef-1234567890ab"
### 1. 提交限制檢查
- [ ] `"problem permission denied"` - 題目權限檢查
- [ ] `"homework hasn't start"` - 作業時間檢查
- [ ] `"Invalid IP address"` - IP 白名單檢查
- [x] IP 網段前綴篩選 - 支援簡單前綴和 CIDR 表示法
- [ ] `"you have used all your quotas"` - 配額限制
- [ ] `"Submit too fast!"` - 提交頻率限制含 `waitFor` 欄位
- [ ] `"Submit too fast!"` - 提交頻率限制(含 `waitFor` 欄位)

### 2. 判題系統整合
- [ ] 實際連接 SandBox 判題系統
Expand Down Expand Up @@ -834,9 +849,15 @@ curl -X GET http://localhost:8000/submission/student-submission-id/ \

## 版本歷史

**v1.1 (2025-12-28)**
- 新增 IP 網段前綴篩選功能
- 支援簡單前綴匹配(如 `192.168.`)
- 支援 CIDR 表示法(如 `192.168.1.0/24`)
- 實作統計資料自動更新(全域與作業層級)

**v1.0 (2025-11-09)**
- 初始版本
- 實作基本提交功能創建、上傳、查詢
- 實作基本提交功能(創建、上傳、查詢)
- 兼容 NOJ 格式標準
- 實作角色權限系統
- 支援重新判題功能
Expand Down
2 changes: 1 addition & 1 deletion submissions/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ class SubmissionBaseCreateSerializer(serializers.ModelSerializer):
min_value=0,
max_value=4,
error_messages={
'invalid': 'invalid data!',
'invalid': 'languageType 格式錯誤:必須是 0-4 的整數 (收到的類型不正確)',
'required': 'post data missing!',
'min_value': 'not allowed language',
'max_value': 'not allowed language'
Expand Down
20 changes: 18 additions & 2 deletions submissions/test_file/get_test_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,25 @@ def create_test_user():
if created:
user.set_password(password)
user.save()
print(f"創建新用戶: {username}")
print(f"創建新用戶: {username}")
else:
print(f"使用現有用戶: {username}")
print(f"✓ 使用現有用戶: {username}")

# 確保 email 已驗證(測試用)
try:
from user.models import UserProfile
profile, profile_created = UserProfile.objects.get_or_create(
user=user,
defaults={'email_verified': True}
)
if not profile.email_verified:
profile.email_verified = True
profile.save()
print(f"✓ Email 已設為驗證狀態")
else:
print(f"✓ Email 已是驗證狀態")
except Exception as e:
print(f"⚠ 無法設置 email 驗證狀態: {e}")

return user, password

Expand Down
32 changes: 32 additions & 0 deletions submissions/test_file/test_submission_views_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,50 @@ class SubmissionAPITestSetup:
@classmethod
def create_test_users(cls):
"""創建測試用戶"""
from user.models import UserProfile

# 普通學生
cls.student1 = User.objects.create_user(
username='api_student1',
email='api_student1@test.com',
password='testpass123'
)
# 設置郵箱驗證
profile1, _ = UserProfile.objects.get_or_create(user=cls.student1)
profile1.email_verified = True
profile1.save()

cls.student2 = User.objects.create_user(
username='api_student2',
email='api_student2@test.com',
password='testpass123'
)
# 設置郵箱驗證
profile2, _ = UserProfile.objects.get_or_create(user=cls.student2)
profile2.email_verified = True
profile2.save()

# 老師
cls.teacher = User.objects.create_user(
username='api_teacher',
email='api_teacher@test.com',
password='testpass123'
)
# 設置郵箱驗證
profile_teacher, _ = UserProfile.objects.get_or_create(user=cls.teacher)
profile_teacher.email_verified = True
profile_teacher.save()

# TA
cls.ta = User.objects.create_user(
username='api_ta',
email='api_ta@test.com',
password='testpass123'
)
# 設置郵箱驗證
profile_ta, _ = UserProfile.objects.get_or_create(user=cls.ta)
profile_ta.email_verified = True
profile_ta.save()

# 管理員
cls.admin = User.objects.create_user(
Expand All @@ -73,6 +92,11 @@ def create_test_users(cls):
is_staff=True,
is_superuser=True
)
# 設置郵箱驗證
profile_admin, _ = UserProfile.objects.get_or_create(user=cls.admin)
profile_admin.email_verified = True
profile_admin.save()


@classmethod
def create_test_courses(cls):
Expand Down Expand Up @@ -117,6 +141,7 @@ def create_test_problems(cls):
description='API測試:給定一個整數數組,返回兩個數字的索引',
course_id=cls.course1,
creator_id=cls.teacher, # 添加必需的 creator_id
is_public='course', # 設置為課程可見
difficulty=Problems.Difficulty.EASY
)

Expand All @@ -126,6 +151,7 @@ def create_test_problems(cls):
description='API測試:反轉一個單鏈表',
course_id=cls.course2,
creator_id=cls.teacher, # 添加必需的 creator_id
is_public='course', # 設置為課程可見
difficulty=Problems.Difficulty.MEDIUM
)

Expand All @@ -136,6 +162,7 @@ def create_test_problems(cls):
description='API測試:用於測試權限的題目(關聯到 course2)',
course_id=cls.course2, # 修改:不能為 None,使用 course2
creator_id=cls.teacher, # 添加必需的 creator_id
is_public='course', # 設置為課程可見
difficulty=Problems.Difficulty.HARD
)

Expand Down Expand Up @@ -290,6 +317,11 @@ def test_create_submission_success(self):

response = self.client.post(self.get_submission_create_url(), data)

# 調試:打印響應內容
if response.status_code != status.HTTP_201_CREATED:
print(f"\n錯誤狀態碼: {response.status_code}")
print(f"響應內容: {response.data}")

# 驗證 NOJ 格式響應 (通過 api_response 包裝)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
message = self.get_api_message(response)
Expand Down
Loading