From 723f25a9999251b0c3f45c57aa88afa83f315b2d Mon Sep 17 00:00:00 2001
From: Ash Furrow <ash@ashfurrow.com>
Date: Sun, 23 Apr 2017 04:43:42 +0200
Subject: [PATCH] Admin UI for confirming users (#2245)

* Shows confirmed status in list.

* Adds ability to confirm users in admin UI.

* Added new english translations.

* Addresses feedback from #2245.

* More feedback.
---
 .../admin/confirmations_controller.rb          | 18 ++++++++++++++++++
 app/models/user.rb                             |  4 ++++
 app/views/admin/accounts/index.html.haml       |  7 +++++++
 app/views/admin/accounts/show.html.haml        |  3 +++
 config/locales/en.yml                          |  2 ++
 config/routes.rb                               |  1 +
 spec/models/user_spec.rb                       | 12 ++++++++++++
 7 files changed, 47 insertions(+)
 create mode 100644 app/controllers/admin/confirmations_controller.rb

diff --git a/app/controllers/admin/confirmations_controller.rb b/app/controllers/admin/confirmations_controller.rb
new file mode 100644
index 000000000..6c41999e0
--- /dev/null
+++ b/app/controllers/admin/confirmations_controller.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Admin
+  class ConfirmationsController < BaseController
+    before_action :set_account
+
+    def create
+      @account.user.confirm
+      redirect_to admin_accounts_path
+    end
+
+    private
+
+    def set_account
+      @account = Account.find(params[:account_id])
+    end
+  end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index cd1f816ca..48e7b8088 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -19,6 +19,10 @@ class User < ApplicationRecord
   scope :admins,    -> { where(admin: true) }
   scope :confirmed, -> { where.not(confirmed_at: nil) }
 
+  def confirmed?
+    confirmed_at.present?
+  end
+
   def send_devise_notification(notification, *args)
     devise_mailer.send(notification, self, *args).deliver_later
   end
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index bd1eb7ecd..c52b3ff74 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -25,6 +25,7 @@
     %tr
       %th= t('admin.accounts.username')
       %th= t('admin.accounts.domain')
+      %th= t('admin.accounts.confirmed')
       %th= fa_icon 'paper-plane-o'
       %th
   %tbody
@@ -34,6 +35,12 @@
         %td
           - unless account.local?
             = link_to account.domain, admin_accounts_path(by_domain: account.domain)
+        %td
+          - if account.local?
+            - if account.user.present? && account.user.confirmed?
+              %i.fa.fa-check
+            - else 
+              %i.fa.fa-times
         %td
           - if account.local?
             = t('admin.accounts.location.local')
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index 75b69b337..5dc3067cd 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -77,6 +77,9 @@
   - else
     = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button'
 
+  - unless @account.user.confirmed?
+    = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button'
+
   - if @account.suspended?
     = link_to t('admin.accounts.undo_suspension'), admin_account_suspension_path(@account.id), method: :delete, class: 'button'
   - else
diff --git a/config/locales/en.yml b/config/locales/en.yml
index cf492e117..b8463673e 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -43,6 +43,8 @@ en:
   admin:
     accounts:
       are_you_sure: Are you sure?
+      confirm: Confirm
+      confirmed: Confirmed
       display_name: Display name
       domain: Domain
       edit: Edit
diff --git a/config/routes.rb b/config/routes.rb
index abc77535a..2c8ac1cff 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -86,6 +86,7 @@ Rails.application.routes.draw do
       resource :reset, only: [:create]
       resource :silence, only: [:create, :destroy]
       resource :suspension, only: [:create, :destroy]
+      resource :confirmation, only: [:create]
     end
   end
 
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 846a206ec..3dd50a701 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -98,6 +98,18 @@ RSpec.describe User, type: :model do
     end
   end
 
+  describe '#confirmed?' do
+    it 'returns true when a confirmed_at is set' do
+      user = Fabricate.build(:user, confirmed_at: Time.now.utc)
+      expect(user.confirmed?).to be true
+    end
+
+    it 'returns false if a confirmed_at is nil' do
+      user = Fabricate.build(:user, confirmed_at: nil)
+      expect(user.confirmed?).to be false
+    end
+  end
+
   describe 'whitelist' do
     around(:each) do |example|
       old_whitelist = Rails.configuration.x.email_whitelist
-- 
GitLab