From c0a788f2ddefcefc52969e33479ae368051600cb Mon Sep 17 00:00:00 2001 From: Zane Date: Wed, 12 Dec 2018 17:57:39 -0800 Subject: [PATCH 01/10] Require signin on fields controller --- app/controllers/attendee_fields_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/attendee_fields_controller.rb b/app/controllers/attendee_fields_controller.rb index 871cd98..2fc72b5 100644 --- a/app/controllers/attendee_fields_controller.rb +++ b/app/controllers/attendee_fields_controller.rb @@ -1,4 +1,5 @@ class AttendeeFieldsController < ApplicationController + before_action :please_sign_in before_action :set_event before_action :set_attendee_field, only: %i[show edit update destroy] before_action -> { authorize @attendee_field }, only: %i[show edit update destroy] From e6a84a694d0542e1d765edcfc8e9c584e34682f9 Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:02:30 -0800 Subject: [PATCH 02/10] Move custom_auth method to application --- app/controllers/application_controller.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3708fd8..9f0f59c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,13 +9,21 @@ class ApplicationController < ActionController::Base rescue_from Pundit::NotAuthorizedError, with: :record_not_authorized end - helper_method :nobody_signed_in?, :current_user_id, :is_my?, :isnt_my?, :set_event + helper_method :nobody_signed_in?, :current_user_id, :set_event, :custom_authorization def set_event @event = Event.friendly.find_by_friendly_id(params[:event_id] || params[:id]) raise ActiveRecord::RecordNotFound unless @event end + def custom_authorization + skip_authorization + # manually authenticate certain methods, Pundit can't + unless @event.users.include?(current_user) || current_user.admin? + raise Pundit::NotAuthorizedError, 'not allowed to view this action' + end + end + # Keep the current user id in memory def current_user_id return unless current_user From ec0c3142a82673905fae0ffcd9accbd90530d11c Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:02:37 -0800 Subject: [PATCH 03/10] Remove old --- app/controllers/attendees_controller.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/controllers/attendees_controller.rb b/app/controllers/attendees_controller.rb index 7de5cab..5a531dc 100644 --- a/app/controllers/attendees_controller.rb +++ b/app/controllers/attendees_controller.rb @@ -28,14 +28,6 @@ def index end end - def custom_authorization - skip_authorization - # manually authenticate certain methods, Pundit can't - unless @event.users.include?(current_user) || current_user.admin? - raise Pundit::NotAuthorizedError, 'not allowed to view this action' - end - end - def show @attendee_fields = @event.fields end From 26f91ab0c2f5adcc5049bf530aca6a15ebf34075 Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:03:14 -0800 Subject: [PATCH 04/10] Add email_config model --- app/models/email_config.rb | 11 ++++++++++ app/models/event.rb | 7 +++++++ .../20181213014752_create_email_configs.rb | 16 ++++++++++++++ test/fixtures/email_configs.yml | 21 +++++++++++++++++++ test/models/email_config_test.rb | 7 +++++++ 5 files changed, 62 insertions(+) create mode 100644 app/models/email_config.rb create mode 100644 db/migrate/20181213014752_create_email_configs.rb create mode 100644 test/fixtures/email_configs.yml create mode 100644 test/models/email_config_test.rb diff --git a/app/models/email_config.rb b/app/models/email_config.rb new file mode 100644 index 0000000..40b0c98 --- /dev/null +++ b/app/models/email_config.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class EmailConfig < ApplicationRecord + belongs_to :event + + def enabled? + true unless [ + smtp_url, smtp_port, authentication, domain, sender_email, username, password + ].any?(&:nil?) + end +end diff --git a/app/models/event.rb b/app/models/event.rb index 8240a27..4c1bcc5 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -3,6 +3,7 @@ class Event < ApplicationRecord default_scope { order(id: :asc) } + has_one :email_config, dependent: :destroy has_many :attendees, dependent: :destroy has_many :fields, class_name: 'AttendeeField', dependent: :destroy has_many :organizer_positions, dependent: :destroy @@ -14,6 +15,12 @@ class Event < ApplicationRecord validates :name, :start_date, :end_date, :location, :user_id, presence: true validate :permitted_domains_cannot_have_trailing_slash + after_create do + create_email_config! + end + + private + def permitted_domains_cannot_have_trailing_slash permitted_domains.split(',').each do |domain| if domain[-1] == '/' diff --git a/db/migrate/20181213014752_create_email_configs.rb b/db/migrate/20181213014752_create_email_configs.rb new file mode 100644 index 0000000..c2454e6 --- /dev/null +++ b/db/migrate/20181213014752_create_email_configs.rb @@ -0,0 +1,16 @@ +class CreateEmailConfigs < ActiveRecord::Migration[5.2] + def change + create_table :email_configs do |t| + t.string :smtp_url + t.string :smtp_port + t.string :authentication + t.string :domain + t.string :sender_email + t.string :username + t.string :password + t.belongs_to :event, index: true + + t.timestamps + end + end +end diff --git a/test/fixtures/email_configs.yml b/test/fixtures/email_configs.yml new file mode 100644 index 0000000..64e678a --- /dev/null +++ b/test/fixtures/email_configs.yml @@ -0,0 +1,21 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + enabled: false + smtp_url: MyString + smtp_port: MyString + authentication: MyString + domain: MyString + sender_email: MyString + username: MyString + password: MyString + +two: + enabled: false + smtp_url: MyString + smtp_port: MyString + authentication: MyString + domain: MyString + sender_email: MyString + username: MyString + password: MyString diff --git a/test/models/email_config_test.rb b/test/models/email_config_test.rb new file mode 100644 index 0000000..bd2ab00 --- /dev/null +++ b/test/models/email_config_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class EmailConfigTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end From eec795dfd6220eca36773ae3a9df8e92e32db6de Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:03:37 -0800 Subject: [PATCH 05/10] Add email model --- app/models/email.rb | 3 +++ app/models/event.rb | 1 + db/migrate/20181213030449_create_emails.rb | 15 +++++++++++++++ test/fixtures/emails.yml | 17 +++++++++++++++++ test/models/email_test.rb | 7 +++++++ 5 files changed, 43 insertions(+) create mode 100644 app/models/email.rb create mode 100644 db/migrate/20181213030449_create_emails.rb create mode 100644 test/fixtures/emails.yml create mode 100644 test/models/email_test.rb diff --git a/app/models/email.rb b/app/models/email.rb new file mode 100644 index 0000000..aad87f8 --- /dev/null +++ b/app/models/email.rb @@ -0,0 +1,3 @@ +class Email < ApplicationRecord + belongs_to :event +end diff --git a/app/models/event.rb b/app/models/event.rb index 4c1bcc5..63a6950 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -4,6 +4,7 @@ class Event < ApplicationRecord default_scope { order(id: :asc) } has_one :email_config, dependent: :destroy + has_many :emails, dependent: :destroy has_many :attendees, dependent: :destroy has_many :fields, class_name: 'AttendeeField', dependent: :destroy has_many :organizer_positions, dependent: :destroy diff --git a/db/migrate/20181213030449_create_emails.rb b/db/migrate/20181213030449_create_emails.rb new file mode 100644 index 0000000..e33408f --- /dev/null +++ b/db/migrate/20181213030449_create_emails.rb @@ -0,0 +1,15 @@ +class CreateEmails < ActiveRecord::Migration[5.2] + def change + create_table :emails do |t| + t.string :recipient + t.string :sender_email + t.text :subject + t.text :body + t.string :read_receipt_img_url + t.string :read_receipt_stats_url + t.belongs_to :event, index: true + + t.timestamps + end + end +end diff --git a/test/fixtures/emails.yml b/test/fixtures/emails.yml new file mode 100644 index 0000000..ba5c94d --- /dev/null +++ b/test/fixtures/emails.yml @@ -0,0 +1,17 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + recipient: MyString + sender_email: MyString + subject: MyText + body: MyText + read_receipt_img_url: MyString + read_receipt_stats_url: MyString + +two: + recipient: MyString + sender_email: MyString + subject: MyText + body: MyText + read_receipt_img_url: MyString + read_receipt_stats_url: MyString diff --git a/test/models/email_test.rb b/test/models/email_test.rb new file mode 100644 index 0000000..dc054e5 --- /dev/null +++ b/test/models/email_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class EmailTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end From 48100c9b5006a43f64c28df7976828bbb113591c Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:03:42 -0800 Subject: [PATCH 06/10] Run migration --- db/schema.rb | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 869560e..05305f2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_12_04_044905) do +ActiveRecord::Schema.define(version: 2018_12_13_030449) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -74,6 +74,33 @@ t.index ["event_id"], name: "index_attendees_on_event_id" end + create_table "email_configs", force: :cascade do |t| + t.string "smtp_url" + t.string "smtp_port" + t.string "authentication" + t.string "domain" + t.string "sender_email" + t.string "username" + t.string "password" + t.bigint "event_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["event_id"], name: "index_email_configs_on_event_id" + end + + create_table "emails", force: :cascade do |t| + t.string "recipient" + t.string "sender_email" + t.text "subject" + t.text "body" + t.string "read_receipt_img_url" + t.string "read_receipt_stats_url" + t.bigint "event_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["event_id"], name: "index_emails_on_event_id" + end + create_table "events", force: :cascade do |t| t.string "name" t.datetime "start_date" From c74a601c53313149a8bd689363729dd5495acc36 Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:03:48 -0800 Subject: [PATCH 07/10] Add emails controller --- app/controllers/emails_controller.rb | 57 ++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 app/controllers/emails_controller.rb diff --git a/app/controllers/emails_controller.rb b/app/controllers/emails_controller.rb new file mode 100644 index 0000000..ceb5fa0 --- /dev/null +++ b/app/controllers/emails_controller.rb @@ -0,0 +1,57 @@ +class EmailsController < ApplicationController + before_action :please_sign_in + before_action :set_event + before_action :set_email, only: %i[show] + before_action :custom_authorization, only: %i[index settings configure] + + def index + end + + def show + authorize @email + end + + def new + @email = @event.emails.new + authorize @email + end + + def create + @email = @event.emails.new(email_params) + authorize @email + + if @email.save + redirect_to event_emails_path(@event) + flash[:success] = 'Email will be sent shortly.' + else + render :new + end + end + + def settings + @email_config = @event.email_config + end + + def configure + if @event.email_config.update(email_config_params) + redirect_to event_emails_path(@event) + flash[:success] = 'Email sending has been configured.' + else + render :edit + end + end + + private + + def set_email + @email = @event.emails.find(params[:id]) + end + + def email_params + params.require(:email).permit(:recipient, :sender_email, :subject, :body) + end + + def email_config_params + params.require(:email_config).permit(:smtp_url, :smtp_port, :authentication, :domain, :sender_email, :username, :password) + end +end From 5d94b59013e7df8db76b288f329fb41184ef6d7d Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:03:53 -0800 Subject: [PATCH 08/10] Add emails policy --- app/policies/email_policy.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 app/policies/email_policy.rb diff --git a/app/policies/email_policy.rb b/app/policies/email_policy.rb new file mode 100644 index 0000000..5ef6c04 --- /dev/null +++ b/app/policies/email_policy.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class EmailPolicy < ApplicationPolicy + def show? + record.event.users.include?(user) || user.admin? + end + + def new? + record.event.users.include?(user) || user.admin? + end + + def create? + record.event.users.include?(user) || user.admin? + end +end From 945d22efcb457e315bcbd5c09da308cb467f73e1 Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:03:58 -0800 Subject: [PATCH 09/10] Add emails routes --- config/routes.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/routes.rb b/config/routes.rb index 0231c26..24f56ca 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,6 +18,12 @@ end end resources :attendee_fields, path: 'fields' + resources :emails do + collection do + get 'settings', to: 'emails#settings', as: :settings + patch 'configure', to: 'emails#configure', as: :configure + end + end resources :organizer_position_invites, path: 'invites' do post 'accept' From d41c2da2e7a74b3d15965cb16a83c8b0804f5534 Mon Sep 17 00:00:00 2001 From: Zane Date: Thu, 13 Dec 2018 00:04:01 -0800 Subject: [PATCH 10/10] Add email views --- app/views/emails/index.html.erb | 20 ++++++++++ app/views/emails/settings.html.erb | 63 ++++++++++++++++++++++++++++++ app/views/events/show.html.erb | 5 +++ 3 files changed, 88 insertions(+) create mode 100644 app/views/emails/index.html.erb create mode 100644 app/views/emails/settings.html.erb diff --git a/app/views/emails/index.html.erb b/app/views/emails/index.html.erb new file mode 100644 index 0000000..655145f --- /dev/null +++ b/app/views/emails/index.html.erb @@ -0,0 +1,20 @@ +<% title "Emails on #{@event.name}" %> + + +

