wpscan 3.0.8 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|