Skip to content

Commit d733bff

Browse files
fix(rbac): if role does not exist anymore, treat it as no one has it (#207)
## 📝 Description (renderedtext/tasks#7794) ## ✅ Checklist - [x] I have tested this change - [x] ~This change requires documentation update~
1 parent eee25a1 commit d733bff

File tree

3 files changed

+61
-53
lines changed

3 files changed

+61
-53
lines changed

ee/rbac/lib/rbac/role_management.ex

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -484,32 +484,27 @@ defmodule Rbac.RoleManagement do
484484
end
485485

486486
defp role_scope_matches_rest_of_data?(project_id, role_id) do
487-
role = Rbac.Repo.RbacRole.get_role_by_id(role_id)
488-
489-
case role.scope.scope_name do
490-
"project_scope" ->
491-
case project_id do
492-
nil ->
493-
{:error, "Project id cant be nil for roles with project scope"}
487+
case Rbac.Repo.RbacRole.get_role_by_id(role_id) do
488+
nil ->
489+
{:error, "Role with id #{role_id} does not exist."}
494490

495-
_ ->
496-
{:ok, nil}
497-
end
491+
%{scope: %{scope_name: "project_scope"}} when is_nil(project_id) ->
492+
{:error, "Project id cant be nil for roles with project scope"}
498493

499-
scope when scope in ["org_scope", "insider_scope"] ->
500-
case project_id do
501-
nil ->
502-
{:ok, nil}
494+
%{scope: %{scope_name: "project_scope"}} ->
495+
{:ok, nil}
503496

504-
:is_nil ->
505-
{:ok, nil}
497+
%{scope: %{scope_name: scope}}
498+
when scope in ["org_scope", "insider_scope"] and
499+
(is_nil(project_id) or project_id == :is_nil) ->
500+
{:ok, nil}
506501

507-
_ ->
508-
{:error, "Project id must be nil for roles with organization or insider scope"}
509-
end
502+
%{scope: %{scope_name: scope}} when scope in ["org_scope", "insider_scope"] ->
503+
{:error, "Project id must be nil for roles with organization or insider scope"}
510504

511-
nil ->
512-
Logger.error("[Rbac RoleManagement] Role with id #{role_id} does not exist.")
505+
%{scope: %{scope_name: scope}} ->
506+
Logger.error("[RoleManagement] Role #{role_id}, unrecongized scope: #{scope}.")
507+
{:error, "Unrecongized scope: #{scope}"}
513508
end
514509
end
515510

ee/rbac/test/rbac/grpc_servers/rbac_server_test.exs

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
99

1010
import Mock
1111
import Ecto.Query
12+
alias Ecto.UUID
1213
alias InternalApi.RBAC.RBAC.Stub
1314

1415
@store_backend Application.compile_env(:rbac, :key_value_store_backend)
1516
@user_permissions_store_name Application.compile_env(:rbac, :user_permissions_store_name)
1617
@project_access_store_name Application.compile_env(:rbac, :project_access_store_name)
1718

1819
@user_name "Jane Doe"
19-
@user_id Ecto.UUID.generate()
20-
@org_id Ecto.UUID.generate()
21-
@project_id Ecto.UUID.generate()
22-
@requester_id Ecto.UUID.generate()
20+
@user_id UUID.generate()
21+
@org_id UUID.generate()
22+
@project_id UUID.generate()
23+
@requester_id UUID.generate()
2324
@org_admin_permissions ["organization.general_settings.manage", "organization.view"]
2425
@proj_reader_permissions ["project.view"]
2526

@@ -60,7 +61,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
6061
test "organization permissions are not returned for user without organization role",
6162
state do
6263
Support.Rbac.assign_org_role_by_name(@org_id, @user_id, "Admin")
63-
req = %Request{user_id: @user_id, org_id: Ecto.UUID.generate()}
64+
req = %Request{user_id: @user_id, org_id: UUID.generate()}
6465

6566
{:ok, %{permissions: permissions}} = state.grpc_channel |> Stub.list_user_permissions(req)
6667
assert permissions == []
@@ -145,12 +146,12 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
145146
describe "assign_role" do
146147
test "role is not assigned if parameters are not valid UUIDs", state do
147148
reqs = [
148-
gen_assign_role_req("", Ecto.UUID.generate(), Ecto.UUID.generate()),
149-
gen_assign_role_req("*", Ecto.UUID.generate(), Ecto.UUID.generate()),
150-
gen_assign_role_req(@user_id, "", Ecto.UUID.generate()),
151-
gen_assign_role_req(@user_id, "*", Ecto.UUID.generate()),
152-
gen_assign_role_req(@user_id, Ecto.UUID.generate(), ""),
153-
gen_assign_role_req(@user_id, Ecto.UUID.generate(), "*")
149+
gen_assign_role_req("", UUID.generate(), UUID.generate()),
150+
gen_assign_role_req("*", UUID.generate(), UUID.generate()),
151+
gen_assign_role_req(@user_id, "", UUID.generate()),
152+
gen_assign_role_req(@user_id, "*", UUID.generate()),
153+
gen_assign_role_req(@user_id, UUID.generate(), ""),
154+
gen_assign_role_req(@user_id, UUID.generate(), "*")
154155
]
155156

156157
Enum.each(reqs, fn req ->
@@ -161,7 +162,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
161162
end
162163

163164
test "organization role is not assigned if it does not exist", state do
164-
role_id = Ecto.UUID.generate()
165+
role_id = UUID.generate()
165166
req = gen_assign_role_req(@user_id, role_id, @org_id)
166167
{:error, err} = state.grpc_channel |> Stub.assign_role(req)
167168

@@ -170,7 +171,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
170171
end
171172

172173
test "role is not assigned if it is not owned by organization", state do
173-
non_existant_org_id = Ecto.UUID.generate()
174+
non_existant_org_id = UUID.generate()
174175
{:ok, role} = Rbac.Repo.RbacRole.get_role_by_name("Admin", "org_scope", @org_id)
175176

176177
req = gen_assign_role_req(@user_id, role.id, non_existant_org_id)
@@ -188,7 +189,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
188189
end)
189190

190191
{:ok, role} = Rbac.Repo.RbacRole.get_role_by_name("Reader", "project_scope", @org_id)
191-
non_existant_proj_id = Ecto.UUID.generate()
192+
non_existant_proj_id = UUID.generate()
192193
req = gen_assign_role_req(@user_id, role.id, @org_id, non_existant_proj_id)
193194

194195
{:error, err} = state.grpc_channel |> Stub.assign_role(req)
@@ -197,7 +198,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
197198
end
198199

199200
test "project role is not assigned if project does not belong to organization", state do
200-
project_id = Ecto.UUID.generate()
201+
project_id = UUID.generate()
201202
Support.Projects.insert(project_id: project_id)
202203

203204
GrpcMock.stub(ProjecthubMock, :describe, fn _, _ ->
@@ -424,7 +425,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
424425
Support.Factories.UserGroupBinding.insert(group_id: group.id, user_id: @user_id)
425426

426427
# Role within some other organization
427-
other_org = Ecto.UUID.generate()
428+
other_org = UUID.generate()
428429
Support.Rbac.create_org_roles(other_org)
429430
Support.Rbac.assign_org_role_by_name(other_org, @user_id, "Admin")
430431

@@ -494,7 +495,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
494495
describe "list_members" do
495496
alias InternalApi.RBAC.ListMembersRequest, as: Request
496497
@new_member_name "Adam Neely"
497-
@new_member Ecto.UUID.generate()
498+
@new_member UUID.generate()
498499

499500
setup state do
500501
Support.Factories.RbacUser.insert(@new_member, @new_member_name)
@@ -578,7 +579,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
578579
test "when listing project members", state do
579580
alias Support.Factories.OrgRoleToProjRoleMappings
580581

581-
{:ok, third_user} = Support.Factories.RbacUser.insert(Ecto.UUID.generate(), @user_name)
582+
{:ok, third_user} = Support.Factories.RbacUser.insert(UUID.generate(), @user_name)
582583

583584
# Two users are 'normal' members of the org
584585
Support.Rbac.assign_org_role_by_name(@org_id, @user_id, "Member")
@@ -616,7 +617,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
616617
1..3
617618
|> Enum.each(fn i ->
618619
{:ok, rbac_user} =
619-
Support.Factories.RbacUser.insert(Ecto.UUID.generate(), "John Doe #{i}")
620+
Support.Factories.RbacUser.insert(UUID.generate(), "John Doe #{i}")
620621

621622
Support.Rbac.assign_org_role_by_name(@org_id, rbac_user.id, Enum.at(roles, i - 1))
622623
end)
@@ -633,7 +634,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
633634
end
634635

635636
test "Should return not found error if organization is not found", %{grpc_channel: channel} do
636-
org_id = Ecto.UUID.generate()
637+
org_id = UUID.generate()
637638
request = %Request{org_id: org_id}
638639

639640
assert {:error, grpc_error} = channel |> Stub.count_members(request)
@@ -711,7 +712,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
711712
alias InternalApi.RBAC.DescribeRoleRequest, as: Request
712713

713714
test "when role does not exist", state do
714-
req = %Request{role_id: Ecto.UUID.generate(), org_id: @org_id}
715+
req = %Request{role_id: UUID.generate(), org_id: @org_id}
715716
{:error, err} = state.grpc_channel |> Stub.describe_role(req)
716717
assert err.status == GRPC.Status.not_found()
717718
assert err.message =~ "not found"
@@ -763,8 +764,8 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
763764

764765
test "creates refresh request and calls worker", state do
765766
# Insert a couple more test projects
766-
project_id2 = Ecto.UUID.generate()
767-
project_id3 = Ecto.UUID.generate()
767+
project_id2 = UUID.generate()
768+
project_id3 = UUID.generate()
768769
Support.Projects.insert(project_id: project_id2, org_id: @org_id)
769770
Support.Projects.insert(project_id: project_id3, org_id: @org_id)
770771

@@ -803,7 +804,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
803804
test "modify role that does not exist", state do
804805
req = %Request{
805806
role: %InternalApi.RBAC.Role{
806-
id: Ecto.UUID.generate(),
807+
id: UUID.generate(),
807808
org_id: @org_id,
808809
scope: :SCOPE_ORG
809810
},
@@ -907,7 +908,7 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
907908
end
908909

909910
test "user is unauthorized to update roles", state do
910-
req = %Request{role_id: Ecto.UUID.generate(), org_id: @org_id, requester_id: @requester_id}
911+
req = %Request{role_id: UUID.generate(), org_id: @org_id, requester_id: @requester_id}
911912

912913
{:error, err} = state.grpc_channel |> Stub.destroy_role(req)
913914

@@ -927,11 +928,18 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
927928
assert err_msg.message =~ "Invalid uuid passed"
928929
end
929930

931+
test "role does not exist anymore", state do
932+
req = %Request{role_assignments: [gen_role_assignment(UUID.generate(), @user_id, @org_id)]}
933+
934+
{:ok, response} = state.grpc_channel |> Stub.subjects_have_roles(req)
935+
assert response.has_roles |> Enum.at(0) |> Map.get(:has_role) == false
936+
end
937+
930938
test "first subject has the role, second does not", state do
931939
Support.Rbac.assign_org_role_by_name(@org_id, @user_id, "Admin")
932940
{:ok, role} = Rbac.Repo.RbacRole.get_role_by_name("Admin", "org_scope", @org_id)
933941

934-
random_user = Ecto.UUID.generate()
942+
random_user = UUID.generate()
935943

936944
req = %Request{
937945
role_assignments: [
@@ -972,8 +980,8 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
972980
end
973981

974982
test "If user has access to 2 orgs, return those ids", state do
975-
org1_id = Ecto.UUID.generate()
976-
org2_id = Ecto.UUID.generate()
983+
org1_id = UUID.generate()
984+
org2_id = UUID.generate()
977985

978986
Support.Rbac.create_org_roles(org1_id)
979987
Support.Rbac.create_org_roles(org2_id)
@@ -1013,10 +1021,10 @@ defmodule Rbac.GrpcServers.RbacServer.Test do
10131021
end
10141022

10151023
test "return only projects that user has access to", state do
1016-
project1_id = Ecto.UUID.generate()
1017-
project2_id = Ecto.UUID.generate()
1018-
project3_id = Ecto.UUID.generate()
1019-
org2_id = Ecto.UUID.generate()
1024+
project1_id = UUID.generate()
1025+
project2_id = UUID.generate()
1026+
project3_id = UUID.generate()
1027+
org2_id = UUID.generate()
10201028

10211029
Support.Rbac.create_org_roles(org2_id)
10221030
Support.Rbac.create_project_roles(org2_id)

ee/rbac/test/rbac/role_management_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ defmodule Rbac.RoleManagement.Test do
4242
assert RoleManagement.has_role(rbi, "") == false
4343
end
4444

45+
test "random non-existent role_id returns false" do
46+
{:ok, rbi} = RBI.new(user_id: @user_id, org_id: @org_id, project_id: @project_id)
47+
assert RoleManagement.has_role(rbi, Ecto.UUID.generate()) == false
48+
end
49+
4550
test "user that has given org_level role" do
4651
Support.Rbac.assign_org_role_by_name(@org_id, @user_id, "Admin")
4752
{:ok, role} = Rbac.Repo.RbacRole.get_role_by_name("Admin", "org_scope", @org_id)

0 commit comments

Comments
 (0)