Merged pull request #50.

This commit is contained in:
Logan Fick
2018-06-10 21:08:22 -04:00
10 changed files with 95 additions and 8 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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?

View File

@@ -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
end

View File

@@ -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

View File

@@ -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 %>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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