diff --git a/app/controllers/public/unsubscribes_controller.rb b/app/controllers/public/unsubscribes_controller.rb new file mode 100644 index 0000000000..2f8484170b --- /dev/null +++ b/app/controllers/public/unsubscribes_controller.rb @@ -0,0 +1,24 @@ +module Public + class UnsubscribesController < ApplicationController + skip_before_filter :authenticate_user!, + :reject_blocked, :set_current_user_for_observers, + :add_abilities + layout 'public_users' + + def show + @user = get_user + end + + def create + @user = get_user + @user.admin_unsubscribe! + redirect_to new_user_session_path, notice: 'You have been unsubscribed' + end + + protected + def get_user + @email = "#{params[:email]}.#{params[:format]}" + User.where(email: @email).first! + end + end +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 9c52c92b3b..4f5e5fa07b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -175,6 +175,7 @@ class User < ActiveRecord::Base scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') } scope :ldap, -> { where(provider: 'ldap') } + scope :subscribed_for_admin_email, -> { where(admin_email_unsubscribed_at: nil) } scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active } @@ -509,4 +510,8 @@ class User < ActiveRecord::Base def system_hook_service SystemHooksService.new end + + def admin_unsubscribe! + update_column :admin_email_unsubscribed_at, Time.now + end end diff --git a/app/views/public/unsubscribes/show.html.haml b/app/views/public/unsubscribes/show.html.haml new file mode 100644 index 0000000000..5c8b17ad11 --- /dev/null +++ b/app/views/public/unsubscribes/show.html.haml @@ -0,0 +1,13 @@ +%h3.page-title Unsubscribe from Admin notifications +%p + Don't want to receive any updates from your system administrator. + By clicking the confirmation button you'll no longer receive these notifications + +%hr += form_tag public_unsubscribe_path(@email) do + %p + Yes, I want to unsubscribe + %strong= @email + from any further admin emails. + .form-actions + = submit_tag 'Unsubscribe', class: 'btn btn-create' diff --git a/app/workers/admin_emails_worker.rb b/app/workers/admin_emails_worker.rb index 6f260cdf5d..fff853a35d 100644 --- a/app/workers/admin_emails_worker.rb +++ b/app/workers/admin_emails_worker.rb @@ -11,11 +11,11 @@ class AdminEmailsWorker def recipient_list(recipient_id) case recipient_id when 'all' - User.where(nil) + User.subscribed_for_admin_email when /group-(\d+)\z/ - Group.find($1).users + Group.find($1).users.subscribed_for_admin_email when /project-(\d+)\z/ - Project.find($1).users + Project.find($1).users.subscribed_for_admin_email end end end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index c1fafde18d..14365e8999 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -52,6 +52,8 @@ Gitlab::Application.routes.draw do # namespace :public do resources :projects, only: [:index] + get 'unsubscribes/:email', to: 'unsubscribes#show', as: :unsubscribe + post 'unsubscribes/:email', to: 'unsubscribes#create' root to: "projects#index" end diff --git a/spec/workers/admin_emails_worker_spec.rb b/spec/workers/admin_emails_worker_spec.rb new file mode 100644 index 0000000000..6b0182b8a0 --- /dev/null +++ b/spec/workers/admin_emails_worker_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe AdminEmailsWorker do + context "recipients" do + let(:recipient_id) { "group-#{group.id}" } + let(:group) { create :group } + + before do + 2.times do + group.add_user(create(:user), Gitlab::Access::DEVELOPER) + end + unsubscribed_user = create(:user, admin_email_unsubscribed_at: 5.days.ago) + group.add_user(unsubscribed_user, Gitlab::Access::DEVELOPER) + ActionMailer::Base.deliveries = [] + end + + it "sends email to subscribed users" do + AdminEmailsWorker.new.perform(recipient_id, 'subject', 'body') + expect(ActionMailer::Base.deliveries.count).to eql 2 + end + end +end \ No newline at end of file