"""
Routes configuration
The more specific and detailed routes should be defined first so they
may take precedent over the more generic routes. For more information
refer to the routes manual at http://routes.groovie.org/docs/
from __future__ import with_statement
from routes import Mapper
from rhodecode.lib.utils import check_repo_fast as cr
def make_map(config):
"""Create, configure and return the routes Mapper"""
map = Mapper(directory=config['pylons.paths']['controllers'],
always_scan=config['debug'])
map.minimization = False
map.explicit = False
def check_repo(environ, match_dict):
check for valid repository for proper 404 handling
:param environ:
:param match_dict:
repo_name = match_dict.get('repo_name')
return not cr(repo_name, config['base_path'])
# The ErrorController route (handles 404/500 error pages); it should
# likely stay at the top, ensuring it can always be resolved
map.connect('/error/{action}', controller='error')
map.connect('/error/{action}/{id}', controller='error')
#==========================================================================
# CUSTOM ROUTES HERE
#MAIN PAGE
map.connect('home', '/', controller='home', action='index')
map.connect('bugtracker', "http://bitbucket.org/marcinkuzminski/rhodecode/issues", _static=True)
map.connect('gpl_license', "http://www.gnu.org/licenses/gpl.html", _static=True)
#ADMIN REPOSITORY REST ROUTES
with map.submapper(path_prefix='/_admin', controller='admin/repos') as m:
m.connect("repos", "/repos",
action="create", conditions=dict(method=["POST"]))
action="index", conditions=dict(method=["GET"]))
m.connect("formatted_repos", "/repos.{format}",
action="index",
conditions=dict(method=["GET"]))
m.connect("new_repo", "/repos/new",
action="new", conditions=dict(method=["GET"]))
m.connect("formatted_new_repo", "/repos/new.{format}",
m.connect("/repos/{repo_name:.*}",
action="update", conditions=dict(method=["PUT"],
function=check_repo))
action="delete", conditions=dict(method=["DELETE"],
m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
action="edit", conditions=dict(method=["GET"],
m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
m.connect("repo", "/repos/{repo_name:.*}",
action="show", conditions=dict(method=["GET"],
m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
#ajax delete repo perm user
m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
action="delete_perm_user", conditions=dict(method=["DELETE"],
#settings actions
m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
action="repo_stats", conditions=dict(method=["DELETE"],
m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
action="repo_cache", conditions=dict(method=["DELETE"],
#ADMIN USER REST ROUTES
map.resource('user', 'users', controller='admin/users', path_prefix='/_admin')
#ADMIN PERMISSIONS REST ROUTES
map.resource('permission', 'permissions', controller='admin/permissions', path_prefix='/_admin')
map.connect('permissions_ldap', '/_admin/permissions_ldap', controller='admin/permissions', action='ldap')
##ADMIN LDAP SETTINGS
map.connect('ldap_settings', '/_admin/ldap', controller='admin/ldap_settings',
action='ldap_settings', conditions=dict(method=["POST"]))
map.connect('ldap_home', '/_admin/ldap', controller='admin/ldap_settings',)
#ADMIN SETTINGS REST ROUTES
with map.submapper(path_prefix='/_admin', controller='admin/settings') as m:
m.connect("admin_settings", "/settings",
m.connect("formatted_admin_settings", "/settings.{format}",
m.connect("admin_new_setting", "/settings/new",
m.connect("formatted_admin_new_setting", "/settings/new.{format}",
m.connect("/settings/{setting_id}",
action="update", conditions=dict(method=["PUT"]))
action="delete", conditions=dict(method=["DELETE"]))
m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
action="edit", conditions=dict(method=["GET"]))
m.connect("formatted_admin_edit_setting", "/settings/{setting_id}.{format}/edit",
m.connect("admin_setting", "/settings/{setting_id}",
action="show", conditions=dict(method=["GET"]))
m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
m.connect("admin_settings_my_account", "/my_account",
action="my_account", conditions=dict(method=["GET"]))
m.connect("admin_settings_my_account_update", "/my_account_update",
action="my_account_update", conditions=dict(method=["PUT"]))
m.connect("admin_settings_create_repository", "/create_repository",
action="create_repository", conditions=dict(method=["GET"]))
#ADMIN MAIN PAGES
with map.submapper(path_prefix='/_admin', controller='admin/admin') as m:
m.connect('admin_home', '', action='index')#main page
m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
action='add_repo')
#USER JOURNAL
map.connect('journal', '/_admin/journal', controller='journal',)
map.connect('toggle_following', '/_admin/toggle_following', controller='journal',
action='toggle_following', conditions=dict(method=["POST"]))
#SEARCH
map.connect('search', '/_admin/search', controller='search',)
map.connect('search_repo', '/_admin/search/{search_repo:.*}', controller='search')
#LOGIN/LOGOUT/REGISTER/SIGN IN
map.connect('login_home', '/_admin/login', controller='login')
map.connect('logout_home', '/_admin/logout', controller='login', action='logout')
map.connect('register', '/_admin/register', controller='login', action='register')
map.connect('reset_password', '/_admin/password_reset', controller='login', action='password_reset')
#FEEDS
map.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
controller='feed', action='rss',
conditions=dict(function=check_repo))
map.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
controller='feed', action='atom',
#REPOSITORY ROUTES
map.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
controller='changeset', revision='tip',
map.connect('raw_changeset_home', '/{repo_name:.*}/raw-changeset/{revision}',
controller='changeset', action='raw_changeset', revision='tip',
map.connect('summary_home', '/{repo_name:.*}/summary',
controller='summary', conditions=dict(function=check_repo))
map.connect('shortlog_home', '/{repo_name:.*}/shortlog',
controller='shortlog', conditions=dict(function=check_repo))
map.connect('branches_home', '/{repo_name:.*}/branches',
controller='branches', conditions=dict(function=check_repo))
map.connect('tags_home', '/{repo_name:.*}/tags',
controller='tags', conditions=dict(function=check_repo))
map.connect('changelog_home', '/{repo_name:.*}/changelog',
controller='changelog', conditions=dict(function=check_repo))
map.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
controller='files', revision='tip', f_path='',
map.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
controller='files', action='diff', revision='tip', f_path='',
map.connect('files_rawfile_home', '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
controller='files', action='rawfile', revision='tip', f_path='',
map.connect('files_raw_home', '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
controller='files', action='raw', revision='tip', f_path='',
map.connect('files_annotate_home', '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
controller='files', action='annotate', revision='tip', f_path='',
new file 100644
# -*- coding: utf-8 -*-
package.rhodecode.controllers.admin.ldap_settings
~~~~~~~~~~~~~~
ldap controller for RhodeCode
:created_on: Nov 26, 2010
:author: marcink
:copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
# 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; version 2
# of the License or (at your opinion) any later version of the license.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
import logging
import formencode
import traceback
from formencode import htmlfill
from pylons import request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect
from pylons.i18n.translation import _
from rhodecode.lib.base import BaseController, render
from rhodecode.lib import helpers as h
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
from rhodecode.lib.auth_ldap import LdapImportError
from rhodecode.model.settings import SettingsModel
from rhodecode.model.forms import LdapSettingsForm
from sqlalchemy.exc import DatabaseError
log = logging.getLogger(__name__)
class LdapSettingsController(BaseController):
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
def __before__(self):
c.admin_user = session.get('admin_user')
c.admin_username = session.get('admin_username')
super(LdapSettingsController, self).__before__()
def index(self):
defaults = SettingsModel().get_ldap_settings()
return htmlfill.render(
render('admin/ldap/ldap.html'),
defaults=defaults,
encoding="UTF-8",
force_defaults=True,)
def ldap_settings(self):
POST ldap create and store ldap settings
settings_model = SettingsModel()
_form = LdapSettingsForm()()
try:
form_result = _form.to_python(dict(request.POST))
for k, v in form_result.items():
if k.startswith('ldap_'):
setting = settings_model.get(k)
setting.app_settings_value = v
self.sa.add(setting)
self.sa.commit()
h.flash(_('Ldap settings updated successfully'),
category='success')
except (DatabaseError,):
raise
except LdapImportError:
h.flash(_('Unable to activate ldap. The "ldap-python" library '
'is missing.'), category='warning')
except formencode.Invalid, errors:
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8")
except Exception:
log.error(traceback.format_exc())
h.flash(_('error occured during update of ldap settings'),
category='error')
return redirect(url('ldap_home'))
@@ -17,202 +17,154 @@
from pylons import request, session, tmpl_context as c, url
from rhodecode.model.forms import LdapSettingsForm, DefaultPermissionsForm
from rhodecode.model.permission import PermissionModel
from rhodecode.model.user import UserModel
class PermissionsController(BaseController):
"""REST Controller styled on the Atom Publishing Protocol"""
# To properly map this controller, ensure your config/routing.py
# file has a resource setup:
# map.resource('permission', 'permissions')
super(PermissionsController, self).__before__()
self.perms_choices = [('repository.none', _('None'),),
('repository.read', _('Read'),),
('repository.write', _('Write'),),
('repository.admin', _('Admin'),)]
self.register_choices = [
('hg.register.none',
_('disabled')),
('hg.register.manual_activate',
_('allowed with manual account activation')),
('hg.register.auto_activate',
_('allowed with automatic account activation')), ]
self.create_choices = [('hg.create.none', _('Disabled')),
('hg.create.repository', _('Enabled'))]
def index(self, format='html'):
"""GET /permissions: All items in the collection"""
# url('permissions')
def create(self):
"""POST /permissions: Create a new item"""
def new(self, format='html'):
"""GET /permissions/new: Form to create a new item"""
# url('new_permission')
def update(self, id):
"""PUT /permissions/id: Update an existing item"""
# Forms posted to this method should contain a hidden field:
# <input type="hidden" name="_method" value="PUT" />
# Or using helpers:
# h.form(url('permission', id=ID),
# method='put')
# url('permission', id=ID)
permission_model = PermissionModel()
_form = DefaultPermissionsForm([x[0] for x in self.perms_choices],
[x[0] for x in self.register_choices],
[x[0] for x in self.create_choices])()
form_result.update({'perm_user_name':id})
permission_model.update(form_result)
h.flash(_('Default permissions updated successfully'),
c.perms_choices = self.perms_choices
c.register_choices = self.register_choices
c.create_choices = self.create_choices
defaults = errors.value
defaults.update(SettingsModel().get_ldap_settings())
render('admin/permissions/permissions.html'),
h.flash(_('error occured during update of permissions'),
return redirect(url('edit_permission', id=id))
def delete(self, id):
"""DELETE /permissions/id: Delete an existing item"""
# <input type="hidden" name="_method" value="DELETE" />
# method='delete')
def show(self, id, format='html'):
"""GET /permissions/id: Show a specific item"""
def edit(self, id, format='html'):
"""GET /permissions/id/edit: Form to edit an existing item"""
#url('edit_permission', id=ID)
if id == 'default':
default_user = UserModel().get_by_username('default')
defaults = {'_method':'put',
'anonymous':default_user.active}
for p in default_user.user_perms:
if p.permission.permission_name.startswith('repository.'):
defaults['default_perm'] = p.permission.permission_name
if p.permission.permission_name.startswith('hg.register.'):
defaults['default_register'] = p.permission.permission_name
if p.permission.permission_name.startswith('hg.create.'):
defaults['default_create'] = p.permission.permission_name
else:
return redirect(url('admin_home'))
def ldap(self, id_user='default'):
except:
'is missing.'),
category='warning')
return redirect(url('edit_permission', id=id_user))
@@ -386,192 +386,199 @@ top:9px;
#header #header-inner #quick li ul li {
border-bottom:1px solid #ddd;
}
#header #header-inner #quick li ul li a {
width:182px;
height:auto;
display:block;
float:left;
background:#FFF;
color:#003367;
font-weight:400;
margin:0;
padding:7px 9px;
#header #header-inner #quick li ul li a:hover {
color:#000;
#header #header-inner #quick ul ul {
top:auto;
#header #header-inner #quick li ul ul {
right:200px;
max-height:275px;
overflow:auto;
overflow-x:hidden;
white-space:normal;
#header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover {
background:url("../images/icons/book.png") no-repeat scroll 4px 9px #FFF;
width:167px;
padding:12px 9px 7px 24px;
#header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover {
background:url("../images/icons/lock.png") no-repeat scroll 4px 9px #FFF;
min-width:167px;
#header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover {
background:url("../images/icons/lock_open.png") no-repeat scroll 4px 9px #FFF;
#header #header-inner #quick li ul li a.hg,#header #header-inner #quick li ul li a.hg:hover {
background:url("../images/icons/hgicon.png") no-repeat scroll 4px 9px #FFF;
margin:0 0 0 14px;
#header #header-inner #quick li ul li a.git,#header #header-inner #quick li ul li a.git:hover {
background:url("../images/icons/giticon.png") no-repeat scroll 4px 9px #FFF;
#header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover {
background:url("../images/icons/database_edit.png") no-repeat scroll 4px 9px #FFF;
#header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover {
background:#FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover {
background:#FFF url("../images/icons/cog.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover {
background:#FFF url("../images/icons/key.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.ldap,#header #header-inner #quick li ul li a.ldap:hover {
background:#FFF url("../images/icons/server_key.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover {
background:#FFF url("../images/icons/arrow_divide.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover {
background:#FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover {
background:#FFF url("../images/icons/delete.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover {
background:#FFF url("../images/icons/arrow_branch.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.tags,#header #header-inner #quick li ul li a.tags:hover {
background:#FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
#header #header-inner #quick li ul li a.admin,#header #header-inner #quick li ul li a.admin:hover {
background:#FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
#content #left {
left:0;
width:280px;
position:absolute;
#content #right {
margin:0 60px 10px 290px;
#content div.box {
clear:both;
overflow:hidden;
background:#fff;
margin:0 0 10px;
padding:0 0 10px;
#content div.box-left {
width:49%;
clear:none;
#content div.box-right {
float:right;
#content div.box div.title {
background:#369 url("../images/header_inner.png") repeat-x;
margin:0 0 20px;
padding:0;
#content div.box div.title h5 {
border:none;
color:#fff;
text-transform:uppercase;
padding:11px 0 11px 10px;
#content div.box div.title ul.links li {
list-style:none;
## -*- coding: utf-8 -*-
<%inherit file="/base/base.html"/>
<%def name="title()">
${_('LDAP administration')} - ${c.rhodecode_name}
</%def>
<%def name="breadcrumbs_links()">
${h.link_to(_('Admin'),h.url('admin_home'))}
»
${_('Ldap')}
<%def name="page_nav()">
${self.menu('admin')}
<%def name="main()">
<div class="box">
<!-- box / title -->
<div class="title">
${self.breadcrumbs()}
</div>
<h3>${_('LDAP administration')}</h3>
${h.form(url('ldap_settings'))}
<div class="form">
<div class="fields">
<div class="field">
<div class="label label-checkbox"><label for="ldap_active">${_('Enable ldap')}</label></div>
<div class="checkboxes"><div class="checkbox">${h.checkbox('ldap_active',True,class_='small')}</div></div>
<div class="label"><label for="ldap_host">${_('Host')}</label></div>
<div class="input">${h.text('ldap_host',class_='small')}</div>
<div class="label"><label for="ldap_port">${_('Port')}</label></div>
<div class="input">${h.text('ldap_port',class_='small')}</div>
<div class="label label-checkbox"><label for="ldap_ldaps">${_('Enable LDAPS')}</label></div>
<div class="checkboxes"><div class="checkbox">${h.checkbox('ldap_ldaps',True,class_='small')}</div></div>
<div class="label"><label for="ldap_dn_user">${_('Account')}</label></div>
<div class="input">${h.text('ldap_dn_user',class_='small')}</div>
<div class="label"><label for="ldap_dn_pass">${_('Password')}</label></div>
<div class="input">${h.password('ldap_dn_pass',class_='small')}</div>
<div class="label"><label for="ldap_base_dn">${_('Base DN')}</label></div>
<div class="input">${h.text('ldap_base_dn',class_='small')}</div>
<div class="buttons">
${h.submit('save','Save',class_="ui-button ui-widget ui-state-default ui-corner-all")}
${h.end_form()}
${_('Permissions administration')} - ${c.rhodecode_name}
${_('Permissions')}
<h3>${_('Default permissions')}</h3>
${h.form(url('permission', id='default'),method='put')}
<!-- fields -->
<div class="label label-checkbox">
<label for="anonymous">${_('Anonymous access')}:</label>
<div class="checkboxes">
<div class="checkbox">
${h.checkbox('anonymous',True)}
<div class="label label-select">
<label for="default_perm">${_('Repository permission')}:</label>
<div class="select">
${h.select('default_perm','',c.perms_choices)}
${h.checkbox('overwrite_default','true')}
<label for="overwrite_default">
<span class="tooltip"
tooltip_title="${h.tooltip(_('All default permissions on each repository will be reset to choosen permission, note that all custom default permission on repositories will be lost'))}">
${_('overwrite existing settings')}</span> </label>
<div class="label">
<label for="default_register">${_('Registration')}:</label>
${h.select('default_register','',c.register_choices)}
<label for="default_create">${_('Repository creation')}:</label>
${h.select('default_create','',c.create_choices)}
${h.submit('set','set',class_="ui-button ui-widget ui-state-default ui-corner-all")}
##LDAP
<h3>${_('LDAP settings')}</h3>
${h.form(url('permissions_ldap',id_iser='default'),method='put')}
@@ -111,246 +111,244 @@
%for repo in c.cached_repo_list:
%if repo['repo'].dbrepo.private:
<li><img src="/images/icons/lock.png" alt="${_('Private repository')}" class="repo_switcher_type"/>${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['repo'].dbrepo.repo_type)}</li>
%else:
<li><img src="/images/icons/lock_open.png" alt="${_('Public repository')}" class="repo_switcher_type" />${h.link_to(repo['repo'].name,h.url('summary_home',repo_name=repo['repo'].name),class_="%s" % repo['repo'].dbrepo.repo_type)}</li>
%endif
%endfor
</ul>
</li>
<li ${is_current('summary')}>
<a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
<span class="icon">
<img src="/images/icons/clipboard_16.png" alt="${_('Summary')}" />
</span>
<span>${_('Summary')}</span>
</a>
##<li ${is_current('shortlog')}>
## <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}">
## <span class="icon">
## <img src="/images/icons/application_view_list.png" alt="${_('Shortlog')}" />
## </span>
## <span>${_('Shortlog')}</span>
## </a>
##</li>
<li ${is_current('changelog')}>
<a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
<img src="/images/icons/time.png" alt="${_('Changelog')}" />
<span>${_('Changelog')}</span>
<li ${is_current('switch_to')}>
<a title="${_('Switch to')}" href="#">
<img src="/images/icons/arrow_switch.png" alt="${_('Switch to')}" />
<span>${_('Switch to')}</span>
<ul>
<li>
${h.link_to('%s (%s)' % (_('branches'),len(c.repository_branches.values()),),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')}
%if c.repository_branches.values():
%for cnt,branch in enumerate(c.repository_branches.items()):
<li>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li>
<li>${h.link_to(_('There are no branches yet'),'#')}</li>
${h.link_to('%s (%s)' % (_('tags'),len(c.repository_tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')}
%if c.repository_tags.values():
%for cnt,tag in enumerate(c.repository_tags.items()):
<li>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li>
<li>${h.link_to(_('There are no tags yet'),'#')}</li>
<li ${is_current('files')}>
<a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}">
<img src="/images/icons/file.png" alt="${_('Files')}" />
<span>${_('Files')}</span>
<li ${is_current('options')}>
<a title="${_('Options')}" href="#">
<img src="/images/icons/table_gear.png" alt="${_('Admin')}" />
<span>${_('Options')}</span>
%if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
<li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
<li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
<li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li>
%if h.HasPermissionAll('hg.admin')('access admin main page'):
${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
<%def name="admin_menu()">
<li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li>
<li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
<li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
<li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
<li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
<li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
${admin_menu()}
<a title="${_('Followers')}" href="#">
<span class="icon_short">
<img src="/images/icons/heart.png" alt="${_('Followers')}" />
<span class="short">${c.repository_followers}</span>
<a title="${_('Forks')}" href="#">
<img src="/images/icons/arrow_divide.png" alt="${_('Forks')}" />
<span class="short">${c.repository_forks}</span>
##ROOT MENU
<ul id="quick">
<a title="${_('Home')}" href="${h.url('home')}">
<img src="/images/icons/home_16.png" alt="${_('Home')}" />
<span>${_('Home')}</span>
<a title="${_('Journal')}" href="${h.url('journal')}">
<img src="/images/icons/book.png" alt="${_('Journal')}" />
<span>${_('Journal')}</span>
<a title="${_('Search')}" href="${h.url('search')}">
<img src="/images/icons/search_16.png" alt="${_('Search')}" />
<span>${_('Search')}</span>
<li ${is_current('admin')}>
<a title="${_('Admin')}" href="${h.url('admin_home')}">
<img src="/images/icons/cog_edit.png" alt="${_('Admin')}" />
<span>${_('Admin')}</span>
<%def name="css()">
<link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/css/pygments.css" />
<link rel="stylesheet" type="text/css" href="/css/diff.css" />
<%def name="js()">
##<script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
##<script type="text/javascript" src="/js/yui/container/container.js"></script>
##<script type="text/javascript" src="/js/yui/datasource/datasource.js"></script>
##<script type="text/javascript" src="/js/yui/autocomplete/autocomplete.js"></script>
##<script type="text/javascript" src="/js/yui/selector/selector-min.js"></script>
<script type="text/javascript" src="/js/yui2a.js"></script>
<!--[if IE]><script language="javascript" type="text/javascript" src="/js/excanvas.min.js"></script><![endif]-->
<script type="text/javascript" src="/js/yui.flot.js"></script>
<script type="text/javascript">
var base_url ='/_admin/toggle_following';
var YUC = YAHOO.util.Connect;
var YUD = YAHOO.util.Dom;
var YUE = YAHOO.util.Event;
function onSuccess(){
var f = YUD.get('follow_toggle');
if(f.getAttribute('class')=='follow'){
f.setAttribute('class','following');
f.setAttribute('title',"${_('Stop following this repository')}");
else{
f.setAttribute('class','follow');
f.setAttribute('title',"${_('Start following this repository')}");
function toggleFollowingUser(fallows_user_id,token){
args = 'follows_user_id='+fallows_user_id;
args+= '&auth_token='+token;
YUC.asyncRequest('POST',base_url,{
success:function(o){
onSuccess();
},args); return false;
function toggleFollowingRepo(fallows_repo_id,token){
args = 'follows_repo_id='+fallows_repo_id;
</script>
<%def name="breadcrumbs()">
<div class="breadcrumbs">
${self.breadcrumbs_links()}
\ No newline at end of file
from rhodecode.tests import *
class TestLdapSettingsController(TestController):
def test_index(self):
response = self.app.get(url(controller='admin/ldap_settings', action='index'))
# Test response...
Status change: