Exemplo n.º 1
0
def new_phone_number(wallet, request):

    user = wallet.user

    if has_pending_phone_number_request(request, user):
        return httpexceptions.HTTPFound(request.resource_url(wallet, "confirm-phone-number"))

    schema = NewPhoneNumber().bind(request=request)

    b = deform.Button(name='process', title="Send verification code", css_class="btn-block btn-lg")
    form = deform.Form(schema, buttons=(b,))

    # User submitted this form
    if request.method == "POST":
        if 'process' in request.POST:

            try:
                appstruct = form.validate(request.POST.items())

                # Save form data from appstruct
                phone_number = normalize_international_phone_number(appstruct["phone_number"])

                assert phone_number, "Could not normalizer phone number: {}".format(appstruct["phone_number"])

                UserNewPhoneNumberConfirmation.require_confirmation(user, phone_number)

                return httpexceptions.HTTPFound(request.resource_url(wallet, "confirm-phone-number"))

            except deform.ValidationFailure as e:
                # Render a form version where errors are visible next to the fields,
                # and the submitted values are posted back
                rendered_form = e.render()
        else:
            # We don't know which control caused form submission
            raise httpexceptions.HTTPInternalServerError("Unknown form button pressed")
    else:
        # Render a form with initial values
        rendered_form = form.render()

    return locals()
Exemplo n.º 2
0
def new_phone_number(wallet, request):

    user = wallet.user

    if has_pending_phone_number_request(request, user):
        return httpexceptions.HTTPFound(request.resource_url(wallet, "confirm-phone-number"))

    schema = NewPhoneNumber().bind(request=request)

    b = deform.Button(name='process', title="Send verification code", css_class="btn-primary btn-block btn-lg")
    form = deform.Form(schema, buttons=(b,))

    # User submitted this form
    if request.method == "POST":
        if 'process' in request.POST:

            try:
                appstruct = form.validate(request.POST.items())

                # Save form data from appstruct
                phone_number = normalize_international_phone_number(appstruct["phone_number"])

                assert phone_number, "Could not normalizer phone number: {}".format(appstruct["phone_number"])

                UserNewPhoneNumberConfirmation.require_confirmation(user, phone_number)

                return httpexceptions.HTTPFound(request.resource_url(wallet, "confirm-phone-number"))

            except deform.ValidationFailure as e:
                # Render a form version where errors are visible next to the fields,
                # and the submitted values are posted back
                rendered_form = e.render()
        else:
            # We don't know which control caused form submission
            raise httpexceptions.HTTPInternalServerError("Unknown form button pressed")
    else:
        # Render a form with initial values
        rendered_form = form.render()

    return locals()
def test_confirm_user_phone_number_cancel(dbsession, user_id):
    """SMS confirmation success."""

    # Prepare confirmation
    with transaction.manager:
        user = dbsession.query(User).get(user_id)
        confirmation = UserNewPhoneNumberConfirmation.require_confirmation(user, "+15551231234")
        assert confirmation.created_at
        assert confirmation.confirmation_type == ManualConfirmationType.sms
        assert confirmation.state == ManualConfirmationState.pending
        assert UserNewPhoneNumberConfirmation.get_pending_confirmation(user)

    # Resolve confirmation and see user gets a phone number
    with transaction.manager:
        user = dbsession.query(User).get(user_id)
        confirmation = dbsession.query(UserNewPhoneNumberConfirmation).first()
        confirmation.cancel()

        assert confirmation.action_taken_at
        assert confirmation.state == ManualConfirmationState.cancelled
        assert "phone_number" not in user.user_data
        assert not UserNewPhoneNumberConfirmation.get_pending_confirmation(user)
def test_confirm_user_phone_number_success(dbsession, user_id):
    """SMS confirmation success."""

    # Prepare confirmation
    with transaction.manager:
        user = dbsession.query(User).get(user_id)
        confirmation = UserNewPhoneNumberConfirmation.require_confirmation(user, "+15551231234")
        assert confirmation.created_at
        assert confirmation.confirmation_type == ManualConfirmationType.sms
        assert confirmation.state == ManualConfirmationState.pending
        assert UserNewPhoneNumberConfirmation.get_pending_confirmation(user)

    # Resolve confirmation and see user gets a phone number
    with transaction.manager:
        user = dbsession.query(User).get(user_id)
        confirmation = dbsession.query(UserNewPhoneNumberConfirmation).first()
        code = confirmation.other_data["sms_code"]
        confirmation.resolve_sms(code, None)

        assert confirmation.action_taken_at
        assert confirmation.state == ManualConfirmationState.resolved
        assert user.user_data["phone_number"] == "+15551231234"
        assert not UserNewPhoneNumberConfirmation.get_pending_confirmation(user)
