def create(self, user, description, lifetime=-1, role=UserApiKeys.ROLE_ALL): """ :param user: user or user_id :param description: description of ApiKey :param lifetime: expiration time in seconds :param role: role for the apikey """ from rhodecode.lib.auth import generate_auth_token user = self._get_user(user) new_auth_token = UserApiKeys() new_auth_token.api_key = generate_auth_token(user.username) new_auth_token.user_id = user.user_id new_auth_token.description = description new_auth_token.role = role new_auth_token.expires = time.time() + (lifetime * 60) if lifetime != -1 else -1 Session().add(new_auth_token) return new_auth_token
def test_salt_is_geneated_when_not_specified(self): user_name = 'test_user' random_salt = os.urandom(16) with patch.object(auth, 'os') as os_mock: os_mock.urandom.return_value = random_salt result = auth.generate_auth_token(user_name) expected_result = sha1(user_name + random_salt).hexdigest() assert result == expected_result
def test_forgot_password(self): response = self.app.get(pwd_reset_url) assert 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_auth_token(username) Session().add(new) Session().commit() response = self.app.post(pwd_reset_url, { 'email': email, }) assert_session_flash(response, 'Your password reset link was sent') response = response.follow() # BAD KEY key = "bad" confirm_url = '{}?key={}'.format(pwd_reset_confirm_url, key) response = self.app.get(confirm_url) assert response.status == '302 Found' assert response.location.endswith(pwd_reset_url) # GOOD KEY key = User.get_by_username(username).api_key confirm_url = '{}?key={}'.format(pwd_reset_confirm_url, key) response = self.app.get(confirm_url) assert response.status == '302 Found' assert response.location.endswith(login_url) assert_session_flash( response, 'Your password reset was successful, ' 'a new password has been sent to your email') response = response.follow()
def my_account_auth_tokens_delete(self): auth_token = request.POST.get('del_auth_token') user_id = c.rhodecode_user.user_id if request.POST.get('del_auth_token_builtin'): user = User.get(user_id) if user: user.api_key = generate_auth_token(user.username) Session().add(user) Session().commit() h.flash(_("Auth token successfully reset"), category='success') elif auth_token: AuthTokenModel().delete(auth_token, c.rhodecode_user.user_id) Session().commit() h.flash(_("Auth token successfully deleted"), category='success') return redirect(url('my_account_auth_tokens'))
def create(cls, form_data): from rhodecode.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_auth_token(form_data['username']) Session.add(new_user) Session.commit() return new_user except: log.error(traceback.format_exc()) Session.rollback() raise
def delete_auth_token(self, user_id): user_id = safe_int(user_id) c.user = User.get_or_404(user_id) if c.user.username == User.DEFAULT_USER: h.flash(_("You can't edit this user"), category='warning') return redirect(url('users')) auth_token = request.POST.get('del_auth_token') if request.POST.get('del_auth_token_builtin'): user = User.get(c.user.user_id) if user: user.api_key = generate_auth_token(user.username) Session().add(user) Session().commit() h.flash(_("Auth token successfully reset"), category='success') elif auth_token: AuthTokenModel().delete(auth_token, c.user.user_id) Session().commit() h.flash(_("Auth token successfully deleted"), category='success') return redirect(url('edit_user_auth_tokens', user_id=c.user.user_id))
def create_or_update( self, username, password, email, firstname='', lastname='', active=True, admin=False, extern_type=None, extern_name=None, cur_user=None, plugin=None, force_password_change=False, allow_to_create_user=True, create_repo_group=False, updating_user_id=None, language=None, strict_creation_check=True): """ Creates a new instance if not found, or updates current one :param username: :param password: :param email: :param firstname: :param lastname: :param active: :param admin: :param extern_type: :param extern_name: :param cur_user: :param plugin: optional plugin this method was called from :param force_password_change: toggles new or existing user flag for password change :param allow_to_create_user: Defines if the method can actually create new users :param create_repo_group: Defines if the method should also create an repo group with user name, and owner :param updating_user_id: if we set it up this is the user we want to update this allows to editing username. :param language: language of user from interface. :returns: new User object with injected `is_new_user` attribute. """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) from rhodecode.lib.auth import ( get_crypt_password, check_password, generate_auth_token) from rhodecode.lib.hooks_base import ( log_create_user, check_allowed_create_user) def _password_change(new_user, password): # empty password if not new_user.password: return False # password check is only needed for RhodeCode internal auth calls # in case it's a plugin we don't care if not plugin: # first check if we gave crypted password back, and if it matches # it's not password change if new_user.password == password: return False password_match = check_password(password, new_user.password) if not password_match: return True return False user_data = { 'username': username, 'password': password, 'email': email, 'firstname': firstname, 'lastname': lastname, 'active': active, 'admin': admin } if updating_user_id: log.debug('Checking for existing account in RhodeCode ' 'database with user_id `%s` ' % (updating_user_id,)) user = User.get(updating_user_id) else: log.debug('Checking for existing account in RhodeCode ' 'database with username `%s` ' % (username,)) user = User.get_by_username(username, case_insensitive=True) if user is None: # we check internal flag if this method is actually allowed to # create new user if not allow_to_create_user: msg = ('Method wants to create new user, but it is not ' 'allowed to do so') log.warning(msg) raise NotAllowedToCreateUserError(msg) log.debug('Creating new user %s', username) # only if we create user that is active new_active_user = active if new_active_user and strict_creation_check: # raises UserCreationError if it's not allowed for any reason to # create new active user, this also executes pre-create hooks check_allowed_create_user(user_data, cur_user, strict_check=True) self.send_event(UserPreCreate(user_data)) new_user = User() edit = False else: log.debug('updating user %s', username) self.send_event(UserPreUpdate(user, user_data)) new_user = user edit = True # we're not allowed to edit default user if user.username == User.DEFAULT_USER: raise DefaultUserException( _("You can't edit this user (`%(username)s`) since it's " "crucial for entire application") % {'username': user.username}) # inject special attribute that will tell us if User is new or old new_user.is_new_user = not edit # for users that didn's specify auth type, we use RhodeCode built in from rhodecode.authentication.plugins import auth_rhodecode extern_name = extern_name or auth_rhodecode.RhodeCodeAuthPlugin.name extern_type = extern_type or auth_rhodecode.RhodeCodeAuthPlugin.name 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) new_user.extern_type = safe_unicode(extern_type) new_user.name = firstname new_user.lastname = lastname if not edit: new_user.api_key = generate_auth_token(username) # set password only if creating an user or password is changed if not edit or _password_change(new_user, password): 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 if force_password_change: new_user.update_userdata(force_password_change=True) if language: new_user.update_userdata(language=language) self.sa.add(new_user) if not edit and create_repo_group: # create new group same as username, and make this user an owner desc = RepoGroupModel.PERSONAL_GROUP_DESC % {'username': username} RepoGroupModel().create(group_name=username, group_description=desc, owner=username, commit_early=False) if not edit: # add the RSS token AuthTokenModel().create(username, description='Generated feed token', role=AuthTokenModel.cls.ROLE_FEED) log_create_user(created_by=cur_user, **new_user.get_dict()) return new_user except (DatabaseError,): log.error(traceback.format_exc()) raise
def test_salt_is_used_when_specified(self): salt = 'abcde' user_name = 'test_user' result = auth.generate_auth_token(user_name, salt) expected_result = sha1(user_name + salt).hexdigest() assert result == expected_result