from flask import Blueprint, jsonify from flask_jwt_extended import get_current_user, create_access_token from webargs.fields import String from webargs.flaskparser import use_args from app.models import User from app.schemas import UserSchema auth_bp = Blueprint("auth", __name__) user_schema = UserSchema(exclude=("projects", )) @auth_bp.route("/auth/", methods=["POST"]) @use_args({ "email": String(required=True), "password": String(required=True) }, locations=("json", )) def login(args) -> Tuple[Any, int]: """ Authenticates a user using an email and password, returning an appropriate response. :param args: Dictionary object from webargs (a library that makes request arguments easier to use) containing the provided email and password. :return: Either a JSON error response (400 or 401), or a valid access token, plus the data of the authenticated user (200 OK). """ # If user is already authenticated, get_current_user() will return a truthy value # and immediately return a JSON response. if get_current_user():
"short": "ua", "name": "Canonical UA", }, "canonical-blender": { "short": "blender", "name": "Blender Support", }, "canonical-cube": { "short": "cube", "name": "Canonical CUBE", }, } @advantage_decorator(permission="user", response="html") @use_kwargs({"subscription": String(), "email": String()}, location="query") def advantage_view(**kwargs): open_subscription = kwargs.get("subscription", None) personal_account = None new_subscription_id = None new_subscription_start_date = None pending_purchase_id = None enterprise_contracts = {} previous_purchase_ids = {"monthly": "", "yearly": ""} total_enterprise_contracts = 0 monthly_info = { "total_subscriptions": 0, "has_monthly": False,
class AddressSchema(Schema): city = String() country = String() line1 = String() postal_code = String() state = String()
class TaxIdSchema(Schema): type = String() value = String()
class AddressSchema(Schema): city = String() country = String() line1 = String() postal_code = String() state = String() class TaxIdSchema(Schema): type = String() value = String() post_advantage_subscriptions = { "account_id": String(required=True), "period": String(enum=["monthly", "yearly"], required=True), "previous_purchase_id": String(required=True), "products": List(Nested(ProductSchema), required=True), "resizing": Boolean(), } cancel_advantage_subscriptions = { "account_id": String(required=True), "previous_purchase_id": String(required=True), "product_listing_id": String(required=True), } post_anonymised_customer_info = { "account_id": String(required=True), "address": Nested(AddressSchema, required=True),
class ProductSchema(Schema): name = String() period = String(enum=["monthly", "yearly"]) price = Int() product_listing_id = String(required=True) quantity = Int(required=True)
is_technical = False try: advantage_mapper.get_purchase_account("canonical-ua") except UAContractsUserHasNoAccount: pass except AccessForbiddenError: # only "technical" user are denied access to purchase account is_technical = True return flask.render_template( "advantage/index.html", is_technical=is_technical ) @shop_decorator(area="advantage", permission="user", response="json") @use_kwargs({"email": String()}, location="query") def get_user_subscriptions(advantage_mapper, **kwargs): email = kwargs.get("email") user_subscriptions = advantage_mapper.get_user_subscriptions(email) return flask.jsonify(to_dict(user_subscriptions)) @shop_decorator(area="advantage", permission="user", response="json") def get_account_users(advantage_mapper, **kwargs): try: account = advantage_mapper.get_purchase_account("canonical-ua") except UAContractsUserHasNoAccount: return flask.jsonify({"errors": "cannot find purchase account"}), 404 account_users = advantage_mapper.get_account_users(account_id=account.id)
"""Parse.""" return self.post_process( parser.parse(self.fields, request, locations=["view_args"])) def post_process(self, request_arguments): """Post process.""" for func in self.processors: func(request_arguments) return request_arguments search_request_parser = RequestParser( fields={ "page": Int(validate=Range(min=1), ), "from": Int( load_from="from", validate=Range(min=1), ), "size": Int( validate=Range(min=1), missing=10, ), "q": String(), # TODO: allow getting it from "query" maybe a Function }, processors=[build_pagination], ) create_request_parser = RequestParser() item_request_parser = RequestParser(fields={"id": String(required=True)})
class ProductListing(Schema): product_listing_id = String(required=True) quantity = Int(required=True)
class CustomerInfo(Schema): email = String() name = String() payment_method_id = String() address = Nested(AddressSchema()) tax_id = Nested(TaxIdSchema())
class SubscriptionRenewalSchema(Schema): subscription_id = String() should_auto_renew = Boolean()
class ProductListing(Schema): product_listing_id = String(required=True) quantity = Int(required=True) class CustomerInfo(Schema): email = String() name = String() payment_method_id = String() address = Nested(AddressSchema()) tax_id = Nested(TaxIdSchema()) account_purhcase = { "account_id": String(), "captcha_value": String(requied=True), "customer_info": Nested(CustomerInfo), "products": List(Nested(ProductListing), required=True), "previous_purchase_id": String(required=True), "marketplace": String( validate=validate.OneOf(["canonical-ua", "canonical-cube", "blender"]), required=True, ), "action": String(validate=validate.OneOf(["purchase", "resize", "trial"])),
class RequestParser: """RequestParser.""" def __init__(self, fields=None, processors=None, *args, **kwargs): """Constructor.""" self.fields = fields or {} self.processors = processors or [] def parse(self, *args, **kwargs): """Parse.""" return self.post_process( parser.parse(self.fields, request, *args, **kwargs)) def post_process(self, request_arguments, *args, **kwargs): """Post process.""" for func in self.processors: func(request_arguments) return request_arguments search_request_parser = RequestParser( fields={ "page": Int(validate=Range(min=1), missing=1), "from": Int(validate=Range(min=1)), "size": Int(validate=Range(min=1), missing=10), "q": String(missing=""), }, processors=[build_pagination], )
user = user_schema.load(request.get_json(), instance=user) user_schema.context.pop("user_id") except ValidationError as errors: return errors.messages, 422 db.session.commit() return jsonify(data=user_schema.dump(user)), 200 elif request.method == "DELETE": if user != get_user(): return make_resp(FORBIDDEN) db.session.delete(user) db.session.commit() return make_resp(({"msg": "success"}, 200)) @users_bp.route("/uniquity-check/username/", methods=["GET"]) @use_args({"username": String(required=True), "user_id": Integer(required=False)}, locations=("querystring",)) def username_check(args) -> Tuple[Any, int]: return jsonify( taken=User.query.filter( User.username == args.get("username", "").lower(), User.id != args.get("user_id", 0) ).first() is not None), 200 @users_bp.route("/uniquity-check/email/", methods=["GET"]) @use_args({"email": String(required=True), "user_id": Integer(required=False)}, locations=("querystring",)) def email_check(args) -> Tuple[Any, int]: return jsonify( taken=User.query.filter( User.email == args.get("email", "").lower(), User.id != args.get("user_id", 0)
class EntitlementSchema(Schema): type = String(required=True) is_enabled = Boolean(required=True)
if not request.is_json: return make_resp(NO_JSON) try: project_schema.context["project_id"] = project.id project = project_schema.load(request.get_json(), instance=project) project.last_modified = datetime.datetime.utcnow() project_schema.context.pop("project_id") except ValidationError as errors: return errors.messages, 422 db.session.commit() return jsonify(data=project_schema.dump(project)), 200 elif request.method == "DELETE": if project.user != get_user(): return make_resp(FORBIDDEN) db.session.delete(project) db.session.commit() return make_resp(({"msg": "success"}, 200)) @projects_bp.route("/uniquity-check/project-name/", methods=["GET"]) @use_args( { "name": String(required=True), "project_id": Integer(required=False) }, locations=("querystring", )) def project_name_check(args) -> Tuple[Any, int]: return jsonify(taken=Project.query.filter( Project.name == args.get("name", "").lower(), Project.id != args.get("project_id", 0)).first() is not None), 200
class AddressSchema(Schema): city = String() country = String() line1 = String() postal_code = String() state = String() class TaxIdSchema(Schema): type = String() value = String() post_advantage_subscriptions = { "account_id": String(required=True), "period": String(enum=["monthly", "yearly"], required=True), "previous_purchase_id": String(required=True), "products": List(Nested(ProductSchema), required=True), "resizing": Boolean(), "trialling": Boolean(), } cancel_advantage_subscriptions = { "account_id": String(required=True), "previous_purchase_id": String(required=True), "product_listing_id": String(required=True), } post_anonymised_customer_info = { "account_id": String(required=True),
from webapp.advantage.schemas import ( post_advantage_subscriptions, post_anonymised_customer_info, cancel_advantage_subscriptions, post_customer_info, ensure_purchase_account, post_payment_method, ) session = talisker.requests.get_session() @advantage_checks(check_list=["is_maintenance", "view_need_user"]) @use_kwargs({"subscription": String(), "email": String()}, location="query") def advantage_view(**kwargs): is_test_backend = kwargs.get("test_backend") api_url = kwargs.get("api_url") stripe_publishable_key = kwargs["stripe_publishable_key"] token = kwargs.get("token") open_subscription = kwargs.get("subscription", None) personal_account = None new_subscription_id = None new_subscription_start_date = None pending_purchase_id = None enterprise_contracts = {} previous_purchase_ids = {"monthly": "", "yearly": ""} total_enterprise_contracts = 0
class PurchaseTotalSchema(Schema): currency = String(required=True) subtotal = Int(required=True) tax = Int() total = Int(required=True)