Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions ee/rbac/lib/rbac/collaborators_refresher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,16 @@ defmodule Rbac.CollaboratorsRefresher do
collaborator["permissions"]["pull"]
)

Rbac.Repo.RbacRefreshProjectAccessRequest.add_request(
project.org_id,
user_id,
project_id,
:add,
source,
role_to_be_assigned
)
if role_to_be_assigned do
Rbac.Repo.RbacRefreshProjectAccessRequest.add_request(
project.org_id,
user_id,
project_id,
:add,
source,
role_to_be_assigned
)
end
end
end)
end
Expand Down
4 changes: 3 additions & 1 deletion ee/rbac/lib/rbac/okta/scim/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,9 @@ defmodule Rbac.Okta.Scim.Api do
end

defp json(conn, status, payload) do
send_resp(conn, status, Jason.encode!(payload))
conn
|> put_resp_content_type("application/json")
|> send_resp(status, Jason.encode!(payload))
end

defp serialize_user(okta_user) do
Expand Down
16 changes: 10 additions & 6 deletions ee/rbac/lib/rbac/repo/repo_to_role_mapping.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ defmodule Rbac.Repo.RepoToRoleMapping do
- pull_acess (boolean) Whehter you have pull access on specific repo
"""
@spec get_project_role_from_repo_access_rights(String.t(), boolean(), boolean(), boolean()) ::
String.t()
String.t() | nil
def get_project_role_from_repo_access_rights(org_id, admin_access, push_access, pull_access) do
repo_to_role_mapping = get_repo_to_role_mapping(org_id)
case get_repo_to_role_mapping(org_id) do
nil ->
nil

case {admin_access, push_access, pull_access} do
{true, _, _} -> Map.get(repo_to_role_mapping, :admin_access_role_id)
{false, true, _} -> Map.get(repo_to_role_mapping, :push_access_role_id)
{false, false, true} -> Map.get(repo_to_role_mapping, :pull_access_role_id)
mapping ->
case {admin_access, push_access, pull_access} do
{true, _, _} -> mapping.admin_access_role_id
{false, true, _} -> mapping.push_access_role_id
{false, false, true} -> mapping.pull_access_role_id
end
end
end

Expand Down
5 changes: 3 additions & 2 deletions ee/rbac/lib/rbac/role_management.ex
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,12 @@ defmodule Rbac.RoleManagement do
"[Role Management] Assigning roles based of collaborators list for RBI: #{inspect(rbi)}"
)

roles_to_be_assign =
roles_to_be_assigned =
gen_query_to_assign_roles_to_collaborators(rbi)
|> Rbac.Repo.all()

list_of_subject_role_bindings =
Enum.map(roles_to_be_assign, fn binding ->
Enum.map(roles_to_be_assigned, fn binding ->
%{
role_id:
Rbac.Repo.RepoToRoleMapping.get_project_role_from_repo_access_rights(
Expand All @@ -335,6 +335,7 @@ defmodule Rbac.RoleManagement do
binding_source: String.to_atom(binding[:provider])
}
end)
|> Enum.filter(fn binding -> binding.role_id != nil end)

assign_roles(list_of_subject_role_bindings, rbi)
end
Expand Down
88 changes: 88 additions & 0 deletions ee/rbac/test/rbac/collaborators_refresher_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,93 @@ defmodule Rbac.CollaboratorsRefresher.Test do
|> Rbac.Repo.one() == nil
end
end

test "does not create refresh requests when org has no RepoToRoleMapping" do
alias InternalApi.Repository.Collaborator

list_collaborators = %InternalApi.Repository.ListCollaboratorsResponse{
next_page_token: "",
collaborators: [
%Collaborator{id: "3", login: "baz", permission: :WRITE},
%Collaborator{id: "4", login: "bam", permission: :READ}
]
}

GrpcMock.stub(RepositoryMock, :list_collaborators, fn _, _ ->
list_collaborators
end)

project = Support.Factories.project()

response = %InternalApi.Projecthub.DescribeResponse{
metadata: Support.Factories.response_meta(),
project: project
}

GrpcMock.stub(ProjecthubMock, :describe, fn _, _ -> response end)

{:ok, project} =
Rbac.Store.Project.update(
project.metadata.id,
"renderedtext/semaphore2",
"15324ba0-1b20-49d0-8ff9-a2d91fa451e0",
"github",
"private"
)

[user1, user2, user3, user4] =
rbac_users =
1..4
|> Enum.map(fn _ ->
{:ok, user} = Support.Factories.RbacUser.insert()
user
end)

Enum.each(rbac_users, fn user ->
Support.Members.insert_user(
id: user.id,
email: user.email,
name: user.name
)
end)

{:ok, _org_scope} = Support.Factories.Scope.insert("org_scope")

Support.Factories.SubjectRoleBinding.insert(
subject_id: user3.id,
org_id: project.org_id,
binding_source: :manually_assigned
)

Support.Factories.SubjectRoleBinding.insert(
subject_id: user4.id,
org_id: project.org_id,
binding_source: :manually_assigned
)

with_mocks [
{Rbac.Store.User, [],
[
find_id_by_provider_uid: fn github_uid, _ ->
case github_uid do
"1" -> user1.id
"2" -> user2.id
"3" -> user3.id
"4" -> user4.id
end
end
]}
] do
assert :ok = Rbac.CollaboratorsRefresher.refresh(project)

# Giving time for message broker to process
:timer.sleep(500)
Rbac.Workers.RefreshProjectAccess.perform_now()
:timer.sleep(1000)

refresh_requests = Rbac.Repo.RbacRefreshProjectAccessRequest |> Rbac.Repo.all()
assert refresh_requests == []
end
end
end
end
74 changes: 74 additions & 0 deletions ee/rbac/test/rbac/repo/repo_to_role_mapping_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,78 @@ defmodule Rbac.Repo.RepoToRoleMapping.Test do
assert state[:mapping_for_specific_org] === mapper
end
end

describe "get_project_role_from_repo_access_rights/4" do
test "returns nil when org has no RepoToRoleMapping for admin access" do
role_id =
RepoToRoleMapping.get_project_role_from_repo_access_rights(
@non_existant_org_id,
true,
false,
false
)

assert role_id === nil
end

test "returns admin role when user has admin access", state do
role_id =
RepoToRoleMapping.get_project_role_from_repo_access_rights(
@org_id,
true,
false,
false
)

assert role_id === state[:mapping_for_specific_org].admin_access_role_id
end

test "returns admin role when user has admin, push, and pull access", state do
role_id =
RepoToRoleMapping.get_project_role_from_repo_access_rights(
@org_id,
true,
true,
true
)

assert role_id === state[:mapping_for_specific_org].admin_access_role_id
end

test "returns push role when user has push access only", state do
role_id =
RepoToRoleMapping.get_project_role_from_repo_access_rights(
@org_id,
false,
true,
false
)

assert role_id === state[:mapping_for_specific_org].push_access_role_id
end

test "returns push role when user has push and pull access", state do
role_id =
RepoToRoleMapping.get_project_role_from_repo_access_rights(
@org_id,
false,
true,
true
)

assert role_id === state[:mapping_for_specific_org].push_access_role_id
end

test "returns pull role when user has pull access only", state do
role_id =
RepoToRoleMapping.get_project_role_from_repo_access_rights(
@org_id,
false,
false,
true
)

assert role_id === state[:mapping_for_specific_org].pull_access_role_id
end
end
end
19 changes: 19 additions & 0 deletions ee/rbac/test/rbac/role_management_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,25 @@ defmodule Rbac.RoleManagement.Test do

assert user_has_access_to_projects?(@user_id, @org_id, [@project_id])
end

test "Organization does not have RepoToRoleMapping" do
Support.Rbac.assign_org_role_by_name(@org_id, @user_id, "Member")
Collaborators.insert_user(user_id: @user_id, github_uid: "1")
Collaborators.insert(github_uid: "1", project_id: @project_id)
Support.Projects.insert(project_id: @project_id, org_id: @org_id)

# Note: We deliberately do NOT create a RepoToRoleMapping for this org

{:ok, project_rbi} = RBI.new(org_id: @org_id, project_id: @project_id)

# Should succeed but skip role assignment due to missing RepoToRoleMapping
{:ok, _} = RoleManagement.assign_project_roles_to_repo_collaborators(project_rbi)

# Verify no project role was assigned to the collaborator
{:ok, admin} = Rbac.Repo.RbacRole.get_role_by_name("Admin", "project_scope", @org_id)
refute has_role_binding?(@user_id, @org_id, @project_id, admin.id, :github)
refute user_has_access_to_projects?(@user_id, @org_id, [@project_id])
end
end

describe "retract_role/2" do
Expand Down