Skip to content

Commit

Permalink
Merge pull request #1746 from freedomofpress/merge-sdk
Browse files Browse the repository at this point in the history
Merge securedrop-sdk
  • Loading branch information
cfm authored Jan 4, 2024
2 parents 2bfba85 + 3845813 commit 0ac0b89
Show file tree
Hide file tree
Showing 100 changed files with 7,705 additions and 121 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: SDK
on: [push, pull_request]

defaults:
run:
shell: bash

jobs:
sdk-with-server:
runs-on: ubuntu-latest
env:
DOCKERIZE_VERSION: "v0.7.0"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: "freedomofpress/securedrop"
path: "securedrop-server"
- uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Install dependencies
run: |
pip install poetry==1.6.1
wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz &&
tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz &&
rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
- name: Run tests without VCR cassettes
run: |
# Start the server in the background
NUM_SOURCES=5 make -C securedrop-server dev &
# And install deps
poetry -C client install --no-ansi
# Wait for server to come up
dockerize -wait http://127.0.0.1:8080 -timeout 5m
# Run tests
rm client/tests/sdk/data/*.yml
make -C client test-sdk
7 changes: 6 additions & 1 deletion client/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ clean: ## Clean the workspace of generated resources
TESTS ?= tests
ITESTS ?= tests/integration
FTESTS ?= tests/functional
TESTOPTS ?= -v --cov-config .coveragerc --cov-report html --cov-report term-missing --cov=securedrop_client --cov-fail-under 100
STESTS ?= tests/sdk
TESTOPTS ?= -v --cov-config .coveragerc --cov-report html --cov-report term-missing --cov=securedrop_client --cov-fail-under 90
RANDOM_SEED ?= $(shell bash -c 'echo $$RANDOM')

.PHONY: test
Expand Down Expand Up @@ -104,6 +105,10 @@ test-integration: ## Run the integration tests
test-functional: ## Run the functional tests
@./test-functional.sh

.PHONY: test-sdk
test-sdk: ## Run just the sdk tests
@poetry run pytest -v $(STESTS)

.PHONY: lint
lint: ## Run the linters
@poetry run flake8 securedrop_client tests
Expand Down
1 change: 0 additions & 1 deletion client/build-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ markupsafe==2.0.1 --hash=sha256:e61445980f0dcd584d728844d8ad516c9e460bd71f53c14c
python-dateutil==2.7.5 --hash=sha256:2961735b604e5165d923a4e39b9bcbde6a4c363f257f5477b6339459fd7c1679
python-editor==1.0.3 --hash=sha256:42e5b2a7583cd278dff00ae1fc6b8b735da0502ceeb0914991eaaf5f91ac84ac
requests==2.31.0 --hash=sha256:9f7f0f507fe7a9e10ea51e666da60aafcfcda94c71f0cac477dbadd8d25de49f
securedrop-sdk==0.4.0 --hash=sha256:54b870fd3566914c2ba13aeb5c7eaa0be8ac128be72b45613843c0b75040bd39
six==1.11.0 --hash=sha256:eb52689b06ca7433c1cac3b91f320400bd3b358790b7ff4b6367cb1c81d37561
sqlalchemy==1.3.3 --hash=sha256:af3ec7384a7da692a0db1b807da2eb5bda1372a1eea2a8b26c2ff8ccc1bbf897 --hash=sha256:86ed1e4985a9fd4f3c784da1fcefb89f4435c1c70815f43e5741c0c9f3c79be3
urllib3==1.26.6 --hash=sha256:7a2814749409a681ab58babe6539b02a2f84f6649904211f90fb649811ae7b36
64 changes: 43 additions & 21 deletions client/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion client/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ alembic = "^1.1.0"
arrow = "^0.12.1"
python-dateutil = "^2.7.5"
requests = "^2.31.0"
securedrop-sdk = "^0.4.0"

[tool.poetry.group.dev.dependencies]
# In production these two are installed using a system package
Expand All @@ -38,6 +37,7 @@ isort = "*"
mypy = "^1.4.1"
polib = "*"
pyqt5-stubs = "*"
pyotp = "2.8.0"
pytest = "^7.2.0"
pytest-cov = "*"
pytest-mock = "*"
Expand All @@ -50,6 +50,7 @@ semgrep = "*"
translate-toolkit = "*"
types-polib = "*"
types-python-dateutil = "*"
types-requests = "^2.31.0"
types-setuptools = "^68.0.0"

[tool.black]
Expand Down
5 changes: 3 additions & 2 deletions client/securedrop_client/api_jobs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from typing import Any, Optional, TypeVar

from PyQt5.QtCore import QObject, pyqtSignal
from sdclientapi import API, AuthError, RequestTimeoutError, ServerConnectionError
from sqlalchemy.orm.session import Session

from securedrop_client.sdk import API, AuthError, RequestTimeoutError, ServerConnectionError

logger = logging.getLogger(__name__)

DEFAULT_NUM_ATTEMPTS = 5
Expand Down Expand Up @@ -67,7 +68,7 @@ class ApiJob(QueueJob):
def __init__(self, remaining_attempts: int = DEFAULT_NUM_ATTEMPTS) -> None:
super().__init__(remaining_attempts)

def _do_call_api(self, api_client: API, session: Session) -> None:
def _do_call_api(self, api_client: Optional[API], session: Session) -> None:
if not api_client:
raise ApiInaccessibleError()

Expand Down
6 changes: 3 additions & 3 deletions client/securedrop_client/api_jobs/downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
from tempfile import NamedTemporaryFile
from typing import Any, Optional, Tuple, Type, Union

from sdclientapi import API, BaseError
from sdclientapi import Reply as SdkReply
from sdclientapi import Submission as SdkSubmission
from sqlalchemy.orm.session import Session

from securedrop_client.api_jobs.base import SingleObjectApiJob
from securedrop_client.crypto import CryptoError, GpgHelper
from securedrop_client.db import DownloadError, DownloadErrorCodes, File, Message, Reply
from securedrop_client.sdk import API, BaseError
from securedrop_client.sdk import Reply as SdkReply
from securedrop_client.sdk import Submission as SdkSubmission
from securedrop_client.storage import (
mark_as_decrypted,
mark_as_downloaded,
Expand Down
2 changes: 1 addition & 1 deletion client/securedrop_client/api_jobs/seen.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import List

from sdclientapi import API
from sqlalchemy.orm.session import Session

from securedrop_client.api_jobs.base import ApiJob
from securedrop_client.sdk import API


class SeenJob(ApiJob):
Expand Down
6 changes: 3 additions & 3 deletions client/securedrop_client/api_jobs/sources.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import logging

import sdclientapi
from sdclientapi import API, RequestTimeoutError, ServerConnectionError
from sqlalchemy.orm.session import Session

from securedrop_client import sdk
from securedrop_client.api_jobs.base import ApiJob
from securedrop_client.sdk import API, RequestTimeoutError, ServerConnectionError

logger = logging.getLogger(__name__)

Expand All @@ -21,7 +21,7 @@ def call_api(self, api_client: API, session: Session) -> str:
Delete a source on the server
"""
try:
source_sdk_object = sdclientapi.Source(uuid=self.uuid)
source_sdk_object = sdk.Source(uuid=self.uuid)
api_client.delete_source(source_sdk_object)

return self.uuid
Expand Down
4 changes: 2 additions & 2 deletions client/securedrop_client/api_jobs/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
import os
from typing import Any, List, Optional

from sdclientapi import API
from sdclientapi import User as SDKUser
from sqlalchemy.orm.session import Session

from securedrop_client import state
from securedrop_client.api_jobs.base import ApiJob
from securedrop_client.db import DeletedUser, DraftReply, User
from securedrop_client.sdk import API
from securedrop_client.sdk import User as SDKUser
from securedrop_client.storage import get_remote_data, update_local_storage

logger = logging.getLogger(__name__)
Expand Down
6 changes: 3 additions & 3 deletions client/securedrop_client/api_jobs/updatestar.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import logging

import sdclientapi
from sdclientapi import API, RequestTimeoutError, ServerConnectionError
from sqlalchemy.orm.session import Session

from securedrop_client import sdk
from securedrop_client.api_jobs.base import SingleObjectApiJob
from securedrop_client.sdk import API, RequestTimeoutError, ServerConnectionError

logger = logging.getLogger(__name__)

Expand All @@ -21,7 +21,7 @@ def call_api(self, api_client: API, session: Session) -> str:
Star or Unstar an user on the server
"""
try:
source_sdk_object = sdclientapi.Source(uuid=self.uuid)
source_sdk_object = sdk.Source(uuid=self.uuid)

if self.is_starred:
api_client.remove_star(source_sdk_object)
Expand Down
8 changes: 4 additions & 4 deletions client/securedrop_client/api_jobs/uploads.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import logging
import os

import sdclientapi
from sdclientapi import API, RequestTimeoutError, ServerConnectionError
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm.session import Session

from securedrop_client import sdk
from securedrop_client.api_jobs.base import SingleObjectApiJob
from securedrop_client.crypto import GpgHelper
from securedrop_client.db import (
Expand All @@ -16,6 +15,7 @@
Source,
User,
)
from securedrop_client.sdk import API, RequestTimeoutError, ServerConnectionError
from securedrop_client.storage import update_draft_replies

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -151,8 +151,8 @@ def _set_status_to_failed(self, session: Session) -> None:
f"Unknown error when setting reply {self.reply_uuid} as failed, skipping: {e}"
)

def _make_call(self, encrypted_reply: str, api_client: API) -> sdclientapi.Reply:
sdk_source = sdclientapi.Source(uuid=self.source_uuid)
def _make_call(self, encrypted_reply: str, api_client: API) -> sdk.Reply:
sdk_source = sdk.Source(uuid=self.source_uuid)
return api_client.reply_source(sdk_source, encrypted_reply, self.reply_uuid)


Expand Down
Loading

0 comments on commit 0ac0b89

Please sign in to comment.