def employees(request): """Get a licenses employees from Metrc. Args: request (HTTPRequest): A `djangorestframework` request. """ # Authenticate the user. claims = authenticate_request(request) if not claims: message = 'Authentication failed. Please use the console or provide a valid API key.' return Response({'error': True, 'message': message}, status=403) _, project_id = google.auth.default() license_number = request.query_params.get('name') # Optional: Figure out how to pre-initialize a Metrc client. # Get Vendor API key using secret manager. # FIXME: Determine where to store project_id, secret_id, and version_id. vendor_api_key = access_secret_version(project_id=project_id, secret_id='metrc_vendor_api_key', version_id='1') # TODO: Get user API key using secret manager. user_api_key = access_secret_version(project_id=project_id, secret_id=f'{license_number}_secret', version_id='1') # Create a Metrc client. track = authorize(vendor_api_key, user_api_key) # Make a request to the Metrc API. data = track.get_employees(license_number=license_number) # Return the requested data. return Response({'data': data}, content_type='application/json')
def initialize_traceability(project_id, license_number, version_id): """Initialize a Metrc client. Optional: Figure out how to pre-initialize and save Metrc client. """ # Get vendor version number. admin_data = get_document('admin/metrc') vendor_version_id = admin_data['vendor_api_key_secret']['version_id'] # Get Vendor API key using secret manager. vendor_api_key = access_secret_version( project_id=project_id, secret_id='metrc_vendor_api_key', version_id=vendor_version_id ) # Get user API key using secret manager. user_api_key = access_secret_version( project_id=project_id, secret_id=f'{license_number}_secret', version_id=version_id ) track = initialize_metrc(vendor_api_key, user_api_key) return track
def test_secret_manager(): """Test Secret Manager by creating a secret, updating the version of the secret, then deleting the secret.""" # Initialize Firebase env = environ.Env() env.read_env('../../.env') credentials = env('GOOGLE_APPLICATION_CREDENTIALS') os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = credentials firebase.initialize_firebase() # Mock license. license_data = { 'license_number': 'test', 'license_type': 'lab', 'state': 'OK', 'user_api_key': '123', } license_number = license_data['license_number'] user_api_key = license_data['user_api_key'] # Create a secret. project_id = 'cannlytics' secret_id = f'{license_number}-secret' try: version_id = firebase.create_secret(project_id, secret_id, user_api_key) except: # AlreadyExists error pass # Secret may already be created. # Add the secret's secret data. secret = firebase.add_secret_version(project_id, secret_id, user_api_key) version_id = secret.split('/')[-1] # Get the secret. # In production the secret ID and version ID are stored with the license data. user_api_key = firebase.access_secret_version(project_id, secret_id, version_id) assert user_api_key == license_data['user_api_key']
def unsubscribe(request): """Unsubscribe a user from a PayPal subscription.""" # Authenticate the user. claims = authenticate_request(request) try: uid = claims['uid'] user_email = claims['email'] except KeyError: response = {'success': False, 'message': 'Unable to authenticate.'} return JsonResponse(response) # Get the subscription they wish to unsubscribe from. data = loads(request.body) plan_name = data['plan_name'] # Unsubscribe the user with the PayPal SDK. try: project_id = os.environ['GOOGLE_CLOUD_PROJECT'] payload = access_secret_version(project_id, 'paypal', 'latest') paypal_secrets = loads(payload) paypal_client_id = paypal_secrets['client_id'] paypal_secret = paypal_secrets['secret'] paypal_access_token = get_paypal_access_token(paypal_client_id, paypal_secret) user_data = get_document(f'users/{uid}') subscription_id = user_data[f'{plan_name}_subscription_id'] cancel_paypal_subscription(paypal_access_token, subscription_id) updated_user_data = {'support': False} updated_user_data[f'{plan_name}_subscription_id'] = '' update_document(f'users/{uid}', updated_user_data) except: subscription_id = 'Unidentified' # Notify the staff. staff_message = """Confirm that the following subscription has been canceled: User: {} Email: {} Plan: {} Subscription ID: {} """.format(uid, user_email, plan_name, subscription_id) send_mail( subject='User unsubscribed from a PayPal subscription.', message=staff_message, from_email=DEFAULT_FROM_EMAIL, recipient_list=[DEFAULT_FROM_EMAIL], fail_silently=False, ) # Create an activity log. create_log( ref='logs/website/subscriptions', claims=claims, action=f'User ({user_email}) unsubscribed from {plan_name}.', log_type='subscription', key='subscribe', changes=data, ) # Return a success message. message = 'Successfully unsubscribed from subscription.' response = {'success': True, 'message': message} return JsonResponse(response)
def buy_data(request): """Facilitate the purchase of a dataset on the data market.""" # Ensure that the user has a valid email. data = loads(request.body) try: user_email = data['email'] validate_email(user_email) except ValidationError: response = { 'success': False, 'message': 'Invalid email in request body.' } return JsonResponse(response) # Check if the payment ID is valid. # FIXME: Make this required. try: payment_id = data['payment_id'] print('Checking payment ID:', payment_id) project_id = os.environ['GOOGLE_CLOUD_PROJECT'] payload = access_secret_version(project_id, 'paypal', 'latest') paypal_secrets = loads(payload) paypal_client_id = paypal_secrets['client_id'] paypal_secret = paypal_secrets['secret'] paypal_access_token = get_paypal_access_token(paypal_client_id, paypal_secret) payment = get_paypal_payment(paypal_access_token, payment_id) assert payment['id'] == payment_id print('Payment ID matched captured payment ID.') except: pass # Future work: Ensure that the user has a .edu email for student discount? # Get the dataset zipped folder. dataset = data['dataset'] file_name = dataset['file_name'] file_ref = dataset['file_ref'] download_url = get_file_url(file_ref) # Optional: Allow for specifying suffix options. short_url = create_short_url(FIREBASE_API_KEY, download_url, FIREBASE_PROJECT_ID) data['download_url'] = download_url data['short_url'] = short_url # Keep track of a user's downloaded data if the user is signed in. now = datetime.now() iso_time = now.isoformat() data['created_at'] = iso_time data['updated_at'] = iso_time try: claims = authenticate_request(request) uid = claims['uid'] update_document(f'users/{uid}/datasets', {**data, **{'uid': uid}}) except KeyError: pass # Optional: Read the email template from storage? # Optional: Use HTML template. # Optional: Load messages from state? # # template_url = 'website/emails/newsletter_subscription_thank_you.html' # Optional: Actually attach the datafile (too large a file problem?) # Email the data to the user. message = f'Congratulations on your new dataset,\n\nYou can access your data with the following link:\n\n{short_url}\n\nYou can monitor the market for new datasets.\n\nAlways here to help,\nThe Cannlytics Team' #pylint: disable=line-too-long subject = 'Dataset Purchased - Your Dataset is Attached' send_mail( subject=subject, message=message, from_email=DEFAULT_FROM_EMAIL, recipient_list=[user_email, DEFAULT_FROM_EMAIL], fail_silently=False, # html_message = render_to_string(template_url, {'context': 'values'}) ) # Create an activity log. create_log( ref='logs/website/payments', claims=claims, action=f'User ({user_email}) bought a dataset.', log_type='market', key='buy_data', changes=data, ) # Return the file to download. return FileResponse(open(download_url, 'rb'), filename=file_name)
env_file = os.path.join(BASE_DIR, '.env') # Attempt to load the Project ID into the environment, safely failing on error. try: _, os.environ['GOOGLE_CLOUD_PROJECT'] = google.auth.default() except google.auth.exceptions.DefaultCredentialsError: pass # Use a local secret file, if provided. # Otherwise retrieve the secrets from Secret Manager. if os.path.isfile(env_file): env.read_env(env_file) else: try: project_id = os.environ['GOOGLE_CLOUD_PROJECT'] payload = access_secret_version(project_id, SECRET_SETTINGS_NAME, 'latest') env.read_env(io.StringIO(payload)) except KeyError: raise Exception('No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.') # Access the secret key. SECRET_KEY = env('SECRET_KEY') # Get production status. When publishing, ensure PRODUCTION in .env is `True`. try: PRODUCTION = env('PRODUCTION') except: PRODUCTION = 'True' # Toggle Django debug mode if not in production. if PRODUCTION == 'True':