Merge pull request #957 from chrishunt/chrishunt/lock-down-the-base

Add 'login required' site setting
This commit is contained in:
Sam 2013-06-04 17:22:08 -07:00
commit 21b3359ea4
15 changed files with 117 additions and 7 deletions

View File

@ -166,6 +166,16 @@ Discourse = Ember.Application.createWithMixins({
return loginController.authenticationComplete(options); return loginController.authenticationComplete(options);
}, },
loginRequired: function() {
return (
Discourse.SiteSettings.login_required && !Discourse.User.current()
);
}.property(),
redirectIfLoginRequired: function(route) {
if(this.get('loginRequired')) { route.transitionTo('login'); }
},
/** /**
Our own $.ajax method. Makes sure the .then method executes in an Ember runloop 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 for performance reasons. Also automatically adjusts the URL to support installs

View File

@ -28,7 +28,7 @@ Discourse.StaticController = Discourse.Controller.extend({
}); });
Discourse.StaticController.reopenClass({ Discourse.StaticController.reopenClass({
pages: ['faq', 'tos', 'privacy'] pages: ['faq', 'tos', 'privacy', 'login']
}); });

View File

@ -8,6 +8,8 @@
**/ **/
Discourse.FilteredListRoute = Discourse.Route.extend({ Discourse.FilteredListRoute = Discourse.Route.extend({
redirect: function() { Discourse.redirectIfLoginRequired(this); },
exit: function() { exit: function() {
this._super(); this._super();

View File

@ -8,6 +8,8 @@
**/ **/
Discourse.ListCategoriesRoute = Discourse.Route.extend({ Discourse.ListCategoriesRoute = Discourse.Route.extend({
redirect: function() { Discourse.redirectIfLoginRequired(this); },
events: { events: {
createCategory: function() { createCategory: function() {

View File

@ -8,6 +8,8 @@
**/ **/
Discourse.TopicRoute = Discourse.Route.extend({ Discourse.TopicRoute = Discourse.Route.extend({
redirect: function() { Discourse.redirectIfLoginRequired(this); },
events: { events: {
// Modals that can pop up within a topic // Modals that can pop up within a topic

View File

@ -29,10 +29,34 @@
{{/if}} {{/if}}
</li> </li>
<li> <li>
<a class='icon expand' href='#' data-dropdown="search-dropdown" title='{{i18n search.title}}'><i class='icon-search'></i></a> {{#if Discourse.loginRequired}}
<a class='icon expand' href='#' {{action showLogin}}>
<i class='icon-search'></i>
</a>
{{else}}
<a class='icon expand'
href='#'
data-dropdown="search-dropdown"
title='{{i18n search.title}}'>
<i class='icon-search'></i>
</a>
{{/if}}
</li> </li>
<li class='categories dropdown'> <li class='categories dropdown'>
<a class='icon' data-dropdown="site-map-dropdown" href="#" title='{{i18n site_map}}'><i class='icon-reorder'></i></a> {{#if Discourse.loginRequired}}
<a class='icon'
href="#"
{{action showLogin}}>
<i class='icon-reorder'></i>
</a>
{{else}}
<a class='icon'
data-dropdown="site-map-dropdown"
href="#"
title='{{i18n site_map}}'>
<i class='icon-reorder'></i>
</a>
{{/if}}
{{#if currentUser.site_flagged_posts_count}} {{#if currentUser.site_flagged_posts_count}}
<a href='/admin/flags/active' title='{{i18n notifications.total_flagged}}' class='badge-notification flagged-posts'>{{currentUser.site_flagged_posts_count}}</a> <a href='/admin/flags/active' title='{{i18n notifications.total_flagged}}' class='badge-notification flagged-posts'>{{currentUser.site_flagged_posts_count}}</a>
{{/if}} {{/if}}

View File

@ -22,6 +22,7 @@ class ApplicationController < ActionController::Base
before_filter :preload_json before_filter :preload_json
before_filter :check_xhr before_filter :check_xhr
before_filter :set_locale before_filter :set_locale
before_filter :redirect_to_login_if_required
rescue_from Exception do |exception| rescue_from Exception do |exception|
unless [ ActiveRecord::RecordNotFound, ActionController::RoutingError, unless [ ActiveRecord::RecordNotFound, ActionController::RoutingError,
@ -280,6 +281,10 @@ class ApplicationController < ActionController::Base
raise Discourse::NotLoggedIn.new unless current_user.present? raise Discourse::NotLoggedIn.new unless current_user.present?
end end
def redirect_to_login_if_required
redirect_to :login if SiteSetting.login_required? && !current_user
end
def render_not_found_page(status=404) def render_not_found_page(status=404)
f = Topic.where(deleted_at: nil, archetype: "regular") f = Topic.where(deleted_at: nil, archetype: "regular")
@latest = f.order('views desc').take(10) @latest = f.order('views desc').take(10)

View File

@ -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 # 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 # once that happens you can't log in with social
skip_before_filter :verify_authenticity_token, only: [:create] skip_before_filter :verify_authenticity_token, only: [:create]
skip_before_filter :redirect_to_login_if_required
def create def create
requires_parameter(:login, :password) requires_parameter(:login, :password)

View File

@ -1,6 +1,6 @@
class StaticController < ApplicationController class StaticController < ApplicationController
skip_before_filter :check_xhr skip_before_filter :check_xhr, :redirect_to_login_if_required
def show def show
@ -30,8 +30,13 @@ class StaticController < ApplicationController
def enter def enter
params.delete(:username) params.delete(:username)
params.delete(:password) 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
end end

View File

@ -134,6 +134,8 @@ class SiteSetting < ActiveRecord::Base
setting(:send_welcome_message, true) setting(:send_welcome_message, true)
client_setting(:login_required, false)
client_setting(:enable_local_logins, true) client_setting(:enable_local_logins, true)
client_setting(:enable_local_account_create, true) client_setting(:enable_local_account_create, true)

View File

@ -0,0 +1,13 @@
<ul class="nav-pills">
<li><a class='active' href="<%=login_path%>">Welcome</a></li>
<li><a href="<%=faq_path%>">FAQ</a></li>
<li><a href="<%=tos_path%>">Terms of Service</a></li>
<li><a href="<%=privacy_path%>">Privacy</a></li>
</ul>
<h2><a href="#welcome">Welcome to <%= SiteSetting.title %></a></h2>
<p>
We are excited to have you participate in <%= SiteSetting.title %>. Please
create an account or login to continue.
</p>

View File

@ -501,6 +501,8 @@ en:
# TODO: perhaps we need a way of protecting these settings for hosted solution, global settings ... # 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_logins: "Enable local authentication"
enable_local_account_create: "Enable local account creation" enable_local_account_create: "Enable local account creation"
enable_google_logins: "Enable Google authentication" enable_google_logins: "Enable Google authentication"

View File

@ -103,6 +103,7 @@ Discourse::Application.routes.draw do
resources :static resources :static
post 'login' => 'static#enter' post 'login' => 'static#enter'
get 'login' => 'static#show', id: 'login'
get 'faq' => 'static#show', id: 'faq' get 'faq' => 'static#show', id: 'faq'
get 'tos' => 'static#show', id: 'tos' get 'tos' => 'static#show', id: 'tos'
get 'privacy' => 'static#show', id: 'privacy' get 'privacy' => 'static#show', id: 'privacy'

View File

@ -24,4 +24,26 @@ describe StaticController do
end end
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 end

View File

@ -435,6 +435,25 @@ describe TopicsController do
end 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 end
describe '#feed' do describe '#feed' do