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:
parent
5077cf52fd
commit
e0d9232259
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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") },
|
||||||
{
|
{
|
||||||
|
|
|
@ -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")}}
|
||||||
|
|
|
@ -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%"> </th>
|
<th style="width: 10%"> </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>
|
||||||
|
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
|
@ -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\./)) {
|
||||||
|
|
|
@ -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 = {};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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
|
||||||
#
|
#
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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])
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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] || ""
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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)'
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
|
@ -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: {})
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
@ -8,4 +8,4 @@ Mime-Version: 1.0
|
||||||
Content-Type: text/plain
|
Content-Type: text/plain
|
||||||
Content-Transfer-Encoding: 7bit
|
Content-Transfer-Encoding: 7bit
|
||||||
|
|
||||||
Email from a domain on blacklist or whitelist.
|
Email from a domain on blocklist or allowlist.
|
|
@ -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
Loading…
Reference in New Issue