Merge pull request #1005 from dod-ccpo/cloud-pdf-downloads

Cloud pdf downloads
This commit is contained in:
richard-dds
2019-08-30 16:11:27 -04:00
committed by GitHub
12 changed files with 159 additions and 25 deletions

View File

@@ -6,7 +6,10 @@ class Uploader:
def generate_token(self):
pass
def object_name(self):
def generate_download_link(self, object_name, filename) -> (dict, str):
pass
def object_name(self) -> str:
return str(uuid4())
@@ -17,6 +20,9 @@ class MockUploader(Uploader):
def get_token(self):
return ({}, self.object_name())
def generate_download_link(self, object_name, filename):
return ""
class AzureUploader(Uploader):
def __init__(self, config):
@@ -53,6 +59,23 @@ class AzureUploader(Uploader):
)
return ({"token": sas_token}, object_name)
def generate_download_link(self, object_name, filename):
account = self.CloudStorageAccount(
account_name=self.account_name, account_key=self.storage_key
)
bbs = account.create_block_blob_service()
sas_token = bbs.generate_blob_shared_access_signature(
self.container_name,
object_name,
permission=self.BlobPermissions.READ,
expiry=datetime.utcnow() + self.timeout,
content_disposition=f"attachment; filename={filename}",
protocol="https",
)
return bbs.make_blob_url(
self.container_name, object_name, protocol="https", sas_token=sas_token
)
class AwsUploader(Uploader):
def __init__(self, config):
@@ -87,7 +110,7 @@ class AwsUploader(Uploader):
presigned_post = s3_client.generate_presigned_post(
self.bucket_name,
object_name,
ExpiresIn=3600,
ExpiresIn=self.timeout_secs,
Conditions=[
("eq", "$Content-Type", "application/pdf"),
("starts-with", "$x-amz-meta-filename", ""),
@@ -95,3 +118,22 @@ class AwsUploader(Uploader):
Fields={"Content-Type": "application/pdf", "x-amz-meta-filename": ""},
)
return (presigned_post, object_name)
def generate_download_link(self, object_name, filename):
s3_client = self.boto3.client(
"s3",
aws_access_key_id=self.access_key_id,
aws_secret_access_key=self.secret_key,
config=self.boto3.session.Config(
signature_version="s3v4", region_name=self.region_name
),
)
return s3_client.generate_presigned_url(
"get_object",
Params={
"Bucket": self.bucket_name,
"Key": object_name,
"ResponseContentDisposition": f"attachment; filename={filename}",
},
ExpiresIn=self.timeout_secs,
)

View File

@@ -17,8 +17,11 @@ from atst.models.permissions import Permissions
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 = {}
def render_task_orders_edit(
template, portfolio_id=None, task_order_id=None, form=None, extra_args=None
):
render_args = extra_args or {}
if task_order_id:
task_order = TaskOrders.get(task_order_id)
portfolio_id = task_order.portfolio_id
@@ -72,7 +75,7 @@ def update_task_order(
)
@task_orders_bp.route("/task_orders/<portfolio_id>/upload-token")
@task_orders_bp.route("/task_orders/<portfolio_id>/upload_token")
@user_can(Permissions.CREATE_TASK_ORDER, message="edit task order form")
def upload_token(portfolio_id):
(token, object_name) = app.csp.files.get_token()
@@ -81,6 +84,18 @@ def upload_token(portfolio_id):
return jsonify(render_args)
@task_orders_bp.route("/task_orders/<portfolio_id>/download_link")
@user_can(Permissions.VIEW_TASK_ORDER_DETAILS, message="view task order download link")
def download_link(portfolio_id):
filename = http_request.args.get("filename")
object_name = http_request.args.get("objectName")
render_args = {
"downloadLink": app.csp.files.generate_download_link(object_name, filename)
}
return jsonify(render_args)
@task_orders_bp.route("/task_orders/<task_order_id>/edit")
@user_can(Permissions.CREATE_TASK_ORDER, message="edit task order form")
def edit(task_order_id):
@@ -219,11 +234,17 @@ def submit_form_step_three_add_clins(task_order_id):
def form_step_four_review(task_order_id):
task_order = TaskOrders.get(task_order_id)
extra_args = {
"pdf_download_url": app.csp.files.generate_download_link(
task_order.pdf.object_name, task_order.pdf.filename
)
}
if task_order.is_completed == False:
raise NoAccessError("task order form review")
return render_task_orders_edit(
"task_orders/step_4.html", task_order_id=task_order_id
"task_orders/step_4.html", task_order_id=task_order_id, extra_args=extra_args
)