wpscan 3.0.8 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/app/controllers.rb +1 -0
- data/app/controllers/aliases.rb +12 -0
- data/app/controllers/core.rb +3 -5
- data/app/controllers/enumeration.rb +2 -28
- data/app/controllers/enumeration/enum_methods.rb +12 -2
- data/app/controllers/wp_version.rb +4 -0
- data/app/finders/main_theme/css_style.rb +2 -2
- data/app/finders/main_theme/urls_in_homepage.rb +3 -3
- data/app/finders/plugin_version.rb +1 -8
- data/app/finders/plugins.rb +13 -4
- data/app/finders/plugins/body_pattern.rb +27 -0
- data/app/finders/plugins/comment.rb +31 -0
- data/app/finders/plugins/config_parser.rb +31 -0
- data/app/finders/plugins/header_pattern.rb +41 -0
- data/app/finders/plugins/javascript_var.rb +29 -0
- data/app/finders/plugins/known_locations.rb +5 -5
- data/app/finders/plugins/query_parameter.rb +25 -0
- data/app/finders/plugins/urls_in_homepage.rb +4 -8
- data/app/finders/plugins/xpath.rb +29 -0
- data/app/finders/theme_version.rb +1 -1
- data/app/finders/theme_version/woo_framework_meta_generator.rb +2 -2
- data/app/finders/themes/known_locations.rb +5 -5
- data/app/finders/themes/urls_in_homepage.rb +2 -2
- data/app/finders/users/login_error_messages.rb +1 -4
- data/app/finders/users/wp_json_api.rb +2 -2
- data/app/finders/wp_items/urls_in_homepage.rb +1 -1
- data/app/finders/wp_version.rb +21 -18
- data/app/models/plugin.rb +4 -4
- data/app/models/theme.rb +6 -6
- data/app/models/timthumb.rb +1 -3
- data/app/models/wp_item.rb +15 -15
- data/app/views/json/enumeration/plugins.erb +1 -1
- data/app/views/json/enumeration/themes.erb +1 -1
- data/app/views/json/wp_item.erb +1 -1
- data/bin/wpscan +2 -1
- data/lib/wpscan/db.rb +14 -10
- data/lib/wpscan/db/dynamic_finders/base.rb +41 -0
- data/lib/wpscan/db/dynamic_finders/plugin.rb +111 -0
- data/lib/wpscan/db/dynamic_finders/theme.rb +16 -0
- data/lib/wpscan/db/dynamic_finders/wordpress.rb +75 -0
- data/lib/wpscan/db/updater.rb +2 -2
- data/lib/wpscan/finders.rb +13 -1
- data/lib/wpscan/finders/dynamic_finder/finder.rb +66 -0
- data/lib/wpscan/finders/dynamic_finder/version/body_pattern.rb +28 -0
- data/lib/wpscan/finders/dynamic_finder/version/comment.rb +16 -0
- data/lib/wpscan/finders/dynamic_finder/version/config_parser.rb +52 -0
- data/lib/wpscan/finders/dynamic_finder/version/finder.rb +29 -0
- data/lib/wpscan/finders/dynamic_finder/version/header_pattern.rb +28 -0
- data/lib/wpscan/finders/dynamic_finder/version/javascript_var.rb +56 -0
- data/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb +62 -0
- data/lib/wpscan/finders/dynamic_finder/version/xpath.rb +34 -0
- data/lib/wpscan/finders/dynamic_finder/wp_item_version.rb +42 -0
- data/lib/wpscan/finders/dynamic_finder/wp_items/finder.rb +96 -0
- data/lib/wpscan/finders/dynamic_finder/wp_version.rb +60 -0
- data/lib/wpscan/helper.rb +11 -0
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +16 -1
- data/lib/wpscan/version.rb +1 -1
- metadata +32 -24
- data/app/finders/plugin_version/layer_slider/translation_file.rb +0 -40
- data/app/finders/plugin_version/revslider/release_log.rb +0 -35
- data/app/finders/plugin_version/shareaholic/meta_tag.rb +0 -27
- data/app/finders/plugin_version/sitepress_multilingual_cms/meta_generator.rb +0 -27
- data/app/finders/plugin_version/sitepress_multilingual_cms/version_parameter.rb +0 -31
- data/app/finders/plugin_version/w3_total_cache/headers.rb +0 -28
- data/app/finders/plugins/comments.rb +0 -31
- data/app/finders/plugins/headers.rb +0 -36
- data/app/finders/wp_version/homepage_stylesheet_numbers.rb +0 -59
- data/app/finders/wp_version/install_stylesheet_numbers.rb +0 -16
- data/app/finders/wp_version/meta_generator.rb +0 -27
- data/app/finders/wp_version/opml_generator.rb +0 -23
- data/app/finders/wp_version/sitemap_generator.rb +0 -23
- data/app/finders/wp_version/upgrade_stylesheet_numbers.rb +0 -13
- data/lib/wpscan/db/dynamic_finders.rb +0 -55
- data/lib/wpscan/finders/finder/plugin_version/comments.rb +0 -27
@@ -1,40 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module PluginVersion
|
4
|
-
module LayerSlider
|
5
|
-
# Version from a Translation file
|
6
|
-
#
|
7
|
-
# See https://github.com/wpscanteam/wpscan/issues/765
|
8
|
-
class TranslationFile < CMSScanner::Finders::Finder
|
9
|
-
# @param [ Hash ] opts
|
10
|
-
#
|
11
|
-
# @return [ Version ]
|
12
|
-
def aggressive(_opts = {})
|
13
|
-
potential_urls.each do |url|
|
14
|
-
res = Browser.get(url)
|
15
|
-
|
16
|
-
next unless res.code == 200 && res.body =~ /Project-Id-Version: LayerSlider WP v?([0-9\.][^\\\s]+)/
|
17
|
-
|
18
|
-
return WPScan::Version.new(
|
19
|
-
Regexp.last_match[1],
|
20
|
-
found_by: 'Translation File (Aggressive Detection)',
|
21
|
-
confidence: 90,
|
22
|
-
interesting_entries: ["#{url}, Match: '#{Regexp.last_match}'"]
|
23
|
-
)
|
24
|
-
end
|
25
|
-
nil
|
26
|
-
end
|
27
|
-
|
28
|
-
# @return [ Array<String> ] The potential URLs where the version is disclosed
|
29
|
-
def potential_urls
|
30
|
-
# Recent versions seem to use the 'locales' directory instead of the 'languages' one.
|
31
|
-
# Maybe also check other locales ?
|
32
|
-
%w[locales languages].reduce([]) do |a, e|
|
33
|
-
a << target.url("#{e}/LayerSlider-en_US.po")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module PluginVersion
|
4
|
-
module Revslider
|
5
|
-
# Version from the release_log.html
|
6
|
-
#
|
7
|
-
# See https://github.com/wpscanteam/wpscan/issues/817
|
8
|
-
class ReleaseLog < CMSScanner::Finders::Finder
|
9
|
-
# @param [ Hash ] opts
|
10
|
-
#
|
11
|
-
# @return [ Version ]
|
12
|
-
def aggressive(_opts = {})
|
13
|
-
res = Browser.get(release_log_url)
|
14
|
-
|
15
|
-
res.html.css('h3.version-number:first').each do |node|
|
16
|
-
next unless node.text =~ /\AVersion ([0-9\.]+).*\z/i
|
17
|
-
|
18
|
-
return WPScan::Version.new(
|
19
|
-
Regexp.last_match[1],
|
20
|
-
found_by: found_by,
|
21
|
-
confidence: 90,
|
22
|
-
interesting_entries: ["#{release_log_url}, Match: '#{Regexp.last_match}'"]
|
23
|
-
)
|
24
|
-
end
|
25
|
-
nil
|
26
|
-
end
|
27
|
-
|
28
|
-
def release_log_url
|
29
|
-
target.url('release_log.html')
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module PluginVersion
|
4
|
-
module Shareaholic
|
5
|
-
# Version from the meta
|
6
|
-
class MetaTag < CMSScanner::Finders::Finder
|
7
|
-
# @param [ Hash ] opts
|
8
|
-
#
|
9
|
-
# @return [ Version ]
|
10
|
-
def passive(_opts = {})
|
11
|
-
target.target.homepage_res.html.css('meta[name="shareaholic:wp_version"]').each do |node|
|
12
|
-
next unless node['content'] =~ /\A([0-9\.]+)/i
|
13
|
-
|
14
|
-
return WPScan::Version.new(
|
15
|
-
Regexp.last_match(1),
|
16
|
-
found_by: found_by,
|
17
|
-
confidence: 50,
|
18
|
-
interesting_entries: ["#{target.target.url}, Match: '#{node.to_s.strip}'"]
|
19
|
-
)
|
20
|
-
end
|
21
|
-
nil
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module PluginVersion
|
4
|
-
module SitepressMultilingualCms
|
5
|
-
# Version from the meta generator
|
6
|
-
class MetaGenerator < CMSScanner::Finders::Finder
|
7
|
-
# @param [ Hash ] opts
|
8
|
-
#
|
9
|
-
# @return [ Version ]
|
10
|
-
def passive(_opts = {})
|
11
|
-
target.target.homepage_res.html.css('meta[name="generator"]').each do |node|
|
12
|
-
next unless node['content'] =~ /\AWPML\sver:([0-9\.]+)\sstt/i
|
13
|
-
|
14
|
-
return WPScan::Version.new(
|
15
|
-
Regexp.last_match(1),
|
16
|
-
found_by: 'Meta Generator (Passive detection)',
|
17
|
-
confidence: 50,
|
18
|
-
interesting_entries: ["#{target.target.url}, Match: '#{node}'"]
|
19
|
-
)
|
20
|
-
end
|
21
|
-
nil
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module PluginVersion
|
4
|
-
module SitepressMultilingualCms
|
5
|
-
# Version from the v parameter in href / src of stylesheets / scripts
|
6
|
-
class VersionParameter < CMSScanner::Finders::Finder
|
7
|
-
# @param [ Hash ] opts
|
8
|
-
#
|
9
|
-
# @return [ Version ]
|
10
|
-
def passive(_opts = {})
|
11
|
-
pattern = %r{#{Regexp.escape(target.target.plugins_dir)}/sitepress-multilingual-cms/}i
|
12
|
-
|
13
|
-
target.target.in_scope_urls(target.target.homepage_res, '//link|//script') do |url|
|
14
|
-
uri = Addressable::URI.parse(url)
|
15
|
-
|
16
|
-
next unless uri.path =~ pattern && uri.query =~ /v=([0-9\.]+)/
|
17
|
-
|
18
|
-
return WPScan::Version.new(
|
19
|
-
Regexp.last_match[1],
|
20
|
-
found_by: found_by,
|
21
|
-
confidence: 50,
|
22
|
-
interesting_entries: [url]
|
23
|
-
)
|
24
|
-
end
|
25
|
-
nil
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module PluginVersion
|
4
|
-
module W3TotalCache
|
5
|
-
# Version from Headers
|
6
|
-
class Headers < CMSScanner::Finders::Finder
|
7
|
-
PATTERN = %r{W3 Total Cache/([0-9.]+)}i
|
8
|
-
|
9
|
-
# @param [ Hash ] opts
|
10
|
-
#
|
11
|
-
# @return [ Version ]
|
12
|
-
def passive(_opts = {})
|
13
|
-
headers = target.target.headers
|
14
|
-
|
15
|
-
return unless headers && headers['X-Powered-By'].to_s =~ PATTERN
|
16
|
-
|
17
|
-
WPScan::Version.new(
|
18
|
-
Regexp.last_match[1],
|
19
|
-
found_by: found_by,
|
20
|
-
confidence: 80,
|
21
|
-
interesting_entries: ["#{target.target.url}, Match: '#{Regexp.last_match}'"]
|
22
|
-
)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module Plugins
|
4
|
-
# Plugins from Comments Finder
|
5
|
-
class Comments < CMSScanner::Finders::Finder
|
6
|
-
# @param [ Hash ] opts
|
7
|
-
# @option opts [ Boolean ] :unique Default: true
|
8
|
-
#
|
9
|
-
# @return [ Array<Plugin> ]
|
10
|
-
def passive(opts = {})
|
11
|
-
found = []
|
12
|
-
opts[:unique] = true unless opts.key?(:unique)
|
13
|
-
|
14
|
-
target.homepage_res.html.xpath('//comment()').each do |node|
|
15
|
-
comment = node.text.to_s.strip
|
16
|
-
|
17
|
-
DB::DynamicPluginFinders.comments.each do |name, config|
|
18
|
-
next unless comment =~ config['pattern']
|
19
|
-
|
20
|
-
plugin = WPScan::Plugin.new(name, target, opts.merge(found_by: found_by, confidence: 70))
|
21
|
-
|
22
|
-
found << plugin unless opts[:unique] && found.include?(plugin)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
found
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module Plugins
|
4
|
-
# Plugins from Headers Finder
|
5
|
-
class Headers < CMSScanner::Finders::Finder
|
6
|
-
# @param [ Hash ] opts
|
7
|
-
#
|
8
|
-
# @return [ Array<Plugin> ]
|
9
|
-
def passive(opts = {})
|
10
|
-
plugin_names_from_headers(opts).reduce([]) do |a, e|
|
11
|
-
a << WPScan::Plugin.new(e, target, opts.merge(found_by: found_by, confidence: 60))
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# X-Powered-By: W3 Total Cache/0.9.2.5
|
16
|
-
# WP-Super-Cache: Served supercache file from PHP
|
17
|
-
#
|
18
|
-
# @return [ Array<String> ]
|
19
|
-
def plugin_names_from_headers(_opts = {})
|
20
|
-
found = []
|
21
|
-
headers = target.homepage_res.headers
|
22
|
-
|
23
|
-
if headers
|
24
|
-
powered_by = headers['X-Powered-By'].to_s
|
25
|
-
wp_super_cache = headers['wp-super-cache'].to_s
|
26
|
-
|
27
|
-
found << 'w3-total-cache' if powered_by =~ Finders::PluginVersion::W3TotalCache::Headers::PATTERN
|
28
|
-
found << 'wp-super-cache' if wp_super_cache =~ /supercache/i
|
29
|
-
end
|
30
|
-
|
31
|
-
found
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module WpVersion
|
4
|
-
# Stylesheets Version Finder from Homepage
|
5
|
-
#
|
6
|
-
# TODO: Maybe put such methods in the CMSScanner to have a generic
|
7
|
-
# way of getting those versions, and allow the confidence to be
|
8
|
-
# customised
|
9
|
-
class HomepageStylesheetNumbers < CMSScanner::Finders::Finder
|
10
|
-
# @return [ Array<WpVersion> ]
|
11
|
-
def passive(_opts = {})
|
12
|
-
wp_versions(target.homepage_url)
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
# @param [ String ] url
|
18
|
-
#
|
19
|
-
# @return [ Array<WpVersion> ]
|
20
|
-
def wp_versions(url)
|
21
|
-
found = []
|
22
|
-
|
23
|
-
scan_page(url).each do |version_number, occurences|
|
24
|
-
next unless WPScan::WpVersion.valid?(version_number) # Skip invalid versions
|
25
|
-
|
26
|
-
found << WPScan::WpVersion.new(
|
27
|
-
version_number,
|
28
|
-
found_by: found_by,
|
29
|
-
confidence: 5 * occurences.count,
|
30
|
-
interesting_entries: occurences
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
found
|
35
|
-
end
|
36
|
-
|
37
|
-
# @param [ String ] url
|
38
|
-
#
|
39
|
-
# @return [ Hash ]
|
40
|
-
def scan_page(url)
|
41
|
-
found = {}
|
42
|
-
pattern = /\bver=([0-9\.]+)/i
|
43
|
-
|
44
|
-
target.in_scope_urls(Browser.get(url), '//link|//script') do |stylesheet_url, _tag|
|
45
|
-
uri = Addressable::URI.parse(stylesheet_url)
|
46
|
-
next unless uri.query&.match(pattern)
|
47
|
-
|
48
|
-
version = Regexp.last_match[1].to_s
|
49
|
-
|
50
|
-
found[version] ||= []
|
51
|
-
found[version] << stylesheet_url
|
52
|
-
end
|
53
|
-
|
54
|
-
found
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module WpVersion
|
4
|
-
# Stylesheets Version Finder from Install page
|
5
|
-
class InstallStylesheetNumbers < HomepageStylesheetNumbers
|
6
|
-
# Overrides the parent
|
7
|
-
def passive(_ops = {}); end
|
8
|
-
|
9
|
-
# @return [ Array<WpVersion> ]
|
10
|
-
def aggressive(_opts = {})
|
11
|
-
wp_versions(target.url('wp-admin/install.php'))
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module WpVersion
|
4
|
-
# Meta Generator Version Finder
|
5
|
-
class MetaGenerator < CMSScanner::Finders::Finder
|
6
|
-
# @return [ WpVersion ]
|
7
|
-
def passive(_opts = {})
|
8
|
-
target.homepage_res.html.css('meta[name="generator"]').each do |node|
|
9
|
-
next unless node.attribute('content').to_s =~ /wordpress ([0-9\.]+)/i
|
10
|
-
|
11
|
-
number = Regexp.last_match(1)
|
12
|
-
|
13
|
-
next unless WPScan::WpVersion.valid?(number)
|
14
|
-
|
15
|
-
return WPScan::WpVersion.new(
|
16
|
-
number,
|
17
|
-
found_by: 'Meta Generator (Passive detection)',
|
18
|
-
confidence: 80,
|
19
|
-
interesting_entries: ["#{target.url}, Match: '#{node.to_s.strip}'"]
|
20
|
-
)
|
21
|
-
end
|
22
|
-
nil
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module WpVersion
|
4
|
-
# Sitemap Generator Version Finder
|
5
|
-
class OpmlGenerator < CMSScanner::Finders::Finder
|
6
|
-
# @return [ WpVersion ]
|
7
|
-
def aggressive(_opts = {})
|
8
|
-
target.comments_from_page(%r{\Agenerator="wordpress/([^"]+)"\z}i, 'wp-links-opml.php') do |match, node|
|
9
|
-
next unless WPScan::WpVersion.valid?(match[1])
|
10
|
-
|
11
|
-
return WPScan::WpVersion.new(
|
12
|
-
match[1],
|
13
|
-
found_by: 'OPML Generator (Aggressive Detection)',
|
14
|
-
confidence: 80,
|
15
|
-
interesting_entries: ["#{target.url('wp-links-opml.php')}, Match: '#{node.to_s.strip}'"]
|
16
|
-
)
|
17
|
-
end
|
18
|
-
nil
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module WpVersion
|
4
|
-
# Sitemap Generator Version Finder
|
5
|
-
class SitemapGenerator < CMSScanner::Finders::Finder
|
6
|
-
# @return [ WpVersion ]
|
7
|
-
def aggressive(_opts = {})
|
8
|
-
target.comments_from_page(%r{\Agenerator="wordpress/([^"]+)"\z}i, 'sitemap.xml') do |match, node|
|
9
|
-
next unless WPScan::WpVersion.valid?(match[1])
|
10
|
-
|
11
|
-
return WPScan::WpVersion.new(
|
12
|
-
match[1],
|
13
|
-
found_by: 'Sitemap Generator (Aggressive Detection)',
|
14
|
-
confidence: 80,
|
15
|
-
interesting_entries: ["#{target.url('sitemap.xml')}, #{node.to_s.strip}"]
|
16
|
-
)
|
17
|
-
end
|
18
|
-
nil
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module Finders
|
3
|
-
module WpVersion
|
4
|
-
# Stylesheets Version Finder from Upgrade page
|
5
|
-
class UpgradeStylesheetNumbers < InstallStylesheetNumbers
|
6
|
-
# @return [ Array<WpVersion> ]
|
7
|
-
def aggressive(_opts = {})
|
8
|
-
wp_versions(target.url('wp-admin/upgrade.php'))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module WPScan
|
2
|
-
module DB
|
3
|
-
# Dynamic Finders
|
4
|
-
class DynamicFinders
|
5
|
-
# @return [ String ]
|
6
|
-
def self.db_file
|
7
|
-
@db_file ||= File.join(DB_DIR, 'dynamic_finders_01.yml')
|
8
|
-
end
|
9
|
-
|
10
|
-
# @return [ Hash ]
|
11
|
-
def self.db_data
|
12
|
-
@db_data ||= YAML.safe_load(File.read(db_file), [Regexp])
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [ Hash ]
|
16
|
-
def self.finder_configs(finder_klass)
|
17
|
-
configs = {}
|
18
|
-
|
19
|
-
db_data.each do |slug, config|
|
20
|
-
next unless config[finder_klass]
|
21
|
-
|
22
|
-
configs[slug] = config[finder_klass].dup
|
23
|
-
end
|
24
|
-
|
25
|
-
configs
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Dynamic Plugin Finders
|
30
|
-
class DynamicPluginFinders < DynamicFinders
|
31
|
-
# @return [ Hash ]
|
32
|
-
def self.db_data
|
33
|
-
@db_data ||= super['plugins'] || {}
|
34
|
-
end
|
35
|
-
|
36
|
-
# @return [ Hash ]
|
37
|
-
def self.comments
|
38
|
-
@comments ||= finder_configs('Comments')
|
39
|
-
end
|
40
|
-
|
41
|
-
# @return [ Hash ]
|
42
|
-
def self.urls_in_page
|
43
|
-
@urls_in_page ||= finder_configs('UrlsInPage')
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Dynamic Theme Finders (none ATM)
|
48
|
-
class DynamicThemeFinders < DynamicFinders
|
49
|
-
# @return [ Hash ]
|
50
|
-
def self.db_data
|
51
|
-
@db_data ||= super['themes'] || {}
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|