def test_extra_email_map(self): usr = UserModel().create_or_update(username=u'test_user', password=u'qweqwe', email=u'*****@*****.**', firstname=u'u1', lastname=u'u1') Session().commit() m = UserEmailMap() m.email = u'*****@*****.**' m.user = usr Session().add(m) Session().commit() u = User.get_by_email(email='*****@*****.**') self.assertEqual(usr.user_id, u.user_id) self.assertEqual(usr.username, u.username) u = User.get_by_email(email='*****@*****.**') self.assertEqual(usr.user_id, u.user_id) self.assertEqual(usr.username, u.username) u = User.get_by_email(email='*****@*****.**') self.assertEqual(None, u) UserModel().delete(usr.user_id) Session().commit()
def reset_password(self, data): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.lib import auth user_email = data['email'] try: try: user = User.get_by_email(user_email) new_passwd = auth.PasswordGenerator().gen_password(8, auth.PasswordGenerator.ALPHABETS_BIG_SMALL) if user: user.password = auth.get_crypt_password(new_passwd) user.api_key = auth.generate_api_key(user.username) Session().add(user) Session().commit() log.info('change password for %s' % user_email) if new_passwd is None: raise Exception('unable to generate new password') except Exception: log.error(traceback.format_exc()) Session().rollback() run_task(tasks.send_email, user_email, _('Your new password'), _('Your new RhodeCode password:%s') % (new_passwd)) log.info('send new password mail to %s' % user_email) except Exception: log.error('Failed to update user password') log.error(traceback.format_exc()) return True
def send_password_link(user_email): from rhodecode.model.notification import EmailNotificationModel log = get_logger(send_password_link) DBS = get_session() try: user = User.get_by_email(user_email) if user: log.debug('password reset user found %s' % user) link = url('reset_password_confirmation', key=user.api_key, qualified=True) reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET body = EmailNotificationModel().get_email_tmpl(reg_type, **{'user':user.short_contact, 'reset_url':link}) log.debug('sending email') run_task(send_email, user_email, _("password reset link"), body) log.info('send new password mail to %s' % user_email) else: log.debug("password reset email %s not found" % user_email) except: log.error(traceback.format_exc()) return False return True
def reset_user_password(user_email): from rhodecode.lib import auth log = get_logger(reset_user_password) DBS = get_session() try: try: user = User.get_by_email(user_email) new_passwd = auth.PasswordGenerator().gen_password(8, auth.PasswordGenerator.ALPHABETS_BIG_SMALL) if user: user.password = auth.get_crypt_password(new_passwd) user.api_key = auth.generate_api_key(user.username) DBS.add(user) DBS.commit() log.info('change password for %s' % user_email) if new_passwd is None: raise Exception('unable to generate new password') except: log.error(traceback.format_exc()) DBS.rollback() run_task(send_email, user_email, 'Your new password', 'Your new RhodeCode password:%s' % (new_passwd)) log.info('send new password mail to %s' % user_email) except: log.error('Failed to update user password') log.error(traceback.format_exc()) return True
def reset_password_link(self, data): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.model.notification import EmailNotificationModel user_email = data['email'] try: user = User.get_by_email(user_email) if user: log.debug('password reset user found %s' % user) link = url('reset_password_confirmation', key=user.api_key, qualified=True) reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET body = EmailNotificationModel().get_email_tmpl(reg_type, **{'user': user.short_contact, 'reset_url': link}) log.debug('sending email') run_task(tasks.send_email, user_email, _("Password reset link"), body, body) log.info('send new password mail to %s' % user_email) else: log.debug("password reset email %s not found" % user_email) except Exception: log.error(traceback.format_exc()) return False return True
def reset_password_link(self, data): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.model.notification import EmailNotificationModel user_email = data['email'] try: user = User.get_by_email(user_email) if user: log.debug('password reset user found %s' % user) link = url('reset_password_confirmation', key=user.api_key, qualified=True) reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET body = EmailNotificationModel().get_email_tmpl( reg_type, **{ 'user': user.short_contact, 'reset_url': link }) log.debug('sending email') run_task(tasks.send_email, user_email, _("Password reset link"), body, body) log.info('send new password mail to %s' % user_email) else: log.debug("password reset email %s not found" % user_email) except Exception: log.error(traceback.format_exc()) return False return True
def reset_password(self, data): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.lib import auth user_email = data['email'] try: try: user = User.get_by_email(user_email) new_passwd = auth.PasswordGenerator().gen_password( 8, auth.PasswordGenerator.ALPHABETS_BIG_SMALL) if user: user.password = auth.get_crypt_password(new_passwd) user.api_key = auth.generate_api_key(user.username) Session().add(user) Session().commit() log.info('change password for %s' % user_email) if new_passwd is None: raise Exception('unable to generate new password') except Exception: log.error(traceback.format_exc()) Session().rollback() run_task(tasks.send_email, user_email, _('Your new password'), _('Your new RhodeCode password:%s') % (new_passwd)) log.info('send new password mail to %s' % user_email) except Exception: log.error('Failed to update user password') log.error(traceback.format_exc()) return True
def reset_password(self, data): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.lib import auth user_email = data['email'] pre_db = True try: user = User.get_by_email(user_email) new_passwd = auth.PasswordGenerator().gen_password( 8, auth.PasswordGenerator.ALPHABETS_BIG_SMALL) if user: user.password = auth.get_crypt_password(new_passwd) user.api_key = auth.generate_api_key(user.username) Session().add(user) Session().commit() log.info('change password for %s' % user_email) if new_passwd is None: raise Exception('unable to generate new password') pre_db = False run_task(tasks.send_email, user_email, _('Your new password'), _('Your new RhodeCode password:%s') % (new_passwd, )) log.info('send new password mail to %s' % user_email) except Exception: log.error('Failed to update user password') log.error(traceback.format_exc()) if pre_db: # we rollback only if local db stuff fails. If it goes into # run_task, we're pass rollback state this wouldn't work then Session().rollback() return True
def validate_python(self, value, state): user = User.get_by_email(value, case_insensitive=True) if user is None: msg = M(self, 'non_existing_email', state, email=value) raise formencode.Invalid(msg, value, state, error_dict=dict(email=msg) )
def test_extra_email_map(test_user): m = UserEmailMap() m.email = u'*****@*****.**' m.user = test_user Session().add(m) Session().commit() u = User.get_by_email(email='*****@*****.**') assert test_user.user_id == u.user_id assert test_user.username == u.username u = User.get_by_email(email='*****@*****.**') assert test_user.user_id == u.user_id assert test_user.username == u.username u = User.get_by_email(email='*****@*****.**') assert u is None
def validate_python(self, value, state): if (old_data.get('email') or '').lower() != value: user = User.get_by_email(value, case_insensitive=True) if user: msg = M(self, 'email_taken', state) raise formencode.Invalid(msg, value, state, error_dict=dict(email=msg) )
def to_python(self, value, state): value = value.lower() if (old_data.get('email') or '').lower() != value: user = User.get_by_email(value, case_insensitive=True) if user: raise formencode.Invalid( _("This e-mail address is already taken"), value, state ) return value
def to_python(self, value, state): value = value.lower() user = User.get_by_email(value, case_insensitive=True) if user is None: raise formencode.Invalid( _("This e-mail address doesn't exist."), value, state ) return value
def password_reset(self): settings = SettingsModel().get_all_settings() captcha_private_key = settings.get('rhodecode_captcha_private_key') captcha_active = bool(captcha_private_key) captcha_public_key = settings.get('rhodecode_captcha_public_key') render_ctx = { 'captcha_active': captcha_active, 'captcha_public_key': captcha_public_key, 'defaults': {}, 'errors': {}, } if self.request.POST: password_reset_form = PasswordResetForm()() try: form_result = password_reset_form.to_python( self.request.params) if captcha_active: response = submit( self.request.params.get('recaptcha_challenge_field'), self.request.params.get('recaptcha_response_field'), private_key=captcha_private_key, remoteip=get_ip_addr(self.request.environ)) if captcha_active and not response.is_valid: _value = form_result _msg = _('bad captcha') error_dict = {'recaptcha_field': _msg} raise formencode.Invalid(_msg, _value, None, error_dict=error_dict) # Generate reset URL and send mail. user_email = form_result['email'] user = User.get_by_email(user_email) password_reset_url = self.request.route_url( 'reset_password_confirmation', _query={'key': user.api_key}) UserModel().reset_password_link( form_result, password_reset_url) # Display success message and redirect. self.session.flash( _('Your password reset link was sent'), queue='success') return HTTPFound(self.request.route_path('login')) except formencode.Invalid as errors: render_ctx.update({ 'defaults': errors.value, 'errors': errors.error_dict, }) return render_ctx
def reset_password(self, data): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.model.notification import EmailNotificationModel from rhodecode.lib import auth user_email = data['email'] pre_db = True try: user = User.get_by_email(user_email) new_passwd = auth.PasswordGenerator().gen_password( 12, auth.PasswordGenerator.ALPHABETS_BIG_SMALL) if user: user.password = auth.get_crypt_password(new_passwd) # also force this user to reset his password ! user.update_userdata(force_password_change=True) Session().add(user) Session().commit() log.info('change password for %s', user_email) if new_passwd is None: raise Exception('unable to generate new password') pre_db = False email_kwargs = { 'new_password': new_passwd, 'user': user, 'email': user_email, 'date': datetime.datetime.now() } (subject, headers, email_body, email_body_plaintext) = EmailNotificationModel().render_email( EmailNotificationModel.TYPE_PASSWORD_RESET_CONFIRMATION, **email_kwargs) recipients = [user_email] action_logger_generic( 'sent new password to user: {} with email: {}'.format( user, user_email), namespace='security.password_reset') run_task(tasks.send_email, recipients, subject, email_body_plaintext, email_body) except Exception: log.error('Failed to update user password') log.error(traceback.format_exc()) if pre_db: # we rollback only if local db stuff fails. If it goes into # run_task, we're pass rollback state this wouldn't work then Session().rollback() return True
def person(author, show_attr="username_and_name"): # attr to return from fetched user person_getter = lambda usr: getattr(usr, show_attr) # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email != '': user = User.get_by_email(_email, case_insensitive=True, cache=True) if user is not None: return person_getter(user) # Maybe it's a username? _author = author_name(author) user = User.get_by_username(_author, case_insensitive=True, cache=True) if user is not None: return person_getter(user) # Still nothing? Just pass back the author name if any, else the email return _author or _email
def email_or_none(author): # extract email from the commit string _email = email(author) if _email != '': # check it against RhodeCode database, and use the MAIN email for this # user user = User.get_by_email(_email, case_insensitive=True, cache=True) if user is not None: return user.email return _email # See if it contains a username we can get an email from user = User.get_by_username(author_name(author), case_insensitive=True, cache=True) if user is not None: return user.email # No valid email, not a valid user in the system, none! return None
def create_user(self, apiuser, username, email, password, firstname=None, lastname=None, active=True, admin=False, ldap_dn=None): """ Create new user :param apiuser: :param username: :param password: :param email: :param name: :param lastname: :param active: :param admin: :param ldap_dn: """ if User.get_by_username(username): raise JSONRPCError("user %s already exist" % username) if User.get_by_email(email, case_insensitive=True): raise JSONRPCError("email %s already exist" % email) if ldap_dn: # generate temporary password if ldap_dn password = PasswordGenerator().gen_password(length=8) try: usr = UserModel().create_or_update( username, password, email, firstname, lastname, active, admin, ldap_dn ) Session.commit() return dict( id=usr.user_id, msg='created new user %s' % username ) except Exception: log.error(traceback.format_exc()) raise JSONRPCError('failed to create user %s' % username)
def reset_password(self, data): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.lib import auth user_email = data["email"] pre_db = True try: user = User.get_by_email(user_email) new_passwd = auth.PasswordGenerator().gen_password(8, auth.PasswordGenerator.ALPHABETS_BIG_SMALL) if user: user.password = auth.get_crypt_password(new_passwd) user.api_key = auth.generate_api_key(user.username) Session().add(user) Session().commit() log.info("change password for %s" % user_email) if new_passwd is None: raise Exception("unable to generate new password") pre_db = False run_task( tasks.send_email, user_email, _("Your new password"), _("Your new RhodeCode password:%s") % (new_passwd,), ) log.info("send new password mail to %s" % user_email) except Exception: log.error("Failed to update user password") log.error(traceback.format_exc()) if pre_db: # we rollback only if local db stuff fails. If it goes into # run_task, we're pass rollback state this wouldn't work then Session().rollback() return True
def reset_password_link(self, data, pwd_reset_url): from rhodecode.lib.celerylib import tasks, run_task from rhodecode.model.notification import EmailNotificationModel user_email = data['email'] try: user = User.get_by_email(user_email) if user: log.debug('password reset user found %s', user) email_kwargs = { 'password_reset_url': pwd_reset_url, 'user': user, 'email': user_email, 'date': datetime.datetime.now() } (subject, headers, email_body, email_body_plaintext) = EmailNotificationModel().render_email( EmailNotificationModel.TYPE_PASSWORD_RESET, **email_kwargs) recipients = [user_email] action_logger_generic( 'sending password reset email to user: {}'.format( user), namespace='security.password_reset') run_task(tasks.send_email, recipients, subject, email_body_plaintext, email_body) else: log.debug("password reset email %s not found", user_email) except Exception: log.error(traceback.format_exc()) return False return True
def get_by_email(self, email, cache=False, case_insensitive=False): return User.get_by_email(email, case_insensitive, cache)
def create(self, text, repo, user, revision=None, pull_request=None, f_path=None, line_no=None, status_change=None): """ Creates new comment for changeset or pull request. IF status_change is not none this comment is associated with a status change of changeset or changesets associated with pull request :param text: :param repo: :param user: :param revision: :param pull_request: :param f_path: :param line_no: :param status_change: """ if not text: return repo = self._get_repo(repo) user = self._get_user(user) comment = ChangesetComment() comment.repo = repo comment.author = user comment.text = text comment.f_path = f_path comment.line_no = line_no if revision: cs = repo.scm_instance.get_changeset(revision) desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256)) author_email = cs.author_email comment.revision = revision elif pull_request: pull_request = self.__get_pull_request(pull_request) comment.pull_request = pull_request desc = pull_request.pull_request_id else: raise Exception('Please specify revision or pull_request_id') self.sa.add(comment) self.sa.flush() # make notification line = '' body = text #changeset if revision: if line_no: line = _('on line %s') % line_no subj = safe_unicode( h.link_to('Re commit: %(desc)s %(line)s' % \ {'desc': desc, 'line': line}, h.url('changeset_home', repo_name=repo.repo_name, revision=revision, anchor='comment-%s' % comment.comment_id, qualified=True, ) ) ) notification_type = Notification.TYPE_CHANGESET_COMMENT # get the current participants of this changeset recipients = ChangesetComment.get_users(revision=revision) # add changeset author if it's in rhodecode system recipients += [User.get_by_email(author_email)] email_kwargs = { 'status_change': status_change, } #pull request elif pull_request: _url = h.url('pullrequest_show', repo_name=pull_request.other_repo.repo_name, pull_request_id=pull_request.pull_request_id, anchor='comment-%s' % comment.comment_id, qualified=True, ) subj = safe_unicode( h.link_to('Re pull request: %(desc)s %(line)s' % \ {'desc': desc, 'line': line}, _url) ) notification_type = Notification.TYPE_PULL_REQUEST_COMMENT # get the current participants of this pull request recipients = ChangesetComment.get_users(pull_request_id= pull_request.pull_request_id) # add pull request author recipients += [pull_request.author] # add the reviewers to notification recipients += [x.user for x in pull_request.reviewers] #set some variables for email notification email_kwargs = { 'pr_id': pull_request.pull_request_id, 'status_change': status_change, 'pr_comment_url': _url, 'pr_comment_user': h.person(user.email), 'pr_target_repo': h.url('summary_home', repo_name=pull_request.other_repo.repo_name, qualified=True) } # create notification objects, and emails NotificationModel().create( created_by=user, subject=subj, body=body, recipients=recipients, type_=notification_type, email_kwargs=email_kwargs ) mention_recipients = set(self._extract_mentions(body))\ .difference(recipients) if mention_recipients: email_kwargs.update({'pr_mention': True}) subj = _('[Mention]') + ' ' + subj NotificationModel().create( created_by=user, subject=subj, body=body, recipients=mention_recipients, type_=notification_type, email_kwargs=email_kwargs ) return comment
def create(self, text, repo_id, user_id, revision, f_path=None, line_no=None): """ Creates new comment for changeset :param text: :param repo_id: :param user_id: :param revision: :param f_path: :param line_no: """ if text: repo = Repository.get(repo_id) cs = repo.scm_instance.get_changeset(revision) desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256)) author_email = cs.author_email comment = ChangesetComment() comment.repo = repo comment.user_id = user_id comment.revision = revision comment.text = text comment.f_path = f_path comment.line_no = line_no self.sa.add(comment) self.sa.flush() # make notification line = '' if line_no: line = _('on line %s') % line_no subj = safe_unicode( h.link_to('Re commit: %(commit_desc)s %(line)s' % \ {'commit_desc': desc, 'line': line}, h.url('changeset_home', repo_name=repo.repo_name, revision=revision, anchor='comment-%s' % comment.comment_id, qualified=True, ) ) ) body = text # get the current participants of this changeset recipients = ChangesetComment.get_users(revision=revision) # add changeset author if it's in rhodecode system recipients += [User.get_by_email(author_email)] NotificationModel().create( created_by=user_id, subject=subj, body=body, recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT) mention_recipients = set(self._extract_mentions(body))\ .difference(recipients) if mention_recipients: subj = _('[Mention]') + ' ' + subj NotificationModel().create( created_by=user_id, subject=subj, body=body, recipients=mention_recipients, type_=Notification.TYPE_CHANGESET_COMMENT) return comment
def create(self, text, repo_id, user_id, revision, f_path=None, line_no=None): """ Creates new comment for changeset :param text: :param repo_id: :param user_id: :param revision: :param f_path: :param line_no: """ if text: repo = Repository.get(repo_id) cs = repo.scm_instance.get_changeset(revision) desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256)) author_email = cs.author_email comment = ChangesetComment() comment.repo = repo comment.user_id = user_id comment.revision = revision comment.text = text comment.f_path = f_path comment.line_no = line_no self.sa.add(comment) self.sa.flush() # make notification line = '' if line_no: line = _('on line %s') % line_no subj = safe_unicode( h.link_to('Re commit: %(commit_desc)s %(line)s' % \ {'commit_desc': desc, 'line': line}, h.url('changeset_home', repo_name=repo.repo_name, revision=revision, anchor='comment-%s' % comment.comment_id, qualified=True, ) ) ) body = text # get the current participants of this changeset recipients = ChangesetComment.get_users(revision=revision) # add changeset author if it's in rhodecode system recipients += [User.get_by_email(author_email)] NotificationModel().create( created_by=user_id, subject=subj, body=body, recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT ) mention_recipients = set(self._extract_mentions(body))\ .difference(recipients) if mention_recipients: subj = _('[Mention]') + ' ' + subj NotificationModel().create( created_by=user_id, subject=subj, body=body, recipients=mention_recipients, type_=Notification.TYPE_CHANGESET_COMMENT ) return comment