def free(): update_profile(identity_id=session['primary_identity'], role='free_user') try: dynamoDB=boto3.resource('dynamodb', region_name=region) except ClientError as e: return error(500, "fail to connect to dynamoDB: "+str(e)) try: ann_table=dynamoDB.Table(app.config['AWS_DYNAMODB_ANNOTATIONS_TABLE']) except ClientError as e: return error(404, "Table not found: "+str(e)) try: response_from_table=ann_table.query(IndexName='user_id_index', KeyConditionExpression=Key('user_id').eq(session['primary_identity'])) except ClientError as e: error(500, str(e)) for item in response_from_table['Items']: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.update_item try: ann_table.update_item( Key={'job_id': item['job_id']}, UpdateExpression="SET user_role = :ud", ExpressionAttributeValues={':ud' : 'free_user'}, ConditionExpression=Key('user_role').eq('premium_user') ) except ClientError as e: return error(500,"fail to update job status in the target table: "+str(e)) return render_template('free.html')
def subscribe(): if (request.method == 'GET'): # Display form to get subscriber credit card info if (session.get('role') == "free_user"): return render_template('subscribe.html') else: return redirect(url_for('profile')) elif (request.method == 'POST'): # Process the subscription request token = str(request.form['stripe_token']).strip() # Create a customer on Stripe stripe.api_key = app.config['STRIPE_SECRET_KEY'] try: customer = stripe.Customer.create(card=token, plan="premium_plan", email=session.get('email'), description=session.get('name')) except Exception as e: app.logger.error(f"Failed to create customer billing record: {e}") return abort(500) # Update user role to allow access to paid features user_id = session['primary_identity'] update_profile(identity_id=user_id, role="premium_user") # Update role in the session session['role'] = "premium_user" # Request restoration of the user's data from Glacier # Add code here to initiate restoration of archived user data # Send message to request queue try: sns = boto3.resource('sns', region_name=app.config['AWS_REGION_NAME']) topic_name = app.config['AWS_SNS_RESTORE_TOPIC'] restore_topic = sns.Topic(topic_name) except (botocore.errorfactory.NotFoundException, botocore.errorfactory.InvalidParameterException) as e: return abort(500) restore_notification = {"user_id": user_id} # publish the notification try: response = restore_topic.publish( Message=json.dumps(restore_notification), MessageStructure='String', ) except (botocore.exceptions.ParamValidationError, botocore.exceptions.ClientError) as e: return abort(500) # Make sure you handle files not yet archived! # Display confirmation page return render_template('subscribe_confirm.html', stripe_customer_id=str(customer['id']))
def subscribe(): if request.method == 'GET': # show subscription form return render_template('subscribe.html') # https://stripe.com/docs/checkout/flask if request.method == 'POST': # set stripe api key stripe.api_key = app.config['STRIPE_SECRET_KEY'] # get stripe token stripe_token = request.form['stripe_token'] # get user email user_id = session['primary_identity'] user_profile = get_profile(identity_id=user_id) user_email = user_profile.email # create new customer in Stripe customer = stripe.Customer.create(email=user_email, source=stripe_token) # subscribe the customer subscription = stripe.Subscription.create( customer=customer.id, items=[{ 'plan': 'premium_plan' }], ) # update user role in Globus update_profile(identity_id=session['primary_identity'], role='premium_user') # connect to SNS try: sns = boto3.client('sns', region_name=app.config['AWS_REGION_NAME']) except Exception as e: print("There was error connecting to SNS: \n" + str(e)) return abort(500) # publish user id to SNS to request thaw for any archived files try: topic_arn = app.config['AWS_SNS_THAW_REQUESTS_TOPIC'] message = json.dumps(user_id) sns_response = sns.publish(TopicArn=topic_arn, Message=message) except Exception as e: print("There was error publishing a message to SNS: \n" + str(e)) return abort(500) # show subcription confirmation return render_template('subscribe_confirm.html', stripe_id=customer.id)
def subscribe(): user_id = session['primary_identity'] profile = get_profile(identity_id=user_id) if request.method == 'GET': if profile.role == 'premium_user': return render_template('subscribe_confirm.html') else: return render_template('subscribe.html') elif request.method == 'POST': # subscribe # https://pippinsplugins.com/stripe-integration-part-7-creating-and-storing-customers/ stripe_token = request.form.get('stripe_token') try: stripe.api_key = app.config['STRIPE_SECRET_KEY'] customer = stripe.Customer.create(email=profile.email, card=stripe_token, plan='premium_plan', description=user_id) # log the customer app.logger.info(customer) if __add_customer__(user_id, customer) is False: return page_not_found('error') # update database update_profile(identity_id=user_id, role='premium_user') data = { 'type': 'user', 'id': user_id, 'action': 'restore', 'url': request.url, 'email': profile.email } # publish subscription message __publish_archive_status__(data) return render_template('subscribe_confirm.html') except ClientError as e: return page_not_found(e) else: return page_not_found('error')
def subscribe_post(): user_id = session.get('primary_identity') profile = get_profile(identity_id=user_id) if profile.role == 'premium_user': abort(403) stripe.api_key = app.config['STRIPE_SECRET_KEY'] token = request.form['stripe_token'] customer = None # https://stripe.com/docs/api/customers/create?lang=python try: customer = stripe.Customer.create( source=token, # obtained with Stripe.js name=profile.name, email=profile.email) except Exception as e: abort(500) # https://stripe.com/docs/api/subscriptions/create try: subscription = stripe.Subscription.create(customer=customer['id'], items=[ { "plan": "premium_plan", }, ]) except Exception as e: abort(500) update_profile(identity_id=session['primary_identity'], role="premium_user") # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns.html#topic sns = boto3.resource('sns', region_name=app.config['AWS_REGION_NAME']) topic = sns.Topic(app.config['AWS_SNS_RESULTS_RESTORE_TOPIC']) data = {'user_id': user_id} try: topic.publish(TopicArn=app.config['AWS_SNS_RESULTS_RESTORE_TOPIC'], Message=json.dumps(data)) except ClientError as e: logging.error(e) abort(500) return render_template('subscribe_confirm.html', stripe_id=customer['id'])
def subscribe(): if (request.method == 'GET'): # Display form to get subscriber credit card info if (session.get('role') == "free_user"): return render_template('subscribe.html') else: return redirect(url_for('profile')) elif (request.method == 'POST'): # Process the subscription request token = str(request.form['stripe_token']).strip() # Create a customer on Stripe stripe.api_key = app.config['STRIPE_SECRET_KEY'] try: customer = stripe.Customer.create(card=token, plan="premium_plan", email=session.get('email'), description=session.get('name')) except Exception as e: app.logger.error(f"Failed to create customer billing record: {e}") return abort(500) # Update user role to allow access to paid features update_profile(identity_id=session['primary_identity'], role="premium_user") # Update role in the session session['role'] = "premium_user" # Request restoration of the user's data from Glacier # Add code here to initiate restoration of archived user data # Make sure you handle files not yet archived! client = boto3.client('sns', region_name=app.config['AWS_REGION_NAME']) restore_topic_arn = app.config['AWS_SNS_RESTORE_TOPIC'] data = {"user_id": session['primary_identity']} try: response = client.publish(TopicArn=restore_topic_arn, Message=json.dumps(data)) except ClientError as e: print("publish to sns results topic failed") # Display confirmation page return render_template('subscribe_confirm.html', stripe_customer_id=str(customer['id']))
def subscribe(): if request.method == "POST": # get token and stripe key token = request.form.get('stripe_token') stripe.api_key = app.config['STRIPE_SECRET_KEY'] cust = stripe.Customer.create(description="New customer" + session['primary_identity'], source=token) # update the user profile value from free to premium update_profile(identity_id=session['primary_identity'], role="premium_user") # dynamodb query dynamodb = boto3.resource('dynamodb', region_name=AWS_REGION) ann_table = dynamodb.Table(DYNAMO_TABLE) user_name = session.get('primary_identity') # accessing all jobs that belong to the current user all_annotations = ann_table.query( IndexName='user_id_index', KeyConditionExpression=Key('user_id').eq(user_name)) # as soon as an user subcribes to premium, the value of user role should be premium_user for item in all_annotations['Items']: job_id = item['job_id'] role_update = { 'user_role': { 'Value': "premium_user", 'Action': 'PUT' } } ann_table.update_item(Key={'job_id': job_id}, AttributeUpdates=role_update) return render_template('subscribe_confirm.html', stripe_id=cust.id) return render_template('subscribe.html')
def cancel_subscription(): user_id = session['primary_identity'] profile = get_profile(identity_id=user_id) try: if __delete_customer__(user_id) is False: return page_not_found('error') data = { 'type': 'user', 'id': user_id, 'action': 'archive', 'url': request.url, 'email': profile.email } # publish cancel subscription message, archive user's file __publish_archive_status__(data) update_profile(identity_id=user_id, role='free_user') return render_template('home.html') except ClientError as e: print(e) return page_not_found(e)
def subscribe(): # get stripe token # https://stripe.com/docs/api if request.get_data() is None: return error(404, "parameters not found!!!") info=request.get_data() info=info.decode('utf-8') stripe_token=info.split('=')[1] # create new customer try: stripe.api_key = app.config['STRIPE_SECRET_KEY'] response=stripe.Customer.create( description=key_pre, source=stripe_token # obtained with Stripe.js ) except: return error(500, 'fail to upgrade...') # update user role update_profile(identity_id=session['primary_identity'], role='premium_user') try: dynamoDB=boto3.resource('dynamodb', region_name=region) except ClientError as e: return error(500, "fail to connect to dynamoDB: "+str(e)) try: ann_table=dynamoDB.Table(app.config['AWS_DYNAMODB_ANNOTATIONS_TABLE']) except ClientError as e: return error(404, "Table not found: "+str(e)) try: response_from_table=ann_table.query(IndexName='user_id_index', KeyConditionExpression=Key('user_id').eq(session['primary_identity'])) except ClientError as e: error(500, str(e)) for item in response_from_table['Items']: try: ann_table.update_item( Key={'job_id': item['job_id']}, UpdateExpression="SET user_role = :ud", ExpressionAttributeValues={':ud' : 'premium_user'}, ConditionExpression=Key('user_role').eq('free_user') ) except ClientError as e: return error(500,"fail to update job status in the target table: "+str(e)) user_email=get_profile(identity_id=session['primary_identity']).email # send job_restore_request try: client=boto3.client('sns', region_name=region) except ClientError as e: error(500, str(e)) user_info={'user_id': session['primary_identity'], 'user_email': user_email} try: client.publish(Message=json.dumps({'default':json.dumps(user_info)}), MessageStructure='json',TopicArn=app.config['AWS_SNS_JOB_RESTORE_TOPIC']) except ClientError as e: error(500, str(e)) return render_template('subscribe_confirm.html', stripe_id=response['id'])
def premium_cancel(): #update profile in the database update_profile(identity_id=session['primary_identity'], role="free_user") return render_template('premium_cancel.html')
def subscribe(): #https://stripe.com/docs/ if request.method == 'POST': stripe.api_key = app.config['STRIPE_SECRET_KEY'] token = request.form['stripe_token'] # Create a Customer: user_id = session['primary_identity'] user_profile = get_profile(identity_id=session['primary_identity']) user_email = user_profile.email customer = stripe.Customer.create( source=token, email=user_email, ) # Create the Subscription stripe.Subscription.create(customer=customer.id, items=[ { "plan": "premium_plan", "quantity": 1, }, ]) #update profile in the database update_profile(identity_id=session['primary_identity'], role="premium_user") #initiate archival restoration jobs #connect to the dynamodb database dynamodb = boto3.resource('dynamodb', region_name=app.config['AWS_REGION_NAME']) ann_table = dynamodb.Table( app.config['AWS_DYNAMODB_ANNOTATIONS_TABLE']) #query dynamodb for all user's jobs try: response = ann_table.query( IndexName='user_id_index', KeyConditionExpression=Key('user_id').eq(user_id)) except Exception: print('Error: failed to retrieve user job list') return abort(500) data = response.get('Items') #update user role on all user's jobs in the database for item in data: ann_table.update_item( Key={'job_id': item['job_id']}, UpdateExpression='SET user_role = :val1', ExpressionAttributeValues={':val1': 'premium_user'}) #find all archived jobs and retrieve their archive id's archived_job_list = [] for item in data: if item['archived'] == 'true': job_details = { 'job_id': None, 'results_file_archive_id': None, 's3_key_result_file': None } job_details['job_id'] = item['job_id'] job_details['results_file_archive_id'] = item[ 'results_file_archive_id'] job_details['s3_key_result_file'] = item['s3_key_result_file'] archived_job_list.append(job_details) #initiate restoration from Glacier glacier_client = boto3.client( 'glacier', region_name=app.config['AWS_REGION_NAME']) for job in archived_job_list: try: response = glacier_client.initiate_job( vaultName=app.config['AWS_GLACIER_VAULT'], jobParameters={ 'Type': 'archive-retrieval', 'Description': job['s3_key_result_file'], 'ArchiveId': job['results_file_archive_id'], 'SNSTopic': app.config['AWS_SNS_RETRIEVAL_TOPIC'], 'Tier': 'Expedited' }) except Exception: print('Error: failed to initiate retrieval job') return abort(500) #update dynamodb entry, indicating that the results files are being retrieved and the user is now premium ann_table.update_item( Key={'job_id': job['job_id']}, UpdateExpression='SET archived = :val1', ExpressionAttributeValues={':val1': 'retrieval in progress'}) print('file ' + job['s3_key_result_file'] + ' is being retrieved from Glacier') customer_id = customer.id print("successfully charged customer ID " + customer_id) return render_template('subscribe_confirm.html', stripe_id=customer_id) else: return render_template('subscribe.html')
def unsubscribe(): # Hacky way to reset the user's role to a free user; simplifies testing update_profile(identity_id=session['primary_identity'], role="free_user") return redirect(url_for('profile'))
def free_user(): update_profile(identity_id=session['primary_identity'], role='free_user') return "User role has been updated to: free_user."
def subscribe(): #if it is a get request, display signup form if request.method == 'GET': return render_template('subscribe.html') #if it is a post request, subscribe user and display confirmation elif request.method == 'POST': #extract the stripe token token = request.form['stripe_token'] #get profile information profile = get_profile(session.get('primary_identity')) name = profile.name email = profile.email #create customer description description = 'Customer profile for ' + name #set API key stripe.api_key = app.config['STRIPE_SECRET_KEY'] #create customer #source: https://stripe.com/docs/api#create_customer customer = stripe.Customer.create(description=description, email=email, source=token) #pass stripe_id stripe_id = customer.id app.logger.info('Customer ID: ' + stripe_id) #subscribe customer to plan #source: https://stripe.com/docs/api#create_subscription subscription = stripe.Subscription.create( customer=stripe_id, items=[{ 'plan': 'premium_plan' }], ) #update profile update_profile(identity_id=session['primary_identity'], role='premium_user') #test to make sure profile = get_profile(session.get('primary_identity')) app.logger.info('New profile status: ' + profile.role) #set Dynamo resource dynamodb = boto3.resource('dynamodb', region_name=app.config['AWS_REGION_NAME']) ann_table = dynamodb.Table('jgoode_annotations') #set glacier resource glacier = boto3.client('glacier', region_name='us-east-1') # Query database to get list of annotations, indexed on userID user_id = session.get('primary_identity') query = ann_table.query( IndexName='user_id_index', Select='ALL_ATTRIBUTES', KeyConditionExpression=Key('user_id').eq(user_id)) annotations = query['Items'] #iterate list of user's jobs, update each item to premium status for job in annotations: #update status to premium ann_table.update_item( Key={ 'job_id': job['job_id'], }, UpdateExpression="SET #R = :a", ExpressionAttributeNames={'#R': 'role'}, ExpressionAttributeValues={ ':a': 'premium_user', #results bucket }) #initiate glacier retrieval for all files #http://boto3.readthedocs.io/en/latest/reference/services/glacier.html#Glacier.Client.initiate_job #try expedited try: glacier.initiate_job( vaultName='ucmpcs', jobParameters={ 'Type': 'archive-retrieval', 'ArchiveId': job['results_file_archive_id'], 'Tier': 'Expedited', 'SNSTopic': 'arn:aws:sns:us-east-1:127134666975:jgoode_glacier_retrieval', }) # update status to RETRIEVING # http://boto3.readthedocs.io/en/latest/reference/services/dynamodb.html#DynamoDB.Table.update_item ann_table.update_item( Key={ 'job_id': job_id, }, UpdateExpression= "set results_file_archive_id = :a, archive_status = :b", ExpressionAttributeValues={ ':a': archive_id, ':b': 'RETRIEVING' } #archive ID ) #otherwise try standard speed (3-5 hrs) except: glacier.initiate_job( vaultName='ucmpcs', jobParameters={ 'Type': 'archive-retrieval', 'ArchiveId': job['results_file_archive_id'], 'Tier': 'Standard', 'SNSTopic': 'arn:aws:sns:us-east-1:127134666975:jgoode_glacier_retrieval', }) # update status to RETRIEVING ann_table.update_item( Key={ 'job_id': job_id, }, UpdateExpression= "set results_file_archive_id = :a, archive_status = :b", ExpressionAttributeValues={ ':a': archive_id, ':b': 'RETRIEVING' } #archive ID ) #return template return render_template('subscribe_confirm.html', stripe_id=stripe_id)
def cancel_premium(): role = get_profile(identity_id=session['primary_identity']).role if role == 'premium_user': update_profile(identity_id=session['primary_identity'], role="free_user") return render_template('cancel.html')
def subscribe(): # Extract user id user_id = session['primary_identity'] # Mehtod GET if request.method == 'GET': role = get_profile(identity_id=user_id).role if role == 'free_user': return render_template('subscribe.html', success=True) else: return render_template('subscribe.html', success=False) # Method POST else: stripe.api_key = app.config['STRIPE_SECRET_KEY'] stripe_token = request.form.get('stripe_token') username = get_profile(identity_id=user_id).name stripe_response = stripe.Customer.create( email=get_profile(identity_id=user_id).email, source=stripe_token, description=username) update_profile(identity_id=user_id, role='premium_user') dynamodb = boto3.resource('dynamodb', region_name=app.config['AWS_REGION_NAME']) ann_table = dynamodb.Table( app.config['AWS_DYNAMODB_ANNOTATIONS_TABLE']) response = ann_table.query( IndexName='user_id-index', KeyConditionExpression=Key('user_id').eq( session['primary_identity']) ) #,Select='SPECIFIC_ATTRIBUTES', ProjectionExpression='job_id, submit_time, input_file_name, job_status') items = response['Items'] # Access Glacier glacier = boto3.client('glacier', region_name=app.config['AWS_REGION_NAME']) for item in items: if 'results_file_archiveId' in item: archiveId = item['results_file_archiveId'] init_response = glacier.initiate_job( accountId='-', jobParameters={ 'SNSTopic': app.config['AWS_SNS_JOB_RETRIEVAL_TOPIC'], 'Tier': 'Expedited', 'Type': 'archive-retrieval', 'ArchiveId': archiveId }, vaultName=app.config['AWS_GLACIER_VAULT']) print(f'Initial Job: {init_response}') elif 'complete_time' in item: if time.time() - float(item['complete_time']) <= 180: sns = boto3.client( 'sns', region_name=app.config['AWS_REGION_NAME']) message = json.dumps({'cancel': item['job_id']}) response = sns.publish( TopicArn=app.config['AWS_SNS_JOB_GLACIER_TOPIC'], Message=message) return render_template('subscribe_confirm.html', stripe_id=stripe_response['id'])