def create_ldap(self, username, password, user_dn, attrs, cur_user=None): """ Checks if user is in database, if not creates this user marked as ldap user :param username: :param password: :param user_dn: :param attrs: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) from rhodecode.lib.auth import get_crypt_password log.debug('Checking for such ldap account in RhodeCode database') if self.get_by_username(username, case_insensitive=True) is None: # autogenerate email for container account without one generate_email = lambda usr: '******' % usr password = get_crypt_password(password) firstname = attrs['name'] lastname = attrs['lastname'] active = attrs.get('active', True) email = attrs['email'] or generate_email(username) from rhodecode.lib.hooks import log_create_user, check_allowed_create_user user_data = { 'username': username, 'password': password, 'email': email, 'firstname': firstname, 'lastname': lastname, 'active': attrs.get('active', True), 'admin': False } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) try: new_user = User() username = username.lower() # add ldap account always lowercase new_user.username = username new_user.password = password new_user.api_key = generate_api_key(username) new_user.email = email new_user.active = active new_user.ldap_dn = safe_unicode(user_dn) new_user.name = firstname new_user.lastname = lastname self.sa.add(new_user) log_create_user(new_user.get_dict(), cur_user) return new_user except (DatabaseError, ): log.error(traceback.format_exc()) self.sa.rollback() raise log.debug('this %s user exists skipping creation of ldap account', username) return None
def create(self, form_data, cur_user=None): if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) user_data = { 'username': form_data['username'], 'password': form_data['password'], 'email': form_data['email'], 'firstname': form_data['firstname'], 'lastname': form_data['lastname'], 'active': form_data['active'], 'extern_type': form_data['extern_type'], 'extern_name': form_data['extern_name'], 'admin': False, 'cur_user': cur_user } try: if form_data.get('create_repo_group'): user_data['create_repo_group'] = True if form_data.get('password_change'): user_data['force_password_change'] = True return UserModel().create_or_update(**user_data) except Exception: log.error(traceback.format_exc()) raise
def delete(self, user, cur_user=None): if not cur_user: cur_user = getattr(get_current_rhodecode_user(), "username", None) user = self._get_user(user) try: if user.username == "default": raise DefaultUserException( _(u"You can't remove this user since it's" " crucial for entire application") ) if user.repositories: repos = [x.repo_name for x in user.repositories] raise UserOwnsReposException( _( u'user "%s" still owns %s repositories and cannot be ' "removed. Switch owners or remove those repositories. %s" ) % (user.username, len(repos), ", ".join(repos)) ) self.sa.delete(user) from rhodecode.lib.hooks import log_delete_user log_delete_user(user.get_dict(), cur_user) except Exception: log.error(traceback.format_exc()) raise
def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): """ Action logger for various actions made by users :param user: user that made this action, can be a unique username string or object containing user_id attribute :param action: action to log, should be on of predefined unique actions for easy translations :param repo: string name of repository or object containing repo_id, that action was made on :param ipaddr: optional ip address from what the action was made :param sa: optional sqlalchemy session """ if not sa: sa = meta.Session() # if we don't get explicit IP address try to get one from registered user # in tmpl context var if not ipaddr: ipaddr = getattr(get_current_rhodecode_user(), 'ip_addr', '') try: if getattr(user, 'user_id', None): user_obj = User.get(user.user_id) elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: raise Exception('You have to provide a user object or a username') if getattr(repo, 'repo_id', None): repo_obj = Repository.get(repo.repo_id) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip('/') repo_obj = Repository.get_by_repo_name(repo_name) else: repo_obj = None repo_name = '' user_log = UserLog() user_log.user_id = user_obj.user_id user_log.username = user_obj.username action = safe_unicode(action) user_log.action = action[:1200000] user_log.repository = repo_obj user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) log.info('Logging action:`%s` on repo:`%s` by user:%s ip:%s', action, safe_unicode(repo), user_obj, ipaddr) if commit: sa.commit() except Exception: log.error(traceback.format_exc()) raise
def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): """ Action logger for various actions made by users :param user: user that made this action, can be a unique username string or object containing user_id attribute :param action: action to log, should be on of predefined unique actions for easy translations :param repo: string name of repository or object containing repo_id, that action was made on :param ipaddr: optional ip address from what the action was made :param sa: optional sqlalchemy session """ if not sa: sa = meta.Session() # if we don't get explicit IP address try to get one from registered user # in tmpl context var if not ipaddr: ipaddr = getattr(get_current_rhodecode_user(), 'ip_addr', '') try: if hasattr(user, 'user_id'): user_obj = User.get(user.user_id) elif isinstance(user, basestring): user_obj = User.get_by_username(user) else: raise Exception('You have to provide a user object or a username') if hasattr(repo, 'repo_id'): repo_obj = Repository.get(repo.repo_id) repo_name = repo_obj.repo_name elif isinstance(repo, basestring): repo_name = repo.lstrip('/') repo_obj = Repository.get_by_repo_name(repo_name) else: repo_obj = None repo_name = '' user_log = UserLog() user_log.user_id = user_obj.user_id user_log.username = user_obj.username user_log.action = safe_unicode(action) user_log.repository = repo_obj user_log.repository_name = repo_name user_log.action_date = datetime.datetime.now() user_log.user_ip = ipaddr sa.add(user_log) log.info('Logging action:%s on %s by user:%s ip:%s' % (action, safe_unicode(repo), user_obj, ipaddr)) if commit: sa.commit() except Exception: log.error(traceback.format_exc()) raise
def create_for_container_auth(self, username, attrs, cur_user=None): """ Creates the given user if it's not already in the database :param username: :param attrs: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) if self.get_by_username(username, case_insensitive=True) is None: # autogenerate email for container account without one generate_email = lambda usr: '******' % usr firstname = attrs['name'] lastname = attrs['lastname'] active = attrs.get('active', True) email = attrs['email'] or generate_email(username) from rhodecode.lib.hooks import log_create_user, check_allowed_create_user user_data = { 'username': username, 'password': None, 'email': email, 'firstname': firstname, 'lastname': lastname, 'active': attrs.get('active', True), 'admin': False } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) try: new_user = User() new_user.username = username new_user.password = None new_user.api_key = generate_api_key(username) new_user.email = email new_user.active = active new_user.name = firstname new_user.lastname = lastname self.sa.add(new_user) log_create_user(new_user.get_dict(), cur_user) return new_user except (DatabaseError, ): log.error(traceback.format_exc()) self.sa.rollback() raise log.debug( 'User %s already exists. Skipping creation of account' ' for container auth.', username) return None
def create_for_container_auth(self, username, attrs, cur_user=None): """ Creates the given user if it's not already in the database :param username: :param attrs: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), "username", None) if self.get_by_username(username, case_insensitive=True) is None: # autogenerate email for container account without one generate_email = lambda usr: "******" % usr firstname = attrs["name"] lastname = attrs["lastname"] active = attrs.get("active", True) email = attrs["email"] or generate_email(username) from rhodecode.lib.hooks import log_create_user, check_allowed_create_user user_data = { "username": username, "password": None, "email": email, "firstname": firstname, "lastname": lastname, "active": attrs.get("active", True), "admin": False, } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) try: new_user = User() new_user.username = username new_user.password = None new_user.api_key = generate_api_key(username) new_user.email = email new_user.active = active new_user.name = firstname new_user.lastname = lastname self.sa.add(new_user) log_create_user(new_user.get_dict(), cur_user) return new_user except (DatabaseError,): log.error(traceback.format_exc()) self.sa.rollback() raise log.debug("User %s already exists. Skipping creation of account" " for container auth.", username) return None
def _log_user_changes(self, action, user_group, user_or_users): users = user_or_users if not isinstance(users, (list, tuple)): users = [users] rhodecode_user = get_current_rhodecode_user() ipaddr = getattr(rhodecode_user, 'ip_addr', '') group_name = user_group.users_group_name for user_or_user_id in users: user = self._get_user(user_or_user_id) log_text = 'User {user} {action} {group}'.format( action=action, user=user.username, group=group_name) log.info('Logging action: {0} by {1} ip:{2}'.format( log_text, rhodecode_user, ipaddr))
def delete(self, user, cur_user=None, handle_repos=None, handle_repo_groups=None, handle_user_groups=None): if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) user = self._get_user(user) try: if user.username == User.DEFAULT_USER: raise DefaultUserException( _(u"You can't remove this user since it's" u" crucial for entire application")) left_overs = self._handle_user_repos( user.username, user.repositories, handle_repos) if left_overs and user.repositories: repos = [x.repo_name for x in user.repositories] raise UserOwnsReposException( _(u'user "%s" still owns %s repositories and cannot be ' u'removed. Switch owners or remove those repositories:%s') % (user.username, len(repos), ', '.join(repos))) left_overs = self._handle_user_repo_groups( user.username, user.repository_groups, handle_repo_groups) if left_overs and user.repository_groups: repo_groups = [x.group_name for x in user.repository_groups] raise UserOwnsRepoGroupsException( _(u'user "%s" still owns %s repository groups and cannot be ' u'removed. Switch owners or remove those repository groups:%s') % (user.username, len(repo_groups), ', '.join(repo_groups))) left_overs = self._handle_user_user_groups( user.username, user.user_groups, handle_user_groups) if left_overs and user.user_groups: user_groups = [x.users_group_name for x in user.user_groups] raise UserOwnsUserGroupsException( _(u'user "%s" still owns %s user groups and cannot be ' u'removed. Switch owners or remove those user groups:%s') % (user.username, len(user_groups), ', '.join(user_groups))) # we might change the user data with detach/delete, make sure # the object is marked as expired before actually deleting ! self.sa.expire(user) self.sa.delete(user) from rhodecode.lib.hooks_base import log_delete_user log_delete_user(deleted_by=cur_user, **user.get_dict()) except Exception: log.error(traceback.format_exc()) raise
def delete(self, repo, forks=None, fs_remove=True, cur_user=None): """ Delete given repository, forks parameter defines what do do with attached forks. Throws AttachedForksError if deleted repo has attached forks :param repo: :param forks: str 'delete' or 'detach' :param fs_remove: remove(archive) repo from filesystem """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) repo = self._get_repo(repo) if repo: if forks == 'detach': for r in repo.forks: r.fork = None self.sa.add(r) elif forks == 'delete': for r in repo.forks: self.delete(r, forks='delete') elif [f for f in repo.forks]: raise AttachedForksError() old_repo_dict = repo.get_dict() try: self.sa.delete(repo) if fs_remove: self._delete_filesystem_repo(repo) else: log.debug('skipping removal from filesystem') old_repo_dict.update({ 'deleted_by': cur_user, 'deleted_on': time.time(), }) log_delete_repository(**old_repo_dict) except Exception: log.error(traceback.format_exc()) raise
def create(self, form_data, cur_user=None): if not cur_user: cur_user = getattr(get_current_rhodecode_user(), "username", None) from rhodecode.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 rhodecode.lib.auth import get_crypt_password try: 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 except Exception: log.error(traceback.format_exc()) raise
def delete(self, user, cur_user=None): if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) user = self._get_user(user) try: if user.username == 'default': raise DefaultUserException( _(u"You can't remove this user since it's" " crucial for entire application")) if user.repositories: repos = [x.repo_name for x in user.repositories] raise UserOwnsReposException( _(u'user "%s" still owns %s repositories and cannot be ' 'removed. Switch owners or remove those repositories. %s' ) % (user.username, len(repos), ', '.join(repos))) self.sa.delete(user) from rhodecode.lib.hooks import log_delete_user log_delete_user(user.get_dict(), cur_user) except Exception: log.error(traceback.format_exc()) raise
def delete(self, repo, forks=None, fs_remove=True, cur_user=None): """ Delete given repository, forks parameter defines what do do with attached forks. Throws AttachedForksError if deleted repo has attached forks :param repo: :param forks: str 'delete' or 'detach' :param fs_remove: remove(archive) repo from filesystem """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) repo = self._get_repo(repo) if repo: if forks == 'detach': for r in repo.forks: r.fork = None self.sa.add(r) elif forks == 'delete': for r in repo.forks: self.delete(r, forks='delete') elif [f for f in repo.forks]: raise AttachedForksError() old_repo_dict = repo.get_dict() owner = repo.user try: self.sa.delete(repo) if fs_remove: self.__delete_repo(repo) else: log.debug('skipping removal from filesystem') log_delete_repository(old_repo_dict, deleted_by=cur_user) except Exception: log.error(traceback.format_exc()) raise
def create(self, form_data, cur_user=None): if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) from rhodecode.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 rhodecode.lib.auth import get_crypt_password try: 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 except Exception: log.error(traceback.format_exc()) raise
def get_accounts_in_creation_order(self, current_user=None): """ Get accounts in order of creation for deactivation for license limits pick currently logged in user, and append to the list in position 0 pick all super-admins in order of creation date and add it to the list pick all other accounts in order of creation and add it to the list. Based on that list, the last accounts can be disabled as they are created at the end and don't include any of the super admins as well as the current user. :param current_user: optionally current user running this operation """ if not current_user: current_user = get_current_rhodecode_user() active_super_admins = [ x.user_id for x in User.query() .filter(User.user_id != current_user.user_id) .filter(User.active == true()) .filter(User.admin == true()) .order_by(User.created_on.asc())] active_regular_users = [ x.user_id for x in User.query() .filter(User.user_id != current_user.user_id) .filter(User.active == true()) .filter(User.admin == false()) .order_by(User.created_on.asc())] list_of_accounts = [current_user.user_id] list_of_accounts += active_super_admins list_of_accounts += active_regular_users return list_of_accounts
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 create_or_update(self, username, password, email, firstname='', lastname='', active=True, admin=False, ldap_dn=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 ldap_dn: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), 'username', None) from rhodecode.lib.auth import get_crypt_password from rhodecode.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 RhodeCode 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 # set password only if creating an user or password is changed if not edit or user.password != password: new_user.password = get_crypt_password( password) if password else None 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 = firstname new_user.lastname = lastname 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 create_ldap(self, username, password, user_dn, attrs, cur_user=None): """ Checks if user is in database, if not creates this user marked as ldap user :param username: :param password: :param user_dn: :param attrs: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), "username", None) from rhodecode.lib.auth import get_crypt_password log.debug("Checking for such ldap account in RhodeCode database") if self.get_by_username(username, case_insensitive=True) is None: # autogenerate email for container account without one generate_email = lambda usr: "******" % usr password = get_crypt_password(password) firstname = attrs["name"] lastname = attrs["lastname"] active = attrs.get("active", True) email = attrs["email"] or generate_email(username) from rhodecode.lib.hooks import log_create_user, check_allowed_create_user user_data = { "username": username, "password": password, "email": email, "firstname": firstname, "lastname": lastname, "active": attrs.get("active", True), "admin": False, } # raises UserCreationError if it's not allowed check_allowed_create_user(user_data, cur_user) try: new_user = User() username = username.lower() # add ldap account always lowercase new_user.username = username new_user.password = password new_user.api_key = generate_api_key(username) new_user.email = email new_user.active = active new_user.ldap_dn = safe_unicode(user_dn) new_user.name = firstname new_user.lastname = lastname self.sa.add(new_user) log_create_user(new_user.get_dict(), cur_user) return new_user except (DatabaseError,): log.error(traceback.format_exc()) self.sa.rollback() raise log.debug("this %s user exists skipping creation of ldap account", username) return None
def create_or_update( self, username, password, email, firstname="", lastname="", active=True, admin=False, ldap_dn=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 ldap_dn: :param cur_user: """ if not cur_user: cur_user = getattr(get_current_rhodecode_user(), "username", None) from rhodecode.lib.auth import get_crypt_password from rhodecode.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 RhodeCode 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 # set password only if creating an user or password is changed if not edit or user.password != password: new_user.password = get_crypt_password(password) if password else None 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 = firstname new_user.lastname = lastname 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