예제 #1
0
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():
예제 #2
0
        "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,
예제 #3
0
class AddressSchema(Schema):
    city = String()
    country = String()
    line1 = String()
    postal_code = String()
    state = String()
예제 #4
0
class TaxIdSchema(Schema):
    type = String()
    value = String()
예제 #5
0
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),
예제 #6
0
class ProductSchema(Schema):
    name = String()
    period = String(enum=["monthly", "yearly"])
    price = Int()
    product_listing_id = String(required=True)
    quantity = Int(required=True)
예제 #7
0
    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)
예제 #8
0
        """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)})
예제 #9
0
class ProductListing(Schema):
    product_listing_id = String(required=True)
    quantity = Int(required=True)
예제 #10
0
class CustomerInfo(Schema):
    email = String()
    name = String()
    payment_method_id = String()
    address = Nested(AddressSchema())
    tax_id = Nested(TaxIdSchema())
예제 #11
0
class SubscriptionRenewalSchema(Schema):
    subscription_id = String()
    should_auto_renew = Boolean()
예제 #12
0
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"])),
예제 #13
0

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],
)
예제 #14
0
            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)
예제 #15
0
class EntitlementSchema(Schema):
    type = String(required=True)
    is_enabled = Boolean(required=True)
예제 #16
0
        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
예제 #17
0
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),
예제 #18
0
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
예제 #19
0
class PurchaseTotalSchema(Schema):
    currency = String(required=True)
    subtotal = Int(required=True)
    tax = Int()
    total = Int(required=True)