@@ -40,97 +40,103 @@ def make_map(config):
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',)
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'))
@@ -65,154 +65,106 @@ class PermissionsController(BaseControll
('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))
@@ -434,96 +434,103 @@ padding:12px 9px 7px 24px;
background:url("../images/icons/lock_open.png") no-repeat scroll 4px 9px #FFF;
min-width:167px;
margin:0;
padding:12px 9px 7px 24px;
}
#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;
width:167px;
#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;
## -*- 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()}
@@ -28,98 +28,57 @@
<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')}
@@ -159,177 +159,175 @@
%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>
%endfor
%else:
<li>${h.link_to(_('There are no branches yet'),'#')}</li>
%endif
</ul>
</li>
<li>
${h.link_to('%s (%s)' % (_('tags'),len(c.repository_tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')}
<ul>
%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)}">
<span class="icon">
<img src="/images/icons/file.png" alt="${_('Files')}" />
</span>
<span>${_('Files')}</span>
</a>
<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();
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: