@@ -10,48 +10,49 @@ Changelog
:status: in-progress
:branch: beta
news
++++
- new codereview system
- email map, allowing users to have multiple email addresses mapped into
their accounts
- improved git-hook system. Now all actions for git are logged into journal
including pushed revisions, user and IP address
- changed setup-app into setup-rhodecode and added default options to it.
- new git repos are created as bare now by default
- #464 added links to groups in permission box
- #465 mentions autocomplete inside comments boxes
- #469 added --update-only option to whoosh to re-index only given list
of repos in index
- rhodecode-api CLI client
- new git http protocol replaced buggy dulwich implementation.
Now based on pygrack & gitweb
- Improved RSS/ATOM feeds. Discoverable by browsers using proper headers, and
reformated based on user suggestions. Additional rss/atom feeds for user
journal
- various i18n improvements
- #478 permissions overview for admin in user edit view
fixes
+++++
- improved translations
- fixes issue #455 Creating an archive generates an exception on Windows
- fixes #448 Download ZIP archive keeps file in /tmp open and results
in out of disk space
- fixes issue #454 Search results under Windows include proceeding
backslash
- fixed issue #450. Rhodecode no longer will crash when bad revision is
present in journal data.
- fix for issue #417, git execution was broken on windows for certain
commands.
- fixed #413. Don't disable .git directory for bare repos on deleting
- fixed issue #459. Changed the way of obtaining logger in reindex task.
- fixed #453 added ID field in whoosh SCHEMA that solves the issue of
reindexing modified files
1.3.6 (**2012-05-17**)
----------------------
@@ -14,49 +14,50 @@
# 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 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.auth import LoginRequired, HasPermissionAllDecorator,\
AuthUser
from rhodecode.lib.base import BaseController, render
from rhodecode.model.db import User, Permission
from rhodecode.model.forms import UserForm
from rhodecode.model.user import UserModel
from rhodecode.model.meta import Session
from rhodecode.lib.utils import action_logger
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']
@@ -90,49 +91,49 @@ class UsersController(BaseController):
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('update_user', id=ID),
# method='put')
# url('user', id=ID)
user_model = UserModel()
c.user = user_model.get(id)
c.perm_user = AuthUser(user_id=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)
usr = form_result['username']
action_logger(self.rhodecode_user, 'admin_updated_user:%s' % usr,
None, self.ip_addr, self.sa)
h.flash(_('User updated successfully'), category='success')
Session.commit()
except formencode.Invalid, errors:
e = errors.error_dict or {}
perm = Permission.get_by_key('hg.create.repository')
e.update({'create_repo_perm': user_model.has_perm(id, perm)})
return htmlfill.render(
render('admin/users/user_edit.html'),
defaults=errors.value,
errors=e,
h.flash(_('error occurred during update of user %s') \
@@ -153,48 +154,49 @@ class UsersController(BaseController):
user_model.delete(id)
h.flash(_('successfully deleted user'), category='success')
except (UserOwnsReposException, DefaultUserException), e:
h.flash(e, category='warning')
h.flash(_('An error occurred during deletion of user'),
category='error')
def show(self, id, format='html'):
"""GET /users/id: Show a specific item"""
def edit(self, id, format='html'):
"""GET /users/id/edit: Form to edit an existing item"""
# url('edit_user', id=ID)
c.user = User.get(id)
if not c.user:
if c.user.username == 'default':
h.flash(_("You can't edit this user"), category='warning')
c.user.permissions = {}
c.granted_permissions = UserModel().fill_perms(c.user)\
.permissions['global']
defaults = c.user.get_dict()
defaults.update({'create_repo_perm': UserModel().has_perm(id, perm)})
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')
@@ -136,26 +136,72 @@
<div class="box box-right">
<!-- box / title -->
<div class="title">
<h5>${_('Permissions')}</h5>
</div>
${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_repo_perm">${_('Create repositories')}:</label>
<div class="checkboxes">
${h.checkbox('create_repo_perm',value=True)}
<div class="buttons">
${h.submit('save',_('Save'),class_="ui-button")}
${h.reset('reset',_('Reset'),class_="ui-button")}
${h.end_form()}
## permissions overview
<div id="perms" class="table">
%for section in sorted(c.perm_user.permissions.keys()):
<div class="perms_section_head">${section.replace("_"," ").capitalize()}</div>
<div id='tbl_list_wrap_${section}' class="yui-skin-sam">
<table id="tbl_list_${section}">
<thead>
<tr>
<th class="left">${_('Name')}</th>
<th class="left">${_('Permission')}</th>
</thead>
<tbody>
%for k in c.perm_user.permissions[section]:
<%
if section != 'global':
section_perm = c.perm_user.permissions[section].get(k)
_perm = section_perm.split('.')[-1]
else:
_perm = section_perm = None
%>
<td>
%if section == 'repositories':
<a href="${h.url('summary_home',repo_name=k)}">${k}</a>
%elif section == 'repositories_groups':
<a href="${h.url('repos_group_home',group_name=k)}">${k}</a>
%else:
${k}
%endif
</td>
%if section == 'global':
${h.bool2icon(True)}
<span class="perm_tag ${_perm}">${section_perm}</span>
</tr>
%endfor
</tbody>
</table>
</%def>
Status change: