Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhttp://jneen.net/ <jneen@jneen.net>2017-07-26 18:43:27 +0300
committerhttp://jneen.net/ <jneen@jneen.net>2017-08-03 19:07:18 +0300
commit618a3d125c0faf3b6e0484bc9955ffd0a597ad33 (patch)
tree96763beaf00a0998374a50478e48a95830948b78 /app/models/notification_recipient.rb
parent618b5d34463b1a54cca0d47d3d815b7e388a1db2 (diff)
move Recipient to its own NotificationRecipient file
Diffstat (limited to 'app/models/notification_recipient.rb')
-rw-r--r--app/models/notification_recipient.rb102
1 files changed, 102 insertions, 0 deletions
diff --git a/app/models/notification_recipient.rb b/app/models/notification_recipient.rb
new file mode 100644
index 00000000000..0b2eee56ff8
--- /dev/null
+++ b/app/models/notification_recipient.rb
@@ -0,0 +1,102 @@
+class NotificationRecipient
+ attr_reader :user, :project, :type
+ def initialize(user, project, type,
+ custom_action: nil, target: nil, acting_user: nil, read_ability: nil)
+ @project = project
+ @custom_action = custom_action
+ @acting_user = acting_user
+ @read_ability = read_ability
+ @target = target
+ @user = user
+ @type = type
+ end
+
+ def notification_setting
+ @notification_setting ||= find_notification_setting
+ end
+
+ def raw_notification_level
+ notification_setting&.level&.to_sym
+ end
+
+ def notification_level
+ # custom is treated the same as watch if it's enabled - otherwise it's
+ # as :disabled.
+ @notification_level ||=
+ case raw_notification_level
+ when :custom
+ if @custom_action && notification_setting.event_enabled?(@custom_action)
+ :watch
+ else
+ :custom
+ end
+ else
+ raw_notification_level
+ end
+ end
+
+ def notifiable?
+ return false unless has_access?
+ return false if own_activity?
+
+ return true if @type == :subscription
+
+ return false if notification_level.nil? || notification_level == :disabled
+
+ return %i[participating mention].include?(@type) if notification_level == :custom
+
+ return false if %i[watch participating].include?(notification_level) && excluded_watcher_action?
+
+ return false unless NotificationSetting.levels[notification_level] <= NotificationSetting.levels[type]
+
+ return false if unsubscribed?
+
+ true
+ end
+
+ def unsubscribed?
+ return false unless @target
+ return false unless @target.respond_to?(:subscriptions)
+
+ subscription = @target.subscriptions.find_by_user_id(@user.id)
+ subscription && !subscription.subscribed
+ end
+
+ def own_activity?
+ return false unless @acting_user
+ return false if @acting_user.notified_of_own_activity?
+
+ user == @acting_user
+ end
+
+ def has_access?
+ return false unless user.can?(:receive_notifications)
+ return true unless @read_ability
+
+ DeclarativePolicy.subject_scope do
+ user.can?(@read_ability, @target)
+ end
+ end
+
+ def excluded_watcher_action?
+ return false unless @custom_action
+ return false if raw_notification_level == :custom
+
+ NotificationSetting::EXCLUDED_WATCHER_EVENTS.include?(@custom_action)
+ end
+
+ private
+
+ def find_notification_setting
+ project_setting = @project && user.notification_settings_for(@project)
+
+ return project_setting unless project_setting.nil? || project_setting.global?
+
+ group_setting = @project&.group && user.notification_settings_for(@project.group)
+
+ return group_setting unless group_setting.nil? || group_setting.global?
+
+ user.global_notification_setting
+ end
+end
+