Add CSP file uploads

This commit is contained in:
richard-dds
2019-07-30 16:51:58 -04:00
parent e333f32aea
commit 8eba9a097d
11 changed files with 390 additions and 34 deletions

View File

@@ -30,6 +30,7 @@ from atst.utils.json import CustomJSONEncoder
from atst.queue import queue
from atst.utils.notification_sender import NotificationSender
from atst.utils.session_limiter import SessionLimiter
from atst.domain.csp.file_uploads import build_uploader
from logging.config import dictConfig
from atst.utils.logging import JsonFormatter, RequestContextFilter
@@ -78,6 +79,7 @@ def make_app(config):
app.register_blueprint(task_orders_bp)
app.register_blueprint(applications_bp)
app.register_blueprint(user_routes)
app.uploader = build_uploader(app.config)
if ENV != "prod":
app.register_blueprint(dev_routes)

View File

@@ -0,0 +1,66 @@
from azure.storage.common import CloudStorageAccount
from azure.storage.blob import ContainerPermissions
from datetime import datetime, timedelta
from uuid import uuid4
import boto3
def build_uploader(config):
if config["CSP"] == "aws":
return AwsUploader(config)
elif config["CSP"] == "azure":
return AzureUploader(config)
class Uploader:
def generate_token(self):
pass
def object_name(self):
return str(uuid4())
class AzureUploader(Uploader):
def __init__(self, config):
self.config = config
def get_token(self):
account = CloudStorageAccount(
account_name="atat", account_key=self.config["AZURE_STORAGE_KEY"]
)
bbs = account.create_block_blob_service()
object_name = self.object_name()
sas_token = bbs.generate_container_shared_access_signature(
"task-order-pdfs",
ContainerPermissions.WRITE,
datetime.utcnow() + timedelta(minutes=15),
)
return ({"token": sas_token}, object_name)
class AwsUploader(Uploader):
def __init__(self, config):
self.config = config
def get_token(self):
s3_client = boto3.client(
"s3",
aws_access_key_id=self.config["AWS_ACCESS_KEY_ID"],
aws_secret_access_key=self.config["AWS_SECRET_KEY"],
config=boto3.session.Config(
signature_version="s3v4", region_name=self.config["AWS_REGION_NAME"]
),
)
object_name = self.object_name()
presigned_post = s3_client.generate_presigned_post(
self.config["AWS_BUCKET_NAME"],
object_name,
ExpiresIn=3600,
Conditions=[
("eq", "$Content-Type", "application/pdf"),
("starts-with", "$x-amz-meta-filename", ""),
],
Fields={"Content-Type": "application/pdf", "x-amz-meta-filename": ""},
)
return (presigned_post, object_name)

View File

@@ -1,4 +1,14 @@
from flask import g, redirect, render_template, request as http_request, url_for
from flask import (
g,
redirect,
render_template,
request as http_request,
url_for,
current_app,
)
from azure.storage.common import CloudStorageAccount
from azure.storage.blob import ContainerPermissions
from datetime import datetime, timedelta
from . import task_orders_bp
from atst.domain.authz.decorator import user_can_access_decorator as user_can
@@ -10,7 +20,8 @@ from atst.utils.flash import formatted_flash as flash
def render_task_orders_edit(template, portfolio_id=None, task_order_id=None, form=None):
render_args = {}
result = current_app.uploader.get_token()
render_args = {"token": result[0], "object_name": result[1]}
if task_order_id:
task_order = TaskOrders.get(task_order_id)
@@ -89,6 +100,7 @@ def edit(task_order_id):
@task_orders_bp.route("/task_orders/<task_order_id>/form/step_1")
@user_can(Permissions.CREATE_TASK_ORDER, message="view task order form")
def form_step_one_add_pdf(portfolio_id=None, task_order_id=None):
return render_task_orders_edit(
"task_orders/step_1.html",
portfolio_id=portfolio_id,