import binascii import json import requests from decouple import config from flask import Flask, request from flask_restful import Resource, Api from pyotp import TOTP from config import etcd_client as client, logging, APP_PORT from stripe_utils import StripeUtils app = Flask(__name__) api = Api(app) def check_otp(name, realm, token): try: data = { "auth_name": config("AUTH_NAME", ""), "auth_token": TOTP(config("AUTH_SEED", "")).now(), "auth_realm": config("AUTH_REALM", ""), "name": name, "realm": realm, "token": token, } except binascii.Error: return 400 response = requests.post( "{OTP_SERVER}{OTP_VERIFY_ENDPOINT}".format( OTP_SERVER=config("OTP_SERVER", ""), OTP_VERIFY_ENDPOINT=config("OTP_VERIFY_ENDPOINT", "verify/"), ), data=data, ) return response.status_code class ListProducts(Resource): @staticmethod def get(): products = client.get_prefix("/v1/products/", value_in_json=False) prod_dict = {} for p in products: prod_dict[p.key] = json.loads(p.value) logging.debug("Products = {}".format(prod_dict)) return prod_dict, 200 class AddProduct(Resource): @staticmethod def post(): data = request.json logging.debug("Got data: {}".format(str(data))) # TODO: Add validation product_key = "/v1/products/" product_value = { "name": data["product_name"], "description": data["product_description"], "type": data["product_type"], "price": data["product_price"], "recurring_duration": data["product_recurring_duration"], "recurring_duration_units": data["product_recurring_duration_units"] } logging.debug("Adding product data: {}".format(str(product_value))) client.put(product_key, product_value, value_in_json=True) return {"message": "Product {} created".format(data['product_name'])}, 200 class UserRegisterPayment(Resource): @staticmethod def post(): try: data = request.json logging.debug("Got data: {}".format(str(data))) otp_response = check_otp(data["name"], data["realm"], data["token"]) if otp_response != 200: return {"message": "Wrong Credentials"}, 403 stripe_utils = StripeUtils() stripe_customer = stripe_utils.get_stripe_customer_from_email( data["email"]) if stripe_customer is None: token_response = stripe_utils.get_token_from_card( data["number"], data["cvc"], data["expiry_month"], data["expiry_year"] ) if token_response["response"]: stripe_customer_resp = stripe_utils.create_customer( token_response["response"].id ) if stripe_customer_resp: stripe_customer = stripe_customer_resp["response"] else: logging.error("Could not get/create stripe_customer " "for {}".format(data["email"])) return {"message": "Error with card. Contact support"}, 400 else: logging.error("Could not get token for the card") return {"message": "Error with card. Contact support"}, 400 user_key = "/v1/users/{}/stripe_customer/".format(data["email"]) user_value = stripe_customer.id client.put(user_key, user_value, value_in_json=False) user_key = "/v1/users/{}/cards/".format(data["email"]) user_value = [token_response["response"].card.id] client.put(user_key, user_value, value_in_json=False) resp = stripe_utils.associate_customer_card(stripe_customer.id, token_response["response"].id) if resp["response"]: return {"message": "Card ending in {} registered as your payment " "soruce".format(data['card'].strip()[-4:]) }, 200 else: logging.error( "Unable to associate card " "{} with customer {}".format( token_response["response"].card.id, data["email"] ) ) return {"message": "Error with card. Contact support"}, 400 except KeyError as key_error: logging.error(str(key_error)) return {"message": "Missing parameters"}, 400 api.add_resource(ListProducts, "/product/list") api.add_resource(AddProduct, "/product/add") if __name__ == '__main__': app.run(host="::", port=APP_PORT, debug=True)