"""
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))
@@ -290,384 +290,391 @@ padding:0;
#header #header-inner #quick li a {
top:0;
left:0;
height:1%;
display:block;
clear:both;
overflow:hidden;
color:#FFF;
font-weight:700;
text-decoration:none;
background:#369 url("../../images/quick_l.png") no-repeat top left;
padding:0;
}
#header #header-inner #quick li span.short {
padding:9px 6px 8px 6px;
#header #header-inner #quick li span {
right:0;
float:left;
background:url("../../images/quick_r.png") no-repeat top right;
border-left:1px solid #3f6f9f;
margin:0;
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 {
border-left:none;
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;
position:absolute;
background:#FFF;
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;
color:#003367;
font-weight:400;
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;
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 {
float: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 {
color:#fff;
text-transform:uppercase;
padding:11px 0 11px 10px;
#content div.box div.title ul.links li {
list-style:none;
#content div.box div.title ul.links li a {
border-left:1px solid #316293;
font-size:11px;
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;
font-size:12px;
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 {
## -*- 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')}
@@ -15,342 +15,340 @@
<!-- 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: