@@ -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"]))
action="index", conditions=dict(method=["GET"]))
m.connect("formatted_users", "/users.{format}",
m.connect("new_user", "/users/new",
action="new", conditions=dict(method=["GET"]))
m.connect("formatted_new_user", "/users/new.{format}",
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",
m.connect("user", "/users/{id}",
action="show", conditions=dict(method=["GET"]))
m.connect("formatted_user", "/users/{id}.{format}",
#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',
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')
@@ -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
@@ -38,7 +38,7 @@ from rhodecode.lib import helpers as h
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
from rhodecode.model.db import User
from rhodecode.model.db import User, RepoToPerm, UserToPerm, Permission
from rhodecode.model.forms import UserForm
@@ -101,7 +101,7 @@ class UsersController(BaseController):
# Forms posted to this method should contain a hidden field:
# <input type="hidden" name="_method" value="PUT" />
# 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):
# <input type="hidden" name="_method" value="DELETE" />
# h.form(url('delete_user', id=ID),
# method='delete')
@@ -167,6 +170,8 @@ class UsersController(BaseController):
.permissions['global']
defaults = c.user.get_dict()
defaults.update({'create_repo_perm': UserToPerm.has_perm(id, perm)})
@@ -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)
UserToPerm.grant_perm(id, perm)
h.flash(_("Granted 'repository create' permission to user"),
category='success')
else:
h.flash(_("Revoked 'repository create' permission to user"),
return redirect(url('edit_user', id=id))
@@ -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):
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)
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()
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', '')
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 '
]
for p in perms:
@@ -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
@@ -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
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):
self.permission_id, self.permission_name)
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')
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
def grant_perm(cls, user_id, perm):
new = cls()
new.user_id = user_id
new.permission = perm
Session.add(new)
Session.commit()
except:
Session.rollback()
def revoke_perm(cls, user_id, perm):
Session.query(cls).filter(cls.user_id == user_id)\
.filter(cls.permission == perm).delete()
class UsersGroupToPerm(Base):
__tablename__ = 'users_group_to_perm'
@@ -24,7 +24,7 @@
${self.breadcrumbs()}
</div>
<!-- end box / title -->
${h.form(url('user', id=c.user.user_id),method='put')}
${h.form(url('update_user', id=c.user.user_id),method='put')}
<div class="form">
<div class="field">
<div class="gravatar_box">
@@ -126,7 +126,7 @@
<div class="title">
<h5>${_('Permissions')}</h5>
${h.form(url('user_perm', id=c.user.user_id),method='put')}
<!-- fields -->
<div class="fields">
@@ -135,7 +135,7 @@
<label for="">${_('Create repositories')}:</label>
<div class="checkboxes">
${h.checkbox('create',value=True)}
${h.checkbox('create_repo_perm',value=True)}
<div class="buttons">
@@ -51,7 +51,7 @@
<td>${h.bool2icon(user.admin)}</td>
<td>${h.bool2icon(bool(user.ldap_dn))}</td>
<td>
${h.form(url('user', id=user.user_id),method='delete')}
${h.form(url('delete_user', id=user.user_id),method='delete')}
${h.submit('remove_','delete',id="remove_user_%s" % user.user_id,
class_="delete_icon action_button",onclick="return confirm('Confirm to delete this user');")}
${h.end_form()}
@@ -247,7 +247,7 @@ ${h.end_form()}
${h.form(url('user', id=''),method='put')}
${h.form(url('xxx', id=''),method='put')}
Status change: