|
2 | 2 |
|
3 | 3 | require "securerandom" |
4 | 4 | require_relative "../security" |
| 5 | +require_relative "../core/plugin_loader" |
5 | 6 |
|
6 | 7 | module Hooks |
7 | 8 | module App |
@@ -64,85 +65,28 @@ def parse_payload(raw_body, headers, symbolize: true) |
64 | 65 | # Load handler class |
65 | 66 | # |
66 | 67 | # @param handler_class_name [String] The name of the handler class to load |
67 | | - # @param handler_dir [String] The directory containing handler files |
| 68 | + # @param handler_dir [String] The directory containing handler files (kept for compatibility) |
68 | 69 | # @return [Object] An instance of the loaded handler class |
69 | | - # @raise [LoadError] If the handler file or class cannot be found |
70 | | - # @raise [StandardError] Halts with error if handler cannot be loaded |
71 | | - def load_handler(handler_class_name, handler_dir) |
72 | | - # Security: Validate handler class name to prevent arbitrary class loading |
73 | | - unless valid_handler_class_name?(handler_class_name) |
74 | | - error!("invalid handler class name: #{handler_class_name}", 400) |
75 | | - end |
76 | | - |
77 | | - # Convert class name to file name (e.g., Team1Handler -> team1_handler.rb) |
78 | | - # E.g.2: GithubHandler -> github_handler.rb |
79 | | - # E.g.3: GitHubHandler -> git_hub_handler.rb |
80 | | - file_name = handler_class_name.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, "") + ".rb" |
81 | | - file_path = File.join(handler_dir, file_name) |
82 | | - |
83 | | - # Security: Ensure the file path doesn't escape the handler directory |
84 | | - normalized_handler_dir = Pathname.new(File.expand_path(handler_dir)) |
85 | | - normalized_file_path = Pathname.new(File.expand_path(file_path)) |
86 | | - unless normalized_file_path.descend.any? { |path| path == normalized_handler_dir } |
87 | | - error!("handler path outside of handler directory", 400) |
88 | | - end |
89 | | - |
90 | | - if File.exist?(file_path) |
91 | | - require file_path |
92 | | - handler_class = Object.const_get(handler_class_name) |
93 | | - |
94 | | - # Security: Ensure the loaded class inherits from the expected base class |
95 | | - unless handler_class < Hooks::Plugins::Handlers::Base |
96 | | - error!("handler class must inherit from Hooks::Plugins::Handlers::Base", 400) |
97 | | - end |
98 | | - |
| 70 | + # @raise [StandardError] If handler cannot be found |
| 71 | + def load_handler(handler_class_name, handler_dir = nil) |
| 72 | + # Get handler class from loaded plugins registry |
| 73 | + begin |
| 74 | + handler_class = Core::PluginLoader.get_handler_plugin(handler_class_name) |
99 | 75 | handler_class.new |
100 | | - else |
101 | | - raise LoadError, "Handler #{handler_class_name} not found at #{file_path}" |
| 76 | + rescue => e |
| 77 | + error!("failed to get handler '#{handler_class_name}': #{e.message}", 500) |
102 | 78 | end |
103 | | - rescue => e |
104 | | - error!("failed to load handler: #{e.message}", 500) |
105 | 79 | end |
106 | 80 |
|
107 | | - # Load auth plugin class |
| 81 | + # Load auth plugin class (DEPRECATED - plugins are now loaded at boot time) |
108 | 82 | # |
| 83 | + # @deprecated This method is kept for compatibility but auth plugins are now loaded at boot time |
109 | 84 | # @param auth_plugin_class_name [String] The name of the auth plugin class to load |
110 | 85 | # @param auth_plugin_dir [String] The directory containing auth plugin files |
111 | 86 | # @return [Class] The loaded auth plugin class |
112 | | - # @raise [LoadError] If the auth plugin file or class cannot be found |
113 | | - # @raise [StandardError] Halts with error if auth plugin cannot be loaded |
| 87 | + # @raise [StandardError] Always raises error as dynamic loading is no longer supported |
114 | 88 | def load_auth_plugin(auth_plugin_class_name, auth_plugin_dir) |
115 | | - # Security: Validate auth plugin class name to prevent arbitrary class loading |
116 | | - unless valid_auth_plugin_class_name?(auth_plugin_class_name) |
117 | | - error!("invalid auth plugin class name: #{auth_plugin_class_name}", 400) |
118 | | - end |
119 | | - |
120 | | - # Convert class name to file name (e.g., SomeCoolAuthPlugin -> some_cool_auth_plugin.rb) |
121 | | - file_name = auth_plugin_class_name.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, "") + ".rb" |
122 | | - file_path = File.join(auth_plugin_dir, file_name) |
123 | | - |
124 | | - # Security: Ensure the file path doesn't escape the auth plugin directory |
125 | | - normalized_auth_plugin_dir = Pathname.new(File.expand_path(auth_plugin_dir)) |
126 | | - normalized_file_path = Pathname.new(File.expand_path(file_path)) |
127 | | - unless normalized_file_path.descend.any? { |path| path == normalized_auth_plugin_dir } |
128 | | - error!("auth plugin path outside of auth plugin directory", 400) |
129 | | - end |
130 | | - |
131 | | - if File.exist?(file_path) |
132 | | - require file_path |
133 | | - auth_plugin_class = Object.const_get("Hooks::Plugins::Auth::#{auth_plugin_class_name}") |
134 | | - |
135 | | - # Security: Ensure the loaded class inherits from the expected base class |
136 | | - unless auth_plugin_class < Hooks::Plugins::Auth::Base |
137 | | - error!("auth plugin class must inherit from Hooks::Plugins::Auth::Base", 400) |
138 | | - end |
139 | | - |
140 | | - auth_plugin_class |
141 | | - else |
142 | | - error!("Auth plugin #{auth_plugin_class_name} not found at #{file_path}", 500) |
143 | | - end |
144 | | - rescue => e |
145 | | - error!("failed to load auth plugin: #{e.message}", 500) |
| 89 | + error!("Dynamic auth plugin loading is deprecated. Auth plugins are now loaded at boot time.", 500) |
146 | 90 | end |
147 | 91 |
|
148 | 92 | private |
|
0 commit comments