Changeset - a1bcfe58a1ab
[Not reviewed]
beta
0 8 0
Marcin Kuzminski - 15 years ago 2011-04-18 20:18:12
marcin@python-works.com
Fixed #161 form saves the create repository permission.
routing update for users to support second form posting.
models updates
8 files changed with 159 insertions and 35 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/routing.py
Show inline comments
 
@@ -12,211 +12,238 @@ from rhodecode.lib.utils import check_re
 

	
 
def make_map(config):
 
    """Create, configure and return the routes Mapper"""
 
    rmap = Mapper(directory=config['pylons.paths']['controllers'],
 
                 always_scan=config['debug'])
 
    rmap.minimization = False
 
    rmap.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
 
    rmap.connect('/error/{action}', controller='error')
 
    rmap.connect('/error/{action}/{id}', controller='error')
 

	
 
    #==========================================================================
 
    # CUSTOM ROUTES HERE
 
    #==========================================================================
 

	
 
    #MAIN PAGE
 
    rmap.connect('home', '/', controller='home', action='index')
 
    rmap.connect('repo_switcher', '/repos', controller='home',
 
                 action='repo_switcher')
 
    rmap.connect('bugtracker',
 
                 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
 
                 _static=True)
 
    rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
 

	
 
    #ADMIN REPOSITORY REST ROUTES
 
    with rmap.submapper(path_prefix='/_admin', controller='admin/repos') as m:
 
        m.connect("repos", "/repos",
 
             action="create", conditions=dict(method=["POST"]))
 
        m.connect("repos", "/repos",
 
             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}",
 
             action="new", conditions=dict(method=["GET"]))
 
        m.connect("/repos/{repo_name:.*}",
 
             action="update", conditions=dict(method=["PUT"],
 
                                              function=check_repo))
 
        m.connect("/repos/{repo_name:.*}",
 
             action="delete", conditions=dict(method=["DELETE"],
 
                                              function=check_repo))
 
        m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
 
             action="edit", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
 
             action="edit", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        m.connect("repo", "/repos/{repo_name:.*}",
 
             action="show", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
 
             action="show", conditions=dict(method=["GET"],
 
                                            function=check_repo))
 
        #ajax delete repo perm user
 
        m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
 
             action="delete_perm_user", conditions=dict(method=["DELETE"],
 
                                                        function=check_repo))
 
        #ajax delete repo perm users_group
 
        m.connect('delete_repo_users_group',
 
                  "/repos_delete_users_group/{repo_name:.*}",
 
                  action="delete_perm_users_group",
 
                  conditions=dict(method=["DELETE"], function=check_repo))
 

	
 
        #settings actions
 
        m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
 
             action="repo_stats", conditions=dict(method=["DELETE"],
 
                                                        function=check_repo))
 
        m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
 
             action="repo_cache", conditions=dict(method=["DELETE"],
 
                                                        function=check_repo))
 
        m.connect('repo_public_journal',
 
                  "/repos_public_journal/{repo_name:.*}",
 
                  action="repo_public_journal", conditions=dict(method=["PUT"],
 
                  function=check_repo))
 
        m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
 
             action="repo_pull", conditions=dict(method=["PUT"],
 
                                                        function=check_repo))
 

	
 
    #ADMIN REPOS GROUP REST ROUTES
 
    rmap.resource('repos_group', 'repos_groups',
 
                  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',
 
                  controller='admin/permissions', path_prefix='/_admin')
 

	
 
    ##ADMIN LDAP SETTINGS
 
    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')
 

	
 
    #ADMIN SETTINGS REST ROUTES
 
    with rmap.submapper(path_prefix='/_admin',
 
                        controller='admin/settings') as m:
 
        m.connect("admin_settings", "/settings",
 
                  action="create", conditions=dict(method=["POST"]))
 
        m.connect("admin_settings", "/settings",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("formatted_admin_settings", "/settings.{format}",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("admin_new_setting", "/settings/new",
 
                  action="new", conditions=dict(method=["GET"]))
 
        m.connect("formatted_admin_new_setting", "/settings/new.{format}",
 
                  action="new", conditions=dict(method=["GET"]))
 
        m.connect("/settings/{setting_id}",
 
                  action="update", conditions=dict(method=["PUT"]))
 
        m.connect("/settings/{setting_id}",
 
                  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",
 
                  action="edit", conditions=dict(method=["GET"]))
 
        m.connect("admin_setting", "/settings/{setting_id}",
 
                  action="show", conditions=dict(method=["GET"]))
 
        m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
 
                  action="show", conditions=dict(method=["GET"]))
 
        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 rmap.submapper(path_prefix='/_admin', controller='admin/admin') as m:
 
        m.connect('admin_home', '', action='index')
 
        m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
 
                  action='add_repo')
 

	
 
    #USER JOURNAL
 
    rmap.connect('journal', '/_admin/journal', controller='journal')
 

	
 
    rmap.connect('public_journal', '/_admin/public_journal',
 
                 controller='journal', action="public_journal")
 

	
 
    rmap.connect('public_journal_rss', '/_admin/public_journal_rss',
 
                 controller='journal', action="public_journal_rss")
 

	
 
    rmap.connect('public_journal_atom', '/_admin/public_journal_atom',
 
                 controller='journal', action="public_journal_atom")
 

	
 
    rmap.connect('toggle_following', '/_admin/toggle_following',
 
                 controller='journal', action='toggle_following',
 
                 conditions=dict(method=["POST"]))
 

	
 
    #SEARCH
 
    rmap.connect('search', '/_admin/search', controller='search',)
 
    rmap.connect('search_repo', '/_admin/search/{search_repo:.*}',
 
                  controller='search')
 

	
 
    #LOGIN/LOGOUT/REGISTER/SIGN IN
 
    rmap.connect('login_home', '/_admin/login', controller='login')
 
    rmap.connect('logout_home', '/_admin/logout', controller='login',
 
                 action='logout')
 

	
 
    rmap.connect('register', '/_admin/register', controller='login',
 
                 action='register')
 

	
 
    rmap.connect('reset_password', '/_admin/password_reset',
 
                 controller='login', action='password_reset')
 

	
 
    #FEEDS
 
    rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
 
                controller='feed', action='rss',
 
                conditions=dict(function=check_repo))
 

	
 
    rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
 
                controller='feed', action='atom',
 
                conditions=dict(function=check_repo))
 

	
 
    #REPOSITORY ROUTES
 
    rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
 
                controller='changeset', revision='tip',
 
                conditions=dict(function=check_repo))
 

	
 
    rmap.connect('raw_changeset_home',
 
                 '/{repo_name:.*}/raw-changeset/{revision}',
 
                 controller='changeset', action='raw_changeset',
 
                 revision='tip', conditions=dict(function=check_repo))
 

	
 
    rmap.connect('summary_home', '/{repo_name:.*}',
 
                controller='summary', conditions=dict(function=check_repo))
 

	
rhodecode/controllers/admin/permissions.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.controllers.admin.permissions
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    permissions controller for Rhodecode
 

	
 
    :created_on: Apr 27, 2010
 
    :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, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# 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, see <http://www.gnu.org/licenses/>.
 

	
 
from formencode import htmlfill
 
from pylons import request, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
 
from rhodecode.lib.auth_ldap import LdapImportError
 
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
 
import traceback
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
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')
 

	
 
    @LoginRequired()
 
    @HasPermissionAllDecorator('hg.admin')
 
    def __before__(self):
 
        c.admin_user = session.get('admin_user')
 
        c.admin_username = session.get('admin_username')
 
        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"""
 
        # url('permissions')
 

	
 
    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])()
 

	
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            form_result.update({'perm_user_name': id})
 
            permission_model.update(form_result)
 
            h.flash(_('Default permissions updated successfully'),
 
                    category='success')
 

	
 
        except formencode.Invalid, errors:
 
            c.perms_choices = self.perms_choices
 
            c.register_choices = self.register_choices
 
            c.create_choices = self.create_choices
 
            defaults = errors.value
 

	
 
            return htmlfill.render(
 
                render('admin/permissions/permissions.html'),
 
                defaults=defaults,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('error occurred during update of permissions'),
 
                    category='error')
 

	
 
        return redirect(url('edit_permission', id=id))
 

	
 
    def delete(self, id):
 
        """DELETE /permissions/id: Delete an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="DELETE" />
 
        # Or using helpers:
 
        #    h.form(url('permission', id=ID),
 
        #           method='delete')
