Remove unusued site_settings, show checkbox in UI for boolean values, remove restrict_access

boolean to avoid locking yourself out by setting access_password to empty string. Minor
UI tweaks.
This commit is contained in:
Robin Ward
2013-03-01 12:45:25 -05:00
parent 0c8c41b131
commit d2596c3c4c
26 changed files with 245 additions and 158 deletions

View File

@ -16,15 +16,18 @@ Discourse.AdminSiteSettingsController = Ember.ArrayController.extend(Discourse.P
@property filteredContent
**/
filteredContent: (function() {
var filter,
_this = this;
// If we have no content, don't bother filtering anything
if (!this.present('content')) return null;
var filter;
if (this.get('filter')) {
filter = this.get('filter').toLowerCase();
}
var adminSettingsController = this;
return this.get('content').filter(function(item, index, enumerable) {
if (_this.get('onlyOverridden') && !item.get('overridden')) return false;
if (adminSettingsController.get('onlyOverridden') && !item.get('overridden')) return false;
if (filter) {
if (item.get('setting').toLowerCase().indexOf(filter) > -1) return true;
if (item.get('description').toLowerCase().indexOf(filter) > -1) return true;

View File

@ -8,48 +8,89 @@
**/
Discourse.SiteSetting = Discourse.Model.extend({
// Whether a property is short.
short: (function() {
if (this.blank('value')) return true;
return this.get('value').toString().length < 80;
}).property('value'),
/**
Is the boolean setting true?
// Whether the site setting has changed
dirty: (function() {
return this.get('originalValue') !== this.get('value');
}).property('originalValue', 'value'),
@property enabled
**/
enabled: function(key, value) {
overridden: (function() {
var defaultVal, val;
val = this.get('value');
defaultVal = this.get('default');
if (val && defaultVal) {
return val.toString() !== defaultVal.toString();
if (arguments.length === 1) {
// get the boolean value of the setting
if (this.blank('value')) return false;
return this.get('value') === 'true';
} else {
// set the boolean value of the setting
this.set('value', value ? 'true' : 'false');
// We save booleans right away, it's not like a text field where it makes sense to
// undo what you typed in.
this.save();
}
return val !== defaultVal;
}).property('value'),
}.property('value'),
/**
Has the user changed the setting? If so we should save it.
@property dirty
**/
dirty: function() {
return this.get('originalValue') !== this.get('value');
}.property('originalValue', 'value'),
/**
Has the setting been overridden from its default value?
@property overridden
**/
overridden: function() {
var val = this.get('value');
var defaultVal = this.get('default');
if (val === null) val = '';
if (defaultVal === null) defaultVal = '';
return val.toString() !== defaultVal.toString();
}.property('value'),
/**
Reset the setting to its original value.
@method resetValue
**/
resetValue: function() {
this.set('value', this.get('originalValue'));
},
/**
Save the setting's value.
@method save
**/
save: function() {
// Update the setting
var _this = this;
var setting = this;
return jQuery.ajax("/admin/site_settings/" + (this.get('setting')), {
data: { value: this.get('value') },
type: 'PUT',
success: function() {
_this.set('originalValue', _this.get('value'));
setting.set('originalValue', setting.get('value'));
}
});
}
});
Discourse.SiteSetting.reopenClass({
/**
Retrieve all settings from the server
@method findAll
**/
findAll: function() {
var result;
result = Em.A();
var result = Em.A();
jQuery.get("/admin/site_settings", function(settings) {
return settings.each(function(s) {
s.originalValue = s.value;

View File

@ -11,24 +11,4 @@
</div>
{{#collection contentBinding="filteredContent" classNames="form-horizontal settings" itemClass="row setting"}}
{{#with view.content}}
<div class='span4 offset1'>
{{unbound setting}}
</div>
<div {{bindAttr class=":span11 overridden:overridden"}}>
{{view Ember.TextField valueBinding="value" classNames="input-xxlarge"}}
<div class='desc'>{{unbound description}}</div>
</div>
{{#if dirty}}
<div class='span3'>
<button class='btn ok' {{action save this target="controller"}}><i class='icon-ok'></i></button>
<button class='btn cancel' {{action cancel this target="controller"}}><i class='icon-remove'></i></button>
</div>
{{else}}
{{#if overridden}}
<button class='btn' href='#' {{action resetDefault this target="controller"}}>{{i18n admin.site_settings.reset}}</button>
{{/if}}
{{/if}}
{{/with}}
{{/collection}}
{{collection contentBinding="filteredContent" classNames="form-horizontal settings" itemViewClass="Discourse.SiteSettingView"}}

View File

@ -0,0 +1,9 @@
{{#with view.content}}
<div class='span4 offset1'>
<h3>{{unbound setting}}</h3>
</div>
<div class="span11">
{{view Ember.Checkbox checkedBinding="enabled" value="true"}}
{{unbound description}}
</div>
{{/with}}

View File

@ -0,0 +1,19 @@
{{#with view.content}}
<div class='span4 offset1'>
<h3>{{unbound setting}}</h3>
</div>
<div class="span11">
{{view Ember.TextField valueBinding="value" classNames="input-xxlarge"}}
<div class='desc'>{{unbound description}}</div>
</div>
{{#if dirty}}
<div class='span3'>
<button class='btn ok' {{action save this}}><i class='icon-ok'></i></button>
<button class='btn cancel' {{action cancel this}}><i class='icon-remove'></i></button>
</div>
{{else}}
{{#if overridden}}
<button class='btn' href='#' {{action resetDefault this}}>{{i18n admin.site_settings.reset}}</button>
{{/if}}
{{/if}}
{{/with}}

View File

@ -4,7 +4,7 @@
A view that wraps the ACE editor (http://ace.ajax.org/)
@class AceEditorView
@extends Em.View
@extends Discourse.View
@namespace Discourse
@module Discourse
**/

View File

@ -4,7 +4,7 @@
A view to handle site customizations
@class AdminCustomizeView
@extends Em.View
@extends Discourse.View
@namespace Discourse
@module Discourse
**/

View File

@ -2,7 +2,7 @@
The default view in the admin section
@class AdminDashboardView
@extends Em.View
@extends Discourse.View
@namespace Discourse
@module Discourse
**/

View File

@ -0,0 +1,22 @@
/**
A view to display a site setting with edit controls
@class SiteSettingView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.SiteSettingView = Discourse.View.extend({
classNameBindings: [':row', ':setting', 'content.overridden'],
templateName: function() {
// If we're editing a boolean, return a different template
if (this.get('content.type') === 'bool') return 'admin/templates/site_settings/setting_bool'
// Default to string editor
return 'admin/templates/site_settings/setting_string';
}.property('content.type')
});

View File

@ -128,15 +128,25 @@
.settings {
.setting {
padding-bottom: 20px;
.overridden {
input[type=text] {
background-color: lighten($yellow, 40%);
}
}
.desc {
padding-top: 3px;
color: darken($white, 40%);
}
h3 {
font-size: 13px;
font-weight: normal;
}
}
.setting.overridden {
input[type=text] {
background-color: lighten($yellow, 40%);
}
h3 {
color: darken($yellow, 20%);
}
}
}

View File

@ -146,7 +146,7 @@ class ApplicationController < ActionController::Base
return false if current_user.present?
# Don't cache if there's restricted access
return false if SiteSetting.restrict_access?
return false if SiteSetting.access_password.present?
true
end
@ -216,7 +216,7 @@ class ApplicationController < ActionController::Base
def check_restricted_access
# note current_user is defined in the CurrentUser mixin
if SiteSetting.restrict_access? && cookies[:_access] != SiteSetting.access_password
if SiteSetting.access_password.present? && cookies[:_access] != SiteSetting.access_password
redirect_to request_access_path(:return_path => request.fullpath)
return false
end

View File

@ -15,7 +15,7 @@ class InvitesController < ApplicationController
user.enqueue_welcome_message('welcome_invite') if user.send_welcome_message
# We skip the access password if we come in via an invite link
cookies.permanent['_access'] = SiteSetting.access_password if SiteSetting.restrict_access?
cookies.permanent['_access'] = SiteSetting.access_password if SiteSetting.access_password.present?
topic = invite.topics.first
if topic.present?

View File

@ -4,7 +4,7 @@ class RobotsTxtController < ApplicationController
skip_before_filter :check_restricted_access
def index
path = if SiteSetting.allow_index_in_robots_txt && !SiteSetting.restrict_access
path = if SiteSetting.allow_index_in_robots_txt && SiteSetting.access_password.blank?
:index
else
:no_index

View File

@ -16,7 +16,6 @@ class SiteSetting < ActiveRecord::Base
setting(:company_short_name, 'Unconfigured Forum')
setting(:company_domain, 'www.example.com')
client_setting(:traditional_markdown_linebreaks, false)
client_setting(:popup_delay, 1500)
client_setting(:top_menu, 'popular|new|unread|favorited|categories')
client_setting(:post_menu, 'like|edit|flag|delete|share|bookmark|reply')
client_setting(:track_external_right_clicks, false)
@ -48,7 +47,6 @@ class SiteSetting < ActiveRecord::Base
setting(:port, Rails.env.development? ? 3000 : '')
setting(:enable_private_messages, true)
setting(:use_ssl, false)
setting(:restrict_access, false)
setting(:access_password)
setting(:queue_jobs, !Rails.env.test?)
setting(:crawl_images, !Rails.env.test?)

View File

@ -1,6 +1,7 @@
development:
adapter: postgresql
database: discourse_development
min_messages: warning
host: localhost
pool: 5
timeout: 5000
@ -13,6 +14,7 @@ development:
test:
adapter: postgresql
database: discourse_test
min_messages: warning
host: localhost
pool: 5
timeout: 5000

View File

@ -212,7 +212,6 @@ nl:
discourse_org_access_key: "De toegangscode voor het discourse.org nickname-register"
title: "titel van deze website"
restrict_access: "beperk forumtoegang aan gebruikers tenzij dit wachtwoord door hen is ingevuld"
access_password: "restrict_access (Beperk Toegang) staat aan. Zorg ervoor dat dit wachtwoord staat ingevuld"
queue_jobs: "zet verschillende taken in een queue binnen sidekiq, als ongeldige queues zich op dezelfde lijn bevinden"
crawl_images: "zet het ophalen van afbeeldingen van externe bronnen aan"
@ -222,7 +221,6 @@ nl:
imgur_endpoint: "endpoint voor het uploaden van imgur.com-afbeeldingen"
max_image_width: "maximale breedte voor een afbeelding in een post"
category_featured_topics: "aantal topics die worden weergegeven in de categorie-lijst"
popup_delay: "Lengte van tijd in ms voordat popups zich tonen op het scherm"
add_rel_nofollow_to_user_content: "Voeg 'rel nofollow' toe aan alle gebruikers-content behalve voor interne links (inclusief parent domeinen). NB: Als je dit verandert moet je ook alle 'baked markdown' updaten"
exclude_rel_nofollow_domains: "Een commagescheiden lijst van domeinen waar 'nofollow' niet is toegevoegd. (voorbeelddomein.com zal automatisch sub.voorbeelddomein.com toestaan)"
post_excerpt_maxlength: "Maximale lengte in karakters van een post-uittreksel."

View File

@ -260,7 +260,6 @@ en:
company_full_name: "The full name of the company that runs this site, used in legal documents like the /tos"
company_short_name: "The short name of the company that runs this site, used in legal documents like the /tos"
company_domain: "The domain name owned by the company that runs this site, used in legal documents like the /tos"
restrict_access: "Restrict forum access unless a password is entered"
access_password: "When restricted access is enabled, this password must be entered"
queue_jobs: "Queue various jobs in sidekiq, if false queues are inline"
crawl_images: "Enable retrieving images from third party sources to insert width and height dimensions"
@ -270,7 +269,6 @@ en:
imgur_endpoint: "End point for uploading imgur.com images"
max_image_width: "Maximum allowed width of images in a post"
category_featured_topics: "Number of topics displayed per category in the /categories page"
popup_delay: "Milliseconds of hover time before popups appear on the screen"
add_rel_nofollow_to_user_content: "Add rel nofollow to all submitted user content, except for internal links (including parent domains) changing this requires you update all your baked markdown"
exclude_rel_nofollow_domains: "A comma delimited list of domains where nofollow is not added (tld.com will automatically allow sub.tld.com as well)"

View File

@ -245,7 +245,6 @@ fr:
discourse_org_access_key: "La clé d'accès utilisée pour le registre de pseudos de discourse.org"
educate_until_posts: "Afficher les aides à la saisie tant que l'utilisateur n'a pas posté ce nombre de messages"
title: "titre de ce site internet"
restrict_access: "restreindre l'acces au forum à ceux qui possèdent ce mot de passe"
access_password: "Si l'accès restreint est activé, assurez-vous que le mot de passe soit saisi ici."
queue_jobs: "mettre les différents jobs en attente sur différentes queues, si false les queues sont en file"
crawl_images: "permettre la récupération des images provenant de sources tierces"
@ -255,7 +254,6 @@ fr:
imgur_endpoint: "point d'arrêt pour le chargement d'images sur imgur.com"
max_image_width: "largeur maximale des images d'un message"
category_featured_topics: "nombre de discussions affichées dans la liste par catégories"
popup_delay: "Laps de temps en ms avant l'affichage des popups à l'écran"
add_rel_nofollow_to_user_content: "Ajouter rel nofollow à tous les contenus des utilisateurs, sauf les liens internes (incluant les domaines parents) Modifier ceci requiert une mise à jour de tout votre markdown"
exclude_rel_nofollow_domains: "Une liste séparée par des virgules contenant les noms de domaines de premier niveau pour lesquels il faut ajouter un attribut nofollow (exemple.com va automatiquement fonctionner aussi avec sous.domaine.exemple.com)"
post_excerpt_maxlength: "Longueur maximale d'un extrait de message."

View File

@ -239,7 +239,6 @@ nl:
discourse_org_access_key: "De toegangscode voor het discourse.org nickname-register"
title: "titel van deze website"
restrict_access: "beperk forumtoegang aan gebruikers tenzij dit wachtwoord door hen is ingevuld"
access_password: "restrict_access (Beperk Toegang) staat aan. Zorg ervoor dat dit wachtwoord staat ingevuld"
queue_jobs: "zet verschillende taken in een queue binnen sidekiq, als ongeldige queues zich op dezelfde lijn bevinden"
crawl_images: "zet het ophalen van afbeeldingen van externe bronnen aan"
@ -249,7 +248,6 @@ nl:
imgur_endpoint: "endpoint voor het uploaden van imgur.com-afbeeldingen"
max_image_width: "maximale breedte voor een afbeelding in een post"
category_featured_topics: "aantal topics die worden weergegeven in de categorie-lijst"
popup_delay: "Lengte van tijd in ms voordat popups zich tonen op het scherm"
add_rel_nofollow_to_user_content: "Voeg 'rel nofollow' toe aan alle gebruikers-content behalve voor interne links (inclusief parent domeinen). NB: Als je dit verandert moet je ook alle 'baked markdown' updaten"
exclude_rel_nofollow_domains: "Een commagescheiden lijst van domeinen waar 'nofollow' niet is toegevoegd. (voorbeelddomein.com zal automatisch sub.voorbeelddomein.com toestaan)"
post_excerpt_maxlength: "Maximale lengte in karakters van een post-uittreksel."

View File

@ -254,7 +254,6 @@ pseudo:
íɳ łéǧáł ďóčůɱéɳťš łíǩé ťĥé /ťóš ]]'
company_domain: ! '[[ Ťĥé ďóɱáíɳ ɳáɱé óŵɳéď ƀý ťĥé čóɱƿáɳý ťĥáť řůɳš ťĥíš šíťé,
ůšéď íɳ łéǧáł ďóčůɱéɳťš łíǩé ťĥé /ťóš ]]'
restrict_access: ! '[[ Řéšťříčť ƒóřůɱ áččéšš ůɳłéšš á ƿáššŵóřď íš éɳťéřéď ]]'
access_password: ! '[[ Ŵĥéɳ řéšťříčťéď áččéšš íš éɳáƀłéď, ťĥíš ƿáššŵóřď ɱůšť ƀé
éɳťéřéď ]]'
queue_jobs: ! '[[ Ƣůéůé νáříóůš ʲóƀš íɳ šíďéǩíƣ, íƒ ƒáłšé ƣůéůéš ářé íɳłíɳé ]]'
@ -270,8 +269,6 @@ pseudo:
max_image_width: ! '[[ Ϻáхíɱůɱ áłłóŵéď ŵíďťĥ óƒ íɱáǧéš íɳ á ƿóšť ]]'
category_featured_topics: ! '[[ Ѝůɱƀéř óƒ ťóƿíčš ďíšƿłáýéď ƿéř čáťéǧóřý íɳ ťĥé
/čáťéǧóříéš ƿáǧé ]]'
popup_delay: ! '[[ Ϻíłłíšéčóɳďš óƒ ĥóνéř ťíɱé ƀéƒóřé ƿóƿůƿš áƿƿéář óɳ ťĥé ščřééɳ
]]'
add_rel_nofollow_to_user_content: ! '[[ Áďď řéł ɳóƒółłóŵ ťó áłł šůƀɱíťťéď ůšéř
čóɳťéɳť, éхčéƿť ƒóř íɳťéřɳáł łíɳǩš (íɳčłůďíɳǧ ƿářéɳť ďóɱáíɳš) čĥáɳǧíɳǧ ťĥíš
řéƣůířéš ýóů ůƿďáťé áłł ýóůř ƀáǩéď ɱářǩďóŵɳ ]]'

View File

@ -101,6 +101,7 @@ module Search
return nil if term.blank?
sanitized_term = PG::Connection.escape_string(term.gsub(/[:()&!]/,'')) # Instead of original term.gsub(/[^0-9a-zA-Z_ ]/, '')
# We are stripping only symbols taking place in FTS and simply sanitizing the rest.
# really short terms are totally pointless
@ -117,7 +118,7 @@ module Search
db_result = []
[user_query_sql, category_query_sql, topic_query_sql].each do |sql|
db_result += ActiveRecord::Base.exec_sql(sql , query: terms.join(" & "),locale: current_locale_long, limit: (Search.per_facet + 1)).to_a
db_result += ActiveRecord::Base.exec_sql(sql , query: terms.join(" & "), locale: current_locale_long, limit: (Search.per_facet + 1)).to_a
end
end

View File

@ -51,10 +51,12 @@ module SiteSettingExtension
# Retrieve all settings
def all_settings
@defaults.map do |s, v|
value = send(s)
{setting: s,
description: description(s),
default: v,
value: send(s).to_s}
type: get_data_type_string(value),
value: value.to_s}
end
end
@ -169,6 +171,16 @@ module SiteSettingExtension
protected
# We're currently in the process of refactoring our Enums. When that's
# done we should pop back and fix this to something better.
def get_data_type_string(val)
case get_data_type(val)
when Types::String then 'string'
when Types::Fixnum then 'number'
when Types::Bool then 'bool'
end
end
def get_data_type(val)
return Types::Null if val.nil?

View File

@ -23,7 +23,7 @@ class SystemMessage
params = defaults.merge(params)
if SiteSetting.restrict_access?
if SiteSetting.access_password.present?
params[:site_password] = MultisiteI18n.t('system_messages.site_password', access_password: SiteSetting.access_password)
end

View File

@ -125,15 +125,14 @@ describe InvitesController do
context 'access_required' do
it "doesn't set a cookie for access if there is no access required" do
SiteSetting.expects(:restrict_access?).returns(false)
SiteSetting.stubs(:access_password).returns(nil)
Invite.any_instance.expects(:redeem).returns(user)
get :show, id: invite.invite_key
cookies[:_access].should be_blank
end
it "sets the cookie when access is required" do
SiteSetting.expects(:restrict_access?).returns(true)
SiteSetting.expects(:access_password).returns('adventure time!')
SiteSetting.stubs(:access_password).returns('adventure time!')
Invite.any_instance.expects(:redeem).returns(user)
get :show, id: invite.invite_key
cookies[:_access].should == 'adventure time!'

View File

@ -18,7 +18,7 @@ describe RobotsTxtController do
it "serves noindex when in private mode regardless of the configuration" do
SiteSetting.stubs(:allow_index_in_robots_txt).returns(true)
SiteSetting.stubs(:restrict_access).returns(true)
SiteSetting.stubs(:access_password).returns('adventure time!')
get :index
response.should render_template :no_index
end

View File

@ -1,3 +1,5 @@
/*global waitsFor:true expect:true describe:true beforeEach:true it:true */
describe("Discourse.Composer", function() {
describe("replyLength", function() {