diff options
-rw-r--r-- | app/controllers/admin_spam_addresses_controller.rb | 27 | ||||
-rw-r--r-- | app/mailers/request_mailer.rb | 2 | ||||
-rw-r--r-- | app/models/spam_address.rb | 11 | ||||
-rw-r--r-- | app/views/admin_request/_incoming_message_actions.html.erb | 7 | ||||
-rw-r--r-- | app/views/admin_spam_addresses/index.html.erb | 51 | ||||
-rw-r--r-- | app/views/layouts/admin.html.erb | 2 | ||||
-rw-r--r-- | app/views/layouts/default.html.erb | 2 | ||||
-rw-r--r-- | app/views/layouts/no_chrome.html.erb | 2 | ||||
-rw-r--r-- | config/routes.rb | 8 | ||||
-rw-r--r-- | db/migrate/20140325120619_create_spam_addresses.rb | 9 | ||||
-rw-r--r-- | spec/controllers/admin_spam_addresses_controller_spec.rb | 91 | ||||
-rw-r--r-- | spec/factories/spam_addresses.rb | 5 | ||||
-rw-r--r-- | spec/mailers/request_mailer_spec.rb | 10 | ||||
-rw-r--r-- | spec/models/spam_address_spec.rb | 49 |
14 files changed, 275 insertions, 1 deletions
diff --git a/app/controllers/admin_spam_addresses_controller.rb b/app/controllers/admin_spam_addresses_controller.rb new file mode 100644 index 000000000..f5c7e93da --- /dev/null +++ b/app/controllers/admin_spam_addresses_controller.rb @@ -0,0 +1,27 @@ +class AdminSpamAddressesController < AdminController + + def index + @spam_addresses = SpamAddress.all + @spam_address = SpamAddress.new + end + + def create + @spam_address = SpamAddress.new(params[:spam_address]) + + if @spam_address.save + notice = "#{ @spam_address.email } has been added to the spam addresses list" + redirect_to spam_addresses_path, :notice => notice + else + @spam_addresses = SpamAddress.all + render :index + end + end + + def destroy + @spam_address = SpamAddress.find(params[:id]) + @spam_address.destroy + notice = "#{ @spam_address.email } has been removed from the spam addresses list" + redirect_to spam_addresses_path, :notice => notice + end + +end diff --git a/app/mailers/request_mailer.rb b/app/mailers/request_mailer.rb index af1a75df9..1fd5b9ba7 100644 --- a/app/mailers/request_mailer.rb +++ b/app/mailers/request_mailer.rb @@ -250,7 +250,7 @@ class RequestMailer < ApplicationMailer if reply_info_requests.size == 0 reason = _("Could not identify the request from the email address") request = InfoRequest.holding_pen_request - request.receive(email, raw_email, false, reason) + request.receive(email, raw_email, false, reason) unless SpamAddress.spam?(email.to) return end diff --git a/app/models/spam_address.rb b/app/models/spam_address.rb new file mode 100644 index 000000000..15c9d1ab8 --- /dev/null +++ b/app/models/spam_address.rb @@ -0,0 +1,11 @@ +class SpamAddress < ActiveRecord::Base + attr_accessible :email + + validates_presence_of :email, :message => _('Please enter the email address to mark as spam') + validates_uniqueness_of :email, :message => _('This address is already marked as spam') + + def self.spam?(email_address) + exists?(:email => email_address) + end + +end diff --git a/app/views/admin_request/_incoming_message_actions.html.erb b/app/views/admin_request/_incoming_message_actions.html.erb index 4cf099b53..dd50eb047 100644 --- a/app/views/admin_request/_incoming_message_actions.html.erb +++ b/app/views/admin_request/_incoming_message_actions.html.erb @@ -22,6 +22,13 @@ </div> </div> + <div class="control-group"> + <label class="control-label">Mark <code>To:</code> address as spam</label> + <div class="controls"> + <%= link_to 'Spam Addresses', spam_addresses_path %> + </div> + </div> + <%= form_tag admin_incoming_destroy_path, :class => "form form-inline" do %> <div class="control-group"> <label class="control-label" for="destroy_message_<%= incoming_message.id %>">Destroy message</label> diff --git a/app/views/admin_spam_addresses/index.html.erb b/app/views/admin_spam_addresses/index.html.erb new file mode 100644 index 000000000..9846bc017 --- /dev/null +++ b/app/views/admin_spam_addresses/index.html.erb @@ -0,0 +1,51 @@ +<% @title = 'Spam Addresses' %> + +<h1><%= @title %></h1> + +<div class="row"> + <div class="span12"> + <p> + Incoming mail that gets redirected to the holding pen will be + rejected if it is sent <code>To:</code> an address on this + list. + </p> + </div> +</div> + +<hr /> + +<div class="row"> + <div class="span12"> + <%= form_for(@spam_address, :html => { :class => 'form-inline' }) do |f| -%> + <%= error_messages_for @spam_address %> + <%= f.text_field :email, :class => 'input-xxlarge', :placeholder => 'Enter email' %> + <%= f.submit 'Add Spam Address', :class => 'btn btn-warning' %> + <% end -%> + </div> +</div> + +<hr /> + +<% if @spam_addresses.any? %> + <div class="row"> + <table class="table table-hover span12"> + <thead> + <tr> + <th>Email</th> + <th></th> + </tr> + </thead> + <tbody> + <% @spam_addresses.each do |spam| %> + <tr> + <td><%= spam.email %></td> + <td><%= link_to 'Remove', spam, + :method => :delete, + :confirm => 'This is permanent! Are you sure?', + :class => 'btn btn-mini btn-danger' %></td> + </tr> + <% end %> + </tbody> + </table> + </div> +<% end %> diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index c1f9335b1..2147f22e1 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb @@ -2,6 +2,8 @@ <html lang="en-gb"> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8" > + <%= csrf_meta_tags %> + <title><%= site_name %> admin<%= @title ? ":" : "" %> <%=@title%></title> <%= javascript_include_tag "admin" %> diff --git a/app/views/layouts/default.html.erb b/app/views/layouts/default.html.erb index 52b718be8..6775ed781 100644 --- a/app/views/layouts/default.html.erb +++ b/app/views/layouts/default.html.erb @@ -2,6 +2,8 @@ <html lang="<%= I18n.locale %>"> <head> <meta charset="utf-8"> + <%= csrf_meta_tags %> + <title> <% if @title %> <%=@title%> - <%= site_name %> diff --git a/app/views/layouts/no_chrome.html.erb b/app/views/layouts/no_chrome.html.erb index e613b8ca2..a4278ab24 100644 --- a/app/views/layouts/no_chrome.html.erb +++ b/app/views/layouts/no_chrome.html.erb @@ -2,6 +2,8 @@ <html lang="<%= I18n.locale %>"> <head> <meta charset="utf-8"> + <%= csrf_meta_tags %> + <title> <% if @title %> <%=@title%> - <%= site_name %> diff --git a/config/routes.rb b/config/routes.rb index 1079fbe14..d9d21f0bd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -248,6 +248,14 @@ Alaveteli::Application.routes.draw do match '/admin/censor/destroy/:censor_rule_id' => 'admin_censor_rule#destroy', :as => :admin_rule_destroy #### + #### AdminSpamAddresses controller + scope '/admin' do + resources :spam_addresses, + :controller => 'admin_spam_addresses', + :only => [:index, :create, :destroy] + end + #### + #### Api controller match '/api/v2/request.json' => 'api#create_request', :as => :api_create_request, :via => :post diff --git a/db/migrate/20140325120619_create_spam_addresses.rb b/db/migrate/20140325120619_create_spam_addresses.rb new file mode 100644 index 000000000..7c730a5c7 --- /dev/null +++ b/db/migrate/20140325120619_create_spam_addresses.rb @@ -0,0 +1,9 @@ +class CreateSpamAddresses < ActiveRecord::Migration + def change + create_table :spam_addresses do |t| + t.string :email, :null => false + + t.timestamps + end + end +end diff --git a/spec/controllers/admin_spam_addresses_controller_spec.rb b/spec/controllers/admin_spam_addresses_controller_spec.rb new file mode 100644 index 000000000..da1e9bb5a --- /dev/null +++ b/spec/controllers/admin_spam_addresses_controller_spec.rb @@ -0,0 +1,91 @@ +require 'spec_helper' + +describe AdminSpamAddressesController do + render_views + before { basic_auth_login @request } + + describe :index do + + it 'lists the spam addresses' do + 3.times { FactoryGirl.create(:spam_address) } + get :index + assigns(:spam_addresses).should == SpamAddress.all + end + + it 'creates a new spam address for the form' do + get :index + expect(assigns(:spam_address)).to be_a_new(SpamAddress) + end + + it 'renders the index template' do + get :index + expect(response).to render_template('index') + end + + end + + describe :create do + + let(:spam_params) { FactoryGirl.attributes_for(:spam_address) } + + it 'creates a new spam address with the given parameters' do + post :create, :spam_address => spam_params + assigns(:spam_address).email.should == spam_params[:email] + assigns(:spam_address).should be_persisted + end + + it 'redirects to the index action if successful' do + SpamAddress.any_instance.stub(:save).and_return(true) + post :create, :spam_address => spam_params + expect(response).to redirect_to(spam_addresses_path) + end + + it 'notifies the admin the spam address has been created' do + SpamAddress.any_instance.stub(:save).and_return(true) + post :create, :spam_address => spam_params + msg = "#{ spam_params[:email] } has been added to the spam addresses list" + flash[:notice].should == msg + end + + it 'renders the index action if the address could not be saved' do + SpamAddress.any_instance.stub(:save).and_return(false) + post :create, :spam_address => spam_params + expect(response).to render_template('index') + end + + it 'collects the spam addresses if the address could not be saved' do + 3.times { FactoryGirl.create(:spam_address) } + SpamAddress.any_instance.stub(:save).and_return(false) + post :create, :spam_address => spam_params + assigns(:spam_addresses).should == SpamAddress.all + end + + end + + describe :delete do + + before(:each) do + @spam = FactoryGirl.create(:spam_address) + delete :destroy, :id => @spam.id + end + + it 'finds the spam address to delete' do + assigns(:spam_address).should == @spam + end + + it 'destroys the spam address' do + assigns(:spam_address).should be_destroyed + end + + it 'tells the admin the spam address has been deleted' do + msg = "#{ @spam.email } has been removed from the spam addresses list" + flash[:notice].should == msg + end + + it 'redirects to the index action' do + expect(response).to redirect_to(spam_addresses_path) + end + + end + +end diff --git a/spec/factories/spam_addresses.rb b/spec/factories/spam_addresses.rb new file mode 100644 index 000000000..bafb7cd50 --- /dev/null +++ b/spec/factories/spam_addresses.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :spam_address do + sequence(:email) { |n| "spam-#{ n }@example.org" } + end +end diff --git a/spec/mailers/request_mailer_spec.rb b/spec/mailers/request_mailer_spec.rb index 516d13127..2c5d6e6a9 100644 --- a/spec/mailers/request_mailer_spec.rb +++ b/spec/mailers/request_mailer_spec.rb @@ -78,6 +78,16 @@ describe RequestMailer, " when receiving incoming mail" do deliveries.clear end + it "should ignore mail sent to known spam addresses" do + @spam_address = FactoryGirl.create(:spam_address) + + receive_incoming_mail('incoming-request-plain.email', @spam_address.email) + + deliveries = ActionMailer::Base.deliveries + deliveries.size.should == 0 + deliveries.clear + end + it "should return incoming mail to sender when a request is stopped fully for spam" do # mark request as anti-spam ir = info_requests(:fancy_dog_request) diff --git a/spec/models/spam_address_spec.rb b/spec/models/spam_address_spec.rb new file mode 100644 index 000000000..79a1afd11 --- /dev/null +++ b/spec/models/spam_address_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +describe SpamAddress do + + describe :new do + + it 'requres an email address' do + SpamAddress.new().should_not be_valid + SpamAddress.new(:email => 'spam@example.org').should be_valid + end + + it 'must have a unique email address' do + existing = FactoryGirl.create(:spam_address) + SpamAddress.new(:email => existing.email).should_not be_valid + end + + end + + describe '.spam?' do + + before(:each) do + @spam_address = FactoryGirl.create(:spam_address) + end + + it 'is a spam address if the address is stored' do + SpamAddress.spam?(@spam_address.email).should be_true + end + + it 'is not a spam address if the adress is not stored' do + SpamAddress.spam?('genuine-email@example.com').should be_false + end + + describe 'when accepting an array of emails' do + + it 'is spam if any of the emails are stored' do + emails = ['genuine-email@example.com', @spam_address.email] + SpamAddress.spam?(emails).should be_true + end + + it 'is not spam if none of the emails are stored' do + emails = ['genuine-email@example.com', 'genuine-email@example.org'] + SpamAddress.spam?(emails).should be_false + end + + end + + end + +end |