Fix RfC Visibility to work as intended

The RfC Visibility of a consumer is intended to restrict who can access which RfCs. So far, those restrictions were only applied one way, for learners of a restricted consumer to view other (external) RfCs. However, the other way around should also work: If a RfC was created as part of a restricted consumer, no other external user should be able to interfere with this RfC. This commit, therefore, adds this direction as well and covers both directions with tests.
This commit is contained in:
Sebastian Serth
2023-07-13 10:51:10 +02:00
parent c6977b6319
commit e097036296
3 changed files with 207 additions and 99 deletions

View File

@ -6,7 +6,7 @@ class RequestForCommentPolicy < ApplicationPolicy
end
def show?
admin? || rfc_visibility
admin? || author? || rfc_visibility
end
def destroy?
@ -14,11 +14,11 @@ class RequestForCommentPolicy < ApplicationPolicy
end
def mark_as_solved?
admin? || (author? && rfc_visibility)
admin? || author?
end
def set_thank_you_note?
admin? || (author? && rfc_visibility)
admin? || author?
end
def clear_question?
@ -42,12 +42,16 @@ class RequestForCommentPolicy < ApplicationPolicy
end
def rfc_visibility
case @user.consumer.rfc_visibility
when 'all'
# The consumer with the most restricted visibility determines the visibility of the RfC
case [@user.consumer.rfc_visibility, @record.author.consumer.rfc_visibility]
# Only if both consumers allow learners to see all RfCs, the RfC is visible to the learner
when %w[all all]
everyone
when 'consumer'
# At least one consumer limits the visibility to the consumer
when %w[consumer all], %w[all consumer], %w[consumer consumer]
@record.author.consumer == @user.consumer
when 'study_group'
# At least one consumer limits the visibility to the study group
when %w[study_group all], %w[all study_group], %w[study_group consumer], %w[consumer study_group], %w[study_group study_group]
@record.submission.study_group.present? && @record.submission.study_group.id == @user.current_study_group_id
else
raise "Unknown RfC Visibility #{current_user.consumer.rfc_visibility}"
@ -61,8 +65,16 @@ class RequestForCommentPolicy < ApplicationPolicy
else
case @user.consumer.rfc_visibility
when 'all'
@scope.all
# We need to filter those RfCs where the visibility is more restricted than the `all` visibility.
rfcs_with_users = @scope
.joins('LEFT OUTER JOIN external_users ON request_for_comments.user_type = \'ExternalUser\' AND request_for_comments.user_id = external_users.id')
.joins('LEFT OUTER JOIN internal_users ON request_for_comments.user_type = \'InternalUser\' AND request_for_comments.user_id = internal_users.id')
rfcs_with_users.where(external_users: {consumer_id: Consumer.rfc_visibility_all})
.or(rfcs_with_users.where(internal_users: {consumer_id: Consumer.rfc_visibility_all}))
when 'consumer'
# Since the `rfc_visibility` is set on a consumer level, we do not need to consider the `study_group` visibility here.
# Therefore, those RfCs where the author is limited to study group RfCs definitely belong to another consumer.
rfcs_with_users = @scope
.joins('LEFT OUTER JOIN external_users ON request_for_comments.user_type = \'ExternalUser\' AND request_for_comments.user_id = external_users.id')
.joins('LEFT OUTER JOIN internal_users ON request_for_comments.user_type = \'InternalUser\' AND request_for_comments.user_id = internal_users.id')
@ -70,6 +82,7 @@ class RequestForCommentPolicy < ApplicationPolicy
rfcs_with_users.where(external_users: {consumer_id: @user.consumer.id})
.or(rfcs_with_users.where(internal_users: {consumer_id: @user.consumer.id}))
when 'study_group'
# Since the `rfc_visibility` is already the most restricted visibility, we do not need to consider any other visibility here.
@scope
.joins(:submission)
.where(submission: {study_group: @user.current_study_group_id})