Beispiel #1
0
def remove_organization_member(org, user_obj):
    org_admins = [u.username for u in __get_org_admin_users(org)]
    if len(org_admins) == 1 and user_obj.username in org_admins:
        raise DataModelException(
            "Cannot remove user as they are the only organization admin")

    with db_transaction():
        # Find and remove the user from any repositories under the org.
        permissions = list(
            RepositoryPermission.select(
                RepositoryPermission.id).join(Repository).where(
                    Repository.namespace_user == org,
                    RepositoryPermission.user == user_obj))

        if permissions:
            RepositoryPermission.delete().where(
                RepositoryPermission.id << permissions).execute()

        # Find and remove the user from any teams under the org.
        members = list(
            TeamMember.select(TeamMember.id).join(Team).where(
                Team.organization == org, TeamMember.user == user_obj))

        if members:
            TeamMember.delete().where(TeamMember.id << members).execute()
Beispiel #2
0
def create_repository(
    namespace, name, creating_user, visibility="private", repo_kind="image", description=None
):
    namespace_user = User.get(username=namespace)
    yesterday = datetime.now() - timedelta(days=1)

    with db_transaction():
        repo = Repository.create(
            name=name,
            visibility=Repository.visibility.get_id(visibility),
            namespace_user=namespace_user,
            kind=Repository.kind.get_id(repo_kind),
            description=description,
        )

        RepositoryActionCount.create(repository=repo, count=0, date=yesterday)
        RepositorySearchScore.create(repository=repo, score=0)

        # Note: We put the admin create permission under the transaction to ensure it is created.
        if creating_user and not creating_user.organization:
            admin = Role.get(name="admin")
            RepositoryPermission.create(user=creating_user, repository=repo, role=admin)

    # Apply default permissions (only occurs for repositories under organizations)
    if creating_user and not creating_user.organization and creating_user.username != namespace:
        permission.apply_default_permissions(repo, creating_user)

    return repo
Beispiel #3
0
def create_repository(namespace,
                      name,
                      creating_user,
                      visibility="private",
                      repo_kind="image",
                      description=None):
    namespace_user = User.get(username=namespace)
    yesterday = datetime.now() - timedelta(days=1)

    try:
        with db_transaction():
            # Check if the repository exists to avoid an IntegrityError if possible.
            existing = get_repository(namespace, name)
            if existing is not None:
                return None

            try:
                repo = Repository.create(
                    name=name,
                    visibility=Repository.visibility.get_id(visibility),
                    namespace_user=namespace_user,
                    kind=Repository.kind.get_id(repo_kind),
                    description=description,
                )
            except IntegrityError as ie:
                raise _RepositoryExistsException(ie)

            RepositoryActionCount.create(repository=repo,
                                         count=0,
                                         date=yesterday)
            RepositorySearchScore.create(repository=repo, score=0)

            # Note: We put the admin create permission under the transaction to ensure it is created.
            if creating_user and not creating_user.organization:
                admin = Role.get(name="admin")
                RepositoryPermission.create(user=creating_user,
                                            repository=repo,
                                            role=admin)
    except _RepositoryExistsException as ree:
        try:
            return Repository.get(namespace_user=namespace_user, name=name)
        except Repository.DoesNotExist:
            logger.error(
                "Got integrity error when trying to create repository %s/%s: %s",
                namespace,
                name,
                ree.internal_exception,
            )
            return None

    # Apply default permissions (only occurs for repositories under organizations)
    if creating_user and not creating_user.organization and creating_user.username != namespace:
        permission.apply_default_permissions(repo, creating_user)

    return repo
Beispiel #4
0
def ensure_admin(user, repos, dry_run=False):
    repos = [repo for repo in repos if not has_admin(user, repo)]

    for repo in repos:
        print("User {} missing admin on: {}".format(user.username, repo.name))

        if not dry_run:
            RepositoryPermission.create(user=user, repository=repo, role=ADMIN)
            print("Granted {} admin on: {}".format(user.username, repo.name))

    return len(repos)
