Exemple #1
0
def do_password_change(request):
    localizer = request.localizer
    token = request.matchdict.get('ticket')
    (verified, user_id) = verify_password_change_token(token, 24)

    if not verified:
        if not user_id:
            raise HTTPBadRequest(localizer.translate(_(
                "Wrong password token.")))
        else:
            return HTTPFound(location=maybe_contextual_route(
                request, 'password_change_sent', profile_id=user_id, _query=dict(
                    sent=True, error=localizer.translate(_(
                        "This token is expired. "
                        "Do you want us to send another?")))))
    user = User.get(user_id)
    headers = remember(request, user_id)
    request.response.headerlist.extend(headers)
    user.last_login = datetime.utcnow()
    slug = request.matchdict.get('discussion_slug', None)
    slug_prefix = "/" + slug if slug else ""
    return dict(
        get_default_context(request),
        slug_prefix=slug_prefix,
        title=localizer.translate(_('Change your password')))
Exemple #2
0
def do_password_change(request):
    localizer = request.localizer
    token = request.matchdict.get('ticket')
    (verified, user_id) = verify_password_change_token(token, 24)

    if not verified:
        if not user_id:
            raise HTTPBadRequest(
                localizer.translate(_("Wrong password token.")))
        else:
            return HTTPFound(location=maybe_contextual_route(
                request,
                'password_change_sent',
                profile_id=user_id,
                _query=dict(sent=True,
                            error=localizer.translate(
                                _("This token is expired. "
                                  "Do you want us to send another?")))))
    user = User.get(user_id)
    headers = remember(request, user_id)
    request.response.headerlist.extend(headers)
    user.last_login = datetime.utcnow()
    slug = request.matchdict.get('discussion_slug', None)
    slug_prefix = "/" + slug if slug else ""
    return dict(get_default_context(request),
                slug_prefix=slug_prefix,
                title=localizer.translate(_('Change your password')))
Exemple #3
0
def do_password_change(request):
    token = request.json_body.get('token') or ''
    password = request.json_body.get('password') or ''
    # TODO: Check password quality!
    localizer = request.localizer
    user, validity = verify_password_change_token(token)
    token_date = get_data_token_time(token)
    old_token = (
        user is None or token_date is None or (
            user.last_login and token_date < user.last_login))

    if (validity != Validity.VALID or old_token):
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(_(
                "This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(_(
                "This link has been used. Do you want us to send another?"))
        raise JSONError(error, validity)
    user.password_p = password
    user.last_login = datetime.utcnow()
    headers = remember(request, user.id)
    request.response.headerlist.extend(headers)
    return HTTPOk()
