@@ -81,19 +81,20 @@ def make_map(config):
action="repo_cache", conditions=dict(method=["DELETE"],
function=check_repo))
#ADMIN USER REST ROUTES
map.resource('user', 'users', controller='admin/users', path_prefix='/_admin')
map.resource('users_group', 'users_groups', controller='admin/users_groups', path_prefix='/_admin')
#ADMIN GROUP REST ROUTES
map.resource('group', 'groups', controller='admin/groups', path_prefix='/_admin')
#ADMIN PERMISSIONS REST ROUTES
map.resource('permission', 'permissions', controller='admin/permissions', path_prefix='/_admin')
##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",
new file 100644
# -*- coding: utf-8 -*-
"""
rhodecode.controllers.admin.users_groups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Users Groups crud controller for pylons
:created_on: Jan 25, 2011
:author: marcink
:copyright: (C) 2009-2011 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 traceback
import formencode
from formencode import htmlfill
from pylons import request, session, tmpl_context as c, url, config
from pylons.controllers.util import abort, redirect
from pylons.i18n.translation import _
from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException
from rhodecode.lib import helpers as h
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
fill_perms
from rhodecode.lib.base import BaseController, render
from rhodecode.model.db import User, UsersGroup
from rhodecode.model.forms import UserForm
from rhodecode.model.user import UserModel
log = logging.getLogger(__name__)
class UsersGroupsController(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('users_group', 'users_groups')
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
def __before__(self):
c.admin_user = session.get('admin_user')
c.admin_username = session.get('admin_username')
super(UsersGroupsController, self).__before__()
c.available_permissions = config['available_permissions']
def index(self, format='html'):
"""GET /users_groups: All items in the collection"""
# url('users_groups')
c.users_groups_list = []
return render('admin/users_groups/users_groups.html')
def create(self):
"""POST /users_groups: Create a new item"""
def new(self, format='html'):
"""GET /users_groups/new: Form to create a new item"""
# url('new_users_group')
def update(self, id):
"""PUT /users_groups/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('users_group', id=ID),
# method='put')
# url('users_group', id=ID)
def delete(self, id):
"""DELETE /users_groups/id: Delete an existing item"""
# <input type="hidden" name="_method" value="DELETE" />
# method='delete')
def show(self, id, format='html'):
"""GET /users_groups/id: Show a specific item"""
def edit(self, id, format='html'):
"""GET /users_groups/id/edit: Form to edit an existing item"""
# url('edit_users_group', id=ID)
@@ -153,6 +153,29 @@ class UserLog(Base, BaseModel):
user = relation('User')
repository = relation('Repository')
class UsersGroup(Base, BaseModel):
__tablename__ = 'users_groups'
__table_args__ = {'useexisting':True}
user_group_id = Column("users_groups_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_group_name = Column("user_group_name", String(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
members = relation('UsersGroupMember')
class UsersGroupMember(Base, BaseModel):
__tablename__ = 'users_groups_members'
user_groups_members_id = Column("user_groups_members_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_groups_id'), nullable=False, unique=None, default=None)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
users_group = relation('UsersGroup')
class Repository(Base, BaseModel):
__tablename__ = 'repositories'
__table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
package.rhodecode.model.user
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rhodecode.model.user
~~~~~~~~~~~~~~~~~~~~
users model for RhodeCode
rhodecode.model.user_group
~~~~~~~~~~~~~~~~~~~~~~~~~~
users groups model for RhodeCode
@@ -478,6 +478,13 @@ margin:0;
padding:12px 9px 7px 24px;
}
#header #header-inner #quick li ul li a.groups,#header #header-inner #quick li ul li a.groups:hover {
background:#FFF url("../images/icons/group_edit.png") no-repeat 4px 9px;
width:167px;
margin:0;
#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;
## -*- coding: utf-8 -*-
<%inherit file="/base/base.html"/>
<%def name="title()">
${_('Users groups administration')} - ${c.rhodecode_name}
</%def>
<%def name="breadcrumbs_links()">
${h.link_to(_('Admin'),h.url('admin_home'))} » ${_('Users groups')}
<%def name="page_nav()">
${self.menu('admin')}
<%def name="main()">
<div class="box">
<!-- box / title -->
<div class="title">
${self.breadcrumbs()}
<ul class="links">
<li>
<span>${h.link_to(u'ADD NEW USER GROUP',h.url('new_users_group'))}</span>
</li>
</ul>
</div>
<!-- end box / title -->
<div class="table">
<table class="table_disp">
<tr class="header">
<th></th>
<th class="left">${_('group name')}</th>
<th class="left">${_('members')}</th>
<th class="left">${_('active')}</th>
<th class="left">${_('action')}</th>
</tr>
%for cnt,u_group in enumerate(c.users_groups_list):
<tr class="parity${cnt%2}">
<td>${h.link_to(u_group.groupname,h.url('edit_user_group', id=u_group.group_id))}</td>
<td>${u_group.members}</td>
<td>${h.bool2icon(u_group.active)}</td>
<td>
${h.form(url('users_group', id=group.group_id),method='delete')}
${h.submit('remove_','delete',id="remove_group_%s" % group.group_id,
class_="delete_icon action_button",onclick="return confirm('Confirm to delete this user group');")}
${h.end_form()}
</td>
%endfor
</table>
@@ -240,6 +240,7 @@
<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(_('users groups'),h.url('users_groups'),class_='groups')}</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>
from rhodecode.tests import *
class TestUsersGroupsController(TestController):
def test_index(self):
response = self.app.get(url('users_groups'))
# Test response...
def test_index_as_xml(self):
response = self.app.get(url('formatted_users_groups', format='xml'))
def test_create(self):
response = self.app.post(url('users_groups'))
def test_new(self):
response = self.app.get(url('new_users_group'))
def test_new_as_xml(self):
response = self.app.get(url('formatted_new_users_group', format='xml'))
def test_update(self):
response = self.app.put(url('users_group', id=1))
def test_update_browser_fakeout(self):
response = self.app.post(url('users_group', id=1), params=dict(_method='put'))
def test_delete(self):
response = self.app.delete(url('users_group', id=1))
def test_delete_browser_fakeout(self):
response = self.app.post(url('users_group', id=1), params=dict(_method='delete'))
def test_show(self):
response = self.app.get(url('users_group', id=1))
def test_show_as_xml(self):
response = self.app.get(url('formatted_users_group', id=1, format='xml'))
def test_edit(self):
response = self.app.get(url('edit_users_group', id=1))
def test_edit_as_xml(self):
response = self.app.get(url('formatted_edit_users_group', id=1, format='xml'))
Status change: