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 829993e388..40bea06ff1 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 5819336521..20884d459c 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 34180883f5..a07f90da0d 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 a7c6f66e8a..734b2cc169 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 834ee57c30..e2341e760a 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 fe600a116d..fe0ea2d0f8 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 e2341e760a..fecde8b49b 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 2e2bccc510..10f652fb03 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 228db475c0..2c7bedf510 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 cfea2889e1..df4d1d5f2f 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}}