From 85ceb5efa704fb816eb4824b954eeb35bf59fbaf Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Tue, 4 Jun 2013 15:30:16 -0700 Subject: [PATCH 1/5] Add 'login required' site setting --- app/models/site_setting.rb | 2 ++ config/locales/server.en.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 829993e388f..40bea06ff1e 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -135,6 +135,8 @@ class SiteSetting < ActiveRecord::Base setting(:send_welcome_message, true) + client_setting(:login_required, false) + client_setting(:enable_local_logins, true) client_setting(:enable_local_account_create, true) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 58193365214..20884d459cd 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -501,6 +501,8 @@ en: # TODO: perhaps we need a way of protecting these settings for hosted solution, global settings ... + login_required: "Require authentication to read posts" + enable_local_logins: "Enable local authentication" enable_local_account_create: "Enable local account creation" enable_google_logins: "Enable Google authentication" From 92a4828f72f8db2aa558bc3810b3a08be59c0a01 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Tue, 4 Jun 2013 15:32:36 -0700 Subject: [PATCH 2/5] Redirect all controllers to login if required We want to skip the filter for sessions controller so that we can login and we want to skip the filter for static pages because those should be visible to visitors. --- app/controllers/application_controller.rb | 5 +++++ app/controllers/session_controller.rb | 1 + app/controllers/static_controller.rb | 2 +- spec/controllers/topics_controller_spec.rb | 19 +++++++++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 34180883f59..a07f90da0d2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -22,6 +22,7 @@ class ApplicationController < ActionController::Base before_filter :preload_json before_filter :check_xhr before_filter :set_locale + before_filter :redirect_to_login_if_required rescue_from Exception do |exception| unless [ ActiveRecord::RecordNotFound, ActionController::RoutingError, @@ -280,6 +281,10 @@ class ApplicationController < ActionController::Base raise Discourse::NotLoggedIn.new unless current_user.present? end + def redirect_to_login_if_required + redirect_to :login if SiteSetting.login_required? && !current_user + end + def render_not_found_page(status=404) f = Topic.where(deleted_at: nil, archetype: "regular") @latest = f.order('views desc').take(10) diff --git a/app/controllers/session_controller.rb b/app/controllers/session_controller.rb index a7c6f66e8ac..734b2cc169d 100644 --- a/app/controllers/session_controller.rb +++ b/app/controllers/session_controller.rb @@ -4,6 +4,7 @@ class SessionController < ApplicationController # page is going to be empty, this means that server will see an invalid CSRF and blow the session # once that happens you can't log in with social skip_before_filter :verify_authenticity_token, only: [:create] + skip_before_filter :redirect_to_login_if_required def create requires_parameter(:login, :password) diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index 834ee57c305..e2341e760a1 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -1,6 +1,6 @@ class StaticController < ApplicationController - skip_before_filter :check_xhr + skip_before_filter :check_xhr, :redirect_to_login_if_required def show diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb index fe600a116df..fe0ea2d0f86 100644 --- a/spec/controllers/topics_controller_spec.rb +++ b/spec/controllers/topics_controller_spec.rb @@ -435,6 +435,25 @@ describe TopicsController do end + context "when 'login required' site setting has been enabled" do + before { SiteSetting.stubs(:login_required?).returns(true) } + + context 'and the user is logged in' do + before { log_in(:coding_horror) } + + it 'shows the topic' do + get :show, topic_id: topic.id, slug: topic.slug + expect(response).to be_successful + end + end + + context 'and the user is not logged in' do + it 'redirects to the login page' do + get :show, topic_id: topic.id, slug: topic.slug + expect(response).to redirect_to login_path + end + end + end end describe '#feed' do From 978785720a6e374c12a0f9fc00f6b990adc6e4c9 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Tue, 4 Jun 2013 15:34:54 -0700 Subject: [PATCH 3/5] Redirect to root after login if no path provided If we do not do this, then people that login from /login will just be redirected back to the login page. We'd rather have them see the root path. --- app/controllers/static_controller.rb | 11 ++++++++--- spec/controllers/static_controller_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index e2341e760a1..fecde8b49b8 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -30,8 +30,13 @@ class StaticController < ApplicationController def enter params.delete(:username) params.delete(:password) - redirect_to(params[:redirect] || '/') + + redirect_to( + if params[:redirect].blank? || params[:redirect].match(login_path) + root_path + else + params[:redirect] + end + ) end - - end diff --git a/spec/controllers/static_controller_spec.rb b/spec/controllers/static_controller_spec.rb index 2e2bccc510a..10f652fb034 100644 --- a/spec/controllers/static_controller_spec.rb +++ b/spec/controllers/static_controller_spec.rb @@ -24,4 +24,26 @@ describe StaticController do end end + describe '#enter' do + context 'without a redirect path' do + it 'redirects to the root url' do + xhr :post, :enter + expect(response).to redirect_to root_path + end + end + + context 'with a redirect path' do + it 'redirects to the redirect path' do + xhr :post, :enter, redirect: '/foo' + expect(response).to redirect_to '/foo' + end + end + + context 'when the redirect path is the login page' do + it 'redirects to the root url' do + xhr :post, :enter, redirect: login_path + expect(response).to redirect_to root_path + end + end + end end From 789289a290e7b10d813ea4d6baa0dce70bf3d7b5 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Tue, 4 Jun 2013 15:37:53 -0700 Subject: [PATCH 4/5] Show login modal on header buttons if required --- app/assets/javascripts/discourse.js | 6 ++++ .../discourse/templates/header.js.handlebars | 28 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js index 228db475c01..2c7bedf5107 100644 --- a/app/assets/javascripts/discourse.js +++ b/app/assets/javascripts/discourse.js @@ -162,6 +162,12 @@ Discourse = Ember.Application.createWithMixins({ return loginController.authenticationComplete(options); }, + loginRequired: function() { + return ( + Discourse.SiteSettings.login_required && !Discourse.User.current() + ); + }.property(), + /** Our own $.ajax method. Makes sure the .then method executes in an Ember runloop for performance reasons. Also automatically adjusts the URL to support installs diff --git a/app/assets/javascripts/discourse/templates/header.js.handlebars b/app/assets/javascripts/discourse/templates/header.js.handlebars index cfea2889e1f..df4d1d5f2f8 100644 --- a/app/assets/javascripts/discourse/templates/header.js.handlebars +++ b/app/assets/javascripts/discourse/templates/header.js.handlebars @@ -29,10 +29,34 @@ {{/if}}
  • - + {{#if Discourse.loginRequired}} + + + + {{else}} + + + + {{/if}}