6859846b7c
- bootstrap 失败恢复 SSH 临时登录回退 - ssh_bootstrap 真安装检测与 config 目录自愈 - axs Gitea 发布源切换为 https://axs.kuma1xn.vip
122 lines
3.6 KiB
Python
122 lines
3.6 KiB
Python
"""Tests for post-upload permission fixup."""
|
|
|
|
import pytest
|
|
|
|
from server.utils.files_upload_permissions import (
|
|
apply_transfer_permissions,
|
|
apply_upload_file_permissions,
|
|
parse_upload_chown,
|
|
parse_upload_dir_mode,
|
|
parse_upload_file_mode,
|
|
upload_permission_plan,
|
|
)
|
|
from server.config import settings
|
|
|
|
|
|
def test_parse_upload_file_mode_from_rsync_default():
|
|
assert parse_upload_file_mode("D755,F755") == "755"
|
|
assert parse_upload_file_mode("F644") == "644"
|
|
assert parse_upload_file_mode("755") == "755"
|
|
|
|
|
|
def test_parse_upload_file_mode_invalid():
|
|
assert parse_upload_file_mode("") is None
|
|
assert parse_upload_file_mode("bad") is None
|
|
|
|
|
|
def test_parse_upload_chown():
|
|
assert parse_upload_chown("www:www") == ("www", "www")
|
|
assert parse_upload_chown("root") == ("root", "root")
|
|
assert parse_upload_chown("www;evil") is None
|
|
|
|
|
|
def test_upload_permission_plan_defaults():
|
|
owner_group, mode = upload_permission_plan()
|
|
assert owner_group == ("www", "www")
|
|
assert mode == "755"
|
|
|
|
|
|
def test_upload_permission_plan_disabled(monkeypatch):
|
|
monkeypatch.setattr(settings, "RSYNC_PUSH_CHOWN", "")
|
|
monkeypatch.setattr(settings, "RSYNC_PUSH_CHMOD", "")
|
|
assert upload_permission_plan() == (None, None)
|
|
|
|
|
|
def test_parse_upload_dir_mode():
|
|
assert parse_upload_dir_mode("D755,F755") == "755"
|
|
assert parse_upload_dir_mode("F644") == "644"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_apply_transfer_permissions_recursive_chown_chmod(monkeypatch):
|
|
calls: list[str] = []
|
|
|
|
async def fake_exec(server, cmd, timeout=30):
|
|
calls.append(cmd)
|
|
return {"exit_code": 0, "elevated": True}
|
|
|
|
monkeypatch.setattr(
|
|
"server.infrastructure.ssh.remote_shell.exec_ssh_command_with_fallback",
|
|
fake_exec,
|
|
)
|
|
|
|
class FakeServer:
|
|
id = 3
|
|
|
|
result = await apply_transfer_permissions(FakeServer(), "/www/backup/site", recursive=True)
|
|
|
|
assert result["applied"] is True
|
|
assert result["owner"] == "www"
|
|
assert "chown -R" in calls[0] and "www:www" in calls[0]
|
|
assert any("chmod -R 755" in c for c in calls)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_apply_upload_file_permissions_success(monkeypatch):
|
|
calls: list[tuple[str, str]] = []
|
|
|
|
async def fake_exec(server, cmd, timeout=30):
|
|
calls.append((getattr(server, "id", "?"), cmd))
|
|
return {"exit_code": 0, "elevated": True}
|
|
|
|
monkeypatch.setattr(
|
|
"server.infrastructure.ssh.remote_shell.exec_ssh_command_with_fallback",
|
|
fake_exec,
|
|
)
|
|
|
|
class FakeServer:
|
|
id = 1
|
|
|
|
result = await apply_upload_file_permissions(FakeServer(), "/var/www/test.txt")
|
|
|
|
assert result["applied"] is True
|
|
assert result["owner"] == "www"
|
|
assert result["group"] == "www"
|
|
assert result["mode"] == "755"
|
|
assert result["elevated"] is True
|
|
assert result["error"] is None
|
|
assert len(calls) == 2
|
|
assert "chown" in calls[0][1] and "www:www" in calls[0][1]
|
|
assert "chmod 755" in calls[1][1]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_apply_upload_file_permissions_chown_failure(monkeypatch):
|
|
async def fake_exec(server, cmd, timeout=30):
|
|
if cmd.startswith("chown"):
|
|
return {"exit_code": 1, "stderr": "permission denied", "elevated": False}
|
|
return {"exit_code": 0, "elevated": False}
|
|
|
|
monkeypatch.setattr(
|
|
"server.infrastructure.ssh.remote_shell.exec_ssh_command_with_fallback",
|
|
fake_exec,
|
|
)
|
|
|
|
class FakeServer:
|
|
id = 2
|
|
|
|
result = await apply_upload_file_permissions(FakeServer(), "/tmp/x")
|
|
|
|
assert result["applied"] is False
|
|
assert "permission denied" in (result["error"] or "")
|