Exemple #4
0
def do_password_change(request):
    token = request.json_body.get('token') or ''
    password1 = request.json_body.get('password1', '').strip()
    password2 = request.json_body.get('password2', '').strip()
    localizer = request.localizer
    if password1 is '' or password2 is '' or password2 != password1:
        error = localizer.translate(
            _("The passwords that were entered are mismatched!"))
        raise JSONError(error, ErrorTypes.PASSWORD)

    # TODO: Check password quality!
    user, validity = verify_password_change_token(token)
    token_date = get_data_token_time(token)
    old_token = (user is None or token_date is None
                 or (user.last_login and token_date < user.last_login))

    if (validity != Validity.VALID or old_token):
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(
                _("This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(
                _("This link has been used. Do you want us to send another?"))
        raise JSONError(error, validity)
    user.password_p = password1
    user.successful_login()
    headers = remember(request, user.id)
    request.response.headerlist.extend(headers)
    return HTTPOk()
Exemple #5
0
def finish_password_change(request):
    localizer = request.localizer
    token = request.params.get('token')
    title = request.params.get('title')
    welcome = asbool(request.params.get('welcome'))
    discussion = discussion_from_request(request)
    if welcome:
        title = localizer.translate(
            _('Welcome to {discussion_topic}.')).format(
                discussion_topic=discussion.topic if discussion else "Assembl")
    else:
        title = localizer.translate(_('Change your password'))

    user, validity = verify_password_change_token(token)
    logged_in = request.authenticated_userid  # if mismatch?
    if user and user.id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    token_date = get_data_token_time(token)
    old_token = (user is None or token_date is None
                 or (user.last_login and token_date < user.last_login))

    if (validity != Validity.VALID or old_token) and not logged_in:
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(
                _("This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(
                _("This link has been used. Do you want us to send another?"))
        request.session.flash(error)
        return HTTPFound(location=maybe_contextual_route(
            request,
            'request_password_change',
            _query=dict(user_id=user.id if user else '')))

    error = None
    p1, p2 = (request.params.get('password1', '').strip(),
              request.params.get('password2', '').strip())
    if p1 != p2:
        error = localizer.translate(_('The passwords are not identical'))
    elif p1:
        user.password_p = p1
        user.successful_login()
        headers = remember(request, user.id)
        request.response.headerlist.extend(headers)
        if discussion:
            maybe_auto_subscribe(user, discussion)
        request.session.flash(localizer.translate(_("Password changed")),
                              'message')
        return HTTPFound(location=request.route_url(
            'home' if discussion else 'discussion_list',
            discussion_slug=discussion.slug))

    return dict(get_default_context(request),
                title=title,
                token=token,
                error=error)
Exemple #6
0
def do_password_change(request):
    token = request.json_body.get('token') or ''
    password1 = request.json_body.get('password1', '').strip()
    password2 = request.json_body.get('password2', '').strip()
    localizer = request.localizer
    if password1 is '' or password2 is '' or password2 != password1:
        error = localizer.translate(
            _("The passwords that were entered are mismatched!"))
        raise JSONError(error, ErrorTypes.PASSWORD)

    # TODO: Check password quality!
    user, validity = verify_password_change_token(token)
    token_date = get_data_token_time(token)
    old_token = (
        user is None or token_date is None or (
            user.last_login and token_date < user.last_login))

    if (validity != Validity.VALID or old_token):
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(_(
                "This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(_(
                "This link has been used. Do you want us to send another?"))
        raise JSONError(error, validity)
    user.password_p = password1
    user.successful_login()
    headers = remember(request, user.id)
    request.response.headerlist.extend(headers)
    return HTTPOk()
Exemple #7
0
def finish_password_change(request):
    localizer = request.localizer
    token = request.params.get('token')
    title = request.params.get('title')
    welcome = asbool(request.params.get('welcome'))
    discussion = discussion_from_request(request)
    if welcome:
        title = localizer.translate(_(
            'Welcome to {discussion_topic}.')).format(
            discussion_topic=discussion.topic if discussion else "Assembl")
    else:
        title = localizer.translate(_('Change your password'))

    user, validity = verify_password_change_token(token)
    logged_in = request.authenticated_userid  # if mismatch?
    if user and user.id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    token_date = get_data_token_time(token)
    old_token = (
        user is None or token_date is None or (
            user.last_login and token_date < user.last_login))

    if (validity != Validity.VALID or old_token) and not logged_in:
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(_(
                "This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(_(
                "This link has been used. Do you want us to send another?"))
        request.session.flash(error)
        return HTTPFound(location=maybe_contextual_route(
            request, 'request_password_change', _query=dict(
                user_id=user.id if user else '')))

    error = None
    p1, p2 = (request.params.get('password1', '').strip(),
              request.params.get('password2', '').strip())
    if p1 != p2:
        error = localizer.translate(_('The passwords are not identical'))
    elif p1:
        user.password_p = p1
        user.successful_login()
        headers = remember(request, user.id)
        request.response.headerlist.extend(headers)
        if discussion:
            maybe_auto_subscribe(user, discussion)
        request.session.flash(localizer.translate(_(
            "Password changed")), 'message')
        return HTTPFound(location=request.route_url(
            'home' if discussion else 'discussion_list',
            discussion_slug=discussion.slug))

    return dict(
        get_default_context(request),
        title=title, token=token, error=error)
Exemple #8
0
def setup_change_password(user, password):
    old_password = user.password
    token = password_change_token(user)
    password_change_payload = {"token": token,
                                "password1": password,
                                "password2": password}
    user, validity = verify_password_change_token(token)
    assert validity == Validity.VALID

    return old_password, password_change_payload
Exemple #9
0
def finish_password_change(request):
    localizer = request.localizer
    token = request.params.get('token')
    title = request.params.get('title')
    user, validity = verify_password_change_token(token)
    logged_in = authenticated_userid(request)  # if mismatch?
    if user and user.id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    token_date = get_data_token_time(token)
    old_token = (
        user is None or token_date is None or (
            user.last_login and token_date < user.last_login))

    if (validity != Validity.VALID or old_token) and not logged_in:
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(_(
                "This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(_(
                "This link has been used. Do you want us to send another?"))

        return HTTPFound(location=maybe_contextual_route(
            request, 'request_password_change', _query=dict(
                user_id=user.id if user else '',
                error=error)))

    discussion_slug = request.matchdict.get('discussion_slug', None)
    error = None
    p1, p2 = (request.params.get('password1', '').strip(),
              request.params.get('password2', '').strip())
    if p1 != p2:
        error = localizer.translate(_('The passwords are not identical'))
    elif p1:
        user.password_p = p1
        user.last_login = datetime.utcnow()
        headers = remember(request, user.id)
        request.response.headerlist.extend(headers)
        if discussion_slug:
            discussion = discussion_from_request(request)
            maybe_auto_subscribe(user, discussion)
        return HTTPFound(location=request.route_url(
            'home' if discussion_slug else 'discussion_list',
            discussion_slug=discussion_slug,
            _query=dict(
                message=localizer.translate(_(
                    "Password changed")))))

    slug_prefix = "/" + discussion_slug if discussion_slug else ""
    return dict(
        get_default_context(request),
        title=title, slug_prefix=slug_prefix, token=token, error=error)
Exemple #10
0
def finish_password_change(request):
    localizer = request.localizer
    token = request.params.get('token')
    title = request.params.get('title')
    user, validity = verify_password_change_token(token)
    logged_in = authenticated_userid(request)  # if mismatch?
    if user and user.id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    token_date = get_data_token_time(token)
    old_token = (
        user is None or token_date is None or (
            user.last_login and token_date < user.last_login))

    if (validity != Validity.VALID or old_token) and not logged_in:
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(_(
                "This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(_(
                "This link has been used. Do you want us to send another?"))

        return HTTPFound(location=maybe_contextual_route(
            request, 'request_password_change', _query=dict(
                user_id=user.id if user else '',
                error=error)))

    discussion_slug = request.matchdict.get('discussion_slug', None)
    error = None
    p1, p2 = (request.params.get('password1', '').strip(),
              request.params.get('password2', '').strip())
    if p1 != p2:
        error = localizer.translate(_('The passwords are not identical'))
    elif p1:
        user.password_p = p1
        user.last_login = datetime.utcnow()
        headers = remember(request, user.id)
        request.response.headerlist.extend(headers)
        if discussion_slug:
            discussion = discussion_from_request(request)
            maybe_auto_subscribe(user, discussion)
        return HTTPFound(location=request.route_url(
            'home' if discussion_slug else 'discussion_list',
            discussion_slug=discussion_slug,
            _query=dict(
                message=localizer.translate(_(
                    "Password changed")))))

    slug_prefix = "/" + discussion_slug if discussion_slug else ""
    return dict(
        get_default_context(request),
        title=title, slug_prefix=slug_prefix, token=token, error=error)
Exemple #11
0
def test_change_password_token(test_app, participant1_user):
    # Set up
    old_password = participant1_user.password
    token = password_change_token(participant1_user)
    my_json = {"token": token, "password1": "lolo", "password2": "lolo"}

    # Test token
    user, validity = verify_password_change_token(token)
    assert validity == Validity.VALID

    # Test API
    response = test_app.post_json('/data/AgentProfile/do_password_change',
                                  my_json)
    assert response.status_code == 200
    assert old_password != participant1_user.password
    assert participant1_user.check_password("lolo") == True
Exemple #12
0
def do_password_change(request):
    "Validate the change_password token, and react accordingly."
    # Codes below refer to those cases:
    # V. token Valid(+) or invalid(-)? (Possibly expired through internal date)
    # P. user has(+) a Password or not (-)?
    # W. Welcome(+) vs change password(-)
    # B. last login absent, or Before token created (+) vs last login after token created (-)
    # L. user is already Logged in(+) or not(-)?

    welcome = 'welcome' in request.matched_route.name
    localizer = request.localizer
    discussion = discussion_from_request(request)
    token = request.matchdict.get('token')
    user, validity = verify_password_change_token(token)
    logged_in = authenticated_userid(request)
    if user and user.id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    lacking_password = user is not None and user.password is None
    token_date = get_data_token_time(token)
    old_token = (
        user is None or token_date is None or (
            user.last_login and token_date < user.last_login))
    print "pwc V%sP%sW%sB%sL%s" % tuple(map(lambda b: "-" if b else "+", (
        validity != Validity.VALID, lacking_password, not welcome,
        old_token, logged_in is None)))
    if welcome and not lacking_password:
        # W+P+: welcome link sends onwards irrespective of token
        if logged_in:
            # L+: send onwards to discussion
            return HTTPFound(location=request.route_url(
                'home' if discussion else 'discussion_list',
                discussion_slug=discussion.slug))
        else:
            # L-: offer to login
            return HTTPFound(location=maybe_contextual_route(
                request, 'login', _query=dict(
                identifier=user.get_preferred_email() if user else None)))

    if (validity != Validity.VALID or old_token) and not logged_in:
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(_(
                "This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(_(
                "This link has been used. Do you want us to send another?"))
        request.session.flash(error)
        return HTTPFound(location=maybe_contextual_route(
            request, 'request_password_change', _query=dict(
                user_id=user.id if user else '')))

    # V+: Valid token (encompasses P-B+, W-, B-L+); ALSO V-L+
    # V+P-B- should not happen, but we'll treat it the same.
    # go through password change dialog. We'll complete login afterwards.
    if welcome:
        if discussion:
            request.session.flash(localizer.translate(_(
                "You will enter the discussion as <b>{name}</b>.")
                ).format(name=user.name), 'message')
        else:
            request.session.flash(localizer.translate(_(
                "You will enter Assembl as <b>{name}</b>.")
                ).format(name=user.name), 'message')
        request.session.flash(localizer.translate(_(
                "Please choose your password for security reasons.")
                ).format(name=user.name), 'message')
    return HTTPFound(location=maybe_contextual_route(
            request, 'react_do_password_change', _query=dict(
                token=token, welcome=welcome)))
Exemple #13
0
def check_password_token(request):
    token = request.matchdict.get('token', None)
    user, validity = verify_password_change_token(token)
    if validity != Validity.VALID:
        raise HTTPBadRequest(validity.name)
    return {"user": user.uri()}
Exemple #14
0
def do_password_change(request):
    "Validate the change_password token, and react accordingly."
    # Codes below refer to those cases:
    # V. token Valid(+) or invalid(-)? (Possibly expired through internal date)
    # P. user has(+) a Password or not (-)?
    # W. Welcome(+) vs change password(-)
    # B. last login absent, or Before token created (+) vs last login after token created (-)
    # L. user is already Logged in(+) or not(-)?

    welcome = 'welcome' in request.matched_route.name
    localizer = request.localizer
    discussion = discussion_from_request(request)
    token = request.matchdict.get('ticket')
    user, validity = verify_password_change_token(token)
    logged_in = authenticated_userid(request)
    if user and user.id != logged_in:
        # token for someone else: forget login.
        logged_in = None
        forget(request)
    lacking_password = user is not None and user.password is None
    token_date = get_data_token_time(token)
    old_token = (
        user is None or token_date is None or (
            user.last_login and token_date < user.last_login))
    print "pwc V%sP%sW%sB%sL%s" % tuple(map(lambda b: "-" if b else "+", (
        validity != Validity.VALID, lacking_password, not welcome,
        old_token, logged_in is None)))
    if welcome and not lacking_password:
        # W+P+: welcome link sends onwards irrespective of token
        if logged_in:
            # L+: send onwards to discussion
            return HTTPFound(location=request.route_url(
                'home' if discussion else 'discussion_list',
                discussion_slug=discussion.slug))
        else:
            # L-: offer to login
            return HTTPFound(location=maybe_contextual_route(
                request, 'login', _query=dict(
                identifier=user.get_preferred_email() if user else None)))

    if (validity != Validity.VALID or old_token) and not logged_in:
        # V-, V+P+W-B-L-: Invalid or obsolete token (obsolete+logged in treated later.)
        # Offer to send a new token
        if validity != Validity.VALID:
            error = localizer.translate(_(
                "This link is not valid. Do you want us to send another?"))
        else:
            error = localizer.translate(_(
                "This link has been used. Do you want us to send another?"))

        return HTTPFound(location=maybe_contextual_route(
            request, 'request_password_change', _query=dict(
                user_id=user.id if user else '',
                error=error)))

    # V+: Valid token (encompasses P-B+, W-, B-L+); ALSO V-L+
    # V+P-B- should not happen, but we'll treat it the same.
    # go through password change dialog. We'll complete login afterwards.
    slug = discussion.slug if discussion else ""
    slug_prefix = "/" + slug if slug else ""
    if welcome:
        if discussion:
            discussion_topic = discussion.topic
            welcome_text = localizer.translate(_(
                "You will enter the discussion as <b>{name}</b>.")).format(name=user.name)
        else:
            discussion_topic = "Assembl"
            welcome_text = localizer.translate(_(
                "You will enter Assembl as <b>{name}</b>."))
        welcome_text += "</p><p>" + localizer.translate(_(
            "Please choose your password for security reasons."))
        title = localizer.translate(_('Welcome to {discussion_topic}.')).format(
            discussion_topic=discussion_topic)
    else:
        title = localizer.translate(_('Change your password'))
        welcome_text = ""
    return dict(
        get_default_context(request),
        slug_prefix=slug_prefix,
        description=welcome_text,
        token=token,
        title=title)
Exemple #15
0
def check_password_token(request):
    token = request.matchdict.get('token', None)
    user, validity = verify_password_change_token(token)
    if validity != Validity.VALID:
        raise HTTPBadRequest(validity.name)
    return {"user": user.uri()}