mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-12-03 12:27:35 -05:00
FEATURE: magic login route for admin when SSO is enabled
This commit is contained in:
parent
10270593a4
commit
2932284293
6 changed files with 136 additions and 2 deletions
|
@ -6,7 +6,7 @@ require_dependency 'rate_limiter'
|
|||
class UsersController < ApplicationController
|
||||
|
||||
skip_before_filter :authorize_mini_profiler, only: [:avatar]
|
||||
skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :account_created, :activate_account, :perform_account_activation, :authorize_email, :user_preferences_redirect, :avatar, :my_redirect, :toggle_anon]
|
||||
skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :account_created, :activate_account, :perform_account_activation, :authorize_email, :user_preferences_redirect, :avatar, :my_redirect, :toggle_anon, :admin_login]
|
||||
|
||||
before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect, :upload_user_image, :pick_avatar, :destroy_user_image, :destroy, :check_emails]
|
||||
before_filter :respond_to_suspicious_request, only: [:create]
|
||||
|
@ -23,7 +23,8 @@ class UsersController < ApplicationController
|
|||
:perform_account_activation,
|
||||
:send_activation_email,
|
||||
:authorize_email,
|
||||
:password_reset]
|
||||
:password_reset,
|
||||
:admin_login]
|
||||
|
||||
def index
|
||||
end
|
||||
|
@ -344,6 +345,46 @@ class UsersController < ApplicationController
|
|||
@success = I18n.t(message)
|
||||
end
|
||||
|
||||
def admin_login
|
||||
|
||||
unless SiteSetting.enable_sso && !current_user
|
||||
return redirect_to path("/")
|
||||
end
|
||||
|
||||
if request.put?
|
||||
RateLimiter.new(nil, "admin-login-hr-#{request.remote_ip}", 6, 1.hour).performed!
|
||||
RateLimiter.new(nil, "admin-login-min-#{request.remote_ip}", 3, 1.minute).performed!
|
||||
|
||||
user = User.where(email: params[:email], admin: true).where.not(id: Discourse::SYSTEM_USER_ID).first
|
||||
if user
|
||||
email_token = user.email_tokens.create(email: user.email)
|
||||
Jobs.enqueue(:user_email, type: :admin_login, user_id: user.id, email_token: email_token.token)
|
||||
@message = I18n.t("admin_login.success")
|
||||
else
|
||||
@message = I18n.t("admin_login.error")
|
||||
end
|
||||
elsif params[:token].present?
|
||||
# token recieved, try to login
|
||||
if EmailToken.valid_token_format?(params[:token])
|
||||
@user = EmailToken.confirm(params[:token])
|
||||
if @user && @user.admin?
|
||||
# Log in user
|
||||
log_on_user(@user)
|
||||
return redirect_to path("/")
|
||||
else
|
||||
@message = I18n.t("admin_login.error")
|
||||
end
|
||||
else
|
||||
@message = I18n.t("admin_login.error")
|
||||
end
|
||||
end
|
||||
|
||||
render layout: false
|
||||
rescue RateLimiter::LimitExceeded
|
||||
@message = I18n.t("rate_limiter.slow_down")
|
||||
render layout: false
|
||||
end
|
||||
|
||||
def toggle_anon
|
||||
user = AnonymousShadowCreator.get_master(current_user) ||
|
||||
AnonymousShadowCreator.get(current_user)
|
||||
|
|
|
@ -31,6 +31,12 @@ class UserNotifications < ActionMailer::Base
|
|||
email_token: opts[:email_token])
|
||||
end
|
||||
|
||||
def admin_login(user, opts={})
|
||||
build_email( user.email,
|
||||
template: "user_notifications.admin_login",
|
||||
email_token: opts[:email_token])
|
||||
end
|
||||
|
||||
def account_created(user, opts={})
|
||||
build_email( user.email, template: "user_notifications.account_created", email_token: opts[:email_token])
|
||||
end
|
||||
|
|
16
app/views/users/admin_login.html.erb
Normal file
16
app/views/users/admin_login.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Admin Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<% if @message %>
|
||||
<%= @message %>
|
||||
<% else %>
|
||||
<%=form_tag({}, method: :put) do %>
|
||||
<%= label_tag(:email, t('admin_login.email_input')) %>
|
||||
<%= text_field_tag(:email) %><br><br>
|
||||
<%= submit_tag t('admin_login.submit_button') %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
|
@ -1906,6 +1906,16 @@ en:
|
|||
Click the following link to choose a password:
|
||||
%{base_url}/users/password-reset/%{email_token}
|
||||
|
||||
admin_login:
|
||||
subject_template: "[%{site_name}] Login"
|
||||
text_body_template: |
|
||||
Somebody asked to login to your account on [%{site_name}](%{base_url}).
|
||||
|
||||
If you did not make this request, you can safely ignore this email.
|
||||
|
||||
Click the following link to login:
|
||||
%{base_url}/users/admin-login/%{email_token}
|
||||
|
||||
account_created:
|
||||
subject_template: "[%{site_name}] Your New Account"
|
||||
text_body_template: |
|
||||
|
@ -2442,3 +2452,9 @@ en:
|
|||
leader: |
|
||||
Blah blah blah
|
||||
Blah blah blah
|
||||
|
||||
admin_login:
|
||||
success: "Email Sent"
|
||||
error: "Error!"
|
||||
email_input: "Admin Email"
|
||||
submit_button: "Send Email"
|
||||
|
|
|
@ -229,6 +229,10 @@ Discourse::Application.routes.draw do
|
|||
get "privacy" => "static#show", id: "privacy", as: 'privacy'
|
||||
get "signup" => "list#latest"
|
||||
|
||||
get "users/admin-login" => "users#admin_login"
|
||||
put "users/admin-login" => "users#admin_login"
|
||||
get "users/admin-login/:token" => "users#admin_login"
|
||||
|
||||
post "users/toggle-anon" => "users#toggle_anon"
|
||||
post "users/read-faq" => "users#read_faq"
|
||||
get "users/search/users" => "users#search_users"
|
||||
|
|
|
@ -315,6 +315,57 @@ describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.admin_login' do
|
||||
let(:admin) { Fabricate(:admin) }
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
context 'enqueues mail' do
|
||||
it 'enqueues mail with admin email and sso enabled' do
|
||||
SiteSetting.enable_sso = true
|
||||
Jobs.expects(:enqueue).with(:user_email, has_entries(type: :admin_login, user_id: admin.id))
|
||||
put :admin_login, email: admin.email
|
||||
end
|
||||
|
||||
it 'does not enqueue mail with admin email and sso disabled' do
|
||||
SiteSetting.enable_sso = false
|
||||
Jobs.expects(:enqueue).never
|
||||
put :admin_login, email: admin.email
|
||||
end
|
||||
|
||||
it 'does not enqueue mail with normal user email and sso enabled' do
|
||||
SiteSetting.enable_sso = true
|
||||
Jobs.expects(:enqueue).never
|
||||
put :admin_login, email: user.email
|
||||
end
|
||||
end
|
||||
|
||||
context 'logs in admin' do
|
||||
it 'does not log in admin with invalid token' do
|
||||
SiteSetting.enable_sso = true
|
||||
get :admin_login, token: "invalid"
|
||||
expect(session[:current_user_id]).to be_blank
|
||||
end
|
||||
|
||||
it 'does not log in admin with valid token and SSO disabled' do
|
||||
SiteSetting.enable_sso = false
|
||||
token = admin.email_tokens.create(email: admin.email).token
|
||||
|
||||
get :admin_login, token: token
|
||||
expect(response).to redirect_to('/')
|
||||
expect(session[:current_user_id]).to be_blank
|
||||
end
|
||||
|
||||
it 'logs in admin with valid token and SSO enabled' do
|
||||
SiteSetting.enable_sso = true
|
||||
token = admin.email_tokens.create(email: admin.email).token
|
||||
|
||||
get :admin_login, token: token
|
||||
expect(response).to redirect_to('/')
|
||||
expect(session[:current_user_id]).to eq(admin.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#toggle_anon' do
|
||||
it 'allows you to toggle anon if enabled' do
|
||||
SiteSetting.allow_anonymous_posting = true
|
||||
|
|
Loading…
Reference in a new issue