"""Model representation of temporary AWS token.""" import json from boto import exception from oto import response from assets import config from assets.connectors import sentry from assets.connectors import sts def _to_dict(credentials): """Standardize AWS credentials dictionary to our convention. Args: credentials (dict): AWS credentials dictionary. Returns: dict: our convention for an AWS token. """ return { 'token': credentials['session_token'], 'aws_access_key_id': credentials['access_key'], 'aws_secret_access_key': credentials['secret_key'], 'expiration': credentials['expiration'] } def _prepare_iam_policy_s3(bucket, filename): """Modify the IAM policy to limit uploads to bucket and filename. Args: filename: Name of the file to put. Returns: dict: The IAM policy """ resource = 'arn:aws:s3:::{bucket}/{filename}.*'.format( bucket=bucket, filename=filename) return { 'Version': '2012-10-17', 'Statement': [ { 'Effect': 'Allow', 'Action': [ 's3:PutObject' ], 'Resource': resource } ] } def get_s3_token(filename, duration=900): """Generate session token for S3 Upload. Args: filename (string): Name of the file, sans extension to be uploaded. duration (int): session token lifetime, in seconds. Default is 900 seconds - 15 minutes. Returns: response.Response: containing credentials. """ connection = sts.connect_to_sts() if not connection: return response.create_fatal_response('sts_unavailable') try: credentials = connection.assume_role( role_arn=config.IAM_ROLE, role_session_name=filename, duration_seconds=duration, policy=json.dumps( _prepare_iam_policy_s3( config.RAW_ASSETS_BUCKET_NAME, filename))) credentials = _to_dict(credentials.credentials.to_dict()) return response.Response(credentials) except exception.BotoServerError as e: if sentry.sentry_client: sentry.sentry_client.captureException() return response.create_fatal_response('sts_token_generation_failure')