diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py --- a/rhodecode/config/routing.py +++ b/rhodecode/config/routing.py @@ -105,16 +105,42 @@ def make_map(config): controller='admin/repos_groups', path_prefix='/_admin') #ADMIN USER REST ROUTES - rmap.resource('user', 'users', controller='admin/users', - path_prefix='/_admin') + with rmap.submapper(path_prefix='/_admin', controller='admin/users') as m: + m.connect("users", "/users", + action="create", conditions=dict(method=["POST"])) + m.connect("users", "/users", + action="index", conditions=dict(method=["GET"])) + m.connect("formatted_users", "/users.{format}", + action="index", conditions=dict(method=["GET"])) + m.connect("new_user", "/users/new", + action="new", conditions=dict(method=["GET"])) + m.connect("formatted_new_user", "/users/new.{format}", + action="new", conditions=dict(method=["GET"])) + m.connect("update_user", "/users/{id}", + action="update", conditions=dict(method=["PUT"])) + m.connect("delete_user", "/users/{id}", + action="delete", conditions=dict(method=["DELETE"])) + m.connect("edit_user", "/users/{id}/edit", + action="edit", conditions=dict(method=["GET"])) + m.connect("formatted_edit_user", + "/users/{id}.{format}/edit", + action="edit", conditions=dict(method=["GET"])) + m.connect("user", "/users/{id}", + action="show", conditions=dict(method=["GET"])) + m.connect("formatted_user", "/users/{id}.{format}", + action="show", conditions=dict(method=["GET"])) + + #EXTRAS USER ROUTES + m.connect("user_perm", "/users_perm/{id}", + action="update_perm", conditions=dict(method=["PUT"])) #ADMIN USERS REST ROUTES rmap.resource('users_group', 'users_groups', controller='admin/users_groups', path_prefix='/_admin') #ADMIN GROUP REST ROUTES - rmap.resource('group', 'groups', controller='admin/groups', - path_prefix='/_admin') + rmap.resource('group', 'groups', + controller='admin/groups', path_prefix='/_admin') #ADMIN PERMISSIONS REST ROUTES rmap.resource('permission', 'permissions', @@ -124,6 +150,7 @@ def make_map(config): rmap.connect('ldap_settings', '/_admin/ldap', controller='admin/ldap_settings', action='ldap_settings', conditions=dict(method=["POST"])) + rmap.connect('ldap_home', '/_admin/ldap', controller='admin/ldap_settings') diff --git a/rhodecode/controllers/admin/permissions.py b/rhodecode/controllers/admin/permissions.py --- a/rhodecode/controllers/admin/permissions.py +++ b/rhodecode/controllers/admin/permissions.py @@ -33,7 +33,6 @@ from rhodecode.lib.auth_ldap import Ldap from rhodecode.lib.base import BaseController, render from rhodecode.model.forms import LdapSettingsForm, DefaultPermissionsForm from rhodecode.model.permission import PermissionModel -from rhodecode.model.settings import SettingsModel from rhodecode.model.user import UserModel import formencode import logging diff --git a/rhodecode/controllers/admin/users.py b/rhodecode/controllers/admin/users.py --- a/rhodecode/controllers/admin/users.py +++ b/rhodecode/controllers/admin/users.py @@ -38,7 +38,7 @@ from rhodecode.lib import helpers as h from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator from rhodecode.lib.base import BaseController, render -from rhodecode.model.db import User +from rhodecode.model.db import User, RepoToPerm, UserToPerm, Permission from rhodecode.model.forms import UserForm from rhodecode.model.user import UserModel @@ -101,7 +101,7 @@ class UsersController(BaseController): # Forms posted to this method should contain a hidden field: # # Or using helpers: - # h.form(url('user', id=ID), + # h.form(url('update_user', id=ID), # method='put') # url('user', id=ID) user_model = UserModel() @@ -113,13 +113,16 @@ class UsersController(BaseController): try: form_result = _form.to_python(dict(request.POST)) user_model.update(id, form_result) - h.flash(_('User updated succesfully'), category='success') + h.flash(_('User updated successfully'), category='success') except formencode.Invalid, errors: + e = errors.error_dict or {} + perm = Permission.get_by_key('hg.create.repository') + e.update({'create_repo_perm': UserToPerm.has_perm(id, perm)}) return htmlfill.render( render('admin/users/user_edit.html'), defaults=errors.value, - errors=errors.error_dict or {}, + errors=e, prefix_error=False, encoding="UTF-8") except Exception: @@ -134,7 +137,7 @@ class UsersController(BaseController): # Forms posted to this method should contain a hidden field: # # Or using helpers: - # h.form(url('user', id=ID), + # h.form(url('delete_user', id=ID), # method='delete') # url('user', id=ID) user_model = UserModel() @@ -167,6 +170,8 @@ class UsersController(BaseController): .permissions['global'] defaults = c.user.get_dict() + perm = Permission.get_by_key('hg.create.repository') + defaults.update({'create_repo_perm': UserToPerm.has_perm(id, perm)}) return htmlfill.render( render('admin/users/user_edit.html'), @@ -174,3 +179,29 @@ class UsersController(BaseController): encoding="UTF-8", force_defaults=False ) + + def update_perm(self, id): + """PUT /users_perm/id: Update an existing item""" + # url('user_perm', id=ID, method='put') + + grant_perm = request.POST.get('create_repo_perm', False) + + if grant_perm: + perm = Permission.get_by_key('hg.create.none') + UserToPerm.revoke_perm(id, perm) + + perm = Permission.get_by_key('hg.create.repository') + UserToPerm.grant_perm(id, perm) + h.flash(_("Granted 'repository create' permission to user"), + category='success') + + else: + perm = Permission.get_by_key('hg.create.repository') + UserToPerm.revoke_perm(id, perm) + + perm = Permission.get_by_key('hg.create.none') + UserToPerm.grant_perm(id, perm) + h.flash(_("Revoked 'repository create' permission to user"), + category='success') + + return redirect(url('edit_user', id=id)) diff --git a/rhodecode/lib/db_manage.py b/rhodecode/lib/db_manage.py --- a/rhodecode/lib/db_manage.py +++ b/rhodecode/lib/db_manage.py @@ -36,13 +36,14 @@ from rhodecode.model import meta from rhodecode.lib.auth import get_crypt_password, generate_api_key from rhodecode.lib.utils import ask_ok from rhodecode.model import init_model -from rhodecode.model.db import User, Permission, RhodeCodeUi, RhodeCodeSettings, \ - UserToPerm, DbMigrateVersion +from rhodecode.model.db import User, Permission, RhodeCodeUi, \ + RhodeCodeSettings, UserToPerm, DbMigrateVersion from sqlalchemy.engine import create_engine log = logging.getLogger(__name__) + class DbManage(object): def __init__(self, log_sql, dbconf, root, tests=False): self.dbname = dbconf.split('/')[-1] @@ -76,8 +77,6 @@ class DbManage(object): meta.Base.metadata.create_all(checkfirst=checkfirst) log.info('Created tables for %s', self.dbname) - - def set_db_version(self): try: ver = DbMigrateVersion() @@ -91,7 +90,6 @@ class DbManage(object): raise log.info('db version set to: %s', __dbversion__) - def upgrade(self): """Upgrades given database schema to given revision following all needed steps, to perform the upgrade @@ -170,8 +168,6 @@ class DbManage(object): print ('performing upgrade step %s' % step) callable = getattr(UpgradeSteps(self), 'step_%s' % step)() - - def fix_repo_paths(self): """Fixes a old rhodecode version path into new one without a '*' """ @@ -225,9 +221,9 @@ class DbManage(object): if not self.tests: import getpass - def get_password(): - password = getpass.getpass('Specify admin password (min 6 chars):') + password = getpass.getpass('Specify admin password ' + '(min 6 chars):') confirm = getpass.getpass('Confirm password:') if password != confirm: @@ -252,9 +248,12 @@ class DbManage(object): self.create_user(username, password, email, True) else: log.info('creating admin and regular test users') - self.create_user('test_admin', 'test12', 'test_admin@mail.com', True) - self.create_user('test_regular', 'test12', 'test_regular@mail.com', False) - self.create_user('test_regular2', 'test12', 'test_regular2@mail.com', False) + self.create_user('test_admin', 'test12', + 'test_admin@mail.com', True) + self.create_user('test_regular', 'test12', + 'test_regular@mail.com', False) + self.create_user('test_regular2', 'test12', + 'test_regular2@mail.com', False) def create_ui_settings(self): """Creates ui settings, fills out hooks @@ -308,7 +307,6 @@ class DbManage(object): self.sa.rollback() raise - def create_ldap_options(self): """Creates ldap settings""" @@ -321,7 +319,6 @@ class DbManage(object): ('ldap_attr_login', ''), ('ldap_attr_firstname', ''), ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]: - setting = RhodeCodeSettings(k, v) self.sa.add(setting) self.sa.commit() @@ -353,14 +350,12 @@ class DbManage(object): log.error('No write permission to given path: %s [%s/3]', path, retries) - if retries == 0: sys.exit() if path_ok is False: retries -= 1 return self.config_prompt(test_repo_path, retries) - return path def create_settings(self, path): @@ -393,12 +388,10 @@ class DbManage(object): paths.ui_key = '/' paths.ui_value = path - hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication') hgsettings2 = RhodeCodeSettings('title', 'RhodeCode') hgsettings3 = RhodeCodeSettings('ga_code', '') - try: self.sa.add(web1) self.sa.add(web2) @@ -467,8 +460,13 @@ class DbManage(object): ('hg.create.repository', 'Repository create'), ('hg.create.none', 'Repository creation disabled'), ('hg.register.none', 'Register disabled'), - ('hg.register.manual_activate', 'Register new user with RhodeCode without manual activation'), - ('hg.register.auto_activate', 'Register new user with RhodeCode without auto activation'), + ('hg.register.manual_activate', 'Register new user with ' + 'RhodeCode without manual' + 'activation'), + + ('hg.register.auto_activate', 'Register new user with ' + 'RhodeCode without auto ' + 'activation'), ] for p in perms: diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -33,7 +33,9 @@ from sqlalchemy.exc import DatabaseError from sqlalchemy.orm import relationship, backref from sqlalchemy.orm.interfaces import MapperExtension +from rhodecode.lib import str2bool from rhodecode.model.meta import Base, Session +from rhodecode.model.caching_query import FromCache log = logging.getLogger(__name__) @@ -61,6 +63,35 @@ class RhodeCodeSettings(Base): return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) + + @classmethod + def get_app_settings(cls, cache=False): + + ret = Session.query(cls) + + if cache: + ret = ret.options(FromCache("sql_cache_short", "get_hg_settings")) + + if not ret: + raise Exception('Could not get application settings !') + settings = {} + for each in ret: + settings['rhodecode_' + each.app_settings_name] = \ + each.app_settings_value + + return settings + + @classmethod + def get_ldap_settings(cls, cache=False): + ret = Session.query(cls)\ + .filter(cls.app_settings_name.startswith('ldap_'))\ + .all() + fd = {} + for row in ret: + fd.update({row.app_settings_name:str2bool(row.app_settings_value)}) + return fd + + class RhodeCodeUi(Base): __tablename__ = 'rhodecode_ui' __table_args__ = {'useexisting':True} @@ -285,6 +316,10 @@ class Permission(Base): return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) + @classmethod + def get_by_key(cls, key): + return Session.query(cls).filter(cls.permission_name == key).scalar() + class RepoToPerm(Base): __tablename__ = 'repo_to_perm' __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True}) @@ -307,6 +342,40 @@ class UserToPerm(Base): user = relationship('User') permission = relationship('Permission') + @classmethod + def has_perm(cls, user_id, perm): + if not isinstance(perm, Permission): + raise Exception('perm needs to be an instance of Permission class') + + return Session.query(cls).filter(cls.user_id == user_id)\ + .filter(cls.permission == perm).scalar() is not None + + @classmethod + def grant_perm(cls, user_id, perm): + if not isinstance(perm, Permission): + raise Exception('perm needs to be an instance of Permission class') + + new = cls() + new.user_id = user_id + new.permission = perm + try: + Session.add(new) + Session.commit() + except: + Session.rollback() + + + @classmethod + def revoke_perm(cls, user_id, perm): + if not isinstance(perm, Permission): + raise Exception('perm needs to be an instance of Permission class') + + try: + Session.query(cls).filter(cls.user_id == user_id)\ + .filter(cls.permission == perm).delete() + Session.commit() + except: + Session.rollback() class UsersGroupToPerm(Base): __tablename__ = 'users_group_to_perm' diff --git a/rhodecode/templates/admin/users/user_edit.html b/rhodecode/templates/admin/users/user_edit.html --- a/rhodecode/templates/admin/users/user_edit.html +++ b/rhodecode/templates/admin/users/user_edit.html @@ -24,7 +24,7 @@ ${self.breadcrumbs()} - ${h.form(url('user', id=c.user.user_id),method='put')} + ${h.form(url('update_user', id=c.user.user_id),method='put')}