admin: change to be a redirect to /admin/$1 (#6726)

This commit is contained in:
Frédéric Péters 2015-04-22 11:35:56 +02:00
parent 9e058cb1f7
commit 7ccfa19c3b
5 changed files with 40 additions and 217 deletions

View File

@ -73,6 +73,11 @@ def test_with_superuser():
app = login(get_app(pub))
app.get('/admin/')
def test_admin_redirect():
create_superuser()
app = login(get_app(pub))
assert app.get('/admin/whatever', status=302).location == 'http://example.net/backoffice/whatever'
def test_forms():
app = login(get_app(pub))
resp = app.get('/admin/forms/')

View File

@ -1,18 +0,0 @@
# w.c.s. - web application for online forms
# Copyright (C) 2005-2010 Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
from qommon.backoffice.menu import html_top
from qommon.admin.menu import command_icon, error_page, get_vc_version

View File

@ -16,22 +16,9 @@
import os
from quixote import get_session, get_publisher, get_request, get_response
from quixote.directory import Directory, AccessControlled
from quixote.html import htmltext, TemplateIO
from qommon.admin.root import AdminDirectory
import settings
import forms
import roles
import users
import categories
import logger
import workflows
import bounces
from qommon import errors, get_cfg
from quixote import get_request, redirect
from quixote.directory import Directory
from quixote.html import htmltext
def gpl():
return htmltext("""<p>This program is free software; you can redistribute it and/or modify it
@ -50,19 +37,8 @@ def gpl():
""")
class RootDirectory(AccessControlled, AdminDirectory):
_q_exports = ['']
settings = settings.SettingsDirectory()
forms = forms.FormsDirectory()
roles = roles.RolesDirectory()
users = users.UsersDirectory()
categories = categories.CategoriesDirectory()
logger = logger.LoggerDirectory()
workflows = workflows.WorkflowsDirectory()
bounces = bounces.BouncesDirectory()
menu_items = [
class RootDirectory(Directory):
menu_items = [ # still used for access control (permissions panel)
('forms/', N_('Forms')),
('workflows/', N_('Workflows')),
('users/', N_('Users')),
@ -73,91 +49,10 @@ class RootDirectory(AccessControlled, AdminDirectory):
('settings/', N_('Settings')),
('/', N_('WCS Form Server'))]
def _q_access(self):
get_response().breadcrumb.append( ('admin/', _('Administration')) )
req = get_request()
if os.path.exists(os.path.join(get_publisher().app_dir, 'ADMIN_FOR_ALL')):
get_response().filter['admin_for_all'] = True
if req.user and req.user.is_admin:
# if the user had access to the admin, ADMIN_FOR_ALL was
# certainly added because something wrong happened when setting
# fine-grained access permissions with roles; so we give the
# user all possible roles.
req.user.roles = [x.id for x in roles.Role.select()]
return
session = get_session()
if req.user:
if get_publisher().user_class.count() == 0:
# this means user logged in anonymously
pass
elif not req.user.is_admin:
raise errors.AccessForbiddenError()
else:
if get_publisher().user_class.count() > 0:
raise errors.AccessUnauthorizedError()
return
def get_intro_text(self):
return _('''
w.c.s. is a web application which allows to design and set up online forms.
It gives users the ability to create web forms easily without requiring any
other skill than familiarity with web surfing.''')
def _q_index(self):
from menu import html_top
html_top('/')
r = TemplateIO(html=True)
r += htmltext('<div class="bo-block"><p>%s</p></div>') % self.get_intro_text()
r += htmltext('<ul class="apps">')
for k, v in self.get_menu_items():
if k.strip('/') not in ('forms', 'workflows', 'users', 'roles',
'categories', 'settings'):
# limit this space to menu entries that have icons.
continue
r += htmltext('<li class="zone-%s"><a href="%s">') % (k.strip('/'), k)
if callable(v):
r += v()
else:
r += _(v)
r += htmltext('</a></li>')
r += htmltext('</ul>')
r += htmltext('<br class="clear">')
r += htmltext('<p id="for-more-info">%s</p>') % _('For more information:')
r += htmltext('<ul>')
r += htmltext('<li><a href="http://wcs.labs.libre-entreprise.org">%s</a></li>') % _('Web site')
if get_publisher().admin_help_url and get_request().language in get_publisher().admin_help_url:
doc_url = get_publisher().admin_help_url[get_request().language]
r += htmltext('<li><a href="%s">%s</a></li>') % (doc_url, _('Online documentation'))
r += htmltext('</ul>')
get_response().filter['sidebar'] = str(self.get_sidebar())
return r.getvalue()
def get_sidebar(self):
from menu import get_vc_version
r = TemplateIO(html=True)
version = get_vc_version()
if version:
r += htmltext('<div class="bo-block"><p class="version-info">')
r += _('Version:')
r += ' '
r += version
r += htmltext('</p></div>')
r += htmltext('<div class="bo-block">')
r += gpl()
r += htmltext('</div>')
return r.getvalue()
def _q_traverse(self, path):
url = get_request().get_path_query()
url = url.replace('/admin/', '/backoffice/', 1)
return redirect(url)
def register_page(cls, url_name, directory = None, label = None):
if directory:
@ -173,35 +68,3 @@ other skill than familiarity with web surfing.''')
cls.menu_items.insert(logger_index, (url_name, label))
register_page = classmethod(register_page)
def _q_lookup(self, component):
if not component in [str(x[0]).strip('/') for x in self.menu_items]:
raise errors.TraversalError()
authorised_roles = get_cfg('admin-permissions', {}).get(component)
if authorised_roles and not os.path.exists(os.path.join(get_publisher().app_dir, 'ADMIN_FOR_ALL')):
user_roles = set(get_request().user.roles)
if not user_roles.intersection(authorised_roles):
raise errors.AccessForbiddenError()
return getattr(self, component)
def get_menu_items(self):
if not get_request().user:
return self.menu_items
user_roles = set(get_request().user.roles or [])
if not get_cfg('admin-permissions', {}):
return self.menu_items
menu_items = self.menu_items[:]
for k, v in self.menu_items:
if not k.endswith(str('/')):
continue
k = k.strip(str('/'))
if not k:
continue
authorised_roles = get_cfg('admin-permissions', {}).get(k)
if not authorised_roles:
continue
if not user_roles.intersection(authorised_roles):
menu_items.remove((k+'/', v))
return menu_items

View File

@ -39,6 +39,7 @@ from wcs.forms.common import FormStatusPage
from wcs.categories import Category
from wcs.formdef import FormDef
from wcs.roles import Role
from wcs.forms.backoffice import FormDefUI
@ -272,6 +273,31 @@ class RootDirectory(BackofficeRootDirectory):
('/', N_('WCS Form Server'))
]
def _q_access(self):
get_response().breadcrumb.append( ('backoffice/', _('Back Office')) )
req = get_request()
if os.path.exists(os.path.join(get_publisher().app_dir, 'ADMIN_FOR_ALL')):
get_response().filter['admin_for_all'] = True
if req.user and req.user.is_admin:
# if the user had access to the admin, ADMIN_FOR_ALL was
# certainly added because something wrong happened when setting
# fine-grained access permissions with roles; so we give the
# user all possible roles.
req.user.roles = [x.id for x in Role.select()]
return
if get_publisher().user_class.count() > 0:
user = req.user
if not user:
raise errors.AccessUnauthorizedError(
public_msg = _('Access to backoffice is restricted to authorized persons only. '\
'Please login.'))
if not user.can_go_in_backoffice():
raise errors.AccessForbiddenError()
get_response().filter['in_backoffice'] = True
def get_intro_text(self):
return _('''Welcome.''')

View File

@ -1,53 +0,0 @@
# w.c.s. - web application for online forms
# Copyright (C) 2005-2012 Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
from quixote import get_publisher
from quixote.directory import Directory
from qommon import get_cfg
from qommon.bounces import Bounce
class AdminDirectory(Directory):
def get_menu_items(self):
return self.menu_items
def generate_header_menu(self, selected=None):
s = ['<ul id="menu">\n']
base_url = get_publisher().get_root_url() + 'admin'
show_logger = get_cfg('debug', {}).get('logger', False)
show_debug = get_cfg('debug', {}).get('debug_panel', False)
show_bounces = (get_cfg('emails', {}).get('bounce_handler') == True and Bounce.count() > 0)
for k, v in self.get_menu_items():
if k == '/':
continue # skip root
if k == 'logger/' and not show_logger:
continue
if k == 'debug/' and not show_debug:
continue
if k == 'bounces/' and not show_bounces:
continue
if k.rstrip('/') == selected:
s.append('<li class="active">')
else:
s.append('<li>')
if callable(v):
s.append('<a href="%s/%s">%s</a></li>\n' % (base_url, k, v()))
else:
s.append('<a href="%s/%s">%s</a></li>\n' % (base_url, k, _(v)))
s.append('</ul>\n')
return ''.join(s)