miteru 2.1.1 → 2.2.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/lib/miteru/cache.rb +53 -0
- data/lib/miteru/config.rb +12 -0
- data/lib/miteru/crawler.rb +25 -9
- data/lib/miteru/orchestrator.rb +18 -4
- data/lib/miteru/version.rb +1 -1
- data/lib/miteru.rb +11 -2
- data/miteru.gemspec +51 -50
- metadata +19 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 62e5976eed670c3d2f2b0309e7723434c1e5c04ad337d4db519a58362618d566
|
|
4
|
+
data.tar.gz: fe54d9316505b380ac50ba9ab8cf520f2fd5b0e76cf88f0e520d7fb0c18a3b56
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 122f011baecb0a38639610ffaf68645c48f454ef7aa6ba79d5e812f71129f303a4386308cf639e233ff43473907f9567f90625b3651e027d18d6324e694ba00e
|
|
7
|
+
data.tar.gz: 0f21e5a5b6882fb9705d9988647de16aad44693ddfbbd9983a01f16c029923629322c40165a28dcb33e4a49482bcddbc1d272825beae7b0017400c560e16a57d
|
data/lib/miteru/cache.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require "redis"
|
|
2
|
+
|
|
3
|
+
module Miteru
|
|
4
|
+
class Cache < Service
|
|
5
|
+
# @return [String]
|
|
6
|
+
attr_reader :url
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# @param [String] url
|
|
10
|
+
#
|
|
11
|
+
def initialize(url)
|
|
12
|
+
super()
|
|
13
|
+
@url = url
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#
|
|
17
|
+
# @param [String] key
|
|
18
|
+
# @param [String] value
|
|
19
|
+
# @param [Integer. nil] ex
|
|
20
|
+
#
|
|
21
|
+
def set(key, value, ex:)
|
|
22
|
+
value = redis.set("#{prefix}:#{key}", value, ex:)
|
|
23
|
+
Miteru.logger.info("Cache:#{key} is set.") if verbose?
|
|
24
|
+
value
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
# @param [String] key
|
|
29
|
+
#
|
|
30
|
+
def cached?(key)
|
|
31
|
+
value = redis.exists?("#{prefix}:#{key}")
|
|
32
|
+
Miteru.logger.info("Cache:#{key} found.") if verbose?
|
|
33
|
+
value
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def verbose?
|
|
39
|
+
Miteru.config.verbose
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def prefix
|
|
43
|
+
Miteru.config.cache_prefix
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# @return [Redis]
|
|
48
|
+
#
|
|
49
|
+
def redis
|
|
50
|
+
@redis ||= Redis.new(url:)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
data/lib/miteru/config.rb
CHANGED
|
@@ -22,6 +22,9 @@ module Miteru
|
|
|
22
22
|
sentry_dsn: nil,
|
|
23
23
|
sentry_trace_sample_rate: 0.25,
|
|
24
24
|
sidekiq_redis_url: nil,
|
|
25
|
+
cache_redis_url: nil,
|
|
26
|
+
cache_ex: nil,
|
|
27
|
+
cache_prefix: "miteru:cache",
|
|
25
28
|
slack_channel: "#general",
|
|
26
29
|
slack_webhook_url: nil,
|
|
27
30
|
threads: Parallel.processor_count,
|
|
@@ -39,6 +42,15 @@ module Miteru
|
|
|
39
42
|
# @return [Float]
|
|
40
43
|
|
|
41
44
|
# @!attribute [r] sidekiq_redis_url
|
|
45
|
+
# @return [String, nil]
|
|
46
|
+
|
|
47
|
+
# @!attribute [r] cache_redis_url
|
|
48
|
+
# @return [String, nil]
|
|
49
|
+
|
|
50
|
+
# @!attribute [r] cache_ex
|
|
51
|
+
# @return [Integer, nil]
|
|
52
|
+
|
|
53
|
+
# @!attribute [r] cache_prefix
|
|
42
54
|
# @return [String]
|
|
43
55
|
|
|
44
56
|
# @!attribute [r] http_timeout
|
data/lib/miteru/crawler.rb
CHANGED
|
@@ -11,28 +11,44 @@ module Miteru
|
|
|
11
11
|
Try[OpenSSL::SSL::SSLError, ::HTTP::Error, Addressable::URI::InvalidURIError] do
|
|
12
12
|
info = "Website:#{website.info}."
|
|
13
13
|
info = info.colorize(:red) if website.kits?
|
|
14
|
-
|
|
15
14
|
Miteru.logger.info(info)
|
|
16
|
-
return unless website.kits?
|
|
17
|
-
|
|
18
|
-
notify website
|
|
19
|
-
|
|
20
|
-
return unless auto_download?
|
|
21
15
|
|
|
22
16
|
website.kits.each do |kit|
|
|
23
17
|
downloader = Downloader.new(kit)
|
|
24
18
|
result = downloader.result
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
else
|
|
19
|
+
|
|
20
|
+
unless result.success?
|
|
28
21
|
Miteru.logger.warn("Kit:#{kit.truncated_url} failed to download - #{result.failure}.")
|
|
22
|
+
next
|
|
29
23
|
end
|
|
24
|
+
|
|
25
|
+
destination = result.value!
|
|
26
|
+
Miteru.logger.info("Kit:#{kit.truncated_url} downloaded as #{destination}.")
|
|
27
|
+
# Remove downloaded file if auto_download is not allowed
|
|
28
|
+
FileUtils.rm(destination, force: true) unless auto_download?
|
|
29
|
+
# Notify the website
|
|
30
|
+
notify website
|
|
30
31
|
end
|
|
32
|
+
|
|
33
|
+
# Cache the website
|
|
34
|
+
cache.set(website.url, website.source, ex: cache_ex) if cache?
|
|
31
35
|
end.recover { nil }.value!
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
private
|
|
35
39
|
|
|
40
|
+
def cache?
|
|
41
|
+
Miteru.cache?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def cache
|
|
45
|
+
Miteru.cache
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def cache_ex
|
|
49
|
+
Miteru.config.cache_ex
|
|
50
|
+
end
|
|
51
|
+
|
|
36
52
|
def auto_download?
|
|
37
53
|
Miteru.config.auto_download
|
|
38
54
|
end
|
data/lib/miteru/orchestrator.rb
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
module Miteru
|
|
4
4
|
class Orchestrator < Service
|
|
5
5
|
def call
|
|
6
|
-
Miteru.logger.info("#{
|
|
6
|
+
Miteru.logger.info("#{non_cached_websites.length} websites loaded in total.") if verbose?
|
|
7
7
|
|
|
8
8
|
if Miteru.sidekiq?
|
|
9
|
-
|
|
9
|
+
non_cached_websites.each do |website|
|
|
10
10
|
Jobs::CrawleJob.perform_async(website.url, website.source)
|
|
11
11
|
Miteru.logger.info("Website:#{website.truncated_url} crawler job queued.") if verbose?
|
|
12
12
|
end
|
|
13
13
|
else
|
|
14
14
|
Miteru.logger.info("Use #{threads} thread(s).") if verbose?
|
|
15
|
-
Parallel.each(
|
|
15
|
+
Parallel.each(non_cached_websites, in_threads: threads) do |website|
|
|
16
16
|
Miteru.logger.info("Website:#{website.truncated_url} crawling started.") if verbose?
|
|
17
17
|
|
|
18
18
|
result = Crawler.result(website)
|
|
@@ -26,7 +26,7 @@ module Miteru
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
#
|
|
29
|
-
# @return [Array<Miteru::
|
|
29
|
+
# @return [Array<Miteru::Website>]
|
|
30
30
|
#
|
|
31
31
|
def websites
|
|
32
32
|
@websites ||= [].tap do |out|
|
|
@@ -43,6 +43,12 @@ module Miteru
|
|
|
43
43
|
end.flatten.uniq(&:url)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
def non_cached_websites
|
|
47
|
+
return websites unless cache?
|
|
48
|
+
|
|
49
|
+
websites.reject { |website| cache.cached?(website.url) }
|
|
50
|
+
end
|
|
51
|
+
|
|
46
52
|
#
|
|
47
53
|
# @return [Array<Miteru::Feeds::Base>]
|
|
48
54
|
#
|
|
@@ -52,6 +58,14 @@ module Miteru
|
|
|
52
58
|
|
|
53
59
|
private
|
|
54
60
|
|
|
61
|
+
def cache?
|
|
62
|
+
Miteru.cache?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def cache
|
|
66
|
+
Miteru.cache
|
|
67
|
+
end
|
|
68
|
+
|
|
55
69
|
def threads
|
|
56
70
|
Miteru.config.threads
|
|
57
71
|
end
|
data/lib/miteru/version.rb
CHANGED
data/lib/miteru.rb
CHANGED
|
@@ -33,6 +33,9 @@ require "miteru/concerns/database_connectable"
|
|
|
33
33
|
require "miteru/concerns/error_unwrappable"
|
|
34
34
|
|
|
35
35
|
# Core classes
|
|
36
|
+
require "miteru/service"
|
|
37
|
+
|
|
38
|
+
require "miteru/cache"
|
|
36
39
|
require "miteru/config"
|
|
37
40
|
require "miteru/http"
|
|
38
41
|
|
|
@@ -93,6 +96,14 @@ module Miteru
|
|
|
93
96
|
env == "development"
|
|
94
97
|
end
|
|
95
98
|
|
|
99
|
+
def cache?
|
|
100
|
+
!Miteru.config.cache_redis_url.nil?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def cache
|
|
104
|
+
@cache ||= Cache.new(Miteru.config.cache_redis_url)
|
|
105
|
+
end
|
|
106
|
+
|
|
96
107
|
#
|
|
97
108
|
# @return [Boolean]
|
|
98
109
|
#
|
|
@@ -117,8 +128,6 @@ module Miteru
|
|
|
117
128
|
end
|
|
118
129
|
|
|
119
130
|
# Services
|
|
120
|
-
require "miteru/service"
|
|
121
|
-
|
|
122
131
|
require "miteru/crawler"
|
|
123
132
|
require "miteru/downloader"
|
|
124
133
|
require "miteru/kit"
|
data/miteru.gemspec
CHANGED
|
@@ -1,67 +1,68 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
lib = File.expand_path(
|
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
-
require
|
|
5
|
+
require "miteru/version"
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |spec|
|
|
8
|
-
spec.name =
|
|
8
|
+
spec.name = "miteru"
|
|
9
9
|
spec.version = Miteru::VERSION
|
|
10
|
-
spec.authors = [
|
|
11
|
-
spec.email = [
|
|
12
|
-
spec.metadata[
|
|
10
|
+
spec.authors = ["Manabu Niseki"]
|
|
11
|
+
spec.email = ["manabu.niseki@gmail.com"]
|
|
12
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
13
13
|
|
|
14
|
-
spec.summary =
|
|
15
|
-
spec.description =
|
|
16
|
-
spec.homepage =
|
|
17
|
-
spec.license =
|
|
14
|
+
spec.summary = "A phishing kit collector for scavengers"
|
|
15
|
+
spec.description = "A phishing kit collector for scavengers"
|
|
16
|
+
spec.homepage = "https://github.com/ninoseki/miteru"
|
|
17
|
+
spec.license = "MIT"
|
|
18
18
|
|
|
19
19
|
# Specify which files should be added to the gem when it is released.
|
|
20
20
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
21
21
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
22
22
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
23
23
|
end
|
|
24
|
-
spec.bindir =
|
|
24
|
+
spec.bindir = "exe"
|
|
25
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
26
|
-
spec.require_paths = [
|
|
26
|
+
spec.require_paths = ["lib"]
|
|
27
27
|
|
|
28
|
-
spec.add_development_dependency
|
|
29
|
-
spec.add_development_dependency
|
|
30
|
-
spec.add_development_dependency
|
|
31
|
-
spec.add_development_dependency
|
|
32
|
-
spec.add_development_dependency
|
|
33
|
-
spec.add_development_dependency
|
|
34
|
-
spec.add_development_dependency
|
|
35
|
-
spec.add_development_dependency
|
|
36
|
-
spec.add_development_dependency
|
|
37
|
-
spec.add_development_dependency
|
|
38
|
-
spec.add_development_dependency
|
|
39
|
-
spec.add_development_dependency
|
|
40
|
-
spec.add_development_dependency
|
|
28
|
+
spec.add_development_dependency "bundler", "~> 2.5"
|
|
29
|
+
spec.add_development_dependency "capybara", "~> 3.40"
|
|
30
|
+
spec.add_development_dependency "coveralls_reborn", "~> 0.28"
|
|
31
|
+
spec.add_development_dependency "fuubar", "~> 2.5"
|
|
32
|
+
spec.add_development_dependency "mysql2", "~> 0.5"
|
|
33
|
+
spec.add_development_dependency "pg", "~> 1.5"
|
|
34
|
+
spec.add_development_dependency "rake", "~> 13.1"
|
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.13"
|
|
36
|
+
spec.add_development_dependency "simplecov-lcov", "~> 0.8"
|
|
37
|
+
spec.add_development_dependency "standard", "~> 1.33"
|
|
38
|
+
spec.add_development_dependency "test-prof", "~> 1.3"
|
|
39
|
+
spec.add_development_dependency "vcr", "~> 6.2"
|
|
40
|
+
spec.add_development_dependency "webmock", "~> 3.19"
|
|
41
41
|
|
|
42
|
-
spec.add_dependency
|
|
43
|
-
spec.add_dependency
|
|
44
|
-
spec.add_dependency
|
|
45
|
-
spec.add_dependency
|
|
46
|
-
spec.add_dependency
|
|
47
|
-
spec.add_dependency
|
|
48
|
-
spec.add_dependency
|
|
49
|
-
spec.add_dependency
|
|
50
|
-
spec.add_dependency
|
|
51
|
-
spec.add_dependency
|
|
52
|
-
spec.add_dependency
|
|
53
|
-
spec.add_dependency
|
|
54
|
-
spec.add_dependency
|
|
55
|
-
spec.add_dependency
|
|
56
|
-
spec.add_dependency
|
|
57
|
-
spec.add_dependency
|
|
58
|
-
spec.add_dependency
|
|
59
|
-
spec.add_dependency
|
|
60
|
-
spec.add_dependency
|
|
61
|
-
spec.add_dependency
|
|
62
|
-
spec.add_dependency
|
|
63
|
-
spec.add_dependency
|
|
64
|
-
spec.add_dependency
|
|
65
|
-
spec.add_dependency
|
|
66
|
-
spec.add_dependency
|
|
42
|
+
spec.add_dependency "activerecord", "7.1.3"
|
|
43
|
+
spec.add_dependency "addressable", "2.8.6"
|
|
44
|
+
spec.add_dependency "anyway_config", "2.6.3"
|
|
45
|
+
spec.add_dependency "colorize", "1.1.0"
|
|
46
|
+
spec.add_dependency "dotenv", "2.8.1"
|
|
47
|
+
spec.add_dependency "down", "5.4.1"
|
|
48
|
+
spec.add_dependency "dry-files", "1.1.0"
|
|
49
|
+
spec.add_dependency "dry-monads", "1.6.0"
|
|
50
|
+
spec.add_dependency "http", "5.2.0"
|
|
51
|
+
spec.add_dependency "memo_wise", "1.8.0"
|
|
52
|
+
spec.add_dependency "oga", "3.4"
|
|
53
|
+
spec.add_dependency "parallel", "1.24.0"
|
|
54
|
+
spec.add_dependency "puma", "6.4.2"
|
|
55
|
+
spec.add_dependency "rack", "3.0.9"
|
|
56
|
+
spec.add_dependency "rack-session", "2.0.0"
|
|
57
|
+
spec.add_dependency "rackup", "2.1.0"
|
|
58
|
+
spec.add_dependency "redis", "5.0.8"
|
|
59
|
+
spec.add_dependency "semantic_logger", "4.15.0"
|
|
60
|
+
spec.add_dependency "sentry-ruby", "5.16.1"
|
|
61
|
+
spec.add_dependency "sentry-sidekiq", "5.16.1"
|
|
62
|
+
spec.add_dependency "sidekiq", "7.2.1"
|
|
63
|
+
spec.add_dependency "slack-notifier", "2.4.0"
|
|
64
|
+
spec.add_dependency "sqlite3", "1.7.2"
|
|
65
|
+
spec.add_dependency "thor", "1.3.0"
|
|
66
|
+
spec.add_dependency "thor-hollaback", "0.2.1"
|
|
67
|
+
spec.add_dependency "uuidtools", "2.2.0"
|
|
67
68
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: miteru
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Manabu Niseki
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-02-
|
|
11
|
+
date: 2024-02-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -226,14 +226,14 @@ dependencies:
|
|
|
226
226
|
requirements:
|
|
227
227
|
- - '='
|
|
228
228
|
- !ruby/object:Gem::Version
|
|
229
|
-
version: 2.6.
|
|
229
|
+
version: 2.6.3
|
|
230
230
|
type: :runtime
|
|
231
231
|
prerelease: false
|
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
|
233
233
|
requirements:
|
|
234
234
|
- - '='
|
|
235
235
|
- !ruby/object:Gem::Version
|
|
236
|
-
version: 2.6.
|
|
236
|
+
version: 2.6.3
|
|
237
237
|
- !ruby/object:Gem::Dependency
|
|
238
238
|
name: colorize
|
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -416,6 +416,20 @@ dependencies:
|
|
|
416
416
|
- - '='
|
|
417
417
|
- !ruby/object:Gem::Version
|
|
418
418
|
version: 2.1.0
|
|
419
|
+
- !ruby/object:Gem::Dependency
|
|
420
|
+
name: redis
|
|
421
|
+
requirement: !ruby/object:Gem::Requirement
|
|
422
|
+
requirements:
|
|
423
|
+
- - '='
|
|
424
|
+
- !ruby/object:Gem::Version
|
|
425
|
+
version: 5.0.8
|
|
426
|
+
type: :runtime
|
|
427
|
+
prerelease: false
|
|
428
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
429
|
+
requirements:
|
|
430
|
+
- - '='
|
|
431
|
+
- !ruby/object:Gem::Version
|
|
432
|
+
version: 5.0.8
|
|
419
433
|
- !ruby/object:Gem::Dependency
|
|
420
434
|
name: semantic_logger
|
|
421
435
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -566,6 +580,7 @@ files:
|
|
|
566
580
|
- exe/miteru
|
|
567
581
|
- lefthook.yml
|
|
568
582
|
- lib/miteru.rb
|
|
583
|
+
- lib/miteru/cache.rb
|
|
569
584
|
- lib/miteru/cli/application.rb
|
|
570
585
|
- lib/miteru/cli/base.rb
|
|
571
586
|
- lib/miteru/cli/database.rb
|