rhodecode/controllers/admin/users.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.controllers.admin.users
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    Users crud controller for pylons
 

	
 
    :created_on: Apr 4, 2010
 
    :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, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# 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, see <http://www.gnu.org/licenses/>.
 

	
 
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
 
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
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class UsersController(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('user', 'users')
 

	
 
    @LoginRequired()
 
    @HasPermissionAllDecorator('hg.admin')
 
    def __before__(self):
 
        c.admin_user = session.get('admin_user')
 
        c.admin_username = session.get('admin_username')
 
        super(UsersController, self).__before__()
 
        c.available_permissions = config['available_permissions']
 

	
 
    def index(self, format='html'):
 
        """GET /users: All items in the collection"""
 
        # url('users')
 

	
 
        c.users_list = self.sa.query(User).all()
 
        return render('admin/users/users.html')
 

	
 
    def create(self):
 
        """POST /users: Create a new item"""
 
        # url('users')
 

	
 
        user_model = UserModel()
 
        login_form = UserForm()()
 
        try:
 
            form_result = login_form.to_python(dict(request.POST))
 
            user_model.create(form_result)
 
            h.flash(_('created user %s') % form_result['username'],
 
                    category='success')
 
            #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
 
        except formencode.Invalid, errors:
 
            return htmlfill.render(
 
                render('admin/users/user_add.html'),
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('error occurred during creation of user %s') \
 
                    % request.POST.get('username'), category='error')
 
        return redirect(url('users'))
 

	
 
    def new(self, format='html'):
 
        """GET /users/new: Form to create a new item"""
 
        # url('new_user')
 
        return render('admin/users/user_add.html')
 

	
 
    def update(self, id):
 
        """PUT /users/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('user', id=ID),
 
        #    h.form(url('update_user', id=ID),
 
        #           method='put')
 
        # url('user', id=ID)
 
        user_model = UserModel()
 
        c.user = user_model.get(id)
 

	
 
        _form = UserForm(edit=True, old_data={'user_id': id,
 
                                              'email': c.user.email})()
 
        form_result = {}
 
        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:
 
            log.error(traceback.format_exc())
 
            h.flash(_('error occurred during update of user %s') \
 
                    % form_result.get('username'), category='error')
 

	
 
        return redirect(url('users'))
 

	
 
    def delete(self, id):
 
        """DELETE /users/id: Delete an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="DELETE" />
 
        # 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()
 
        try:
 
            user_model.delete(id)
 
            h.flash(_('successfully deleted user'), category='success')
 
        except (UserOwnsReposException, DefaultUserException), e:
 
            h.flash(str(e), category='warning')
 
        except Exception:
 
            h.flash(_('An error occurred during deletion of user'),
 
                    category='error')
 
        return redirect(url('users'))
 

	
 
    def show(self, id, format='html'):
 
        """GET /users/id: Show a specific item"""
 
        # url('user', id=ID)
 

	
 
    def edit(self, id, format='html'):
 
        """GET /users/id/edit: Form to edit an existing item"""
 
        # url('edit_user', id=ID)
 
        user_model = UserModel()
 
        c.user = user_model.get(id)
 
        if not c.user:
 
            return redirect(url('users'))
 
        if c.user.username == 'default':
 
            h.flash(_("You can't edit this user"), category='warning')
 
            return redirect(url('users'))
 
        c.user.permissions = {}
 
        c.granted_permissions = user_model.fill_perms(c.user)\
 
            .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'),
 
            defaults=defaults,
 
            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))
rhodecode/lib/db_manage.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.lib.db_manage
 
    ~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    Database creation, and setup module for RhodeCode. Used for creation
 
    of database as well as for migration operations
 

	
 
    :created_on: Apr 10, 2010
 
    :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, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# 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, see <http://www.gnu.org/licenses/>.
 

	
 
import os
 
import sys
 
import uuid
 
import logging
 
from os.path import dirname as dn, join as jn
 

	
 
