Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions app/models/abuse_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,17 @@ def akismet_attributes

scope :by_date, -> { order('created_at DESC') }

# Standardize the format of work, chapter, comment, profile and bookmark URLs
# Standardize the format of work, chapter, comment, profile, bookmark and series URLs
# to get it ready for the url_is_not_over_reported validation.
# Work URLs: "works/123"
# Chapter URLs: "chapters/123"
# Comment URLs: "comments/123"
# Profile URLs: "users/username"
# Bookmark URLs: "bookmarks/123"
# Series URLs: "series/123"
before_validation :standardize_url, on: :create
def standardize_url
return unless url =~ %r{((chapters|works|comments|bookmarks)/\d+)} || url =~ %r{(users/\w+)}
return unless url =~ %r{((chapters|works|comments|bookmarks|series)/\d+)} || url =~ %r{(users/\w+)}

self.url = add_scheme_to_url(url)
self.url = clean_url(url)
Expand Down Expand Up @@ -248,6 +249,14 @@ def url_is_not_over_reported
user_report_period,
"%#{user_params_only}%").count
errors.add(:base, :over_reported) if existing_reports_total >= ArchiveConfig.ABUSE_REPORTS_PER_USER_MAX
when %r{/series/\d+}
series_params_only = url.match(%r{/series/\d+/}).to_s
series_report_period = ArchiveConfig.ABUSE_REPORTS_PER_SERIES_PERIOD.days.ago
existing_reports_total = AbuseReport.where('created_at > ? AND
url LIKE ?',
series_report_period,
"%#{series_params_only}%").count
errors.add(:base, :over_reported_series) if existing_reports_total >= ArchiveConfig.ABUSE_REPORTS_PER_SERIES_MAX
end
end

Expand Down
4 changes: 4 additions & 0 deletions config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ ABUSE_REPORTS_PER_WORK_PERIOD: 31
ABUSE_REPORTS_PER_COMMENT_MAX: 3
# time period, in days, used to total number of reports for a given comment URL
ABUSE_REPORTS_PER_COMMENT_PERIOD: 30
# max number of abuse reports to accept for a given series URL
ABUSE_REPORTS_PER_SERIES_MAX: 3
# time period, in days, used to total number of reports for a given series URL
ABUSE_REPORTS_PER_SERIES_PERIOD: 30
# max number of abuse reports to accept for a given bookmark URL
ABUSE_REPORTS_PER_BOOKMARK_MAX: 3
# time period, in days, used to total number of reports for a given bookmark URL
Expand Down
1 change: 1 addition & 0 deletions config/locales/models/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ en:
over_reported: This page has already been reported. Our volunteers only need one report in order to investigate and resolve an issue, so please be patient and do not submit another report.
over_reported_bookmark: This bookmark has already been reported. Our volunteers only need one report in order to investigate and resolve an issue, so please be patient and do not submit another report.
over_reported_comment: This comment has already been reported. Our volunteers only need one report in order to investigate and resolve an issue, so please be patient and do not submit another report.
over_reported_series: This series has already been reported. Our volunteers only need one report in order to investigate and resolve an issue, so please be patient and do not submit another report.
url:
not_on_archive: does not appear to be on this site.
admin_post:
Expand Down
48 changes: 48 additions & 0 deletions spec/models/abuse_report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@
end
end

shared_examples "enough series reports" do |url|
let(:report) { build(:abuse_report, url: url) }
it "can't be submitted" do
expect(report.save).to be_falsey
expect(report.errors[:base].first).to include("This series has already been reported")
end
end

shared_examples "enough bookmark reports" do |url|
let(:report) { build(:abuse_report, url: url) }
it "can't be submitted" do
Expand Down Expand Up @@ -287,6 +295,46 @@
end
end

context "for a series reported the maximum number of times" do
series_url = "http://archiveofourown.org/series/567"

before do
ArchiveConfig.ABUSE_REPORTS_PER_SERIES_MAX.times do
create(:abuse_report, url: series_url)
end
expect(AbuseReport.count).to eq(ArchiveConfig.ABUSE_REPORTS_PER_SERIES_MAX)
end

# obviously
it_behaves_like "enough series reports", series_url

# the same series, different protocol
it_behaves_like "enough series reports", "https://archiveofourown.org/series/567"

# the same series, with parameters/anchors
it_behaves_like "enough series reports", "http://archiveofourown.org/series/567?smut=yes"
it_behaves_like "enough series reports", "http://archiveofourown.org/series/567#timeline"
it_behaves_like "enough series reports", "http://archiveofourown.org/series/567?smut=yes#timeline"
it_behaves_like "enough series reports", "http://archiveofourown.org/series/567/?smut=yes"
it_behaves_like "enough series reports", "http://archiveofourown.org/series/567/#timeline"
it_behaves_like "enough series reports", "http://archiveofourown.org/series/567/?smut=yes#timeline"

# not the same series
it_behaves_like "alright", "http://archiveofourown.org/series/67"
it_behaves_like "alright", "http://archiveofourown.org/series/1"

# unrelated
it_behaves_like "alright", "http://archiveofourown.org/someone/series"
it_behaves_like "alright", "http://archiveofourown.org/works/876/comments"
it_behaves_like "alright", "http://archiveofourown.org/users/someone"

context "after the over-reporting period" do
before { travel(ArchiveConfig.ABUSE_REPORTS_PER_SERIES_PERIOD.days) }

it_behaves_like "alright", series_url
end
end

context "when reporting work URLs that cross the reporting period timeframe" do
work_url = "http://archiveofourown.org/works/790"

Expand Down
Loading