Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(deps): update all minor dependencies #78

Merged
merged 15 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ AUTH_TOKENS = 'auth-token'

DOCUMENTS_BUCKET = 'development-notification-canada-ca-document-download'

MLWR_HOST=''
MLWR_USER=''
MLWR_KEY=''

HTTP_SCHEME = 'http'
BACKEND_HOSTNAME = 'localhost:7000'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/generate-sbom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0

- name: Generate app SBOM
uses: cds-snc/security-tools/.github/actions/generate-sbom@00801dc7049671a1a9bfa25a11ef2c2709ca78ed # v1
uses: cds-snc/security-tools/.github/actions/generate-sbom@4368a5486da1f0bb698ffe717687612d4231c6cd # v1.1.7
with:
dependency_track_api_key: ${{ secrets.DEPENDENCY_TRACK_API_KEY }}
project_name: notification-document-download-api/app
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
cp -f .env.example .env

- name: Checks for new endpoints against AWS WAF rules
uses: cds-snc/notification-utils/.github/actions/waffles@main
uses: cds-snc/notification-utils/.github/actions/waffles@d70335dbab2a1a6f12de99f9256b179312e2aef5 # 49.1.0
with:
app-loc: '/github/workspace'
app-libs: '/github/workspace/env/site-packages'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/s3-backup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fetch-depth: 0 # retrieve all history

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # tag=v1
uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # v1.7.0
with:
aws-access-key-id: ${{ secrets.AWS_S3_BACKUP_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_S3_BACKUP_SECRET_ACCESS_KEY }}
Expand Down
16 changes: 8 additions & 8 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
from app.utils.store import DocumentStore
from app.utils.antivirus import AntivirusClient

document_store = DocumentStore() # noqa, has to be imported before views
antivirus_client = AntivirusClient() # noqa
document_store = DocumentStore() # noqa, has to be imported before views
antivirus_client = AntivirusClient() # noqa

from .download.views import download_blueprint
from .upload.views import upload_blueprint
from .healthcheck import healthcheck_blueprint
from .download.views import download_blueprint # noqa
from .upload.views import upload_blueprint # noqa
from .healthcheck import healthcheck_blueprint # noqa


class Base64UUIDConverter(BaseConverter):
Expand All @@ -32,10 +32,10 @@ def to_url(self, value):


def create_app():
application = Flask('app', static_folder=None)
application.config.from_object(configs[os.environ['NOTIFY_ENVIRONMENT']])
application = Flask("app", static_folder=None)
application.config.from_object(configs[os.environ["NOTIFY_ENVIRONMENT"]])

application.url_map.converters['base64_uuid'] = Base64UUIDConverter
application.url_map.converters["base64_uuid"] = Base64UUIDConverter

request_helper.init_app(application)
logging.init_app(application)
Expand Down
54 changes: 25 additions & 29 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ class Config(metaclass=MetaFlaskEnv):
SECRET_KEY = os.getenv("SECRET_KEY", "secret-key")
AUTH_TOKENS = os.getenv("AUTH_TOKENS", "auth-token")

DOCUMENTS_BUCKET = os.getenv("DOCUMENTS_BUCKET", "development-notification-canada-ca-document-download")
DOCUMENTS_BUCKET = os.getenv(
"DOCUMENTS_BUCKET", "development-notification-canada-ca-document-download"
)

ALLOWED_MIME_TYPES = [
'application/pdf',
'application/CDFV2',
'text/csv',
'text/plain',
'application/msword', # .doc
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', # .docx
'image/jpeg',
'image/png',
'application/vnd.ms-excel', # .xls
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', # .xlsx
'application/vnd.apple.numbers', # "Numbers" app on macOS
"application/pdf",
"application/CDFV2",
"text/csv",
"text/plain",
"application/msword", # .doc
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", # .docx
"image/jpeg",
"image/png",
"application/vnd.ms-excel", # .xls
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", # .xlsx
"application/vnd.apple.numbers", # "Numbers" app on macOS
]
EXTRA_MIME_TYPES = os.getenv("EXTRA_MIME_TYPES", "")

Expand All @@ -39,28 +41,22 @@ class Config(metaclass=MetaFlaskEnv):
ANTIVIRUS_API_HOST = os.getenv("ANTIVIRUS_API_HOST", "http://localhost:6016")
ANTIVIRUS_API_KEY = os.getenv("ANTIVIRUS_API_KEY", "")

MLWR_HOST = os.getenv("MLWR_HOST", False)
MLWR_USER = os.getenv("MLWR_USER", "")
MLWR_KEY = os.getenv("MLWR_KEY", "")


class Test(Config):
DEBUG = True

# used during tests as a domain name
SERVER_NAME = 'document-download.test'

SECRET_KEY = 'test-secret'
AUTH_TOKENS = 'auth-token:test-token:test-token-2'
SERVER_NAME = "document-download.test"

