def grant_user_permission(self, user_group, user, perm): """ Grant permission for user on given user group, or update existing one if found :param user_group: Instance of UserGroup, users_group_id, or users_group_name :param user: Instance of User, user_id or username :param perm: Instance of Permission, or permission_name """ user_group = UserGroup.guess_instance(user_group) user = User.guess_instance(user) permission = Permission.guess_instance(perm) # check if we have that permission already obj = UserUserGroupToPerm.query() \ .filter(UserUserGroupToPerm.user == user) \ .filter(UserUserGroupToPerm.user_group == user_group) \ .scalar() if obj is None: # create new ! obj = UserUserGroupToPerm() Session().add(obj) obj.user_group = user_group obj.user = user obj.permission = permission log.debug('Granted perm %s to %s on %s', perm, user, user_group) return obj
def commit_change(self, repo, repo_name, cs, user, ip_addr, author, message, content, f_path): """ Commit a change to a single file :param repo: a db_repo.scm_instance """ user = User.guess_instance(user) IMC = self._get_IMC_module(repo.alias) imc = IMC(repo) imc.change(FileNode(f_path, content, mode=cs.get_file_mode(f_path))) try: tip = imc.commit(message=message, author=author, parents=[cs], branch=cs.branch) except Exception as e: log.error(traceback.format_exc()) # clear caches - we also want a fresh object if commit fails self.mark_for_invalidation(repo_name) raise IMCCommitError(str(e)) self._handle_push(repo, username=user.username, ip_addr=ip_addr, action='push_local', repo_name=repo_name, revisions=[tip.raw_id]) return tip
def enforce_groups(self, user, groups, extern_type=None): user = User.guess_instance(user) log.debug('Enforcing groups %s on user %s', user, groups) current_groups = user.group_member # find the external created groups externals = [ x.users_group for x in current_groups if 'extern_type' in x.users_group.group_data ] # calculate from what groups user should be removed # externals that are not in groups for gr in externals: if gr.users_group_name not in groups: log.debug('Removing user %s from user group %s', user, gr) self.remove_user_from_group(gr, user) # now we calculate in which groups user should be == groups params owner = User.get_first_admin().username for gr in set(groups): existing_group = UserGroup.get_by_group_name(gr) if not existing_group: desc = u'Automatically created from plugin:%s' % extern_type # we use first admin account to set the owner of the group existing_group = UserGroupModel().create( gr, desc, owner, group_data={'extern_type': extern_type}) # we can only add users to special groups created via plugins managed = 'extern_type' in existing_group.group_data if managed: log.debug('Adding user %s to user group %s', user, gr) UserGroupModel().add_user_to_group(existing_group, user) else: log.debug('Skipping addition to group %s since it is ' 'not managed by auth plugins' % gr)
def get_user_notification(self, user, notification): user = User.guess_instance(user) notification = Notification.guess_instance(notification) return UserNotification.query() \ .filter(UserNotification.notification == notification) \ .filter(UserNotification.user == user).scalar()
def grant_user_permission(self, repo, user, perm): """ Grant permission for user on given repository, or update existing one if found :param repo: Instance of Repository, repository_id, or repository name :param user: Instance of User, user_id or username :param perm: Instance of Permission, or permission_name """ user = User.guess_instance(user) repo = Repository.guess_instance(repo) permission = Permission.guess_instance(perm) # check if we have that permission already obj = UserRepoToPerm.query() \ .filter(UserRepoToPerm.user == user) \ .filter(UserRepoToPerm.repository == repo) \ .scalar() if obj is None: # create new ! obj = UserRepoToPerm() Session().add(obj) obj.repository = repo obj.user = user obj.permission = permission log.debug('Granted perm %s to %s on %s', perm, user, repo) return obj
def delete(self, user, cur_user=None): if cur_user is None: cur_user = getattr(get_current_authuser(), 'username', None) user = User.guess_instance(user) if user.is_default_user: raise DefaultUserException( _("You can't remove this user since it is" " crucial for the entire application")) if user.repositories: repos = [x.repo_name for x in user.repositories] raise UserOwnsReposException( _('User "%s" still owns %s repositories and cannot be ' 'removed. Switch owners or remove those repositories: %s') % (user.username, len(repos), ', '.join(repos))) if user.repo_groups: repogroups = [x.group_name for x in user.repo_groups] raise UserOwnsReposException(_( 'User "%s" still owns %s repository groups and cannot be ' 'removed. Switch owners or remove those repository groups: %s') % (user.username, len(repogroups), ', '.join(repogroups))) if user.user_groups: usergroups = [x.users_group_name for x in user.user_groups] raise UserOwnsReposException( _('User "%s" still owns %s user groups and cannot be ' 'removed. Switch owners or remove those user groups: %s') % (user.username, len(usergroups), ', '.join(usergroups))) Session().delete(user) from kallithea.lib.hooks import log_delete_user log_delete_user(user.get_dict(), cur_user)
def get_api_keys(self, user, show_expired=True): user = User.guess_instance(user) user_api_keys = UserApiKeys.query() \ .filter(UserApiKeys.user_id == user.user_id) if not show_expired: user_api_keys = user_api_keys.filter_by(is_expired=False) return user_api_keys
def enforce_groups(self, user, groups, extern_type=None): user = User.guess_instance(user) log.debug('Enforcing groups %s on user %s', user, groups) current_groups = user.group_member # find the external created groups externals = [x.users_group for x in current_groups if 'extern_type' in x.users_group.group_data] # calculate from what groups user should be removed # externals that are not in groups for gr in externals: if gr.users_group_name not in groups: log.debug('Removing user %s from user group %s', user, gr) self.remove_user_from_group(gr, user) # now we calculate in which groups user should be == groups params owner = User.get_first_admin().username for gr in set(groups): existing_group = UserGroup.get_by_group_name(gr) if not existing_group: desc = u'Automatically created from plugin:%s' % extern_type # we use first admin account to set the owner of the group existing_group = UserGroupModel().create(gr, desc, owner, group_data={'extern_type': extern_type}) # we can only add users to special groups created via plugins managed = 'extern_type' in existing_group.group_data if managed: log.debug('Adding user %s to user group %s', user, gr) UserGroupModel().add_user_to_group(existing_group, user) else: log.debug('Skipping addition to group %s since it is ' 'not managed by auth plugins' % gr)
def create(self, user, description, public_key): """ :param user: user or user_id :param description: description of SshKey :param publickey: public key text Will raise SshKeyModelException on errors """ try: keytype, _pub, comment = ssh.parse_pub_key(public_key) except ssh.SshKeyParseError as e: raise SshKeyModelException(_('SSH key %r is invalid: %s') % (public_key, e.args[0])) if not description.strip(): description = comment.strip() user = User.guess_instance(user) new_ssh_key = UserSshKeys() new_ssh_key.user_id = user.user_id new_ssh_key.description = description new_ssh_key.public_key = public_key for ssh_key in UserSshKeys.query().filter(UserSshKeys.fingerprint == new_ssh_key.fingerprint).all(): raise SshKeyModelException(_('SSH key %s is already used by %s') % (new_ssh_key.fingerprint, ssh_key.user.username)) Session().add(new_ssh_key) return new_ssh_key
def set_status(self, repo, status, user, comment, revision=None, pull_request=None, dont_allow_on_closed_pull_request=False): """ Creates new status for changeset or updates the old ones bumping their version, leaving the current status at the value of 'status'. :param repo: :param status: :param user: :param comment: :param revision: :param pull_request: :param dont_allow_on_closed_pull_request: don't allow a status change if last status was for pull request and it's closed. We shouldn't mess around this manually """ repo = Repository.guess_instance(repo) q = ChangesetStatus.query() if revision is not None: assert pull_request is None q = q.filter(ChangesetStatus.repo == repo) q = q.filter(ChangesetStatus.revision == revision) revisions = [revision] else: assert pull_request is not None pull_request = PullRequest.guess_instance(pull_request) repo = pull_request.org_repo q = q.filter(ChangesetStatus.repo == repo) q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions)) revisions = pull_request.revisions cur_statuses = q.all() #if statuses exists and last is associated with a closed pull request # we need to check if we can allow this status change if (dont_allow_on_closed_pull_request and cur_statuses and getattr(cur_statuses[0].pull_request, 'status', '') == PullRequest.STATUS_CLOSED): raise StatusChangeOnClosedPullRequestError( 'Changing status on closed pull request is not allowed' ) #update all current statuses with older version for st in cur_statuses: st.version += 1 new_statuses = [] for rev in revisions: new_status = ChangesetStatus() new_status.version = 0 # default new_status.author = User.guess_instance(user) new_status.repo = Repository.guess_instance(repo) new_status.status = status new_status.comment = comment new_status.revision = rev new_status.pull_request = pull_request new_statuses.append(new_status) Session().add(new_status) return new_statuses
def get_user_permission(self, repository, user): repository = Repository.guess_instance(repository) user = User.guess_instance(user) return UserRepoToPerm.query() \ .filter(UserRepoToPerm.user == user) \ .filter(UserRepoToPerm.repository == repository) \ .scalar()
def delete_extra_ip(self, user, ip_id): """ Removes IP address from UserIpMap :param user: :param ip_id: """ user = User.guess_instance(user) obj = UserIpMap.query().get(ip_id) if obj: Session().delete(obj)
def delete_extra_email(self, user, email_id): """ Removes email address from UserEmailMap :param user: :param email_id: """ user = User.guess_instance(user) obj = UserEmailMap.query().get(email_id) if obj is not None: Session().delete(obj)
def set_status(self, repo, status, user, comment, revision=None, pull_request=None): """ Creates new status for changeset or updates the old ones bumping their version, leaving the current status at the value of 'status'. :param repo: :param status: :param user: :param comment: :param revision: :param pull_request: """ repo = Repository.guess_instance(repo) q = ChangesetStatus.query() if revision is not None: assert pull_request is None q = q.filter(ChangesetStatus.repo == repo) q = q.filter(ChangesetStatus.revision == revision) revisions = [revision] else: assert pull_request is not None pull_request = PullRequest.guess_instance(pull_request) repo = pull_request.org_repo q = q.filter(ChangesetStatus.repo == repo) q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions)) revisions = pull_request.revisions cur_statuses = q.all() # update all current statuses with older version for st in cur_statuses: st.version += 1 new_statuses = [] for rev in revisions: new_status = ChangesetStatus() new_status.version = 0 # default new_status.author = User.guess_instance(user) new_status.repo = Repository.guess_instance(repo) new_status.status = status new_status.comment = comment new_status.revision = rev new_status.pull_request = pull_request new_statuses.append(new_status) Session().add(new_status) return new_statuses
def delete(self, api_key, user=None): """ Deletes given api_key, if user is set it also filters the object for deletion by given user. """ api_key = UserApiKeys.query().filter(UserApiKeys.api_key == api_key) if user is not None: user = User.guess_instance(user) api_key = api_key.filter(UserApiKeys.user_id == user.user_id) api_key = api_key.scalar() Session().delete(api_key)
def get_all_user_repos(self, user): """ Gets all repositories that user have at least read access :param user: """ from kallithea.lib.auth import AuthUser user = User.guess_instance(user) repos = AuthUser(dbuser=user).permissions['repositories'] access_check = lambda r: r[ 1] in ['repository.read', 'repository.write', 'repository.admin'] repos = [x[0] for x in filter(access_check, repos.items())] return Repository.query().filter(Repository.repo_name.in_(repos))
def mark_all_read_for_user(self, user, filter_=None): user = User.guess_instance(user) q = UserNotification.query() \ .filter(UserNotification.user == user) \ .filter(UserNotification.read == False) \ .join((Notification, UserNotification.notification_id == Notification.notification_id)) if filter_: q = q.filter(Notification.type_.in_(filter_)) # this is a little inefficient but sqlalchemy doesn't support # update on joined tables :( for obj in q: obj.read = True
def get_all_user_repos(self, user): """ Gets all repositories that user have at least read access :param user: """ from kallithea.lib.auth import AuthUser user = User.guess_instance(user) repos = AuthUser(dbuser=user).permissions['repositories'] access_check = lambda r: r[1] in ['repository.read', 'repository.write', 'repository.admin'] repos = [x[0] for x in filter(access_check, repos.items())] return Repository.query().filter(Repository.repo_name.in_(repos))
def revoke_perm(self, user, perm): """ Revoke users global permissions :param user: :param perm: """ user = User.guess_instance(user) perm = Permission.guess_instance(perm) UserToPerm.query().filter( UserToPerm.user == user, UserToPerm.permission == perm, ).delete()
def delete(self, fingerprint, user): """ Deletes ssh key with given fingerprint for the given user. Will raise SshKeyModelException on errors """ ssh_key = UserSshKeys.query().filter(UserSshKeys.fingerprint == fingerprint) user = User.guess_instance(user) ssh_key = ssh_key.filter(UserSshKeys.user_id == user.user_id) ssh_key = ssh_key.scalar() if ssh_key is None: raise SshKeyModelException(_('SSH key with fingerprint %r found') % fingerprint) Session().delete(ssh_key)
def get_all_user_repos(self, user): """ Gets all repositories that user have at least read access :param user: """ from kallithea.lib.auth import AuthUser auth_user = AuthUser(dbuser=User.guess_instance(user)) repos = [ repo_name for repo_name, perm in auth_user.permissions['repositories'].items() if perm in ['repository.read', 'repository.write', 'repository.admin'] ] return Repository.query().filter(Repository.repo_name.in_(repos))
def create(self, group_name, group_description, owner, parent=None, just_db=False, copy_permissions=False): try: owner = User.guess_instance(owner) parent_group = RepoGroup.guess_instance(parent) new_repo_group = RepoGroup() new_repo_group.owner = owner new_repo_group.group_description = group_description or group_name new_repo_group.parent_group = parent_group new_repo_group.group_name = new_repo_group.get_new_name(group_name) Session().add(new_repo_group) # create an ADMIN permission for owner except if we're super admin, # later owner should go into the owner field of groups if not owner.is_admin: self.grant_user_permission(repo_group=new_repo_group, user=owner, perm='group.admin') if parent_group and copy_permissions: # copy permissions from parent user_perms = UserRepoGroupToPerm.query() \ .filter(UserRepoGroupToPerm.group == parent_group).all() group_perms = UserGroupRepoGroupToPerm.query() \ .filter(UserGroupRepoGroupToPerm.group == parent_group).all() for perm in user_perms: # don't copy over the permission for user who is creating # this group, if he is not super admin he get's admin # permission set above if perm.user != owner or owner.is_admin: UserRepoGroupToPerm.create(perm.user, new_repo_group, perm.permission) for perm in group_perms: UserGroupRepoGroupToPerm.create(perm.users_group, new_repo_group, perm.permission) else: self._create_default_perms(new_repo_group) if not just_db: # we need to flush here, in order to check if database won't # throw any exceptions, create filesystem dirs at the very end Session().flush() self._create_group(new_repo_group.group_name) return new_repo_group except Exception: log.error(traceback.format_exc()) raise
def mark_read(self, user, notification): try: notification = Notification.guess_instance(notification) user = User.guess_instance(user) if notification and user: obj = UserNotification.query() \ .filter(UserNotification.user == user) \ .filter(UserNotification.notification == notification) \ .one() obj.read = True return True except Exception: log.error(traceback.format_exc()) raise
def delete(self, user, notification): # we don't want to remove actual notification just the assignment try: notification = Notification.guess_instance(notification) user = User.guess_instance(user) if notification and user: obj = UserNotification.query() \ .filter(UserNotification.user == user) \ .filter(UserNotification.notification == notification) \ .one() Session().delete(obj) return True except Exception: log.error(traceback.format_exc()) raise
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 = User.guess_instance(user) new_api_key = UserApiKeys() new_api_key.api_key = generate_api_key() 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 update_user(self, user, **kwargs): from kallithea.lib.auth import get_crypt_password user = User.guess_instance(user) if user.is_default_user: raise DefaultUserException( _("You can't edit this user since it's" " crucial for entire application") ) for k, v in kwargs.items(): if k == 'password' and v: v = get_crypt_password(v) setattr(user, k, v) return user
def add_extra_email(self, user, email): """ Adds email address to UserEmailMap :param user: :param email: """ from kallithea.model import forms form = forms.UserExtraEmailForm()() data = form.to_python(dict(email=email)) user = User.guess_instance(user) obj = UserEmailMap() obj.user = user obj.email = data['email'] Session().add(obj) return obj
def add_extra_ip(self, user, ip): """ Adds IP address to UserIpMap :param user: :param ip: """ from kallithea.model import forms form = forms.UserExtraIpForm()() data = form.to_python(dict(ip=ip)) user = User.guess_instance(user) obj = UserIpMap() obj.user = user obj.ip_addr = data['ip'] Session().add(obj) return obj
def _set_perm_user(obj, user, perm): if isinstance(obj, RepoGroup): self.grant_user_permission(repo_group=obj, user=user, perm=perm) elif isinstance(obj, Repository): user = User.guess_instance(user) # private repos will not allow to change the default permissions # using recursive mode if obj.private and user.is_default_user: return # we set group permission but we have to switch to repo # permission perm = perm.replace('group.', 'repository.') RepoModel().grant_user_permission( repo=obj, user=user, perm=perm )
def revoke_user_permission(self, repo, user): """ Revoke permission for user on given repository :param repo: Instance of Repository, repository_id, or repository name :param user: Instance of User, user_id or username """ user = User.guess_instance(user) repo = Repository.guess_instance(repo) obj = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository == repo) \ .filter(UserRepoToPerm.user == user) \ .scalar() if obj is not None: Session().delete(obj) log.debug('Revoked perm on %s on %s', repo, user)
def revoke_user_permission(self, repo_group, user): """ Revoke permission for user on given repository group :param repo_group: Instance of RepoGroup, repositories_group_id, or repositories_group name :param user: Instance of User, user_id or username """ repo_group = RepoGroup.guess_instance(repo_group) user = User.guess_instance(user) obj = UserRepoGroupToPerm.query() \ .filter(UserRepoGroupToPerm.user == user) \ .filter(UserRepoGroupToPerm.group == repo_group) \ .scalar() if obj is not None: Session().delete(obj) log.debug('Revoked perm on %s on %s', repo_group, user)
def create(self, name, description, owner, active=True, group_data=None): try: new_user_group = UserGroup() new_user_group.owner = User.guess_instance(owner) new_user_group.users_group_name = name new_user_group.user_group_description = description new_user_group.users_group_active = active if group_data: new_user_group.group_data = group_data Session().add(new_user_group) self._create_default_perms(new_user_group) self.grant_user_permission(user_group=new_user_group, user=owner, perm='usergroup.admin') return new_user_group except Exception: log.error(traceback.format_exc()) raise
def revoke_user_permission(self, user_group, user): """ Revoke permission for user on given repository group :param user_group: Instance of RepoGroup, repositories_group_id, or repositories_group name :param user: Instance of User, user_id or username """ user_group = UserGroup.guess_instance(user_group) user = User.guess_instance(user) obj = UserUserGroupToPerm.query() \ .filter(UserUserGroupToPerm.user == user) \ .filter(UserUserGroupToPerm.user_group == user_group) \ .scalar() if obj is not None: Session().delete(obj) log.debug('Revoked perm on %s on %s', user_group, user)
def grant_perm(self, user, perm): """ Grant user global permissions :param user: :param perm: """ user = User.guess_instance(user) perm = Permission.guess_instance(perm) # if this permission is already granted skip it _perm = UserToPerm.query() \ .filter(UserToPerm.user == user) \ .filter(UserToPerm.permission == perm) \ .scalar() if _perm: return new = UserToPerm() new.user = user new.permission = perm Session().add(new) return new
def remove_user_from_group(self, user_group, user): user_group = UserGroup.guess_instance(user_group) user = User.guess_instance(user) user_group_member = None for m in user_group.members: if m.user_id == user.user_id: # Found this user's membership row user_group_member = m break if user_group_member: try: Session().delete(user_group_member) return True except Exception: log.error(traceback.format_exc()) raise else: # User isn't in that group return False
def query_for_user(self, user, filter_=None): """ Get notifications for given user, filter them if filter dict is given :param user: :param filter: """ user = User.guess_instance(user) q = UserNotification.query() \ .filter(UserNotification.user == user) \ .join((Notification, UserNotification.notification_id == Notification.notification_id)) \ .options(joinedload('notification')) \ .options(subqueryload('notification.created_by_user')) \ .order_by(Notification.created_on.desc()) if filter_: q = q.filter(Notification.type_.in_(filter_)) return q
def create_default_permissions(self, user, force=False): """ Create missing default permissions for user. If force is set, the default permissions for the user are reset, otherwise only missing permissions are created. :param user: """ user = User.guess_instance(user) def _make_perm(perm): new_perm = UserToPerm() new_perm.user = user new_perm.permission = Permission.get_by_key(perm) return new_perm def _get_group(perm_name): return '.'.join(perm_name.split('.')[:1]) perms = UserToPerm.query().filter(UserToPerm.user == user).all() defined_perms_groups = map(_get_group, (x.permission.permission_name for x in perms)) log.debug('GOT ALREADY DEFINED:%s', perms) DEFAULT_PERMS = Permission.DEFAULT_USER_PERMISSIONS if force: for perm in perms: Session().delete(perm) Session().commit() defined_perms_groups = [] # For every default permission that needs to be created, we check if # its group is already defined. If it's not, we create default permission. for perm_name in DEFAULT_PERMS: gr = _get_group(perm_name) if gr not in defined_perms_groups: log.debug('GR:%s not found, creating permission %s', gr, perm_name) new_perm = _make_perm(perm_name) Session().add(new_perm)
def add_user_to_group(self, user_group, user): user_group = UserGroup.guess_instance(user_group) user = User.guess_instance(user) for m in user_group.members: u = m.user if u.user_id == user.user_id: # user already in the group, skip return True try: user_group_member = UserGroupMember() user_group_member.user = user user_group_member.users_group = user_group user_group.members.append(user_group_member) user.group_member.append(user_group_member) Session().add(user_group_member) return user_group_member except Exception: log.error(traceback.format_exc()) raise
def create(self, text, repo, author, revision=None, pull_request=None, f_path=None, line_no=None, status_change=None, closing_pr=False, send_email=True): """ Creates a new comment for either a changeset or a pull request. status_change and closing_pr is only for the optional email. Returns the created comment. """ if not status_change and not text: log.warning('Missing text for comment, skipping...') return None repo = Repository.guess_instance(repo) author = User.guess_instance(author) comment = ChangesetComment() comment.repo = repo comment.author = author comment.text = text comment.f_path = f_path comment.line_no = line_no if revision is not None: comment.revision = revision elif pull_request is not None: pull_request = PullRequest.guess_instance(pull_request) comment.pull_request = pull_request else: raise Exception('Please specify revision or pull_request_id') Session().add(comment) Session().flush() if send_email: (subj, body, recipients, notification_type, email_kwargs) = self._get_notification_data( repo, comment, author, comment_text=text, line_no=line_no, revision=revision, pull_request=pull_request, status_change=status_change, closing_pr=closing_pr) email_kwargs['is_mention'] = False # create notification objects, and emails NotificationModel().create( created_by=author, subject=subj, body=body, recipients=recipients, type_=notification_type, email_kwargs=email_kwargs, ) mention_recipients = extract_mentioned_users(body).difference(recipients) if mention_recipients: email_kwargs['is_mention'] = True subj = _('[Mention]') + ' ' + subj # FIXME: this subject is wrong and unused! NotificationModel().create( created_by=author, subject=subj, body=body, recipients=mention_recipients, type_=notification_type, email_kwargs=email_kwargs ) return comment
def create(self, description, owner, gist_mapping, gist_type=Gist.GIST_PUBLIC, lifetime=-1): """ :param description: description of the gist :param owner: user who created this gist :param gist_mapping: mapping {filename:{'content':content},...} :param gist_type: type of gist private/public :param lifetime: in minutes, -1 == forever """ owner = User.guess_instance(owner) gist_id = make_gist_id() lifetime = safe_int(lifetime, -1) gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1 log.debug('set GIST expiration date to: %s', time_to_datetime(gist_expires) if gist_expires != -1 else 'forever') #create the Database version gist = Gist() gist.gist_description = description gist.gist_access_id = gist_id gist.owner_id = owner.user_id gist.gist_expires = gist_expires gist.gist_type = safe_unicode(gist_type) Session().add(gist) Session().flush() # make database assign gist.gist_id if gist_type == Gist.GIST_PUBLIC: # use DB ID for easy to use GIST ID gist_id = safe_unicode(gist.gist_id) gist.gist_access_id = gist_id gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id) log.debug('Creating new %s GIST repo in %s', gist_type, gist_repo_path) repo = RepoModel()._create_filesystem_repo( repo_name=gist_id, repo_type='hg', repo_group=GIST_STORE_LOC) processed_mapping = {} for filename in gist_mapping: if filename != os.path.basename(filename): raise Exception('Filename cannot be inside a directory') content = gist_mapping[filename]['content'] #TODO: expand support for setting explicit lexers # if lexer is None: # try: # guess_lexer = pygments.lexers.guess_lexer_for_filename # lexer = guess_lexer(filename,content) # except pygments.util.ClassNotFound: # lexer = 'text' processed_mapping[filename] = {'content': content} # now create single multifile commit message = 'added file' message += 's: ' if len(processed_mapping) > 1 else ': ' message += ', '.join([x for x in processed_mapping]) #fake Kallithea Repository object fake_repo = AttributeDict(dict( repo_name=gist_repo_path, scm_instance_no_cache=lambda: repo, )) ScmModel().create_nodes( user=owner.user_id, repo=fake_repo, message=message, nodes=processed_mapping, trigger_push_hook=False ) self._store_metadata(repo, gist.gist_id, gist.gist_access_id, owner.user_id, gist.gist_type, gist.gist_expires) return gist