Beispiel #5
0
def convert_user_to_organization(user_obj, admin_user):
    if user_obj.robot:
        raise DataModelException("Cannot convert a robot into an organization")

    with db_transaction():
        # Change the user to an organization and disable this account for login.
        user_obj.organization = True
        user_obj.password_hash = None
        user_obj.save()

        # Clear any federated auth pointing to this user.
        FederatedLogin.delete().where(
            FederatedLogin.user == user_obj).execute()

        # Delete any user-specific permissions on repositories.
        (RepositoryPermission.delete().where(
            RepositoryPermission.user == user_obj).execute())

        # Create a team for the owners
        owners_team = team.create_team("owners", user_obj, "admin")

        # Add the user who will admin the org to the owners team
        team.add_user_to_team(admin_user, owners_team)

        return user_obj
Beispiel #6
0
def _get_user_repo_permissions(user,
                               limit_to_repository_obj=None,
                               limit_namespace=None,
                               limit_repo_name=None):
    UserThroughTeam = User.alias()

    base_query = (RepositoryPermission.select(
        RepositoryPermission, Role, Repository,
        Namespace).join(Role).switch(RepositoryPermission).join(
            Repository).join(Namespace,
                             on=(Repository.namespace_user == Namespace.id
                                 )).switch(RepositoryPermission))

    if limit_to_repository_obj is not None:
        base_query = base_query.where(
            RepositoryPermission.repository == limit_to_repository_obj)
    elif limit_namespace and limit_repo_name:
        base_query = base_query.where(Repository.name == limit_repo_name,
                                      Namespace.username == limit_namespace)

    direct = base_query.clone().join(User).where(User.id == user)

    team = (base_query.clone().join(Team).join(TeamMember).join(
        UserThroughTeam, on=(UserThroughTeam.id == TeamMember.user)).where(
            UserThroughTeam.id == user))

    return direct | team
Beispiel #7
0
def __set_entity_repo_permission(entity, permission_entity_property,
                                 namespace_name, repository_name, role_name):
  repo = _basequery.get_existing_repository(namespace_name, repository_name)
  new_role = Role.get(Role.name == role_name)

  # Fetch any existing permission for this entity on the repo
  try:
    entity_attr = getattr(RepositoryPermission, permission_entity_property)
    perm = RepositoryPermission.get(entity_attr == entity, RepositoryPermission.repository == repo)
    perm.role = new_role
    perm.save()
    return perm
  except RepositoryPermission.DoesNotExist:
    set_entity_kwargs = {permission_entity_property: entity}
    new_perm = RepositoryPermission.create(repository=repo, role=new_role, **set_entity_kwargs)
    return new_perm
Beispiel #8
0
def get_all_repo_users(namespace_name, repository_name):
    return (RepositoryPermission.select(
        User, Role,
        RepositoryPermission).join(User).switch(RepositoryPermission).join(
            Role).switch(RepositoryPermission).join(Repository).join(
                Namespace,
                on=(Repository.namespace_user == Namespace.id)).where(
                    Namespace.username == namespace_name,
                    Repository.name == repository_name))
Beispiel #9
0
def _get_visible_repositories_for_user(user,
                                       repo_kind="image",
                                       include_public=False,
                                       namespace=None):
    """
    Returns all repositories directly visible to the given user, by either repo permission, or the
    user being the admin of a namespace.
    """
    for repo in Repository.select():
        if repo_kind is not None and repo.kind.name != repo_kind:
            continue

        if namespace is not None and repo.namespace_user.username != namespace:
            continue

        if include_public and repo.visibility.name == "public":
            yield repo
            continue

        # Direct repo permission.
        try:
            RepositoryPermission.get(repository=repo, user=user).get()
            yield repo
            continue
        except RepositoryPermission.DoesNotExist:
            pass

        # Team permission.
        found_in_team = False
        for perm in RepositoryPermission.select().where(
                RepositoryPermission.repository == repo):
            if perm.team and _is_team_member(perm.team, user):
                found_in_team = True
                break

        if found_in_team:
            yield repo
            continue

        # Org namespace admin permission.
        if user in get_admin_users(repo.namespace_user):
            yield repo
            continue
Beispiel #10
0
def list_organization_member_permissions(organization, limit_to_user=None):
    query = (RepositoryPermission.select(
        RepositoryPermission, Repository,
        User).join(Repository).switch(RepositoryPermission).join(User).where(
            Repository.namespace_user == organization))

    if limit_to_user is not None:
        query = query.where(RepositoryPermission.user == limit_to_user)
    else:
        query = query.where(User.robot == False)

    return query
Beispiel #11
0
def __entity_permission_repo_query(entity_id, entity_table, entity_id_property,
                                   namespace_name, repository_name):
    """ This method works for both users and teams. """

    return (RepositoryPermission.select(
        entity_table, Repository, Namespace, Role,
        RepositoryPermission).join(entity_table).switch(RepositoryPermission).
            join(Role).switch(RepositoryPermission).join(Repository).join(
                Namespace,
                on=(Repository.namespace_user == Namespace.id)).where(
                    Repository.name == repository_name,
                    Namespace.username == namespace_name,
                    entity_id_property == entity_id,
                ))
Beispiel #12
0
def get_teams_within_org(organization, has_external_auth=False):
    """
    Returns a AttrDict of team info (id, name, description), its role under the org, the number of
    repositories on which it has permission, and the number of members.
    """
    query = Team.select().where(
        Team.organization == organization).join(TeamRole)

    def _team_view(team):
        return {
            "id": team.id,
            "name": team.name,
            "description": team.description,
            "role_name": Team.role.get_name(team.role_id),
            "repo_count": 0,
            "member_count": 0,
            "is_synced": False,
        }

    teams = {team.id: _team_view(team) for team in query}
    if not teams:
        # Just in case. Should ideally never happen.
        return []

    # Add repository permissions count.
    permission_tuples = (RepositoryPermission.select(
        RepositoryPermission.team, fn.Count(RepositoryPermission.id)).where(
            RepositoryPermission.team << list(teams.keys())).group_by(
                RepositoryPermission.team).tuples())

    for perm_tuple in permission_tuples:
        teams[perm_tuple[0]]["repo_count"] = perm_tuple[1]

    # Add the member count.
    members_tuples = (TeamMember.select(TeamMember.team, fn.Count(
        TeamMember.id)).where(TeamMember.team << list(teams.keys())).group_by(
            TeamMember.team).tuples())

    for member_tuple in members_tuples:
        teams[member_tuple[0]]["member_count"] = member_tuple[1]

    # Add syncing information.
    if has_external_auth:
        sync_query = TeamSync.select(
            TeamSync.team).where(TeamSync.team << list(teams.keys()))
        for team_sync in sync_query:
            teams[team_sync.team_id]["is_synced"] = True

    return [AttrDict(team_info) for team_info in list(teams.values())]
Beispiel #13
0
def list_robot_permissions(robot_name):
    return (RepositoryPermission.select(
        RepositoryPermission, User,
        Repository).join(Repository).join(Visibility).switch(
            RepositoryPermission).join(Role).switch(RepositoryPermission).join(
                User).where(User.username == robot_name, User.robot == True))
Beispiel #14
0
    def create_user_permission(user, repo, role):
        # The creating user always gets admin anyway
        if user.username == creating_user_obj.username:
            return

        RepositoryPermission.create(user=user, repository=repo, role=role)
Beispiel #15
0
 def create_team_permission(team, repo, role):
     RepositoryPermission.create(team=team, repository=repo, role=role)
Beispiel #16
0
def list_team_permissions(team):
    return (RepositoryPermission.select(RepositoryPermission).join(Repository).
            join(Visibility).switch(RepositoryPermission).join(Role).switch(
                RepositoryPermission).where(RepositoryPermission.team == team))