fix: harden google drive import auth
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
This commit is contained in:
98
tests/test_google_drive_runtime_auth.py
Normal file
98
tests/test_google_drive_runtime_auth.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import json
|
||||
import types
|
||||
|
||||
|
||||
def _configure_paths(monkeypatch, gds, tmp_path):
|
||||
credentials_file = tmp_path / "google_credentials.json"
|
||||
token_file = tmp_path / "google_token.json"
|
||||
legacy_file = tmp_path / "google_token.pickle"
|
||||
credentials_file.write_text("{}", encoding="utf-8")
|
||||
monkeypatch.setattr(gds, "CREDENTIALS_FILE", str(credentials_file))
|
||||
monkeypatch.setattr(gds, "TOKEN_FILE", str(token_file))
|
||||
monkeypatch.setattr(gds, "_LEGACY_PICKLE_FILE", str(legacy_file))
|
||||
return credentials_file, token_file, legacy_file
|
||||
|
||||
|
||||
def test_production_runtime_never_starts_interactive_drive_auth(monkeypatch, tmp_path):
|
||||
import services.google_drive_service as gds
|
||||
|
||||
_configure_paths(monkeypatch, gds, tmp_path)
|
||||
monkeypatch.setenv("GOOGLE_DRIVE_ALLOW_INTERACTIVE_AUTH", "true")
|
||||
monkeypatch.setenv("FLASK_ENV", "production")
|
||||
|
||||
class ExplodingFlow:
|
||||
@staticmethod
|
||||
def from_client_secrets_file(*_args, **_kwargs):
|
||||
raise AssertionError("browser OAuth must not run in production")
|
||||
|
||||
monkeypatch.setattr(gds, "InstalledAppFlow", ExplodingFlow)
|
||||
|
||||
service = gds.GoogleDriveService()
|
||||
|
||||
assert service.authenticate() is False
|
||||
assert service.last_error_kind == "reauthorization_required"
|
||||
assert "授權檔不存在" in service.last_error
|
||||
|
||||
|
||||
def test_drive_auth_readiness_refreshes_and_persists_json_token(monkeypatch, tmp_path):
|
||||
import services.google_drive_service as gds
|
||||
|
||||
_, token_file, _ = _configure_paths(monkeypatch, gds, tmp_path)
|
||||
token_file.write_text(json.dumps({"token": "old"}), encoding="utf-8")
|
||||
|
||||
class FakeCredentials:
|
||||
valid = False
|
||||
expired = True
|
||||
refresh_token = "refresh-token"
|
||||
|
||||
def refresh(self, _request):
|
||||
self.valid = True
|
||||
self.expired = False
|
||||
|
||||
def to_json(self):
|
||||
return json.dumps({"token": "new-token", "refresh_token": self.refresh_token})
|
||||
|
||||
fake_credentials = FakeCredentials()
|
||||
monkeypatch.setattr(
|
||||
gds,
|
||||
"Credentials",
|
||||
types.SimpleNamespace(
|
||||
from_authorized_user_info=lambda _token_data, _scopes: fake_credentials
|
||||
),
|
||||
)
|
||||
|
||||
service = gds.GoogleDriveService()
|
||||
status = service.check_auth_readiness(refresh_expired=True)
|
||||
|
||||
assert status["ready"] is True
|
||||
assert status["kind"] == "ready"
|
||||
assert service.last_error_kind is None
|
||||
assert json.loads(token_file.read_text(encoding="utf-8"))["token"] == "new-token"
|
||||
|
||||
|
||||
def test_drive_auth_readiness_requires_refresh_token(monkeypatch, tmp_path):
|
||||
import services.google_drive_service as gds
|
||||
|
||||
_, token_file, _ = _configure_paths(monkeypatch, gds, tmp_path)
|
||||
token_file.write_text(json.dumps({"token": "stale"}), encoding="utf-8")
|
||||
|
||||
class FakeCredentials:
|
||||
valid = False
|
||||
expired = False
|
||||
refresh_token = None
|
||||
|
||||
monkeypatch.setattr(
|
||||
gds,
|
||||
"Credentials",
|
||||
types.SimpleNamespace(
|
||||
from_authorized_user_info=lambda _token_data, _scopes: FakeCredentials()
|
||||
),
|
||||
)
|
||||
|
||||
service = gds.GoogleDriveService()
|
||||
status = service.check_auth_readiness(refresh_expired=True)
|
||||
|
||||
assert status["ready"] is False
|
||||
assert status["kind"] == "reauthorization_required"
|
||||
assert service.last_error_kind == "reauthorization_required"
|
||||
assert "缺少可刷新憑證" in service.last_error
|
||||
Reference in New Issue
Block a user