miteru 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 509957b241020f76fcd9c85a6acbb9e80c0f8b3224fe5c1b4af41dcd2faa6ca5
4
- data.tar.gz: 4e507a9974264a9b98d1ded16c09496a06ed4ca83409f75fc49719c37f934f77
3
+ metadata.gz: 62e5976eed670c3d2f2b0309e7723434c1e5c04ad337d4db519a58362618d566
4
+ data.tar.gz: fe54d9316505b380ac50ba9ab8cf520f2fd5b0e76cf88f0e520d7fb0c18a3b56
5
5
  SHA512:
6
- metadata.gz: 3dc8e2b4569555f5551a1b7fd2407162949cc7a459a5a7f83c5a787206b5cf39b34f16235466b6bcd74f34bac1878e1e4df6797daebe407eda2c03a9e7379e3a
7
- data.tar.gz: 69d83a4c964ebbcd87b416675ed03bc18e270c0d604a19ef98b8988a0f344388eb49d0fb290edaa2f8637fa5f100608a3e9a76a1571503bda529611aea332bc0
6
+ metadata.gz: 122f011baecb0a38639610ffaf68645c48f454ef7aa6ba79d5e812f71129f303a4386308cf639e233ff43473907f9567f90625b3651e027d18d6324e694ba00e
7
+ data.tar.gz: 0f21e5a5b6882fb9705d9988647de16aad44693ddfbbd9983a01f16c029923629322c40165a28dcb33e4a49482bcddbc1d272825beae7b0017400c560e16a57d
@@ -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
@@ -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
- if result.success?
26
- Miteru.logger.info("Kit:#{kit.truncated_url} downloaded as #{result.value!}.")
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
@@ -3,16 +3,16 @@
3
3
  module Miteru
4
4
  class Orchestrator < Service
5
5
  def call
6
- Miteru.logger.info("#{websites.length} websites loaded in total.") if verbose?
6
+ Miteru.logger.info("#{non_cached_websites.length} websites loaded in total.") if verbose?
7
7
 
8
8
  if Miteru.sidekiq?
9
- websites.each do |website|
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(websites, in_threads: threads) do |website|
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::Websites>]
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Miteru
4
- VERSION = "2.1.1"
4
+ VERSION = "2.2.0"
5
5
  end
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('lib', __dir__)
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'miteru/version'
5
+ require "miteru/version"
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = 'miteru'
8
+ spec.name = "miteru"
9
9
  spec.version = Miteru::VERSION
10
- spec.authors = ['Manabu Niseki']
11
- spec.email = ['manabu.niseki@gmail.com']
12
- spec.metadata['rubygems_mfa_required'] = 'true'
10
+ spec.authors = ["Manabu Niseki"]
11
+ spec.email = ["manabu.niseki@gmail.com"]
12
+ spec.metadata["rubygems_mfa_required"] = "true"
13
13
 
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'
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 = 'exe'
24
+ spec.bindir = "exe"
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
- spec.require_paths = ['lib']
26
+ spec.require_paths = ["lib"]
27
27
 
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'
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 'activerecord', '7.1.3'
43
- spec.add_dependency 'addressable', '2.8.6'
44
- spec.add_dependency 'anyway_config', '2.6.2'
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 'semantic_logger', '4.15.0'
59
- spec.add_dependency 'sentry-ruby', '5.16.1'
60
- spec.add_dependency 'sentry-sidekiq', '5.16.1'
61
- spec.add_dependency 'sidekiq', '7.2.1'
62
- spec.add_dependency 'slack-notifier', '2.4.0'
63
- spec.add_dependency 'sqlite3', '1.7.2'
64
- spec.add_dependency 'thor', '1.3.0'
65
- spec.add_dependency 'thor-hollaback', '0.2.1'
66
- spec.add_dependency 'uuidtools', '2.2.0'
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.1.1
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-07 00:00:00.000000000 Z
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.2
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.2
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