summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Fick <logaldeveloper@protonmail.com>2018-06-10 21:08:22 -0400
committerLogan Fick <logaldeveloper@protonmail.com>2018-06-10 21:08:22 -0400
commit37be5f56b68f3deda5b8c769c87317aaf23a232f (patch)
treea2cf8d57735b6fbd7627a271e66f373606b5ae63
parent3d8199c9f9186cec4b331edc50d99e5f1d5d11f2 (diff)
parent09e3312ccaf3215876444c6f3afc08b0c7eea4ce (diff)
Merged pull request #50.
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.lock6
-rw-r--r--app/controllers/application_controller.rb10
-rw-r--r--app/controllers/sessions_controller.rb6
-rw-r--r--app/controllers/users_controller.rb19
-rw-r--r--app/views/sessions/new.html.erb8
-rw-r--r--app/views/users/edit.html.erb2
-rw-r--r--app/views/users/edit_login.html.erb41
-rw-r--r--db/migrate/20180606223258_add_totp_to_users.rb6
-rw-r--r--db/schema.rb4
10 files changed, 95 insertions, 8 deletions
diff --git a/Gemfile b/Gemfile
index 09f297d..4ef3294 100644
--- a/Gemfile
+++ b/Gemfile
@@ -17,6 +17,7 @@ gem 'kaminari', github: 'jomo/kaminari', branch: 'patch-2' # pagination
gem 'jquery-textcomplete-rails' # @mentions
gem 'actionpack-action_caching', github: 'antulik/actionpack-action_caching', ref: '8c6e52c69315d67437f480da5dce4b7c8737fb32'
gem 'mail-gpg', github: 'jomo/mail-gpg', ref: 'a666b48ee866dfa3eaa700f9c5edf4d195d0f8c9'
+gem 'totp'
# Gems used only for assets and not required
# in production environments by default.
diff --git a/Gemfile.lock b/Gemfile.lock
index bd8feba..939e4e6 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -99,6 +99,7 @@ GEM
airbrussh (1.3.0)
sshkit (>= 1.6.1, != 1.7.0)
arel (6.0.4)
+ base32 (0.3.2)
bcrypt (3.1.11)
better_errors (2.4.0)
coderay (>= 1.0.0)
@@ -237,6 +238,8 @@ GEM
thor (0.20.0)
thread_safe (0.3.6)
tilt (2.0.8)
+ totp (1.0.0)
+ base32
tzinfo (1.2.5)
thread_safe (~> 0.1)
uglifier (4.1.8)
@@ -277,10 +280,11 @@ DEPENDENCIES
sass-rails
sqlite3
strip_attributes
+ totp
tzinfo-data
uglifier
unicorn
webrick
BUNDLED WITH
- 1.16.1
+ 1.16.2
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d489611..063c173 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,6 +1,6 @@
class ApplicationController < ActionController::Base
protect_from_forgery
- before_filter :update_ip, :update_seen, :check_banned
+ before_filter :update_ip, :update_seen, :check_banned, :check_2fa
# TODO: use SSL
@@ -41,6 +41,14 @@ class ApplicationController < ActionController::Base
end
end
+ def check_2fa
+ # Over complicated way of asking if the user is logged in as a mod without TOTP enabled while they are not on their login settings screen, logging out, or updating their login settings.
+ if current_user && current_user.mod? && !current_user.totp_enabled? && !(controller_name == "users" && action_name == "edit_login") && !(controller_name == "sessions" && action_name == "destroy") && !(controller_name == "users" && action_name == "update_login")
+ flash[:alert] = "Due to your staff rank, you are required to enable 2FA."
+ redirect_to :controller => "users", :action => "edit_login", :id => current_user.id
+ end
+ end
+
#roles
def disabled?
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 784647c..cb8dcef 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -21,6 +21,10 @@ class SessionsController < ApplicationController
flash[:alert] = "Your account has been disabled!"
elsif user.banned?
flash[:alert] = "You are banned!"
+ elsif user.totp_enabled && !TOTP.valid?(user.totp_secret, params[:totp_code].to_i)
+ flash[:alert] = "You're doing it wrong!"
+ render action: 'new'
+ return
else
session[:user_id] = user.id
flash[:notice] = "Logged in!"
@@ -110,4 +114,4 @@ class SessionsController < ApplicationController
redirect_to login_path
end
end
-end \ No newline at end of file
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 85e1613..4ad9d59 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -241,6 +241,11 @@ class UsersController < ApplicationController
unless @user.is?(current_user) || admin? && current_user.role > @user.role || superadmin?
flash[:alert] = "You are not allowed to edit this user's login details!"
redirect_to @user
+ return
+ end
+
+ if !@user.totp_enabled
+ @user.update(totp_secret: TOTP.secret)
end
end
@@ -263,6 +268,18 @@ class UsersController < ApplicationController
@user.email_token = SecureRandom.hex(16) if mail_changed
@user.confirmed = !mail_changed
+ if params[:user][:totp_enabled] == "1" && !@user.totp_enabled
+ if TOTP.valid?(@user.totp_secret, params[:totp_code].to_i)
+ @user.totp_enabled = true
+ else
+ flash[:alert] = "Wrong TOTP code!"
+ render action: "edit_login"
+ return
+ end
+ elsif params[:user][:totp_enabled] == "0" && @user.totp_enabled
+ @user.totp_enabled = false
+ end
+
# checking here for password so we can send back changes to the view
if authenticated
if @user.save
@@ -370,7 +387,7 @@ class UsersController < ApplicationController
end
def user_params(add = [])
- a = [:ign, :email, :password, :password_confirmation, :mail_own_thread_reply, :mail_other_thread_reply, :mail_own_blogpost_comment, :mail_other_blogpost_comment, :mail_mention, :public_key] + add
+ a = [:ign, :email, :password, :password_confirmation, :mail_own_thread_reply, :mail_other_thread_reply, :mail_own_blogpost_comment, :mail_other_blogpost_comment, :mail_mention, :public_key, :totp_code] + add
params.require(:user).permit(a)
end
end
diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb
index 0158f59..c7cac42 100644
--- a/app/views/sessions/new.html.erb
+++ b/app/views/sessions/new.html.erb
@@ -16,6 +16,14 @@
<td></td>
<td><%= link_to "Lost your password?", lost_password_users_path %></td>
</tr>
+ <tr>
+ <td><%= label_tag :totp_code %></td>
+ <td><%= text_field_tag :totp_code, nil, placeholder: "123456", required: false %></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>Leave this field blank if you do not have 2FA enabled.</td>
+ </tr>
</table>
<p><%= submit_tag "Log in", class: "btn blue" %></p>
<% end %>
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb
index 2408c3b..3516cc9 100644
--- a/app/views/users/edit.html.erb
+++ b/app/views/users/edit.html.erb
@@ -71,7 +71,7 @@
<p><%= f.submit "Save Profile", class: "btn variable-size left", disabled: (!@user.confirmed? && @user.is?(current_user)) %></p>
<p>
- <%= link_to "Edit Login Details", edit_login_user_path(@user), class: "btn variable-size right" %>
+ <%= link_to "Login Settings", edit_login_user_path(@user), class: "btn variable-size right" %>
<%= link_to "Notification Settings", edit_notifications_user_path(@user), class: "btn variable-size right" %>
<%= link_to "Website Settings", edit_website_settings_user_path(@user), class: "btn variable-size right" %>
</p>
diff --git a/app/views/users/edit_login.html.erb b/app/views/users/edit_login.html.erb
index 2fb9903..c55ace7 100644
--- a/app/views/users/edit_login.html.erb
+++ b/app/views/users/edit_login.html.erb
@@ -1,7 +1,7 @@
<% title "Edit Login Credentials: #{@user.name}" %>
-<%= link_to @user.name, @user %> → Edit Login credentials
-<h1>Edit Login Credentials</h1>
+<%= link_to @user.name, @user %> → Edit Login settings
+<h1>Edit Login Settings</h1>
<%= form_for @user, url: update_login_user_path(@user), method: :put do |f| %>
@@ -25,12 +25,49 @@
<%= f.password_field :password_confirmation %>
</td>
</tr>
+ </tbody>
+ </table>
+ <hr>
+ <table>
+ <tbody>
+ <tr>
+ <td>2FA Enabled</td>
+ <td>
+ <%= f.check_box :totp_enabled %>
+ </td>
+ </tr>
+ <tr>
+ <td>TOTP Secret</td>
+ <td>
+ <% if !@user.totp_enabled? %>
+ <%= f.text_field :totp_secret, :readonly => true %>
+ <% else %>
+ <i>2FA is currently enabled. Disable 2FA to generate a new secret.</i>
+ <% end %>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <hr>
+ <table>
+ <tbody>
<tr>
<td>Current password</td>
<td>
<%= password_field_tag :current_password, nil, disabled: !@user.is?(current_user) %>
</td>
</tr>
+ <% if !@user.totp_enabled? %>
+ <tr>
+ <td>TOTP Code</td>
+ <td>
+ <%= text_field_tag :totp_code, nil, disabled: !@user.is?(current_user) %>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><i>Leave this field blank if you are not enabling 2FA.</i></td>
+ <% end %>
</tbody>
</table>
<p><%= f.submit "Save Changes", class: "btn blue left" %></p>
diff --git a/db/migrate/20180606223258_add_totp_to_users.rb b/db/migrate/20180606223258_add_totp_to_users.rb
new file mode 100644
index 0000000..7113c0f
--- /dev/null
+++ b/db/migrate/20180606223258_add_totp_to_users.rb
@@ -0,0 +1,6 @@
+class AddTotpToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :totp_secret, :string
+ add_column :users, :totp_enabled, :boolean, default: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 183a432..1e4d5f4 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: 20171013001146) do
+ActiveRecord::Schema.define(version: 20180606223258) do
create_table "badges", force: :cascade do |t|
t.string "name", limit: 191
@@ -154,6 +154,8 @@ ActiveRecord::Schema.define(version: 20171013001146) do
t.boolean "header_scroll", default: false
t.boolean "dark", default: false
t.text "public_key", limit: 65535
+ t.string "totp_secret", limit: 255
+ t.boolean "totp_enabled", default: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree