@@ -14,51 +14,54 @@
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License or (at your opinion) any later version of the license.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
import logging
import traceback
import formencode
from pylons import tmpl_context as c, request, url
from pylons.controllers.util import redirect
from pylons.i18n.translation import _
import rhodecode.lib.helpers as h
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator, \
NotAnonymous
from rhodecode.lib.base import BaseRepoController, render
from rhodecode.lib.utils import invalidate_cache, action_logger
from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
from rhodecode.model.repo import RepoModel
from rhodecode.model.db import User
log = logging.getLogger(__name__)
class SettingsController(BaseRepoController):
@LoginRequired()
def __before__(self):
super(SettingsController, self).__before__()
@HasRepoPermissionAllDecorator('repository.admin')
def index(self, repo_name):
repo_model = RepoModel()
c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
if not repo:
h.flash(_('%s repository is not mapped to db perhaps'
' it was created or renamed from the file system'
' please run the application again'
' in order to rescan repositories') % repo_name,
category='error')
return redirect(url('home'))
@@ -136,64 +139,65 @@ class SettingsController(BaseRepoControl
# url('repo_settings_delete', repo_name=ID)
repo = repo_model.get_by_repo_name(repo_name)
' it was moved or renamed from the filesystem'
try:
action_logger(self.rhodecode_user, 'user_deleted_repo',
repo_name, '', self.sa)
repo_model.delete(repo)
invalidate_cache('get_repo_cached_%s' % repo_name)
h.flash(_('deleted repository %s') % repo_name, category='success')
except Exception:
h.flash(_('An error occurred during deletion of %s') % repo_name,
@NotAnonymous()
@HasRepoPermissionAllDecorator('repository.read')
def fork(self, repo_name):
return render('settings/repo_fork.html')
def fork_create(self, repo_name):
c.repo_info = repo_model.get_by_repo_name(repo_name)
_form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
form_result = {}
form_result = _form.to_python(dict(request.POST))
form_result.update({'repo_name':repo_name})
repo_model.create_fork(form_result, c.rhodecode_user)
h.flash(_('forked %s repository as %s') \
% (repo_name, form_result['fork_name']),
category='success')
action_logger(self.rhodecode_user,
'user_forked_repo:%s' % form_result['fork_name'],
except formencode.Invalid, errors:
c.new_repo = errors.value['fork_name']
r = render('settings/repo_fork.html')
return formencode.htmlfill.render(
r,
defaults=errors.value,
errors=errors.error_dict or {},
@@ -12,48 +12,49 @@
# This program is free software; you can redistribute it and/or
import bcrypt
import random
from decorator import decorator
from pylons import config, session, url, request
from pylons.controllers.util import abort, redirect
from rhodecode.lib.exceptions import LdapPasswordError, LdapUsernameError
from rhodecode.lib.utils import get_repo_slug
from rhodecode.lib.auth_ldap import AuthLdap
from rhodecode.model import meta
from rhodecode.model.user import UserModel
from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
UserToPerm, UsersGroupToPerm, UsersGroupMember
PERM_WEIGHTS = {'repository.none':0,
'repository.read':1,
'repository.write':3,
'repository.admin':3}
class PasswordGenerator(object):
"""This is a simple class for generating password from
different sets of characters
usage:
@@ -363,48 +364,52 @@ class LoginRequired(object):
log.debug('redirecting to login page with %s', p)
return redirect(url('login_home', came_from=p))
class NotAnonymous(object):
"""Must be logged in to execute this function else
redirect to login page"""
def __call__(self, func):
return decorator(self.__wrapper, func)
def __wrapper(self, func, *fargs, **fkwargs):
user = session.get('rhodecode_user', AuthUser())
log.debug('Checking if user is not anonymous')
anonymous = user.username == 'default'
if anonymous:
p = ''
if request.environ.get('SCRIPT_NAME') != '/':
p += request.environ.get('SCRIPT_NAME')
p += request.environ.get('PATH_INFO')
if request.environ.get('QUERY_STRING'):
p += '?' + request.environ.get('QUERY_STRING')
h.flash(_('You need to be a registered user to perform this action'),
category='warning')
else:
return func(*fargs, **fkwargs)
class PermsDecorator(object):
"""Base class for decorators"""
def __init__(self, *required_perms):
available_perms = config['available_permissions']
for perm in required_perms:
if perm not in available_perms:
raise Exception("'%s' permission is not defined" % perm)
self.required_perms = set(required_perms)
self.user_perms = None
# _wrapper.__name__ = func.__name__
# _wrapper.__dict__.update(func.__dict__)
# _wrapper.__doc__ = func.__doc__
self.user = session.get('rhodecode_user', AuthUser())
## -*- coding: utf-8 -*-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
<head>
<title>${_('Sign In')} - ${c.rhodecode_name}</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="icon" href="${h.url("/images/icons/database_gear.png")}" type="image/png" />
<meta name="robots" content="index, nofollow"/>
<!-- stylesheets -->
<link rel="stylesheet" type="text/css" href="${h.url('/css/style.css')}" media="screen" />
</head>
<body>
<div id="login">
<div class="flash_msg">
<% messages = h.flash.pop_messages() %>
% if messages:
<ul id="flash-messages">
% for message in messages:
<li class="${message.category}_msg">${message}</li>
% endfor
</ul>
% endif
</div>
<!-- login -->
<div class="title top-left-rounded-corner top-right-rounded-corner">
<h5>${_('Sign In to')} ${c.rhodecode_name}</h5>
<div class="inner">
${h.form(h.url.current(came_from=c.came_from))}
<div class="form">
<!-- fields -->
<div class="fields">
<div class="field">
<div class="label">
<label for="username">${_('Username')}:</label>
<div class="input">
${h.text('username',class_='focus',size=40)}
<label for="password">${_('Password')}:</label>
Status change: