FIX: use allowlist and blocklist terminology (#10209)

This is a PR of the renaming whitelist to allowlist and blacklist to the blocklist.
This commit is contained in:
Krzysztof Kotlarek 2020-07-27 10:23:54 +10:00 committed by GitHub
parent 5077cf52fd
commit e0d9232259
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
130 changed files with 675 additions and 569 deletions

View File

@ -240,7 +240,7 @@ GEM
omniauth-twitter (1.4.0) omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1) omniauth-oauth (~> 1.1)
rack rack
onebox (1.9.30) onebox (2.0.0)
addressable (~> 2.7.0) addressable (~> 2.7.0)
htmlentities (~> 4.3) htmlentities (~> 4.3)
multi_json (~> 1.11) multi_json (~> 1.11)

View File

@ -42,7 +42,7 @@ export default Component.extend(bufferedProperty("host"), {
const props = this.buffered.getProperties( const props = this.buffered.getProperties(
"host", "host",
"path_whitelist", "allowed_paths",
"class_name" "class_name"
); );
props.category_id = this.categoryId; props.category_id = this.categoryId;

View File

@ -3,7 +3,7 @@ import discourseComputed from "discourse-common/utils/decorators";
import { schedule } from "@ember/runloop"; import { schedule } from "@ember/runloop";
import Component from "@ember/component"; import Component from "@ember/component";
/** /**
A form to create an IP address that will be blocked or whitelisted. A form to create an IP address that will be blocked or allowed.
Example usage: Example usage:
{{screened-ip-address-form action=(action "recordAdded")}} {{screened-ip-address-form action=(action "recordAdded")}}
@ -21,9 +21,9 @@ export default Component.extend({
formSubmitted: false, formSubmitted: false,
actionName: "block", actionName: "block",
@discourseComputed("siteSettings.use_admin_ip_whitelist") @discourseComputed("siteSettings.use_admin_ip_allowlist")
actionNames(adminWhitelistEnabled) { actionNames(adminAllowlistEnabled) {
if (adminWhitelistEnabled) { if (adminAllowlistEnabled) {
return [ return [
{ id: "block", name: I18n.t("admin.logs.screened_ips.actions.block") }, { id: "block", name: I18n.t("admin.logs.screened_ips.actions.block") },
{ {

View File

@ -8,8 +8,8 @@
{{input value=buffered.class_name placeholder="class" enter=(action "save") class="class-name"}} {{input value=buffered.class_name placeholder="class" enter=(action "save") class="class-name"}}
</td> </td>
<td class="editing-input"> <td class="editing-input">
<div class="label">{{i18n "admin.embedding.path_whitelist"}}</div> <div class="label">{{i18n "admin.embedding.allowed_paths"}}</div>
{{input value=buffered.path_whitelist placeholder="/blog/.*" enter=(action "save") class="path-whitelist"}} {{input value=buffered.allowed_paths placeholder="/blog/.*" enter=(action "save") class="path-allowlist"}}
</td> </td>
<td class="editing-input"> <td class="editing-input">
<div class="label">{{i18n "admin.embedding.category"}}</div> <div class="label">{{i18n "admin.embedding.category"}}</div>
@ -26,7 +26,7 @@
{{else}} {{else}}
<td><div class="label">{{i18n "admin.embedding.host"}}</div>{{host.host}}</td> <td><div class="label">{{i18n "admin.embedding.host"}}</div>{{host.host}}</td>
<td><div class="label">{{i18n "admin.embedding.class_name"}}</div>{{host.class_name}}</td> <td><div class="label">{{i18n "admin.embedding.class_name"}}</div>{{host.class_name}}</td>
<td><div class="label">{{i18n "admin.embedding.path_whitelist"}}</div>{{host.path_whitelist}}</td> <td><div class="label">{{i18n "admin.embedding.allowed_paths"}}</div>{{host.allowed_paths}}</td>
<td><div class="label">{{i18n "admin.embedding.category"}}</div>{{category-badge host.category}}</td> <td><div class="label">{{i18n "admin.embedding.category"}}</div>{{category-badge host.category}}</td>
<td class="controls"> <td class="controls">
{{d-button icon="pencil-alt" action=(action "edit")}} {{d-button icon="pencil-alt" action=(action "edit")}}

View File

@ -4,7 +4,7 @@
<thead> <thead>
<th style="width: 25%">{{i18n "admin.embedding.host"}}</th> <th style="width: 25%">{{i18n "admin.embedding.host"}}</th>
<th style="width: 15%">{{i18n "admin.embedding.class_name"}}</th> <th style="width: 15%">{{i18n "admin.embedding.class_name"}}</th>
<th style="width: 25%">{{i18n "admin.embedding.path_whitelist"}}</th> <th style="width: 25%">{{i18n "admin.embedding.allowed_paths"}}</th>
<th style="width: 25%">{{i18n "admin.embedding.category"}}</th> <th style="width: 25%">{{i18n "admin.embedding.category"}}</th>
<th style="width: 10%">&nbsp;</th> <th style="width: 10%">&nbsp;</th>
</thead> </thead>
@ -45,16 +45,16 @@
<h3>{{i18n "admin.embedding.crawling_settings"}}</h3> <h3>{{i18n "admin.embedding.crawling_settings"}}</h3>
<p class="description">{{i18n "admin.embedding.crawling_description"}}</p> <p class="description">{{i18n "admin.embedding.crawling_description"}}</p>
{{embedding-setting field="embed_whitelist_selector" {{embedding-setting field="allowed_embed_selectors"
value=embedding.embed_whitelist_selector value=embedding.allowed_embed_selectors
placeholder="article, #story, .post"}} placeholder="article, #story, .post"}}
{{embedding-setting field="embed_blacklist_selector" {{embedding-setting field="blocked_embed_selectors"
value=embedding.embed_blacklist_selector value=embedding.blocked_embed_selectors
placeholder=".ad-unit, header"}} placeholder=".ad-unit, header"}}
{{embedding-setting field="embed_classname_whitelist" {{embedding-setting field="allowed_embed_classnames"
value=embedding.embed_classname_whitelist value=embedding.allowed_embed_classnames
placeholder="emoji, classname"}} placeholder="emoji, classname"}}
</div> </div>

View File

@ -102,7 +102,7 @@ export class Tag {
]; ];
} }
static whitelists() { static allowedTags() {
return ["ins", "del", "small", "big", "kbd", "ruby", "rt", "rb", "rp"]; return ["ins", "del", "small", "big", "kbd", "ruby", "rt", "rb", "rp"];
} }
@ -192,7 +192,7 @@ export class Tag {
}; };
} }
static whitelist(name) { static allowedTag(name) {
return class extends Tag { return class extends Tag {
constructor() { constructor() {
super(name, `<${name}>`, `</${name}>`); super(name, `<${name}>`, `</${name}>`);
@ -526,7 +526,7 @@ function tags() {
...Tag.headings().map((h, i) => Tag.heading(h, i + 1)), ...Tag.headings().map((h, i) => Tag.heading(h, i + 1)),
...Tag.slices().map(s => Tag.slice(s, "\n")), ...Tag.slices().map(s => Tag.slice(s, "\n")),
...Tag.emphases().map(e => Tag.emphasis(e[0], e[1])), ...Tag.emphases().map(e => Tag.emphasis(e[0], e[1])),
...Tag.whitelists().map(t => Tag.whitelist(t)), ...Tag.allowedTags().map(t => Tag.allowedTag(t)),
Tag.aside(), Tag.aside(),
Tag.cell("td"), Tag.cell("td"),
Tag.cell("th"), Tag.cell("th"),

View File

@ -8,7 +8,7 @@
{{/if}} {{/if}}
{{category-selector {{category-selector
categories=model.watchedCategories categories=model.watchedCategories
blacklist=selectedCategories blocklist=selectedCategories
onChange=(action (mut model.watchedCategories)) onChange=(action (mut model.watchedCategories))
}} }}
</div> </div>
@ -21,7 +21,7 @@
{{/if}} {{/if}}
{{category-selector {{category-selector
categories=model.trackedCategories categories=model.trackedCategories
blacklist=selectedCategories blocklist=selectedCategories
onChange=(action (mut model.trackedCategories)) onChange=(action (mut model.trackedCategories))
}} }}
</div> </div>
@ -31,7 +31,7 @@
<label>{{d-icon "d-watching-first"}} {{i18n "user.watched_first_post_categories"}}</label> <label>{{d-icon "d-watching-first"}} {{i18n "user.watched_first_post_categories"}}</label>
{{category-selector {{category-selector
categories=model.watchedFirstPostCategories categories=model.watchedFirstPostCategories
blacklist=selectedCategories blocklist=selectedCategories
onChange=(action (mut model.watchedFirstPostCategories)) onChange=(action (mut model.watchedFirstPostCategories))
}} }}
</div> </div>
@ -45,7 +45,7 @@
{{/if}} {{/if}}
{{category-selector {{category-selector
categories=model.mutedCategories categories=model.mutedCategories
blacklist=selectedCategories blocklist=selectedCategories
onChange=(action (mut model.mutedCategories)) onChange=(action (mut model.mutedCategories))
}} }}
</div> </div>

View File

@ -6,7 +6,7 @@
<label>{{d-icon "d-watching" class="icon watching"}} {{i18n "user.watched_tags"}}</label> <label>{{d-icon "d-watching" class="icon watching"}} {{i18n "user.watched_tags"}}</label>
{{tag-chooser {{tag-chooser
tags=model.watched_tags tags=model.watched_tags
blacklist=selectedTags blocklist=selectedTags
allowCreate=false allowCreate=false
everyTag=true everyTag=true
unlimitedTagCount=true unlimitedTagCount=true
@ -19,7 +19,7 @@
<label>{{d-icon "d-tracking" class="icon tracking"}} {{i18n "user.tracked_tags"}}</label> <label>{{d-icon "d-tracking" class="icon tracking"}} {{i18n "user.tracked_tags"}}</label>
{{tag-chooser {{tag-chooser
tags=model.tracked_tags tags=model.tracked_tags
blacklist=selectedTags blocklist=selectedTags
allowCreate=false allowCreate=false
everyTag=true everyTag=true
unlimitedTagCount=true}} unlimitedTagCount=true}}
@ -31,7 +31,7 @@
<label>{{d-icon "d-watching-first" class="icon watching-first-post"}} {{i18n "user.watched_first_post_tags"}}</label> <label>{{d-icon "d-watching-first" class="icon watching-first-post"}} {{i18n "user.watched_first_post_tags"}}</label>
{{tag-chooser {{tag-chooser
tags=model.watching_first_post_tags tags=model.watching_first_post_tags
blacklist=selectedTags blocklist=selectedTags
allowCreate=false allowCreate=false
everyTag=true everyTag=true
unlimitedTagCount=true}} unlimitedTagCount=true}}
@ -45,7 +45,7 @@
<label>{{d-icon "d-muted" class="icon muted"}} {{i18n "user.muted_tags"}}</label> <label>{{d-icon "d-muted" class="icon muted"}} {{i18n "user.muted_tags"}}</label>
{{tag-chooser {{tag-chooser
tags=model.muted_tags tags=model.muted_tags
blacklist=selectedTags blocklist=selectedTags
allowCreate=false allowCreate=false
everyTag=true everyTag=true
unlimitedTagCount=true}} unlimitedTagCount=true}}

View File

@ -514,12 +514,12 @@ export default createWidget("header", {
const currentPath = this.register const currentPath = this.register
.lookup("service:router") .lookup("service:router")
.get("_router.currentPath"); .get("_router.currentPath");
const blacklist = [/^discovery\.categories/]; const blocklist = [/^discovery\.categories/];
const whitelist = [/^topic\./]; const allowlist = [/^topic\./];
const check = function(regex) { const check = function(regex) {
return !!currentPath.match(regex); return !!currentPath.match(regex);
}; };
let showSearch = whitelist.any(check) && !blacklist.any(check); let showSearch = allowlist.any(check) && !blocklist.any(check);
// If we're viewing a topic, only intercept search if there are cloaked posts // If we're viewing a topic, only intercept search if there are cloaked posts
if (showSearch && currentPath.match(/^topic\./)) { if (showSearch && currentPath.match(/^topic\./)) {

View File

@ -389,7 +389,7 @@ export function setup(opts, siteSettings, state) {
} }
export function cook(raw, opts) { export function cook(raw, opts) {
// we still have to hoist html_raw nodes so they bypass the whitelister // we still have to hoist html_raw nodes so they bypass the allowlister
// this is the case for oneboxes // this is the case for oneboxes
let hoisted = {}; let hoisted = {};

View File

@ -30,7 +30,7 @@ function resolveSize(img) {
// Detect square images and apply smaller onebox-avatar class // Detect square images and apply smaller onebox-avatar class
function applySquareGenericOnebox($elem) { function applySquareGenericOnebox($elem) {
if (!$elem.hasClass("whitelistedgeneric")) { if (!$elem.hasClass("allowlistedgeneric")) {
return; return;
} }

View File

@ -108,7 +108,7 @@ export default class WhiteLister {
} }
} }
// Only add to `default` when you always want your whitelist to occur. In other words, // Only add to `default` when you always want your allowlist to occur. In other words,
// don't change this for a plugin or a feature that can be disabled // don't change this for a plugin or a feature that can be disabled
export const DEFAULT_LIST = [ export const DEFAULT_LIST = [
"a.attachment", "a.attachment",

View File

@ -8,7 +8,7 @@ export default MultiSelectComponent.extend({
pluginApiIdentifiers: ["category-selector"], pluginApiIdentifiers: ["category-selector"],
classNames: ["category-selector"], classNames: ["category-selector"],
categories: null, categories: null,
blacklist: null, blockedCategories: null,
selectKitOptions: { selectKitOptions: {
filterable: true, filterable: true,
@ -22,14 +22,15 @@ export default MultiSelectComponent.extend({
this._super(...arguments); this._super(...arguments);
if (!this.categories) this.set("categories", []); if (!this.categories) this.set("categories", []);
if (!this.blacklist) this.set("blacklist", []); if (!this.blockedCategories) this.set("blockedCategories", []);
}, },
content: computed("categories.[]", "blacklist.[]", function() { content: computed("categories.[]", "blockedCategories.[]", function() {
const blacklist = makeArray(this.blacklist); const blockedCategories = makeArray(this.blockedCategories);
return Category.list().filter(category => { return Category.list().filter(category => {
return ( return (
this.categories.includes(category) || !blacklist.includes(category) this.categories.includes(category) ||
!blockedCategories.includes(category)
); );
}); });
}), }),

View File

@ -19,7 +19,7 @@ export default MultiSelectComponent.extend(TagsMixin, {
return "tag-chooser-row"; return "tag-chooser-row";
}, },
blacklist: null, blockedTags: null,
attributeBindings: ["categoryId"], attributeBindings: ["categoryId"],
excludeSynonyms: false, excludeSynonyms: false,
excludeHasSynonyms: false, excludeHasSynonyms: false,
@ -49,7 +49,7 @@ export default MultiSelectComponent.extend(TagsMixin, {
this._super(...arguments); this._super(...arguments);
this.setProperties({ this.setProperties({
blacklist: this.blacklist || [], blockedTags: this.blockedTags || [],
termMatchesForbidden: false, termMatchesForbidden: false,
termMatchErrorMessage: null termMatchErrorMessage: null
}); });
@ -84,9 +84,9 @@ export default MultiSelectComponent.extend(TagsMixin, {
categoryId: this.categoryId categoryId: this.categoryId
}; };
if (selectedTags.length || this.blacklist.length) { if (selectedTags.length || this.blockedTags.length) {
data.selected_tags = selectedTags data.selected_tags = selectedTags
.concat(this.blacklist) .concat(this.blockedTags)
.uniq() .uniq()
.slice(0, 100); .slice(0, 100);
} }
@ -106,9 +106,9 @@ export default MultiSelectComponent.extend(TagsMixin, {
termMatchErrorMessage: json.forbidden_message termMatchErrorMessage: json.forbidden_message
}); });
if (context.blacklist) { if (context.blockedTags) {
results = results.filter(result => { results = results.filter(result => {
return !context.blacklist.includes(result.id); return !context.blockedTags.includes(result.id);
}); });
} }

View File

@ -625,7 +625,8 @@ aside.onebox.stackexchange .onebox-body {
} }
} }
// whitelistedgeneric twitter labels // allowlistedgeneric twitter labels
.onebox.allowlistedgeneric,
.onebox.whitelistedgeneric { .onebox.whitelistedgeneric {
.label1, .label1,
.label2 { .label2 {
@ -640,6 +641,7 @@ aside.onebox.stackexchange .onebox-body {
} }
.onebox { .onebox {
&.allowlistedgeneric,
&.whitelistedgeneric, &.whitelistedgeneric,
&.gfycat { &.gfycat {
.site-icon { .site-icon {

View File

@ -22,7 +22,7 @@ class Admin::EmbeddableHostsController < Admin::AdminController
def save_host(host, action) def save_host(host, action)
host.host = params[:embeddable_host][:host] host.host = params[:embeddable_host][:host]
host.path_whitelist = params[:embeddable_host][:path_whitelist] host.allowed_paths = params[:embeddable_host][:allowed_paths]
host.class_name = params[:embeddable_host][:class_name] host.class_name = params[:embeddable_host][:class_name]
host.category_id = params[:embeddable_host][:category_id] host.category_id = params[:embeddable_host][:category_id]
host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank? host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?

View File

@ -15,7 +15,7 @@ class Admin::ThemesController < Admin::AdminController
def upload_asset def upload_asset
ban_in_whitelist_mode! ban_in_allowlist_mode!
path = params[:file].path path = params[:file].path
@ -53,7 +53,7 @@ class Admin::ThemesController < Admin::AdminController
@theme = nil @theme = nil
if params[:theme] && params[:theme].content_type == "application/json" if params[:theme] && params[:theme].content_type == "application/json"
ban_in_whitelist_mode! ban_in_allowlist_mode!
# .dcstyle.json import. Deprecated, but still available to allow conversion # .dcstyle.json import. Deprecated, but still available to allow conversion
json = JSON::parse(params[:theme].read) json = JSON::parse(params[:theme].read)
@ -104,7 +104,7 @@ class Admin::ThemesController < Admin::AdminController
end end
elsif params[:bundle] || (params[:theme] && THEME_CONTENT_TYPES.include?(params[:theme].content_type)) elsif params[:bundle] || (params[:theme] && THEME_CONTENT_TYPES.include?(params[:theme].content_type))
ban_in_whitelist_mode! ban_in_allowlist_mode!
# params[:bundle] used by theme CLI. params[:theme] used by admin UI # params[:bundle] used by theme CLI. params[:theme] used by admin UI
bundle = params[:bundle] || params[:theme] bundle = params[:bundle] || params[:theme]
@ -152,7 +152,7 @@ class Admin::ThemesController < Admin::AdminController
def create def create
ban_in_whitelist_mode! ban_in_allowlist_mode!
@theme = Theme.new(name: theme_params[:name], @theme = Theme.new(name: theme_params[:name],
user_id: theme_user.id, user_id: theme_user.id,
@ -297,8 +297,8 @@ class Admin::ThemesController < Admin::AdminController
private private
def ban_in_whitelist_mode! def ban_in_allowlist_mode!
raise Discourse::InvalidAccess if !GlobalSetting.whitelisted_theme_ids.nil? raise Discourse::InvalidAccess if !GlobalSetting.allowed_theme_ids.nil?
end end
def add_relative_themes!(kind, ids) def add_relative_themes!(kind, ids)
@ -358,7 +358,7 @@ class Admin::ThemesController < Admin::AdminController
def set_fields def set_fields
return unless fields = theme_params[:theme_fields] return unless fields = theme_params[:theme_fields]
ban_in_whitelist_mode! ban_in_allowlist_mode!
fields.each do |field| fields.each do |field|
@theme.set_field( @theme.set_field(

View File

@ -276,7 +276,7 @@ class PostsController < ApplicationController
reply_history = post.reply_history(params[:max_replies].to_i, guardian) reply_history = post.reply_history(params[:max_replies].to_i, guardian)
user_custom_fields = {} user_custom_fields = {}
if (added_fields = User.whitelisted_user_custom_fields(guardian)).present? if (added_fields = User.allowed_user_custom_fields(guardian)).present?
user_custom_fields = User.custom_fields_for_ids(reply_history.pluck(:user_id), added_fields) user_custom_fields = User.custom_fields_for_ids(reply_history.pluck(:user_id), added_fields)
end end
@ -365,7 +365,7 @@ class PostsController < ApplicationController
replies = post.replies.secured(guardian) replies = post.replies.secured(guardian)
user_custom_fields = {} user_custom_fields = {}
if (added_fields = User.whitelisted_user_custom_fields(guardian)).present? if (added_fields = User.allowed_user_custom_fields(guardian)).present?
user_custom_fields = User.custom_fields_for_ids(replies.pluck(:user_id), added_fields) user_custom_fields = User.custom_fields_for_ids(replies.pluck(:user_id), added_fields)
end end
@ -704,10 +704,10 @@ class PostsController < ApplicationController
end end
result = params.permit(*permitted).tap do |whitelisted| result = params.permit(*permitted).tap do |allowed|
whitelisted[:image_sizes] = params[:image_sizes] allowed[:image_sizes] = params[:image_sizes]
# TODO this does not feel right, we should name what meta_data is allowed # TODO this does not feel right, we should name what meta_data is allowed
whitelisted[:meta_data] = params[:meta_data] allowed[:meta_data] = params[:meta_data]
end end
# Staff are allowed to pass `is_warning` # Staff are allowed to pass `is_warning`

View File

@ -55,15 +55,15 @@ class RobotsTxtController < ApplicationController
agents: [] agents: []
} }
if SiteSetting.whitelisted_crawler_user_agents.present? if SiteSetting.allowed_crawler_user_agents.present?
SiteSetting.whitelisted_crawler_user_agents.split('|').each do |agent| SiteSetting.allowed_crawler_user_agents.split('|').each do |agent|
result[:agents] << { name: agent, disallow: deny_paths } result[:agents] << { name: agent, disallow: deny_paths }
end end
result[:agents] << { name: '*', disallow: deny_all } result[:agents] << { name: '*', disallow: deny_all }
elsif SiteSetting.blacklisted_crawler_user_agents.present? elsif SiteSetting.blocked_crawler_user_agents.present?
result[:agents] << { name: '*', disallow: deny_paths } result[:agents] << { name: '*', disallow: deny_paths }
SiteSetting.blacklisted_crawler_user_agents.split('|').each do |agent| SiteSetting.blocked_crawler_user_agents.split('|').each do |agent|
result[:agents] << { name: agent, disallow: deny_all } result[:agents] << { name: agent, disallow: deny_all }
end end
else else

View File

@ -117,7 +117,7 @@ class UsersController < ApplicationController
users = users.filter { |u| guardian.can_see_profile?(u) } users = users.filter { |u| guardian.can_see_profile?(u) }
preload_fields = User.whitelisted_user_custom_fields(guardian) + UserField.all.pluck(:id).map { |fid| "#{User::USER_FIELD_PREFIX}#{fid}" } preload_fields = User.allowed_user_custom_fields(guardian) + UserField.all.pluck(:id).map { |fid| "#{User::USER_FIELD_PREFIX}#{fid}" }
User.preload_custom_fields(users, preload_fields) User.preload_custom_fields(users, preload_fields)
User.preload_recent_time_read(users) User.preload_recent_time_read(users)

View File

@ -205,7 +205,7 @@ module Jobs
hostname = uri.hostname hostname = uri.hostname
return false unless hostname return false unless hostname
# check the domains blacklist # check the domains blocklist
SiteSetting.should_download_images?(src) SiteSetting.should_download_images?(src)
end end

View File

@ -72,15 +72,15 @@ module HasCustomFields
# To avoid n+1 queries, use this function to retrieve lots of custom fields in one go # To avoid n+1 queries, use this function to retrieve lots of custom fields in one go
# and create a "sideloaded" version for easy querying by id. # and create a "sideloaded" version for easy querying by id.
def self.custom_fields_for_ids(ids, whitelisted_fields) def self.custom_fields_for_ids(ids, allowed_fields)
klass = "#{name}CustomField".constantize klass = "#{name}CustomField".constantize
foreign_key = "#{name.underscore}_id".to_sym foreign_key = "#{name.underscore}_id".to_sym
result = {} result = {}
return result if whitelisted_fields.blank? return result if allowed_fields.blank?
klass.where(foreign_key => ids, :name => whitelisted_fields) klass.where(foreign_key => ids, :name => allowed_fields)
.pluck(foreign_key, :name, :value).each do |cf| .pluck(foreign_key, :name, :value).each do |cf|
result[cf[0]] ||= {} result[cf[0]] ||= {}
append_custom_field(result[cf[0]], cf[1], cf[2]) append_custom_field(result[cf[0]], cf[1], cf[2])

View File

@ -10,6 +10,9 @@ class EmbeddableHost < ActiveRecord::Base
self.host.sub!(/\/.*$/, '') self.host.sub!(/\/.*$/, '')
end end
# TODO(2021-07-23): Remove
self.ignored_columns = ["path_whitelist"]
def self.record_for_url(uri) def self.record_for_url(uri)
if uri.is_a?(String) if uri.is_a?(String)
@ -31,9 +34,9 @@ class EmbeddableHost < ActiveRecord::Base
path << "?" << uri.query if uri.query.present? path << "?" << uri.query if uri.query.present?
where("lower(host) = ?", host).each do |eh| where("lower(host) = ?", host).each do |eh|
return eh if eh.path_whitelist.blank? return eh if eh.allowed_paths.blank?
path_regexp = Regexp.new(eh.path_whitelist) path_regexp = Regexp.new(eh.allowed_paths)
return eh if path_regexp.match(path) || path_regexp.match(UrlHelper.unencode(path)) return eh if path_regexp.match(path) || path_regexp.match(UrlHelper.unencode(path))
end end
@ -78,6 +81,6 @@ end
# category_id :integer not null # category_id :integer not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# path_whitelist :string # allowed_paths :string
# class_name :string # class_name :string
# #

View File

@ -11,9 +11,9 @@ class Embedding < OpenStruct
embed_title_scrubber embed_title_scrubber
embed_truncate embed_truncate
embed_unlisted embed_unlisted
embed_whitelist_selector allowed_embed_selectors
embed_blacklist_selector blocked_embed_selectors
embed_classname_whitelist) allowed_embed_classnames)
end end
def base_url def base_url

View File

@ -204,15 +204,15 @@ class GlobalSetting
end end
# test only # test only
def self.reset_whitelisted_theme_ids! def self.reset_allowed_theme_ids!
@whitelisted_theme_ids = nil @allowed_theme_ids = nil
end end
def self.whitelisted_theme_ids def self.allowed_theme_ids
return nil if whitelisted_theme_repos.blank? return nil if allowed_theme_repos.blank?
@whitelisted_theme_ids ||= begin @allowed_theme_ids ||= begin
urls = whitelisted_theme_repos.split(",").map(&:strip) urls = allowed_theme_repos.split(",").map(&:strip)
Theme Theme
.joins(:remote_theme) .joins(:remote_theme)
.where('remote_themes.remote_url in (?)', urls) .where('remote_themes.remote_url in (?)', urls)

View File

@ -254,8 +254,8 @@ class Post < ActiveRecord::Base
Digest::SHA1.hexdigest(raw) Digest::SHA1.hexdigest(raw)
end end
def self.white_listed_image_classes def self.allowed_image_classes
@white_listed_image_classes ||= ['avatar', 'favicon', 'thumbnail', 'emoji', 'ytp-thumbnail-image'] @allowed_image_classes ||= ['avatar', 'favicon', 'thumbnail', 'emoji', 'ytp-thumbnail-image']
end end
def post_analyzer def post_analyzer
@ -335,9 +335,9 @@ class Post < ActiveRecord::Base
self.last_editor_id ? (User.find_by_id(self.last_editor_id) || user) : user self.last_editor_id ? (User.find_by_id(self.last_editor_id) || user) : user
end end
def whitelisted_spam_hosts def allowed_spam_hosts
hosts = SiteSetting hosts = SiteSetting
.white_listed_spam_host_domains .allowed_spam_host_domains
.split('|') .split('|')
.map { |h| h.strip } .map { |h| h.strip }
.reject { |h| !h.include?('.') } .reject { |h| !h.include?('.') }
@ -349,10 +349,10 @@ class Post < ActiveRecord::Base
def total_hosts_usage def total_hosts_usage
hosts = linked_hosts.clone hosts = linked_hosts.clone
whitelisted = whitelisted_spam_hosts allowlisted = allowed_spam_hosts
hosts.reject! do |h| hosts.reject! do |h|
whitelisted.any? do |w| allowlisted.any? do |w|
h.end_with?(w) h.end_with?(w)
end end
end end

View File

@ -52,7 +52,7 @@ class PostAnalyzer
cooked_stripped.css("img").reject do |t| cooked_stripped.css("img").reject do |t|
if dom_class = t["class"] if dom_class = t["class"]
(Post.white_listed_image_classes & dom_class.split).count > 0 (Post.allowed_image_classes & dom_class.split).count > 0
end end
end.count end.count
end end

View File

@ -75,7 +75,7 @@ class ScreenedIpAddress < ActiveRecord::Base
exists_for_ip_address_and_action?(ip_address, actions[:block]) exists_for_ip_address_and_action?(ip_address, actions[:block])
end end
def self.is_whitelisted?(ip_address) def self.is_allowed?(ip_address)
exists_for_ip_address_and_action?(ip_address, actions[:do_nothing]) exists_for_ip_address_and_action?(ip_address, actions[:do_nothing])
end end
@ -87,7 +87,7 @@ class ScreenedIpAddress < ActiveRecord::Base
end end
def self.block_admin_login?(user, ip_address) def self.block_admin_login?(user, ip_address)
return false unless SiteSetting.use_admin_ip_whitelist return false unless SiteSetting.use_admin_ip_allowlist
return false if user.nil? return false if user.nil?
return false if !user.admin? return false if !user.admin?
return false if ScreenedIpAddress.where(action_type: actions[:allow_admin]).count == 0 return false if ScreenedIpAddress.where(action_type: actions[:allow_admin]).count == 0

View File

@ -100,29 +100,29 @@ class SiteSetting < ActiveRecord::Base
WATCHED_SETTINGS ||= [ WATCHED_SETTINGS ||= [
:default_locale, :default_locale,
:attachment_content_type_blacklist, :blocked_attachment_content_types,
:attachment_filename_blacklist, :blocked_attachment_filenames,
:unicode_username_character_whitelist, :allowed_unicode_username_characters,
:markdown_typographer_quotation_marks :markdown_typographer_quotation_marks
] ]
def self.reset_cached_settings! def self.reset_cached_settings!
@attachment_content_type_blacklist_regex = nil @blocked_attachment_content_types_regex = nil
@attachment_filename_blacklist_regex = nil @blocked_attachment_filenames_regex = nil
@unicode_username_whitelist_regex = nil @allowed_unicode_username_regex = nil
end end
def self.attachment_content_type_blacklist_regex def self.blocked_attachment_content_types_regex
@attachment_content_type_blacklist_regex ||= Regexp.union(SiteSetting.attachment_content_type_blacklist.split("|")) @blocked_attachment_content_types_regex ||= Regexp.union(SiteSetting.blocked_attachment_content_types.split("|"))
end end
def self.attachment_filename_blacklist_regex def self.blocked_attachment_filenames_regex
@attachment_filename_blacklist_regex ||= Regexp.union(SiteSetting.attachment_filename_blacklist.split("|")) @blocked_attachment_filenames_regex ||= Regexp.union(SiteSetting.blocked_attachment_filenames.split("|"))
end end
def self.unicode_username_character_whitelist_regex def self.allowed_unicode_username_characters_regex
@unicode_username_whitelist_regex ||= SiteSetting.unicode_username_character_whitelist.present? \ @allowed_unicode_username_regex ||= SiteSetting.allowed_unicode_username_characters.present? \
? Regexp.new(SiteSetting.unicode_username_character_whitelist) : nil ? Regexp.new(SiteSetting.allowed_unicode_username_characters) : nil
end end
# helpers for getting s3 settings that fallback to global # helpers for getting s3 settings that fallback to global
@ -213,6 +213,38 @@ class SiteSetting < ActiveRecord::Base
c.present? && c.to_i != SiteSetting.uncategorized_category_id.to_i c.present? && c.to_i != SiteSetting.uncategorized_category_id.to_i
end end
ALLOWLIST_DEPRECATED_SITE_SETTINGS = {
'email_domains_blacklist': 'blocked_email_domains',
'email_domains_whitelist': 'allowed_email_domains',
'unicode_username_character_whitelist': 'allowed_unicode_username_characters',
'user_website_domains_whitelist': 'allowed_user_website_domains',
'whitelisted_link_domains': 'allowed_link_domains',
'embed_whitelist_selector': 'allowed_embed_selectors',
'auto_generated_whitelist': 'auto_generated_allowlist',
'attachment_content_type_blacklist': 'blocked_attachment_content_types',
'attachment_filename_blacklist': 'blocked_attachment_filenames',
'use_admin_ip_whitelist': 'use_admin_ip_allowlist',
'blacklist_ip_blocks': 'blocked_ip_blocks',
'whitelist_internal_hosts': 'allowed_internal_hosts',
'whitelisted_crawler_user_agents': 'allowed_crawler_user_agents',
'blacklisted_crawler_user_agents': 'blocked_crawler_user_agents',
'onebox_domains_blacklist': 'blocked_onebox_domains',
'inline_onebox_domains_whitelist': 'allowed_inline_onebox_domains',
'white_listed_spam_host_domains': 'allowed_spam_host_domains',
'embed_blacklist_selector': 'blocked_embed_selectors',
'embed_classname_whitelist': 'allowed_embed_classnames',
}
ALLOWLIST_DEPRECATED_SITE_SETTINGS.each_pair do |old_method, new_method|
self.class.define_method(old_method) do
Discourse.deprecate("#{old_method.to_s} is deprecated, use the #{new_method.to_s}.", drop_from: "2.6")
send(new_method)
end
self.class.define_method("#{old_method}=") do |args|
Discourse.deprecate("#{old_method.to_s} is deprecated, use the #{new_method.to_s}.", drop_from: "2.6")
send("#{new_method}=", args)
end
end
end end
# == Schema Information # == Schema Information

View File

@ -124,9 +124,9 @@ class TopicEmbed < ActiveRecord::Base
remove_empty_nodes: false remove_empty_nodes: false
} }
opts[:whitelist] = SiteSetting.embed_whitelist_selector if SiteSetting.embed_whitelist_selector.present? opts[:allowlist] = SiteSetting.allowed_embed_selectors if SiteSetting.allowed_embed_selectors.present?
opts[:blacklist] = SiteSetting.embed_blacklist_selector if SiteSetting.embed_blacklist_selector.present? opts[:blocklist] = SiteSetting.blocked_embed_selectors if SiteSetting.blocked_embed_selectors.present?
embed_classname_whitelist = SiteSetting.embed_classname_whitelist if SiteSetting.embed_classname_whitelist.present? allowed_embed_classnames = SiteSetting.allowed_embed_classnames if SiteSetting.allowed_embed_classnames.present?
response = FetchResponse.new response = FetchResponse.new
begin begin
@ -169,8 +169,8 @@ class TopicEmbed < ActiveRecord::Base
# If there is a mistyped URL, just do nothing # If there is a mistyped URL, just do nothing
end end
end end
# only allow classes in the whitelist # only allow classes in the allowlist
allowed_classes = if embed_classname_whitelist.blank? then [] else embed_classname_whitelist.split(/[ ,]+/i) end allowed_classes = if allowed_embed_classnames.blank? then [] else allowed_embed_classnames.split(/[ ,]+/i) end
doc.search('[class]:not([class=""])').each do |classnode| doc.search('[class]:not([class=""])').each do |classnode|
classes = classnode[:class].split(' ').select { |classname| allowed_classes.include?(classname) } classes = classnode[:class].split(' ').select { |classname| allowed_classes.include?(classname) }
if classes.length === 0 if classes.length === 0

View File

@ -92,7 +92,7 @@ class TopicLinkClick < ActiveRecord::Base
return nil unless uri return nil unless uri
# Only redirect to whitelisted hostnames # Only redirect to allowlisted hostnames
return url if WHITELISTED_REDIRECT_HOSTNAMES.include?(uri.hostname) || is_cdn_link return url if WHITELISTED_REDIRECT_HOSTNAMES.include?(uri.hostname) || is_cdn_link
return nil return nil

View File

@ -3,7 +3,7 @@
require "i18n/i18n_interpolation_keys_finder" require "i18n/i18n_interpolation_keys_finder"
class TranslationOverride < ActiveRecord::Base class TranslationOverride < ActiveRecord::Base
# Whitelist i18n interpolation keys that can be included when customizing translations # Allowlist i18n interpolation keys that can be included when customizing translations
CUSTOM_INTERPOLATION_KEYS_WHITELIST = { CUSTOM_INTERPOLATION_KEYS_WHITELIST = {
"user_notifications.user_" => %w{ "user_notifications.user_" => %w{
topic_title_url_encoded topic_title_url_encoded

View File

@ -294,7 +294,7 @@ class User < ActiveRecord::Base
DiscoursePluginRegistry.register_public_user_custom_field(custom_field_name, plugin) DiscoursePluginRegistry.register_public_user_custom_field(custom_field_name, plugin)
end end
def self.whitelisted_user_custom_fields(guardian) def self.allowed_user_custom_fields(guardian)
fields = [] fields = []
fields.push *DiscoursePluginRegistry.public_user_custom_fields fields.push *DiscoursePluginRegistry.public_user_custom_fields

View File

@ -131,7 +131,7 @@ class UserProfile < ActiveRecord::Base
end end
def website_domain_validator def website_domain_validator
allowed_domains = SiteSetting.user_website_domains_whitelist allowed_domains = SiteSetting.allowed_user_website_domains
return if (allowed_domains.blank? || self.website.blank?) return if (allowed_domains.blank? || self.website.blank?)
domain = begin domain = begin

View File

@ -32,7 +32,7 @@ class UsernameValidator
username_length_min? username_length_min?
username_length_max? username_length_max?
username_char_valid? username_char_valid?
username_char_whitelisted? username_char_allowed?
username_first_char_valid? username_first_char_valid?
username_last_char_valid? username_last_char_valid?
username_no_double_special? username_no_double_special?
@ -85,10 +85,10 @@ class UsernameValidator
end end
end end
def username_char_whitelisted? def username_char_allowed?
return unless errors.empty? && self.class.char_whitelist_exists? return unless errors.empty? && self.class.char_allowlist_exists?
if username.chars.any? { |c| !self.class.whitelisted_char?(c) } if username.chars.any? { |c| !self.class.allowed_char?(c) }
self.errors << I18n.t(:'user.username.characters') self.errors << I18n.t(:'user.username.characters')
end end
end end
@ -133,11 +133,11 @@ class UsernameValidator
SiteSetting.unicode_usernames ? UNICODE_INVALID_CHAR_PATTERN : ASCII_INVALID_CHAR_PATTERN SiteSetting.unicode_usernames ? UNICODE_INVALID_CHAR_PATTERN : ASCII_INVALID_CHAR_PATTERN
end end
def self.char_whitelist_exists? def self.char_allowlist_exists?
SiteSetting.unicode_usernames && SiteSetting.unicode_username_character_whitelist_regex.present? SiteSetting.unicode_usernames && SiteSetting.allowed_unicode_username_characters.present?
end end
def self.whitelisted_char?(c) def self.allowed_char?(c)
c.match?(/[\w.-]/) || c.match?(SiteSetting.unicode_username_character_whitelist_regex) c.match?(/[\w.-]/) || c.match?(SiteSetting.allowed_unicode_username_characters)
end end
end end

View File

@ -2,7 +2,7 @@
class EmbeddableHostSerializer < ApplicationSerializer class EmbeddableHostSerializer < ApplicationSerializer
TO_SERIALIZE = [:id, :host, :path_whitelist, :class_name, :category_id] TO_SERIALIZE = [:id, :host, :allowed_paths, :class_name, :category_id]
attributes *TO_SERIALIZE attributes *TO_SERIALIZE

View File

@ -36,7 +36,7 @@ class FlaggedUserSerializer < BasicUserSerializer
end end
def custom_fields def custom_fields
fields = User.whitelisted_user_custom_fields(scope) fields = User.allowed_user_custom_fields(scope)
result = {} result = {}
fields.each do |k| fields.each do |k|

View File

@ -216,6 +216,6 @@ class UserCardSerializer < BasicUserSerializer
def custom_field_keys def custom_field_keys
# Can be extended by other serializers # Can be extended by other serializers
User.whitelisted_user_custom_fields(scope) User.allowed_user_custom_fields(scope)
end end
end end

View File

@ -22,6 +22,6 @@ class UserWithCustomFieldsSerializer < BasicUserSerializer
def custom_field_keys def custom_field_keys
# Can be extended by other serializers # Can be extended by other serializers
User.whitelisted_user_custom_fields(scope) User.allowed_user_custom_fields(scope)
end end
end end

View File

@ -28,7 +28,7 @@ class SpamRule::FlagSockpuppets
@post.user != first_post.user && @post.user != first_post.user &&
@post.user.ip_address == first_post.user.ip_address && @post.user.ip_address == first_post.user.ip_address &&
@post.user.new_user? && @post.user.new_user? &&
!ScreenedIpAddress.is_whitelisted?(@post.user.ip_address) !ScreenedIpAddress.is_allowed?(@post.user.ip_address)
end end
def flag_sockpuppet_users def flag_sockpuppet_users

View File

@ -44,7 +44,7 @@ class UserDestroyer
if opts[:block_urls] if opts[:block_urls]
post.topic_links.each do |link| post.topic_links.each do |link|
next if link.internal next if link.internal
next if Oneboxer.engine(link.url) != Onebox::Engine::WhitelistedGenericOnebox next if Oneboxer.engine(link.url) != Onebox::Engine::AllowlistedGenericOnebox
ScreenedUrl.watch(link.url, link.domain, ip_address: user.ip_address)&.record_match! ScreenedUrl.watch(link.url, link.domain, ip_address: user.ip_address)&.record_match!
end end
end end

View File

@ -12,7 +12,7 @@
<ul> <ul>
<%- @hosts.each do |eh| %> <%- @hosts.each do |eh| %>
<li> <li>
<%= eh.host %><%- if eh.path_whitelist.present? %><%= eh.path_whitelist %><% end %> <%= eh.host %><%- if eh.allowed_paths.present? %><%= eh.allowed_paths %><% end %>
</li> </li>
<%- end %> <%- end %>
</ul> </ul>

View File

@ -291,11 +291,11 @@ anon_cache_store_threshold = 2
# EXPERIMENTAL - not yet supported in production # EXPERIMENTAL - not yet supported in production
# by default admins can install and amend any theme # by default admins can install and amend any theme
# you may restrict it so only specific themes are approved # you may restrict it so only specific themes are approved
# in whitelist mode all theme updates must happen via git repos # in allowlist mode all theme updates must happen via git repos
# themes missing from the list are automatically disallowed # themes missing from the list are automatically disallowed
# list is a comma seperated list of git repos eg: # list is a comma seperated list of git repos eg:
# https://github.com/discourse/discourse-custom-header-links.git,https://github.com/discourse/discourse-simple-theme.git # https://github.com/discourse/discourse-custom-header-links.git,https://github.com/discourse/discourse-simple-theme.git
whitelisted_theme_repos = allowed_theme_repos =
# Demon::EmailSync is used in conjunction with the enable_imap site setting # Demon::EmailSync is used in conjunction with the enable_imap site setting
# to sync N IMAP mailboxes with specific groups. It is a process started in # to sync N IMAP mailboxes with specific groups. It is a process started in

View File

@ -4255,7 +4255,7 @@ en:
domain: "Domain" domain: "Domain"
screened_ips: screened_ips:
title: "Screened IPs" title: "Screened IPs"
description: 'IP addresses that are being watched. Use "Allow" to whitelist IP addresses.' description: 'IP addresses that are being watched. Use "Allow" to allowlist IP addresses.'
delete_confirm: "Are you sure you want to remove the rule for %{ip_address}?" delete_confirm: "Are you sure you want to remove the rule for %{ip_address}?"
roll_up_confirm: "Are you sure you want to roll up commonly screened IP addresses into subnets?" roll_up_confirm: "Are you sure you want to roll up commonly screened IP addresses into subnets?"
rolled_up_some_subnets: "Successfully rolled up IP ban entries to these subnets: %{subnets}." rolled_up_some_subnets: "Successfully rolled up IP ban entries to these subnets: %{subnets}."
@ -4777,7 +4777,7 @@ en:
title: "Embedding" title: "Embedding"
host: "Allowed Hosts" host: "Allowed Hosts"
class_name: "Class Name" class_name: "Class Name"
path_whitelist: "Path Whitelist" allowed_paths: "Path Allowlist"
edit: "edit" edit: "edit"
category: "Post to Category" category: "Post to Category"
add_host: "Add Host" add_host: "Add Host"
@ -4790,9 +4790,9 @@ en:
embed_title_scrubber: "Regular expression used to scrub the title of posts" embed_title_scrubber: "Regular expression used to scrub the title of posts"
embed_truncate: "Truncate the embedded posts" embed_truncate: "Truncate the embedded posts"
embed_unlisted: "Imported topics will be unlisted until there is a reply." embed_unlisted: "Imported topics will be unlisted until there is a reply."
embed_whitelist_selector: "CSS selector for elements that are allowed in embeds" allowed_embed_selectors: "CSS selector for elements that are allowed in embeds"
embed_blacklist_selector: "CSS selector for elements that are removed from embeds" blocked_embed_selectors: "CSS selector for elements that are removed from embeds"
embed_classname_whitelist: "Allowed CSS class names" allowed_embed_classnames: "Allowed CSS class names"
save: "Save Embedding Settings" save: "Save Embedding Settings"
permalink: permalink:

View File

@ -139,7 +139,7 @@ en:
bounced_email_error: "Email is a bounced email report." bounced_email_error: "Email is a bounced email report."
screened_email_error: "Happens when the sender's email address was already screened." screened_email_error: "Happens when the sender's email address was already screened."
unsubscribe_not_allowed: "Happens when unsubscribing via email is not allowed for this user." unsubscribe_not_allowed: "Happens when unsubscribing via email is not allowed for this user."
email_not_allowed: "Happens when the email address is not on the whitelist or is on the blacklist." email_not_allowed: "Happens when the email address is not on the allowlist or is on the blocklist."
unrecognized_error: "Unrecognized Error" unrecognized_error: "Unrecognized Error"
secure_media_placeholder: "Redacted: this site has secure media enabled, visit the topic to see the attached image/audio/video." secure_media_placeholder: "Redacted: this site has secure media enabled, visit the topic to see the attached image/audio/video."
@ -1485,9 +1485,9 @@ en:
show_pinned_excerpt_mobile: "Show excerpt on pinned topics in mobile view." show_pinned_excerpt_mobile: "Show excerpt on pinned topics in mobile view."
show_pinned_excerpt_desktop: "Show excerpt on pinned topics in desktop view." show_pinned_excerpt_desktop: "Show excerpt on pinned topics in desktop view."
post_onebox_maxlength: "Maximum length of a oneboxed Discourse post in characters." post_onebox_maxlength: "Maximum length of a oneboxed Discourse post in characters."
onebox_domains_blacklist: "A list of domains that will never be oneboxed." blocked_onebox_domains: "A list of domains that will never be oneboxed."
inline_onebox_domains_whitelist: "A list of domains that will be oneboxed in miniature form if linked without a title" allowed_inline_onebox_domains: "A list of domains that will be oneboxed in miniature form if linked without a title"
enable_inline_onebox_on_all_domains: "Ignore inline_onebox_domain_whitelist site setting and allow inline onebox on all domains." enable_inline_onebox_on_all_domains: "Ignore inline_onebox_domain_allowlist site setting and allow inline onebox on all domains."
force_custom_user_agent_hosts: "Hosts for which to use the custom onebox user agent on all requests. (Especially useful for hosts that limit access by user agent)." force_custom_user_agent_hosts: "Hosts for which to use the custom onebox user agent on all requests. (Especially useful for hosts that limit access by user agent)."
max_oneboxes_per_post: "Maximum number of oneboxes in a post." max_oneboxes_per_post: "Maximum number of oneboxes in a post."
@ -1556,22 +1556,22 @@ en:
ga_universal_tracking_code: "Google Universal Analytics (analytics.js) tracking code ID, eg: UA-12345678-9; see <a href='https://google.com/analytics' target='_blank'>https://google.com/analytics</a>" ga_universal_tracking_code: "Google Universal Analytics (analytics.js) tracking code ID, eg: UA-12345678-9; see <a href='https://google.com/analytics' target='_blank'>https://google.com/analytics</a>"
ga_universal_domain_name: "Google Universal Analytics (analytics.js) domain name, eg: mysite.com; see <a href='https://google.com/analytics' target='_blank'>https://google.com/analytics</a>" ga_universal_domain_name: "Google Universal Analytics (analytics.js) domain name, eg: mysite.com; see <a href='https://google.com/analytics' target='_blank'>https://google.com/analytics</a>"
ga_universal_auto_link_domains: "Enable Google Universal Analytics (analytics.js) cross-domain tracking. Outgoing links to these domains will have the client id added to them. See <a href='https://support.google.com/analytics/answer/1034342?hl=en' target='_blank'>Google's Cross-Domain Tracking guide.</a>" ga_universal_auto_link_domains: "Enable Google Universal Analytics (analytics.js) cross-domain tracking. Outgoing links to these domains will have the client id added to them. See <a href='https://support.google.com/analytics/answer/1034342?hl=en' target='_blank'>Google's Cross-Domain Tracking guide.</a>"
gtm_container_id: "Google Tag Manager container id. eg: GTM-ABCDEF. <br/>Note: Third-party scripts loaded by GTM may need to be whitelisted in 'content security policy script src'." gtm_container_id: "Google Tag Manager container id. eg: GTM-ABCDEF. <br/>Note: Third-party scripts loaded by GTM may need to be allowlisted in 'content security policy script src'."
enable_escaped_fragments: "Fall back to Google's Ajax-Crawling API if no webcrawler is detected. See <a href='https://developers.google.com/webmasters/ajax-crawling/docs/learn-more' target='_blank'>https://developers.google.com/webmasters/ajax-crawling/docs/learn-more</a>" enable_escaped_fragments: "Fall back to Google's Ajax-Crawling API if no webcrawler is detected. See <a href='https://developers.google.com/webmasters/ajax-crawling/docs/learn-more' target='_blank'>https://developers.google.com/webmasters/ajax-crawling/docs/learn-more</a>"
moderators_create_categories: "Allow moderators to create new categories" moderators_create_categories: "Allow moderators to create new categories"
cors_origins: "Allowed origins for cross-origin requests (CORS). Each origin must include http:// or https://. The DISCOURSE_ENABLE_CORS env variable must be set to true to enable CORS." cors_origins: "Allowed origins for cross-origin requests (CORS). Each origin must include http:// or https://. The DISCOURSE_ENABLE_CORS env variable must be set to true to enable CORS."
use_admin_ip_whitelist: "Admins can only log in if they are at an IP address defined in the Screened IPs list (Admin > Logs > Screened Ips)." use_admin_ip_allowlist: "Admins can only log in if they are at an IP address defined in the Screened IPs list (Admin > Logs > Screened Ips)."
blacklist_ip_blocks: "A list of private IP blocks that should never be crawled by Discourse" blocked_ip_blocks: "A list of private IP blocks that should never be crawled by Discourse"
whitelist_internal_hosts: "A list of internal hosts that discourse can safely crawl for oneboxing and other purposes" allowed_internal_hosts: "A list of internal hosts that discourse can safely crawl for oneboxing and other purposes"
allowed_iframes: "A list of iframe src domain prefixes that discourse can safely allow in posts" allowed_iframes: "A list of iframe src domain prefixes that discourse can safely allow in posts"
whitelisted_crawler_user_agents: "User agents of web crawlers that should be allowed to access the site. WARNING! SETTING THIS WILL DISALLOW ALL CRAWLERS NOT LISTED HERE!" allowed_crawler_user_agents: "User agents of web crawlers that should be allowed to access the site. WARNING! SETTING THIS WILL DISALLOW ALL CRAWLERS NOT LISTED HERE!"
blacklisted_crawler_user_agents: "Unique case insensitive word in the user agent string identifying web crawlers that should not be allowed to access the site. Does not apply if whitelist is defined." blocked_crawler_user_agents: "Unique case insensitive word in the user agent string identifying web crawlers that should not be allowed to access the site. Does not apply if allowlist is defined."
slow_down_crawler_user_agents: "User agents of web crawlers that should be rate limited in robots.txt using the Crawl-delay directive" slow_down_crawler_user_agents: "User agents of web crawlers that should be rate limited in robots.txt using the Crawl-delay directive"
slow_down_crawler_rate: "If slow_down_crawler_user_agents is specified this rate will apply to all the crawlers (number of seconds delay between requests)" slow_down_crawler_rate: "If slow_down_crawler_user_agents is specified this rate will apply to all the crawlers (number of seconds delay between requests)"
content_security_policy: "Enable Content-Security-Policy" content_security_policy: "Enable Content-Security-Policy"
content_security_policy_report_only: "Enable Content-Security-Policy-Report-Only" content_security_policy_report_only: "Enable Content-Security-Policy-Report-Only"
content_security_policy_collect_reports: "Enable CSP violation report collection at /csp_reports" content_security_policy_collect_reports: "Enable CSP violation report collection at /csp_reports"
content_security_policy_script_src: "Additional whitelisted script sources. The current host and CDN are included by default. See <a href='https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243' target='_blank'>Mitigate XSS Attacks with Content Security Policy.</a>" content_security_policy_script_src: "Additional allowlisted script sources. The current host and CDN are included by default. See <a href='https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243' target='_blank'>Mitigate XSS Attacks with Content Security Policy.</a>"
invalidate_inactive_admin_email_after_days: "Admin accounts that have not visited the site in this number of days will need to re-validate their email address before logging in. Set to 0 to disable." invalidate_inactive_admin_email_after_days: "Admin accounts that have not visited the site in this number of days will need to re-validate their email address before logging in. Set to 0 to disable."
top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|categories|top|read|posted|bookmarks" top_menu: "Determine which items appear in the homepage navigation, and in what order. Example latest|new|unread|categories|top|read|posted|bookmarks"
post_menu: "Determine which items appear on the post menu, and in what order. Example like|edit|flag|delete|share|bookmark|reply" post_menu: "Determine which items appear on the post menu, and in what order. Example like|edit|flag|delete|share|bookmark|reply"
@ -1601,8 +1601,8 @@ en:
enable_whispers: "Allow staff private communication within topics." enable_whispers: "Allow staff private communication within topics."
allow_index_in_robots_txt: "Specify in robots.txt that this site is allowed to be indexed by web search engines. In exceptional cases you can permanently <a href='%{base_path}/admin/customize/robots'>override robots.txt</a>." allow_index_in_robots_txt: "Specify in robots.txt that this site is allowed to be indexed by web search engines. In exceptional cases you can permanently <a href='%{base_path}/admin/customize/robots'>override robots.txt</a>."
email_domains_blacklist: "A pipe-delimited list of email domains that users are not allowed to register accounts with. Example: mailinator.com|trashmail.net" blocked_email_domains: "A pipe-delimited list of email domains that users are not allowed to register accounts with. Example: mailinator.com|trashmail.net"
email_domains_whitelist: "A pipe-delimited list of email domains that users MUST register accounts with. WARNING: Users with email domains other than those listed will not be allowed!" allowed_email_domains: "A pipe-delimited list of email domains that users MUST register accounts with. WARNING: Users with email domains other than those listed will not be allowed!"
auto_approve_email_domains: "Users with email addresses from this list of domains will be automatically approved." auto_approve_email_domains: "Users with email addresses from this list of domains will be automatically approved."
hide_email_address_taken: "Don't inform users that an account exists with a given email address during signup and from the forgot password form." hide_email_address_taken: "Don't inform users that an account exists with a given email address during signup and from the forgot password form."
log_out_strict: "When logging out, log out ALL sessions for the user on all devices" log_out_strict: "When logging out, log out ALL sessions for the user on all devices"
@ -1618,7 +1618,7 @@ en:
min_username_length: "Minimum username length in characters. WARNING: if any existing users or groups have names shorter than this, your site will break!" min_username_length: "Minimum username length in characters. WARNING: if any existing users or groups have names shorter than this, your site will break!"
max_username_length: "Maximum username length in characters. WARNING: if any existing users or groups have names longer than this, your site will break!" max_username_length: "Maximum username length in characters. WARNING: if any existing users or groups have names longer than this, your site will break!"
unicode_usernames: "Allow usernames and group names to contain Unicode letters and numbers." unicode_usernames: "Allow usernames and group names to contain Unicode letters and numbers."
unicode_username_character_whitelist: "Regular expression to allow only some Unicode characters within usernames. ASCII letters and numbers will always be allowed and don't need to be included in the whitelist." allowed_unicode_username_characters: "Regular expression to allow only some Unicode characters within usernames. ASCII letters and numbers will always be allowed and don't need to be included in the allowlist."
reserved_usernames: "Usernames for which signup is not allowed. Wildcard symbol * can be used to match any character zero or more times." reserved_usernames: "Usernames for which signup is not allowed. Wildcard symbol * can be used to match any character zero or more times."
@ -1819,7 +1819,7 @@ en:
min_trust_to_post_links: "The minimum trust level required to include links in posts" min_trust_to_post_links: "The minimum trust level required to include links in posts"
min_trust_to_post_images: "The minimum trust level required to include images in a post" min_trust_to_post_images: "The minimum trust level required to include images in a post"
whitelisted_link_domains: "Domains that users may link to even if they don't have the appropriate trust level to post links" allowed_link_domains: "Domains that users may link to even if they don't have the appropriate trust level to post links"
newuser_max_links: "How many links a new user can add to a post." newuser_max_links: "How many links a new user can add to a post."
newuser_max_images: "How many images a new user can add to a post." newuser_max_images: "How many images a new user can add to a post."
@ -1887,7 +1887,7 @@ en:
newuser_spam_host_threshold: "How many times a new user can post a link to the same host within their `newuser_spam_host_threshold` posts before being considered spam." newuser_spam_host_threshold: "How many times a new user can post a link to the same host within their `newuser_spam_host_threshold` posts before being considered spam."
white_listed_spam_host_domains: "A list of domains excluded from spam host testing. New users will never be restricted from creating posts with links to these domains." allowed_spam_host_domains: "A list of domains excluded from spam host testing. New users will never be restricted from creating posts with links to these domains."
staff_like_weight: "How much extra weighting factor to give staff likes." staff_like_weight: "How much extra weighting factor to give staff likes."
topic_view_duration_hours: "Count a new topic view once per IP/User every N hours" topic_view_duration_hours: "Count a new topic view once per IP/User every N hours"
user_profile_view_duration_hours: "Count a new user profile view once per IP/User every N hours" user_profile_view_duration_hours: "Count a new user profile view once per IP/User every N hours"
@ -1933,7 +1933,7 @@ en:
max_emails_per_day_per_user: "Maximum number of emails to send users per day. 0 to disable the limit" max_emails_per_day_per_user: "Maximum number of emails to send users per day. 0 to disable the limit"
enable_staged_users: "Automatically create staged users when processing incoming emails." enable_staged_users: "Automatically create staged users when processing incoming emails."
maximum_staged_users_per_email: "Maximum number of staged users created when processing an incoming email." maximum_staged_users_per_email: "Maximum number of staged users created when processing an incoming email."
auto_generated_whitelist: "List of email addresses that won't be checked for auto-generated content. Example: foo@bar.com|discourse@bar.com" auto_generated_allowlist: "List of email addresses that won't be checked for auto-generated content. Example: foo@bar.com|discourse@bar.com"
block_auto_generated_emails: "Block incoming emails identified as being auto generated." block_auto_generated_emails: "Block incoming emails identified as being auto generated."
ignore_by_title: "Ignore incoming emails based on their title." ignore_by_title: "Ignore incoming emails based on their title."
mailgun_api_key: "Mailgun Secret API key used to verify webhook messages." mailgun_api_key: "Mailgun Secret API key used to verify webhook messages."
@ -1943,8 +1943,8 @@ en:
bounce_score_threshold: "Max bounce score before we will stop emailing a user." bounce_score_threshold: "Max bounce score before we will stop emailing a user."
reset_bounce_score_after_days: "Automatically reset bounce score after X days." reset_bounce_score_after_days: "Automatically reset bounce score after X days."
attachment_content_type_blacklist: "List of keywords used to blacklist attachments based on the content type." blocked_attachment_content_types: "List of keywords used to blocklist attachments based on the content type."
attachment_filename_blacklist: "List of keywords used to blacklist attachments based on the filename." blocked_attachment_filenames: "List of keywords used to blocklist attachments based on the filename."
forwarded_emails_behaviour: "How to treat a forwarded email to Discourse" forwarded_emails_behaviour: "How to treat a forwarded email to Discourse"
always_show_trimmed_content: "Always show trimmed part of incoming emails. WARNING: might reveal email addresses." always_show_trimmed_content: "Always show trimmed part of incoming emails. WARNING: might reveal email addresses."
@ -2046,7 +2046,7 @@ en:
max_notifications_per_user: "Maximum amount of notifications per user, if this number is exceeded old notifications will be deleted. Enforced weekly. Set to 0 to disable" max_notifications_per_user: "Maximum amount of notifications per user, if this number is exceeded old notifications will be deleted. Enforced weekly. Set to 0 to disable"
user_website_domains_whitelist: "User website will be verified against these domains. Pipe-delimited list." allowed_user_website_domains: "User website will be verified against these domains. Pipe-delimited list."
allow_profile_backgrounds: "Allow users to upload profile backgrounds." allow_profile_backgrounds: "Allow users to upload profile backgrounds."
@ -2110,7 +2110,7 @@ en:
embed_truncate: "Truncate the embedded posts." embed_truncate: "Truncate the embedded posts."
embed_unlisted: "Imported topics will be unlisted until a user replies." embed_unlisted: "Imported topics will be unlisted until a user replies."
embed_support_markdown: "Support Markdown formatting for embedded posts." embed_support_markdown: "Support Markdown formatting for embedded posts."
embed_whitelist_selector: "A comma separated list of CSS elements that are allowed in embeds." allowed_embed_selectors: "A comma separated list of CSS elements that are allowed in embeds."
allowed_href_schemes: "Schemes allowed in links in addition to http and https." allowed_href_schemes: "Schemes allowed in links in addition to http and https."
embed_post_limit: "Maximum number of posts to embed." embed_post_limit: "Maximum number of posts to embed."
embed_username_required: "The username for topic creation is required." embed_username_required: "The username for topic creation is required."
@ -2280,7 +2280,7 @@ en:
low_weight_invalid: "You cannot set the weight to be greater or equal to 1 or smaller than 'category_search_priority_very_low_weight'." low_weight_invalid: "You cannot set the weight to be greater or equal to 1 or smaller than 'category_search_priority_very_low_weight'."
high_weight_invalid: "You cannot set the weight to be smaller or equal to 1 or greater than 'category_search_priority_very_high_weight'." high_weight_invalid: "You cannot set the weight to be smaller or equal to 1 or greater than 'category_search_priority_very_high_weight'."
very_high_weight_invalid: "You cannot set the weight to be smaller than 'category_search_priority_high_weight'." very_high_weight_invalid: "You cannot set the weight to be smaller than 'category_search_priority_high_weight'."
unicode_username_whitelist: allowed_unicode_usernames:
regex_invalid: "The regular expression is invalid: %{error}" regex_invalid: "The regular expression is invalid: %{error}"
leading_trailing_slash: "The regular expression must not start and end with a slash." leading_trailing_slash: "The regular expression must not start and end with a slash."
unicode_usernames_avatars: "The internal system avatars do not support Unicode usernames." unicode_usernames_avatars: "The internal system avatars do not support Unicode usernames."
@ -2642,7 +2642,7 @@ en:
- Is your domain's [DKIM record][3] correct? This will significantly improve email deliverability. [Test your DKIM record][7] here. - Is your domain's [DKIM record][3] correct? This will significantly improve email deliverability. [Test your DKIM record][7] here.
- If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blacklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services. - If you run your own mail server, check to make sure the IPs of your mail server are [not on any email blocklists][4]. Also verify that it is definitely sending a fully-qualified hostname that resolves in DNS in its HELO message. If not, this will cause your email to be rejected by many mail services.
- We highly recommend you **send a test email to [mail-tester.com][mt]** to verify that all the above is working correctly. - We highly recommend you **send a test email to [mail-tester.com][mt]** to verify that all the above is working correctly.
@ -3236,7 +3236,7 @@ en:
Please [review the user](%{user_url}). Please [review the user](%{user_url}).
This can be modified via the `newuser_spam_host_threshold` and `white_listed_spam_host_domains` site settings. Consider adding %{domains} to the whitelist if they should be exempt. This can be modified via the `newuser_spam_host_threshold` and `allowed_spam_host_domains` site settings. Consider adding %{domains} to the allowlist if they should be exempt.
unsilenced: unsilenced:
title: "Unsilenced" title: "Unsilenced"

View File

@ -443,10 +443,10 @@ login:
sso_overrides_website: false sso_overrides_website: false
sso_overrides_card_background: false sso_overrides_card_background: false
sso_not_approved_url: "" sso_not_approved_url: ""
email_domains_blacklist: blocked_email_domains:
default: "mailinator.com" default: "mailinator.com"
type: list type: list
email_domains_whitelist: allowed_email_domains:
default: "" default: ""
type: list type: list
auto_approve_email_domains: auto_approve_email_domains:
@ -478,8 +478,8 @@ users:
default: false default: false
client: true client: true
validator: "UnicodeUsernameValidator" validator: "UnicodeUsernameValidator"
unicode_username_character_whitelist: allowed_unicode_username_characters:
validator: "UnicodeUsernameWhitelistValidator" validator: "UnicodeUsernameAllowlistValidator"
default: "" default: ""
locale_default: locale_default:
cs: "[ěščřžýáíéóůúďťňĚŠČŘŽÝÁÍÉÓŮÚĎŤŇ]" cs: "[ěščřžýáíéóůúďťňĚŠČŘŽÝÁÍÉÓŮÚĎŤŇ]"
@ -573,7 +573,7 @@ users:
client: true client: true
show_inactive_accounts: show_inactive_accounts:
default: false default: false
user_website_domains_whitelist: allowed_user_website_domains:
default: "" default: ""
type: list type: list
hide_suspension_reasons: hide_suspension_reasons:
@ -798,7 +798,7 @@ posting:
ko: 50 ko: 50
zh_CN: 50 zh_CN: 50
zh_TW: 50 zh_TW: 50
whitelisted_link_domains: allowed_link_domains:
default: "" default: ""
type: list type: list
newuser_max_links: 2 newuser_max_links: 2
@ -908,7 +908,7 @@ posting:
embed_unlisted: false embed_unlisted: false
embed_truncate: true embed_truncate: true
embed_support_markdown: false embed_support_markdown: false
embed_whitelist_selector: "" allowed_embed_selectors: ""
allowed_href_schemes: allowed_href_schemes:
client: true client: true
default: "" default: ""
@ -1082,7 +1082,7 @@ email:
max_emails_per_day_per_user: 100 max_emails_per_day_per_user: 100
enable_staged_users: true enable_staged_users: true
maximum_staged_users_per_email: 10 maximum_staged_users_per_email: 10
auto_generated_whitelist: auto_generated_allowlist:
default: "" default: ""
type: list type: list
block_auto_generated_emails: true block_auto_generated_emails: true
@ -1109,11 +1109,11 @@ email:
reset_bounce_score_after_days: reset_bounce_score_after_days:
default: 30 default: 30
max: 36500 max: 36500
attachment_content_type_blacklist: blocked_attachment_content_types:
type: list type: list
default: "pkcs7|x-vcard" default: "pkcs7|x-vcard"
list_type: compact list_type: compact
attachment_filename_blacklist: blocked_attachment_filenames:
type: list type: list
default: "smime.p7s|signature.asc|winmail.dat" default: "smime.p7s|signature.asc|winmail.dat"
list_type: compact list_type: compact
@ -1456,25 +1456,25 @@ security:
cors_origins: cors_origins:
default: "" default: ""
type: list type: list
use_admin_ip_whitelist: use_admin_ip_allowlist:
default: false default: false
client: true client: true
blacklist_ip_blocks: blocked_ip_blocks:
default: "" default: ""
type: list type: list
list_type: compact list_type: compact
whitelist_internal_hosts: allowed_internal_hosts:
default: "" default: ""
type: list type: list
allowed_iframes: allowed_iframes:
default: "https://www.google.com/maps/embed?|https://www.openstreetmap.org/export/embed.html?|https://calendar.google.com/calendar/embed?|https://codepen.io/" default: "https://www.google.com/maps/embed?|https://www.openstreetmap.org/export/embed.html?|https://calendar.google.com/calendar/embed?|https://codepen.io/"
type: list type: list
client: true client: true
whitelisted_crawler_user_agents: allowed_crawler_user_agents:
type: list type: list
default: "" default: ""
list_type: compact list_type: compact
blacklisted_crawler_user_agents: blocked_crawler_user_agents:
type: list type: list
default: "mauibot|semrushbot|ahrefsbot|blexbot|seo spider" default: "mauibot|semrushbot|ahrefsbot|blexbot|seo spider"
list_type: compact list_type: compact
@ -1511,14 +1511,14 @@ onebox:
ja: 200 ja: 200
zh_CN: 200 zh_CN: 200
zh_TW: 200 zh_TW: 200
onebox_domains_blacklist: blocked_onebox_domains:
default: "" default: ""
type: list type: list
list_type: compact list_type: compact
max_oneboxes_per_post: max_oneboxes_per_post:
default: 50 default: 50
client: true client: true
inline_onebox_domains_whitelist: allowed_inline_onebox_domains:
default: "" default: ""
type: list type: list
list_type: compact list_type: compact
@ -1542,7 +1542,7 @@ spam:
notify_mods_when_user_silenced: false notify_mods_when_user_silenced: false
flag_sockpuppets: false flag_sockpuppets: false
newuser_spam_host_threshold: 3 newuser_spam_host_threshold: 3
white_listed_spam_host_domains: allowed_spam_host_domains:
default: "" default: ""
type: list type: list
levenshtein_distance_spammer_emails: levenshtein_distance_spammer_emails:
@ -1728,10 +1728,10 @@ embedding:
embed_title_scrubber: embed_title_scrubber:
default: "" default: ""
hidden: true hidden: true
embed_blacklist_selector: blocked_embed_selectors:
default: "" default: ""
hidden: true hidden: true
embed_classname_whitelist: allowed_embed_classnames:
default: "emoji" default: "emoji"
hidden: true hidden: true

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
class AllowlistAndBlocklistSiteSettings < ActiveRecord::Migration[6.0]
def up
SiteSetting::ALLOWLIST_DEPRECATED_SITE_SETTINGS.each_pair do |old_key, new_key|
DB.exec <<~SQL
INSERT INTO site_settings(name, data_type, value, created_at, updated_at)
SELECT '#{new_key}', data_type, value, created_at, updated_At
FROM site_settings
WHERE name = '#{old_key}'
SQL
end
end
def down
SiteSetting::ALLOWLIST_DEPRECATED_SITE_SETTINGS.each_pair do |_old_key, new_key|
DB.exec <<~SQL
DELETE FROM site_settings
WHERE name = '#{new_key}'
SQL
end
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class RenamePathWhitelistToAllowedPaths < ActiveRecord::Migration[6.0]
def change
rename_column :embeddable_hosts, :path_whitelist, :allowed_paths
end
end

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
class RemoveDeprecatedAllowlistSettings < ActiveRecord::Migration[6.0]
def up
SiteSetting::ALLOWLIST_DEPRECATED_SITE_SETTINGS.each_pair do |old_key, _new_key|
DB.exec <<~SQL
DELETE FROM site_settings
WHERE name = '#{old_key}'
SQL
end
end
def down
SiteSetting::ALLOWLIST_DEPRECATED_SITE_SETTINGS.each_pair do |old_key, new_key|
DB.exec <<~SQL
INSERT INTO site_settings(name, data_type, value, created_at, updated_at)
SELECT '#{old_key}', data_type, value, created_at, updated_At
FROM site_settings
WHERE name = '#{new_key}'
SQL
end
end
end

View File

@ -29,7 +29,7 @@ There are 3 main scenarios we protect against:
3. **CSP is on by default** for [all Discourse installations](https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243) as of Discourse 2.2. It can be switched off in the site settings, but it is default on. 3. **CSP is on by default** for [all Discourse installations](https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243) as of Discourse 2.2. It can be switched off in the site settings, but it is default on.
On the server side we run a whitelist based sanitizer, implemented using the [Sanitize gem](https://github.com/rgrove/sanitize). See the [relevant Discourse code](https://github.com/discourse/discourse/blob/master/lib/pretty_text.rb). On the server side we run a allowlist based sanitizer, implemented using the [Sanitize gem](https://github.com/rgrove/sanitize). See the [relevant Discourse code](https://github.com/discourse/discourse/blob/master/lib/pretty_text.rb).
In addition, titles and all other places where non-admins can enter code are protected either using the Handlebars library or standard Rails XSS protection. In addition, titles and all other places where non-admins can enter code are protected either using the Handlebars library or standard Rails XSS protection.

View File

@ -113,8 +113,8 @@ class Auth::GithubAuthenticator < Auth::Authenticator
end end
# If we *still* don't have a user, check to see if there's an email that # If we *still* don't have a user, check to see if there's an email that
# passes validation (this includes whitelist/blacklist filtering if any is # passes validation (this includes allowlist/blocklist filtering if any is
# configured). When no whitelist/blacklist is in play, this will simply # configured). When no allowlist/blocklist is in play, this will simply
# choose the primary email since it's at the front of the list. # choose the primary email since it's at the front of the list.
if !user if !user
validator = EmailValidator.new(attributes: :email) validator = EmailValidator.new(attributes: :email)

View File

@ -592,7 +592,7 @@ class CookedPostProcessor
found = false found = false
parent = img parent = img
while parent = parent.parent while parent = parent.parent
if parent["class"] && parent["class"].include?("whitelistedgeneric") if parent["class"] && parent["class"].include?("allowlistedgeneric")
found = true found = true
break break
end end

View File

@ -39,18 +39,18 @@ module CrawlerDetection
# Given a user_agent that returns true from crawler?, should its request be allowed? # Given a user_agent that returns true from crawler?, should its request be allowed?
def self.allow_crawler?(user_agent) def self.allow_crawler?(user_agent)
return true if SiteSetting.whitelisted_crawler_user_agents.blank? && return true if SiteSetting.allowed_crawler_user_agents.blank? &&
SiteSetting.blacklisted_crawler_user_agents.blank? SiteSetting.blocked_crawler_user_agents.blank?
@whitelisted_matchers ||= {} @allowlisted_matchers ||= {}
@blacklisted_matchers ||= {} @blocklisted_matchers ||= {}
if SiteSetting.whitelisted_crawler_user_agents.present? if SiteSetting.allowed_crawler_user_agents.present?
whitelisted = @whitelisted_matchers[SiteSetting.whitelisted_crawler_user_agents] ||= to_matcher(SiteSetting.whitelisted_crawler_user_agents) allowlisted = @allowlisted_matchers[SiteSetting.allowed_crawler_user_agents] ||= to_matcher(SiteSetting.allowed_crawler_user_agents)
!user_agent.nil? && user_agent.match?(whitelisted) !user_agent.nil? && user_agent.match?(allowlisted)
else else
blacklisted = @blacklisted_matchers[SiteSetting.blacklisted_crawler_user_agents] ||= to_matcher(SiteSetting.blacklisted_crawler_user_agents) blocklisted = @blocklisted_matchers[SiteSetting.blocked_crawler_user_agents] ||= to_matcher(SiteSetting.blocked_crawler_user_agents)
user_agent.nil? || !user_agent.match?(blacklisted) user_agent.nil? || !user_agent.match?(blocklisted)
end end
end end

View File

@ -62,7 +62,7 @@ module Email
end end
def process! def process!
return if is_blacklisted? return if is_blocked?
id_hash = Digest::SHA1.hexdigest(@message_id) id_hash = Digest::SHA1.hexdigest(@message_id)
DistributedMutex.synchronize("process_email_#{id_hash}") do DistributedMutex.synchronize("process_email_#{id_hash}") do
begin begin
@ -105,7 +105,7 @@ module Email
end end
end end
def is_blacklisted? def is_blocked?
return false if SiteSetting.ignore_by_title.blank? return false if SiteSetting.ignore_by_title.blank?
Regexp.new(SiteSetting.ignore_by_title, Regexp::IGNORECASE) =~ @mail.subject Regexp.new(SiteSetting.ignore_by_title, Regexp::IGNORECASE) =~ @mail.subject
end end
@ -289,7 +289,7 @@ module Email
end end
def is_auto_generated? def is_auto_generated?
return false if SiteSetting.auto_generated_whitelist.split('|').include?(@from_email) return false if SiteSetting.auto_generated_allowlist.split('|').include?(@from_email)
@mail[:precedence].to_s[/list|junk|bulk|auto_reply/i] || @mail[:precedence].to_s[/list|junk|bulk|auto_reply/i] ||
@mail[:from].to_s[/(mailer[\-_]?daemon|post[\-_]?master|no[\-_]?reply)@/i] || @mail[:from].to_s[/(mailer[\-_]?daemon|post[\-_]?master|no[\-_]?reply)@/i] ||
@mail[:subject].to_s[/^\s*(Auto:|Automatic reply|Autosvar|Automatisk svar|Automatisch antwoord|Abwesenheitsnotiz|Risposta Non al computer|Automatisch antwoord|Auto Response|Respuesta automática|Fuori sede|Out of Office|Frånvaro|Réponse automatique)/i] || @mail[:subject].to_s[/^\s*(Auto:|Automatic reply|Autosvar|Automatisk svar|Automatisch antwoord|Abwesenheitsnotiz|Risposta Non al computer|Automatisch antwoord|Auto Response|Respuesta automática|Fuori sede|Out of Office|Frånvaro|Réponse automatique)/i] ||
@ -1009,18 +1009,18 @@ module Email
raise InvalidPostAction.new if result.failed? && result.forbidden raise InvalidPostAction.new if result.failed? && result.forbidden
end end
def is_whitelisted_attachment?(attachment) def is_allowed?(attachment)
attachment.content_type !~ SiteSetting.attachment_content_type_blacklist_regex && attachment.content_type !~ SiteSetting.blocked_attachment_content_types_regex &&
attachment.filename !~ SiteSetting.attachment_filename_blacklist_regex attachment.filename !~ SiteSetting.blocked_attachment_filenames_regex
end end
def attachments def attachments
@attachments ||= begin @attachments ||= begin
attachments = @mail.attachments.select { |attachment| is_whitelisted_attachment?(attachment) } attachments = @mail.attachments.select { |attachment| is_allowed?(attachment) }
attachments << @mail if @mail.attachment? && is_whitelisted_attachment?(@mail) attachments << @mail if @mail.attachment? && is_allowed?(@mail)
@mail.parts.each do |part| @mail.parts.each do |part|
attachments << part if part.attachment? && is_whitelisted_attachment?(part) attachments << part if part.attachment? && is_allowed?(part)
end end
attachments.uniq! attachments.uniq!

View File

@ -152,7 +152,7 @@ module Email
# iframes can't go in emails, so replace them with clickable links # iframes can't go in emails, so replace them with clickable links
@fragment.css('iframe').each do |i| @fragment.css('iframe').each do |i|
begin begin
# sometimes, iframes are blacklisted... # sometimes, iframes are blocklisted...
if i["src"].blank? if i["src"].blank?
i.remove i.remove
next next

View File

@ -284,13 +284,13 @@ class FinalDestination
def is_dest_valid? def is_dest_valid?
return false unless @uri && @uri.host return false unless @uri && @uri.host
# Whitelisted hosts # Allowlisted hosts
return true if hostname_matches?(SiteSetting.Upload.s3_cdn_url) || return true if hostname_matches?(SiteSetting.Upload.s3_cdn_url) ||
hostname_matches?(GlobalSetting.try(:cdn_url)) || hostname_matches?(GlobalSetting.try(:cdn_url)) ||
hostname_matches?(Discourse.base_url_no_prefix) hostname_matches?(Discourse.base_url_no_prefix)
if SiteSetting.whitelist_internal_hosts.present? if SiteSetting.allowed_internal_hosts.present?
return true if SiteSetting.whitelist_internal_hosts.split("|").any? { |h| h.downcase == @uri.hostname.downcase } return true if SiteSetting.allowed_internal_hosts.split("|").any? { |h| h.downcase == @uri.hostname.downcase }
end end
address_s = @opts[:lookup_ip].call(@uri.hostname) address_s = @opts[:lookup_ip].call(@uri.hostname)
@ -320,7 +320,7 @@ class FinalDestination
def private_ranges def private_ranges
FinalDestination.standard_private_ranges + FinalDestination.standard_private_ranges +
SiteSetting.blacklist_ip_blocks.split('|').map { |r| IPAddr.new(r) rescue nil }.compact SiteSetting.blocked_ip_blocks.split('|').map { |r| IPAddr.new(r) rescue nil }.compact
end end
def log(log_level, message) def log(log_level, message)

View File

@ -137,7 +137,7 @@ module FlagQuery
guardian = Guardian.new(current_user) guardian = Guardian.new(current_user)
users = User.includes(:user_stat).where(id: user_ids.to_a).to_a users = User.includes(:user_stat).where(id: user_ids.to_a).to_a
User.preload_custom_fields(users, User.whitelisted_user_custom_fields(guardian)) User.preload_custom_fields(users, User.allowed_user_custom_fields(guardian))
[ [
posts, posts,

View File

@ -477,9 +477,9 @@ class Guardian
def allowed_theme_repo_import?(repo) def allowed_theme_repo_import?(repo)
return false if !@user.admin? return false if !@user.admin?
whitelisted_repos = GlobalSetting.whitelisted_theme_repos allowed_repos = GlobalSetting.allowed_theme_repos
if !whitelisted_repos.blank? if !allowed_repos.blank?
urls = whitelisted_repos.split(",").map(&:strip) urls = allowed_repos.split(",").map(&:strip)
return urls.include?(repo) return urls.include?(repo)
end end
@ -489,8 +489,8 @@ class Guardian
def allow_themes?(theme_ids, include_preview: false) def allow_themes?(theme_ids, include_preview: false)
return true if theme_ids.blank? return true if theme_ids.blank?
if whitelisted_theme_ids = GlobalSetting.whitelisted_theme_ids if allowed_theme_ids = GlobalSetting.allowed_theme_ids
if (theme_ids - whitelisted_theme_ids).present? if (theme_ids - allowed_theme_ids).present?
return false return false
end end
end end

View File

@ -10,7 +10,7 @@ module PostGuardian
def link_posting_access def link_posting_access
if unrestricted_link_posting? if unrestricted_link_posting?
'full' 'full'
elsif SiteSetting.whitelisted_link_domains.present? elsif SiteSetting.allowed_link_domains.present?
'limited' 'limited'
else else
'none' 'none'
@ -21,7 +21,7 @@ module PostGuardian
return false if host.blank? return false if host.blank?
unrestricted_link_posting? || unrestricted_link_posting? ||
SiteSetting.whitelisted_link_domains.split('|').include?(host) SiteSetting.allowed_link_domains.split('|').include?(host)
end end
# Can the user act on the post in a particular way. # Can the user act on the post in a particular way.

View File

@ -42,7 +42,7 @@ class InlineOneboxer
end end
always_allow = SiteSetting.enable_inline_onebox_on_all_domains always_allow = SiteSetting.enable_inline_onebox_on_all_domains
domains = SiteSetting.inline_onebox_domains_whitelist&.split('|') unless always_allow domains = SiteSetting.allowed_inline_onebox_domains&.split('|') unless always_allow
if always_allow || domains if always_allow || domains
uri = begin uri = begin

View File

@ -4,9 +4,9 @@ require "ipaddr"
module Onebox module Onebox
module Engine module Engine
class WhitelistedGenericOnebox class AllowlistedGenericOnebox
# overwrite the whitelist # overwrite the allowlist
def self.===(other) def self.===(other)
other.is_a?(URI) ? (IPAddr.new(other.hostname) rescue nil).nil? : true other.is_a?(URI) ? (IPAddr.new(other.hostname) rescue nil).nil? : true
end end
@ -18,10 +18,10 @@ module Onebox
private private
# overwrite to whitelist iframes # overwrite to allowlist iframes
def is_embedded? def is_embedded?
return false unless data[:html] && data[:height] return false unless data[:html] && data[:height]
return true if WhitelistedGenericOnebox.html_providers.include?(data[:provider_name]) return true if AllowlistedGenericOnebox.html_providers.include?(data[:provider_name])
if data[:html]["iframe"] if data[:html]["iframe"]
fragment = Nokogiri::HTML5::fragment(data[:html]) fragment = Nokogiri::HTML5::fragment(data[:html])

View File

@ -292,8 +292,8 @@ module Oneboxer
end end
end end
def self.blacklisted_domains def self.blocked_domains
SiteSetting.onebox_domains_blacklist.split("|") SiteSetting.blocked_onebox_domains.split("|")
end end
def self.preserve_fragment_url_hosts def self.preserve_fragment_url_hosts
@ -304,12 +304,12 @@ module Oneboxer
Discourse.cache.fetch(onebox_cache_key(url), expires_in: 1.day) do Discourse.cache.fetch(onebox_cache_key(url), expires_in: 1.day) do
fd = FinalDestination.new(url, fd = FinalDestination.new(url,
ignore_redirects: ignore_redirects, ignore_redirects: ignore_redirects,
ignore_hostnames: blacklisted_domains, ignore_hostnames: blocked_domains,
force_get_hosts: force_get_hosts, force_get_hosts: force_get_hosts,
force_custom_user_agent_hosts: force_custom_user_agent_hosts, force_custom_user_agent_hosts: force_custom_user_agent_hosts,
preserve_fragment_url_hosts: preserve_fragment_url_hosts) preserve_fragment_url_hosts: preserve_fragment_url_hosts)
uri = fd.resolve uri = fd.resolve
return blank_onebox if uri.blank? || blacklisted_domains.map { |hostname| uri.hostname.match?(hostname) }.any? return blank_onebox if uri.blank? || blocked_domains.map { |hostname| uri.hostname.match?(hostname) }.any?
options = { options = {
max_width: 695, max_width: 695,

View File

@ -161,10 +161,20 @@ class Plugin::Instance
end end
def whitelist_staff_user_custom_field(field) def whitelist_staff_user_custom_field(field)
Discourse.deprecate("whitelist_staff_user_custom_field is deprecated, use the allow_staff_user_custom_field.", drop_from: "2.6")
allow_staff_user_custom_field(field)
end
def allow_staff_user_custom_field(field)
DiscoursePluginRegistry.register_staff_user_custom_field(field, self) DiscoursePluginRegistry.register_staff_user_custom_field(field, self)
end end
def whitelist_public_user_custom_field(field) def whitelist_public_user_custom_field(field)
Discourse.deprecate("whitelist_public_user_custom_field is deprecated, use the allow_public_user_custom_field.", drop_from: "2.6")
allow_public_user_custom_field(field)
end
def allow_public_user_custom_field(field)
DiscoursePluginRegistry.register_public_user_custom_field(field, self) DiscoursePluginRegistry.register_public_user_custom_field(field, self)
end end
@ -256,10 +266,15 @@ class Plugin::Instance
end end
end end
# Add a post_custom_fields_whitelister block to the TopicView, respecting if the plugin is enabled
def topic_view_post_custom_fields_whitelister(&block) def topic_view_post_custom_fields_whitelister(&block)
Discourse.deprecate("topic_view_post_custom_fields_whitelister is deprecated, use the topic_view_post_custom_fields_allowlister.", drop_from: "2.6")
topic_view_post_custom_fields_allowlister(&block)
end
# Add a post_custom_fields_allowlister block to the TopicView, respecting if the plugin is enabled
def topic_view_post_custom_fields_allowlister(&block)
reloadable_patch do |plugin| reloadable_patch do |plugin|
::TopicView.add_post_custom_fields_whitelister do |user| ::TopicView.add_post_custom_fields_allowlister do |user|
plugin.enabled? ? block.call(user) : [] plugin.enabled? ? block.call(user) : []
end end
end end

View File

@ -284,10 +284,10 @@ module PrettyText
end end
def self.add_rel_nofollow_to_user_content(doc) def self.add_rel_nofollow_to_user_content(doc)
whitelist = [] allowlist = []
domains = SiteSetting.exclude_rel_nofollow_domains domains = SiteSetting.exclude_rel_nofollow_domains
whitelist = domains.split('|') if domains.present? allowlist = domains.split('|') if domains.present?
site_uri = nil site_uri = nil
doc.css("a").each do |l| doc.css("a").each do |l|
@ -299,7 +299,7 @@ module PrettyText
if !uri.host.present? || if !uri.host.present? ||
uri.host == site_uri.host || uri.host == site_uri.host ||
uri.host.ends_with?(".#{site_uri.host}") || uri.host.ends_with?(".#{site_uri.host}") ||
whitelist.any? { |u| uri.host == u || uri.host.ends_with?(".#{u}") } allowlist.any? { |u| uri.host == u || uri.host.ends_with?(".#{u}") }
# we are good no need for nofollow # we are good no need for nofollow
l.remove_attribute("rel") l.remove_attribute("rel")
else else

View File

@ -378,8 +378,8 @@ module SiteSettingExtension
end end
HOSTNAME_SETTINGS ||= %w{ HOSTNAME_SETTINGS ||= %w{
disabled_image_download_domains onebox_domains_blacklist exclude_rel_nofollow_domains disabled_image_download_domains blocked_onebox_domains exclude_rel_nofollow_domains
email_domains_blacklist email_domains_whitelist white_listed_spam_host_domains blocked_email_domains allowed_email_domains allowed_spam_host_domains
} }
def filter_value(name, value) def filter_value(name, value)

View File

@ -17,8 +17,8 @@ class SpamHandler
return false if staff_members_with_same_ip > 0 return false if staff_members_with_same_ip > 0
ip_whitelisted = ScreenedIpAddress.is_whitelisted?(ip_address) allowed_ip = ScreenedIpAddress.is_allowed?(ip_address)
return false if ip_whitelisted return false if allowed_ip
tl0_accounts_with_same_ip = User.unscoped tl0_accounts_with_same_ip = User.unscoped
.where(trust_level: TrustLevel[0]) .where(trust_level: TrustLevel[0])

View File

@ -13,7 +13,7 @@ class Typepad < Thor
require './config/environment' require './config/environment'
backup_settings = {} backup_settings = {}
%w(email_domains_blacklist).each do |s| %w(blocked_email_domains).each do |s|
backup_settings[s] = SiteSetting.get(s) backup_settings[s] = SiteSetting.get(s)
end end
@ -53,7 +53,7 @@ class Typepad < Thor
end end
RateLimiter.disable RateLimiter.disable
SiteSetting.email_domains_blacklist = "" SiteSetting.blocked_email_domains = ""
puts "Importing #{entries.size} entries" puts "Importing #{entries.size} entries"

View File

@ -38,16 +38,16 @@ class TopicView
@default_post_custom_fields ||= [Post::NOTICE_TYPE, Post::NOTICE_ARGS, "action_code_who"] @default_post_custom_fields ||= [Post::NOTICE_TYPE, Post::NOTICE_ARGS, "action_code_who"]
end end
def self.post_custom_fields_whitelisters def self.post_custom_fields_allowlisters
@post_custom_fields_whitelisters ||= Set.new @post_custom_fields_allowlisters ||= Set.new
end end
def self.add_post_custom_fields_whitelister(&block) def self.add_post_custom_fields_allowlister(&block)
post_custom_fields_whitelisters << block post_custom_fields_allowlisters << block
end end
def self.whitelisted_post_custom_fields(user) def self.allowed_post_custom_fields(user)
wpcf = default_post_custom_fields + post_custom_fields_whitelisters.map { |w| w.call(user) } wpcf = default_post_custom_fields + post_custom_fields_allowlisters.map { |w| w.call(user) }
wpcf.flatten.uniq wpcf.flatten.uniq
end end
@ -87,12 +87,12 @@ class TopicView
filter_posts(options) filter_posts(options)
if @posts && !@skip_custom_fields if @posts && !@skip_custom_fields
if (added_fields = User.whitelisted_user_custom_fields(@guardian)).present? if (added_fields = User.allowed_user_custom_fields(@guardian)).present?
@user_custom_fields = User.custom_fields_for_ids(@posts.pluck(:user_id), added_fields) @user_custom_fields = User.custom_fields_for_ids(@posts.pluck(:user_id), added_fields)
end end
if (whitelisted_fields = TopicView.whitelisted_post_custom_fields(@user)).present? if (allowed_fields = TopicView.allowed_post_custom_fields(@user)).present?
@post_custom_fields = Post.custom_fields_for_ids(@posts.pluck(:id), whitelisted_fields) @post_custom_fields = Post.custom_fields_for_ids(@posts.pluck(:id), allowed_fields)
end end
end end

View File

@ -51,7 +51,7 @@ class UploadCreator
return @upload if @upload.errors.present? return @upload if @upload.errors.present?
if @image_info.type.to_s == "svg" if @image_info.type.to_s == "svg"
whitelist_svg! clean_svg!
elsif !Rails.env.test? || @opts[:force_optimize] elsif !Rails.env.test? || @opts[:force_optimize]
convert_to_jpeg! if convert_png_to_jpeg? convert_to_jpeg! if convert_png_to_jpeg?
downsize! if should_downsize? downsize! if should_downsize?
@ -302,9 +302,9 @@ class UploadCreator
end end
end end
def whitelist_svg! def clean_svg!
doc = Nokogiri::XML(@file) doc = Nokogiri::XML(@file)
doc.xpath(svg_whitelist_xpath).remove doc.xpath(svg_allowlist_xpath).remove
doc.xpath("//@*[starts-with(name(), 'on')]").remove doc.xpath("//@*[starts-with(name(), 'on')]").remove
doc.css('use').each do |use_el| doc.css('use').each do |use_el|
if use_el.attr('href') if use_el.attr('href')
@ -400,8 +400,8 @@ class UploadCreator
@allow_animation ||= @opts[:type] == "avatar" ? SiteSetting.allow_animated_avatars : SiteSetting.allow_animated_thumbnails @allow_animation ||= @opts[:type] == "avatar" ? SiteSetting.allow_animated_avatars : SiteSetting.allow_animated_thumbnails
end end
def svg_whitelist_xpath def svg_allowlist_xpath
@@svg_whitelist_xpath ||= "//*[#{WHITELISTED_SVG_ELEMENTS.map { |e| "name()!='#{e}'" }.join(" and ") }]" @@svg_allowlist_xpath ||= "//*[#{WHITELISTED_SVG_ELEMENTS.map { |e| "name()!='#{e}'" }.join(" and ") }]"
end end
def add_metadata! def add_metadata!

View File

@ -17,7 +17,7 @@ class UploadRecovery
analyzer.cooked_stripped.css("img", "a").each do |media| analyzer.cooked_stripped.css("img", "a").each do |media|
if media.name == "img" && orig_src = media["data-orig-src"] if media.name == "img" && orig_src = media["data-orig-src"]
if dom_class = media["class"] if dom_class = media["class"]
if (Post.white_listed_image_classes & dom_class.split).count > 0 if (Post.allowed_image_classes & dom_class.split).count > 0
next next
end end
end end

View File

@ -115,7 +115,7 @@ module UserNameSuggester
end end
name.gsub!(UsernameValidator.invalid_char_pattern, '_') name.gsub!(UsernameValidator.invalid_char_pattern, '_')
name = apply_whitelist(name) if UsernameValidator.char_whitelist_exists? name = apply_allowlist(name) if UsernameValidator.char_allowlist_exists?
name.gsub!(UsernameValidator::INVALID_LEADING_CHAR_PATTERN, '') name.gsub!(UsernameValidator::INVALID_LEADING_CHAR_PATTERN, '')
name.gsub!(UsernameValidator::CONFUSING_EXTENSIONS, "_") name.gsub!(UsernameValidator::CONFUSING_EXTENSIONS, "_")
name.gsub!(UsernameValidator::INVALID_TRAILING_CHAR_PATTERN, '') name.gsub!(UsernameValidator::INVALID_TRAILING_CHAR_PATTERN, '')
@ -123,9 +123,9 @@ module UserNameSuggester
name name
end end
def self.apply_whitelist(name) def self.apply_allowlist(name)
name.grapheme_clusters name.grapheme_clusters
.map { |c| UsernameValidator.whitelisted_char?(c) ? c : '_' } .map { |c| UsernameValidator.allowed_char?(c) ? c : '_' }
.join .join
end end

View File

@ -17,9 +17,9 @@ class EmailValidator < ActiveModel::EachValidator
end end
def self.allowed?(email) def self.allowed?(email)
if (setting = SiteSetting.email_domains_whitelist).present? if (setting = SiteSetting.allowed_email_domains).present?
return email_in_restriction_setting?(setting, email) || is_developer?(email) return email_in_restriction_setting?(setting, email) || is_developer?(email)
elsif (setting = SiteSetting.email_domains_blacklist).present? elsif (setting = SiteSetting.blocked_email_domains).present?
return !(email_in_restriction_setting?(setting, email) && !is_developer?(email)) return !(email_in_restriction_setting?(setting, email) && !is_developer?(email))
end end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class UnicodeUsernameWhitelistValidator class UnicodeUsernameAllowlistValidator
def initialize(opts = {}) def initialize(opts = {})
@opts = opts @opts = opts
end end
@ -10,12 +10,12 @@ class UnicodeUsernameWhitelistValidator
return true if value.blank? return true if value.blank?
if value.match?(/^\/.*\/[imxo]*$/) if value.match?(/^\/.*\/[imxo]*$/)
@error_message = I18n.t("site_settings.errors.unicode_username_whitelist.leading_trailing_slash") @error_message = I18n.t("site_settings.errors.allowed_unicode_usernames.leading_trailing_slash")
else else
begin begin
Regexp.new(value) Regexp.new(value)
rescue RegexpError => e rescue RegexpError => e
@error_message = I18n.t("site_settings.errors.unicode_username_whitelist.regex_invalid", error: e.message) @error_message = I18n.t("site_settings.errors.allowed_unicode_usernames.regex_invalid", error: e.message)
end end
end end

View File

@ -12,9 +12,9 @@ class UploadValidator < ActiveModel::Validator
return true if upload.user&.staff? return true if upload.user&.staff?
end end
# check the attachment blacklist # check the attachment blocklist
if upload.for_group_message && SiteSetting.allow_all_attachments_for_group_messages if upload.for_group_message && SiteSetting.allow_all_attachments_for_group_messages
return upload.original_filename =~ SiteSetting.attachment_filename_blacklist_regex return upload.original_filename =~ SiteSetting.blocked_attachment_filenames_regex
end end
extension = File.extname(upload.original_filename)[1..-1] || "" extension = File.extname(upload.original_filename)[1..-1] || ""

View File

@ -562,7 +562,7 @@ after_initialize do
register_post_custom_field_type(DiscoursePoll::HAS_POLLS, :boolean) register_post_custom_field_type(DiscoursePoll::HAS_POLLS, :boolean)
topic_view_post_custom_fields_whitelister { [DiscoursePoll::HAS_POLLS] } topic_view_post_custom_fields_allowlister { [DiscoursePoll::HAS_POLLS] }
add_to_class(:topic_view, :polls) do add_to_class(:topic_view, :polls) do
@polls ||= begin @polls ||= begin

View File

@ -70,7 +70,7 @@ class ImportScripts::Base
def get_site_settings_for_import def get_site_settings_for_import
{ {
email_domains_blacklist: '', blocked_email_domains: '',
min_topic_title_length: 1, min_topic_title_length: 1,
min_post_length: 1, min_post_length: 1,
min_first_post_length: 1, min_first_post_length: 1,

View File

@ -68,12 +68,12 @@ class ImportScripts::FMGP < ImportScripts::Base
@usermap = {} @usermap = {}
# G+ user IDs to filter out (spam, abuse) — no topics or posts, silence and suspend when creating # G+ user IDs to filter out (spam, abuse) — no topics or posts, silence and suspend when creating
# loaded from blacklist.json as array of google ids `[ 92310293874, 12378491235293 ]` # loaded from blocklist.json as array of google ids `[ 92310293874, 12378491235293 ]`
@blacklist = Set[] @blocklist = Set[]
# G+ user IDs whose posts are useful; if this is set, include only # G+ user IDs whose posts are useful; if this is set, include only
# posts (and non-blacklisted comments) authored by these IDs # posts (and non-blocklisted comments) authored by these IDs
@whitelist = nil @allowlist = nil
# Tags to apply to every topic; empty Array to not have any tags applied everywhere # Tags to apply to every topic; empty Array to not have any tags applied everywhere
@globaltags = [ "gplus" ] @globaltags = [ "gplus" ]
@ -117,10 +117,10 @@ class ImportScripts::FMGP < ImportScripts::Base
@categories = load_fmgp_json(arg) @categories = load_fmgp_json(arg)
elsif arg.end_with?("usermap.json") elsif arg.end_with?("usermap.json")
@usermap = load_fmgp_json(arg) @usermap = load_fmgp_json(arg)
elsif arg.end_with?('blacklist.json') elsif arg.end_with?('blocklist.json')
@blacklist = load_fmgp_json(arg).map { |i| i.to_s }.to_set @blocklist = load_fmgp_json(arg).map { |i| i.to_s }.to_set
elsif arg.end_with?('whitelist.json') elsif arg.end_with?('allowlist.json')
@whitelist = load_fmgp_json(arg).map { |i| i.to_s }.to_set @allowlist = load_fmgp_json(arg).map { |i| i.to_s }.to_set
elsif arg.end_with?('.json') elsif arg.end_with?('.json')
@feeds << load_fmgp_json(arg) @feeds << load_fmgp_json(arg)
elsif arg == '--dry-run' elsif arg == '--dry-run'
@ -149,8 +149,8 @@ class ImportScripts::FMGP < ImportScripts::Base
@posts_imported = 0 @posts_imported = 0
@topics_skipped = 0 @topics_skipped = 0
@posts_skipped = 0 @posts_skipped = 0
@topics_blacklisted = 0 @blocked_topics = 0
@posts_blacklisted = 0 @blocked_posts = 0
# count uploaded file size # count uploaded file size
@totalsize = 0 @totalsize = 0
@ -324,10 +324,10 @@ class ImportScripts::FMGP < ImportScripts::Base
newuser.approved = true newuser.approved = true
newuser.approved_by_id = @system_user.id newuser.approved_by_id = @system_user.id
newuser.approved_at = newuser.created_at newuser.approved_at = newuser.created_at
if @blacklist.include?(id.to_s) if @blocklist.include?(id.to_s)
now = DateTime.now now = DateTime.now
forever = 1000.years.from_now forever = 1000.years.from_now
# you can suspend as well if you want your blacklist to # you can suspend as well if you want your blocklist to
# be hard to recover from # be hard to recover from
#newuser.suspended_at = now #newuser.suspended_at = now
#newuser.suspended_till = forever #newuser.suspended_till = forever
@ -348,7 +348,7 @@ class ImportScripts::FMGP < ImportScripts::Base
# user already on system # user already on system
u = User.find(google_user_info.user_id) u = User.find(google_user_info.user_id)
if u.silenced? || u.suspended? if u.silenced? || u.suspended?
@blacklist.add(id) @blocklist.add(id)
end end
@users[id] = u @users[id] = u
email = u.email email = u.email
@ -371,7 +371,7 @@ class ImportScripts::FMGP < ImportScripts::Base
category["posts"].each do |post| category["posts"].each do |post|
# G+ post / Discourse topic # G+ post / Discourse topic
import_topic(post, category) import_topic(post, category)
print("\r#{@topics_imported}/#{@posts_imported} topics/posts (skipped: #{@topics_skipped}/#{@posts_skipped} blacklisted: #{@topics_blacklisted}/#{@posts_blacklisted}) ") print("\r#{@topics_imported}/#{@posts_imported} topics/posts (skipped: #{@topics_skipped}/#{@posts_skipped} blocklisted: #{@blocked_topics}/#{@blocked_posts}) ")
end end
end end
end end
@ -389,13 +389,13 @@ class ImportScripts::FMGP < ImportScripts::Base
@topics_skipped += 1 @topics_skipped += 1
else else
# new post # new post
if !@whitelist.nil? && !@whitelist.include?(post["author"]["id"]) if !@allowlist.nil? && !@allowlist.include?(post["author"]["id"])
# only ignore non-whitelisted if whitelist defined # only ignore non-allowlisted if allowlist defined
return return
end end
postmap = make_postmap(post, category, nil) postmap = make_postmap(post, category, nil)
if postmap.nil? if postmap.nil?
@topics_blacklisted += 1 @blocked_topics += 1
return return
end end
p = create_post(postmap, postmap[:id]) if !@dryrun p = create_post(postmap, postmap[:id]) if !@dryrun
@ -409,7 +409,7 @@ class ImportScripts::FMGP < ImportScripts::Base
else else
commentmap = make_postmap(comment, nil, p) commentmap = make_postmap(comment, nil, p)
if commentmap.nil? if commentmap.nil?
@posts_blacklisted += 1 @blocked_posts += 1
else else
@posts_imported += 1 @posts_imported += 1
new_comment = create_post(commentmap, commentmap[:id]) if !@dryrun new_comment = create_post(commentmap, commentmap[:id]) if !@dryrun
@ -420,7 +420,7 @@ class ImportScripts::FMGP < ImportScripts::Base
def make_postmap(post, category, parent) def make_postmap(post, category, parent)
post_author_id = post["author"]["id"] post_author_id = post["author"]["id"]
return nil if @blacklist.include?(post_author_id.to_s) return nil if @blocklist.include?(post_author_id.to_s)
raw = formatted_message(post) raw = formatted_message(post)
# if no message, image, or images, it's just empty # if no message, image, or images, it's just empty

View File

@ -497,10 +497,10 @@ class ImportScripts::Smf1 < ImportScripts::Base
def import_banned_domains def import_banned_domains
puts "", "Importing banned email domains..." puts "", "Importing banned email domains..."
blacklist = SiteSetting.email_domains_blacklist.split("|") blocklist = SiteSetting.blocked_email_domains.split("|")
banned_domains = mysql_query("SELECT SUBSTRING(email_address, 3) domain FROM smf_ban_items WHERE email_address RLIKE '^%@[^%]+$' GROUP BY email_address").map { |r| r["domain"] } banned_domains = mysql_query("SELECT SUBSTRING(email_address, 3) domain FROM smf_ban_items WHERE email_address RLIKE '^%@[^%]+$' GROUP BY email_address").map { |r| r["domain"] }
SiteSetting.email_domains_blacklist = (blacklist + banned_domains).uniq.sort.join("|") SiteSetting.blocked_email_domains = (blocklist + banned_domains).uniq.sort.join("|")
end end
def import_banned_emails def import_banned_emails

View File

@ -178,38 +178,38 @@ describe Auth::GithubAuthenticator do
expect(result.email_valid).to eq(hash[:info][:email].present?) expect(result.email_valid).to eq(hash[:info][:email].present?)
end end
it 'will skip blacklisted domains for non existing users' do it 'will skip blocklisted domains for non existing users' do
hash = { hash = {
extra: { extra: {
all_emails: [{ all_emails: [{
email: "not_allowed@blacklist.com", email: "not_allowed@blocklist.com",
primary: true, primary: true,
verified: true, verified: true,
}, { }, {
email: "allowed@whitelist.com", email: "allowed@allowlist.com",
primary: false, primary: false,
verified: true, verified: true,
}] }]
}, },
info: { info: {
email: "not_allowed@blacklist.com", email: "not_allowed@blocklist.com",
nickname: "person", nickname: "person",
name: "Person Lastname", name: "Person Lastname",
}, },
uid: "100" uid: "100"
} }
SiteSetting.email_domains_blacklist = "blacklist.com" SiteSetting.blocked_email_domains = "blocklist.com"
result = authenticator.after_authenticate(hash) result = authenticator.after_authenticate(hash)
expect(result.user).to eq(nil) expect(result.user).to eq(nil)
expect(result.username).to eq(hash[:info][:nickname]) expect(result.username).to eq(hash[:info][:nickname])
expect(result.name).to eq(hash[:info][:name]) expect(result.name).to eq(hash[:info][:name])
expect(result.email).to eq("allowed@whitelist.com") expect(result.email).to eq("allowed@allowlist.com")
expect(result.email_valid).to eq(true) expect(result.email_valid).to eq(true)
end end
it 'will find whitelisted domains for non existing users' do it 'will find allowlisted domains for non existing users' do
hash = { hash = {
extra: { extra: {
all_emails: [{ all_emails: [{
@ -217,11 +217,11 @@ describe Auth::GithubAuthenticator do
primary: true, primary: true,
verified: true, verified: true,
}, { }, {
email: "not_allowed@blacklist.com", email: "not_allowed@blocklist.com",
primary: false, primary: false,
verified: true, verified: true,
}, { }, {
email: "allowed@whitelist.com", email: "allowed@allowlist.com",
primary: false, primary: false,
verified: true, verified: true,
}] }]
@ -234,13 +234,13 @@ describe Auth::GithubAuthenticator do
uid: "100" uid: "100"
} }
SiteSetting.email_domains_whitelist = "whitelist.com" SiteSetting.allowed_email_domains = "allowlist.com"
result = authenticator.after_authenticate(hash) result = authenticator.after_authenticate(hash)
expect(result.user).to eq(nil) expect(result.user).to eq(nil)
expect(result.username).to eq(hash[:info][:nickname]) expect(result.username).to eq(hash[:info][:nickname])
expect(result.name).to eq(hash[:info][:name]) expect(result.name).to eq(hash[:info][:name])
expect(result.email).to eq("allowed@whitelist.com") expect(result.email).to eq("allowed@allowlist.com")
expect(result.email_valid).to eq(true) expect(result.email_valid).to eq(true)
end end

View File

@ -235,7 +235,7 @@ describe HasCustomFields do
it "supports bulk retrieval with a list of ids" do it "supports bulk retrieval with a list of ids" do
item1 = CustomFieldsTestItem.new item1 = CustomFieldsTestItem.new
item1.custom_fields = { "a" => ["b", "c", "d"], 'not_whitelisted' => 'secret' } item1.custom_fields = { "a" => ["b", "c", "d"], 'not_allowlisted' => 'secret' }
item1.save item1.save
item2 = CustomFieldsTestItem.new item2 = CustomFieldsTestItem.new
@ -245,7 +245,7 @@ describe HasCustomFields do
fields = CustomFieldsTestItem.custom_fields_for_ids([item1.id, item2.id], ['a', 'e']) fields = CustomFieldsTestItem.custom_fields_for_ids([item1.id, item2.id], ['a', 'e'])
expect(fields).to be_present expect(fields).to be_present
expect(fields[item1.id]['a']).to match_array(['b', 'c', 'd']) expect(fields[item1.id]['a']).to match_array(['b', 'c', 'd'])
expect(fields[item1.id]['not_whitelisted']).to be_blank expect(fields[item1.id]['not_allowlisted']).to be_blank
expect(fields[item2.id]['e']).to eq('hallo') expect(fields[item2.id]['e']).to eq('hallo')
end end

View File

@ -1600,7 +1600,7 @@ describe CookedPostProcessor do
context "onebox" do context "onebox" do
before do before do
Oneboxer.stubs(:onebox).with(anything, anything).returns(nil) Oneboxer.stubs(:onebox).with(anything, anything).returns(nil)
Oneboxer.stubs(:onebox).with('https://discourse.org', anything).returns("<aside class=\"onebox whitelistedgeneric\">the rest of the onebox</aside>") Oneboxer.stubs(:onebox).with('https://discourse.org', anything).returns("<aside class=\"onebox allowlistedgeneric\">the rest of the onebox</aside>")
end end
it "awards the badge for using an onebox" do it "awards the badge for using an onebox" do

View File

@ -70,13 +70,13 @@ describe CrawlerDetection do
end end
describe 'allow_crawler?' do describe 'allow_crawler?' do
it 'returns true if whitelist and blacklist are blank' do it 'returns true if allowlist and blocklist are blank' do
expect(CrawlerDetection.allow_crawler?('Googlebot/2.1 (+http://www.google.com/bot.html)')).to eq(true) expect(CrawlerDetection.allow_crawler?('Googlebot/2.1 (+http://www.google.com/bot.html)')).to eq(true)
end end
context 'whitelist is set' do context 'allowlist is set' do
before do before do
SiteSetting.whitelisted_crawler_user_agents = 'Googlebot|Twitterbot' SiteSetting.allowed_crawler_user_agents = 'Googlebot|Twitterbot'
end end
it 'returns true for matching user agents' do it 'returns true for matching user agents' do
@ -91,20 +91,20 @@ describe CrawlerDetection do
expect(CrawlerDetection.allow_crawler?('')).to eq(false) expect(CrawlerDetection.allow_crawler?('')).to eq(false)
end end
context 'and blacklist is set' do context 'and blocklist is set' do
before do before do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot-Image' SiteSetting.blocked_crawler_user_agents = 'Googlebot-Image'
end end
it 'ignores the blacklist' do it 'ignores the blocklist' do
expect(CrawlerDetection.allow_crawler?('Googlebot-Image/1.0')).to eq(true) expect(CrawlerDetection.allow_crawler?('Googlebot-Image/1.0')).to eq(true)
end end
end end
end end
context 'blacklist is set' do context 'blocklist is set' do
before do before do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot|Twitterbot' SiteSetting.blocked_crawler_user_agents = 'Googlebot|Twitterbot'
end end
it 'returns true for crawlers that do not match' do it 'returns true for crawlers that do not match' do
@ -122,47 +122,47 @@ describe CrawlerDetection do
end end
describe 'is_blocked_crawler?' do describe 'is_blocked_crawler?' do
it 'is false if user agent is a crawler and no whitelist or blacklist is defined' do it 'is false if user agent is a crawler and no allowlist or blocklist is defined' do
expect(CrawlerDetection.is_blocked_crawler?('Twitterbot')).to eq(false) expect(CrawlerDetection.is_blocked_crawler?('Twitterbot')).to eq(false)
end end
it 'is false if user agent is not a crawler and no whitelist or blacklist is defined' do it 'is false if user agent is not a crawler and no allowlist or blocklist is defined' do
expect(CrawlerDetection.is_blocked_crawler?('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')).to eq(false) expect(CrawlerDetection.is_blocked_crawler?('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')).to eq(false)
end end
it 'is true if user agent is a crawler and is not whitelisted' do it 'is true if user agent is a crawler and is not allowlisted' do
SiteSetting.whitelisted_crawler_user_agents = 'Googlebot' SiteSetting.allowed_crawler_user_agents = 'Googlebot'
expect(CrawlerDetection.is_blocked_crawler?('Twitterbot')).to eq(true) expect(CrawlerDetection.is_blocked_crawler?('Twitterbot')).to eq(true)
end end
it 'is false if user agent is not a crawler and there is a whitelist' do it 'is false if user agent is not a crawler and there is a allowlist' do
SiteSetting.whitelisted_crawler_user_agents = 'Googlebot' SiteSetting.allowed_crawler_user_agents = 'Googlebot'
expect(CrawlerDetection.is_blocked_crawler?('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')).to eq(false) expect(CrawlerDetection.is_blocked_crawler?('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')).to eq(false)
end end
it 'is true if user agent is a crawler and is blacklisted' do it 'is true if user agent is a crawler and is blocklisted' do
SiteSetting.blacklisted_crawler_user_agents = 'Twitterbot' SiteSetting.blocked_crawler_user_agents = 'Twitterbot'
expect(CrawlerDetection.is_blocked_crawler?('Twitterbot')).to eq(true) expect(CrawlerDetection.is_blocked_crawler?('Twitterbot')).to eq(true)
end end
it 'is true if user agent is a crawler and is not blacklisted' do it 'is true if user agent is a crawler and is not blocklisted' do
SiteSetting.blacklisted_crawler_user_agents = 'Twitterbot' SiteSetting.blocked_crawler_user_agents = 'Twitterbot'
expect(CrawlerDetection.is_blocked_crawler?('Googlebot')).to eq(false) expect(CrawlerDetection.is_blocked_crawler?('Googlebot')).to eq(false)
end end
it 'is false if user agent is not a crawler and blacklist is defined' do it 'is false if user agent is not a crawler and blocklist is defined' do
SiteSetting.blacklisted_crawler_user_agents = 'Mozilla' SiteSetting.blocked_crawler_user_agents = 'Mozilla'
expect(CrawlerDetection.is_blocked_crawler?('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')).to eq(false) expect(CrawlerDetection.is_blocked_crawler?('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')).to eq(false)
end end
it 'is true if user agent is missing and whitelist is defined' do it 'is true if user agent is missing and allowlist is defined' do
SiteSetting.whitelisted_crawler_user_agents = 'Googlebot' SiteSetting.allowed_crawler_user_agents = 'Googlebot'
expect(CrawlerDetection.is_blocked_crawler?('')).to eq(true) expect(CrawlerDetection.is_blocked_crawler?('')).to eq(true)
expect(CrawlerDetection.is_blocked_crawler?(nil)).to eq(true) expect(CrawlerDetection.is_blocked_crawler?(nil)).to eq(true)
end end
it 'is false if user agent is missing and blacklist is defined' do it 'is false if user agent is missing and blocklist is defined' do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot' SiteSetting.blocked_crawler_user_agents = 'Googlebot'
expect(CrawlerDetection.is_blocked_crawler?('')).to eq(false) expect(CrawlerDetection.is_blocked_crawler?('')).to eq(false)
expect(CrawlerDetection.is_blocked_crawler?(nil)).to eq(false) expect(CrawlerDetection.is_blocked_crawler?(nil)).to eq(false)
end end

View File

@ -25,16 +25,16 @@ describe Email::Receiver do
expect { process(:screened_email) }.to raise_error(Email::Receiver::ScreenedEmailError) expect { process(:screened_email) }.to raise_error(Email::Receiver::ScreenedEmailError)
end end
it "raises EmailNotAllowed when email address is not on whitelist" do it "raises EmailNotAllowed when email address is not on allowlist" do
SiteSetting.email_domains_whitelist = "example.com|bar.com" SiteSetting.allowed_email_domains = "example.com|bar.com"
Fabricate(:group, incoming_email: "some_group@bar.com") Fabricate(:group, incoming_email: "some_group@bar.com")
expect { process(:blacklist_whitelist_email) }.to raise_error(Email::Receiver::EmailNotAllowed) expect { process(:blocklist_allowlist_email) }.to raise_error(Email::Receiver::EmailNotAllowed)
end end
it "raises EmailNotAllowed when email address is on blacklist" do it "raises EmailNotAllowed when email address is on blocklist" do
SiteSetting.email_domains_blacklist = "email.com|mail.com" SiteSetting.blocked_email_domains = "email.com|mail.com"
Fabricate(:group, incoming_email: "some_group@bar.com") Fabricate(:group, incoming_email: "some_group@bar.com")
expect { process(:blacklist_whitelist_email) }.to raise_error(Email::Receiver::EmailNotAllowed) expect { process(:blocklist_allowlist_email) }.to raise_error(Email::Receiver::EmailNotAllowed)
end end
it "raises an UserNotFoundError when staged users are disabled" do it "raises an UserNotFoundError when staged users are disabled" do
@ -419,9 +419,9 @@ describe Email::Receiver do
expect { process(:invalid_from_2) }.to raise_error(Email::Receiver::NoSenderDetectedError) expect { process(:invalid_from_2) }.to raise_error(Email::Receiver::NoSenderDetectedError)
end end
it "doesn't raise an AutoGeneratedEmailError when the mail is auto generated but is whitelisted" do it "doesn't raise an AutoGeneratedEmailError when the mail is auto generated but is allowlisted" do
SiteSetting.auto_generated_whitelist = "foo@bar.com|discourse@bar.com" SiteSetting.auto_generated_allowlist = "foo@bar.com|discourse@bar.com"
expect { process(:auto_generated_whitelisted) }.to change { topic.posts.count } expect { process(:auto_generated_allowlisted) }.to change { topic.posts.count }
end end
it "doesn't raise an AutoGeneratedEmailError when block_auto_generated_emails is disabled" do it "doesn't raise an AutoGeneratedEmailError when block_auto_generated_emails is disabled" do
@ -1211,41 +1211,41 @@ describe Email::Receiver do
include_examples "does not create staged users", :unsubscribe_new_user, Email::Receiver::UnsubscribeNotAllowed include_examples "does not create staged users", :unsubscribe_new_user, Email::Receiver::UnsubscribeNotAllowed
end end
context "when From email address is not on whitelist" do context "when From email address is not on allowlist" do
before do before do
SiteSetting.email_domains_whitelist = "example.com|bar.com" SiteSetting.allowed_email_domains = "example.com|bar.com"
Fabricate(:group, incoming_email: "some_group@bar.com") Fabricate(:group, incoming_email: "some_group@bar.com")
end end
include_examples "does not create staged users", :blacklist_whitelist_email, Email::Receiver::EmailNotAllowed include_examples "does not create staged users", :blocklist_allowlist_email, Email::Receiver::EmailNotAllowed
end end
context "when From email address is on blacklist" do context "when From email address is on blocklist" do
before do before do
SiteSetting.email_domains_blacklist = "email.com|mail.com" SiteSetting.blocked_email_domains = "email.com|mail.com"
Fabricate(:group, incoming_email: "some_group@bar.com") Fabricate(:group, incoming_email: "some_group@bar.com")
end end
include_examples "does not create staged users", :blacklist_whitelist_email, Email::Receiver::EmailNotAllowed include_examples "does not create staged users", :blocklist_allowlist_email, Email::Receiver::EmailNotAllowed
end end
context "blacklist and whitelist for To and Cc" do context "blocklist and allowlist for To and Cc" do
before do before do
Fabricate(:group, incoming_email: "some_group@bar.com") Fabricate(:group, incoming_email: "some_group@bar.com")
end end
it "does not create staged users for email addresses not on whitelist" do it "does not create staged users for email addresses not on allowlist" do
SiteSetting.email_domains_whitelist = "mail.com|example.com" SiteSetting.allowed_email_domains = "mail.com|example.com"
process(:blacklist_whitelist_email) process(:blocklist_allowlist_email)
expect(User.find_by_email("alice@foo.com")).to be_nil expect(User.find_by_email("alice@foo.com")).to be_nil
expect(User.find_by_email("bob@foo.com")).to be_nil expect(User.find_by_email("bob@foo.com")).to be_nil
expect(User.find_by_email("carol@example.com")).to be_present expect(User.find_by_email("carol@example.com")).to be_present
end end
it "does not create staged users for email addresses on blacklist" do it "does not create staged users for email addresses on blocklist" do
SiteSetting.email_domains_blacklist = "email.com|foo.com" SiteSetting.blocked_email_domains = "email.com|foo.com"
process(:blacklist_whitelist_email) process(:blocklist_allowlist_email)
expect(User.find_by_email("alice@foo.com")).to be_nil expect(User.find_by_email("alice@foo.com")).to be_nil
expect(User.find_by_email("bob@foo.com")).to be_nil expect(User.find_by_email("bob@foo.com")).to be_nil

View File

@ -396,7 +396,7 @@ describe FinalDestination do
end end
it "returns false for IPV6 via site settings" do it "returns false for IPV6 via site settings" do
SiteSetting.blacklist_ip_blocks = '2001:abc:de::/48|2002:abc:de::/48' SiteSetting.blocked_ip_blocks = '2001:abc:de::/48|2002:abc:de::/48'
expect(fd('https://[2001:abc:de:01:0:3f0:6a65:c2bf]').is_dest_valid?).to eq(false) expect(fd('https://[2001:abc:de:01:0:3f0:6a65:c2bf]').is_dest_valid?).to eq(false)
expect(fd('https://[2002:abc:de:01:0:3f0:6a65:c2bf]').is_dest_valid?).to eq(false) expect(fd('https://[2002:abc:de:01:0:3f0:6a65:c2bf]').is_dest_valid?).to eq(false)
expect(fd('https://internal-ipv6.com').is_dest_valid?).to eq(false) expect(fd('https://internal-ipv6.com').is_dest_valid?).to eq(false)
@ -404,7 +404,7 @@ describe FinalDestination do
end end
it "ignores invalid ranges" do it "ignores invalid ranges" do
SiteSetting.blacklist_ip_blocks = '2001:abc:de::/48|eviltrout' SiteSetting.blocked_ip_blocks = '2001:abc:de::/48|eviltrout'
expect(fd('https://[2001:abc:de:01:0:3f0:6a65:c2bf]').is_dest_valid?).to eq(false) expect(fd('https://[2001:abc:de:01:0:3f0:6a65:c2bf]').is_dest_valid?).to eq(false)
end end
@ -432,8 +432,8 @@ describe FinalDestination do
expect(fd("https://cdn.example.com/some/asset").is_dest_valid?).to eq(true) expect(fd("https://cdn.example.com/some/asset").is_dest_valid?).to eq(true)
end end
it 'supports whitelisting via a site setting' do it 'supports allowlisting via a site setting' do
SiteSetting.whitelist_internal_hosts = 'private-host.com' SiteSetting.allowed_internal_hosts = 'private-host.com'
expect(fd("https://private-host.com/some/url").is_dest_valid?).to eq(true) expect(fd("https://private-host.com/some/url").is_dest_valid?).to eq(true)
end end
end end

View File

@ -51,8 +51,8 @@ describe Guardian do
expect(Guardian.new(user).link_posting_access).to eq('none') expect(Guardian.new(user).link_posting_access).to eq('none')
end end
it "is limited for a user of a low trust level with a whitelist" do it "is limited for a user of a low trust level with a allowlist" do
SiteSetting.whitelisted_link_domains = 'example.com' SiteSetting.allowed_link_domains = 'example.com'
user.trust_level = 0 user.trust_level = 0
SiteSetting.min_trust_to_post_links = 1 SiteSetting.min_trust_to_post_links = 1
expect(Guardian.new(user).link_posting_access).to eq('limited') expect(Guardian.new(user).link_posting_access).to eq('limited')
@ -78,9 +78,9 @@ describe Guardian do
expect(Guardian.new(user).can_post_link?(host: host)).to eq(false) expect(Guardian.new(user).can_post_link?(host: host)).to eq(false)
end end
describe "whitelisted host" do describe "allowlisted host" do
before do before do
SiteSetting.whitelisted_link_domains = host SiteSetting.allowed_link_domains = host
end end
it "allows a new user to post the link to the host" do it "allows a new user to post the link to the host" do
@ -2931,17 +2931,17 @@ describe Guardian do
let!(:theme) { Fabricate(:theme) } let!(:theme) { Fabricate(:theme) }
let!(:theme2) { Fabricate(:theme) } let!(:theme2) { Fabricate(:theme) }
context "whitelist mode" do context "allowlist mode" do
before do before do
GlobalSetting.reset_whitelisted_theme_ids! GlobalSetting.reset_allowed_theme_ids!
global_setting :whitelisted_theme_repos, " https://magic.com/repo.git, https://x.com/git" global_setting :allowed_theme_repos, " https://magic.com/repo.git, https://x.com/git"
end end
after do after do
GlobalSetting.reset_whitelisted_theme_ids! GlobalSetting.reset_allowed_theme_ids!
end end
it "should respect theme whitelisting" do it "should respect theme allowlisting" do
r = RemoteTheme.create!(remote_url: "https://magic.com/repo.git") r = RemoteTheme.create!(remote_url: "https://magic.com/repo.git")
theme.update!(remote_theme_id: r.id) theme.update!(remote_theme_id: r.id)

View File

@ -116,7 +116,7 @@ describe InlineOneboxer do
expect(onebox[:title]).to eq("Hello 🍕 with an emoji") expect(onebox[:title]).to eq("Hello 🍕 with an emoji")
end end
it "will not crawl domains that aren't whitelisted" do it "will not crawl domains that aren't allowlisted" do
onebox = InlineOneboxer.lookup("https://eviltrout.com", skip_cache: true) onebox = InlineOneboxer.lookup("https://eviltrout.com", skip_cache: true)
expect(onebox).to be_blank expect(onebox).to be_blank
end end
@ -153,8 +153,8 @@ describe InlineOneboxer do
expect(onebox[:title]).to eq(nil) expect(onebox[:title]).to eq(nil)
end end
it "will lookup whitelisted domains" do it "will lookup allowlisted domains" do
SiteSetting.inline_onebox_domains_whitelist = "eviltrout.com" SiteSetting.allowed_inline_onebox_domains = "eviltrout.com"
RetrieveTitle.stubs(:crawl).returns("Evil Trout's Blog") RetrieveTitle.stubs(:crawl).returns("Evil Trout's Blog")
onebox = InlineOneboxer.lookup( onebox = InlineOneboxer.lookup(

View File

@ -215,8 +215,8 @@ describe Middleware::AnonymousCache::Helper do
@status, @response_header, @response = middleware.call(@env) @status, @response_header, @response = middleware.call(@env)
end end
it "applies whitelisted_crawler_user_agents correctly" do it "applies allowed_crawler_user_agents correctly" do
SiteSetting.whitelisted_crawler_user_agents = 'Googlebot' SiteSetting.allowed_crawler_user_agents = 'Googlebot'
get '/', headers: { get '/', headers: {
'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)' 'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)'
@ -236,7 +236,7 @@ describe Middleware::AnonymousCache::Helper do
end end
it "doesn't block api requests" do it "doesn't block api requests" do
SiteSetting.whitelisted_crawler_user_agents = 'Googlebot' SiteSetting.allowed_crawler_user_agents = 'Googlebot'
api_key = Fabricate(:api_key) api_key = Fabricate(:api_key)
get "/latest?api_key=#{api_key.key}&api_username=system", headers: { get "/latest?api_key=#{api_key.key}&api_username=system", headers: {
@ -245,8 +245,8 @@ describe Middleware::AnonymousCache::Helper do
expect(@status).to eq(200) expect(@status).to eq(200)
end end
it "applies blacklisted_crawler_user_agents correctly" do it "applies blocked_crawler_user_agents correctly" do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot' SiteSetting.blocked_crawler_user_agents = 'Googlebot'
get '/', headers: non_crawler get '/', headers: non_crawler
expect(@status).to eq(200) expect(@status).to eq(200)
@ -265,7 +265,7 @@ describe Middleware::AnonymousCache::Helper do
end end
it "should never block robots.txt" do it "should never block robots.txt" do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot' SiteSetting.blocked_crawler_user_agents = 'Googlebot'
get '/robots.txt', headers: { get '/robots.txt', headers: {
'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)' 'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)'
@ -275,7 +275,7 @@ describe Middleware::AnonymousCache::Helper do
end end
it "should never block srv/status" do it "should never block srv/status" do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot' SiteSetting.blocked_crawler_user_agents = 'Googlebot'
get '/srv/status', headers: { get '/srv/status', headers: {
'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)' 'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)'
@ -285,7 +285,7 @@ describe Middleware::AnonymousCache::Helper do
end end
it "blocked crawlers shouldn't log page views" do it "blocked crawlers shouldn't log page views" do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot' SiteSetting.blocked_crawler_user_agents = 'Googlebot'
get '/', headers: { get '/', headers: {
'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)' 'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)'
@ -295,7 +295,7 @@ describe Middleware::AnonymousCache::Helper do
end end
it "blocks json requests" do it "blocks json requests" do
SiteSetting.blacklisted_crawler_user_agents = 'Googlebot' SiteSetting.blocked_crawler_user_agents = 'Googlebot'
get '/srv/status.json', headers: { get '/srv/status.json', headers: {
'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)' 'HTTP_USER_AGENT' => 'Googlebot/2.1 (+http://www.google.com/bot.html)'

View File

@ -343,7 +343,7 @@ describe Middleware::RequestTracker do
tracker.call(env("REQUEST_URI" => uri, "ANON_CACHE_DURATION" => 60)) tracker.call(env("REQUEST_URI" => uri, "ANON_CACHE_DURATION" => 60))
expect(@data[:cache]).to eq("true") expect(@data[:cache]).to eq("true")
# not whitelisted # not allowlisted
request_params.delete("a") request_params.delete("a")
expect(@env["action_dispatch.request.parameters"]).to eq(request_params) expect(@env["action_dispatch.request.parameters"]).to eq(request_params)

View File

@ -0,0 +1,49 @@
# frozen_string_literal: true
require 'rails_helper'
require 'oneboxer'
describe Onebox::Engine::AllowlistedGenericOnebox do
describe ".===" do
it "matches any domain" do
expect(described_class === URI('http://foo.bar/resource')).to be(true)
end
it "doesn't match an IP address" do
expect(described_class === URI('http://1.2.3.4/resource')).to be(false)
expect(described_class === URI('http://1.2.3.4:1234/resource')).to be(false)
end
end
it "allowlists iframes" do
allowlisted_body = '<html><head><link rel="alternate" type="application/json+oembed" href="https://allowlist.ed/iframes.json" />'
blocklisted_body = '<html><head><link rel="alternate" type="application/json+oembed" href="https://blocklist.ed/iframes.json" />'
allowlisted_oembed = {
type: "rich",
height: "100",
html: "<iframe src='https://ifram.es/foo/bar'></iframe>"
}
blocklisted_oembed = {
type: "rich",
height: "100",
html: "<iframe src='https://malicious/discourse.org/'></iframe>"
}
stub_request(:get, "https://blocklist.ed/iframes").to_return(status: 200, body: blocklisted_body)
stub_request(:get, "https://blocklist.ed/iframes.json").to_return(status: 200, body: blocklisted_oembed.to_json)
stub_request(:get, "https://allowlist.ed/iframes").to_return(status: 200, body: allowlisted_body)
stub_request(:get, "https://allowlist.ed/iframes.json").to_return(status: 200, body: allowlisted_oembed.to_json)
SiteSetting.allowed_iframes = "discourse.org|https://ifram.es"
expect(Onebox.preview("https://blocklist.ed/iframes").to_s).to be_empty
expect(Onebox.preview("https://allowlist.ed/iframes").to_s).to match("iframe src")
end
end

View File

@ -1,49 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
require 'oneboxer'
describe Onebox::Engine::WhitelistedGenericOnebox do
describe ".===" do
it "matches any domain" do
expect(described_class === URI('http://foo.bar/resource')).to be(true)
end
it "doesn't match an IP address" do
expect(described_class === URI('http://1.2.3.4/resource')).to be(false)
expect(described_class === URI('http://1.2.3.4:1234/resource')).to be(false)
end
end
it "whitelists iframes" do
whitelisted_body = '<html><head><link rel="alternate" type="application/json+oembed" href="https://whitelist.ed/iframes.json" />'
blacklisted_body = '<html><head><link rel="alternate" type="application/json+oembed" href="https://blacklist.ed/iframes.json" />'
whitelisted_oembed = {
type: "rich",
height: "100",
html: "<iframe src='https://ifram.es/foo/bar'></iframe>"
}
blacklisted_oembed = {
type: "rich",
height: "100",
html: "<iframe src='https://malicious/discourse.org/'></iframe>"
}
stub_request(:get, "https://blacklist.ed/iframes").to_return(status: 200, body: blacklisted_body)
stub_request(:get, "https://blacklist.ed/iframes.json").to_return(status: 200, body: blacklisted_oembed.to_json)
stub_request(:get, "https://whitelist.ed/iframes").to_return(status: 200, body: whitelisted_body)
stub_request(:get, "https://whitelist.ed/iframes.json").to_return(status: 200, body: whitelisted_oembed.to_json)
SiteSetting.allowed_iframes = "discourse.org|https://ifram.es"
expect(Onebox.preview("https://blacklist.ed/iframes").to_s).to be_empty
expect(Onebox.preview("https://whitelist.ed/iframes").to_s).to match("iframe src")
end
end

View File

@ -155,8 +155,8 @@ describe Oneboxer do
end end
end end
it "does not crawl blacklisted URLs" do it "does not crawl blocklisted URLs" do
SiteSetting.onebox_domains_blacklist = "git.*.com|bitbucket.com" SiteSetting.blocked_onebox_domains = "git.*.com|bitbucket.com"
url = 'https://github.com/discourse/discourse/commit/21b562852885f883be43032e03c709241e8e6d4f' url = 'https://github.com/discourse/discourse/commit/21b562852885f883be43032e03c709241e8e6d4f'
stub_request(:head, 'https://discourse.org/').to_return(status: 302, body: "", headers: { location: url }) stub_request(:head, 'https://discourse.org/').to_return(status: 302, body: "", headers: { location: url })
@ -164,7 +164,7 @@ describe Oneboxer do
expect(Oneboxer.external_onebox('https://discourse.org/')[:onebox]).to be_empty expect(Oneboxer.external_onebox('https://discourse.org/')[:onebox]).to be_empty
end end
it "does not consider ignore_redirects domains as blacklisted" do it "does not consider ignore_redirects domains as blocklisted" do
url = 'https://store.steampowered.com/app/271590/Grand_Theft_Auto_V/' url = 'https://store.steampowered.com/app/271590/Grand_Theft_Auto_V/'
stub_request(:head, url).to_return(status: 200, body: "", headers: {}) stub_request(:head, url).to_return(status: 200, body: "", headers: {})
stub_request(:get, url).to_return(status: 200, body: "", headers: {}) stub_request(:get, url).to_return(status: 200, body: "", headers: {})

View File

@ -762,7 +762,7 @@ describe PrettyText do
context 'option to preserve onebox source' do context 'option to preserve onebox source' do
it "should return the right excerpt" do it "should return the right excerpt" do
onebox = "<aside class=\"onebox whitelistedgeneric\">\n <header class=\"source\">\n <a href=\"https://meta.discourse.org/t/infrequent-translation-updates-in-stable-branch/31213/9\">meta.discourse.org</a>\n </header>\n <article class=\"onebox-body\">\n <img src=\"https://cdn-enterprise.discourse.org/meta/user_avatar/meta.discourse.org/gerhard/200/70381_1.png\" width=\"\" height=\"\" class=\"thumbnail\">\n\n<h3><a href=\"https://meta.discourse.org/t/infrequent-translation-updates-in-stable-branch/31213/9\">Infrequent translation updates in stable branch</a></h3>\n\n<p>Well, there's an Italian translation for \"New Topic\" in beta, it's been there since November 2014 and it works here on meta. Do you have any plugins installed? Try disabling them. I'm quite confident that it's either a plugin or a site...</p>\n\n </article>\n <div class=\"onebox-metadata\">\n \n \n </div>\n <div style=\"clear: both\"></div>\n</aside>\n\n\n" onebox = "<aside class=\"onebox allowlistedgeneric\">\n <header class=\"source\">\n <a href=\"https://meta.discourse.org/t/infrequent-translation-updates-in-stable-branch/31213/9\">meta.discourse.org</a>\n </header>\n <article class=\"onebox-body\">\n <img src=\"https://cdn-enterprise.discourse.org/meta/user_avatar/meta.discourse.org/gerhard/200/70381_1.png\" width=\"\" height=\"\" class=\"thumbnail\">\n\n<h3><a href=\"https://meta.discourse.org/t/infrequent-translation-updates-in-stable-branch/31213/9\">Infrequent translation updates in stable branch</a></h3>\n\n<p>Well, there's an Italian translation for \"New Topic\" in beta, it's been there since November 2014 and it works here on meta. Do you have any plugins installed? Try disabling them. I'm quite confident that it's either a plugin or a site...</p>\n\n </article>\n <div class=\"onebox-metadata\">\n \n \n </div>\n <div style=\"clear: both\"></div>\n</aside>\n\n\n"
expected = "<a href=\"https://meta.discourse.org/t/infrequent-translation-updates-in-stable-branch/31213/9\">meta.discourse.org</a>" expected = "<a href=\"https://meta.discourse.org/t/infrequent-translation-updates-in-stable-branch/31213/9\">meta.discourse.org</a>"
expect(PrettyText.excerpt(onebox, 100, keep_onebox_source: true)) expect(PrettyText.excerpt(onebox, 100, keep_onebox_source: true))
@ -1554,7 +1554,7 @@ HTML
end end
it "can properly whitelist iframes" do it "can properly allowlist iframes" do
SiteSetting.allowed_iframes = "https://bob.com/a|http://silly.com?EMBED=" SiteSetting.allowed_iframes = "https://bob.com/a|http://silly.com?EMBED="
raw = <<~IFRAMES raw = <<~IFRAMES
<iframe src='https://www.google.com/maps/Embed?testing'></iframe> <iframe src='https://www.google.com/maps/Embed?testing'></iframe>
@ -1619,12 +1619,12 @@ HTML
expect(cooked).to include("data-theme-a") expect(cooked).to include("data-theme-a")
end end
it "whitelists lang attribute" do it "allowlists lang attribute" do
cooked = PrettyText.cook("<p lang='fr'>tester</p><div lang='fr'>tester</div><span lang='fr'>tester</span>") cooked = PrettyText.cook("<p lang='fr'>tester</p><div lang='fr'>tester</div><span lang='fr'>tester</span>")
expect(cooked).to eq("<p lang=\"fr\">tester</p><div lang=\"fr\">tester</div><span lang=\"fr\">tester</span>") expect(cooked).to eq("<p lang=\"fr\">tester</p><div lang=\"fr\">tester</div><span lang=\"fr\">tester</span>")
end end
it "whitelists ruby tags" do it "allowlists ruby tags" do
# read all about ruby chars at: https://en.wikipedia.org/wiki/Ruby_character # read all about ruby chars at: https://en.wikipedia.org/wiki/Ruby_character
# basically it is super hard to remember every single rare letter when there are # basically it is super hard to remember every single rare letter when there are
# so many, so ruby tags provide a hint. # so many, so ruby tags provide a hint.

View File

@ -595,18 +595,18 @@ describe SiteSettingExtension do
describe "filter domain name" do describe "filter domain name" do
before do before do
settings.setting(:white_listed_spam_host_domains, "www.example.com") settings.setting(:allowed_spam_host_domains, "www.example.com")
settings.refresh! settings.refresh!
end end
it "filters domain" do it "filters domain" do
settings.set("white_listed_spam_host_domains", "http://www.discourse.org/") settings.set("allowed_spam_host_domains", "http://www.discourse.org/")
expect(settings.white_listed_spam_host_domains).to eq("www.discourse.org") expect(settings.allowed_spam_host_domains).to eq("www.discourse.org")
end end
it "returns invalid domain as is, without throwing exception" do it "returns invalid domain as is, without throwing exception" do
settings.set("white_listed_spam_host_domains", "test!url") settings.set("allowed_spam_host_domains", "test!url")
expect(settings.white_listed_spam_host_domains).to eq("test!url") expect(settings.allowed_spam_host_domains).to eq("test!url")
end end
end end

View File

@ -48,11 +48,11 @@ describe SpamHandler do
Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[0]) Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[0])
end end
it "doesn't limit registrations when the IP is whitelisted" do it "doesn't limit registrations when the IP is allowlisted" do
# setup # setup
SiteSetting.max_new_accounts_per_registration_ip = 0 SiteSetting.max_new_accounts_per_registration_ip = 0
Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[0]) Fabricate(:user, ip_address: "42.42.42.42", trust_level: TrustLevel[0])
ScreenedIpAddress.stubs(:is_whitelisted?).with("42.42.42.42").returns(true) ScreenedIpAddress.stubs(:is_allowed?).with("42.42.42.42").returns(true)
# should not limit registration # should not limit registration
SiteSetting.max_new_accounts_per_registration_ip = 1 SiteSetting.max_new_accounts_per_registration_ip = 1

View File

@ -171,14 +171,14 @@ describe UserNameSuggester do
.to eq('য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া') .to eq('য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া-য়া')
end end
it "uses whitelist" do it "uses allowlist" do
SiteSetting.unicode_username_character_whitelist = "[äöüßÄÖÜẞ]" SiteSetting.allowed_unicode_username_characters = "[äöüßÄÖÜẞ]"
expect(UserNameSuggester.suggest('πουλί')).to eq('111') expect(UserNameSuggester.suggest('πουλί')).to eq('111')
expect(UserNameSuggester.suggest('a鳥b')).to eq('a_b') expect(UserNameSuggester.suggest('a鳥b')).to eq('a_b')
expect(UserNameSuggester.suggest('Löwe')).to eq('Löwe') expect(UserNameSuggester.suggest('Löwe')).to eq('Löwe')
SiteSetting.unicode_username_character_whitelist = "[য়া]" SiteSetting.allowed_unicode_username_characters = "[য়া]"
expect(UserNameSuggester.suggest('aয়াb鳥c')).to eq('aয়াb_c') expect(UserNameSuggester.suggest('aয়াb鳥c')).to eq('aয়াb_c')
end end
end end

View File

@ -21,8 +21,8 @@ describe EmailValidator do
expect(blocks?('SAM@sam.com')).to eq(true) expect(blocks?('SAM@sam.com')).to eq(true)
end end
it "blocks based on email_domains_blacklist" do it "blocks based on blocked_email_domains" do
SiteSetting.email_domains_blacklist = "email.com|mail.com|e-mail.com" SiteSetting.blocked_email_domains = "email.com|mail.com|e-mail.com"
expect(blocks?('sam@email.com')).to eq(true) expect(blocks?('sam@email.com')).to eq(true)
expect(blocks?('sam@EMAIL.com')).to eq(true) expect(blocks?('sam@EMAIL.com')).to eq(true)
expect(blocks?('sam@bob.email.com')).to eq(true) expect(blocks?('sam@bob.email.com')).to eq(true)
@ -30,8 +30,8 @@ describe EmailValidator do
expect(blocks?('sam@googlemail.com')).to eq(false) expect(blocks?('sam@googlemail.com')).to eq(false)
end end
it "blocks based on email_domains_whitelist" do it "blocks based on allowed_email_domains" do
SiteSetting.email_domains_whitelist = "googlemail.com|email.com" SiteSetting.allowed_email_domains = "googlemail.com|email.com"
expect(blocks?('sam@email.com')).to eq(false) expect(blocks?('sam@email.com')).to eq(false)
expect(blocks?('sam@EMAIL.com')).to eq(false) expect(blocks?('sam@EMAIL.com')).to eq(false)
expect(blocks?('sam@bob.email.com')).to eq(false) expect(blocks?('sam@bob.email.com')).to eq(false)
@ -49,8 +49,8 @@ describe EmailValidator do
expect(EmailValidator.can_auto_approve_user?("foobar@example.com")).to eq(true) expect(EmailValidator.can_auto_approve_user?("foobar@example.com")).to eq(true)
end end
it "returns false if domain not present in email_domains_whitelist" do it "returns false if domain not present in allowed_email_domains" do
SiteSetting.email_domains_whitelist = "googlemail.com" SiteSetting.allowed_email_domains = "googlemail.com"
SiteSetting.auto_approve_email_domains = "example.com|googlemail.com" SiteSetting.auto_approve_email_domains = "example.com|googlemail.com"
expect(EmailValidator.can_auto_approve_user?("foobar@example.com")).to eq(false) expect(EmailValidator.can_auto_approve_user?("foobar@example.com")).to eq(false)

View File

@ -2,16 +2,16 @@
require 'rails_helper' require 'rails_helper'
describe UnicodeUsernameWhitelistValidator do describe UnicodeUsernameAllowlistValidator do
subject { described_class.new } subject { described_class.new }
it "allows an empty whitelist" do it "allows an empty allowlist" do
expect(subject.valid_value?("")).to eq(true) expect(subject.valid_value?("")).to eq(true)
expect(subject.error_message).to be_blank expect(subject.error_message).to be_blank
end end
it "disallows leading and trailing slashes" do it "disallows leading and trailing slashes" do
expected_error = I18n.t("site_settings.errors.unicode_username_whitelist.leading_trailing_slash") expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.leading_trailing_slash")
expect(subject.valid_value?("/foo/")).to eq(false) expect(subject.valid_value?("/foo/")).to eq(false)
expect(subject.error_message).to eq(expected_error) expect(subject.error_message).to eq(expected_error)
@ -30,7 +30,7 @@ describe UnicodeUsernameWhitelistValidator do
end end
it "detects invalid regular expressions" do it "detects invalid regular expressions" do
expected_error = I18n.t("site_settings.errors.unicode_username_whitelist.regex_invalid", error: "") expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.regex_invalid", error: "")
expect(subject.valid_value?("\\p{Foo}")).to eq(false) expect(subject.valid_value?("\\p{Foo}")).to eq(false)
expect(subject.error_message).to start_with(expected_error) expect(subject.error_message).to start_with(expected_error)

View File

@ -66,7 +66,7 @@ describe ContentSecurityPolicy do
expect(script_srcs).to include("'report-sample'") expect(script_srcs).to include("'report-sample'")
end end
it 'whitelists Google Analytics and Tag Manager when integrated' do it 'allowlists Google Analytics and Tag Manager when integrated' do
SiteSetting.ga_universal_tracking_code = 'UA-12345678-9' SiteSetting.ga_universal_tracking_code = 'UA-12345678-9'
SiteSetting.gtm_container_id = 'GTM-ABCDEF' SiteSetting.gtm_container_id = 'GTM-ABCDEF'
@ -75,7 +75,7 @@ describe ContentSecurityPolicy do
expect(script_srcs).to include('https://www.googletagmanager.com/gtm.js') expect(script_srcs).to include('https://www.googletagmanager.com/gtm.js')
end end
it 'whitelists CDN assets when integrated' do it 'allowlists CDN assets when integrated' do
set_cdn_url('https://cdn.com') set_cdn_url('https://cdn.com')
script_srcs = parse(policy)['script-src'] script_srcs = parse(policy)['script-src']

Some files were not shown because too many files have changed in this diff Show More