flysuper commited on
Commit
1e0eaf9
·
verified ·
1 Parent(s): fc61798

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -5
app.py CHANGED
@@ -56,11 +56,16 @@ app.add_middleware(
56
 
57
  # 允許的來源網址清單
58
  ALLOWED_ORIGINS = [
59
- "https://n-m2azgihk7rtcqqaxywntv75at3thf3bgps4xdlq-0lu-script.googleusercontent.com",
60
  "https://www.dfes.ntpc.edu.tw",
61
  "https://demo.dfes.ntpc.edu.tw"
62
  ]
63
 
 
 
 
 
 
 
64
  # 如果希望允許所有 GAS,取消下面兩行的註解
65
  # "https://script.google.com", # 所有 Google Apps Script
66
 
@@ -96,12 +101,20 @@ def _is_origin_allowed(request: Request) -> bool:
96
  if origin.startswith(allowed_origin):
97
  print(f"✅ Origin 匹配: {origin} 匹配 {allowed_origin}")
98
  return True
 
 
 
 
99
 
100
  if referer:
101
  for allowed_origin in ALLOWED_ORIGINS:
102
  if referer.startswith(allowed_origin):
103
  print(f"✅ Referer 匹配: {referer} 匹配 {allowed_origin}")
104
  return True
 
 
 
 
105
 
106
  # 允許來自 Hugging Face Spaces 的直接調用
107
  if "huggingface" in user_agent.lower():
@@ -111,6 +124,40 @@ def _is_origin_allowed(request: Request) -> bool:
111
  print(f"❌ 請求被拒絕 - Origin: {origin}, Referer: {referer}")
112
  return False
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  @app.get("/")
115
  async def root():
116
  """根路徑,返回 API 信息"""
@@ -138,23 +185,36 @@ async def get_allowed_origins():
138
  """獲取允許的來源列表(僅供管理員查看)"""
139
  return {
140
  "allowed_origins": ALLOWED_ORIGINS,
141
- "count": len(ALLOWED_ORIGINS),
142
- "description": "允許的來源網址清單,支援擴充匹配"
 
143
  }
144
 
145
  @app.get("/debug-request")
146
  async def debug_request(request: Request):
147
  """調試端點:顯示請求的詳細信息"""
148
  headers = dict(request.headers)
 
 
 
 
 
 
 
 
 
 
149
  return {
150
  "method": request.method,
151
  "url": str(request.url),
152
  "headers": headers,
153
- "origin": headers.get("origin"),
154
- "referer": headers.get("referer"),
155
  "user_agent": headers.get("user-agent"),
156
  "is_allowed": _is_origin_allowed(request),
157
  "client_ip": request.client.host if request.client else "unknown",
 
 
158
  "request_info": {
159
  "has_origin": bool(headers.get("origin")),
160
  "has_referer": bool(headers.get("referer")),
@@ -163,6 +223,33 @@ async def debug_request(request: Request):
163
  }
164
  }
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
  @app.get("/voices")
168
  async def get_voices():
 
56
 
57
  # 允許的來源網址清單
58
  ALLOWED_ORIGINS = [
 
59
  "https://www.dfes.ntpc.edu.tw",
60
  "https://demo.dfes.ntpc.edu.tw"
61
  ]
62
 
63
+ # 允許的 GAS 專案 ID 清單(支援多個專案)
64
+ ALLOWED_GAS_PROJECT_IDS = [
65
+ "m2azgihk7rtcqqaxywntv75at3thf3bgps4xdlq", # 您的 GAS 專案 ID
66
+ # 可以在這裡添加更多 GAS 專案 ID
67
+ ]
68
+
69
  # 如果希望允許所有 GAS,取消下面兩行的註解
70
  # "https://script.google.com", # 所有 Google Apps Script
71
 
 
101
  if origin.startswith(allowed_origin):
102
  print(f"✅ Origin 匹配: {origin} 匹配 {allowed_origin}")
103
  return True
104
+
105
+ # 檢查 GAS 專案 ID
106
+ if _is_gas_project_allowed(origin):
107
+ return True
108
 
109
  if referer:
110
  for allowed_origin in ALLOWED_ORIGINS:
111
  if referer.startswith(allowed_origin):
112
  print(f"✅ Referer 匹配: {referer} 匹配 {allowed_origin}")
113
  return True
114
+
115
+ # 檢查 GAS 專案 ID
116
+ if _is_gas_project_allowed(referer):
117
+ return True
118
 
119
  # 允許來自 Hugging Face Spaces 的直接調用
120
  if "huggingface" in user_agent.lower():
 
124
  print(f"❌ 請求被拒絕 - Origin: {origin}, Referer: {referer}")
125
  return False
126
 
127
+ def _is_gas_project_allowed(url: str) -> bool:
128
+ """檢查是否為允許的 GAS 專案"""
129
+ if not url:
130
+ return False
131
+
132
+ # 檢查是否為 GAS 網址格式
133
+ if not url.startswith("https://n-") or not url.endswith("-script.googleusercontent.com"):
134
+ return False
135
+
136
+ # 提取專案 ID
137
+ # 網址格式: https://n-{專案ID}-{使用者ID}lu-script.googleusercontent.com
138
+ try:
139
+ # 移除前綴和後綴
140
+ project_part = url.replace("https://n-", "").replace("-script.googleusercontent.com", "")
141
+
142
+ # 找到最後一個 "-" 的位置,前面就是專案 ID
143
+ last_dash_index = project_part.rfind("-")
144
+ if last_dash_index == -1:
145
+ return False
146
+
147
+ project_id = project_part[:last_dash_index]
148
+
149
+ # 檢查專案 ID 是否在允許清單中
150
+ if project_id in ALLOWED_GAS_PROJECT_IDS:
151
+ print(f"✅ GAS 專案匹配: {project_id} 在允許清單中")
152
+ return True
153
+ else:
154
+ print(f"❌ GAS 專案不匹配: {project_id} 不在允許清單中")
155
+ return False
156
+
157
+ except Exception as e:
158
+ print(f"⚠️ 解析 GAS 網址時發生錯誤: {e}")
159
+ return False
160
+
161
  @app.get("/")
162
  async def root():
163
  """根路徑,返回 API 信息"""
 
185
  """獲取允許的來源列表(僅供管理員查看)"""
186
  return {
187
  "allowed_origins": ALLOWED_ORIGINS,
188
+ "allowed_gas_project_ids": ALLOWED_GAS_PROJECT_IDS,
189
+ "count": len(ALLOWED_ORIGINS) + len(ALLOWED_GAS_PROJECT_IDS),
190
+ "description": "允許的來源網址清單,支援擴充匹配。GAS 專案 ID 會自動匹配所有使用者的網址變體。"
191
  }
192
 
193
  @app.get("/debug-request")
194
  async def debug_request(request: Request):
195
  """調試端點:顯示請求的詳細信息"""
196
  headers = dict(request.headers)
197
+ origin = headers.get("origin")
198
+ referer = headers.get("referer")
199
+
200
+ # 檢查 GAS 專案
201
+ gas_project_info = {}
202
+ if origin:
203
+ gas_project_info["origin"] = _extract_gas_project_id(origin)
204
+ if referer:
205
+ gas_project_info["referer"] = _extract_gas_project_id(referer)
206
+
207
  return {
208
  "method": request.method,
209
  "url": str(request.url),
210
  "headers": headers,
211
+ "origin": origin,
212
+ "referer": referer,
213
  "user_agent": headers.get("user-agent"),
214
  "is_allowed": _is_origin_allowed(request),
215
  "client_ip": request.client.host if request.client else "unknown",
216
+ "gas_project_info": gas_project_info,
217
+ "allowed_gas_project_ids": ALLOWED_GAS_PROJECT_IDS,
218
  "request_info": {
219
  "has_origin": bool(headers.get("origin")),
220
  "has_referer": bool(headers.get("referer")),
 
223
  }
224
  }
225
 
226
+ def _extract_gas_project_id(url: str) -> dict:
227
+ """提取 GAS 專案 ID 信息"""
228
+ if not url:
229
+ return {"is_gas": False}
230
+
231
+ if not url.startswith("https://n-") or not url.endswith("-script.googleusercontent.com"):
232
+ return {"is_gas": False}
233
+
234
+ try:
235
+ project_part = url.replace("https://n-", "").replace("-script.googleusercontent.com", "")
236
+ last_dash_index = project_part.rfind("-")
237
+
238
+ if last_dash_index == -1:
239
+ return {"is_gas": True, "project_id": None, "user_id": None, "error": "無法解析專案 ID"}
240
+
241
+ project_id = project_part[:last_dash_index]
242
+ user_id = project_part[last_dash_index + 1:]
243
+
244
+ return {
245
+ "is_gas": True,
246
+ "project_id": project_id,
247
+ "user_id": user_id,
248
+ "is_allowed": project_id in ALLOWED_GAS_PROJECT_IDS
249
+ }
250
+ except Exception as e:
251
+ return {"is_gas": True, "error": str(e)}
252
+
253
 
254
  @app.get("/voices")
255
  async def get_voices():