from rhodecode import __dbversion__
 
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]
 
        self.tests = tests
 
        self.root = root
 
        self.dburi = dbconf
 
        self.log_sql = log_sql
 
        self.db_exists = False
 
        self.init_db()
 

	
 
    def init_db(self):
 
        engine = create_engine(self.dburi, echo=self.log_sql)
 
        init_model(engine)
 
        self.sa = meta.Session()
 

	
 
    def create_tables(self, override=False):
 
        """Create a auth database
 
        """
 

	
 
        log.info("Any existing database is going to be destroyed")
 
        if self.tests:
 
            destroy = True
 
        else:
 
            destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
 
        if not destroy:
 
            sys.exit()
 
        if destroy:
 
            meta.Base.metadata.drop_all()
 

	
 
        checkfirst = not override
 
        meta.Base.metadata.create_all(checkfirst=checkfirst)
 
        log.info('Created tables for %s', self.dbname)
 

	
 

	
 

	
 
    def set_db_version(self):
 
        try:
 
            ver = DbMigrateVersion()
 
            ver.version = __dbversion__
 
            ver.repository_id = 'rhodecode_db_migrations'
 
            ver.repository_path = 'versions'
 
            self.sa.add(ver)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            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
 

	
 
        """
 

	
 
        from rhodecode.lib.dbmigrate.migrate.versioning import api
 
        from rhodecode.lib.dbmigrate.migrate.exceptions import \
 
            DatabaseNotControlledError
 

	
 
        upgrade = ask_ok('You are about to perform database upgrade, make '
 
                         'sure You backed up your database before. '
 
                         'Continue ? [y/n]')
 
        if not upgrade:
 
            sys.exit('Nothing done')
 

	
 
        repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
 
                             'rhodecode/lib/dbmigrate')
 
        db_uri = self.dburi
 

	
 
        try:
 
            curr_version = api.db_version(db_uri, repository_path)
 
            msg = ('Found current database under version'
 
                 ' control with version %s' % curr_version)
 

	
 
        except (RuntimeError, DatabaseNotControlledError), e:
 
            curr_version = 1
 
            msg = ('Current database is not under version control. Setting'
 
                   ' as version %s' % curr_version)
 
            api.version_control(db_uri, repository_path, curr_version)
 

	
 
        print (msg)
 

	
 
        if curr_version == __dbversion__:
 
            sys.exit('This database is already at the newest version')
 

	
 
        #======================================================================
 
        # UPGRADE STEPS
 
        #======================================================================
 
        class UpgradeSteps(object):
 
            """Those steps follow schema versions so for example schema
 
            for example schema with seq 002 == step_2 and so on.
 
            """
 

	
 
            def __init__(self, klass):
 
                self.klass = klass
 

	
 
            def step_0(self):
 
                #step 0 is the schema upgrade, and than follow proper upgrades
 
                print ('attempting to do database upgrade to version %s' \
 
                                % __dbversion__)
 
                api.upgrade(db_uri, repository_path, __dbversion__)
 
                print ('Schema upgrade completed')
 

	
 
            def step_1(self):
 
                pass
 

	
 
            def step_2(self):
 
                print ('Patching repo paths for newer version of RhodeCode')
 
                self.klass.fix_repo_paths()
 

	
 
                print ('Patching default user of RhodeCode')
 
                self.klass.fix_default_user()
 

	
 
                log.info('Changing ui settings')
 
                self.klass.create_ui_settings()
 

	
 
            def step_3(self):
 
                print ('Adding additional settings into RhodeCode db')
 
                self.klass.fix_settings()
 

	
 
        upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
 

	
 
        #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
 
        for step in upgrade_steps:
 
            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 '*'
 
        """
 

	
 
        paths = self.sa.query(RhodeCodeUi)\
 
                .filter(RhodeCodeUi.ui_key == '/')\
 
                .scalar()
 

	
 
        paths.ui_value = paths.ui_value.replace('*', '')
 

	
 
        try:
 
            self.sa.add(paths)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def fix_default_user(self):
 
        """Fixes a old default user with some 'nicer' default values,
 
        used mostly for anonymous access
 
        """
 
        def_user = self.sa.query(User)\
 
                .filter(User.username == 'default')\
 
                .one()
 

	
 
        def_user.name = 'Anonymous'
 
        def_user.lastname = 'User'
 
        def_user.email = 'anonymous@rhodecode.org'
 

	
 
        try:
 
            self.sa.add(def_user)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def fix_settings(self):
 
        """Fixes rhodecode settings adds ga_code key for google analytics
 
        """
 

	
 
        hgsettings3 = RhodeCodeSettings('ga_code', '')
 

	
 
        try:
 
            self.sa.add(hgsettings3)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def admin_prompt(self, second=False):
 
        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:
 
                    log.error('passwords mismatch')
 
                    return False
 
                if len(password) < 6:
 
                    log.error('password is to short use at least 6 characters')
 
                    return False
 

	
 
                return password
 

	
 
            username = raw_input('Specify admin username:')
 

	
 
            password = get_password()
 
            if not password:
 
                #second try
 
                password = get_password()
 
                if not password:
 
                    sys.exit()
 

	
 
            email = raw_input('Specify admin email:')
 
            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
 
        and disables dotencode
 

	
 
        """
 
        #HOOKS
 
        hooks1_key = 'changegroup.update'
 
        hooks1_ = self.sa.query(RhodeCodeUi)\
 
            .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
 

	
 
        hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
 
        hooks1.ui_section = 'hooks'
 
        hooks1.ui_key = hooks1_key
 
        hooks1.ui_value = 'hg update >&2'
 
        hooks1.ui_active = False
 

	
 
        hooks2_key = 'changegroup.repo_size'
 
        hooks2_ = self.sa.query(RhodeCodeUi)\
 
            .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
 

	
 
        hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
 
        hooks2.ui_section = 'hooks'
 
        hooks2.ui_key = hooks2_key
 
        hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
 

	
 
        hooks3 = RhodeCodeUi()
 
        hooks3.ui_section = 'hooks'
 
        hooks3.ui_key = 'pretxnchangegroup.push_logger'
 
        hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
 

	
 
        hooks4 = RhodeCodeUi()
 
        hooks4.ui_section = 'hooks'
 
        hooks4.ui_key = 'preoutgoing.pull_logger'
 
        hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
 

	
 
        #For mercurial 1.7 set backward comapatibility with format
 
        dotencode_disable = RhodeCodeUi()
 
        dotencode_disable.ui_section = 'format'
 
        dotencode_disable.ui_key = 'dotencode'
 
        dotencode_disable.ui_value = 'false'
 

	
 
        try:
 
            self.sa.add(hooks1)
 
            self.sa.add(hooks2)
 
            self.sa.add(hooks3)
 
            self.sa.add(hooks4)
 
            self.sa.add(dotencode_disable)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 

	
 
    def create_ldap_options(self):
 
        """Creates ldap settings"""
 

	
 
        try:
 
            for k, v in [('ldap_active', 'false'), ('ldap_host', ''),
 
                        ('ldap_port', '389'), ('ldap_ldaps', 'false'),
 
                        ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''),
 
                        ('ldap_dn_pass', ''), ('ldap_base_dn', ''),
 
                        ('ldap_filter', ''), ('ldap_search_scope', ''),
 
                        ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
 
                        ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
 

	
 

	
 
                setting = RhodeCodeSettings(k, v)
 
                self.sa.add(setting)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def config_prompt(self, test_repo_path='', retries=3):
 
        if retries == 3:
 
            log.info('Setting up repositories config')
 

	
 
        if not self.tests and not test_repo_path:
 
            path = raw_input('Specify valid full path to your repositories'
 
                        ' you can change this later in application settings:')
 
        else:
 
            path = test_repo_path
 
        path_ok = True
 

	
 
        #check proper dir
 
        if not os.path.isdir(path):
 
            path_ok = False
 
            log.error('Entered path is not a valid directory: %s [%s/3]',
 
                      path, retries)
 

	
 
        #check write access
 
        if not os.access(path, os.W_OK):
 
            path_ok = False
 

	
 
            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):
 

	
 
        self.create_ui_settings()
 

	
 
        #HG UI OPTIONS
 
        web1 = RhodeCodeUi()
 
        web1.ui_section = 'web'
 
        web1.ui_key = 'push_ssl'
 
        web1.ui_value = 'false'
 

	
 
        web2 = RhodeCodeUi()
 
        web2.ui_section = 'web'
 
        web2.ui_key = 'allow_archive'
 
        web2.ui_value = 'gz zip bz2'
 

	
 
        web3 = RhodeCodeUi()
 
        web3.ui_section = 'web'
 
        web3.ui_key = 'allow_push'
 
        web3.ui_value = '*'
 

	
 
        web4 = RhodeCodeUi()
 
        web4.ui_section = 'web'
 
        web4.ui_key = 'baseurl'
 
        web4.ui_value = '/'
 

	
 
        paths = RhodeCodeUi()
 
        paths.ui_section = 'paths'
 
        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)
 
            self.sa.add(web3)
 
            self.sa.add(web4)
 
            self.sa.add(paths)
 
            self.sa.add(hgsettings1)
 
            self.sa.add(hgsettings2)
 
            self.sa.add(hgsettings3)
 

	
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
        self.create_ldap_options()
 

	
 
        log.info('created ui config')
 

	
 
    def create_user(self, username, password, email='', admin=False):
 
        log.info('creating administrator user %s', username)
 
        new_user = User()
 
        new_user.username = username
 
        new_user.password = get_crypt_password(password)
 
        new_user.api_key = generate_api_key(username)
 
        new_user.name = 'RhodeCode'
 
        new_user.lastname = 'Admin'
 
        new_user.email = email
 
        new_user.admin = admin
 
        new_user.active = True
 

	
 
        try:
 
            self.sa.add(new_user)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def create_default_user(self):
 
        log.info('creating default user')
 
        #create default user for handling default permissions.
 
        def_user = User()
 
        def_user.username = 'default'
 
        def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
 
        def_user.api_key = generate_api_key('default')
 
        def_user.name = 'Anonymous'
 
        def_user.lastname = 'User'
 
        def_user.email = 'anonymous@rhodecode.org'
 
        def_user.admin = False
 
        def_user.active = False
 
        try:
 
            self.sa.add(def_user)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
 

	
 
    def create_permissions(self):
 
        #module.(access|create|change|delete)_[name]
 
        #module.(read|write|owner)
 
        perms = [('repository.none', 'Repository no access'),
 
                 ('repository.read', 'Repository read access'),
 
                 ('repository.write', 'Repository write access'),
 
                 ('repository.admin', 'Repository admin access'),
 
                 ('hg.admin', 'Hg Administrator'),
 
                 ('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:
 
            new_perm = Permission()
 
            new_perm.permission_name = p[0]
 
            new_perm.permission_longname = p[1]
 
            try:
 
                self.sa.add(new_perm)
 
                self.sa.commit()
 
            except:
 
                self.sa.rollback()
 
                raise
 

	
 
    def populate_default_permissions(self):
 
        log.info('creating default user permissions')
 

	
 
        default_user = self.sa.query(User)\
 
        .filter(User.username == 'default').scalar()
 

	
 
        reg_perm = UserToPerm()
 
        reg_perm.user = default_user
 
        reg_perm.permission = self.sa.query(Permission)\
 
        .filter(Permission.permission_name == 'hg.register.manual_activate')\
 
        .scalar()
 

	
 
        create_repo_perm = UserToPerm()
 
        create_repo_perm.user = default_user
 
        create_repo_perm.permission = self.sa.query(Permission)\
 
        .filter(Permission.permission_name == 'hg.create.repository')\
 
        .scalar()
 

	
 
        default_repo_perm = UserToPerm()
 
        default_repo_perm.user = default_user
 
        default_repo_perm.permission = self.sa.query(Permission)\
 
        .filter(Permission.permission_name == 'repository.read')\
 
        .scalar()
 

	
 
        try:
 
            self.sa.add(reg_perm)
 
            self.sa.add(create_repo_perm)
 
            self.sa.add(default_repo_perm)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise
rhodecode/model/db.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.model.db
 
    ~~~~~~~~~~~~~~~~~~
 

	
 
    Database Models for RhodeCode
 

	
 
    :created_on: Apr 08, 2010
 
    :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, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# 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, see <http://www.gnu.org/licenses/>.
 

	
 
import os
 
import logging
 
import datetime
 
from datetime import date
 

	
 
from sqlalchemy import *
 
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__)
 

	
 
#==============================================================================
 
# MAPPER EXTENSIONS
 
#==============================================================================
 

	
 
class RepositoryMapper(MapperExtension):
 
    def after_update(self, mapper, connection, instance):
 
        pass
 

	
 

	
 
class RhodeCodeSettings(Base):
 
    __tablename__ = 'rhodecode_settings'
 
    __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
 
    app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 

	
 
    def __init__(self, k='', v=''):
 
        self.app_settings_name = k
 
        self.app_settings_value = v
 

	
 
    def __repr__(self):
 
        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}
 
    ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
 

	
 

	
 
class User(Base):
 
    __tablename__ = 'users'
 
    __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
 
    user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    active = Column("active", Boolean(), nullable=True, unique=None, default=None)
 
    admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
 
    name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
 
    ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 

	
 
    user_log = relationship('UserLog', cascade='all')
 
    user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
 

	
 
    repositories = relationship('Repository')
 
    user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
 

	
 
    group_member = relationship('UsersGroupMember', cascade='all')
 

	
 
    @property
 
    def full_contact(self):
 
        return '%s %s <%s>' % (self.name, self.lastname, self.email)
 

	
 
    @property
 
    def short_contact(self):
 
        return '%s %s' % (self.name, self.lastname)
 

	
 

	
 
    @property
 
    def is_admin(self):
 
        return self.admin
 

	
 
    def __repr__(self):
 
        return "<%s('id:%s:%s')>" % (self.__class__.__name__,
 
                                     self.user_id, self.username)
 

	
 
    @classmethod
 
    def by_username(cls, username):
 
        return Session.query(cls).filter(cls.username == username).one()
 

	
 

	
 
    def update_lastlogin(self):
 
        """Update user lastlogin"""
 

	
 
        try:
 
            session = Session.object_session(self)
 
            self.last_login = datetime.datetime.now()
 
            session.add(self)
 
            session.commit()
 
            log.debug('updated user %s lastlogin', self.username)
 
        except (DatabaseError,):
 
            session.rollback()
 

	
 

	
 
class UserLog(Base):
 
    __tablename__ = 'user_logs'
 
    __table_args__ = {'useexisting':True}
 
    user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 
    repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
 

	
 
    @property
 
    def action_as_day(self):
 
        return date(*self.action_date.timetuple()[:3])
 

	
 
    user = relationship('User')
 
    repository = relationship('Repository')
 

	
 

	
 
class UsersGroup(Base):
 
    __tablename__ = 'users_groups'
 
    __table_args__ = {'useexisting':True}
 

	
 
    users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
 
    users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
 

	
 
    members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
 
@@ -192,196 +223,234 @@ class Repository(Base):
 

	
 

	
 
    user = relationship('User')
 
    fork = relationship('Repository', remote_side=repo_id)
 
    group = relationship('Group')
 
    repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
 
    users_group_to_perm = relationship('UsersGroupToPerm', cascade='all')
 
    stats = relationship('Statistics', cascade='all', uselist=False)
 

	
 
    followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
 

	
 
    logs = relationship('UserLog', cascade='all')
 

	
 
    def __repr__(self):
 
        return "<%s('%s:%s')>" % (self.__class__.__name__,
 
                                  self.repo_id, self.repo_name)
 

	
 
    @classmethod
 
    def by_repo_name(cls, repo_name):
 
        return Session.query(cls).filter(cls.repo_name == repo_name).one()
 

	
 
    @property
 
    def just_name(self):
 
        return self.repo_name.split(os.sep)[-1]
 

	
 
    @property
 
    def groups_with_parents(self):
 
        groups = []
 
        if self.group is None:
 
            return groups
 

	
 
        cur_gr = self.group
 
        groups.insert(0, cur_gr)
 
        while 1:
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            groups.insert(0, gr)
 

	
 
        return groups
 

	
 
    @property
 
    def groups_and_repo(self):
 
        return self.groups_with_parents, self.just_name
 

	
 

	
 
class Group(Base):
 
    __tablename__ = 'groups'
 
    __table_args__ = (UniqueConstraint('group_name'), {'useexisting':True},)
 

	
 
    group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
 
    group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
 

	
 
    parent_group = relationship('Group', remote_side=group_id)
 

	
 

	
 
    def __init__(self, group_name='', parent_group=None):
 
        self.group_name = group_name
 
        self.parent_group = parent_group
 

	
 
    def __repr__(self):
 
        return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
 
                                  self.group_name)
 

	
 
    @property
 
    def parents(self):
 
        groups = []
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        while 1:
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def repositories(self):
 
        return Session.query(Repository).filter(Repository.group == self).all()
 

	
 
class Permission(Base):
 
    __tablename__ = 'permissions'
 
    __table_args__ = {'useexisting':True}
 
    permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 

	
 
    def __repr__(self):
 
        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})
 
    repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 

	
 
    user = relationship('User')
 
    permission = relationship('Permission')
 
    repository = relationship('Repository')
 

	
 
class UserToPerm(Base):
 
    __tablename__ = 'user_to_perm'
 
    __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
 
    user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 

	
 
    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'
 
    __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
 
    users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
 

	
 
    users_group = relationship('UsersGroup')
 
    permission = relationship('Permission')
 
    repository = relationship('Repository')
 

	
 
class GroupToPerm(Base):
 
    __tablename__ = 'group_to_perm'
 
    __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'useexisting':True})
 

	
 
    group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
 
    group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
 

	
 
    user = relationship('User')
 
    permission = relationship('Permission')
 
    group = relationship('Group')
 

	
 
class Statistics(Base):
 
    __tablename__ = 'statistics'
 
    __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
 
    stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
 
    stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
 
    commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
 
    commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
 
    languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
 

	
 
    repository = relationship('Repository', single_parent=True)
 

	
 
class UserFollowing(Base):
 
    __tablename__ = 'user_followings'
 
    __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
 
                      UniqueConstraint('user_id', 'follows_user_id')
 
                      , {'useexisting':True})
 

	
 
    user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
 
    follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
 

	
 
    user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
 

	
 
    follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
 
    follows_repository = relationship('Repository', order_by='Repository.repo_name')
 

	
 
class CacheInvalidation(Base):
 
    __tablename__ = 'cache_invalidation'
 
    __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
 
    cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
 
    cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
 

	
 

	
 
    def __init__(self, cache_key, cache_args=''):
 
        self.cache_key = cache_key
 
        self.cache_args = cache_args
 
        self.cache_active = False
 

	
 
    def __repr__(self):
 
        return "<%s('%s:%s')>" % (self.__class__.__name__,
 
                                  self.cache_id, self.cache_key)
 

	
 
class DbMigrateVersion(Base):
 
    __tablename__ = 'db_migrate_version'
 
    __table_args__ = {'useexisting':True}
 
    repository_id = Column('repository_id', String(250), primary_key=True)
 
    repository_path = Column('repository_path', Text)
 
    version = Column('version', Integer)
rhodecode/templates/admin/users/user_edit.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Edit user')} ${c.user.username} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_('Admin'),h.url('admin_home'))} 
 
    &raquo; 
 
    ${h.link_to(_('Users'),h.url('users'))} 
 
    &raquo;
 
    ${_('edit')} "${c.user.username}"
 
</%def>
 

	
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
</%def>
 

	
 
<%def name="main()">
 
<div class="box box-left">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${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">
 
               <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div>
 
               <p>
 
               <strong>Change your avatar at <a href="http://gravatar.com">gravatar.com</a></strong><br/> 
 
               ${_('Using')} ${c.user.email}
 
               </p>
 
           </div>
 
        </div>
 
        <div class="field">
 
            <div class="label">
 
                <label>${_('API key')}</label> ${c.user.api_key}
 
            </div>
 
        </div>
 
                 
 
        <div class="fields">
 
             <div class="field">
 
                <div class="label">
 
                    <label for="username">${_('Username')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('username',class_='medium')}
 
                </div>
 
             </div>
 
            
 
             <div class="field">
 
                <div class="label">
 
                    <label for="ldap_dn">${_('LDAP DN')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('ldap_dn',class_='medium')}
 
                </div>
 
             </div>
 
            
 
             <div class="field">
 
                <div class="label">
 
                    <label for="new_password">${_('New password')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.password('new_password',class_='medium')}
 
                </div>
 
             </div>
 
            
 
             <div class="field">
 
                <div class="label">
 
                    <label for="name">${_('First Name')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('name',class_='medium')}
 
                </div>
 
             </div>
 
            
 
             <div class="field">
 
                <div class="label">
 
                    <label for="lastname">${_('Last Name')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('lastname',class_='medium')}
 
                </div>
 
             </div>
 
            
 
             <div class="field">
 
                <div class="label">
 
                    <label for="email">${_('Email')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('email',class_='medium')}
 
                </div>
 
             </div>
 
            
 
             <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="active">${_('Active')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('active',value=True)}
 
                </div>
 
             </div>
 
             
 
             <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="admin">${_('Admin')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('admin',value=True)}
 
                </div>
 
             </div>             
 
            <div class="buttons">
 
              ${h.submit('save','Save',class_="ui-button")}
 
              ${h.reset('reset','Reset',class_="ui-button")}
 
            </div>             
 
    	</div>    
 
    </div>
 
    ${h.end_form()}
 
</div>
 
<div class="box box-right">
 
    <!-- box / title -->
 
    <div class="title">
 
        <h5>${_('Permissions')}</h5>       
 
    </div>
 
    ${h.form(url('user', id=c.user.user_id),method='put')}
 
    ${h.form(url('user_perm', id=c.user.user_id),method='put')}
 
    <div class="form">
 
        <!-- fields -->
 
        <div class="fields">
 
             <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="">${_('Create repositories')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('create',value=True)}
 
                    ${h.checkbox('create_repo_perm',value=True)}
 
                </div>
 
             </div>
 
            <div class="buttons">
 
              ${h.submit('save','Save',class_="ui-button")}
 
              ${h.reset('reset','Reset',class_="ui-button")}
 
            </div>             
 
        </div>    
 
    </div>
 
    ${h.end_form()}    
 
</div>
 
</%def>
rhodecode/templates/admin/users/users.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Users administration')} - ${c.rhodecode_name}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Users')}
 
</%def>
 

	
 
<%def name="page_nav()">
 
	${self.menu('admin')}
 
</%def>
 

	
 
<%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',h.url('new_user'))}</span>
 
          </li>
 
          
 
        </ul>        
 
    </div>
 
    <!-- end box / title -->
 
    <div class="table">
 
        <table class="table_disp">
 
        <tr class="header">
 
        	<th></th>
 
            <th class="left">${_('username')}</th>
 
            <th class="left">${_('name')}</th>
 
            <th class="left">${_('lastname')}</th>
 
            <th class="left">${_('last login')}</th>
 
            <th class="left">${_('active')}</th>
 
            <th class="left">${_('admin')}</th>
 
            <th class="left">${_('ldap')}</th>
 
            <th class="left">${_('action')}</th>
 
        </tr>
 
            %for cnt,user in enumerate(c.users_list):
 
             %if user.name !='default':
 
                <tr class="parity${cnt%2}">
 
                	<td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,24)}"/> </div></td>
 
                    <td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
 
                    <td>${user.name}</td>
 
                    <td>${user.lastname}</td>
 
                    <td>${user.last_login}</td>
 
                    <td>${h.bool2icon(user.active)}</td>
 
                    <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()}
 
                    </td>
 
                </tr>
 
             %endif
 
            %endfor
 
        </table>
 
    </div>
 
</div>
 
</%def>
rhodecode/templates/admin/users_groups/users_group_edit.html
Show inline comments
 
@@ -154,117 +154,117 @@ ${h.end_form()}
 
            
 
            for(var i = 0;node = tmp_cache[i];i++){
 
                ac.options[i] = node;
 
            }
 
            
 
            function prompts_action_callback(e){
 
                
 
                var choosen = D.get(selected_container);  
 
                var available = D.get(available_container);
 
                
 
                //get checked and unchecked options from field
 
                function get_checked(from_field){
 
                    //temp container for storage.
 
                    var sel_cache = new Array();
 
                    var oth_cache = new Array();
 
                    
 
                    for(var i = 0;node = from_field.options[i];i++){
 
                        if(node.selected){
 
                            //push selected fields :)
 
                            sel_cache.push(node);
 
                        }
 
                        else{
 
                        	oth_cache.push(node)
 
                        }
 
                    }                    
 
                    
 
                    return [sel_cache,oth_cache]
 
                }
 
                
 
                //fill the field with given options
 
                function fill_with(field,options){
 
                	//clear firtst
 
                	field.options.length=0;
 
                    for(var i = 0;node = options[i];i++){
 
                            field.options[i]=new Option(node.text, node.value, 
 
                                    false, false);
 
                    }
 
                	
 
                }
 
                //adds to current field
 
                function add_to(field,options){
 
                    for(var i = 0;node = options[i];i++){
 
                            field.appendChild(new Option(node.text, node.value, 
 
                                    false, false));
 
                    }
 
                }
 
                
 
                // add action
 
                if (this.id=='add_element'){
 
                    var c = get_checked(available);
 
                    add_to(choosen,c[0]);
 
                    fill_with(available,c[1]);
 
                }
 
                // remove action
 
                if (this.id=='remove_element'){
 
                    var c = get_checked(choosen);
 
                    add_to(available,c[0]);
 
                    fill_with(choosen,c[1]);             
 
                }                   
 
                // add all elements
 
                if(this.id=='add_all_elements'){
 
                    for(var i=0; node = available.options[i];i++){
 
                            choosen.appendChild(new Option(node.text, 
 
                                    node.value, false, false));
 
                    }
 
                    available.options.length = 0;
 
                }
 
                //remove all elements
 
                if(this.id=='remove_all_elements'){
 
                    for(var i=0; node = choosen.options[i];i++){
 
                        available.appendChild(new Option(node.text, 
 
                                node.value, false, false));
 
                    }
 
                    choosen.options.length = 0;                	
 
                }
 
                
 
            }
 
            
 
    
 
            E.addListener(['add_element','remove_element',
 
                           'add_all_elements','remove_all_elements'],'click',
 
                           prompts_action_callback)
 

	
 
            E.addListener(form_id,'submit',function(){
 
                var choosen = D.get(selected_container);
 
                for (var i = 0; i < choosen.options.length; i++) {
 
                    choosen.options[i].selected = 'selected';
 
                }
 
            })  
 
        });
 
</script>    
 
<div class="box box-right">
 
    <!-- box / title -->
 
    <div class="title">
 
        <h5>${_('Permissions')}</h5>       
 
    </div>
 
    ${h.form(url('user', id=''),method='put')}
 
    ${h.form(url('xxx', id=''),method='put')}
 
    <div class="form">
 
        <!-- fields -->
 
        <div class="fields">
 
             <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="">${_('Create repositories')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('create',value=True)}
 
                </div>
 
             </div>
 
            <div class="buttons">
 
              ${h.submit('save','Save',class_="ui-button")}
 
              ${h.reset('reset','Reset',class_="ui-button")}
 
            </div>             
 
        </div>    
 
    </div>
 
    ${h.end_form()}    
 
</div>
 
</%def>  
 
\ No newline at end of file
0 comments (0 inline, 0 general)