"""
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='',
map.connect('files_archive_home', '/{repo_name:.*}/archive/{revision}/{fileformat}',
controller='files', action='archivefile', revision='tip',
map.connect('repo_settings_delete', '/{repo_name:.*}/settings',
controller='settings', action="delete",
conditions=dict(method=["DELETE"], function=check_repo))
map.connect('repo_settings_update', '/{repo_name:.*}/settings',
controller='settings', action="update",
conditions=dict(method=["PUT"], function=check_repo))
map.connect('repo_settings_home', '/{repo_name:.*}/settings',
controller='settings', action='index',
map.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
controller='settings', action='fork_create',
conditions=dict(function=check_repo, method=["POST"]))
map.connect('repo_fork_home', '/{repo_name:.*}/fork',
controller='settings', action='fork',
return map
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'))
package.rhodecode.controllers.admin.permissions
permissions controller for Rhodecode
:created_on: Apr 27, 2010
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))
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td {
border:0;
outline:0;
font-size:100%;
vertical-align:baseline;
background:transparent;
margin:0;
padding:0;
}
body {
line-height:1;
height:100%;
background:url("../images/background.png") repeat scroll 0 0 #B0B0B0;
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
font-size:12px;
color:#000;
ol,ul {
list-style:none;
blockquote,q {
quotes:none;
blockquote:before,blockquote:after,q:before,q:after {
content:none;
:focus {
del {
text-decoration:line-through;
table {
border-collapse:collapse;
border-spacing:0;
html {
a {
color:#003367;
text-decoration:none;
cursor:pointer;
font-weight:700;
a:hover {
color:#316293;
text-decoration:underline;
h1,h2,h3,h4,h5,h6 {
color:#292929;
h1 {
font-size:22px;
h2 {
font-size:20px;
h3 {
font-size:18px;
h4 {
font-size:16px;
h5 {
font-size:14px;
h6 {
font-size:11px;
ul.circle {
list-style-type:circle;
ul.disc {
list-style-type:disc;
ul.square {
list-style-type:square;
ol.lower-roman {
list-style-type:lower-roman;
ol.upper-roman {
list-style-type:upper-roman;
ol.lower-alpha {
list-style-type:lower-alpha;
ol.upper-alpha {
list-style-type:upper-alpha;
ol.decimal {
list-style-type:decimal;
div.color {
clear:both;
overflow:hidden;
position:absolute;
background:#FFF;
margin:7px 0 0 60px;
padding:1px 1px 1px 0;
div.color a {
width:15px;
height:15px;
display:block;
float:left;
margin:0 0 0 1px;
div.options {
margin:7px 0 0 162px;
div.options a {
height:1%;
padding:3px 8px;
.top-left-rounded-corner {
-webkit-border-top-left-radius: 8px;
-khtml-border-radius-topleft: 8px;
-moz-border-radius-topleft: 8px;
border-top-left-radius: 8px;
.top-right-rounded-corner {
-webkit-border-top-right-radius: 8px;
-khtml-border-radius-topright: 8px;
-moz-border-radius-topright: 8px;
border-top-right-radius: 8px;
.bottom-left-rounded-corner {
-webkit-border-bottom-left-radius: 8px;
-khtml-border-radius-bottomleft: 8px;
-moz-border-radius-bottomleft: 8px;
border-bottom-left-radius: 8px;
.bottom-right-rounded-corner {
-webkit-border-bottom-right-radius: 8px;
-khtml-border-radius-bottomright: 8px;
-moz-border-radius-bottomright: 8px;
border-bottom-right-radius: 8px;
#header {
padding:0 30px;
#header ul#logged-user li {
border-left:1px solid #bbb;
border-right:1px solid #a5a5a5;
margin:-2px 0 0;
padding:10px 12px;
#header ul#logged-user li.first {
border-left:none;
margin:-6px;
#header ul#logged-user li.first div.account {
padding-top:4px;
#header ul#logged-user li.last {
border-right:none;
#header ul#logged-user li a {
color:#4e4e4e;
#header ul#logged-user li a:hover {
color:#376ea6;
#header ul#logged-user li.highlight a {
color:#fff;
#header ul#logged-user li.highlight a:hover {
#header #header-inner {
height:40px;
position:relative;
background:#003367 url("../images/header_inner.png") repeat-x;
border-bottom:2px solid #fff;
#header #header-inner #home a {
width:46px;
background:url("../images/button_home.png");
background-position:0 0;
#header #header-inner #home a:hover {
background-position:0 -40px;
#header #header-inner #logo h1 {
color:#FFF;
margin:10px 0 0 13px;
#header #header-inner #logo a {
#header #header-inner #logo a:hover {
color:#bfe3ff;
#header #header-inner #quick,#header #header-inner #quick ul {
float:right;
list-style-type:none;
list-style-position:outside;
margin:10px 5px 0 0;
#header #header-inner #quick li {
margin:0 5px 0 0;
#header #header-inner #quick li a {
top:0;
left:0;
background:#369 url("../../images/quick_l.png") no-repeat top left;
#header #header-inner #quick li span.short {
padding:9px 6px 8px 6px;
#header #header-inner #quick li span {
right:0;
background:url("../../images/quick_r.png") no-repeat top right;
border-left:1px solid #3f6f9f;
padding:10px 12px 8px 10px;
#header #header-inner #quick li span.normal {
border:none;
padding:10px 12px 8px;
#header #header-inner #quick li span.icon {
background:url("../../images/quick_l.png") no-repeat top left;
border-right:1px solid #2e5c89;
padding:8px 8px 4px;
#header #header-inner #quick li span.icon_short {
padding:9px 4px 4px;
#header #header-inner #quick li a:hover {
background:#4e4e4e url("../../images/quick_l_selected.png") no-repeat top left;
#header #header-inner #quick li a:hover span {
border-left:1px solid #545454;
background:url("../../images/quick_r_selected.png") no-repeat top right;
#header #header-inner #quick li a:hover span.icon,#header #header-inner #quick li a:hover span.icon_short {
border-right:1px solid #464646;
background:url("../../images/quick_l_selected.png") no-repeat top left;
#header #header-inner #quick ul {
top:29px;
min-width:200px;
display:none;
border:1px solid #666;
border-top:1px solid #003367;
z-index:100;
#header #header-inner #quick ul.repo_switcher {
max-height:275px;
overflow-x:hidden;
overflow-y:auto;
#header #header-inner #quick .repo_switcher_type{
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;
font-weight:400;
padding:7px 9px;
#header #header-inner #quick li ul li a:hover {
#header #header-inner #quick ul ul {
top:auto;
#header #header-inner #quick li ul ul {
right:200px;
overflow:auto;
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 {
width:280px;
#content #right {
margin:0 60px 10px 290px;
#content div.box {
background:#fff;
margin:0 0 10px;
padding:0 0 10px;
#content div.box-left {
width:49%;
clear:none;
#content div.box-right {
#content div.box div.title {
background:#369 url("../images/header_inner.png") repeat-x;
margin:0 0 20px;
#content div.box div.title h5 {
text-transform:uppercase;
padding:11px 0 11px 10px;
#content div.box div.title ul.links li {
#content div.box div.title ul.links li a {
border-left:1px solid #316293;
padding:13px 16px 12px;
#content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6 {
border-bottom:1px solid #DDD;
margin:10px 20px;
padding:0 0 15px;
#content div.box p {
color:#5f5f5f;
line-height:150%;
margin:0 24px 10px;
#content div.box blockquote {
border-left:4px solid #DDD;
margin:0 34px;
padding:0 0 0 14px;
#content div.box blockquote p {
margin:10px 0;
#content div.box dl {
margin:10px 24px;
#content div.box dt {
#content div.box dd {
padding:8px 0 8px 15px;
#content div.box li {
padding:4px 0;
#content div.box ul.disc,#content div.box ul.circle {
margin:10px 24px 10px 38px;
#content div.box ul.square {
margin:10px 24px 10px 40px;
#content div.box img.left {
margin:10px 10px 10px 0;
#content div.box img.right {
margin:10px 0 10px 10px;
#content div.box div.messages {
margin:0 20px;
#content div.box div.message {
padding:10px 0;
#content div.box div.message a {
font-weight:400 !important;
#content div.box div.message div.image {
margin:9px 0 0 5px;
padding:6px;
#content div.box div.message div.image img {
vertical-align:middle;
#content div.box div.message div.text {
padding:9px 6px;
#content div.box div.message div.dismiss a {
height:16px;
width:16px;
background:url("../images/icons/cross.png") no-repeat;
margin:15px 14px 0 0;
#content div.box div.message div.text h1,#content div.box div.message div.text h2,#content div.box div.message div.text h3,#content div.box div.message div.text h4,#content div.box div.message div.text h5,#content div.box div.message div.text h6 {
#content div.box div.message div.text span {
padding:5px 0 0;
#content div.box div.message-error {
background:#FBE3E4;
border:1px solid #FBC2C4;
color:#860006;
#content div.box div.message-error h6 {
#content div.box div.message-warning {
background:#FFF6BF;
border:1px solid #FFD324;
color:#5f5200;
#content div.box div.message-warning h6 {
#content div.box div.message-notice {
background:#8FBDE0;
border:1px solid #6BACDE;
color:#003863;
#content div.box div.message-notice h6 {
#content div.box div.message-success {
background:#E6EFC2;
border:1px solid #C6D880;
color:#4e6100;
#content div.box div.message-success h6 {
#content div.box div.form div.fields div.field {
#content div.box div.form div.fields div.field-first {
#content div.box div.form div.fields div.field-noborder {
border-bottom:0 !important;
#content div.box div.form div.fields div.field span.error-message {
display:inline-block;
color:red;
margin:8px 0 0 4px;
#content div.box div.form div.fields div.field span.success {
color:#316309;
margin:8px 0 0;
#content div.box div.form div.fields div.field div.label {
left:80px;
width:auto;
padding:8px 0 0 5px;
#content div.box-left div.form div.fields div.field div.label,#content div.box-right div.form div.fields div.field div.label {
padding:0 0 8px;
#content div.box div.form div.fields div.field div.label-select {
padding:5px 0 0 5px;
#content div.box-left div.form div.fields div.field div.label-select,#content div.box-right div.form div.fields div.field div.label-select {
#content div.box-left div.form div.fields div.field div.label-textarea,#content div.box-right div.form div.fields div.field div.label-textarea {
padding:0 0 8px !important;
#content div.box div.form div.fields div.field div.label label {
color:#393939;
#content div.box div.form div.fields div.field div.input {
margin:0 0 0 200px;
#content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input {
margin:0 0 0 0px;
#content div.box div.form div.fields div.field div.input input {
border-top:1px solid #b3b3b3;
border-left:1px solid #b3b3b3;
border-right:1px solid #eaeaea;
border-bottom:1px solid #eaeaea;
padding:7px 7px 6px;
#content div.box div.form div.fields div.field div.input input.small {
width:30%;
#content div.box div.form div.fields div.field div.input input.medium {
width:55%;
#content div.box div.form div.fields div.field div.input input.large {
width:85%;
#content div.box div.form div.fields div.field div.input input.date {
width:177px;
#content div.box div.form div.fields div.field div.input input.button {
background:#D4D0C8;
border-top:1px solid #FFF;
border-left:1px solid #FFF;
border-right:1px solid #404040;
border-bottom:1px solid #404040;
padding:4px 8px;
#content div.box div.form div.fields div.field div.input a.ui-input-file {
width:28px;
height:28px;
display:inline;
background:#e5e3e3 url("../images/button_browse.png") no-repeat;
margin:0 0 0 6px;
#content div.box div.form div.fields div.field div.textarea {
padding:10px;
#content div.box div.form div.fields div.field div.textarea-editor {
border:1px solid #ddd;
#content div.box div.form div.fields div.field div.textarea textarea {
width:100%;
height:220px;
outline:none;
border-width:0;
#content div.box-left div.form div.fields div.field div.textarea textarea,#content div.box-right div.form div.fields div.field div.textarea textarea {
height:100px;
#content div.box div.form div.fields div.field div.textarea table {
#content div.box div.form div.fields div.field div.textarea table td {
background:#DDD;
#content div.box div.form div.fields div.field div.textarea table td table {
#content div.box div.form div.fields div.field div.textarea table td table td {
padding:5px 5px 5px 0;
#content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive {
background:#b1b1b1;
#content div.box div.form div.fields div.field div.select a.ui-selectmenu {
color:#565656;
#content div.box div.form div.fields div.field input[type=text]:focus,#content div.box div.form div.fields div.field input[type=password]:focus,#content div.box div.form div.fields div.field input[type=file]:focus,#content div.box div.form div.fields div.field textarea:focus,#content div.box div.form div.fields div.field select:focus {
background:#f6f6f6;
border-color:#666;
div.form div.fields div.field div.button {
padding:0 0 0 8px;
div.form div.fields div.field div.highlight .ui-state-default {
background:#4e85bb url("../images/button_highlight.png") repeat-x;
border-top:1px solid #5c91a4;
border-left:1px solid #2a6f89;
border-right:1px solid #2b7089;
border-bottom:1px solid #1a6480;
padding:6px 12px;
div.form div.fields div.field div.highlight .ui-state-hover {
background:#46a0c1 url("../images/button_highlight_selected.png") repeat-x;
border-top:1px solid #78acbf;
border-left:1px solid #34819e;
border-right:1px solid #35829f;
border-bottom:1px solid #257897;
#content div.box div.form div.fields div.buttons div.highlight input.ui-state-default {
background:#4e85bb url("../../images/button_highlight.png") repeat-x;
#content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover {
background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
#content div.box table {
#content div.box table th {
background:#eee;
padding:5px 0px 5px 5px;
#content div.box table th.left {
text-align:left;
#content div.box table th.right {
text-align:right;
#content div.box table th.center {
text-align:center;
#content div.box table th.selected {
#content div.box table td {
border-bottom:1px solid #cdcdcd;
padding:5px;
#content div.box table tr.selected td {
background:#FFC;
#content div.box table td.selected {
width:3%;
#content div.box table td.action {
width:45%;
#content div.box table td.date {
width:33%;
#content div.box div.action {
margin:10px 0 0;
#content div.box div.action select {
#content div.box div.action .ui-selectmenu {
#content div.box div.pagination {
#content div.box div.pagination ul.pager {
#content div.box div.pagination ul.pager li {
background:#ebebeb url("../images/pager.png") repeat-x;
border-top:1px solid #dedede;
border-left:1px solid #cfcfcf;
border-right:1px solid #c4c4c4;
border-bottom:1px solid #c4c4c4;
color:#4A4A4A;
margin:0 0 0 4px;
#content div.box div.pagination ul.pager li.separator {
#content div.box div.pagination ul.pager li.current {
background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
border-top:1px solid #ccc;
border-left:1px solid #bebebe;
border-right:1px solid #b1b1b1;
border-bottom:1px solid #afafaf;
color:#515151;
#content div.box div.pagination ul.pager li a {
#content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active {
margin:-1px;
#content div.box div.pagination-wh {
#content div.box div.pagination-right {
#content div.box div.pagination-wh a,#content div.box div.pagination-wh span.pager_dotdot {
#content div.box div.pagination-wh span.pager_curpage {
#content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active {
#content div.box div.traffic div.legend {
#content div.box div.traffic div.legend h6 {
#content div.box div.traffic div.legend li {
padding:0 8px 0 4px;
#content div.box div.traffic div.legend li.visits {
border-left:12px solid #edc240;
#content div.box div.traffic div.legend li.pageviews {
border-left:12px solid #afd8f8;
#content div.box div.traffic table {
#content div.box div.traffic table td {
padding:2px 3px 3px;
#content div.box div.traffic table td.legendLabel {
padding:0 3px 2px;
#footer {
padding:0 30px 4px;
margin:-10px 0 0;
#footer div#footer-inner {
background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
border-top:2px solid #FFFFFF;
#footer div#footer-inner p {
padding:15px 25px 15px 0;
#footer div#footer-inner .footer-link {
padding-left:10px;
#footer div#footer-inner .footer-link a {
#login div.title {
width:420px;
background:#003367 url("../../images/header_inner.png") repeat-x;
margin:0 auto;
#login div.inner {
width:380px;
background:#FFF url("../images/login.png") no-repeat top left;
border-top:none;
border-bottom:none;
padding:20px;
#login div.form div.fields div.field div.label {
width:173px;
margin:2px 10px 0 0;
#login div.form div.fields div.field div.input input {
width:176px;
#login div.form div.fields div.buttons {
border-top:1px solid #DDD;
padding:10px 0 0;
#login div.form div.links {
padding:0 0 2px;
#register div.title {
#register div.inner {
#register div.form div.fields div.field div.label {
width:135px;
#register div.form div.fields div.field div.input input {
width:300px;
#register div.form div.fields div.buttons {
padding:10px 0 0 114px;
#register div.form div.fields div.buttons div.highlight input.ui-state-default {
background:url("../images/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
border-style:solid;
border-width:1px;
#register div.form div.activation_msg {
padding-bottom:4px;
.trending_language_tbl,.trending_language_tbl td {
border:0 !important;
margin:0 !important;
padding:0 !important;
.trending_language {
background-color:#003367;
min-width:20px;
height:12px;
margin-bottom:4px;
margin-left:5px;
white-space:pre;
padding:3px;
h3.files_location {
font-size:1.8em;
border-bottom:none !important;
margin:10px 0 !important;
#files_data dl dt {
width:115px;
#files_data dl dd {
padding:5px !important;
#changeset_content {
border:1px solid #CCC;
#changeset_content .container {
min-height:120px;
font-size:1.2em;
#changeset_content .container .right {
width:25%;
#changeset_content .container .left .message {
font-style:italic;
color:#556CB5;
white-space:pre-wrap;
.cs_files .cs_added {
background:url("../images/icons/page_white_add.png") no-repeat scroll 3px;
padding-left:20px;
margin-top:7px;
.cs_files .cs_changed {
background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px;
.cs_files .cs_removed {
background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px;
#graph {
#graph_nodes {
width:160px;
margin-left:-50px;
margin-top:5px;
#graph_content {
width:800px;
#graph_content .container_header {
#graph_content .container {
border-bottom:1px solid #CCC;
border-left:1px solid #CCC;
border-right:1px solid #CCC;
min-height:80px;
#graph_content .container .right {
width:28%;
padding-bottom:5px;
#graph_content .container .left .date {
#graph_content .container .left .message {
padding-top:3px;
.right div {
.right .changes .added,.changed,.removed {
border:1px solid #DDD;
min-width:15px;
.right .changes .added {
background:#BFB;
.right .changes .changed {
background:#FD8;
.right .changes .removed {
background:#F88;
.right .merge {
vertical-align:top;
font-size:0.75em;
.right .parent {
font-size:90%;
font-family:monospace;
.right .logtags .branchtag {
background:#FFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
font-size:0.8em;
padding:11px 16px 0 0;
.right .logtags .tagtag {
background:#FFF url("../images/icons/tag_blue.png") no-repeat right 6px;
div.browserblock {
border:1px solid #ccc;
background:#f8f8f8;
line-height:125%;
div.browserblock .browser-header {
color:blue;
div.browserblock .browser-header span {
margin-left:25px;
div.browserblock .browser-body {
background:#EEE;
table.code-browser {
table.code-browser tr {
margin:3px;
table.code-browser thead th {
background-color:#EEE;
height:20px;
font-size:1.1em;
table.code-browser tbody td {
table.code-browser .browser-file {
background:url("../images/icons/document_16.png") no-repeat scroll 3px;
table.code-browser .browser-dir {
background:url("../images/icons/folder_16.png") no-repeat scroll 3px;
.box .search {
padding:0 20px 10px;
.box .search div.search_path {
background:none repeat scroll 0 0 #EEE;
margin-bottom:10px;
.box .search div.search_path div.link {
.box .search div.search_path div.link a {
#path_unlock {
padding-left:4px;
.info_box * {
background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
padding:4px 6px;
.info_box span {
margin-left:3px;
margin-right:3px;
.info_box input#at_rev {
padding:5px 3px 3px 2px;
.info_box input#view {
padding:4px 3px 2px 2px;
.yui-overlay,.yui-panel-container {
visibility:hidden;
z-index:2;
.yui-tt {
color:#666;
background-color:#FFF;
font-family:arial, helvetica, verdana, sans-serif;
border:2px solid #003367;
font:100% sans-serif;
opacity:1px;
padding:8px;
white-space: pre;
.ac {
.ac .yui-ac {
font-family:arial;
.ac .perm_ac {
width:15em;
.ac .yui-ac-input {
.ac .yui-ac-container {
top:1.6em;
.ac .yui-ac-content {
border:1px solid gray;
z-index:9050;
.ac .yui-ac-shadow {
background:#000;
-moz-opacity:0.1px;
opacity:.10;
filter:alpha(opacity = 10);
z-index:9049;
margin:.3em;
.ac .yui-ac-content ul {
.ac .yui-ac-content li {
cursor:default;
white-space:nowrap;
padding:2px 5px;
.ac .yui-ac-content li.yui-ac-prehighlight {
background:#B3D4FF;
.ac .yui-ac-content li.yui-ac-highlight {
background:#556CB5;
.follow{
background:url("../images/icons/heart_add.png") no-repeat scroll 3px;
height: 16px;
width: 20px;
cursor: pointer;
display: block;
float: right;
margin-top: 2px;
.following{
background:url("../images/icons/heart_delete.png") no-repeat scroll 3px;
.currently_following{
padding-left: 10px;
.add_icon {
background:url("../images/icons/add.png") no-repeat scroll 3px;
padding-top:1px;
.edit_icon {
background:url("../images/icons/folder_edit.png") no-repeat scroll 3px;
.delete_icon {
background:url("../images/icons/delete.png") no-repeat scroll 3px;
.refresh_icon {
background:url("../images/icons/arrow_refresh.png") no-repeat scroll 3px;
.rss_icon {
background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
.atom_icon {
background:url("../images/icons/atom.png") no-repeat scroll 3px;
.archive_icon {
background:url("../images/icons/compress.png") no-repeat scroll 3px;
.action_button {
.action_button:hover {
#switch_repos {
height:25px;
z-index:1;
#switch_repos select {
min-width:150px;
max-height:250px;
.breadcrumbs {
border:medium none;
.breadcrumbs a {
.flash_msg ul {
.error_msg {
background-color:#FFCFCF;
background-image:url("../../images/icons/error_msg.png");
border:1px solid #FF9595;
color:#C30;
.warning_msg {
background-color:#FFFBCC;
background-image:url("../../images/icons/warning_msg.png");
border:1px solid #FFF35E;
color:#C69E00;
.success_msg {
background-color:#D5FFCF;
background-image:url("../../images/icons/success_msg.png");
border:1px solid #97FF88;
color:#090;
.notice_msg {
background-color:#DCE3FF;
background-image:url("../../images/icons/notice_msg.png");
border:1px solid #93A8FF;
.success_msg,.error_msg,.notice_msg,.warning_msg {
background-position:10px center;
background-repeat:no-repeat;
min-height:14px;
line-height:14px;
margin-bottom:0;
margin-top:0;
padding:6px 10px 6px 40px;
#msg_close {
background:transparent url("../../icons/cross_grey_small.png") no-repeat scroll 0 0;
right:5px;
top:5px;
div#legend_container table,div#legend_choices table {
width:auto !important;
table#permissions_manage {
width:0 !important;
table#permissions_manage span.private_repo_msg {
opacity:0.6px;
table#permissions_manage td.private_repo_msg {
table#permissions_manage tr#add_perm_input td {
div.gravatar {
border:1px solid #D0D0D0;
margin-right:0.7em;
padding:2px 2px 0;
#header,#content,#footer {
min-width:1024px;
#content {
min-height:100%;
padding:14px 30px;
#content div.box div.title div.search {
background:url("../../images/title_link.png") no-repeat top left;
## -*- 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')}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
<head>
<title>${next.title()}</title>
<link rel="icon" href="/images/icons/database_gear.png" type="image/png" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="robots" content="index, nofollow"/>
<!-- stylesheets -->
${self.css()}
<!-- scripts -->
${self.js()}
</head>
<body>
<!-- header -->
<div id="header">
<!-- user -->
<ul id="logged-user">
<li class="first">
<div class="gravatar">
<img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,24)}" />
%if c.rhodecode_user.username == 'default':
<div class="account">
${h.link_to('%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname),h.url('#'))}<br/>
${h.link_to(c.rhodecode_user.username,h.url('#'))}
</li>
<li class="last highlight">${h.link_to(u'Login',h.url('login_home'))}</li>
%else:
${h.link_to('%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname),h.url('admin_settings_my_account'))}<br/>
${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'))}
<li class="last highlight">${h.link_to(u'Logout',h.url('logout_home'))}</li>
%endif
</ul>
<!-- end user -->
<div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner">
<!-- logo -->
<div id="logo">
<h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
<!-- end logo -->
<!-- menu -->
${self.page_nav()}
<!-- quick -->
<!-- end header -->
<!-- CONTENT -->
<div id="content">
<div class="flash_msg">
<% messages = h.flash.pop_messages() %>
% if messages:
<ul id="flash-messages">
% for message in messages:
<li class="${message.category}_msg">${message}</li>
% endfor
% endif
<div id="main">
${next.main()}
<!-- END CONTENT -->
<!-- footer -->
<div id="footer">
<div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner">
<div>
<p class="footer-link">${h.link_to(_('Submit a bug'),h.url('bugtracker'))}</p>
<p class="footer-link">${h.link_to(_('GPL license'),h.url('gpl_license'))}</p>
<p>RhodeCode ${c.rhodecode_version} © 2010 by Marcin Kuzminski</p>
<script type="text/javascript">${h.tooltip.activate()}</script>
<!-- end footer -->
</body>
</html>
### MAKO DEFS ###
${self.menu()}
<%def name="menu(current=None)">
<%
def is_current(selected):
if selected == current:
return h.literal('class="current"')
%>
%if current not in ['home','admin']:
##REGULAR MENU
<ul id="quick">
<!-- repo switcher -->
<li>
<a id="repo_switcher" title="${_('Switch repository')}" href="#">
<span class="icon">
<img src="/images/icons/database.png" alt="${_('Products')}" />
</span>
<span>↓</span>
</a>
<ul class="repo_switcher">
%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>
<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>
%endfor
<li ${is_current('summary')}>
<a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
<img src="/images/icons/clipboard_16.png" alt="${_('Summary')}" />
<span>${_('Summary')}</span>
##<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>
${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
<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: