Commit 53869dc2 authored by Mark Chao's avatar Mark Chao

ES: update permission spec table

Remove impossible cases due to private project's features can only be
private or disabled.

Fix spec due to sidekiq indexing not triggered.

Update guest use cases: some features has additional constraint that
"Guest users are able to perform action on public/internal projects,
but not private ones."
parent 4a525497
...@@ -18,16 +18,16 @@ describe Search::GlobalService do ...@@ -18,16 +18,16 @@ describe Search::GlobalService do
let(:service) { described_class.new(user, params) } let(:service) { described_class.new(user, params) }
end end
context 'visibility', :elastic do context 'visibility', :elastic, :sidekiq_inline do
include_context 'ProjectPolicyTable context' include_context 'ProjectPolicyTable context'
set(:group) { create(:group) } set(:group) { create(:group) }
let(:project) { create(:project, project_level, namespace: group) } let(:project) { create(:project, project_level, namespace: group) }
let(:project2) { create(:project, project_level) }
let(:user) { create_user_from_membership(project, membership) } let(:user) { create_user_from_membership(project, membership) }
context 'merge request' do context 'merge request' do
let!(:merge_request) { create :merge_request, target_project: project, source_project: project } let!(:merge_request) { create :merge_request, target_project: project, source_project: project }
let!(:note) { create :note, project: project, noteable: merge_request }
where(:project_level, :feature_access_level, :membership, :expected_count) do where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_reporter_feature_access permission_table_for_reporter_feature_access
...@@ -35,41 +35,118 @@ describe Search::GlobalService do ...@@ -35,41 +35,118 @@ describe Search::GlobalService do
with_them do with_them do
it "respects visibility" do it "respects visibility" do
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level) update_feature_access_level(project, feature_access_level)
end
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'merge_requests', expected_count: expected_count) do |user| expect_search_results(user, 'merge_requests', expected_count: expected_count, pending: pending?) do |user|
described_class.new(user, search: merge_request.title).execute described_class.new(user, search: merge_request.title).execute
end end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(user, search: note.note).execute
end
end end
end end
end end
context 'code' do context 'code' do
let!(:project) { create(:project, project_level, :repository, namespace: group ) } let!(:project) { create(:project, project_level, :repository, namespace: group ) }
let!(:project2) { create(:project, project_level, :repository) } let!(:note) { create :note_on_commit, project: project }
let(:pendings) do
[
{ project_level: :public, feature_access_level: :private, membership: :guest, expected_count: 1 },
{ project_level: :internal, feature_access_level: :private, membership: :guest, expected_count: 1 }
]
end
where(:project_level, :feature_access_level, :membership, :expected_count) do where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access permission_table_for_guest_feature_access_and_non_private_project_only
end end
with_them do with_them do
it "respects visibility" do it "respects visibility" do
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level) update_feature_access_level(project, feature_access_level)
ElasticCommitIndexerWorker.new.perform(project.id) ElasticCommitIndexerWorker.new.perform(project.id)
end
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'commits', expected_count: expected_count) do |user| expect_search_results(user, 'commits', expected_count: expected_count, pending: pending?) do |user|
described_class.new(user, search: 'initial').execute described_class.new(user, search: 'initial').execute
end end
expect_search_results(user, 'blobs', expected_count: expected_count) do |user| expect_search_results(user, 'blobs', expected_count: expected_count) do |user|
described_class.new(user, search: '.gitmodules').execute described_class.new(user, search: '.gitmodules').execute
end end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(user, search: note.note).execute
end
end
end
end
context 'issue' do
let!(:issue) { create :issue, project: project }
let!(:note) { create :note, project: project, noteable: issue }
where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
update_feature_access_level(project, feature_access_level)
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'issues', expected_count: expected_count) do |user|
described_class.new(user, search: issue.title).execute
end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(user, search: note.note).execute
end
end
end
end
context 'wiki' do
let!(:project) { create(:project, project_level, :wiki_repo) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
project.wiki.create_page('test.md', '# term')
project.wiki.index_wiki_blobs
update_feature_access_level(project, feature_access_level)
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'wiki_blobs', expected_count: expected_count) do |user|
described_class.new(user, search: 'term').execute
end
end
end
end
context 'milestone' do
let!(:milestone) { create :milestone, project: project }
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :expected_count) do
permission_table_for_milestone_access
end
with_them do
it "respects visibility" do
project.update!(
'issues_access_level' => issues_access_level,
'merge_requests_access_level' => merge_requests_access_level
)
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'milestones', expected_count: expected_count) do |user|
described_class.new(user, search: milestone.title).execute
end
end end
end end
end end
......
...@@ -67,7 +67,7 @@ describe Search::GroupService, :elastic do ...@@ -67,7 +67,7 @@ describe Search::GroupService, :elastic do
end end
end end
context 'visibility' do context 'visibility', :sidekiq_inline do
include_context 'ProjectPolicyTable context' include_context 'ProjectPolicyTable context'
set(:group) { create(:group) } set(:group) { create(:group) }
...@@ -78,7 +78,14 @@ describe Search::GroupService, :elastic do ...@@ -78,7 +78,14 @@ describe Search::GroupService, :elastic do
context 'merge request' do context 'merge request' do
let!(:merge_request) { create :merge_request, target_project: project, source_project: project } let!(:merge_request) { create :merge_request, target_project: project, source_project: project }
let!(:merge_request2) { create :merge_request, target_project: project2, source_project: project2, title: merge_request.title } let!(:merge_request2) { create :merge_request, target_project: project2, source_project: project2, title: merge_request.title }
let!(:note) { create :note, project: project, noteable: merge_request }
let!(:note2) { create :note, project: project2, noteable: merge_request2, note: note.note }
let(:pendings) do
[
{ project_level: :public, feature_access_level: :enabled, membership: :guest, expected_count: 1 },
{ project_level: :internal, feature_access_level: :enabled, membership: :guest, expected_count: 1 }
]
end
where(:project_level, :feature_access_level, :membership, :expected_count) do where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_reporter_feature_access permission_table_for_reporter_feature_access
end end
...@@ -90,18 +97,31 @@ describe Search::GroupService, :elastic do ...@@ -90,18 +97,31 @@ describe Search::GroupService, :elastic do
end end
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'merge_requests', expected_count: expected_count) do |user| expect_search_results(user, 'merge_requests', expected_count: expected_count, pending: pending?) do |user|
described_class.new(user, group, search: merge_request.title).execute described_class.new(user, group, search: merge_request.title).execute
end end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(user, group, search: note.note).execute
end
end end
end end
end end
context 'code' do context 'code' do
let!(:project) { create(:project, project_level, :repository, namespace: group ) } let!(:project) { create(:project, project_level, :repository, namespace: group ) }
let!(:note) { create :note_on_commit, project: project }
let(:pendings) do
[
{ project_level: :public, feature_access_level: :enabled, membership: :guest, expected_count: 1 },
{ project_level: :public, feature_access_level: :private, membership: :guest, expected_count: 1 },
{ project_level: :internal, feature_access_level: :enabled, membership: :guest, expected_count: 1 },
{ project_level: :internal, feature_access_level: :private, membership: :guest, expected_count: 1 }
]
end
where(:project_level, :feature_access_level, :membership, :expected_count) do where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access permission_table_for_guest_feature_access_and_non_private_project_only
end end
with_them do with_them do
...@@ -113,13 +133,88 @@ describe Search::GroupService, :elastic do ...@@ -113,13 +133,88 @@ describe Search::GroupService, :elastic do
ElasticCommitIndexerWorker.new.perform(project.id) ElasticCommitIndexerWorker.new.perform(project.id)
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'commits', expected_count: expected_count) do |user| expect_search_results(user, 'commits', expected_count: expected_count, pending: pending?) do |user|
described_class.new(user, group, search: 'initial').execute described_class.new(user, group, search: 'initial').execute
end end
expect_search_results(user, 'blobs', expected_count: expected_count) do |user| expect_search_results(user, 'blobs', expected_count: expected_count, pending: pending?) do |user|
described_class.new(user, group, search: '.gitmodules').execute described_class.new(user, group, search: '.gitmodules').execute
end end
expect_search_results(user, 'notes', expected_count: expected_count, pending: pending?) do |user|
described_class.new(user, group, search: note.note).execute
end
end
end
end
context 'issue' do
let!(:issue) { create :issue, project: project }
let!(:issue2) { create :issue, project: project2, title: issue.title }
let!(:note) { create :note, project: project, noteable: issue }
let!(:note2) { create :note, project: project2, noteable: issue2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
end
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'issues', expected_count: expected_count) do |user|
described_class.new(user, group, search: issue.title).execute
end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(user, group, search: note.note).execute
end
end
end
end
context 'wiki' do
let!(:project) { create(:project, project_level, :wiki_repo) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
project.wiki.create_page('test.md', '# term')
project.wiki.index_wiki_blobs
update_feature_access_level(project, feature_access_level)
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'wiki_blobs', expected_count: expected_count) do |user|
described_class.new(user, project.namespace, search: 'term').execute
end
end
end
end
context 'milestone' do
let!(:milestone) { create :milestone, project: project }
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :expected_count) do
permission_table_for_milestone_access
end
with_them do
it "respects visibility" do
project.update!(
'issues_access_level' => issues_access_level,
'merge_requests_access_level' => merge_requests_access_level
)
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'milestones', expected_count: expected_count) do |user|
described_class.new(user, group, search: milestone.title).execute
end
end end
end end
end end
......
...@@ -17,7 +17,7 @@ describe Search::ProjectService do ...@@ -17,7 +17,7 @@ describe Search::ProjectService do
let(:service) { described_class.new(scope, user, params) } let(:service) { described_class.new(scope, user, params) }
end end
context 'visibility', :elastic do context 'visibility', :elastic, :sidekiq_inline do
include_context 'ProjectPolicyTable context' include_context 'ProjectPolicyTable context'
set(:group) { create(:group) } set(:group) { create(:group) }
...@@ -28,6 +28,14 @@ describe Search::ProjectService do ...@@ -28,6 +28,14 @@ describe Search::ProjectService do
context 'merge request' do context 'merge request' do
let!(:merge_request) { create :merge_request, target_project: project, source_project: project } let!(:merge_request) { create :merge_request, target_project: project, source_project: project }
let!(:merge_request2) { create :merge_request, target_project: project2, source_project: project2, title: merge_request.title } let!(:merge_request2) { create :merge_request, target_project: project2, source_project: project2, title: merge_request.title }
let!(:note) { create :note, project: project, noteable: merge_request }
let!(:note2) { create :note, project: project2, noteable: merge_request2, note: note.note }
let(:pendings) do
[
{ project_level: :public, feature_access_level: :enabled, membership: :guest, expected_count: 1 },
{ project_level: :internal, feature_access_level: :enabled, membership: :guest, expected_count: 1 }
]
end
where(:project_level, :feature_access_level, :membership, :expected_count) do where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_reporter_feature_access permission_table_for_reporter_feature_access
...@@ -40,9 +48,13 @@ describe Search::ProjectService do ...@@ -40,9 +48,13 @@ describe Search::ProjectService do
end end
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'merge_requests', expected_count: expected_count) do |user| expect_search_results(user, 'merge_requests', expected_count: expected_count, pending: pending?) do |user|
described_class.new(project, user, search: merge_request.title).execute described_class.new(project, user, search: merge_request.title).execute
end end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(project, user, search: note.note).execute
end
end end
end end
end end
...@@ -50,9 +62,11 @@ describe Search::ProjectService do ...@@ -50,9 +62,11 @@ describe Search::ProjectService do
context 'code' do context 'code' do
let!(:project) { create(:project, project_level, :repository, namespace: group ) } let!(:project) { create(:project, project_level, :repository, namespace: group ) }
let!(:project2) { create(:project, project_level, :repository) } let!(:project2) { create(:project, project_level, :repository) }
let!(:note) { create :note_on_commit, project: project }
let!(:note2) { create :note_on_commit, project: project2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access permission_table_for_guest_feature_access_and_non_private_project_only
end end
with_them do with_them do
...@@ -63,13 +77,88 @@ describe Search::ProjectService do ...@@ -63,13 +77,88 @@ describe Search::ProjectService do
end end
Gitlab::Elastic::Helper.refresh_index Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'commits', expected_count: expected_count) do |user| expect_search_results(user, 'commits', expected_count: expected_count, pending: pending?) do |user|
described_class.new(project, user, search: 'initial').execute described_class.new(project, user, search: 'initial').execute
end end
expect_search_results(user, 'blobs', expected_count: expected_count) do |user| expect_search_results(user, 'blobs', expected_count: expected_count) do |user|
described_class.new(project, user, search: '.gitmodules').execute described_class.new(project, user, search: '.gitmodules').execute
end end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(project, user, search: note.note).execute
end
end
end
end
context 'issue' do
let!(:issue) { create :issue, project: project }
let!(:issue2) { create :issue, project: project2, title: issue.title }
let!(:note) { create :note, project: project, noteable: issue }
let!(:note2) { create :note, project: project2, noteable: issue2, note: note.note }
where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
[project, project2].each do |project|
update_feature_access_level(project, feature_access_level)
end
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'issues', expected_count: expected_count) do |user|
described_class.new(project, user, search: issue.title).execute
end
expect_search_results(user, 'notes', expected_count: expected_count) do |user|
described_class.new(project, user, search: note.note).execute
end
end
end
end
context 'wiki' do
let!(:project) { create(:project, project_level, :wiki_repo) }
where(:project_level, :feature_access_level, :membership, :expected_count) do
permission_table_for_guest_feature_access
end
with_them do
it "respects visibility" do
project.wiki.create_page('test.md', '# term')
project.wiki.index_wiki_blobs
update_feature_access_level(project, feature_access_level)
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'wiki_blobs', expected_count: expected_count) do |user|
described_class.new(project, user, search: 'term').execute
end
end
end
end
context 'milestone' do
let!(:milestone) { create :milestone, project: project }
where(:project_level, :issues_access_level, :merge_requests_access_level, :membership, :expected_count) do
permission_table_for_milestone_access
end
with_them do
it "respects visibility" do
project.update!(
'issues_access_level' => issues_access_level,
'merge_requests_access_level' => merge_requests_access_level
)
Gitlab::Elastic::Helper.refresh_index
expect_search_results(user, 'milestones', expected_count: expected_count) do |user|
described_class.new(project, user, search: milestone.title).execute
end
end end
end end
end end
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
module SearchResultHelpers module SearchResultHelpers
# @param target [Symbol] search target, e.g. "merge_requests", "blobs" # @param target [Symbol] search target, e.g. "merge_requests", "blobs"
def expect_search_results(users, target, expected_count: nil, expected_objects: nil) def expect_search_results(users, target, expected_count: nil, expected_objects: nil, pending: false)
# TODO: https://gitlab.com/gitlab-org/gitlab/issues/32645 # TODO: https://gitlab.com/gitlab-org/gitlab/issues/32645
return if expected_count && expected_count > 0 pending("https://gitlab.com/gitlab-org/gitlab/issues/32645") if pending
users = Array(users) users = Array(users)
target = target.to_s target = target.to_s
...@@ -17,7 +17,7 @@ module SearchResultHelpers ...@@ -17,7 +17,7 @@ module SearchResultHelpers
if expected_count if expected_count
actual_count = results.public_send("#{target}_count") actual_count = results.public_send("#{target}_count")
expect(actual_count).to eq(expected_count), "expected count to be #{expected_count} for #{user_name}, got #{actual_count}" expect(actual_count).to eq(expected_count), "#{target} expected count to be #{expected_count} for #{user_name}, got #{actual_count}"
end end
if expected_objects if expected_objects
......
...@@ -16,10 +16,10 @@ module ProjectHelpers ...@@ -16,10 +16,10 @@ module ProjectHelpers
end end
def update_feature_access_level(project, access_level) def update_feature_access_level(project, access_level)
project.update!( features = ProjectFeature::FEATURES.dup
repository_access_level: access_level, features.delete(:pages)
merge_requests_access_level: access_level, params = features.each_with_object({}) { |feature, h| h["#{feature}_access_level"] = access_level }
builds_access_level: access_level
) project.update!(params)
end end
end end
...@@ -3,7 +3,20 @@ ...@@ -3,7 +3,20 @@
RSpec.shared_context 'ProjectPolicyTable context' do RSpec.shared_context 'ProjectPolicyTable context' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
let(:pendings) { {} }
let(:pending?) do
pendings.include?(
{
project_level: project_level,
feature_access_level: feature_access_level,
membership: membership,
expected_count: expected_count
}
)
end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize
# project_level, :feature_access_level, :membership, :expected_count
def permission_table_for_reporter_feature_access def permission_table_for_reporter_feature_access
:public | :enabled | :reporter | 1 :public | :enabled | :reporter | 1
:public | :enabled | :guest | 1 :public | :enabled | :guest | 1
...@@ -35,11 +48,6 @@ RSpec.shared_context 'ProjectPolicyTable context' do ...@@ -35,11 +48,6 @@ RSpec.shared_context 'ProjectPolicyTable context' do
:internal | :disabled | :non_member | 0 :internal | :disabled | :non_member | 0
:internal | :disabled | :anonymous | 0 :internal | :disabled | :anonymous | 0
:private | :enabled | :reporter | 1
:private | :enabled | :guest | 1
:private | :enabled | :non_member | 0
:private | :enabled | :anonymous | 0
:private | :private | :reporter | 1 :private | :private | :reporter | 1
:private | :private | :guest | 0 :private | :private | :guest | 0
:private | :private | :non_member | 0 :private | :private | :non_member | 0
...@@ -51,6 +59,7 @@ RSpec.shared_context 'ProjectPolicyTable context' do ...@@ -51,6 +59,7 @@ RSpec.shared_context 'ProjectPolicyTable context' do
:private | :disabled | :anonymous | 0 :private | :disabled | :anonymous | 0
end end
# project_level, :feature_access_level, :membership, :expected_count
def permission_table_for_guest_feature_access def permission_table_for_guest_feature_access
:public | :enabled | :reporter | 1 :public | :enabled | :reporter | 1
:public | :enabled | :guest | 1 :public | :enabled | :guest | 1
...@@ -82,11 +91,6 @@ RSpec.shared_context 'ProjectPolicyTable context' do ...@@ -82,11 +91,6 @@ RSpec.shared_context 'ProjectPolicyTable context' do
:internal | :disabled | :non_member | 0 :internal | :disabled | :non_member | 0
:internal | :disabled | :anonymous | 0 :internal | :disabled | :anonymous | 0
:private | :enabled | :reporter | 1
:private | :enabled | :guest | 1
:private | :enabled | :non_member | 0
:private | :enabled | :anonymous | 0
:private | :private | :reporter | 1 :private | :private | :reporter | 1
:private | :private | :guest | 1 :private | :private | :guest | 1
:private | :private | :non_member | 0 :private | :private | :non_member | 0
...@@ -98,6 +102,172 @@ RSpec.shared_context 'ProjectPolicyTable context' do ...@@ -98,6 +102,172 @@ RSpec.shared_context 'ProjectPolicyTable context' do
:private | :disabled | :anonymous | 0 :private | :disabled | :anonymous | 0
end end
# This table is based on permission_table_for_guest_feature_access,
# but with a slight twist.
# Some features can be hidden away to GUEST, when project is private.
# (see ProjectFeature::PRIVATE_FEATURES_MIN_ACCESS_LEVEL_FOR_PRIVATE_PROJECT)
# This is the table for such features.
#
# e.g. `repository` feature has minimum requirement of GUEST,
# but a GUEST are prohibited from reading code if project is private.
#
# project_level, :feature_access_level, :membership, :expected_count
def permission_table_for_guest_feature_access_and_non_private_project_only
:public | :enabled | :reporter | 1
:public | :enabled | :guest | 1
:public | :enabled | :non_member | 1
:public | :enabled | :anonymous | 1
:public | :private | :reporter | 1
:public | :private | :guest | 1
:public | :private | :non_member | 0
:public | :private | :anonymous | 0
:public | :disabled | :reporter | 0
:public | :disabled | :guest | 0
:public | :disabled | :non_member | 0
:public | :disabled | :anonymous | 0
:internal | :enabled | :reporter | 1
:internal | :enabled | :guest | 1
:internal | :enabled | :non_member | 1
:internal | :enabled | :anonymous | 0
:internal | :private | :reporter | 1
:internal | :private | :guest | 1
:internal | :private | :non_member | 0
:internal | :private | :anonymous | 0
:internal | :disabled | :reporter | 0
:internal | :disabled | :guest | 0
:internal | :disabled | :non_member | 0
:internal | :disabled | :anonymous | 0
:private | :private | :reporter | 1
:private | :private | :guest | 0
:private | :private | :non_member | 0
:private | :private | :anonymous | 0
:private | :disabled | :reporter | 0
:private | :disabled | :guest | 0
:private | :disabled | :non_member | 0
:private | :disabled | :anonymous | 0
end
# :project_level, :issues_access_level, :merge_requests_access_level, :membership, :expected_count
def permission_table_for_milestone_access
:public | :enabled | :enabled | :reporter | 1
:public | :enabled | :enabled | :guest | 1
:public | :enabled | :enabled | :non_member | 1
:public | :enabled | :enabled | :anonymous | 1
:public | :enabled | :private | :reporter | 1
:public | :enabled | :private | :guest | 1
:public | :enabled | :private | :non_member | 1
:public | :enabled | :private | :anonymous | 1
:public | :enabled | :disabled | :reporter | 1
:public | :enabled | :disabled | :guest | 1
:public | :enabled | :disabled | :non_member | 1
:public | :enabled | :disabled | :anonymous | 1
:public | :private | :enabled | :reporter | 1
:public | :private | :enabled | :guest | 1
:public | :private | :enabled | :non_member | 1
:public | :private | :enabled | :anonymous | 1
:public | :private | :private | :reporter | 1
:public | :private | :private | :guest | 1
:public | :private | :private | :non_member | 0
:public | :private | :private | :anonymous | 0
:public | :private | :disabled | :reporter | 1
:public | :private | :disabled | :guest | 1
:public | :private | :disabled | :non_member | 0
:public | :private | :disabled | :anonymous | 0
:public | :disabled | :enabled | :reporter | 1
:public | :disabled | :enabled | :guest | 1
:public | :disabled | :enabled | :non_member | 1
:public | :disabled | :enabled | :anonymous | 1
:public | :disabled | :private | :reporter | 1
:public | :disabled | :private | :guest | 0
:public | :disabled | :private | :non_member | 0
:public | :disabled | :private | :anonymous | 0
:public | :disabled | :disabled | :reporter | 0
:public | :disabled | :disabled | :guest | 0
:public | :disabled | :disabled | :non_member | 0
:public | :disabled | :disabled | :anonymous | 0
:internal | :enabled | :enabled | :reporter | 1
:internal | :enabled | :enabled | :guest | 1
:internal | :enabled | :enabled | :non_member | 1
:internal | :enabled | :enabled | :anonymous | 0
:internal | :enabled | :private | :reporter | 1
:internal | :enabled | :private | :guest | 1
:internal | :enabled | :private | :non_member | 1
:internal | :enabled | :private | :anonymous | 0
:internal | :enabled | :disabled | :reporter | 1
:internal | :enabled | :disabled | :guest | 1
:internal | :enabled | :disabled | :non_member | 1
:internal | :enabled | :disabled | :anonymous | 0
:internal | :private | :enabled | :reporter | 1
:internal | :private | :enabled | :guest | 1
:internal | :private | :enabled | :non_member | 1
:internal | :private | :enabled | :anonymous | 0
:internal | :private | :private | :reporter | 1
:internal | :private | :private | :guest | 1
:internal | :private | :private | :non_member | 0
:internal | :private | :private | :anonymous | 0
:internal | :private | :disabled | :reporter | 1
:internal | :private | :disabled | :guest | 1
:internal | :private | :disabled | :non_member | 0
:internal | :private | :disabled | :anonymous | 0
:internal | :disabled | :enabled | :reporter | 1
:internal | :disabled | :enabled | :guest | 1
:internal | :disabled | :enabled | :non_member | 1
:internal | :disabled | :enabled | :anonymous | 0
:internal | :disabled | :private | :reporter | 1
:internal | :disabled | :private | :guest | 0
:internal | :disabled | :private | :non_member | 0
:internal | :disabled | :private | :anonymous | 0
:internal | :disabled | :disabled | :reporter | 0
:internal | :disabled | :disabled | :guest | 0
:internal | :disabled | :disabled | :non_member | 0
:internal | :disabled | :disabled | :anonymous | 0
:private | :private | :private | :reporter | 1
:private | :private | :private | :guest | 1
:private | :private | :private | :non_member | 0
:private | :private | :private | :anonymous | 0
:private | :private | :disabled | :reporter | 1
:private | :private | :disabled | :guest | 1
:private | :private | :disabled | :non_member | 0
:private | :private | :disabled | :anonymous | 0
:private | :disabled | :private | :reporter | 1
:private | :disabled | :private | :guest | 0
:private | :disabled | :private | :non_member | 0
:private | :disabled | :private | :anonymous | 0
:private | :disabled | :disabled | :reporter | 0
:private | :disabled | :disabled | :guest | 0
:private | :disabled | :disabled | :non_member | 0
:private | :disabled | :disabled | :anonymous | 0
end
# :project_level, :membership, :expected_count
def permission_table_for_project_access def permission_table_for_project_access
:public | :reporter | 1 :public | :reporter | 1
:public | :guest | 1 :public | :guest | 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment