Python客户端API,用于访问SecureDrop记者REST API
项目描述
通过向此项目贡献力量,您同意遵守我们的行为准则。
SecureDrop的Python SDK
本SDK提供了一种便捷的Python接口,用于访问SecureDrop记者接口API。SDK的开发主要是受到基于Qubes OS的SecureDrop工作站创建的启发。
SDK目前被SecureDrop工作站的一个组件SecureDrop客户端所使用。当在Qubes OS中使用时,SDK会使用securedrop-proxy服务,因为运行客户端的虚拟机按设计没有网络访问权限。
快速入门
make venv
source .venv/bin/activate
make test
我们涵盖了SecureDrop记者接口API支持的所有API调用。
为了测试目的将SDK安装到你的virtualenv
pip uninstall securedrop-sdk
pip install git+https://github.com/freedomofpress/securedrop-sdk@my_branch#egg=securedrop-sdk
升级单个依赖项
要升级单个Python依赖项,例如requests
,请运行以下命令
PACKAGE=requests make upgrade-pip
这将升级dev-requirements
和主要requirements
。
运行测试
要运行所有测试和检查,请运行
make check
要运行所有测试,请运行
make test
要运行所有通过HTTP进行API调用的测试,请运行
make test TESTS=tests/test_api.py
要运行所有通过qrexec进行API调用的测试,请运行
make test TESTS=tests/test_apiproxy.py
要运行单个测试,指定文件名、类名和测试名,例如
make test TESTS=tests/test_api.py::TestAPI::test_get_sources
创建和更新测试
当测试运行时,它们会回放记录的API请求和响应数据,而不是向服务器实际发出API调用。这就是为什么即使没有服务器运行,测试也能通过。如果服务器更改了API或您想添加新的API调用测试,那么您需要按照以下步骤记录新的请求和响应数据。
注意:我们有一个CI测试,它不使用记录的API请求和响应数据,以确保我们对SDK的最新更改与最新的服务器API进行测试(见https://github.com/freedomofpress/securedrop-sdk/blob/main/.circleci/config.yml中的test-against-latest-api
)。
我们使用vcrpy记录和回放通过HTTP发出的API调用,并使用名为@qrexec_datasaver
的装饰器记录和回放通过qrexec发出的API调用。测试中发出的每个请求及其从服务器收到的响应都存储在data
目录下的“cassette”中。测试回放这些cassette而不是向服务器发出实际的API调用。
如果您运行测试时看到以下vcrpy警告,则需要重新记录cassette,因为现有的cassette中没有包含预期的API调用,并且我们不允许覆盖现有的cassette
Can't overwrite existing cassette ('<path-to-cassette-for-a-functional-test>') in your current record mode ('once').
根据通信协议,生成新cassette的步骤分为两个部分:生成通过HTTP进行的API调用的cassette和生成通过qrexec进行的API调用的cassette。
生成通过HTTP进行的API调用的cassette
-
通过运行以下命令在docker容器中启动服务器
NUM_SOURCES=5 make dev
-
删除您希望重新生成的cassette或通过运行以下命令删除所有yaml文件
rm data/*.yml
如果您只是添加新测试而不是修改现有测试,可以跳过此步骤,但在cassette生成期间仍需要移除身份验证设置。否则,您将收到API端点的403错误,这些端点需要有效的令牌。通过以下命令移除设置cassette
rm data/test-setup.yml
(您可以在以后恢复未修改的版本。)
-
通过以下命令生成新的cassette,这些cassette会通过HTTP进行API调用
make test TESTS=tests/test_api.py
注意:一些测试会更改服务器上的源和会话数据,因此在测试运行之间可能需要重新启动服务器。
生成通过qrexec进行的API调用的cassette
为了生成使用qrexec进行API调用的测试磁带,您需要在单独的虚拟机上运行服务器和代理。如果您第一次生成磁带,请首先按照《qrexec通信测试设置》部分中概述的步骤操作,这将帮助您设置一个名为sd-dev-proxy
的新虚拟机。
一旦您的代理虚拟机设置完毕,请按照以下步骤操作
-
在
sd-dev-proxy
上启动Docker容器中的服务器,执行以下命令NUM_SOURCES=5 make dev
-
删除您希望重新生成的磁带或删除所有JSON文件,执行以下命令
rm data/*.json
如果您只是添加新测试而不是修改现有测试,可以跳过此步骤,但在cassette生成期间仍需要移除身份验证设置。否则,您将收到API端点的403错误,这些端点需要有效的令牌。通过以下命令移除设置cassette
rm data/setup_method.json
(您可以在以后恢复未修改的版本。)
-
对服务器进行qrexec调用并收集响应数据。要运行所有代理测试
make test TESTS=tests/test_apiproxy.py
注意:如果您收到403错误,也可能是因为测试试图重新使用旧的TOTP代码,所以请等待60秒后再试。一些测试会修改服务器上的源和会话数据,因此您应该在测试运行之间重新启动服务器。
qrexec通信测试设置
如果您第一次生成使用qrexec进行API调用的新磁带,那么您需要按照以下步骤设置一个新的虚拟机来运行服务器和代理
-
根据
debian-10
模板创建一个名为sd-dev-proxy
的新AppVM。 -
安装最新的代理软件包
wget https://apt.freedom.press/pool/main/s/securedrop-proxy/<latest-package>.deb dpkg -i <latest-package>.deb
-
创建
/home/user/.securedrop_proxy/sd-proxy.yaml
,内容如下(假设您将运行SDK测试的虚拟机称为sd-dev
)host: 127.0.0.1 scheme: http port: 8081 target_vm: sd-dev dev: False
-
安装Docker。
-
在
sd-dev-proxy
上克隆securedrop
并运行Docker容器中的服务器git clone https://github.com/freedomofpress/securedrop cd securedrop virtualenv .venv --python=python3 source .venv/bin/activate pip install -r securedrop/requirements/python3/develop-requirements.txt NUM_SOURCES=5 make dev
-
在
sd-dev
上打开终端并创建/etc/sd-sdk.conf
,内容如下
[proxy]
name=sd-dev-proxy
- 在
dom0
中修改/etc/qubes-rpc/policy/securedrop.Proxy
,在文件顶部添加以下行,以便sdk测试可以调用代理
sd-dev sd-dev-proxy allow
注意:在dom0
中执行make test
运行之前,您可能想要切换回预配置的RPC配置文件,因为此更改和以下对RPC策略的更改将破坏那些测试中严格的RPC策略验证。
- 在
dom0
中修改/etc/qubes-rpc/policy/qubes.Filecopy
,在文件顶部添加以下行,以便代理可以通过qrexec将文件发送到sdk
sd-dev-proxy sd-dev allow
-
验证
sd-dev-proxy
和sd-dev
之间的qrexec通信是否设置正确。a. 如果服务器尚未运行,则在
sd-dev-proxy
上运行服务器NUM_SOURCES=5 make dev
b. 在
sd-dev
上检出此存储库的主要分支,在test_apiproxy.py::TestAPIProxy::setUp
方法上方注释掉@qrexec_datasaver
装饰器,以便test_api_auth
通过qrexec进行实际API调用。c. 运行test_api_auth
make test TESTS=tests/test_apiproxy.py::TestAPIProxy::test_api_auth
注意:如果测试失败,在尝试再次之前,在
dom0
中运行journalctl -f
,以查看是否拒绝sd-dev
和sd-dev-proxy
之间的通信。成功的日志看起来像这样Aug 28 15:45:13 dom0 qrexec[1474]: securedrop.Proxy: sd-dev -> sd-dev-proxy: allowed to sd-dev-proxy
发布
要发布,您应该
- 创建一个名为
release/$new_version_number
的分支 - 更新
CHANGELOG.md
和setup.py
- 提交更改。
- 创建一个PR,并让PR被审查并合并到
main
。 git tag $new_version_number
并推送新标签。- 在本地检出新标签。
- 按照以下文档推送新发布源tarball到PSF的PyPI:https://packaging.pythonlang.cn/tutorials/packaging-projects/#uploading-the-distribution-archives。在上传之前,请从
dist/
目录中删除wheel(通过在上传之前从目录中删除它)。 - 如果您想将新的SDK发布到FPF PyPI镜像,请转到
securedrop-debian-packaging
存储库,并按照build-a-package说明将包推送到我们的PyPI镜像:https://pypi.ac.cn/simple
贡献
请阅读CONTRIBUTING.md以了解我们的行为准则以及向我们提交拉取请求的过程。
版本控制
我们使用SemVer进行版本控制。有关可用的版本,请参阅此存储库上的标签。
许可证
Python SecureDrop SDK采用GPLv3许可。有关更多详细信息,请参阅LICENSE
。