DOCUMENTS_BUCKET = 'test-bucket'
SECRET_KEY = "test-secret"
AUTH_TOKENS = "auth-token:test-token:test-token-2"

ANTIVIRUS_API_HOST = 'https://test-antivirus'
ANTIVIRUS_API_KEY = 'test-antivirus-secret'
DOCUMENTS_BUCKET = "test-bucket"

BACKEND_HOSTNAME = 'localhost:7000'
ANTIVIRUS_API_HOST = "https://test-antivirus"
ANTIVIRUS_API_KEY = "test-antivirus-secret"

MLWR_HOST = "localhost"
BACKEND_HOSTNAME = "localhost:7000"


class Development(Config):
Expand All @@ -76,8 +72,8 @@ class Staging(Production):


configs = {
'test': Test,
'development': Development,
'staging': Staging,
'production': Production,
"test": Test,
"development": Development,
"staging": Staging,
"production": Production,
}
96 changes: 56 additions & 40 deletions app/download/views.py
Original file line number Diff line number Diff line change
@@ -1,83 +1,99 @@
from flask import Blueprint, abort, current_app, jsonify, make_response, request, send_file
from flask import (
Blueprint,
abort,
current_app,
jsonify,
make_response,
request,
send_file,
)
from notifications_utils.base64_uuid import base64_to_bytes

from app import document_store
from app.utils.store import DocumentStoreError

download_blueprint = Blueprint('download', __name__, url_prefix='')
download_blueprint = Blueprint("download", __name__, url_prefix="")


@download_blueprint.route('/services/<uuid:service_id>/documents/<uuid:document_id>', methods=['GET'])
@download_blueprint.route(
"/services/<uuid:service_id>/documents/<uuid:document_id>", methods=["GET"]
)
def download_document(service_id, document_id):
if 'key' not in request.args:
return jsonify(error='Missing decryption key'), 400
if "key" not in request.args:
return jsonify(error="Missing decryption key"), 400

filename = request.args.get('filename')
sending_method = request.args.get('sending_method', "link")
filename = request.args.get("filename")
sending_method = request.args.get("sending_method", "link")

try:
key = base64_to_bytes(request.args['key'])
key = base64_to_bytes(request.args["key"])
except ValueError:
return jsonify(error='Invalid decryption key'), 400
return jsonify(error="Invalid decryption key"), 400

try:
document = document_store.get(service_id, document_id, key, sending_method)
except DocumentStoreError as e:
current_app.logger.info(
'Failed to download document: {}'.format(e),
"Failed to download document: {}".format(e),
extra={
'service_id': service_id,
'document_id': document_id,
}
"service_id": service_id,
"document_id": document_id,
},
)
return jsonify(error=str(e)), 400

response = make_response(send_file(
document['body'],
mimetype=document['mimetype'],
# as_attachment can only be `True` if the filename is set
as_attachment=(filename is not None),
download_name=filename,
))
response.headers['Content-Length'] = document['size']
response.headers['X-Robots-Tag'] = 'noindex, nofollow'
response = make_response(
send_file(
document["body"],
mimetype=document["mimetype"],
# as_attachment can only be `True` if the filename is set
as_attachment=(filename is not None),
download_name=filename,
)
)
response.headers["Content-Length"] = document["size"]
response.headers["X-Robots-Tag"] = "noindex, nofollow"

return response


@download_blueprint.route('/d/<base64_uuid:service_id>/<base64_uuid:document_id>', methods=['GET'])
@download_blueprint.route(
"/d/<base64_uuid:service_id>/<base64_uuid:document_id>", methods=["GET"]
)
def download_document_b64(service_id, document_id):
if 'key' not in request.args:
if "key" not in request.args:
abort(404)

filename = request.args.get('filename')
sending_method = request.args.get('sending_method', 'link')
filename = request.args.get("filename")
sending_method = request.args.get("sending_method", "link")

try:
key = base64_to_bytes(request.args['key'])
key = base64_to_bytes(request.args["key"])
except ValueError:
abort(404)

try:
document = document_store.get(service_id, document_id, key, sending_method)
except DocumentStoreError as e:
current_app.logger.info(
'Failed to download document: {}'.format(e),
"Failed to download document: {}".format(e),
extra={
'service_id': service_id,
'document_id': document_id,
}
"service_id": service_id,
"document_id": document_id,
},
)
abort(404)

response = make_response(send_file(
document['body'],
mimetype=document['mimetype'],
# as_attachment can only be `True` if the filename is set
as_attachment=(filename is not None),
attachment_filename=filename,
))
response.headers['Content-Length'] = document['size']
response.headers['X-Robots-Tag'] = 'noindex, nofollow'
response = make_response(
send_file(
document["body"],
mimetype=document["mimetype"],
# as_attachment can only be `True` if the filename is set
as_attachment=(filename is not None),
download_name=filename,
)
)
response.headers["Content-Length"] = document["size"]
response.headers["X-Robots-Tag"] = "noindex, nofollow"

return response