+ Emails + <% if @event.email_config.enabled? %> + <%= link_to 'Send an email', new_event_email_path, class: 'btn bg-success' %> + <%= link_to 'Edit settings', settings_event_emails_path, class: 'btn bg-info' %> + <% else %> + <%= link_to 'Configure email sending', settings_event_emails_path, class: 'btn bg-info' %> + <% end %> +

+ +<% if @event.email_config.enabled? %> + a +<% else %> +

Email sending hasn’t been configured.

+<% end %> diff --git a/app/views/emails/settings.html.erb b/app/views/emails/settings.html.erb new file mode 100644 index 0000000..2fd9850 --- /dev/null +++ b/app/views/emails/settings.html.erb @@ -0,0 +1,63 @@ +<% title "Editing email settings on #{@event.name}" %> + +

Email Configuration

+ +<%= form_with(model: @email_config, local: true, url: configure_event_emails_path) do |form| %> + <% if @email_config.errors.any? %> +
+

<%= pluralize(@email_config.errors.count, "error") %> prohibited this event from being saved:

+ +
    + <% @email_config.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= form.label :smtp_url %> + <%= form.text_field :smtp_url %> +
+ +
+ <%= form.label :smtp_port %> + <%= form.text_field :smtp_port %> +
+ +
+ <%= form.label :authentication %> + <%= form.text_field :authentication, placeholder: 'PLAIN' %> +
+ +
+ <%= form.label :smtp_url %> + <%= form.text_field :smtp_url %> +
+ +
+ <%= form.label :domain %> + <%= form.text_field :domain %> +
+ +
+ <%= form.label :sender_email %> + <%= form.text_field :sender_email %> +
+ +
+ <%= form.label :username %> + <%= form.text_field :username %> +
+ +
+ <%= form.label :password %> + <%= form.password_field :password %> +
+ +
+ <%= form.submit 'Configure' %> +
+<% end %> diff --git a/app/views/events/show.html.erb b/app/views/events/show.html.erb index 03ac0d7..ef8a1b8 100644 --- a/app/views/events/show.html.erb +++ b/app/views/events/show.html.erb @@ -35,6 +35,11 @@ Hardware<%= @event.hardwares.count %> <% end %> + <%= link_to event_emails_path(@event) do %> +
  • + Emails<%= @event.email_config.enabled? ? @event.emails.count : 'Disabled' %> +
  • + <% end %>