From 97abcabffa977a3270b3ef0fe094df4026fd1cb6 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Fri, 18 Aug 2017 09:17:19 +0200 Subject: [PATCH] Log mail delivery errors to database and add an UI for it --- .../admin/mail_delivery_status_controller.rb | 30 +++++++++++++++++++ app/controllers/admin/users_controller.rb | 1 + app/mailers/mailer.rb | 2 +- app/models/mail_delivery_status.rb | 5 ++++ app/models/user.rb | 1 + .../_maildeliverystatus.html.haml | 26 ++++++++++++++++ .../mail_delivery_status/index.html.haml | 7 +++++ .../admin/mail_delivery_status/index.js.haml | 1 + app/views/admin/users/_users.html.haml | 5 +++- app/views/admin/users/show.html.haml | 5 +++- config/locales/de.yml | 14 +++++++++ config/locales/en.yml | 14 +++++++++ config/navigation.rb | 1 + config/routes.rb | 4 +++ ...70801000000_create_mail_delivery_status.rb | 13 ++++++++ db/schema.rb | 12 +++++++- 16 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 app/controllers/admin/mail_delivery_status_controller.rb create mode 100644 app/models/mail_delivery_status.rb create mode 100644 app/views/admin/mail_delivery_status/_maildeliverystatus.html.haml create mode 100644 app/views/admin/mail_delivery_status/index.html.haml create mode 100644 app/views/admin/mail_delivery_status/index.js.haml create mode 100644 db/migrate/20170801000000_create_mail_delivery_status.rb diff --git a/app/controllers/admin/mail_delivery_status_controller.rb b/app/controllers/admin/mail_delivery_status_controller.rb new file mode 100644 index 00000000..4ae34fb7 --- /dev/null +++ b/app/controllers/admin/mail_delivery_status_controller.rb @@ -0,0 +1,30 @@ +class Admin::MailDeliveryStatusController < Admin::BaseController + inherit_resources + + def index + @maildeliverystatus = MailDeliveryStatus.order(created_at: :desc) + @maildeliverystatus = @maildeliverystatus.where(email: params[:email]) unless params[:email].blank? + @maildeliverystatus = @maildeliverystatus.page(params[:page]).per(@per_page) + end + + def show + @maildeliverystatus = MailDeliveryStatus.find(params[:id]) + filename = "maildeliverystatus_#{params[:id]}.#{MIME::Types[@maildeliverystatus.attachment_mime].first.preferred_extension}" + send_data(@maildeliverystatus.attachment_data, :filename => filename, :type => @maildeliverystatus.attachment_mime) + end + + def destroy_all + @maildeliverystatus = MailDeliveryStatus.delete_all + redirect_to admin_mail_delivery_status_index_path, notice: t('.notice') + rescue => error + redirect_to admin_mail_delivery_status_index_path, alert: I18n.t('errors.general_msg', msg: error.message) + end + + def destroy + @maildeliverystatus = MailDeliveryStatus.find(params[:id]) + @maildeliverystatus.destroy + redirect_to admin_mail_delivery_status_index_path, notice: t('.notice') + rescue => error + redirect_to admin_mail_delivery_status_index_path, I18n.t('errors.general_msg', msg: error.message) + end +end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 3c73d63c..d4e2b78a 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -3,6 +3,7 @@ class Admin::UsersController < Admin::BaseController def index @users = params[:show_deleted] ? User.deleted : User.undeleted + @users = @users.includes(:mail_delivery_status) # if somebody uses the search field: @users = @users.natural_search(params[:user_name]) unless params[:user_name].blank? diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb index 25f94691..ad5aebcd 100644 --- a/app/mailers/mailer.rb +++ b/app/mailers/mailer.rb @@ -102,7 +102,7 @@ class Mailer < ActionMailer::Base message = yield message.deliver_now rescue => error - Rails.logger.warn "Can't deliver mail to #{message.to[0]}: #{error.message}" + MailDeliveryStatus.create email: message.to[0], message: error.message end end diff --git a/app/models/mail_delivery_status.rb b/app/models/mail_delivery_status.rb new file mode 100644 index 00000000..2949c073 --- /dev/null +++ b/app/models/mail_delivery_status.rb @@ -0,0 +1,5 @@ +class MailDeliveryStatus < ActiveRecord::Base + self.table_name = 'mail_delivery_status' + + belongs_to :user, foreign_key: 'email', primary_key: 'email' +end diff --git a/app/models/user.rb b/app/models/user.rb index 858afaac..a419269c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,6 +18,7 @@ class User < ActiveRecord::Base has_many :tasks, :through => :assignments has_many :send_messages, :class_name => "Message", :foreign_key => "sender_id" has_many :created_orders, :class_name => 'Order', :foreign_key => 'created_by_user_id', :dependent => :nullify + has_many :mail_delivery_status, :class_name => 'MailDeliveryStatus', :foreign_key => 'email', :primary_key => 'email' attr_accessor :password, :settings_attributes diff --git a/app/views/admin/mail_delivery_status/_maildeliverystatus.html.haml b/app/views/admin/mail_delivery_status/_maildeliverystatus.html.haml new file mode 100644 index 00000000..0dc84541 --- /dev/null +++ b/app/views/admin/mail_delivery_status/_maildeliverystatus.html.haml @@ -0,0 +1,26 @@ +- if MailDeliveryStatus.count > 20 + = items_per_page += pagination_links_remote @maildeliverystatus +%table.table.table-striped + %thead + %tr + %th= heading_helper MailDeliveryStatus, :created_at + %th= heading_helper MailDeliveryStatus, :email + %th= heading_helper MailDeliveryStatus, :message + %th= t 'ui.actions' + %tbody + - for maildeliverystatus in @maildeliverystatus + %tr{:class => cycle('even','odd', :name => 'groups')} + %td= format_time maildeliverystatus.created_at + %td + - if user = maildeliverystatus.user + = link_to maildeliverystatus.email, [:admin, user] + - else + = maildeliverystatus.email + %td + - if maildeliverystatus.attachment_data + = link_to maildeliverystatus.message, [:admin, maildeliverystatus] + - else + = maildeliverystatus.message + %td + = link_to t('ui.delete'), [:admin, maildeliverystatus], :method => :delete, class: 'btn btn-mini btn-danger' diff --git a/app/views/admin/mail_delivery_status/index.html.haml b/app/views/admin/mail_delivery_status/index.html.haml new file mode 100644 index 00000000..4d2264e5 --- /dev/null +++ b/app/views/admin/mail_delivery_status/index.html.haml @@ -0,0 +1,7 @@ +- title t('.title') + +- content_for :actionbar do + = link_to t('.destroy_all'), admin_mail_delivery_status_index_path, :method => :delete, class: 'btn btn-danger' + +#maildeliverystatus + = render "maildeliverystatus" diff --git a/app/views/admin/mail_delivery_status/index.js.haml b/app/views/admin/mail_delivery_status/index.js.haml new file mode 100644 index 00000000..7fca685c --- /dev/null +++ b/app/views/admin/mail_delivery_status/index.js.haml @@ -0,0 +1 @@ +$('#maildeliverystatus').html('#{escape_javascript(render("maildeliverystatus"))}'); diff --git a/app/views/admin/users/_users.html.haml b/app/views/admin/users/_users.html.haml index d836e972..1a7a0cea 100644 --- a/app/views/admin/users/_users.html.haml +++ b/app/views/admin/users/_users.html.haml @@ -17,7 +17,10 @@ %td= link_to show_user(user), [:admin, user] - if FoodsoftConfig[:use_nick] %td= user.name - %td= user.email + %td + = user.email + - if user.mail_delivery_status.any? + = link_to t('.show_email_problems'), admin_mail_delivery_status_index_path(email: user.email), class: 'btn btn-warning btn-mini' %td= format_roles(user, true) %td= format_time(user.last_activity) %td= link_to t('ui.edit'), edit_admin_user_path(user), class: 'btn btn-mini' diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index a4030f38..a9c25c41 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -12,7 +12,10 @@ %dt= heading_helper User, :name %dd= h @user.name %dt= heading_helper User, :email - %dd= @user.email + %dd + = @user.email + - if @user.mail_delivery_status.any? + = link_to t('.show_email_problems'), admin_mail_delivery_status_index_path(email: @user.email), class: 'btn btn-warning btn-mini' %dt= heading_helper User, :phone %dd= @user.phone %dt= heading_helper User, :last_login diff --git a/config/locales/de.yml b/config/locales/de.yml index dea6931f..359d4fa9 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -74,6 +74,10 @@ de: orders: Bestellung paid_on: Bezahlt am supplier: Lieferant + mail_delivery_status: + created_at: Zeitpunkt + email: E-Mail + message: Nachicht order: boxfill: Kistenfüllen ab closed_by: Abgerechnet von @@ -256,6 +260,12 @@ de: update: notice: Einstellungen gespeichert. confirm: Bist Du sicher? + mail_delivery_status: + destroy_all: + notice: Alle E-Mail Probleme wurden gelöscht + index: + destroy_all: Alle E-Mail Probleme löschen + title: E-Mail Probleme ordergroups: destroy: error: 'Bestellgruppe konnte nicht als gelöscht markiert werden: %{error}' @@ -306,7 +316,10 @@ de: person: Person preference: Einstellungen send_message: Nachricht senden + show_email_problems: Zeige E-Mail Probleme sudo: Als anderer Benutzer anmelden + users: + show_email_problems: Zeige E-Mail Probleme workgroups: destroy: error: 'Arbeitsgruppe konnte nicht gelöscht werden: %{error}' @@ -1289,6 +1302,7 @@ de: admin: config: Einstellungen home: "Übersicht" + mail_delivery_status: E-Mail Probleme ordergroups: Bestellgruppen title: Administration users: Benutzer/innen diff --git a/config/locales/en.yml b/config/locales/en.yml index 580334fa..795a538b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -74,6 +74,10 @@ en: orders: Order paid_on: Paid on supplier: Supplier + mail_delivery_status: + created_at: Time + email: Email + message: Message order: boxfill: Fill boxes after closed_by: Settled by @@ -258,6 +262,12 @@ en: update: notice: Configuration saved. confirm: Are you sure? + mail_delivery_status: + destroy_all: + notice: All email problems were deleted + index: + destroy_all: Delete all email problems + title: Email problems ordergroups: destroy: error: 'Ordergroup could not be marked as deleted: %{error}' @@ -308,7 +318,10 @@ en: person: Person preference: Preferences send_message: Send message + show_email_problems: Show email problems sudo: Take on identity + users: + show_email_problems: Show email problems workgroups: destroy: error: 'Workgroup could not be deleted: %{error}' @@ -1298,6 +1311,7 @@ en: admin: config: Configuration home: Overview + mail_delivery_status: Email problems ordergroups: Ordergroups title: Administration users: Users diff --git a/config/navigation.rb b/config/navigation.rb index 42e0b337..1447788b 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -45,6 +45,7 @@ SimpleNavigation::Configuration.run do |navigation| subnav.item :users, I18n.t('navigation.admin.users'), admin_users_path subnav.item :ordergroups, I18n.t('navigation.admin.ordergroups'), admin_ordergroups_path subnav.item :workgroups, I18n.t('navigation.admin.workgroups'), admin_workgroups_path + subnav.item :mail_delivery_status, I18n.t('navigation.admin.mail_delivery_status'), admin_mail_delivery_status_index_path subnav.item :config, I18n.t('navigation.admin.config'), admin_config_path end diff --git a/config/routes.rb b/config/routes.rb index e135002b..218914c7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -188,6 +188,10 @@ Foodsoft::Application.routes.draw do get :memberships, on: :member end + resources :mail_delivery_status, only: [:index, :show, :destroy] do + delete :index, on: :collection, action: :destroy_all + end + resource :config, only: [:show, :update] do get :list end diff --git a/db/migrate/20170801000000_create_mail_delivery_status.rb b/db/migrate/20170801000000_create_mail_delivery_status.rb new file mode 100644 index 00000000..f4c5de65 --- /dev/null +++ b/db/migrate/20170801000000_create_mail_delivery_status.rb @@ -0,0 +1,13 @@ +class CreateMailDeliveryStatus < ActiveRecord::Migration + def change + create_table :mail_delivery_status do |t| + t.datetime :created_at + t.string :email, :null => false + t.string :message, :null => false + t.string :attachment_mime + t.binary :attachment_data, limit: 16.megabyte + + t.index :email + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 2419a0cc..0f850f6c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161001000000) do +ActiveRecord::Schema.define(version: 20170801000000) do create_table "article_categories", force: :cascade do |t| t.string "name", limit: 255, default: "", null: false @@ -175,6 +175,16 @@ ActiveRecord::Schema.define(version: 20161001000000) do add_index "invoices", ["supplier_id"], name: "index_invoices_on_supplier_id", using: :btree + create_table "mail_delivery_status", force: :cascade do |t| + t.datetime "created_at" + t.string "email", null: false + t.string "message", null: false + t.string "attachment_mime" + t.binary "attachment_data" + end + + add_index "mail_delivery_status", ["email"], name: "index_mail_delivery_status_on_email", using: :btree + create_table "memberships", force: :cascade do |t| t.integer "group_id", limit: 4, default: 0, null: false t.integer "user_id", limit: 4, default: 0, null: false