]> git.ipfire.org Git - ipfire.org.git/commitdiff
people: Move profile page into main website
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 24 Jun 2023 17:43:54 +0000 (17:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 24 Jun 2023 17:43:54 +0000 (17:43 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/accounts.py
src/templates/people/user.html [deleted file]
src/templates/users/show.html [new file with mode: 0644]
src/web/__init__.py
src/web/people.py
src/web/users.py [new file with mode: 0644]

index c545593a0263ace43d86614697f30d0fbd5121bf..e08d4b5d916a4aff7229e5e2bb552eb890fd5cc3 100644 (file)
@@ -93,6 +93,7 @@ web_PYTHON = \
        src/web/nopaste.py \
        src/web/people.py \
        src/web/ui_modules.py \
+       src/web/users.py \
        src/web/wiki.py
 
 webdir = $(backenddir)/web
@@ -272,7 +273,6 @@ templates_people_DATA = \
        src/templates/people/subscribed.html \
        src/templates/people/unsubscribe.html \
        src/templates/people/unsubscribed.html \
-       src/templates/people/user.html \
        src/templates/people/user-edit.html \
        src/templates/people/users.html
 
@@ -303,6 +303,11 @@ templates_static_DATA = \
 
 templates_staticdir = $(templatesdir)/static
 
+templates_users_DATA = \
+       src/templates/users/show.html
+
+templates_usersdir = $(templatesdir)/users
+
 templates_wiki_DATA = \
        src/templates/wiki/404.html \
        src/templates/wiki/base.html \
index 35079d9be7f71b1114216328424b50917dfe6e8b..5dabbef0f84ddcc9362bb828d7689e3ea39995ac 100644 (file)
@@ -786,6 +786,9 @@ class Account(LDAPObject):
        def has_sip(self):
                return "sipUser" in self.classes or "sipRoutingObject" in self.classes
 
+       def is_lwl(self):
+               return self.is_member_of_group("lwl-staff")
+
        def can_be_managed_by(self, account):
                """
                        Returns True if account is allowed to manage this account
diff --git a/src/templates/people/user.html b/src/templates/people/user.html
deleted file mode 100644 (file)
index 1ed4171..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-{% extends "../base.html" %}
-
-{% block title %}{{ account }}{% end block %}
-
-{% block container %}
-       {% import phonenumbers %}
-
-       <div class="header">
-               <div class="container">
-                       <div class="row align-items-center justify-content-center">
-                               <div class="col-4 col-lg-2 text-center">
-                                       <img class="img-fluid rounded-circle my-5"
-                                               src="{{ account.avatar_url(512) }}" alt="{{ account }}" />
-                               </div>
-
-                               <div class="col-12 col-lg-10">
-                                       <h2>{{ account }}</h2>
-
-                                       {% if account.description %}
-                                               <div>
-                                                       {% module Markdown(account.description) %}
-                                               </div>
-                                       {% end %}
-
-                                       <div class="btn-toolbar mb-3">
-                                               <a class="btn btn-secondary btn-sm mr-2" href="https://community.ipfire.org/u/{{ account.uid }}">
-                                                       <i class="fas fa-users"></i> {{ _("Community Profile") }}
-                                               </a>
-
-                                               {% if account.has_shell() %}
-                                                       <a class="btn btn-secondary btn-sm" href="/~{{ account.uid }}/">
-                                                               <span class="fas fa-home mr-2"></span> {{ _("Home Directory") }}
-                                                       </a>
-                                               {% end %}
-
-                                               {% if account.can_be_managed_by(current_user) %}
-                                                       {% if account.has_sip() %}
-                                                               <a class="btn btn-secondary btn-sm ml-2" href="/users/{{ account.uid }}/calls">
-                                                                       <span class="fas fa-phone mr-2"></span> {{ _("Calls") }}
-                                                               </a>
-                                                       {% end %}
-
-                                                       <a class="btn btn-link text-warning btn-sm" href="/users/{{ account.uid }}/edit">
-                                                               {{ _("Edit") }}
-                                                       </a>
-
-                                                       <a class="btn btn-link text-muted btn-sm" href="/users/{{ account.uid }}/passwd">
-                                                               {{ _("Change Password") }}
-                                                       </a>
-                                               {% end %}
-                                       </div>
-                               </div>
-                       </div>
-               </div>
-       </div>
-
-       {% if current_user == account or current_user.is_staff() %}
-               <div class="container">
-                       <section>
-                               {% if account == current_user %}
-                                       {# Suggest adding a description #}
-                                       {% if not current_user.description %}
-                                               <div class="alert alert-info">
-                                                       <h6 class="alert-heading">{{ _("Tell Us About Yourself" ) }}</h6>
-
-                                                       <p class="mb-0">
-                                                               {{ _("Add a couple of lines about yourself to your profile so that others get to know you better") }}
-
-                                                               <a class="alert-link" href="/users/{{ account.uid }}/edit#description">{{ _("Edit Profile") }}</a>
-                                                       </p>
-                                               </div>
-
-                                       {# Suggest uploading an avatar if this user does not have one #}
-                                       {% elif not current_user.has_avatar() %}
-                                               <div class="alert alert-info">
-                                                       <h6 class="alert-heading">{{ _("Upload An Avatar" ) }}</h6>
-
-                                                       <p class="mb-0">
-                                                               {{ _("A picture says more than a thousand words") }}
-
-                                                               <a class="alert-link" href="/users/{{ account.uid }}/edit#avatar">{{ _("Upload Avatar") }}</a>
-                                                       </p>
-                                               </div>
-                                       {% end %}
-                               {% end %}
-
-                               <div class="row">
-                                       <div class="col-12 col-lg-6">
-                                               {% if current_user.is_staff() %}
-                                                       <h6>{{ _("Email") }}</h6>
-
-                                                       <ul class="list-unstyled">
-                                                               <li>
-                                                                       <a href="mailto:{{ account.email }}">
-                                                                               {{ account.email }}
-                                                                       </a>
-                                                               </li>
-                                                       </ul>
-                                               {% end %}
-
-                                               {% if account.address %}
-                                                       <h6>{{ _("Address") }}</h6>
-
-                                                       <address>
-                                                               {{ account.name }}<br>
-                                                               {% for line in account.address %}
-                                                                       {{ line }}<br>
-                                                               {% end %}
-                                                       </address>
-                                               {% end %}
-
-                                               {% if account.phone_number or account.fax_number %}
-                                                       <h6>{{ _("Phone Numbers") }}</h6>
-
-                                                       <ul class="list-unstyled">
-                                                               {% if account.has_sip() %}
-                                                                       <li>
-                                                                               {% if account.sip_channels %}
-                                                                                       <i class="fas fa-phone-volume text-warning fa-fw"></i>
-                                                                               {% elif account.sip_registrations %}
-                                                                                       <i class="fas fa-phone-square text-success fa-fw"></i>
-                                                                               {% elif account.uses_sip_forwarding() %}
-                                                                                       <i class="fas fa-phone-square text-warning fa-fw"></i>
-                                                                               {% else %}
-                                                                                       <i class="fas fa-phone-square text-danger fa-fw"></i>
-                                                                               {% end %}
-
-                                                                               <a href="sip:{{ account.sip_url }}">{{ account.sip_id }}</a>
-                                                                       </li>
-                                                               {% end %}
-
-                                                               {% if account.phone_number %}
-                                                                       <li>
-                                                                               <i class="fas fa-phone fa-fw"></i>
-
-                                                                               <a href="tel:{{ format_phone_number_to_e164(account.phone_number) }}">
-                                                                                       {{ format_phone_number(account.phone_number) }}
-                                                                               </a>
-                                                                       </li>
-                                                               {% end %}
-
-                                                               {% if account.fax_number %}
-                                                                       <li>
-                                                                               <i class="fas fa-fax fa-fw"></i>
-
-                                                                               <a href="fax:{{ format_phone_number_to_e164(account.fax_number) }}">
-                                                                                       {{ format_phone_number(account.fax_number) }}
-                                                                               </a>
-                                                                       </li>
-                                                               {% end %}
-                                                       </ul>
-                                               {% end %}
-
-                                               {% if account.phone_numbers %}
-                                                       <h6>{{ _("External Phone Numbers") }}</h6>
-
-                                                       <ul class="list-unstyled">
-                                                               {% for number in account.phone_numbers %}
-                                                                       <li>
-                                                                               {% if phonenumbers.number_type(number) == phonenumbers.PhoneNumberType.MOBILE %}
-                                                                                       <i class="fas fa-mobile fa-fw" title="{{ _("Mobile") }}"></i>
-                                                                               {% else %}
-                                                                                       <i class="fas fa-phone fa-fw"></i>
-                                                                               {% end %}
-
-                                                                               <a href="tel:{{ format_phone_number_to_e164(number) }}"
-                                                                                       title="{{ format_phone_number_location(number) }}">{{ format_phone_number(number) }}</a>
-                                                                       </li>
-                                                               {% end %}
-                                                       </ul>
-                                               {% end %}
-                                       </div>
-
-                                       {% if current_user.is_staff() %}
-                                               <div class="col-12 col-lg-6">
-                                                       {% if account.groups %}
-                                                               <h6>{{ _("Groups") }}</h6>
-
-                                                               <div class="list-group mb-3">
-                                                                       {% for g in account.groups %}
-                                                                               <a class="list-group-item list-group-item-action" href="/groups/{{ g.gid }}">
-                                                                                       <i class="fas fa-users mr-2"></i> {{ g }}
-                                                                               </a>
-                                                                       {% end %}
-                                                               </div>
-                                                       {% end %}
-
-                                                       <ul class="list-unstyled small text-muted">
-                                                               <li>
-                                                                       {{ _("Joined %s") % locale.format_date(account.created_at, shorter=True) }}
-                                                               </li>
-
-                                                               {% if current_user.is_admin() %}
-                                                                       <li>
-                                                                               {{ _("Last Modified %s") % locale.format_date(account.modified_at) }}
-                                                                       </li>
-
-                                                                       {% if account.last_successful_authentication %}
-                                                                               <li>
-                                                                                       {{ _("Last successful authentication: %s") % locale.format_date(account.last_successful_authentication) }}
-                                                                               </li>
-                                                                       {% end %}
-
-                                                                       {% if account.failed_login_count %}
-                                                                               <li class="text-warning">
-                                                                                       {{ _("One unsuccessful authentication attempt.", "%(num)s unsuccessful authentication attempts.", account.failed_login_count) % { "num" : account.failed_login_count } }}
-
-                                                                                       {% if account.last_failed_authentication %}
-                                                                                               {{ _("Last attempt: %s") % locale.format_date(account.last_failed_authentication) }}
-                                                                                       {% end %}
-                                                                               </li>
-                                                                       {% end %}
-                                                               {% end %}
-                                                       </ul>
-                                               </div>
-                                       {% end %}
-                               </div>
-                       </section>
-               </div>
-       {% end %}
-{% end block %}
diff --git a/src/templates/users/show.html b/src/templates/users/show.html
new file mode 100644 (file)
index 0000000..29bc136
--- /dev/null
@@ -0,0 +1,271 @@
+{% extends "../base.html" %}
+
+{% block title %}{{ account }}{% end block %}
+
+{% block container %}
+       {% import phonenumbers %}
+
+       <section class="hero {% if account.is_lwl() %}is-lwl{% else %}is-dark{% end %}">
+               <div class="hero-body">
+                       <div class="container">
+                               <div class="columns is-vcentered">
+                                       <div class="column">
+                                               <nav class="breadcrumb is-medium" aria-label="breadcrumbs">
+                                                       <ul>
+                                                               <li>
+                                                                       <a href="/">
+                                                                               {{ _("Home") }}
+                                                                       </a>
+                                                               </li>
+                                                               <li>
+                                                                       <a href="/users">
+                                                                               {{ _("Users") }}
+                                                                       </a>
+                                                               </li>
+                                                               <li class="is-active">
+                                                                       <a href="#" aria-current="page">{{ account }}</a>
+                                                               </li>
+                                                       </ul>
+                                               </nav>
+
+                                               <h1 class="title is-1">{{ account }}</h1>
+                                               <h6 class="subtitle is-6">{{ account.uid }}</h6>
+
+                                               {# Description #}
+                                               {% if account.description %}
+                                                       <div class="block">
+                                                               <div class="content">
+                                                                       {% module Markdown(account.description) %}
+                                                               </div>
+                                                       </div>
+                                               {% end %}
+                                       </div>
+
+                                       <div class="column is-narrow is-hidden-mobile">
+                                               <figure class="image">
+                                                       <img class="is-rounded" src="{{ account.avatar_url(192) }}">
+                                               </figure>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+       </section>
+
+       <section class="section">
+               <div class="container">
+                       <div class="buttons">
+                               <a class="button is-light" href="mailto:{{ account.email }}">
+                                       <span class="icon-text">
+                                               <span class="icon">
+                                                       <i class="fas fa-envelope"></i>
+                                               </span>
+                                               <span>{{ account.email }}</span>
+                                       </span>
+                               </a>
+
+                               <a class="button is-light" href="https://community.ipfire.org/u/{{ account.uid }}">
+                                       <span class="icon-text">
+                                               <span class="icon">
+                                                       <i class="fas fa-users"></i>
+                                               </span>
+                                               <span>{{ _("Community Profile") }}</span>
+                                       </span>
+                               </a>
+
+                               {% if account.has_shell() %}
+                                       <a class="button is-dark" href="/~{{ account.uid }}/">
+                                               <span class="icon-text">
+                                                       <span class="icon">
+                                                               <i class="fas fa-home"></i>
+                                                       </span>
+                                                       <span>{{ _("Home Directory") }}</span>
+                                               </span>
+                                       </a>
+                               {% end %}
+
+                               {% if account.can_be_managed_by(current_user) %}
+                                       {% if account.has_sip() %}
+                                               <a class="button is-success" href="/users/{{ account.uid }}/calls">
+                                                       <span class="icon-text">
+                                                               <span class="icon">
+                                                                       <i class="fas fa-phone"></i>
+                                                               </span>
+                                                               <span>{{ _("Calls") }}</span>
+                                                       </span>
+                                               </a>
+                                       {% end %}
+
+                                       <a class="button is-warning" href="/users/{{ account.uid }}/edit">
+                                               {{ _("Edit") }}
+                                       </a>
+
+                                       <a class="button is-light" href="/users/{{ account.uid }}/passwd">
+                                               {{ _("Change Password") }}
+                                       </a>
+                               {% end %}
+                       </div>
+
+                       {% if account == current_user %}
+                               {# Suggest adding a description #}
+                               {% if not current_user.description %}
+                                       <div class="notification is-info">
+                                               <strong>{{ _("Tell Us About Yourself!") }}</strong>
+
+                                               {{ _("Add a couple of lines about yourself to your profile so that others get to know you better") }}
+
+                                               <a href="/users/{{ account.uid }}/edit#description">{{ _("Edit Profile") }}</a>
+                                       </div>
+
+                               {# Suggest uploading an avatar if this user does not have one #}
+                               {% elif not current_user.has_avatar() %}
+                                       <div class="notification is-info">
+                                               <strong>{{ _("Upload An Avatar!") }}</strong>
+
+                                               {{ _("A picture says more than a thousand words") }}
+
+                                               <a href="/users/{{ account.uid }}/edit#avatar">{{ _("Upload Avatar") }}</a>
+                                       </div>
+                               {% end %}
+                       {% end %}
+               </div>
+       </section>
+
+       {% if current_user == account or current_user.is_staff() %}
+               <section class="section">
+                       <div class="container">
+                               <div class="columns">
+                                       {# Address #}
+                                       {% if account.address %}
+                                               <div class="column">
+                                                       <h6 class="title is-6">{{ _("Address") }}</h6>
+
+                                                       <address>
+                                                               {{ account.name }}<br>
+                                                               {% for line in account.address %}
+                                                                       {{ line }}<br>
+                                                               {% end %}
+                                                       </address>
+                                               </div>
+                                       {% end %}
+
+                                       {# Phone Numbers #}
+                                       {% if account.phone_number or account.fax_number %}
+                                               <div class="column">
+                                                       <h6 class="title is-6">{{ _("Phone Numbers") }}</h6>
+
+                                                       <ul>
+                                                               {% if account.has_sip() %}
+                                                                       <li>
+                                                                               {% if account.sip_channels %}
+                                                                                       <i class="fas fa-phone-volume has-text-warning fa-fw"></i>
+                                                                               {% elif account.sip_registrations %}
+                                                                                       <i class="fas fa-phone-square has-text-success fa-fw"></i>
+                                                                               {% elif account.uses_sip_forwarding() %}
+                                                                                       <i class="fas fa-phone-square has-text-warning fa-fw"></i>
+                                                                               {% else %}
+                                                                                       <i class="fas fa-phone-square has-text-danger fa-fw"></i>
+                                                                               {% end %}
+
+                                                                               <a href="sip:{{ account.sip_url }}">{{ account.sip_id }}</a>
+                                                                       </li>
+                                                               {% end %}
+
+                                                               {% if account.phone_number %}
+                                                                       <li>
+                                                                               <i class="fas fa-phone fa-fw"></i>
+
+                                                                               <a href="tel:{{ format_phone_number_to_e164(account.phone_number) }}">
+                                                                                       {{ format_phone_number(account.phone_number) }}
+                                                                               </a>
+                                                                       </li>
+                                                               {% end %}
+
+                                                               {% if account.fax_number %}
+                                                                       <li>
+                                                                               <i class="fas fa-fax fa-fw"></i>
+
+                                                                               <a href="fax:{{ format_phone_number_to_e164(account.fax_number) }}">
+                                                                                       {{ format_phone_number(account.fax_number) }}
+                                                                               </a>
+                                                                       </li>
+                                                               {% end %}
+                                                       </ul>
+                                               </div>
+                                       {% end %}
+
+                                       {% if current_user.is_staff() %}
+                                               {% if account.groups %}
+                                                       <div class="column is-half">
+                                                               <h6 class="title is-6">{{ _("Groups") }}</h6>
+
+                                                               <nav class="panel">
+                                                                       {% for g in account.groups %}
+                                                                               <a class="panel-block" href="/groups/{{ g.gid }}">
+                                                                                       <span class="panel-icon">
+                                                                                               <i class="fas fa-users" aria-hidden="true"></i>
+                                                                                       </span>
+                                                                                       {{ g }}
+                                                                               </a>
+                                                                       {% end %}
+                                                               </nav>
+                                                       </div>
+                                               {% end %}
+                                       {% end %}
+                               </div>
+                       </div>
+               </section>
+
+               <section class="section">
+                       <div class="container">
+                               <nav class="level">
+                                       <div class="level-item has-text-centered">
+                                               <div>
+                                                       <p class="heading">{{ _("Joined") }}</p>
+                                                       <p>
+                                                               {{ locale.format_date(account.created_at, shorter=True) }}
+                                                       </p>
+                                               </div>
+                                       </div>
+
+                                       <div class="level-item has-text-centered">
+                                               <div>
+                                                       <p class="heading">{{ _("Last Modified") }}</p>
+                                                       <p>
+                                                               {{ locale.format_date(account.modified_at) }}
+                                                       </p>
+                                               </div>
+                                       </div>
+
+                                       {% if account.last_successful_authentication %}
+                                               <div class="level-item has-text-centered">
+                                                       <div>
+                                                               <p class="heading">{{ _("Last Successful Authentication") }}</p>
+                                                               <p>
+                                                                       {{ locale.format_date(account.last_successful_authentication) }}
+                                                               </p>
+                                                       </div>
+                                               </div>
+                                       {% end %}
+
+                                       {% if account.failed_login_count %}
+                                               <div class="level-item has-text-warning has-text-centered">
+                                                       <div>
+                                                               <p class="heading">{{ _("Failed Authentication Attempts") }}</p>
+                                                               <p>{{ account.failed_login_count }}</p>
+                                                       </div>
+                                               </div>
+
+                                               {% if account.last_failed_authentication %}
+                                                       <div class="level-item has-text-warning has-text-centered">
+                                                               <div>
+                                                                       <p class="heading">{{ _("Last Failed Authentication Attempt") }}</p>
+                                                                       <p>{{ locale.format_date(account.last_failed_authentication) }}</p>
+                                                               </div>
+                                                       </div>
+                                               {% end %}
+                                       {% end %}
+                               </nav>
+                       </div>
+               </section>
+       {% end %}
+{% end block %}
index a75e48cfbf632aa67c4435df14c1e79f8120d4e8..f28ff8f66a9cd7875fb5e9096b982f9b495d2797 100644 (file)
@@ -25,6 +25,7 @@ from . import location
 from . import nopaste
 from . import people
 from . import ui_modules
+from . import users
 from . import wiki
 
 class Application(tornado.web.Application):
@@ -147,6 +148,9 @@ class Application(tornado.web.Application):
                        (r"/donate/error", donate.ErrorHandler),
                        (r"/donation", tornado.web.RedirectHandler, { "url" : "/donate" }),
 
+                       # Users
+                       (r"/users/([\w]+)", users.ShowHandler),
+
                        # RSS feed
                        (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
 
@@ -298,7 +302,6 @@ class Application(tornado.web.Application):
                        (r"/register", auth.RegisterHandler),
                        (r"/search", people.SearchHandler),
                        (r"/users", people.UsersHandler),
-                       (r"/users/([a-z_][a-z0-9_-]{0,31})", people.UserHandler),
                        (r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", people.AvatarHandler),
                        (r"/users/([a-z_][a-z0-9_-]{0,31})/calls/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})", people.CallHandler),
                        (r"/users/([a-z_][a-z0-9_-]{0,31})/calls(?:/(\d{4}-\d{2}-\d{2}))?", people.CallsHandler),
index 5a3f3da63141ad8fbc591b8143825b4ff74cae5a..68c297344c77faaac59659990ced35a969cb1094 100644 (file)
@@ -270,16 +270,6 @@ class UsersHandler(auth.CacheMixin, base.BaseHandler):
                self.render("people/users.html")
 
 
-class UserHandler(auth.CacheMixin, base.BaseHandler):
-       @tornado.web.authenticated
-       def get(self, uid):
-               account = self.backend.accounts.get_by_uid(uid)
-               if not account:
-                       raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
-
-               self.render("people/user.html", account=account)
-
-
 class UserEditHandler(auth.CacheMixin, base.BaseHandler):
        @tornado.web.authenticated
        def get(self, uid):
diff --git a/src/web/users.py b/src/web/users.py
new file mode 100644 (file)
index 0000000..d354486
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/python
+
+import tornado.web
+
+from . import auth
+from . import base
+
+class ShowHandler(auth.CacheMixin, base.BaseHandler):
+       @tornado.web.authenticated
+       def get(self, uid):
+               account = self.backend.accounts.get_by_uid(uid)
+               if not account:
+                       raise tornado.web.HTTPError(404, "Could not find account %s" % uid)
+
+               self.render("users/show.html", account=account)