diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/ci/build.rb | 2 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 16 | ||||
-rw-r--r-- | app/models/concerns/protected_branch_access.rb | 7 | ||||
-rw-r--r-- | app/models/concerns/spammable.rb | 52 | ||||
-rw-r--r-- | app/models/hooks/project_hook.rb | 1 | ||||
-rw-r--r-- | app/models/hooks/web_hook.rb | 1 | ||||
-rw-r--r-- | app/models/issue.rb | 8 | ||||
-rw-r--r-- | app/models/project.rb | 2 | ||||
-rw-r--r-- | app/models/project_services/builds_email_service.rb | 3 | ||||
-rw-r--r-- | app/models/protected_branch.rb | 11 | ||||
-rw-r--r-- | app/models/protected_branch/merge_access_level.rb | 6 | ||||
-rw-r--r-- | app/models/protected_branch/push_access_level.rb | 6 | ||||
-rw-r--r-- | app/models/service.rb | 7 | ||||
-rw-r--r-- | app/models/spam_log.rb | 4 | ||||
-rw-r--r-- | app/models/user.rb | 7 | ||||
-rw-r--r-- | app/models/user_agent_detail.rb | 9 |
16 files changed, 126 insertions, 16 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 3d6c6ea3209..4c84f4c21c5 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -344,7 +344,7 @@ module Ci def execute_hooks return unless project - build_data = Gitlab::BuildDataBuilder.build(self) + build_data = Gitlab::DataBuilder::Build.build(self) project.execute_hooks(build_data.dup, :build_hooks) project.execute_services(build_data.dup, :build_hooks) project.running_or_pending_build_count(force: true) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 8cfba92ae9b..130afeb724e 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -19,6 +19,8 @@ module Ci after_save :keep_around_commits + delegate :stages, to: :statuses + state_machine :status, initial: :created do event :enqueue do transition created: :pending @@ -56,6 +58,10 @@ module Ci before_transition do |pipeline| pipeline.update_duration end + + after_transition do |pipeline, transition| + pipeline.execute_hooks unless transition.loopback? + end end # ref can't be HEAD or SHA, can only be branch/tag name @@ -243,8 +249,18 @@ module Ci self.duration = statuses.latest.duration end + def execute_hooks + data = pipeline_data + project.execute_hooks(data, :pipeline_hooks) + project.execute_services(data, :pipeline_hooks) + end + private + def pipeline_data + Gitlab::DataBuilder::Pipeline.build(self) + end + def latest_builds_status return 'failed' unless yaml_errors.blank? diff --git a/app/models/concerns/protected_branch_access.rb b/app/models/concerns/protected_branch_access.rb new file mode 100644 index 00000000000..5a7b36070e7 --- /dev/null +++ b/app/models/concerns/protected_branch_access.rb @@ -0,0 +1,7 @@ +module ProtectedBranchAccess + extend ActiveSupport::Concern + + def humanize + self.class.human_access_levels[self.access_level] + end +end diff --git a/app/models/concerns/spammable.rb b/app/models/concerns/spammable.rb index 3b8e6df2da9..ce54fe5d3bf 100644 --- a/app/models/concerns/spammable.rb +++ b/app/models/concerns/spammable.rb @@ -1,9 +1,32 @@ module Spammable extend ActiveSupport::Concern + module ClassMethods + def attr_spammable(attr, options = {}) + spammable_attrs << [attr.to_s, options] + end + end + included do + has_one :user_agent_detail, as: :subject, dependent: :destroy + attr_accessor :spam + after_validation :check_for_spam, on: :create + + cattr_accessor :spammable_attrs, instance_accessor: false do + [] + end + + delegate :ip_address, :user_agent, to: :user_agent_detail, allow_nil: true + end + + def submittable_as_spam? + if user_agent_detail + user_agent_detail.submittable? + else + false + end end def spam? @@ -13,4 +36,33 @@ module Spammable def check_for_spam self.errors.add(:base, "Your #{self.class.name.underscore} has been recognized as spam and has been discarded.") if spam? end + + def spam_title + attr = self.class.spammable_attrs.find do |_, options| + options.fetch(:spam_title, false) + end + + public_send(attr.first) if attr && respond_to?(attr.first.to_sym) + end + + def spam_description + attr = self.class.spammable_attrs.find do |_, options| + options.fetch(:spam_description, false) + end + + public_send(attr.first) if attr && respond_to?(attr.first.to_sym) + end + + def spammable_text + result = self.class.spammable_attrs.map do |attr| + public_send(attr.first) + end + + result.reject(&:blank?).join("\n") + end + + # Override in Spammable if further checks are necessary + def check_for_spam? + true + end end diff --git a/app/models/hooks/project_hook.rb b/app/models/hooks/project_hook.rb index ba42a8eeb70..836a75b0608 100644 --- a/app/models/hooks/project_hook.rb +++ b/app/models/hooks/project_hook.rb @@ -5,5 +5,6 @@ class ProjectHook < WebHook scope :note_hooks, -> { where(note_events: true) } scope :merge_request_hooks, -> { where(merge_requests_events: true) } scope :build_hooks, -> { where(build_events: true) } + scope :pipeline_hooks, -> { where(pipeline_events: true) } scope :wiki_page_hooks, -> { where(wiki_page_events: true) } end diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb index 8b87b6c3d64..f365dee3141 100644 --- a/app/models/hooks/web_hook.rb +++ b/app/models/hooks/web_hook.rb @@ -8,6 +8,7 @@ class WebHook < ActiveRecord::Base default_value_for :merge_requests_events, false default_value_for :tag_push_events, false default_value_for :build_events, false + default_value_for :pipeline_events, false default_value_for :enable_ssl_verification, true scope :push_hooks, -> { where(push_events: true) } diff --git a/app/models/issue.rb b/app/models/issue.rb index d62ffb21467..788611305fe 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -36,6 +36,9 @@ class Issue < ActiveRecord::Base scope :order_due_date_asc, -> { reorder('issues.due_date IS NULL, issues.due_date ASC') } scope :order_due_date_desc, -> { reorder('issues.due_date IS NULL, issues.due_date DESC') } + attr_spammable :title, spam_title: true + attr_spammable :description, spam_description: true + state_machine :state, initial: :opened do event :close do transition [:reopened, :opened] => :closed @@ -262,4 +265,9 @@ class Issue < ActiveRecord::Base def overdue? due_date.try(:past?) || false end + + # Only issues on public projects should be checked for spam + def check_for_spam? + project.public? + end end diff --git a/app/models/project.rb b/app/models/project.rb index e0b28160937..eefdae35615 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -197,6 +197,8 @@ class Project < ActiveRecord::Base scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') } scope :abandoned, -> { where('projects.last_activity_at < ?', 6.months.ago) } + scope :excluding_project, ->(project) { where.not(id: project) } + state_machine :import_status, initial: :none do event :import_start do transition [:none, :finished] => :started diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb index 5e166471077..fa66e5864b8 100644 --- a/app/models/project_services/builds_email_service.rb +++ b/app/models/project_services/builds_email_service.rb @@ -51,8 +51,7 @@ class BuildsEmailService < Service end def test_data(project = nil, user = nil) - build = project.builds.last - Gitlab::BuildDataBuilder.build(build) + Gitlab::DataBuilder::Build.build(project.builds.last) end def fields diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb index 226b3f54342..6240912a6e1 100644 --- a/app/models/protected_branch.rb +++ b/app/models/protected_branch.rb @@ -5,11 +5,14 @@ class ProtectedBranch < ActiveRecord::Base validates :name, presence: true validates :project, presence: true - has_one :merge_access_level, dependent: :destroy - has_one :push_access_level, dependent: :destroy + has_many :merge_access_levels, dependent: :destroy + has_many :push_access_levels, dependent: :destroy - accepts_nested_attributes_for :push_access_level - accepts_nested_attributes_for :merge_access_level + validates_length_of :merge_access_levels, is: 1, message: "are restricted to a single instance per protected branch." + validates_length_of :push_access_levels, is: 1, message: "are restricted to a single instance per protected branch." + + accepts_nested_attributes_for :push_access_levels + accepts_nested_attributes_for :merge_access_levels def commit project.commit(self.name) diff --git a/app/models/protected_branch/merge_access_level.rb b/app/models/protected_branch/merge_access_level.rb index b1112ee737d..806b3ccd275 100644 --- a/app/models/protected_branch/merge_access_level.rb +++ b/app/models/protected_branch/merge_access_level.rb @@ -1,4 +1,6 @@ class ProtectedBranch::MergeAccessLevel < ActiveRecord::Base + include ProtectedBranchAccess + belongs_to :protected_branch delegate :project, to: :protected_branch @@ -17,8 +19,4 @@ class ProtectedBranch::MergeAccessLevel < ActiveRecord::Base project.team.max_member_access(user.id) >= access_level end - - def humanize - self.class.human_access_levels[self.access_level] - end end diff --git a/app/models/protected_branch/push_access_level.rb b/app/models/protected_branch/push_access_level.rb index 6a5e49cf453..92e9c51d883 100644 --- a/app/models/protected_branch/push_access_level.rb +++ b/app/models/protected_branch/push_access_level.rb @@ -1,4 +1,6 @@ class ProtectedBranch::PushAccessLevel < ActiveRecord::Base + include ProtectedBranchAccess + belongs_to :protected_branch delegate :project, to: :protected_branch @@ -20,8 +22,4 @@ class ProtectedBranch::PushAccessLevel < ActiveRecord::Base project.team.max_member_access(user.id) >= access_level end - - def humanize - self.class.human_access_levels[self.access_level] - end end diff --git a/app/models/service.rb b/app/models/service.rb index 40cd9b861f0..09b4717a523 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -36,6 +36,7 @@ class Service < ActiveRecord::Base scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) } scope :note_hooks, -> { where(note_events: true, active: true) } scope :build_hooks, -> { where(build_events: true, active: true) } + scope :pipeline_hooks, -> { where(pipeline_events: true, active: true) } scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) } scope :external_issue_trackers, -> { issue_trackers.active.without_defaults } @@ -79,13 +80,17 @@ class Service < ActiveRecord::Base end def test_data(project, user) - Gitlab::PushDataBuilder.build_sample(project, user) + Gitlab::DataBuilder::Push.build_sample(project, user) end def event_channel_names [] end + def event_names + supported_events.map { |event| "#{event}_events" } + end + def event_field(event) nil end diff --git a/app/models/spam_log.rb b/app/models/spam_log.rb index 12df68ef83b..3b8b9833565 100644 --- a/app/models/spam_log.rb +++ b/app/models/spam_log.rb @@ -7,4 +7,8 @@ class SpamLog < ActiveRecord::Base user.block user.destroy end + + def text + [title, description].join("\n") + end end diff --git a/app/models/user.rb b/app/models/user.rb index 87a2d999843..48e83ab7e56 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -429,6 +429,13 @@ class User < ActiveRecord::Base owned_groups.select(:id), namespace.id).joins(:namespace) end + # Returns projects which user can admin issues on (for example to move an issue to that project). + # + # This logic is duplicated from `Ability#project_abilities` into a SQL form. + def projects_where_can_admin_issues + authorized_projects(Gitlab::Access::REPORTER).non_archived.where.not(issues_enabled: false) + end + def is_admin? admin end diff --git a/app/models/user_agent_detail.rb b/app/models/user_agent_detail.rb new file mode 100644 index 00000000000..0949c6ef083 --- /dev/null +++ b/app/models/user_agent_detail.rb @@ -0,0 +1,9 @@ +class UserAgentDetail < ActiveRecord::Base + belongs_to :subject, polymorphic: true + + validates :user_agent, :ip_address, :subject_id, :subject_type, presence: true + + def submittable? + !submitted? + end +end |