summaryrefslogtreecommitdiff
path: root/app/models/event.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/event.rb')
-rw-r--r--app/models/event.rb194
1 files changed, 87 insertions, 107 deletions
diff --git a/app/models/event.rb b/app/models/event.rb
index 12b85697690..9c0fcbb354b 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -7,36 +7,31 @@ class Event < ApplicationRecord
include DeleteWithLimit
include CreatedAtFilterable
include Gitlab::Utils::StrongMemoize
+ include UsageStatistics
- default_scope { reorder(nil) }
-
- CREATED = 1
- UPDATED = 2
- CLOSED = 3
- REOPENED = 4
- PUSHED = 5
- COMMENTED = 6
- MERGED = 7
- JOINED = 8 # User joined project
- LEFT = 9 # User left project
- DESTROYED = 10
- EXPIRED = 11 # User left project due to expiry
+ default_scope { reorder(nil) } # rubocop:disable Cop/DefaultScope
ACTIONS = HashWithIndifferentAccess.new(
- created: CREATED,
- updated: UPDATED,
- closed: CLOSED,
- reopened: REOPENED,
- pushed: PUSHED,
- commented: COMMENTED,
- merged: MERGED,
- joined: JOINED,
- left: LEFT,
- destroyed: DESTROYED,
- expired: EXPIRED
+ created: 1,
+ updated: 2,
+ closed: 3,
+ reopened: 4,
+ pushed: 5,
+ commented: 6,
+ merged: 7,
+ joined: 8, # User joined project
+ left: 9, # User left project
+ destroyed: 10,
+ expired: 11, # User left project due to expiry
+ approved: 12,
+ archived: 13 # Recoverable deletion
).freeze
- WIKI_ACTIONS = [CREATED, UPDATED, DESTROYED].freeze
+ private_constant :ACTIONS
+
+ WIKI_ACTIONS = [:created, :updated, :destroyed].freeze
+
+ DESIGN_ACTIONS = [:created, :updated, :destroyed, :archived].freeze
TARGET_TYPES = HashWithIndifferentAccess.new(
issue: Issue,
@@ -46,16 +41,20 @@ class Event < ApplicationRecord
project: Project,
snippet: Snippet,
user: User,
- wiki: WikiPage::Meta
+ wiki: WikiPage::Meta,
+ design: DesignManagement::Design
).freeze
RESET_PROJECT_ACTIVITY_INTERVAL = 1.hour
REPOSITORY_UPDATED_AT_INTERVAL = 5.minutes
+ enum action: ACTIONS, _suffix: true
+
delegate :name, :email, :public_email, :username, to: :author, prefix: true, allow_nil: true
delegate :title, to: :issue, prefix: true, allow_nil: true
delegate :title, to: :merge_request, prefix: true, allow_nil: true
delegate :title, to: :note, prefix: true, allow_nil: true
+ delegate :title, to: :design, prefix: true, allow_nil: true
belongs_to :author, class_name: "User"
belongs_to :project
@@ -77,16 +76,16 @@ class Event < ApplicationRecord
# Callbacks
after_create :reset_project_activity
after_create :set_last_repository_updated_at, if: :push_action?
- after_create :track_user_interacted_projects
+ after_create ->(event) { UserInteractedProject.track(event) }
# Scopes
scope :recent, -> { reorder(id: :desc) }
- scope :code_push, -> { where(action: PUSHED) }
- scope :merged, -> { where(action: MERGED) }
scope :for_wiki_page, -> { where(target_type: 'WikiPage::Meta') }
+ scope :for_design, -> { where(target_type: 'DesignManagement::Design') }
# Needed to implement feature flag: can be removed when feature flag is removed
scope :not_wiki_page, -> { where('target_type IS NULL or target_type <> ?', 'WikiPage::Meta') }
+ scope :not_design, -> { where('target_type IS NULL or target_type <> ?', 'DesignManagement::Design') }
scope :with_associations, -> do
# We're using preload for "push_event_payload" as otherwise the association
@@ -105,6 +104,13 @@ class Event < ApplicationRecord
# should ensure the ID points to a valid user.
validates :author_id, presence: true
+ validates :action_enum_value,
+ if: :design?,
+ inclusion: {
+ in: actions.values_at(*DESIGN_ACTIONS),
+ message: ->(event, _data) { "#{event.action} is not a valid design action" }
+ }
+
self.inheritance_column = 'action'
class << self
@@ -113,7 +119,7 @@ class Event < ApplicationRecord
end
def find_sti_class(action)
- if action.to_i == PUSHED
+ if actions.fetch(action, action) == actions[:pushed] # action can be integer or symbol
PushEvent
else
Event
@@ -123,19 +129,15 @@ class Event < ApplicationRecord
# Update Gitlab::ContributionsCalendar#activity_dates if this changes
def contributions
where("action = ? OR (target_type IN (?) AND action IN (?)) OR (target_type = ? AND action = ?)",
- Event::PUSHED,
- %w(MergeRequest Issue), [Event::CREATED, Event::CLOSED, Event::MERGED],
- "Note", Event::COMMENTED)
+ actions[:pushed],
+ %w(MergeRequest Issue), [actions[:created], actions[:closed], actions[:merged]],
+ "Note", actions[:commented])
end
def limit_recent(limit = 20, offset = nil)
recent.limit(limit).offset(offset)
end
- def actions
- ACTIONS.keys
- end
-
def target_types
TARGET_TYPES.keys
end
@@ -148,7 +150,9 @@ class Event < ApplicationRecord
def visible_to_user?(user = nil)
return false unless capability.present?
- Ability.allowed?(user, capability, permission_object)
+ capability.all? do |rule|
+ Ability.allowed?(user, rule, permission_object)
+ end
end
def resource_parent
@@ -159,46 +163,10 @@ class Event < ApplicationRecord
target.try(:title)
end
- def created_action?
- action == CREATED
- end
-
def push_action?
false
end
- def merged_action?
- action == MERGED
- end
-
- def closed_action?
- action == CLOSED
- end
-
- def reopened_action?
- action == REOPENED
- end
-
- def joined_action?
- action == JOINED
- end
-
- def left_action?
- action == LEFT
- end
-
- def expired_action?
- action == EXPIRED
- end
-
- def destroyed_action?
- action == DESTROYED
- end
-
- def commented_action?
- action == COMMENTED
- end
-
def membership_changed?
joined_action? || left_action? || expired_action?
end
@@ -208,11 +176,11 @@ class Event < ApplicationRecord
end
def created_wiki_page?
- wiki_page? && action == CREATED
+ wiki_page? && created_action?
end
def updated_wiki_page?
- wiki_page? && action == UPDATED
+ wiki_page? && updated_action?
end
def created_target?
@@ -239,6 +207,10 @@ class Event < ApplicationRecord
target_type == 'WikiPage::Meta'
end
+ def design?
+ target_type == 'DesignManagement::Design'
+ end
+
def milestone
target if milestone?
end
@@ -247,6 +219,10 @@ class Event < ApplicationRecord
target if issue?
end
+ def design
+ target if design?
+ end
+
def merge_request
target if merge_request?
end
@@ -266,6 +242,8 @@ class Event < ApplicationRecord
def action_name
if push_action?
push_action_name
+ elsif design?
+ design_action_names[action.to_sym]
elsif closed_action?
"closed"
elsif merged_action?
@@ -386,34 +364,30 @@ class Event < ApplicationRecord
protected
- # rubocop:disable Metrics/CyclomaticComplexity
- # rubocop:disable Metrics/PerceivedComplexity
- #
- # TODO Refactor this method so we no longer need to disable the above cops
- # https://gitlab.com/gitlab-org/gitlab/-/issues/216879.
def capability
@capability ||= begin
- if push_action? || commit_note?
- :download_code
- elsif membership_changed? || created_project_action?
- :read_project
- elsif issue? || issue_note?
- :read_issue
- elsif merge_request? || merge_request_note?
- :read_merge_request
- elsif personal_snippet_note? || project_snippet_note?
- :read_snippet
- elsif milestone?
- :read_milestone
- elsif wiki_page?
- :read_wiki
- elsif design_note?
- :read_design
- end
- end
- end
- # rubocop:enable Metrics/CyclomaticComplexity
- # rubocop:enable Metrics/PerceivedComplexity
+ capabilities.flat_map do |ability, syms|
+ if syms.any? { |sym| send(sym) } # rubocop: disable GitlabSecurity/PublicSend
+ [ability]
+ else
+ []
+ end
+ end
+ end
+ end
+
+ def capabilities
+ {
+ download_code: %i[push_action? commit_note?],
+ read_project: %i[membership_changed? created_project_action?],
+ read_issue: %i[issue? issue_note?],
+ read_merge_request: %i[merge_request? merge_request_note?],
+ read_snippet: %i[personal_snippet_note? project_snippet_note?],
+ read_milestone: %i[milestone?],
+ read_wiki: %i[wiki_page?],
+ read_design: %i[design_note? design?]
+ }
+ end
private
@@ -455,11 +429,17 @@ class Event < ApplicationRecord
.update_all(last_repository_updated_at: created_at)
end
- def track_user_interacted_projects
- # Note the call to .available? is due to earlier migrations
- # that would otherwise conflict with the call to .track
- # (because the table does not exist yet).
- UserInteractedProject.track(self) if UserInteractedProject.available?
+ def design_action_names
+ {
+ created: _('uploaded'),
+ updated: _('revised'),
+ destroyed: _('deleted'),
+ archived: _('archived')
+ }
+ end
+
+ def action_enum_value
+ self.class.actions[action]
end
end