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 8
end
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 13
end
Go to line 14
end
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 26
cond do
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 43
true ->
Go to line 44
add_owner(package, owners, user, params, audit_data)
Go to line 45
end
Go to line 46
end
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 53
multi =
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 59
end)
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
TODO found
Go to line 64
owners =
Go to line 65
owners
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 77
end
Go to line 78
end
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 86
owners
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 95
end)
Go to line 96
end
Go to line 98
defp remove_existing_owners(multi, _owners, _params) do
Go to line 99
multi
Go to line 100
end
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 106
cond do
Go to line 107
!owner ->
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 113
true ->
Go to line 114
multi =
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 119
end)
Go to line 121
{:ok, _} = Repo.transaction(multi)
Go to line 123
# TODO: Separate email for the affected person
TODO found
Go to line 124
owners =
Go to line 125
owners
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()
Go to line 132
:ok
Go to line 133
end
Go to line 134
end
Go to line 135
end