Merge pull request #957 from chrishunt/chrishunt/lock-down-the-base
Add 'login required' site setting
This commit is contained in:
commit
21b3359ea4
|
@ -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
|
||||||
|
|
|
@ -28,7 +28,7 @@ Discourse.StaticController = Discourse.Controller.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.StaticController.reopenClass({
|
Discourse.StaticController.reopenClass({
|
||||||
pages: ['faq', 'tos', 'privacy']
|
pages: ['faq', 'tos', 'privacy', 'login']
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -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"
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue