Mail Subscription API Documentation
[TOC]
Base URL
/api/v1
Authentication
This system uses Django Session Authentication combined with a CSRF Token mechanism for security.
Login
Validates LDAP credentials and, upon success, sets the authentication cookies.
POST /api/v1/auth/login/
Permission:
AllowAnyRequest Body
{
"username": "b13902xxx",
"password": "secret"
}
Response:
200 OK
{
"username": "b13902xxx",
"is_staff": false
}
Response Headers
Set-Cookie: sessionid=abc123xyz...; HttpOnly; Path=/; SameSite=Lax; Secure
Set-Cookie: csrftoken=def456uvw...; Path=/; SameSite=Lax; Secure
:bookmark_tabs: Note: CSRF token
Include the CSRF token in headers for all state-changing requests (
POST,PUT,DELETE). The frontend must manually read the csrftoken value from the cookies and include it in the HTTP headers asX-CSRFToken: <token_value>import Cookies from 'js-cookie'; const csrfToken = Cookies.get('csrftoken');
Check Session
Used by the frontend upon page load/refresh to verify if the user’s session is still active and to retrieve their role for rendering decisions.
GET /api/v1/auth/me/
Permission:
IsAuthenticatedResponse:
200 OK
{
"username": "b13902xxx",
"is_admin": false
}
Error Response:
403 Forbidden
Logout
POST /api/v1/auth/logout/
Permission:
IsAuthenticatedRequest Headers:
X-CSRFToken: <x-csrftoken>Response:
205 Reset Content
After calling this API, the backend will instruct the browser to clear the cookies. The frontend should then clear its own global state and redirect the user to the login page.
User
Endpoints for standard users to manage their own mailing list subscriptions. The backend automatically identifies the user via the session cookie.
Get User Setting
Retrieves the subscription status of all available aliases for the currently logged-in user.
GET /api/v1/user/subscriptions/
Permission:
IsAuthenticatedResponse:
200 OK
[
{
"alias_name": "workstation",
"display_name": "工作站",
"description": "工作站清理、重開機公告",
"is_subscribed": true
},
{
"alias_name": "activities",
"display_name": "系上活動",
"description": "演講、交流",
"is_subscribed": false
},
{
"alias_3": ...
...
}
]
Update User Setting
PUT /api/v1/user/subscriptions/
Permission:
IsAuthenticatedRequest Headers:
X-CSRFToken: <token_value>Request Body
{
"workstation": false,
"activities": true,
"alias_3": true,
...
}
Response:
200 OK
{
"status": "success",
"message": "已收到訂閱狀態更新請求,將於 10 分鐘內生效"
}
:bookmark_tabs: Note: Rate Limiting (Cooldown) This endpoint is protected by a rate limiter to prevent spam and LDAP sync overload. If a user calls this endpoint too frequently, the server will reject the request and return a
429 Too Many Requestserror.
Admin
Endpoints for administrators (users in the NASA mail group) to manage mailing list aliases and their subscribers.
:bookmark_tabs: Note: Permissions All endpoints in this section require the permission (
is_admin=True). If a standard user attempts to access these, the server will return a403 Forbiddenresponse.
Get All Aliases
Retrieves a list of all existing aliases and their basic information.
GET /api/v1/admin/aliases/
Permission:
IsAdminUserResponse:
200 OK
[
{
"alias_name": "workstation",
"display_name": "工作站",
"description": "工作站清理、重開機公告"
},
{
"alias_name": "activities",
"display_name": "系上活動",
"description": "演講、交流"
}
]
Create Alias
Creates a new mailing list alias.
POST /api/v1/admin/aliases/
Permission:
IsAdminUserRequest Headers:
X-CSRFToken: <token_value>Request Body
{
"alias_name": "new_alias",
"display_name": "新群組",
"description": "這是一個新建立的群組"
}
Response:
201 Created
Update Alias
PATCH /api/v1/admin/aliases/<alias_name>/
Permission:
IsAdminUserRequest Headers:
X-CSRFToken: <token_value>Request body: 只需要傳遞想要更新的欄位即可:
{
"display_name": "新工作站公告",
"description": "更新後的工作站清理、重開機與維護公告"
}
Response 200 OK
{
"alias_name": "workstation",
"display_name": "新工作站公告",
"description": "更新後的工作站清理、重開機與維護公告"
}
Possible Errors
400 Bad Request— 欄位驗證失敗(例如display_name或description超過字數限制)。
{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"details": {
"display_name": ["Ensure this field has no more than 255 characters."],
"description": ["Ensure this field has no more than 500 characters."]
}
}
404 Not Found— 指定的 alias 不存在。
{
"error": "The requested resource was not found.",
"code": "NOT_FOUND"
}
500 Internal Server Error— 伺服器錯誤。
Delete Alias
Deletes an entire mailing list alias.
DELETE /api/v1/admin/aliases/<alias_name>/
Permission:
IsAdminUserRequest Headers:
X-CSRFToken: <token_value>Response:
204 No Content
Get Alias Subscribers
Retrieves a list of all users currently subscribed to a specific alias.
GET /api/v1/admin/aliases/<alias_name>/users/
Permission:
IsAdminUserResponse:
200 OK
[
"b13902001",
"b13902002",
"b13902003"
]
Add Subscriber to Alias
Manually adds a specific user (by UID) to an alias.
POST /api/v1/admin/aliases/<alias_name>/users/
Permission:
IsAdminUserRequest Headers:
X-CSRFToken: <token_value>Request Body
{
"uid": "b13902xxx"
}
Response:
200 OK
Remove Subscriber from Alias
Manually removes a specific user from an alias. The user’s UID is passed directly in the URL path.
DELETE /api/v1/admin/aliases/<alias_name>/users/<uid>/
Permission:
IsAdminUserRequest Headers:
X-CSRFToken: <token_value>Response:
204 No Content
Error Responses
400 Bad Request
{
"error": "Validation failed",
"code": "VALIDATION_ERROR",
"details": {
"alias_name": ["Alias name can only contain lowercase letters and numbers."],
"uid": ["Ensure this field has exactly 9 characters."]
}
}
403 Forbidden
{
"error": "You do not have permission to perform this action.",
"code": "PERMISSION_DENIED"
}
404 Not Found
{
"error": "The requested resource was not found.",
"code": "NOT_FOUND"
}
409 Conflict
{
"error": "Alias name already exists.",
"code": "CONFLICT",
"details": {
"existing_alias": "workstation"
}
}
429 Too Many Requests
{
"error": "Request was throttled.",
"code": "TOO_MANY_REQUESTS",
"details": {
"wait_seconds": 45
}
}
500 Internal Server Error
{
"error": "An unexpected error occurred. Please contact the administrator.",
"code": "INTERNAL_SERVER_ERROR"
}