# -*- coding: utf-8 -*-
"""
rhodecode.controllers.login
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Login controller for rhodeocode
:created_on: Apr 22, 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 formencode
from formencode import htmlfill
from pylons.i18n.translation import _
from pylons.controllers.util import abort, redirect
from pylons import request, response, session, tmpl_context as c, url
import rhodecode.lib.helpers as h
from rhodecode.lib.auth import AuthUser, HasPermissionAnyDecorator
from rhodecode.lib.base import BaseController, render
from rhodecode.model.db import User
from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
from rhodecode.model.user import UserModel
from rhodecode.model.meta import Session
log = logging.getLogger(__name__)
class LoginController(BaseController):
def __before__(self):
super(LoginController, self).__before__()
def index(self):
# redirect if already logged in
c.came_from = request.GET.get('came_from', None)
if self.rhodecode_user.is_authenticated \
and self.rhodecode_user.username != 'default':
return redirect(url('home'))
if request.POST:
# import Login Form validator class
login_form = LoginForm()
try:
c.form_result = login_form.to_python(dict(request.POST))
# form checks for username/password, now we're authenticated
username = c.form_result['username']
user = User.get_by_username(username, case_insensitive=True)
auth_user = AuthUser(user.user_id)
auth_user.set_authenticated()
cs = auth_user.get_cookie_store()
session['rhodecode_user'] = cs
session.save()
log.info('user %s is now authenticated and stored in '
'session, session attrs %s' % (username, cs))
user.update_lastlogin()
if c.came_from:
return redirect(c.came_from)
else:
except formencode.Invalid, errors:
return htmlfill.render(
render('/login.html'),
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8")
return render('/login.html')
@HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
'hg.register.manual_activate')
def register(self):
user_model = UserModel()
c.auto_active = False
for perm in User.get_by_username('default').user_perms:
if perm.permission.permission_name == 'hg.register.auto_activate':
c.auto_active = True
break
register_form = RegisterForm()()
form_result = register_form.to_python(dict(request.POST))
form_result['active'] = c.auto_active
user_model.create_registration(form_result)
h.flash(_('You have successfully registered into rhodecode'),
category='success')
Session().commit()
return redirect(url('login_home'))
render('/register.html'),
return render('/register.html')
def password_reset(self):
password_reset_form = PasswordResetForm()()
form_result = password_reset_form.to_python(dict(request.POST))
user_model.reset_password_link(form_result)
h.flash(_('Your password reset link was sent'),
render('/password_reset.html'),
return render('/password_reset.html')
def password_reset_confirmation(self):
if request.GET and request.GET.get('key'):
user = User.get_by_api_key(request.GET.get('key'))
data = dict(email=user.email)
user_model.reset_password(data)
h.flash(_('Your password reset was successful, '
'new password has been sent to your email'),
except Exception, e:
log.error(e)
return redirect(url('reset_password'))
def logout(self):
del session['rhodecode_user']
log.info('Logging out and setting user as Empty')
redirect(url('home'))
@@ -190,192 +190,196 @@ class RhodeCodeSetting(Base, BaseModel):
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 = cls.query()\
.filter(cls.app_settings_name.startswith('ldap_')).all()
fd = {}
for row in ret:
fd.update({row.app_settings_name:row.app_settings_value})
return fd
class RhodeCodeUi(Base, BaseModel):
__tablename__ = 'rhodecode_ui'
__table_args__ = (UniqueConstraint('ui_key'), {'extend_existing':True})
HOOK_UPDATE = 'changegroup.update'
HOOK_REPO_SIZE = 'changegroup.repo_size'
HOOK_PUSH = 'pretxnchangegroup.push_logger'
HOOK_PULL = 'preoutgoing.pull_logger'
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)
def get_by_key(cls, key):
return cls.query().filter(cls.ui_key == key)
def get_builtin_hooks(cls):
q = cls.query()
q = q.filter(cls.ui_key.in_([cls.HOOK_UPDATE,
cls.HOOK_REPO_SIZE,
cls.HOOK_PUSH, cls.HOOK_PULL]))
return q.all()
def get_custom_hooks(cls):
q = q.filter(~cls.ui_key.in_([cls.HOOK_UPDATE,
q = q.filter(cls.ui_section == 'hooks')
def create_or_update_hook(cls, key, val):
new_ui = cls.get_by_key(key).scalar() or cls()
new_ui.ui_section = 'hooks'
new_ui.ui_active = True
new_ui.ui_key = key
new_ui.ui_value = val
Session().add(new_ui)
class User(Base, BaseModel):
__tablename__ = 'users'
__table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'extend_existing':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')
repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all')
group_member = relationship('UsersGroupMember', cascade='all')
notifications = relationship('UserNotification',)
@property
def full_name(self):
return '%s %s' % (self.name, self.lastname)
def full_contact(self):
return '%s %s <%s>' % (self.name, self.lastname, self.email)
def short_contact(self):
def is_admin(self):
return self.admin
def __repr__(self):
return "<%s('id:%s:%s')>" % (self.__class__.__name__,
self.user_id, self.username)
def get_by_username(cls, username, case_insensitive=False, cache=False):
if case_insensitive:
q = cls.query().filter(cls.username.ilike(username))
q = cls.query().filter(cls.username == username)
if cache:
q = q.options(FromCache("sql_cache_short",
"get_user_%s" % username))
return q.scalar()
def get_by_api_key(cls, api_key, cache=False):
q = cls.query().filter(cls.api_key == api_key)
"get_api_key_%s" % api_key))
def get_by_email(cls, email, cache=False):
q = cls.query().filter(cls.email == email)
"get_api_key_%s" % email))
def update_lastlogin(self):
"""Update user lastlogin"""
self.last_login = datetime.datetime.now()
Session().add(self)
log.debug('updated user %s lastlogin', self.username)
class UserLog(Base, BaseModel):
__tablename__ = 'user_logs'
__table_args__ = {'extend_existing':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(), 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)
def action_as_day(self):
return datetime.date(*self.action_date.timetuple()[:3])
user = relationship('User')
repository = relationship('Repository')
class UsersGroup(Base, BaseModel):
__tablename__ = 'users_groups'
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")
return '<userGroup(%s)>' % (self.users_group_name)
def get_by_group_name(cls, group_name, cache=False,
case_insensitive=False):
q = cls.query().filter(cls.users_group_name.ilike(group_name))
q = cls.query().filter(cls.users_group_name == group_name)
@@ -1077,162 +1081,163 @@ class CacheInvalidation(Base, BaseModel)
self.cache_args = cache_args
self.cache_active = False
return "<%s('%s:%s')>" % (self.__class__.__name__,
self.cache_id, self.cache_key)
def invalidate(cls, key):
Returns Invalidation object if this given key should be invalidated
None otherwise. `cache_active = False` means that this cache
state is not valid and needs to be invalidated
:param key:
return cls.query()\
.filter(CacheInvalidation.cache_key == key)\
.filter(CacheInvalidation.cache_active == False)\
.scalar()
def set_invalidate(cls, key):
Mark this Cache key for invalidation
log.debug('marking %s for invalidation' % key)
inv_obj = Session().query(cls)\
.filter(cls.cache_key == key).scalar()
if inv_obj:
inv_obj.cache_active = False
log.debug('cache key not found in invalidation db -> creating one')
inv_obj = CacheInvalidation(key)
Session().add(inv_obj)
except Exception:
log.error(traceback.format_exc())
Session().rollback()
def set_valid(cls, key):
Mark this cache key as active and currently cached
inv_obj = CacheInvalidation.query()\
.filter(CacheInvalidation.cache_key == key).scalar()
inv_obj.cache_active = True
class ChangesetComment(Base, BaseModel):
__tablename__ = 'changeset_comments'
__table_args__ = ({'extend_existing':True},)
comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
revision = Column('revision', String(40), nullable=False)
line_no = Column('line_no', Unicode(10), nullable=True)
f_path = Column('f_path', Unicode(1000), nullable=True)
user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
text = Column('text', Unicode(25000), nullable=False)
modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
author = relationship('User', lazy='joined')
repo = relationship('Repository')
def get_users(cls, revision):
Returns user associated with this changesetComment. ie those
who actually commented
:param cls:
:param revision:
return Session().query(User)\
.filter(cls.revision == revision)\
.join(ChangesetComment.author).all()
class Notification(Base, BaseModel):
__tablename__ = 'notifications'
__table_args__ = ({'extend_existing':True})
TYPE_CHANGESET_COMMENT = u'cs_comment'
TYPE_MESSAGE = u'message'
TYPE_MENTION = u'mention'
TYPE_REGISTRATION = u'registration'
notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True)
subject = Column('subject', Unicode(512), nullable=True)
body = Column('body', Unicode(50000), nullable=True)
created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True)
created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
type_ = Column('type', Unicode(256))
created_by_user = relationship('User')
notifications_to_users = relationship('UserNotification', lazy='joined',
cascade="all, delete, delete-orphan")
def recipients(self):
return [x.user for x in UserNotification.query()\
.filter(UserNotification.notification == self).all()]
def create(cls, created_by, subject, body, recipients, type_=None):
if type_ is None:
type_ = Notification.TYPE_MESSAGE
notification = cls()
notification.created_by_user = created_by
notification.subject = subject
notification.body = body
notification.type_ = type_
notification.created_on = datetime.datetime.now()
for u in recipients:
assoc = UserNotification()
assoc.notification = notification
u.notifications.append(assoc)
Session().add(notification)
return notification
def description(self):
from rhodecode.model.notification import NotificationModel
return NotificationModel().make_description(self)
class UserNotification(Base, BaseModel):
__tablename__ = 'user_to_notification'
__table_args__ = (UniqueConstraint('user_id', 'notification_id'),
{'extend_existing':True})
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), primary_key=True)
notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True)
read = Column('read', Boolean, default=False)
sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
user = relationship('User', lazy="joined")
notification = relationship('Notification', lazy="joined",
order_by=lambda:Notification.created_on.desc(),
cascade='all')
def mark_as_read(self):
self.read = True
class DbMigrateVersion(Base, BaseModel):
__tablename__ = 'db_migrate_version'
repository_id = Column('repository_id', String(250), primary_key=True)
repository_path = Column('repository_path', Text)
version = Column('version', Integer)
rhodecode.model.notification
~~~~~~~~~~~~~~
Model for notifications
:created_on: Nov 20, 2011
import os
import traceback
import datetime
import rhodecode
from rhodecode.lib import helpers as h
from rhodecode.model import BaseModel
from rhodecode.model.db import Notification, User, UserNotification
class NotificationModel(BaseModel):
def __get_user(self, user):
if isinstance(user, basestring):
return User.get_by_username(username=user)
return self._get_instance(User, user)
def __get_notification(self, notification):
if isinstance(notification, Notification):
elif isinstance(notification, int):
return Notification.get(notification)
if notification:
raise Exception('notification must be int or Instance'
' of Notification got %s' % type(notification))
def create(self, created_by, subject, body, recipients,
type_=Notification.TYPE_MESSAGE):
def create(self, created_by, subject, body, recipients=None,
type_=Notification.TYPE_MESSAGE, with_email=True,
email_kwargs={}):
Creates notification of given type
:param created_by: int, str or User instance. User who created this
notification
:param subject:
:param body:
:param recipients: list of int, str or User objects
:param recipients: list of int, str or User objects, when None
is given send to all admins
:param type_: type of notification
:param with_email: send email with this notification
:param email_kwargs: additional dict to pass as args to email template
from rhodecode.lib.celerylib import tasks, run_task
if not getattr(recipients, '__iter__', False):
if recipients and not getattr(recipients, '__iter__', False):
raise Exception('recipients must be a list of iterable')
created_by_obj = self.__get_user(created_by)
recipients_objs = []
obj = self.__get_user(u)
if obj:
recipients_objs.append(obj)
recipients_objs = set(recipients_objs)
if recipients:
# empty recipients means to all admins
recipients_objs = User.query().filter(User.admin == True).all()
notif = Notification.create(created_by=created_by_obj, subject=subject,
body=body, recipients=recipients_objs,
type_=type_)
if with_email is False:
return notif
# send email with notification
for rec in recipients_objs:
email_subject = NotificationModel().make_description(notif, False)
type_ = EmailNotificationModel.TYPE_CHANGESET_COMMENT
type_ = type_
email_body = body
kwargs = {'subject':subject, 'body':h.rst(body)}
kwargs.update(email_kwargs)
email_body_html = EmailNotificationModel()\
.get_email_tmpl(type_, **{'subject':subject,
'body':h.rst(body)})
.get_email_tmpl(type_, **kwargs)
run_task(tasks.send_email, rec.email, email_subject, email_body,
email_body_html)
def delete(self, user, notification):
# we don't want to remove actual notification just the assignment
notification = self.__get_notification(notification)
user = self.__get_user(user)
if notification and user:
obj = UserNotification.query()\
.filter(UserNotification.user == user)\
.filter(UserNotification.notification
== notification)\
.one()
self.sa.delete(obj)
return True
raise
def get_for_user(self, user):
return user.notifications
def get_unread_cnt_for_user(self, user):
return UserNotification.query()\
.filter(UserNotification.read == False)\
.filter(UserNotification.user == user).count()
def get_unread_for_user(self, user):
return [x.notification for x in UserNotification.query()\
.filter(UserNotification.user == user).all()]
def get_user_notification(self, user, notification):
.filter(UserNotification.notification == notification)\
.filter(UserNotification.user == user).scalar()
def make_description(self, notification, show_age=True):
Creates a human readable description based on properties
of notification object
_map = {notification.TYPE_CHANGESET_COMMENT:_('commented on commit'),
notification.TYPE_MESSAGE:_('sent message'),
notification.TYPE_MENTION:_('mentioned you')}
notification.TYPE_MENTION:_('mentioned you'),
notification.TYPE_REGISTRATION:_('registered in RhodeCode')}
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
tmpl = "%(user)s %(action)s %(when)s"
if show_age:
when = h.age(notification.created_on)
DTF = lambda d: datetime.datetime.strftime(d, DATETIME_FORMAT)
when = DTF(notification.created_on)
data = dict(user=notification.created_by_user.username,
action=_map[notification.type_],
when=when)
return tmpl % data
class EmailNotificationModel(BaseModel):
TYPE_CHANGESET_COMMENT = 'changeset_comment'
TYPE_PASSWORD_RESET = 'passoword_link'
TYPE_REGISTRATION = 'registration'
TYPE_DEFAULT = 'default'
def __init__(self):
self._template_root = rhodecode.CONFIG['pylons.paths']['templates'][0]
self._tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
self.email_types = {
self.TYPE_CHANGESET_COMMENT:'email_templates/changeset_comment.html',
self.TYPE_PASSWORD_RESET:'email_templates/password_reset.html',
self.TYPE_REGISTRATION:'email_templates/registration.html',
self.TYPE_DEFAULT:'email_templates/default.html'
}
def get_email_tmpl(self, type_, **kwargs):
return generated template for email based on given type
:param type_:
base = self.email_types.get(type_, self.TYPE_DEFAULT)
email_template = self._tmpl_lookup.get_template(base)
# translator inject
_kwargs = {'_':_}
_kwargs.update(kwargs)
log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs))
return email_template.render(**_kwargs)
rhodecode.model.user
~~~~~~~~~~~~~~~~~~~~
users model for RhodeCode
:created_on: Apr 9, 2010
from pylons import url
from rhodecode.lib import safe_unicode
from rhodecode.lib.caching_query import FromCache
from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \
UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember
UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember, \
Notification
from rhodecode.lib.exceptions import DefaultUserException, \
UserOwnsReposException
from sqlalchemy.exc import DatabaseError
from rhodecode.lib import generate_api_key
from sqlalchemy.orm import joinedload
PERM_WEIGHTS = {'repository.none': 0,
'repository.read': 1,
'repository.write': 3,
'repository.admin': 3}
class UserModel(BaseModel):
def get(self, user_id, cache=False):
user = self.sa.query(User)
user = user.options(FromCache("sql_cache_short",
"get_user_%s" % user_id))
return user.get(user_id)
def get_by_username(self, username, cache=False, case_insensitive=False):
user = self.sa.query(User).filter(User.username.ilike(username))
user = self.sa.query(User)\
.filter(User.username == username)
return user.scalar()
def get_by_api_key(self, api_key, cache=False):
return User.get_by_api_key(api_key, cache)
def create(self, form_data):
new_user = User()
for k, v in form_data.items():
setattr(new_user, k, v)
new_user.api_key = generate_api_key(form_data['username'])
self.sa.add(new_user)
self.sa.commit()
return new_user
except:
self.sa.rollback()
def create_or_update(self, username, password, email, name, lastname,
active=True, admin=False, ldap_dn=None):
Creates a new instance if not found, or updates current one
:param username:
:param password:
:param email:
:param active:
:param name:
:param lastname:
:param admin:
:param ldap_dn:
from rhodecode.lib.auth import get_crypt_password
log.debug('Checking for %s account in RhodeCode database', username)
if user is None:
log.debug('creating new user %s', username)
log.debug('updating user %s', username)
new_user = user
new_user.username = username
new_user.admin = admin
new_user.password = get_crypt_password(password)
new_user.api_key = generate_api_key(username)
new_user.email = email
new_user.active = active
new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None
new_user.name = name
new_user.lastname = lastname
except (DatabaseError,):
def create_for_container_auth(self, username, attrs):
Creates the given user if it's not already in the database
:param attrs:
if self.get_by_username(username, case_insensitive=True) is None:
# autogenerate email for container account without one
generate_email = lambda usr: '%s@container_auth.account' % usr
new_user.password = None
new_user.email = attrs['email']
new_user.active = attrs.get('active', True)
new_user.name = attrs['name'] or generate_email(username)
new_user.lastname = attrs['lastname']
log.debug('User %s already exists. Skipping creation of account'
' for container auth.', username)
return None
def create_ldap(self, username, password, user_dn, attrs):
Checks if user is in database, if not creates this user marked
as ldap user
:param user_dn:
log.debug('Checking for such ldap account in RhodeCode database')
# autogenerate email for ldap account without one
generate_email = lambda usr: '%s@ldap.account' % usr
username = username.lower()
# add ldap account always lowercase
new_user.email = attrs['email'] or generate_email(username)
new_user.ldap_dn = safe_unicode(user_dn)
new_user.name = attrs['name']
log.debug('this %s user exists skipping creation of ldap account',
username)
def create_registration(self, form_data):
if k != 'admin':
self.sa.flush()
# notification to admins
subject = _('new user registration')
body = ('New user registration\n'
'username: %s\n'
'email: %s\n')
body = body % (form_data['username'], form_data['email'])
'---------------------\n'
'- Username: %s\n'
'- Full Name: %s\n'
'- Email: %s\n')
body = body % (new_user.username, new_user.full_name,
new_user.email)
edit_url = url('edit_user', id=new_user.user_id, qualified=True)
kw = {'registered_user_url':edit_url}
NotificationModel().create(created_by=new_user, subject=subject,
body=body, recipients=None,
type_=Notification.TYPE_REGISTRATION,
email_kwargs=kw)
run_task(tasks.send_email, None,
_('[RhodeCode] New User registration'),
body)
def update(self, user_id, form_data):
user = self.get(user_id, cache=False)
if user.username == 'default':
raise DefaultUserException(
_("You can't Edit this user since it's"
" crucial for entire application"))
if k == 'new_password' and v != '':
user.password = v
user.api_key = generate_api_key(user.username)
setattr(user, k, v)
self.sa.add(user)
def update_my_account(self, user_id, form_data):
if k not in ['admin', 'active']:
def delete(self, user_id):
_("You can't remove this user since it's"
if user.repositories:
raise UserOwnsReposException(_('This user still owns %s '
'repositories and cannot be '
'removed. Switch owners or '
'remove those repositories') \
% user.repositories)
self.sa.delete(user)
def reset_password_link(self, data):
run_task(tasks.send_password_link, data['email'])
def reset_password(self, data):
run_task(tasks.reset_user_password, data['email'])
def fill_data(self, auth_user, user_id=None, api_key=None):
Fetches auth_user by user_id,or api_key if present.
Fills auth_user attributes with those taken from database.
Additionally set's is_authenitated if lookup fails
present in database
:param auth_user: instance of user to set attributes
:param user_id: user id to fetch by
:param api_key: api key to fetch by
if user_id is None and api_key is None:
raise Exception('You need to pass user_id or api_key')
if api_key:
dbuser = self.get_by_api_key(api_key)
dbuser = self.get(user_id)
if dbuser is not None and dbuser.active:
log.debug('filling %s data', dbuser)
new file 100644
## -*- coding: utf-8 -*-
<%inherit file="main.html"/>
A new user have registered in RhodeCode
${body}
View this user here :${registered_user_url}
\ No newline at end of file
Status change: