Meet SourceLevel, an All-in-one Data & Analytics for Engineering Teams

SourceLevel provides metrics and insights by collecting data from many sources such as GitHub and GitLab. Our product brings visibility over every corner of the delivery pipeline in a Data & Analytics Solution for Engineering Teams.

Get started for free
Go to line 1
defmodule Hexpm.Repository.Owners do
Go to line 2
  use Hexpm.Context
Go to line 4
  def all(package, preload \\ []) do
Go to line 5
    assoc(package, :package_owners)
Go to line 6
    |> Repo.all()
Go to line 7
    |> Repo.preload(preload)
Go to line 10
  def get(package, user) do
Go to line 11
    if owner = Repo.get_by(PackageOwner, package_id: package.id, user_id: user.id) do
Go to line 12
      %{owner | package: package, user: user}
Go to line 16
  def add(package, user, params, audit: audit_data) do
Go to line 17
    repository = package.repository
Go to line 18
    owners = all(package, user: [:emails, :organization])
Go to line 19
    organization_owner = Enum.find(owners, &User.organization?(&1.user))
Go to line 20
    repository_access = Organizations.access?(repository.organization, user, "read")
Go to line 21
    owner_organization = organization_owner && organization_owner.user.organization
Go to line 23
    organization_access =
Go to line 24
      owner_organization && Organizations.access?(owner_organization, user, "read")
Go to line 27
      !repository.public && !repository_access ->
Go to line 28
        {:error, :not_member}
Go to line 30
      # Outside collaborators are not allowed at this time
Go to line 31
      owner_organization && !organization_access ->
Go to line 32
        {:error, :not_member}
Go to line 34
      User.organization?(user) && Map.get(params, "transfer", false) != true ->
Go to line 35
        {:error, :not_organization_transfer}
Go to line 37
      User.organization?(user) && Map.get(params, "level", "full") != "full" ->
Go to line 38
        {:error, :organization_level}
Go to line 40
      !User.organization?(user) && Organizations.get(user.username) ->
Go to line 41
        {:error, :organization_user_conflict}
Go to line 44
        add_owner(package, owners, user, params, audit_data)
Go to line 48
  defp add_owner(package, owners, user, params, audit_data) do
Go to line 49
    owner = Enum.find(owners, &(&1.user_id == user.id))
Go to line 50
    owner = owner || %PackageOwner{package_id: package.id, user_id: user.id}
Go to line 51
    changeset = PackageOwner.changeset(owner, params)
Go to line 54
      Multi.new()
Go to line 55
      |> Multi.insert_or_update(:owner, changeset)
Go to line 56
      |> remove_existing_owners(owners, params)
Go to line 57
      |> audit(audit_data, add_owner_audit_log_action(params), fn %{owner: owner} ->
Go to line 58
        {package, owner.level, user}
Go to line 61
    case Repo.transaction(multi) do
Go to line 62
      {:ok, %{owner: owner}} ->
Go to line 63
        # TODO: Separate email for the affected person
Go to line 66
          |> Enum.map(& &1.user)
Go to line 67
          |> Kernel.++([user])
Go to line 68
          |> Repo.preload(organization: [organization_users: [user: :emails]])
Go to line 70
        Emails.owner_added(package, owners, user)
Go to line 71
        |> Mailer.deliver_now_throttled()
Go to line 73
        {:ok, %{owner | user: user}}
Go to line 75
      {:error, :owner, changeset, _} ->
Go to line 76
        {:error, changeset}
Go to line 80
  defp add_owner_audit_log_action(%{"transfer" => true}), do: "owner.transfer"
Go to line 81
  defp add_owner_audit_log_action(_params), do: "owner.add"
Go to line 83
  defp remove_existing_owners(multi, owners, %{"transfer" => true}) do
Go to line 84
    Multi.run(multi, :removed_owners, fn repo, %{owner: owner} ->
Go to line 85
      owner_ids =
Go to line 87
        |> Enum.filter(&(&1.id != owner.id))
Go to line 88
        |> Enum.map(& &1.id)
Go to line 90
      {num_rows, _} =
Go to line 91
        from(po in PackageOwner, where: po.id in ^owner_ids)
Go to line 92
        |> repo.delete_all()
Go to line 94
      {:ok, num_rows}
Go to line 98
  defp remove_existing_owners(multi, _owners, _params) do
Go to line 102
  def remove(package, user, audit: audit_data) do
Go to line 103
    owners = all(package, user: :emails)
Go to line 104
    owner = Enum.find(owners, &(&1.user_id == user.id))
Go to line 108
        {:error, :not_owner}
Go to line 110
      length(owners) == 1 and package.repository.public ->
Go to line 111
        {:error, :last_owner}
Go to line 115
          Multi.new()
Go to line 116
          |> Multi.delete(:owner, owner)
Go to line 117
          |> audit(audit_data, "owner.remove", fn %{owner: owner} ->
Go to line 118
            {package, owner.level, owner.user}
Go to line 121
        {:ok, _} = Repo.transaction(multi)
Go to line 123
        # TODO: Separate email for the affected person
Go to line 126
          |> Enum.map(& &1.user)
Go to line 127
          |> Repo.preload(organization: [users: :emails])
Go to line 129
        Emails.owner_removed(package, owners, owner.user)
Go to line 130
        |> Mailer.deliver_now_throttled()