diff options
author | Logan Fick <logaldeveloper@protonmail.com> | 2018-06-10 21:08:22 -0400 |
---|---|---|
committer | Logan Fick <logaldeveloper@protonmail.com> | 2018-06-10 21:08:22 -0400 |
commit | 37be5f56b68f3deda5b8c769c87317aaf23a232f (patch) | |
tree | a2cf8d57735b6fbd7627a271e66f373606b5ae63 | |
parent | 3d8199c9f9186cec4b331edc50d99e5f1d5d11f2 (diff) | |
parent | 09e3312ccaf3215876444c6f3afc08b0c7eea4ce (diff) |
Merged pull request #50.
-rw-r--r-- | Gemfile | 1 | ||||
-rw-r--r-- | Gemfile.lock | 6 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 10 | ||||
-rw-r--r-- | app/controllers/sessions_controller.rb | 6 | ||||
-rw-r--r-- | app/controllers/users_controller.rb | 19 | ||||
-rw-r--r-- | app/views/sessions/new.html.erb | 8 | ||||
-rw-r--r-- | app/views/users/edit.html.erb | 2 | ||||
-rw-r--r-- | app/views/users/edit_login.html.erb | 41 | ||||
-rw-r--r-- | db/migrate/20180606223258_add_totp_to_users.rb | 6 | ||||
-rw-r--r-- | db/schema.rb | 4 |
10 files changed, 95 insertions, 8 deletions
@@ -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 |