-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplugin.rb
More file actions
93 lines (80 loc) · 3.07 KB
/
Copy pathplugin.rb
File metadata and controls
93 lines (80 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# frozen_string_literal: true
# name: discourse-plugin-redirect-on-forbidden
# about: Redirects 403 responses to configurable external URLs based on category mapping rules
# meta_topic_id: TODO
# version: 0.1.0
# authors: Marfeel
# url: https://github.com/Marfeel/discourse-plugin-redirect-on-forbidden
# required_version: 2.7.0
enabled_site_setting :redirect_on_forbidden_enabled
register_asset "stylesheets/redirect-on-forbidden.scss"
add_admin_route "redirect_on_forbidden.admin.title", "redirect-on-forbidden"
module ::RedirectOnForbidden
PLUGIN_NAME ||= "discourse-plugin-redirect-on-forbidden"
end
require_relative "lib/redirect_on_forbidden/engine"
after_initialize do
add_to_serializer(
:site,
:redirect_on_forbidden_rules,
include_condition: -> { SiteSetting.redirect_on_forbidden_enabled },
) do
RedirectOnForbidden::RedirectRule.cached_rules.map do |rule|
{ category_ids: rule.category_ids, url_pattern: rule.url_pattern }
end
end
on(:site_setting_changed) do |name, _old, _new|
if name == :redirect_on_forbidden_enabled
RedirectOnForbidden::RedirectRule.reset_cache!
end
end
MessageBus.subscribe("/redirect-on-forbidden/cache-reset") do
RedirectOnForbidden::RedirectRule.reset_cache!
end
reloadable_patch do
module ::RedirectOnForbidden::ControllerExtension
def rescue_discourse_actions(type, status_code, opts = nil)
if type == :invalid_access && status_code == 403 && SiteSetting.redirect_on_forbidden_enabled
category_id = nil
topic_slug = nil
if params[:topic_id] || (params[:controller] == "topics" && params[:id])
topic_id = params[:topic_id] || params[:id]
topic = Topic.find_by(id: topic_id)
if topic
category_id = topic.category_id
topic_slug = topic.slug
end
elsif params[:category_id] || (params[:controller] == "categories")
category_id = (params[:category_id] || params[:id]).to_i
category_id = nil if category_id == 0
elsif params[:category_slug_path_with_id]
parts = params[:category_slug_path_with_id].split("/")
category_id = parts.last.to_i
category_id = nil if category_id == 0
end
if category_id
redirect_url = RedirectOnForbidden::UrlResolver.resolve(
category_id: category_id,
topic_slug: topic_slug,
)
if redirect_url
if request.format.html?
redirect_to redirect_url, status: 301, allow_other_host: true
return
elsif request.xhr? || request.format.json?
render json: {
error_type: "invalid_access",
redirect_to: redirect_url,
category_id: category_id,
}, status: 403
return
end
end
end
end
super(type, status_code, opts)
end
end
::ApplicationController.prepend(::RedirectOnForbidden::ControllerExtension)
end
end