Mercurial > hg > savane-forge
changeset 251:44fe8b68a005
Superuser status can be turned on&off during session; implement user impersonification
author | Sylvain Beucler <beuc@beuc.net> |
---|---|
date | Sun, 08 Aug 2010 23:50:22 +0200 |
parents | 8c660f0f5ec6 |
children | 5f6d5199a413 |
files | locale/fr/LC_MESSAGES/django.po savane/perms.py savane/svmain/models.py savane/svmain/templatetags/qsup.py savane/svmain/urls.py savane/svmain/views.py templates/base.html |
diffstat | 7 files changed, 260 insertions(+), 143 deletions(-) [+] |
line wrap: on
line diff
--- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -39,8 +39,8 @@ msgstr "" "Project-Id-Version: Savane\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-08-08 13:38-0500\n" -"PO-Revision-Date: 2010-08-08 20:39+0200\n" +"POT-Creation-Date: 2010-08-08 16:17-0500\n" +"PO-Revision-Date: 2010-08-08 23:18+0200\n" "Last-Translator: Sylvain Beucler <beuc@beuc.net>\n" "Language-Team: French <fr@li.org>\n" "Language: fr\n" @@ -89,6 +89,14 @@ msgid "Swedish" msgstr "Suédois" +#: savane/perms.py:27 savane/perms.py:40 +msgid "Permission denied" +msgstr "Accès refusé" + +#: savane/perms.py:54 +msgid "You are not superuser" +msgstr "Vous n'êtes pas super-utilisateur" + #: savane/my/forms.py:25 msgid "E-mail" msgstr "Courriel" @@ -330,16 +338,16 @@ msgid "Project Menu Settings" msgstr "Configuration du menu du projet" -#: savane/svmain/models.py:118 savane/svmain/models.py:397 +#: savane/svmain/models.py:118 savane/svmain/models.py:399 msgid "Active" msgstr "Actif" -#: savane/svmain/models.py:119 savane/svmain/models.py:399 +#: savane/svmain/models.py:119 savane/svmain/models.py:401 #: savane/svmain/models.py:720 msgid "Deleted" msgstr "Supprimé" -#: savane/svmain/models.py:120 savane/svmain/models.py:398 +#: savane/svmain/models.py:120 savane/svmain/models.py:400 msgid "Pending" msgstr "En attente" @@ -351,26 +359,26 @@ msgid "new e-mail address" msgstr "nouvelle adresse courriel" -#: savane/svmain/models.py:218 +#: savane/svmain/models.py:220 msgid "Development statuses" msgstr "Stades de développement" -#: savane/svmain/models.py:224 +#: savane/svmain/models.py:226 msgid "Will be added on each project main page" msgstr "Description (qui sera ajouté sur chaque page principale de projet)" -#: savane/svmain/models.py:233 +#: savane/svmain/models.py:235 msgid "would be %LIST@gnu.org for GNU projects at sv.gnu.org" msgstr "ce serait %LIST@gnu.org pour les projets GNU sur sv.gnu.org" -#: savane/svmain/models.py:235 +#: savane/svmain/models.py:237 msgid "" "would be lists.gnu.org or lists.nongnu.org at sv.gnu.org [BACKEND SPECIFIC]" msgstr "" "ce serait lists.gnu.org or lists.nongnu.org sur sv.gnu.org [spécifique à la " "partie système]" -#: savane/svmain/models.py:237 +#: savane/svmain/models.py:239 msgid "" "With this, you can force projects to follow a specific policy for the name " "of the %LIST. Here you should use the special wildcard %NAME, which is the " @@ -385,18 +393,18 @@ "projets non-GNU projects sur sv.gnu.org). N'ajoutez pas de @hostname ici! " "Vous pouvez spécier plusieurs formats séparés par une \",\" virgule." -#: savane/svmain/models.py:243 +#: savane/svmain/models.py:245 msgid "" "This is useful if you provide directly download areas (created by the " "backend) or if you want to allow projects to configure the related menu " "entry (see below)." msgstr "" -#: savane/svmain/models.py:251 +#: savane/svmain/models.py:253 msgid "This is useful if you want project to select a license on submission." msgstr "" -#: savane/svmain/models.py:253 +#: savane/svmain/models.py:255 msgid "" "This is useful if you want project to be able to defines their development " "status that will be shown on their main page. This is purely a matter of " @@ -404,148 +412,148 @@ "is useless (it does not makes sense for organizational projects)." msgstr "" -#: savane/svmain/models.py:255 +#: savane/svmain/models.py:257 msgid "" "This is one of the main issue tracker of Savane. Projects are supposed to " "use it as primary interface with end user." msgstr "" -#: savane/svmain/models.py:262 +#: savane/svmain/models.py:264 msgid "the homepage link can be modified" msgstr "le lien vers le site web du projet peut être modifié" -#: savane/svmain/models.py:284 +#: savane/svmain/models.py:286 msgid "" "the download _directory_ can be modified -- beware, if the backend is " "running and creating download dir, it can be used maliciously. don't " "activate this feature unless you truly know what you're doing" msgstr "" -#: savane/svmain/models.py:288 +#: savane/svmain/models.py:290 msgid "CVS" msgstr "CVS" -#: savane/svmain/models.py:289 -msgid "Subversion" -msgstr "Subversion" - -#: savane/svmain/models.py:290 -msgid "GNU Arch" -msgstr "GNU Arch" - #: savane/svmain/models.py:291 +msgid "Subversion" +msgstr "Subversion" + +#: savane/svmain/models.py:292 +msgid "GNU Arch" +msgstr "GNU Arch" + +#: savane/svmain/models.py:293 msgid "Git" msgstr "Git" -#: savane/svmain/models.py:292 +#: savane/svmain/models.py:294 msgid "Mercurial" msgstr "Mercurial" -#: savane/svmain/models.py:293 +#: savane/svmain/models.py:295 msgid "Bazaar" msgstr "Bazaar" -#: savane/svmain/models.py:297 +#: savane/svmain/models.py:299 msgid "Basic directory" msgstr "Dossier basique" -#: savane/svmain/models.py:298 +#: savane/svmain/models.py:300 msgid "Basic CVS directory" msgstr "Dossier CVS basique" -#: savane/svmain/models.py:299 +#: savane/svmain/models.py:301 msgid "Basic Subversion directory" msgstr "Dossier Subversion basique" -#: savane/svmain/models.py:300 +#: savane/svmain/models.py:302 msgid "Basic Git directory" msgstr "Dossier Git basique" -#: savane/svmain/models.py:301 +#: savane/svmain/models.py:303 msgid "Basic Mercurial directory" msgstr "Dossier Mercurial basique" -#: savane/svmain/models.py:302 +#: savane/svmain/models.py:304 msgid "Basic Bazaar directory" msgstr "Dossier Bazaar basique" -#: savane/svmain/models.py:303 +#: savane/svmain/models.py:305 msgid "CVS Attic/Gna!" msgstr "" -#: savane/svmain/models.py:304 -msgid "Subversion Attic/Gna!" -msgstr "" - -#: savane/svmain/models.py:305 -msgid "Subversion Subdirectory Attic/Gna!" -msgstr "" - #: savane/svmain/models.py:306 -msgid "CVS Savannah GNU" +msgid "Subversion Attic/Gna!" msgstr "" #: savane/svmain/models.py:307 +msgid "Subversion Subdirectory Attic/Gna!" +msgstr "" + +#: savane/svmain/models.py:308 +msgid "CVS Savannah GNU" +msgstr "" + +#: savane/svmain/models.py:309 msgid "CVS Savannah non-GNU" msgstr "" -#: savane/svmain/models.py:386 +#: savane/svmain/models.py:388 msgid "project information" msgstr "informations du projet" -#: savane/svmain/models.py:393 +#: savane/svmain/models.py:395 msgid "full name" msgstr "nom complet" -#: savane/svmain/models.py:394 +#: savane/svmain/models.py:396 msgid "Full project name (not Unix system name)" msgstr "Nom complet du projet (pas le nom système Unix!)" -#: savane/svmain/models.py:400 +#: savane/svmain/models.py:402 msgid "Maintenance (accessible only to superuser)" msgstr "Maintenance (accessible seulement aux superutilisateurs)" -#: savane/svmain/models.py:401 +#: savane/svmain/models.py:403 msgid "Incomplete (failure during registration)" msgstr "Incomplet (échec lors de l'inscription)" -#: savane/svmain/models.py:406 +#: savane/svmain/models.py:408 msgid "short description" msgstr "description courte" -#: savane/svmain/models.py:407 +#: savane/svmain/models.py:409 msgid "long description" msgstr "description longue" -#: savane/svmain/models.py:408 +#: savane/svmain/models.py:410 msgid "license" msgstr "licence" -#: savane/svmain/models.py:409 +#: savane/svmain/models.py:411 msgid "license (other)" msgstr "licence (autre)" -#: savane/svmain/models.py:413 +#: savane/svmain/models.py:415 msgid "development status" msgstr "stade de développement" -#: savane/svmain/models.py:611 templates/svmain/group_admin_members.html:20 +#: savane/svmain/models.py:613 templates/svmain/group_admin_members.html:20 msgid "Admin" msgstr "Admin" -#: savane/svmain/models.py:614 +#: savane/svmain/models.py:616 msgid "Pending moderation" msgstr "En attente de modération" -#: savane/svmain/models.py:615 +#: savane/svmain/models.py:617 msgid "Squad" msgstr "Escouade" -#: savane/svmain/models.py:618 +#: savane/svmain/models.py:620 msgid "membership properties" msgstr "propriété de l'appartenance à un projet" -#: savane/svmain/models.py:620 +#: savane/svmain/models.py:622 msgid "Untick to hide emeritous members from the project page" msgstr "Décocher pour masquer les membres émérites de la page de projet" @@ -561,104 +569,104 @@ msgid "Created" msgstr "Créée" -#: savane/svmain/urls.py:56 templates/base.html:29 +#: savane/svmain/urls.py:64 templates/base.html:49 msgid "Users" msgstr "Utilisateurs" -#: savane/svmain/urls.py:62 +#: savane/svmain/urls.py:70 msgid "User detail" msgstr "" -#: savane/svmain/urls.py:76 templates/base.html:30 +#: savane/svmain/urls.py:84 templates/base.html:50 msgid "Projects" msgstr "Projets" -#: savane/svmain/urls.py:90 +#: savane/svmain/urls.py:98 msgid "Project memberlist" msgstr "Liste des membres du projet" -#: savane/svmain/urls.py:95 +#: savane/svmain/urls.py:103 msgid "Project members GPG keyring" msgstr "Trousseau de clefs GPG des membres du projet" -#: savane/svmain/urls.py:100 savane/svmain/templatetags/svtopmenu.py:75 +#: savane/svmain/urls.py:108 savane/svmain/templatetags/svtopmenu.py:75 msgid "Mailing lists" msgstr "Listes de discussion" -#: savane/svmain/urls.py:106 +#: savane/svmain/urls.py:114 msgid "CVS Repositories" msgstr "Dépôts CVS" -#: savane/svmain/urls.py:113 +#: savane/svmain/urls.py:121 msgid "Subversion Repositories" msgstr "Dépôts Subversion" -#: savane/svmain/urls.py:120 +#: savane/svmain/urls.py:128 msgid "GNU Arch Repositories" msgstr "Dépôts GNU Arch" -#: savane/svmain/urls.py:127 +#: savane/svmain/urls.py:135 msgid "Git Repositories" msgstr "Dépôts Git" -#: savane/svmain/urls.py:134 +#: savane/svmain/urls.py:142 msgid "Mercurial Repositories" msgstr "Dépôts Mercurial" -#: savane/svmain/urls.py:141 +#: savane/svmain/urls.py:149 msgid "Bazaar Repositories" msgstr "Dépôts Bazaar" -#: savane/svmain/urls.py:155 +#: savane/svmain/urls.py:163 msgid "Editing public info" msgstr "Modifier les infos publiques" -#: savane/svmain/urls.py:158 savane/svmain/templatetags/svtopmenu.py:59 +#: savane/svmain/urls.py:166 savane/svmain/templatetags/svtopmenu.py:59 msgid "Select features" msgstr "Selectionner les outils" -#: savane/svmain/urls.py:162 savane/svmain/urls.py:165 +#: savane/svmain/urls.py:170 savane/svmain/urls.py:173 #: savane/svmain/templatetags/svtopmenu.py:61 msgid "Manage members" msgstr "Gérer les membres" -#: savane/svmain/urls.py:172 +#: savane/svmain/urls.py:180 msgid "License list" msgstr "Liste des licences" -#: savane/svmain/urls.py:176 +#: savane/svmain/urls.py:184 msgid "License detail" msgstr "Détails de la licence" -#: savane/svmain/views.py:45 +#: savane/svmain/views.py:80 msgid "Request for inclusion already registered" msgstr "La requête d'inclusion est déjà prise en compte" -#: savane/svmain/views.py:49 +#: savane/svmain/views.py:84 msgid "Request for inclusion sent to project administrators" msgstr "La requête d'inclusion a été transmise aux administrateurs" -#: savane/svmain/views.py:120 +#: savane/svmain/views.py:155 #, python-format msgid "GPG Keyring of the project %s" msgstr "Trousseau GPG du projet %s" -#: savane/svmain/views.py:150 savane/svmain/views.py:176 +#: savane/svmain/views.py:185 savane/svmain/views.py:211 #, python-format msgid "%s saved." msgstr "%s enregistré(e)." -#: savane/svmain/views.py:210 savane/svmain/views.py:215 +#: savane/svmain/views.py:245 savane/svmain/views.py:250 #, python-format msgid "Permissions of %s updated." msgstr "Permissions de %s mises à jour." -#: savane/svmain/views.py:219 savane/svmain/views.py:228 +#: savane/svmain/views.py:254 savane/svmain/views.py:263 #, python-format msgid "User %s deleted from the project." msgstr "L'utilisateur %s est supprimé du projet." -#: savane/svmain/views.py:225 savane/svmain/views.py:246 +#: savane/svmain/views.py:260 savane/svmain/views.py:281 #, python-format msgid "User %s added to the project." msgstr "L'utilisateur %s est ajouté au projet." @@ -1087,53 +1095,39 @@ msgid "Back to homepage" msgstr "Retour à la page d'accueil" -#: templates/base.html:18 +#: templates/base.html:20 +#, python-format +msgid "%(username)s logged in as superuser" +msgstr "" + +#: templates/base.html:23 #, python-format msgid "Connected as %(username)s" msgstr "Authentifié(e) en tant que %(username)s" -#: templates/base.html:19 +#: templates/base.html:25 msgid "My account" msgstr "Mon compte" -#: templates/base.html:20 +#: templates/base.html:26 msgid "Logout" msgstr "Retour à l'anonymat" -#: templates/base.html:22 -msgid "Login status" -msgstr "État de la connexion :" - -#: templates/base.html:23 -msgid "Not connected" -msgstr "Vous n'êtes pas authentifié" - -#: templates/base.html:24 -msgid "Login" -msgstr "S'authentifier" - -#: templates/base.html:25 -msgid "New user" -msgstr "Nouvel utilisateur" - -#: templates/base.html:28 templates/svmain/group_admin_members_add.html:20 -#: templates/svmain/group_list.html:9 templates/svmain/user_list.html:9 -msgid "Search" -msgstr "Rechercher" +#: templates/base.html:30 +msgid "Superuser rights are required to perform site admin tasks" +msgstr "" +"Les privilèges de super utilisateur sont requires to accomplir des tâches " +"d'administration du site" + +#: templates/base.html:30 +msgid "Become superuser" +msgstr "Devenir super-utilisateur" #: templates/base.html:32 -msgid "Site help" -msgstr "Aide du site" - -#: templates/base.html:33 -msgid "Contact us" -msgstr "Nous contacter" - -#: templates/title.html:3 -msgid "Welcome" -msgstr "Bienvenue" - -#: templates/my/contact.html:5 templates/my/i18n.html:5 +msgid "Impersonate this user" +msgstr "Se faire passer pour cet utilisateur" + +#: templates/base.html:32 templates/my/contact.html:5 templates/my/i18n.html:5 #: templates/my/resume_skill.html:5 templates/my/ssh.html:5 #: templates/svmain/group_admin_features.html:6 #: templates/svmain/group_admin_info.html:6 @@ -1145,6 +1139,47 @@ msgid ": " msgstr " : " +#: templates/base.html:38 +msgid "End the Superuser session, go back to normal user session" +msgstr "Clore la session Superutilisateur, retour à une session classique" + +#: templates/base.html:38 +msgid "Logout Superuser" +msgstr "Retour en mode utilisateur" + +#: templates/base.html:42 +msgid "Login status" +msgstr "État de la connexion :" + +#: templates/base.html:43 +msgid "Not connected" +msgstr "Vous n'êtes pas authentifié" + +#: templates/base.html:44 +msgid "Login" +msgstr "S'authentifier" + +#: templates/base.html:45 +msgid "New user" +msgstr "Nouvel utilisateur" + +#: templates/base.html:48 templates/svmain/group_admin_members_add.html:20 +#: templates/svmain/group_list.html:9 templates/svmain/user_list.html:9 +msgid "Search" +msgstr "Rechercher" + +#: templates/base.html:52 +msgid "Site help" +msgstr "Aide du site" + +#: templates/base.html:53 +msgid "Contact us" +msgstr "Nous contacter" + +#: templates/title.html:3 +msgid "Welcome" +msgstr "Bienvenue" + #: templates/my/contact.html:9 msgid "Change e-mail" msgstr "Modifier l'e-mail" @@ -1222,7 +1257,7 @@ msgid "Your account is now active." msgstr "Votre compte est maintenant actif." -#: templates/registration/login.html:12 +#: templates/registration/login.html:13 msgid "Lost your password?" msgstr "Vous avez perdu votre mot de passe ?" @@ -1511,7 +1546,10 @@ msgid "" "This project has not yet submitted a short description. You can " "%(begin_link)ssubmit it%(end_link)s now." -msgstr "L'administrateur de ce projet n'a pas encore renseigné de description courte. Si vous êtes l'administrateur du projet, vous pouvez %(begin_link)sl'enregistrer maintenant%(end_link)s." +msgstr "" +"L'administrateur de ce projet n'a pas encore renseigné de description " +"courte. Si vous êtes l'administrateur du projet, vous pouvez " +"%(begin_link)sl'enregistrer maintenant%(end_link)s." #: templates/svmain/group_detail.html:55 msgid "Registration date" @@ -2626,9 +2664,6 @@ #~ msgid "Exiting with Error" #~ msgstr "Quitte suite à une erreur" -#~ msgid "Permission Denied" -#~ msgstr "Accès refusé" - #~ msgid "No group chosen" #~ msgstr "Aucun groupe choisi" @@ -3530,14 +3565,6 @@ #~ msgid "Logged in as %s" #~ msgstr "Authentifié(e) en tant que %s" -#~ msgid "Become Superuser" -#~ msgstr "Devenir super utilisateur" - -#~ msgid "Superuser rights are required to perform site admin tasks" -#~ msgstr "" -#~ "Les privilèges de super utilisateur sont requires to accomplir des tâches " -#~ "d'administration du site" - #~ msgid "What's new for me: new items I should have a look at" #~ msgstr "" #~ "Quoi de neuf pour moi : de nouveaux items auquels je devrais jetter un " @@ -3549,12 +3576,6 @@ #~ msgid "Show my bookmarks" #~ msgstr "Consulter mes signets" -#~ msgid "Logout Superuser" -#~ msgstr "Retour en mode utilisateur" - -#~ msgid "End the Superuser session, go back to normal user session" -#~ msgstr "Clore la session Superutilisateur, retour à une session classique" - #~ msgid "End the session, remove the session cookie" #~ msgstr "Clore la session, impliquant la suppression du cookie de session"
--- a/savane/perms.py +++ b/savane/perms.py @@ -18,10 +18,13 @@ import django.contrib.auth.models as auth_models from django.shortcuts import get_object_or_404 +from functools import update_wrapper, wraps +from django.utils.decorators import available_attrs +from django.utils.translation import ugettext, ugettext_lazy as _ from savane.middleware.exception import HttpAppException import savane.svmain.models as svmain_models -def only_project_admin(f, error_msg="Permission Denied"): +def only_project_admin(f, error_msg=_("Permission denied")): """ Decorator to keep non-members out of project administration screens. Identifies the current group using the 'slug' keyword @@ -33,3 +36,19 @@ raise HttpAppException(error_msg) return f(request, *args, **kwargs) return _f + +def sv_user_passes_test(test_func, error_msg=_("Permission denied")): + """ + Like Django's django.contrib.auth.decorators import + user_passes_test but returns an error message instead of + confusingly redirect to the login page. + """ + def decorator(view_func): + def _f(request, *args, **kwargs): + if test_func(request.user): + return view_func(request, *args, **kwargs) + raise HttpAppException(error_msg) + return wraps(view_func, assigned=available_attrs(view_func))(_f) + return decorator + +only_superuser = sv_user_passes_test(lambda u: u.is_superuser, _("You are not superuser"))
--- a/savane/svmain/models.py +++ b/savane/svmain/models.py @@ -152,6 +152,8 @@ timezone = models.CharField(max_length=192, blank=True) theme = models.CharField(max_length=45, blank=True) + superuser_is_enabled = models.BooleanField(default=False) + # Inherit specialized models.Manager with convenience functions objects = auth_models.UserManager() @@ -649,15 +651,13 @@ @staticmethod def is_member(user, group): - return (user.is_superuser or - user.is_staff or + return ((user.is_superuser and user.svuserinfo.superuser_is_enabled) or (not user.is_anonymous() and group.user_set.filter(pk=user.pk).count() > 0)) @staticmethod def is_admin(user, group): - return (user.is_superuser or - user.is_staff or + return ((user.is_superuser and user.svuserinfo.superuser_is_enabled) or (not user.is_anonymous() and Membership.is_member(user, group) and Membership.objects
--- a/savane/svmain/templatetags/qsup.py +++ b/savane/svmain/templatetags/qsup.py @@ -38,3 +38,16 @@ # Update query_string params[param_name] = param_value return { 'text': params.urlencode() } + +@register.inclusion_tag('svmain/identity.html', takes_context=True) +def qsdel(context, param_name): + """ + Same as qsup but removes the entry. + This is preferred to qsup(name, ''). + """ + + params = context['request'].GET.copy() + # Update query_string + if param_name in params: + del params[param_name] + return { 'text': params.urlencode() }
--- a/savane/svmain/urls.py +++ b/savane/svmain/urls.py @@ -26,7 +26,7 @@ import django.contrib.auth.models as auth_models import views from savane.filters import search -from savane.perms import only_project_admin +from savane.perms import only_project_admin, only_superuser from savane.django_utils import decorated_patterns urlpatterns = patterns ('',) @@ -43,6 +43,14 @@ name='contact'), ) +# Superuser actions +urlpatterns += decorated_patterns ('', only_superuser, + url(r'^superuser/toggle/$', views.superuser_toggle, + name='superuser_toggle'), + url(r'^superuser/impersonate/$', views.superuser_impersonate, + name='superuser_impersonate'), +) + # TODO: not sure about the views naming convention - all this # "models in 'svmain', views in 'my'" is getting messy, probably a # mistake from me (Beuc) :P
--- a/savane/svmain/views.py +++ b/savane/svmain/views.py @@ -27,6 +27,41 @@ import forms as svmain_forms from annoying.decorators import render_to + +## +# Superuser +## + +def superuser_toggle(request): + """ + Take user's superuser status into account. By default, the user + works without any special privileges, so (s)he can test the + website as a normal use. + """ + svuserinfo = request.user.svuserinfo + svuserinfo.superuser_is_enabled = not svuserinfo.superuser_is_enabled + svuserinfo.save() + return HttpResponseRedirect(request.REQUEST.get('next', reverse('savane:svmain:homepage'))) + +def superuser_impersonate(request): + """ + Ugly Django self-breakin + """ + u = get_object_or_404(auth_models.User, username=request.POST['username']) + + from django.contrib.auth import SESSION_KEY + data = request.session._get_session() # not documented + data[SESSION_KEY] = u.pk + request.session.modified = True + # data is cached and will be saved as-is by the middleware + + return HttpResponseRedirect(request.REQUEST.get('next', reverse('savane:svmain:homepage'))) + + +## +# Aliases +## + def user_redir(request, slug): u = get_object_or_404(auth_models.User, username=slug) return HttpResponseRedirect(reverse('savane.svmain.user_detail', args=(slug,)))
--- a/templates/base.html +++ b/templates/base.html @@ -3,6 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" lang="{{LANGUAGE_CODE}}" xml:lang="{{LANGUAGE_CODE}}"> <head> {% load i18n %} + {% load qsup %} <title> {% include "title.html" %} [{{ site_name }}] @@ -15,13 +16,33 @@ <!-- sitemenu --> <li><a href="{% url savane:svmain:homepage %}"><img src="{{STATIC_MEDIA_URL}}savane/images/floating.png" alt="{% trans "Back to homepage" %}" border="0" width="148" height="125" /></a></li> {% if user.is_authenticated %} + {% if user.is_superuser and user.svuserinfo.superuser_is_enabled %} + <li class="menutitle"><span class="warn"> + {% blocktrans with user.username as username %}{{username}} logged in as superuser{% endblocktrans %} + </span></li> + {% else %} <li class="menutitle">{% blocktrans with user.username as username %}Connected as {{username}}{% endblocktrans %}</li> + {% endif %} <li class="menuitem"><a href="{% url savane:my:index %}">{% trans "My account" %}</a></li> <li class="menuitem"><a href="{% url django.contrib.auth.views.logout %}">{% trans "Logout" %}</a></li> + {% if user.is_superuser %} + {% if not user.svuserinfo.superuser_is_enabled %} + <li class="menuitem"><a href="{% url savane:svmain:superuser_toggle %}?next={{request.get_full_path|urlencode}}" + title="{% trans "Superuser rights are required to perform site admin tasks" %}">{% trans "Become superuser" %}</a></li> + {% else %} + <li>{% trans "Impersonate this user" %}{% trans ": " %}<br /> + <form method="post" action="{% url savane:svmain:superuser_impersonate %}">{% csrf_token %} + <input type="hidden" name="next" value="{{request.get_full_path}}" /> + <input type="text" name="username" size="10" /> + </form></li> + <li class="menuitem"><a href="{% url savane:svmain:superuser_toggle %}?next={{request.get_full_path|urlencode}}" + title="{% trans "End the Superuser session, go back to normal user session" %}">{% trans "Logout Superuser" %}</a></li> + {% endif %} + {% endif %} {% else %} <li class="menutitle">{% trans "Login status" %}</li> <li class="menuitem"><span class="error">{% trans "Not connected" %}</span></li> - <li class="menuitem"><a href="{% url django.contrib.auth.views.login %}?next={{request.get_full_path}}">{% trans "Login" %}</a></li> + <li class="menuitem"><a href="{% url django.contrib.auth.views.login %}?next={{request.get_full_path|urlencode}}">{% trans "Login" %}</a></li> <li class="menuitem"><a href="{% url registration_register %}">{% trans "New user" %}</a></li> {% endif %}