From 1b45ab1bb4f36b966b49287a0a5436d63822c827 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Mon, 20 Mar 2023 21:04:42 +0100 Subject: rename profile to user-data This is not really a profile page, but rather a page to change your personal data, so it should be named accordingly (in preparation for real profiles). Additionally, we use POST requests to deal with the data change. --- fietsboek/routes.py | 3 +- fietsboek/templates/layout.jinja2 | 2 +- fietsboek/templates/profile.jinja2 | 83 ------------------ fietsboek/templates/user_data.jinja2 | 83 ++++++++++++++++++ fietsboek/views/profile.py | 159 ----------------------------------- fietsboek/views/user_data.py | 159 +++++++++++++++++++++++++++++++++++ 6 files changed, 244 insertions(+), 245 deletions(-) delete mode 100644 fietsboek/templates/profile.jinja2 create mode 100644 fietsboek/templates/user_data.jinja2 delete mode 100644 fietsboek/views/profile.py create mode 100644 fietsboek/views/user_data.py diff --git a/fietsboek/routes.py b/fietsboek/routes.py index 9e71686..cf6af82 100644 --- a/fietsboek/routes.py +++ b/fietsboek/routes.py @@ -53,8 +53,7 @@ def includeme(config): config.add_route("admin-badge-edit", "/admin/edit-badge") config.add_route("admin-badge-delete", "/admin/delete-badge") - config.add_route("profile", "/me") - config.add_route("change-profile", "/me/personal-data") + config.add_route("user-data", "/me") config.add_route("add-friend", "/me/send-friend-request") config.add_route("delete-friend", "/me/delete-friend") config.add_route("accept-friend", "/me/accept-friend") diff --git a/fietsboek/templates/layout.jinja2 b/fietsboek/templates/layout.jinja2 index d4e0a0d..8f322f6 100644 --- a/fietsboek/templates/layout.jinja2 +++ b/fietsboek/templates/layout.jinja2 @@ -73,7 +73,7 @@ const Legende = false; {{ _("page.navbar.logout") }}
  • - {{ _("page.navbar.profile") }} + {{ _("page.navbar.profile") }}
  • {% if request.identity.is_admin %}
  • diff --git a/fietsboek/templates/profile.jinja2 b/fietsboek/templates/profile.jinja2 deleted file mode 100644 index ef2ab5f..0000000 --- a/fietsboek/templates/profile.jinja2 +++ /dev/null @@ -1,83 +0,0 @@ -{% extends "layout.jinja2" %} - -{% import "util.jinja2" as util with context %} - -{% block content %} -
    -

    {{ _("page.my_profile.title") }}

    - -
    - -

    {{ _("page.my_profile.personal_data") }}

    - -
    -
    - - -
    -
    - -
    - {{ _("page.my_profile.personal_data.password_invalid") }} -
    - -
    -
    - -
    - {{ _("page.my_profile.personal_data.password_must_match") }} -
    - -
    - {{ util.hidden_csrf_input() }} - -
    - -
    - -

    {{ _("page.my_profile.friends") }}

    - -
      - {% for friend in user.get_friends() %} -
    • -
      - - {{ util.hidden_csrf_input() }} - -
      - {{ friend.name }} ({{ friend.email }}) -
    • - {% endfor %} - {% for friend_request in incoming_friend_requests %} -
    • -
      - - {{ util.hidden_csrf_input() }} - -
      - {{ friend_request.sender.name }} ({{ friend_request.sender.email }}) -
    • - {% endfor %} - {% for friend_request in outgoing_friend_requests %} -
    • {{ friend_request.recipient.name }} ({{ friend_request.recipient.email }})
    • - {% endfor %} -
    - -
    -
    - {{ util.hidden_csrf_input() }} -
    -
    -
    - - -
    -
    -
    - -
    -
    -
    -
    -
    -{% endblock %} diff --git a/fietsboek/templates/user_data.jinja2 b/fietsboek/templates/user_data.jinja2 new file mode 100644 index 0000000..15588e8 --- /dev/null +++ b/fietsboek/templates/user_data.jinja2 @@ -0,0 +1,83 @@ +{% extends "layout.jinja2" %} + +{% import "util.jinja2" as util with context %} + +{% block content %} +
    +

    {{ _("page.my_profile.title") }}

    + +
    + +

    {{ _("page.my_profile.personal_data") }}

    + +
    +
    + + +
    +
    + +
    + {{ _("page.my_profile.personal_data.password_invalid") }} +
    + +
    +
    + +
    + {{ _("page.my_profile.personal_data.password_must_match") }} +
    + +
    + {{ util.hidden_csrf_input() }} + +
    + +
    + +

    {{ _("page.my_profile.friends") }}

    + +
      + {% for friend in user.get_friends() %} +
    • +
      + + {{ util.hidden_csrf_input() }} + +
      + {{ friend.name }} ({{ friend.email }}) +
    • + {% endfor %} + {% for friend_request in incoming_friend_requests %} +
    • +
      + + {{ util.hidden_csrf_input() }} + +
      + {{ friend_request.sender.name }} ({{ friend_request.sender.email }}) +
    • + {% endfor %} + {% for friend_request in outgoing_friend_requests %} +
    • {{ friend_request.recipient.name }} ({{ friend_request.recipient.email }})
    • + {% endfor %} +
    + +
    +
    + {{ util.hidden_csrf_input() }} +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    +
    +{% endblock %} diff --git a/fietsboek/views/profile.py b/fietsboek/views/profile.py deleted file mode 100644 index 6354465..0000000 --- a/fietsboek/views/profile.py +++ /dev/null @@ -1,159 +0,0 @@ -"""Views corresponding to the user profile.""" -import datetime - -from pyramid.httpexceptions import HTTPForbidden, HTTPFound, HTTPNotFound -from pyramid.i18n import TranslationString as _ -from pyramid.view import view_config -from sqlalchemy import select - -from .. import models, util - - -@view_config( - route_name="profile", - renderer="fietsboek:templates/profile.jinja2", - permission="user", - request_method="GET", -) -def profile(request): - """Provides the profile overview. - - :param request: The Pyramid request. - :type request: pyramid.request.Request - :return: The HTTP response. - :rtype: pyramid.response.Response - """ - - coming_requests = request.dbsession.execute( - select(models.FriendRequest).filter_by(recipient_id=request.identity.id) - ).scalars() - going_requests = request.dbsession.execute( - select(models.FriendRequest).filter_by(sender_id=request.identity.id) - ).scalars() - return { - "user": request.identity, - "outgoing_friend_requests": going_requests, - "incoming_friend_requests": coming_requests, - } - - -@view_config(route_name="change-profile", permission="user", request_method="POST") -def do_change_profile(request): - """Endpoint to change the personal data. - - :param request: The Pyramid request. - :type request: pyramid.request.Request - :return: The HTTP response. - :rtype: pyramid.response.Response - """ - password = request.params["password"] - if password: - try: - util.check_password_constraints(password, request.params["repeat-password"]) - except ValueError as exc: - request.session.flash(request.localizer.translate(exc.args[0])) - return HTTPFound(request.route_url("profile")) - request.identity.set_password(request.params["password"]) - name = request.params["name"] - if request.identity.name != name: - request.identity.name = name - request.session.flash(request.localizer.translate(_("flash.personal_data_updated"))) - return HTTPFound(request.route_url("profile")) - - -@view_config(route_name="add-friend", permission="user", request_method="POST") -def do_add_friend(request): - """Sends a friend request. - - This is the endpoint of a form on the profile overview. - - :param request: The Pyramid request. - :type request: pyramid.request.Request - :return: The HTTP response. - :rtype: pyramid.response.Response - """ - email = request.params["friend-email"] - candidate = request.dbsession.execute(models.User.query_by_email(email)).scalar_one_or_none() - if candidate is None: - request.session.flash(request.localizer.translate(_("flash.friend_not_found"))) - return HTTPFound(request.route_url("profile")) - - if candidate in request.identity.get_friends() or candidate in [ - x.recipient for x in request.identity.outgoing_requests - ]: - request.session.flash(request.localizer.translate(_("flash.friend_already_exists"))) - return HTTPFound(request.route_url("profile")) - - for incoming in request.identity.incoming_requests: - if incoming.sender == candidate: - # We have an incoming request from that person, so we just accept that - request.identity.add_friend(candidate) - request.dbsession.delete(incoming) - request.session.flash(request.localizer.translate(_("flash.friend_added"))) - return HTTPFound(request.route_url("profile")) - - # Nothing helped, so we send the friend request - friend_req = models.FriendRequest( - sender=request.identity, - recipient=candidate, - date=datetime.datetime.utcnow(), - ) - request.dbsession.add(friend_req) - request.session.flash(request.localizer.translate(_("flash.friend_request_sent"))) - return HTTPFound(request.route_url("profile")) - - -@view_config(route_name="delete-friend", permission="user", request_method="POST") -def do_delete_friend(request): - """Deletes a friend. - - This is the endpoint of a form on the profile overview. - - :param request: The Pyramid request. - :type request: pyramid.request.Request - :return: The HTTP response. - :rtype: pyramid.response.Response - """ - friend = request.dbsession.execute( - select(models.User).filter_by(id=request.params["friend-id"]) - ).scalar_one_or_none() - if friend: - request.identity.remove_friend(friend) - return HTTPFound(request.route_url("profile")) - - -@view_config(route_name="accept-friend", permission="user", request_method="POST") -def do_accept_friend(request): - """Accepts a friend request. - - This is the endpoint of a form on the profile overview. - - :param request: The Pyramid request. - :type request: pyramid.request.Request - :return: The HTTP response. - :rtype: pyramid.response.Response - """ - friend_request = request.dbsession.execute( - select(models.FriendRequest).filter_by(id=request.params["request-id"]) - ).scalar_one_or_none() - if friend_request is None: - return HTTPNotFound() - if friend_request.recipient != request.identity: - return HTTPForbidden() - - friend_request.sender.add_friend(friend_request.recipient) - request.dbsession.delete(friend_request) - return HTTPFound(request.route_url("profile")) - - -@view_config(route_name="json-friends", renderer="json", permission="user") -def json_friends(request): - """Returns a JSON-ified list of the user's friends. - - :param request: The Pyramid request. - :type request: pyramid.request.Request - :return: The HTTP response. - :rtype: pyramid.response.Response - """ - friends = [{"name": friend.name, "id": friend.id} for friend in request.identity.get_friends()] - return friends diff --git a/fietsboek/views/user_data.py b/fietsboek/views/user_data.py new file mode 100644 index 0000000..a6ad11d --- /dev/null +++ b/fietsboek/views/user_data.py @@ -0,0 +1,159 @@ +"""Views corresponding to the user profile.""" +import datetime + +from pyramid.httpexceptions import HTTPForbidden, HTTPFound, HTTPNotFound +from pyramid.i18n import TranslationString as _ +from pyramid.view import view_config +from sqlalchemy import select + +from .. import models, util + + +@view_config( + route_name="user-data", + renderer="fietsboek:templates/user_data.jinja2", + permission="user", + request_method="GET", +) +def user_data(request): + """Provides the user's data. + + :param request: The Pyramid request. + :type request: pyramid.request.Request + :return: The HTTP response. + :rtype: pyramid.response.Response + """ + + coming_requests = request.dbsession.execute( + select(models.FriendRequest).filter_by(recipient_id=request.identity.id) + ).scalars() + going_requests = request.dbsession.execute( + select(models.FriendRequest).filter_by(sender_id=request.identity.id) + ).scalars() + return { + "user": request.identity, + "outgoing_friend_requests": going_requests, + "incoming_friend_requests": coming_requests, + } + + +@view_config(route_name="user-data", permission="user", request_method="POST") +def do_change_profile(request): + """Endpoint to change the personal data. + + :param request: The Pyramid request. + :type request: pyramid.request.Request + :return: The HTTP response. + :rtype: pyramid.response.Response + """ + password = request.params["password"] + if password: + try: + util.check_password_constraints(password, request.params["repeat-password"]) + except ValueError as exc: + request.session.flash(request.localizer.translate(exc.args[0])) + return HTTPFound(request.route_url("user-data")) + request.identity.set_password(request.params["password"]) + name = request.params["name"] + if request.identity.name != name: + request.identity.name = name + request.session.flash(request.localizer.translate(_("flash.personal_data_updated"))) + return HTTPFound(request.route_url("user-data")) + + +@view_config(route_name="add-friend", permission="user", request_method="POST") +def do_add_friend(request): + """Sends a friend request. + + This is the endpoint of a form on the profile overview. + + :param request: The Pyramid request. + :type request: pyramid.request.Request + :return: The HTTP response. + :rtype: pyramid.response.Response + """ + email = request.params["friend-email"] + candidate = request.dbsession.execute(models.User.query_by_email(email)).scalar_one_or_none() + if candidate is None: + request.session.flash(request.localizer.translate(_("flash.friend_not_found"))) + return HTTPFound(request.route_url("user-data")) + + if candidate in request.identity.get_friends() or candidate in [ + x.recipient for x in request.identity.outgoing_requests + ]: + request.session.flash(request.localizer.translate(_("flash.friend_already_exists"))) + return HTTPFound(request.route_url("user-data")) + + for incoming in request.identity.incoming_requests: + if incoming.sender == candidate: + # We have an incoming request from that person, so we just accept that + request.identity.add_friend(candidate) + request.dbsession.delete(incoming) + request.session.flash(request.localizer.translate(_("flash.friend_added"))) + return HTTPFound(request.route_url("user-data")) + + # Nothing helped, so we send the friend request + friend_req = models.FriendRequest( + sender=request.identity, + recipient=candidate, + date=datetime.datetime.utcnow(), + ) + request.dbsession.add(friend_req) + request.session.flash(request.localizer.translate(_("flash.friend_request_sent"))) + return HTTPFound(request.route_url("user-data")) + + +@view_config(route_name="delete-friend", permission="user", request_method="POST") +def do_delete_friend(request): + """Deletes a friend. + + This is the endpoint of a form on the profile overview. + + :param request: The Pyramid request. + :type request: pyramid.request.Request + :return: The HTTP response. + :rtype: pyramid.response.Response + """ + friend = request.dbsession.execute( + select(models.User).filter_by(id=request.params["friend-id"]) + ).scalar_one_or_none() + if friend: + request.identity.remove_friend(friend) + return HTTPFound(request.route_url("user-data")) + + +@view_config(route_name="accept-friend", permission="user", request_method="POST") +def do_accept_friend(request): + """Accepts a friend request. + + This is the endpoint of a form on the profile overview. + + :param request: The Pyramid request. + :type request: pyramid.request.Request + :return: The HTTP response. + :rtype: pyramid.response.Response + """ + friend_request = request.dbsession.execute( + select(models.FriendRequest).filter_by(id=request.params["request-id"]) + ).scalar_one_or_none() + if friend_request is None: + return HTTPNotFound() + if friend_request.recipient != request.identity: + return HTTPForbidden() + + friend_request.sender.add_friend(friend_request.recipient) + request.dbsession.delete(friend_request) + return HTTPFound(request.route_url("user-data")) + + +@view_config(route_name="json-friends", renderer="json", permission="user") +def json_friends(request): + """Returns a JSON-ified list of the user's friends. + + :param request: The Pyramid request. + :type request: pyramid.request.Request + :return: The HTTP response. + :rtype: pyramid.response.Response + """ + friends = [{"name": friend.name, "id": friend.id} for friend in request.identity.get_friends()] + return friends -- cgit v1.2.3