def request_reset(self): context = {'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj} data_dict = {'id': request.params.get('user')} try: check_access('request_reset', context) except NotAuthorized: abort(401, _('Unauthorized to request reset password.')) if request.method == 'POST': id = request.params.get('user') context = {'model': model, 'user': c.user} data_dict = {'id': id} user_obj = None try: user_dict = get_action('user_show')(context, data_dict) user_obj = context['user_obj'] except NotFound: # Show success regardless of outcome to prevent scanning h.flash_success(_('Please check your inbox for ' 'a reset code.')) if user_obj: try: mailer.send_reset_link(user_obj) h.flash_success(_('Please check your inbox for ' 'a reset code.')) h.redirect_to('/') except mailer.MailerException, e: h.flash_error(_('Could not send reset link: %s') % unicode(e))
def request_reset(self): context = {'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj} try: check_access('request_reset', context) except NotAuthorized: abort(401, _('Unauthorized to request reset password.')) if request.method == 'POST': email = request.params.get('email') users = model.User.by_email(email) if not users: h.flash_error(_('Email not registered: %s') % email) else: try: mailer.send_reset_link(users[0]) h.flash_success(_('Please check your inbox for ' 'a reset code.')) h.redirect_to('/') except mailer.MailerException, e: h.flash_error(_('Could not send reset link: %s') % unicode(e))
def request_reset(self): context = {'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj} data_dict = {'id': request.params.get('user')} try: check_access('request_reset', context) except NotAuthorized: abort(401, _('Unauthorized to request reset password.')) if request.method == 'POST': id = request.params.get('user') context = {'model': model, 'user': c.user} data_dict = {'id': id} user_obj = None try: user_dict = get_action('user_show')(context, data_dict) user_obj = context['user_obj'] except NotFound: h.flash_error(_('No such user: %s') % id) if user_obj: try: mailer.send_reset_link(user_obj) h.flash_success(_('Please check your inbox for ' 'a reset code.')) h.redirect_to('/') except mailer.MailerException, e: h.flash_error(_('Could not send reset link: %s') % unicode(e))
def user_create(context, data_dict): user_dict = ckan_user_create(context, data_dict) group_context = context.get('group') # We don't do this when inviting new user to a group if not group_context or group_context.type != 'group': # Add the created user to existed groups groups = p.toolkit.get_action('group_list')({}, {}) context['ignore_auth'] = True for group in groups: group_dict = { 'id': group, 'username': user_dict['id'], 'role': 'member' } p.toolkit.get_action('group_member_create')(context, group_dict) # We don't need these when inviting new users if not context['auth_user_obj']: user = model.User.get(user_dict['id']) # Set the user as pending before changing his/her password. user.set_pending() # Reset the created user's password immediately try: mailer.send_reset_link(user) except mailer.MailerException, e: log.debug('Could not send reset link: %s' % unicode(e))
def request_reset(self): context = {"model": model, "session": model.Session, "user": toolkit.c.user, "auth_user_obj": toolkit.c.userobj} data_dict = {"id": toolkit.request.params.get("user")} try: toolkit.check_access("request_reset", context) except toolkit.NotAuthorized: toolkit.abort(401, toolkit._("Unauthorized to request reset password.")) if toolkit.request.method == "POST": id = toolkit.request.params.get("user") context = {"model": model, "user": toolkit.c.user} data_dict = {"id": id} user_obj = None try: toolkit.get_action("user_show")(context, data_dict) user_obj = context["user_obj"] except toolkit.ObjectNotFound: h.flash_error(toolkit._("No such user: %s") % id) if user_obj: try: mailer.send_reset_link(user_obj) h.flash_success(toolkit._("Please check your inbox for " "a reset code.")) h.redirect_to("/") except mailer.MailerException, e: h.flash_error(toolkit._("Could not send reset link: %s") % unicode(e))
def request_reset(self): context = { 'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj } data_dict = {'id': request.params.get('user')} try: check_access('request_reset', context) except NotAuthorized: abort(403, _('Unauthorized to request reset password.')) if request.method == 'POST': id = request.params.get('user') context = {'model': model, 'user': c.user} data_dict = {'id': id} user_obj = None try: user_dict = get_action('user_show_gdpr')(context, data_dict) user_obj = context['user_obj'] except NotFound: # Try searching the user del data_dict['id'] data_dict['q'] = id if id and len(id) > 2: user_list = get_action('user_list_gdpr')(context, data_dict) if len(user_list) == 1: # This is ugly, but we need the user object for the # mailer, # and user_list does not return them del data_dict['q'] data_dict['id'] = user_list[0]['id'] user_dict = get_action('user_show_gdpr')(context, data_dict) user_obj = context['user_obj'] elif len(user_list) > 1: h.flash_error(_('"%s" matched several users') % (id)) else: h.flash_error(_('No such user: %s') % id) else: h.flash_error(_('No such user: %s') % id) if user_obj: try: mailer.send_reset_link(user_obj) h.flash_success( _('Please check your inbox for ' 'a reset code.')) h.redirect_to('/') except mailer.MailerException, e: h.flash_error( _('Could not send reset link: %s') % unicode(e))
def request_reset(self): context = { 'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj } data_dict = {'id': request.params.get('user')} try: check_access('request_reset', context) except NotAuthorized: abort(401, _('Unauthorized to request reset password.')) if request.method == 'POST': id = request.params.get('user') context = {'model': model, 'user': c.user} data_dict = {'id': id} user_obj = None try: user_dict = get_action('user_show')(context, data_dict) user_obj = context['user_obj'] except NotFound: # Try searching the user del data_dict['id'] data_dict['q'] = id if id and len(id) > 2: user_list = get_action('user_list')(context, data_dict) if len(user_list) == 1: # This is ugly, but we need the user object for the # mailer, # and user_list does not return them del data_dict['q'] data_dict['id'] = user_list[0]['id'] user_dict = get_action('user_show')(context, data_dict) user_obj = context['user_obj'] elif len(user_list) > 1: h.flash_error(_('"%s" matched several users') % (id)) else: h.flash_error(_('No such user: %s') % id) else: h.flash_error(_('No such user: %s') % id) if user_obj: try: mailer.send_reset_link(user_obj) h.flash_success( _('Please check your inbox for ' 'a reset code.')) h.redirect_to('/') except mailer.MailerException, e: h.flash_error( _('Could not send reset link: %s') % unicode(e))
def request_reset(self): if request.method == 'POST': id = request.params.get('user') user = model.User.get(id) if user is None: h.flash_error(_('No such user: %s') % id) try: mailer.send_reset_link(user) h.flash_success(_('Please check your inbox for a reset code.')) redirect('/') except mailer.MailerException, e: h.flash_error(_('Could not send reset link: %s') % unicode(e))
def request_reset(self): # Later versions of CKAN core have fixed this behaviour, we default to overriding # with our own implementation but allow client to disable if needed if asbool(config.get('ckanext.security.disable_password_reset_override')): return original_password_reset(self) # This is a one-to-one copy from ckan core, except for user errors # handling. There should be no feedback about whether or not a user # is found in the db. # Original method is `ckan.controllers.user.UserController.request_reset` context = {'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj} data_dict = {'id': request.params.get('user')} try: check_access('request_reset', context) except NotAuthorized: abort(403, _('Unauthorized to request reset password.')) if request.method == 'POST': id = request.params.get('user') context = {'model': model, 'user': c.user, u'ignore_auth': True} data_dict = {'id': id} user_obj = None try: user_dict = get_action('user_show')(context, data_dict) user_obj = context['user_obj'] except NotFound: # Try searching the user del data_dict['id'] data_dict['q'] = id if id and len(id) > 2: user_list = get_action('user_list')(context, data_dict) if len(user_list) == 1: # This is ugly, but we need the user object for the # mailer, # and user_list does not return them del data_dict['q'] data_dict['id'] = user_list[0]['id'] user_dict = get_action('user_show')(context, data_dict) user_obj = context['user_obj'] helpers.flash_success(_('A reset token has been sent.')) if user_obj: mailer.send_reset_link(user_obj) return render('user/request_reset.html')
def test_send_reset_email(self): # send email mailer.send_reset_link(model.User.by_name(u"bob")) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] assert_equal(msg[1], config["smtp.mail_from"]) assert_equal(msg[2], [model.User.by_name(u"bob").email]) assert "Reset" in msg[3], msg[3] test_msg = mailer.get_reset_link_body(model.User.by_name(u"bob")) expected_body = self.mime_encode(test_msg, u"bob") assert expected_body in msg[3], "%r not in %r" % (expected_body, msg[3])
def test_send_reset_email(self): # send email mailer.send_reset_link(model.User.by_name(u'bob')) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] assert_equal(msg[1], config['smtp.mail_from']) assert_equal(msg[2], [model.User.by_name(u'bob').email]) assert 'Reset' in msg[3], msg[3] test_msg = mailer.get_reset_link_body(model.User.by_name(u'bob')) expected_body = self.mime_encode(test_msg, u'bob') assert expected_body in msg[3], '%r not in %r' % (expected_body, msg[3])
def test_reset_password_custom_body(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = {'reset_link': mailer.get_reset_link(user_obj)} expected = render_jinja2('emails/reset_password.txt', extra_vars) body = self.get_email_body(msg[3]) assert_equal(expected, body) assert_in('**test**', body)
def test_reset_password_custom_body(self): user = factories.User() user_obj = model.User.by_name(user["name"]) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert len(msgs) == 1 msg = msgs[0] extra_vars = {"reset_link": mailer.get_reset_link(user_obj)} expected = render_jinja2("emails/reset_password.txt", extra_vars) body = self.get_email_body(msg[3]) assert expected == body assert "**test**" in body
def post(self): context, data_dict = self._prepare() id = data_dict[u'id'] context = {u'model': model, u'user': g.user} user_obj = None try: logic.get_action(u'user_show')(context, data_dict) user_obj = context[u'user_obj'] except logic.NotFound: # Try getting the user by email user_accounts = model.User.by_email(id) if user_accounts: user_obj = user_accounts[0] if not user_obj: # Try searching the user if id and len(id) > 2: user_list = logic.get_action(u'user_list')(context, { u'id': id }) if len(user_list) == 1: # This is ugly, but we need the user object for the # mailer, # and user_list does not return them data_dict[u'id'] = user_list[0][u'id'] logic.get_action(u'user_show')(context, data_dict) user_obj = context[u'user_obj'] elif len(user_list) > 1: h.flash_error(_(u'"%s" matched several users') % (id)) else: h.flash_error(_(u'No such user: %s') % id) else: h.flash_error(_(u'No such user: %s') % id) if user_obj: try: # FIXME: How about passing user.id instead? Mailer already # uses model and it allow to simplify code above mailer.send_reset_link(user_obj) h.flash_success( _(u'Please check your inbox for ' u'a reset code.')) return h.redirect_to(u'home.index') except mailer.MailerException as e: h.flash_error(_(u'Could not send reset link: %s') % text_type(e)) return self.get()
def activate_user(context, data_dict): check_access('sysadmin', context, {}) model = context['model'] id = get_or_bust(data_dict, 'id') user_obj = model.User.get(id) if not user_obj: raise ObjectNotFound('User was not found') user_obj.activate() user_obj.save() try: send_reset_link(user_obj) except Exception, e: h.flash_error(_('Could not send reset link: %s') % unicode(e))
def test_send_reset_email(self): # send email send_reset_link(model.User.by_name(u'bob')) time.sleep(0.1) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] assert_equal(msg[1], config['smtp.mail_from']) assert_equal(msg[2], [model.User.by_name(u'bob').email]) assert 'Reset' in msg[3], msg[3] test_msg = get_reset_link_body(model.User.by_name(u'bob')) expected_body = self.mime_encode(test_msg, u'bob') assert expected_body in msg[3], '%r not in %r' % (expected_body, msg[3])
def request_reset(self): context = {"model": model, "session": model.Session, "user": c.user, "auth_user_obj": c.userobj} data_dict = {"id": request.params.get("user")} try: check_access("request_reset", context) except NotAuthorized: abort(401, _("Unauthorized to request reset password.")) if request.method == "POST": id = request.params.get("user") context = {"model": model, "user": c.user} data_dict = {"id": id} user_obj = None try: user_dict = get_action("user_show")(context, data_dict) user_obj = context["user_obj"] except NotFound: # Try searching the user del data_dict["id"] data_dict["q"] = id if id and len(id) > 2: user_list = get_action("user_list")(context, data_dict) if len(user_list) == 1: # This is ugly, but we need the user object for the # mailer, # and user_list does not return them del data_dict["q"] data_dict["id"] = user_list[0]["id"] user_dict = get_action("user_show")(context, data_dict) user_obj = context["user_obj"] elif len(user_list) > 1: h.flash_error(_('"%s" matched several users') % (id)) else: h.flash_error(_("No such user: %s") % id) else: h.flash_error(_("No such user: %s") % id) if user_obj: try: mailer.send_reset_link(user_obj) h.flash_success(_("Please check your inbox for " "a reset code.")) h.redirect_to("/") except mailer.MailerException, e: h.flash_error(_("Could not send reset link: %s") % unicode(e))
def test_reset_password_custom_subject(self, mail_server): user = factories.User() user_obj = model.User.by_name(user["name"]) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = mail_server.get_smtp_messages() assert len(msgs) == 1 msg = msgs[0] extra_vars = {"site_title": config.get("ckan.site_title")} expected = render("emails/reset_password_subject.txt", extra_vars) expected = expected.split("\n")[0] subject = self.get_email_subject(msg[3]).decode() assert expected == subject assert "**test**" in subject
def test_send_reset_email(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] assert_equal(msg[1], config['smtp.mail_from']) assert_equal(msg[2], [user['email']]) assert 'Reset' in msg[3], msg[3] test_msg = mailer.get_reset_link_body(user_obj) expected_body = self.mime_encode(test_msg, user['name']) assert_in(expected_body, msg[3])
def test_send_reset_email(self, mail_server): user = factories.User() user_obj = model.User.by_name(user["name"]) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = mail_server.get_smtp_messages() assert len(msgs) == 1 msg = msgs[0] assert msg[1] == config["smtp.mail_from"] assert msg[2] == [user["email"]] assert "Reset" in msg[3], msg[3] test_msg = mailer.get_reset_link_body(user_obj) expected_body = self.mime_encode(test_msg + '\n', user["name"]) assert expected_body in msg[3]
def test_reset_password_custom_subject(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = {'site_title': config.get('ckan.site_title')} expected = render_jinja2('emails/reset_password_subject.txt', extra_vars) expected = expected.split('\n')[0] subject = self.get_email_subject(msg[3]) assert_equal(expected, subject) assert_in('**test**', subject)
def test_reset_password_custom_body(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = { 'reset_link': mailer.get_reset_link(user_obj) } expected = render_jinja2('emails/reset_password.txt', extra_vars) body = self.get_email_body(msg[3]) assert_equal(expected, body) assert_in('**test**', body)
def test_reset_password_custom_subject(self): user = factories.User() user_obj = model.User.by_name(user['name']) mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] extra_vars = { 'site_title': config.get('ckan.site_title') } expected = render_jinja2('emails/reset_password_subject.txt', extra_vars) expected = expected.split('\n')[0] subject = self.get_email_subject(msg[3]) assert_equal(expected, subject) assert_in('**test**', subject)
def post(self): context, data_dict = self._prepare() id = data_dict[u'id'] context = {u'model': model, u'user': g.user} user_obj = None try: logic.get_action(u'user_show')(context, data_dict) user_obj = context[u'user_obj'] except logic.NotFound: # Try searching the user if id and len(id) > 2: user_list = logic.get_action(u'user_list')(context, { u'id': id }) if len(user_list) == 1: # This is ugly, but we need the user object for the # mailer, # and user_list does not return them data_dict[u'id'] = user_list[0][u'id'] logic.get_action(u'user_show')(context, data_dict) user_obj = context[u'user_obj'] elif len(user_list) > 1: h.flash_error(_(u'"%s" matched several users') % (id)) else: h.flash_error(_(u'No such user: %s') % id) else: h.flash_error(_(u'No such user: %s') % id) if user_obj: try: # FIXME: How about passing user.id instead? Mailer already # uses model and it allow to simplify code above mailer.send_reset_link(user_obj) h.flash_success( _(u'Please check your inbox for ' u'a reset code.')) return h.redirect_to(u'/') except mailer.MailerException as e: h.flash_error(_(u'Could not send reset link: %s') % unicode(e)) return self.get()
def test_send_reset_email(self): user = factories.User() user_obj = model.User.by_name(user['name']) # We need to provide a context as url_for is used internally with self.app.flask_app.test_request_context(): mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() assert_equal(len(msgs), 1) msg = msgs[0] assert_equal(msg[1], config['smtp.mail_from']) assert_equal(msg[2], [user['email']]) assert 'Reset' in msg[3], msg[3] # We need to provide a context as url_for is used internally with self.app.flask_app.test_request_context(): test_msg = mailer.get_reset_link_body(user_obj) expected_body = self.mime_encode(test_msg, user['name']) assert_in(expected_body, msg[3])
def post(self): self._prepare() id = request.form.get(u'user') if id in (None, u''): h.flash_error(_(u'Email is required')) return h.redirect_to(u'/user/reset') log.info(u'Password reset requested for user "{}"'.format(id)) context = {u'model': model, u'user': g.user, u'ignore_auth': True} user_objs = [] # Usernames cannot contain '@' symbols if u'@' in id: # Search by email address # (You can forget a user id, but you don't tend to forget your # email) user_list = logic.get_action(u'user_list')(context, { u'email': id }) if user_list: # send reset emails for *all* user accounts with this email # (otherwise we'd have to silently fail - we can't tell the # user, as that would reveal the existence of accounts with # this email address) for user_dict in user_list: # This is ugly, but we need the user object for the mailer, # and user_list does not return them logic.get_action(u'user_show')( context, {u'id': user_dict[u'id']}) user_objs.append(context[u'user_obj']) else: # Search by user name # (this is helpful as an option for a user who has multiple # accounts with the same email address and they want to be # specific) try: logic.get_action(u'user_show')(context, {u'id': id}) user_objs.append(context[u'user_obj']) except logic.NotFound: pass if not user_objs: log.info(u'User requested reset link for unknown user: {}' .format(id)) for user_obj in user_objs: log.info(u'Emailing reset link to user: {}' .format(user_obj.name)) try: # FIXME: How about passing user.id instead? Mailer already # uses model and it allow to simplify code above mailer.send_reset_link(user_obj) except mailer.MailerException as e: # SMTP is not configured correctly or the server is # temporarily unavailable h.flash_error(_(u'Error sending the email. Try again later ' 'or contact an administrator for help')) log.exception(e) return h.redirect_to(u'home.index') # always tell the user it succeeded, because otherwise we reveal # which accounts exist or not h.flash_success( _(u'A reset link has been emailed to you ' '(unless the account specified does not exist)')) return h.redirect_to(u'home.index')
def post(self): self._prepare() id = request.form.get(u'user') if id in (None, u''): h.flash_error(_(u'Email is required')) return h.redirect_to(u'/user/reset') log.info(u'Password reset requested for user "{}"'.format(id)) context = {u'model': model, u'user': g.user, u'ignore_auth': True} user_objs = [] # Usernames cannot contain '@' symbols if u'@' in id: # Search by email address # (You can forget a user id, but you don't tend to forget your # email) user_list = logic.get_action(u'user_list')(context, {u'email': id}) if user_list: # send reset emails for *all* user accounts with this email # (otherwise we'd have to silently fail - we can't tell the # user, as that would reveal the existence of accounts with # this email address) for user_dict in user_list: # This is ugly, but we need the user object for the mailer, # and user_list does not return them logic.get_action(u'user_show')(context, { u'id': user_dict[u'id'] }) user_objs.append(context[u'user_obj']) else: # Search by user name # (this is helpful as an option for a user who has multiple # accounts with the same email address and they want to be # specific) try: logic.get_action(u'user_show')(context, {u'id': id}) user_objs.append(context[u'user_obj']) except logic.NotFound: pass if not user_objs: log.info( u'User requested reset link for unknown user: {}'.format(id)) for user_obj in user_objs: log.info(u'Emailing reset link to user: {}'.format(user_obj.name)) try: # FIXME: How about passing user.id instead? Mailer already # uses model and it allow to simplify code above mailer.send_reset_link(user_obj) except mailer.MailerException as e: # SMTP is not configured correctly or the server is # temporarily unavailable h.flash_error( _(u'Error sending the email. Try again later ' 'or contact an administrator for help')) log.exception(e) return h.redirect_to(u'home.index') # always tell the user it succeeded, because otherwise we reveal # which accounts exist or not h.flash_success( _(u'A reset link has been emailed to you ' '(unless the account specified does not exist)')) return h.redirect_to(u'home.index')
def request_reset(self): context = { 'model': model, 'session': model.Session, 'user': c.user, 'auth_user_obj': c.userobj } data_dict = {'id': request.params.get('user')} try: check_access('request_reset', context) except NotAuthorized: abort(403, _('Unauthorized to request reset password.')) if request.method == 'POST': id = request.params.get('user') if id in (None, u''): h.flash_error(_(u'Email is required')) return h.redirect_to(u'/user/reset') context = {'model': model, 'user': c.user, u'ignore_auth': True} user_objs = [] if u'@' not in id: try: user_dict = get_action('user_show')(context, {'id': id}) user_objs.append(context['user_obj']) except NotFound: pass else: user_list = logic.get_action(u'get_data_user')(context, { u'email': id }) if user_list: # send reset emails for *all* user accounts with this email # (otherwise we'd have to silently fail - we can't tell the # user, as that would reveal the existence of accounts with # this email address) for user_dict in user_list: logic.get_action(u'user_show')(context, { u'id': user_dict[u'id'] }) user_objs.append(context[u'user_obj']) if not user_objs: log.info( u'User requested reset link for unknown user: {}'.format( id)) for user_obj in user_objs: log.info(u'Emailing reset link to user: {}'.format( user_obj.name)) try: mailer.send_reset_link(user_obj) except mailer.MailerException as e: h.flash_error( _(u'Error sending the email. Try again later ' 'or contact an administrator for help')) log.exception(e) return h.redirect_to(u'/') # always tell the user it succeeded, because otherwise we reveal # which accounts exist or not h.flash_success( _(u'A reset link has been emailed to you ' '(unless the account specified does not exist)')) return h.redirect_to(u'/') return render('user/request_reset.html')