def create(self, form_data, cur_user=None): if not cur_user: cur_user = getattr(get_current_authuser(), 'username', None) from kallithea.lib.hooks import log_create_user, \ check_allowed_create_user _fd = form_data user_data = { 'username': _fd['username'], 'password': _fd['password'], 'email': _fd['email'], 'firstname': _fd['firstname'], 'lastname': _fd['lastname'], 'active': _fd['active'], 'admin': False } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) from kallithea.lib.auth import get_crypt_password new_user = User() for k, v in form_data.items(): if k == 'password': v = get_crypt_password(v) if k == 'firstname': k = 'name' setattr(new_user, k, v) new_user.api_key = generate_api_key() Session().add(new_user) Session().flush() # make database assign new_user.user_id log_create_user(new_user.get_dict(), cur_user) return new_user
def create(self, form_data, cur_user=None): if not cur_user: cur_user = getattr(get_current_authuser(), 'username', None) from kallithea.lib.hooks import log_create_user, check_allowed_create_user _fd = form_data user_data = { 'username': _fd['username'], 'password': _fd['password'], 'email': _fd['email'], 'firstname': _fd['firstname'], 'lastname': _fd['lastname'], 'active': _fd['active'], 'admin': False } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) from kallithea.lib.auth import get_crypt_password new_user = User() for k, v in form_data.items(): if k == 'password': v = get_crypt_password(v) if k == 'firstname': k = 'name' setattr(new_user, k, v) new_user.api_key = generate_api_key(form_data['username']) self.sa.add(new_user) log_create_user(new_user.get_dict(), cur_user) return new_user
def test_forgot_password(self): response = self.app.get( url(controller='login', action='password_reset')) self.assertEqual(response.status, '200 OK') username = '******' password = '******' email = '*****@*****.**' name = 'passwd' lastname = 'reset' new = User() new.username = username new.password = password new.email = email new.name = name new.lastname = lastname new.api_key = generate_api_key(username) Session().add(new) Session().commit() response = self.app.post( url(controller='login', action='password_reset'), { 'email': email, }) self.checkSessionFlash(response, 'Your password reset link was sent') response = response.follow() # BAD KEY key = "bad" response = self.app.get( url(controller='login', action='password_reset_confirmation', key=key)) self.assertEqual(response.status, '302 Found') self.assertTrue(response.location.endswith(url('reset_password'))) # GOOD KEY key = User.get_by_username(username).api_key response = self.app.get( url(controller='login', action='password_reset_confirmation', key=key)) self.assertEqual(response.status, '302 Found') self.assertTrue(response.location.endswith(url('login_home'))) self.checkSessionFlash(response, ('Your password reset was successful, ' 'new password has been sent to your email')) response = response.follow()
def test_forgot_password(self): response = self.app.get(url(controller='login', action='password_reset')) self.assertEqual(response.status, '200 OK') username = '******' password = '******' email = '*****@*****.**' name = 'passwd' lastname = 'reset' new = User() new.username = username new.password = password new.email = email new.name = name new.lastname = lastname new.api_key = generate_api_key(username) Session().add(new) Session().commit() response = self.app.post(url(controller='login', action='password_reset'), {'email': email, }) self.checkSessionFlash(response, 'Your password reset link was sent') response = response.follow() # BAD KEY key = "bad" response = self.app.get(url(controller='login', action='password_reset_confirmation', key=key)) self.assertEqual(response.status, '302 Found') self.assertTrue(response.location.endswith(url('reset_password'))) # GOOD KEY key = User.get_by_username(username).api_key response = self.app.get(url(controller='login', action='password_reset_confirmation', key=key)) self.assertEqual(response.status, '302 Found') self.assertTrue(response.location.endswith(url('login_home'))) self.checkSessionFlash(response, ('Your password reset was successful, ' 'new password has been sent to your email')) response = response.follow()
def my_account_api_keys_delete(self): api_key = request.POST.get('del_api_key') if request.POST.get('del_api_key_builtin'): user = User.get(request.authuser.user_id) user.api_key = generate_api_key() Session().commit() h.flash(_("API key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, request.authuser.user_id) Session().commit() h.flash(_("API key successfully deleted"), category='success') raise HTTPFound(location=url('my_account_api_keys'))
def delete_api_key(self, id): c.user = self._get_user_or_raise_if_default(id) api_key = request.POST.get('del_api_key') if request.POST.get('del_api_key_builtin'): c.user.api_key = generate_api_key() Session().commit() h.flash(_("API key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, c.user.user_id) Session().commit() h.flash(_("API key successfully deleted"), category='success') raise HTTPFound(location=url('edit_user_api_keys', id=c.user.user_id))
def create(self, user, description, lifetime=-1): """ :param user: user or user_id :param description: description of ApiKey :param lifetime: expiration time in seconds """ user = self._get_user(user) new_api_key = UserApiKeys() new_api_key.api_key = generate_api_key(user.username) new_api_key.user_id = user.user_id new_api_key.description = description new_api_key.expires = time.time() + (lifetime * 60) if lifetime != -1 else -1 Session().add(new_api_key) return new_api_key
def my_account_api_keys_delete(self): api_key = request.POST.get('del_api_key') user_id = self.authuser.user_id if request.POST.get('del_api_key_builtin'): user = User.get(user_id) if user: user.api_key = generate_api_key(user.username) Session().add(user) Session().commit() h.flash(_("Api key successfully reset"), category='success') elif api_key: ApiKeyModel().delete(api_key, self.authuser.user_id) Session().commit() h.flash(_("Api key successfully deleted"), category='success') return redirect(url('my_account_api_keys'))
def create(cls, form_data): from kallithea.lib.auth import get_crypt_password try: new_user = cls() for k, v in form_data.items(): if k == 'password': v = get_crypt_password(v) setattr(new_user, k, v) new_user.api_key = generate_api_key(form_data['username']) Session.add(new_user) Session.commit() return new_user except: log.error(traceback.format_exc()) Session.rollback() raise
def create_or_update(self, username, password, email, firstname='', lastname='', active=True, admin=False, extern_type=None, extern_name=None, cur_user=None): """ Creates a new instance if not found, or updates current one :param username: :param password: :param email: :param active: :param firstname: :param lastname: :param active: :param admin: :param extern_name: :param extern_type: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_authuser(), 'username', None) from kallithea.lib.auth import get_crypt_password, check_password from kallithea.lib.hooks import log_create_user, \ check_allowed_create_user user_data = { 'username': username, 'password': password, 'email': email, 'firstname': firstname, 'lastname': lastname, 'active': active, 'admin': admin } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) log.debug('Checking for %s account in Kallithea database', username) user = User.get_by_username(username, case_insensitive=True) if user is None: log.debug('creating new user %s', username) new_user = User() edit = False else: log.debug('updating user %s', username) new_user = user edit = True try: new_user.username = username new_user.admin = admin new_user.email = email new_user.active = active new_user.extern_name = extern_name new_user.extern_type = extern_type new_user.name = firstname new_user.lastname = lastname if not edit: new_user.api_key = generate_api_key() # set password only if creating an user or password is changed password_change = new_user.password and \ not check_password(password, new_user.password) if not edit or password_change: reason = 'new password' if edit else 'new user' log.debug('Updating password reason=>%s', reason) new_user.password = get_crypt_password(password) \ if password else '' if user is None: Session().add(new_user) Session().flush() # make database assign new_user.user_id if not edit: log_create_user(new_user.get_dict(), cur_user) return new_user except (DatabaseError,): log.error(traceback.format_exc()) raise
def create_or_update(self, username, password, email, firstname='', lastname='', active=True, admin=False, extern_type=None, extern_name=None, cur_user=None): """ Creates a new instance if not found, or updates current one :param username: :param password: :param email: :param active: :param firstname: :param lastname: :param active: :param admin: :param extern_name: :param extern_type: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_authuser(), 'username', None) from kallithea.lib.auth import get_crypt_password, check_password from kallithea.lib.hooks import log_create_user, check_allowed_create_user user_data = { 'username': username, 'password': password, 'email': email, 'firstname': firstname, 'lastname': lastname, 'active': active, 'admin': admin } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) log.debug('Checking for %s account in Kallithea database' % username) user = User.get_by_username(username, case_insensitive=True) if user is None: log.debug('creating new user %s' % username) new_user = User() edit = False else: log.debug('updating user %s' % username) new_user = user edit = True try: new_user.username = username new_user.admin = admin new_user.email = email new_user.active = active new_user.extern_name = safe_unicode(extern_name) if extern_name else None new_user.extern_type = safe_unicode(extern_type) if extern_type else None new_user.name = firstname new_user.lastname = lastname if not edit: new_user.api_key = generate_api_key(username) # set password only if creating an user or password is changed password_change = new_user.password and not check_password(password, new_user.password) if not edit or password_change: reason = 'new password' if edit else 'new user' log.debug('Updating password reason=>%s' % (reason,)) new_user.password = get_crypt_password(password) if password else None self.sa.add(new_user) if not edit: log_create_user(new_user.get_dict(), cur_user) return new_user except (DatabaseError,): log.error(traceback.format_exc()) raise
def test_forgot_password(self): response = self.app.get(base.url(controller='login', action='password_reset')) assert response.status == '200 OK' username = '******' password = '******' email = '*****@*****.**' name = 'passwd' lastname = 'reset' timestamp = int(time.time()) new = User() new.username = username new.password = password new.email = email new.name = name new.lastname = lastname new.api_key = generate_api_key() Session().add(new) Session().commit() token = UserModel().get_reset_password_token( User.get_by_username(username), timestamp, self.session_csrf_secret_token()) collected = [] def mock_send_email(recipients, subject, body='', html_body='', headers=None, from_name=None): collected.append((recipients, subject, body, html_body)) with mock.patch.object(kallithea.lib.celerylib.tasks, 'send_email', mock_send_email), \ mock.patch.object(time, 'time', lambda: timestamp): response = self.app.post(base.url(controller='login', action='password_reset'), {'email': email, '_session_csrf_secret_token': self.session_csrf_secret_token()}) self.checkSessionFlash(response, 'A password reset confirmation code has been sent') ((recipients, subject, body, html_body),) = collected assert recipients == ['*****@*****.**'] assert subject == 'Password reset link' assert '\n%s\n' % token in body (confirmation_url,) = (line for line in body.splitlines() if line.startswith('http://')) assert ' href="%s"' % confirmation_url.replace('&', '&').replace('@', '%40') in html_body d = urllib.parse.parse_qs(urllib.parse.urlparse(confirmation_url).query) assert d['token'] == [token] assert d['timestamp'] == [str(timestamp)] assert d['email'] == [email] response = response.follow() # BAD TOKEN bad_token = "bad" response = self.app.post(base.url(controller='login', action='password_reset_confirmation'), {'email': email, 'timestamp': timestamp, 'password': "******", 'password_confirm': "p@ssw0rd", 'token': bad_token, '_session_csrf_secret_token': self.session_csrf_secret_token(), }) assert response.status == '200 OK' response.mustcontain('Invalid password reset token') # GOOD TOKEN response = self.app.get(confirmation_url) assert response.status == '200 OK' response.mustcontain("You are about to set a new password for the email address %s" % email) response.mustcontain('<form action="%s" method="post">' % base.url(controller='login', action='password_reset_confirmation')) response.mustcontain('value="%s"' % self.session_csrf_secret_token()) response.mustcontain('value="%s"' % token) response.mustcontain('value="%s"' % timestamp) response.mustcontain('value="*****@*****.**"') # fake a submit of that form response = self.app.post(base.url(controller='login', action='password_reset_confirmation'), {'email': email, 'timestamp': timestamp, 'password': "******", 'password_confirm': "p@ssw0rd", 'token': token, '_session_csrf_secret_token': self.session_csrf_secret_token(), }) assert response.status == '302 Found' self.checkSessionFlash(response, 'Successfully updated password') response = response.follow()
def test_forgot_password(self): response = self.app.get(url(controller='login', action='password_reset')) self.assertEqual(response.status, '200 OK') username = '******' password = '******' email = '*****@*****.**' name = u'passwd' lastname = u'reset' timestamp = int(time.time()) new = User() new.username = username new.password = password new.email = email new.name = name new.lastname = lastname new.api_key = generate_api_key() Session().add(new) Session().commit() response = self.app.post(url(controller='login', action='password_reset'), {'email': email, }) self.checkSessionFlash(response, 'A password reset confirmation code has been sent') response = response.follow() # BAD TOKEN token = "bad" response = self.app.post(url(controller='login', action='password_reset_confirmation'), {'email': email, 'timestamp': timestamp, 'password': "******", 'password_confirm': "p@ssw0rd", 'token': token, }) self.assertEqual(response.status, '200 OK') response.mustcontain('Invalid password reset token') # GOOD TOKEN # TODO: The token should ideally be taken from the mail sent # above, instead of being recalculated. token = UserModel().get_reset_password_token( User.get_by_username(username), timestamp, self.authentication_token()) response = self.app.get(url(controller='login', action='password_reset_confirmation', email=email, timestamp=timestamp, token=token)) self.assertEqual(response.status, '200 OK') response.mustcontain("You are about to set a new password for the email address %s" % email) response = self.app.post(url(controller='login', action='password_reset_confirmation'), {'email': email, 'timestamp': timestamp, 'password': "******", 'password_confirm': "p@ssw0rd", 'token': token, }) self.assertEqual(response.status, '302 Found') self.checkSessionFlash(response, 'Successfully updated password') response = response.follow()
def test_forgot_password(self): response = self.app.get( url(controller='login', action='password_reset')) assert response.status == '200 OK' username = '******' password = '******' email = '*****@*****.**' name = u'passwd' lastname = u'reset' timestamp = int(time.time()) new = User() new.username = username new.password = password new.email = email new.name = name new.lastname = lastname new.api_key = generate_api_key() Session().add(new) Session().commit() response = self.app.post( url(controller='login', action='password_reset'), { 'email': email, }) self.checkSessionFlash( response, 'A password reset confirmation code has been sent') response = response.follow() # BAD TOKEN token = "bad" response = self.app.post( url(controller='login', action='password_reset_confirmation'), { 'email': email, 'timestamp': timestamp, 'password': "******", 'password_confirm': "p@ssw0rd", 'token': token, }) assert response.status == '200 OK' response.mustcontain('Invalid password reset token') # GOOD TOKEN # TODO: The token should ideally be taken from the mail sent # above, instead of being recalculated. token = UserModel().get_reset_password_token( User.get_by_username(username), timestamp, self.authentication_token()) response = self.app.get( url(controller='login', action='password_reset_confirmation', email=email, timestamp=timestamp, token=token)) assert response.status == '200 OK' response.mustcontain( "You are about to set a new password for the email address %s" % email) response = self.app.post( url(controller='login', action='password_reset_confirmation'), { 'email': email, 'timestamp': timestamp, 'password': "******", 'password_confirm': "p@ssw0rd", 'token': token, }) assert response.status == '302 Found' self.checkSessionFlash(response, 'Successfully updated password') response = response.follow()