项目代码提交
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
"""Read-only HTTP checks for the isolated localhost:18080 deployment rehearsal."""
|
||||
import hashlib
|
||||
import http.cookiejar
|
||||
from html.parser import HTMLParser
|
||||
import json
|
||||
from pathlib import Path
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
BASE = "http://localhost:18080"
|
||||
|
||||
|
||||
class Links(HTMLParser):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.urls = []
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
values = dict(attrs)
|
||||
if tag in ("script", "img") and values.get("src"):
|
||||
self.urls.append(values["src"])
|
||||
if tag == "link" and values.get("href"):
|
||||
self.urls.append(values["href"])
|
||||
|
||||
|
||||
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
||||
def redirect_request(self, req, fp, code, msg, headers, newurl):
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
credentials = dict(line.split(": ", 1) for line in
|
||||
(ROOT / "artifacts/preview-access.txt").read_text().splitlines())
|
||||
opener = urllib.request.build_opener(NoRedirect)
|
||||
cookies = http.cookiejar.CookieJar()
|
||||
signed_in = urllib.request.build_opener(NoRedirect, urllib.request.HTTPCookieProcessor(cookies))
|
||||
|
||||
def request(path, status=200, authenticated=False, data=None, headers=None):
|
||||
headers = dict(headers or {})
|
||||
if data is not None:
|
||||
headers["Content-Type"] = "application/json"
|
||||
req = urllib.request.Request(BASE + path, headers=headers,
|
||||
data=json.dumps(data).encode() if data is not None else None)
|
||||
try:
|
||||
response = (signed_in if authenticated else opener).open(req, timeout=15)
|
||||
except urllib.error.HTTPError as error:
|
||||
response = error
|
||||
with response:
|
||||
body = response.read()
|
||||
assert response.status == status, (path, response.status, status)
|
||||
assert "WWW-Authenticate" not in response.headers, path
|
||||
return body, response.headers
|
||||
|
||||
portal, _ = request("/")
|
||||
assert b'href="/blackjack/"' in portal and b'href="/wolin/"' in portal
|
||||
game, _ = request("/blackjack/")
|
||||
assert hashlib.sha256(game).digest() == hashlib.sha256(
|
||||
(ROOT / "deploy/site/blackjack/index.html").read_bytes()).digest()
|
||||
for path in ["/blackjack", "/wolin"]:
|
||||
_, headers = request(path, 308)
|
||||
assert headers["Location"].endswith(path + "/")
|
||||
_, headers = request("/wolin/", 303, headers={"Accept": "text/html"})
|
||||
assert headers["Location"] == "/wolin/login"
|
||||
login_page, _ = request("/wolin/login")
|
||||
assert b'id="login-form"' in login_page
|
||||
for path in ["/wolin/docs", "/wolin/openapi.json", "/wolin/static/app.js",
|
||||
"/wolin/api/studentsManagement/workspace/overview",
|
||||
"/wolin/api/studentsManagement/ai/status"]:
|
||||
request(path, 401)
|
||||
request("/wolin/api/studentsManagement/workspace/query", 401, data={"module": "students"})
|
||||
for path in ["/api/studentsManagement/workspace/overview", "/docs", "/openapi.json",
|
||||
"/static/app.js", "/.env", "/.env.cloud", "/.git/config"]:
|
||||
request(path, 404)
|
||||
|
||||
request("/wolin/auth/login", 401, data={"username": credentials["Username"], "password": "incorrect-test-password"})
|
||||
request("/wolin/auth/login", authenticated=True,
|
||||
data={"username": credentials["Username"], "password": credentials["Password"]},
|
||||
headers={"Origin": BASE})
|
||||
assert cookies, "Login did not issue a session cookie"
|
||||
assert all(cookie.path == "/wolin/" and cookie.has_nonstandard_attr("HttpOnly") for cookie in cookies)
|
||||
page, headers = request("/wolin/", authenticated=True)
|
||||
assert headers["Cache-Control"] == "no-store"
|
||||
parser = Links()
|
||||
parser.feed(page.decode())
|
||||
for url in parser.urls:
|
||||
if urllib.parse.urlsplit(url).scheme:
|
||||
continue
|
||||
path = urllib.parse.urlsplit(urllib.parse.urljoin(BASE + "/wolin/", url)).path
|
||||
assert path.startswith("/wolin/"), path
|
||||
request(path, authenticated=True)
|
||||
request("/wolin/docs", authenticated=True)
|
||||
schema, _ = request("/wolin/openapi.json", authenticated=True)
|
||||
assert any(server["url"] == "/wolin" for server in json.loads(schema)["servers"])
|
||||
body, _ = request("/wolin/api/studentsManagement/workspace/overview", authenticated=True)
|
||||
overview = json.loads(body)
|
||||
for module in ["students", "classes", "teachers", "advisors", "scores", "employment"]:
|
||||
request("/wolin/api/studentsManagement/workspace/query", authenticated=True,
|
||||
data={"module": module, "page": 1, "page_size": 1})
|
||||
request("/wolin/auth/logout", authenticated=True, data={})
|
||||
assert not list(cookies), "Logout did not clear the session"
|
||||
request("/wolin/api/studentsManagement/workspace/overview", 401, authenticated=True)
|
||||
report = {"portal": "ok", "game_bytes_match_online_build": True,
|
||||
"authentication": "form login, signed cookie, logout, private routes protected", "student_assets": "ok",
|
||||
"api_docs_prefix": "ok", "six_modules": "ok", "counts": overview["counts"]}
|
||||
(ROOT / "artifacts/cloud-preview-check.json").write_text(
|
||||
json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
print(json.dumps(report, ensure_ascii=True))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user