Exemplo n.º 5
0
    def inner(*args, **kwargs):
        context, request = args
        wallet = get_wallet(context)
        user = request.user

        if not user:
            messages.add(request, kind="warning", msg="Please sign in to view the page.")
            return httpexceptions.HTTPFound(request.route_url("home"))

        # Redirect user to the phone number confirmation
        if request.registry.settings.get("websauna.wallet.require_phone_number"):
            if not UserNewPhoneNumberConfirmation.has_confirmed_phone_number(user):
                return httpexceptions.HTTPFound(request.resource_url(wallet, "new-phone-number"))

        return func(*args, **kwargs)
Exemplo n.º 6
0
def test_ui_confirm_phone_number(require_phone_number,
                                 logged_in_wallet_user_browser: DriverAPI,
                                 dbsession: Session, mock_eth_service,
                                 test_request):
    """User needs a confirmed phone number before entering the wallet."""

    # Run functional tests against a Waitress web server running in another thread
    b = logged_in_wallet_user_browser
    b.find_by_css("#nav-wallet").click()

    assert b.is_element_present_by_css("#heading-new-phone-number")
    b.fill("phone_number", "+15551231234")
    b.find_by_css("button[type='submit']").click()

    # We arrived to SMS code verification page
    assert b.is_element_present_by_css("#heading-confirm-phone-number")

    # Peek into SMS code
    with transaction.manager:
        user = dbsession.query(User).first()
        confirmation = UserNewPhoneNumberConfirmation.get_pending_confirmation(
            user)
        sms_code = confirmation.other_data["sms_code"]

    # Get a dummy SMS backend that's configured in test fixtures
    backend = get_sms_backend(test_request)

    # Make sure code got out to the user
    msg = backend.get_last_message()
    assert sms_code in msg

    # Enter the code
    b.fill("code", sms_code)
    b.find_by_css("button[type='submit']").click()

    # We arrived to wallet overview
    assert b.is_element_present_by_css("#heading-wallet-overview")

    # We have a notification for phone number verified
    assert b.is_element_present_by_css("#msg-phone-confirmed")
def test_ui_confirm_phone_number(require_phone_number, logged_in_wallet_user_browser: DriverAPI, dbsession: Session, mock_eth_service, test_request):
    """User needs a confirmed phone number before entering the wallet."""

    # Run functional tests against a Waitress web server running in another thread
    b = logged_in_wallet_user_browser
    b.find_by_css("#nav-wallet").click()

    assert b.is_element_present_by_css("#heading-new-phone-number")
    b.fill("phone_number", "+15551231234")
    b.find_by_css("button[type='submit']").click()

    # We arrived to SMS code verification page
    assert b.is_element_present_by_css("#heading-confirm-phone-number")

    # Peek into SMS code
    with transaction.manager:
        user = dbsession.query(User).first()
        confirmation = UserNewPhoneNumberConfirmation.get_pending_confirmation(user)
        sms_code = confirmation.other_data["sms_code"]

    # Get a dummy SMS backend that's configured in test fixtures
    backend = get_sms_backend(test_request)

    # Make sure code got out to the user
    msg = backend.get_last_message()
    assert sms_code in msg

    # Enter the code
    b.fill("code", sms_code)
    b.find_by_css("button[type='submit']").click()

    # We arrived to wallet overview
    assert b.is_element_present_by_css("#heading-wallet-overview")

    # We have a notification for phone number verified
    assert b.is_element_present_by_css("#msg-phone-confirmed")
Exemplo n.º 8
0
 def manual_confirmation(self) -> UserNewPhoneNumberConfirmation:
     wallet = self.context
     return UserNewPhoneNumberConfirmation.get_pending_confirmation(wallet.user)
Exemplo n.º 9
0
 def manual_confirmation(self) -> UserNewPhoneNumberConfirmation:
     wallet = self.context
     return UserNewPhoneNumberConfirmation.get_pending_confirmation(wallet.user)