euax_gems_validator 1.0.0.beta

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: be1d4e909fe11107bb534a59ac2b4b7abc304d1c3d023781f89d1e9bfc6f3e09
4
+ data.tar.gz: cde3ec65c292ca2236f0f288e668014053d575a687d59ebf46ab14f279c6f93d
5
+ SHA512:
6
+ metadata.gz: 8da6269f85753c5b5c69c62b70897603eee2421203df42d23cf446a7e8164c9107adbb373fa9dfd6457d68fe01b37899f33507a4bc67ff1c97aabf6511f66f41
7
+ data.tar.gz: 6dc0add79e2228f541fa400887ce6dd6e047bc9c409d37bee8d38b5e6c6ce7903dc2e2198c9d9ba593a313d0bce618d5a171ba545462a29d2742ea9df155aec8
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Dockerfile ADDED
@@ -0,0 +1,7 @@
1
+ FROM ruby:2.3.8
2
+
3
+ WORKDIR /app
4
+
5
+ COPY . .
6
+
7
+ RUN bundle install
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in gems-validator.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+ gem "bundler-audit"
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gems-validator (0.7.4)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ bundler-audit (0.9.1)
10
+ bundler (>= 1.2.0, < 3)
11
+ thor (~> 1.0)
12
+ rake (13.0.6)
13
+ thor (1.2.1)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ bundler-audit
20
+ gems-validator!
21
+ rake (~> 13.0)
22
+
23
+ BUNDLED WITH
24
+ 1.17.3
data/Makefile ADDED
@@ -0,0 +1,2 @@
1
+ bash:
2
+ sudo docker exec -it gems-validator_app_1 /bin/bash
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Gems validator
2
+
3
+ Um plugin Bundle para validar gems homologadas nas aplicações do grupo EUAX.
4
+
5
+ ## 📦 **Instalação**
6
+
7
+ Execute `bundle plugin install euax_gems_validator` para adicionar o plugin ao seu bundle.
8
+
9
+ ## 🤷‍♂️ **Como funciona?**
10
+
11
+ Após instalar o plugin ele irá rodar toda vez que `bundle install` for executado. O plugin utiliza da [API de bibliotecas homologadas](https://github.com/Artia/euax-homologated-libraries)
12
+ para validar as gems de um produto, verificando se elas podem ou não serem instaladas. Ao detectar que uma gem não pode ser instalada o processo de instalação
13
+ é interrompido e uma mensagem de erro com o motivo da falha é apresentada no terminal.
14
+
15
+ ## 🤝 **Contribuindo**
16
+
17
+ Todo tipo de contribuição é muito bem vinda e apreciada!
18
+
19
+ - ⭐️ Dê uma estrela ao projeto
20
+ - 🐛 Encontre e reporte issues
21
+ - 📥 Envie PRs e ajude a resolver issues e adição de features
22
+
23
+ ---
24
+
25
+ Feito com ❤️ por **Henrique Schmeller**.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,9 @@
1
+ version: "3"
2
+ services:
3
+ app:
4
+ build:
5
+ context: .
6
+ dockerfile: Dockerfile
7
+ volumes:
8
+ - .:/app
9
+ tty: true
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemsValidator
4
+ class AuditService
5
+ def initialize()
6
+ @audit_response = %x[bundle audit check --format json]
7
+ parse_response()
8
+
9
+ @audit_data = {}
10
+ generate_data()
11
+ end
12
+
13
+ def is_a_vulnerable_gem?(gem)
14
+ name = gem.name
15
+ version = gem.version.to_s
16
+ unless @audit_data[name].nil?
17
+ generate_messages(name, version)
18
+ end
19
+ end
20
+
21
+ private
22
+ def get_translate_criticality(criticality)
23
+ translate_default_criticalities = { "critical" => "crítica", "high" => "alta", "medium" => "média", "low" => "baixa" }
24
+ translate_default_criticalities[criticality] || 'não definido'
25
+ end
26
+
27
+ def generate_messages(name, version)
28
+ GemsValidator::OutputMessage.warn("A gem #{name} na versão #{version} apresenta #{@audit_data[name]["vulnerabilities"].size} vulnerabilidade#{@audit_data[name]["vulnerabilities"].size > 1 ? "s" : ""}")
29
+ @audit_data[name]["vulnerabilities"].map.with_index do |vulnerability, number|
30
+ GemsValidator::OutputMessage.warn("* Título: #{vulnerability[:title]} \n Nível: #{get_translate_criticality(vulnerability[:level])} \n URL: #{vulnerability[:url]}")
31
+ end
32
+ end
33
+
34
+ def generate_data()
35
+
36
+ @audit_response["results"]&.map do |audit_item|
37
+ gem_name = audit_item["gem"]["name"]
38
+ if (@audit_data[gem_name])
39
+ @audit_data[gem_name]["vulnerabilities"].push({"title": audit_item["advisory"]["title"], "level": audit_item["advisory"]["criticality"], "url": audit_item["advisory"]["url"]})
40
+ else
41
+ @audit_data[gem_name] = {
42
+ "vulnerabilities" => [
43
+ {
44
+ "title": audit_item["advisory"]["title"],
45
+ "level": audit_item["advisory"]["criticality"],
46
+ "url": audit_item["advisory"]["url"]
47
+ }
48
+ ]
49
+ }
50
+ end
51
+ end
52
+ end
53
+
54
+ def parse_response()
55
+ begin
56
+ @audit_response = JSON.parse(@audit_response)
57
+ rescue => exception
58
+ GemsValidator::OutputMessage.error("Erro ao gerar dados de pacotes vulneráveis.")
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemsValidator
4
+ API_BASE_URL = "https://c1cc-2804-14c-f288-9d8e-6f0c-1c9a-fd64-a09b.sa.ngrok.io"
5
+ class GemsService
6
+ def initialize()
7
+ @pwd = Dir.pwd
8
+ end
9
+
10
+ # Response:
11
+ # {
12
+ # allowed_gems: {
13
+ # [name]: {
14
+ # approved_at: Date,
15
+ # version?: String
16
+ # }
17
+ # },
18
+ # blocked_gems: {
19
+ # [name]: {
20
+ # blocked_at: Date,
21
+ # version?: String
22
+ # }
23
+ # },
24
+ # pending_gems: {
25
+ # [name]: {
26
+ # requested_at: Date
27
+ # }
28
+ # }
29
+ # }
30
+ def get_gems()
31
+ gems_formatted_request
32
+ end
33
+
34
+ private
35
+ def get_token
36
+ uri = URI("#{GemsValidator::API_BASE_URL}/sessions/token")
37
+ request = Net::HTTP::Post.new(uri)
38
+ request.body = { username: 'viewer', password: 'viewer@euax' }.to_json
39
+ request['Content-Type'] = 'application/json'
40
+
41
+ Net::HTTP.start(uri.host, uri.port) do |http|
42
+ response = http.request request
43
+ response.header['access_token']
44
+ end
45
+ end
46
+
47
+ def gems_formatted_request
48
+ uri = URI("#{GemsValidator::API_BASE_URL}/gems/formatted")
49
+ begin
50
+ access_token = get_token
51
+
52
+ Net::HTTP.start(uri.host, uri.port) do |http|
53
+ request = Net::HTTP::Get.new uri
54
+ request["Authorization"] = access_token
55
+ response = http.request request
56
+ parse_body = JSON.parse(response.body)["data"]
57
+ generate_file("#{@pwd}/.euax-homologated-libraries", parse_body.to_json)
58
+ parse_body
59
+ end
60
+ rescue
61
+ puts " "
62
+ GemsValidator::OutputMessage.warn("A API das bibliotecas homologadas esta fora do ar. Para prosseguir, nesse momento os dados serão coletados do cache.")
63
+ puts " "
64
+ sleep(3)
65
+ begin
66
+ JSON.parse(File.read("#{@pwd}/.euax-homologated-libraries/gems-response.json"))
67
+ rescue
68
+ { "allowed_gems" => {}, "blocked_gems" => {}, "pending_gems" => {} }
69
+ end
70
+ end
71
+ end
72
+
73
+ def generate_file(base_url, data)
74
+ Dir.mkdir(base_url) unless File.exists?(base_url)
75
+ File.write("#{base_url}/gems-response.json", data)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemsValidator
4
+ class OutputMessage
5
+ def self.error(message)
6
+ Bundler::GemspecError.new("[GemsValidator::Error] - #{message}")
7
+ end
8
+
9
+ def self.warn(message)
10
+ Bundler.ui.warn("[GemsValidator::Warning] - #{message}")
11
+ end
12
+
13
+ def self.success(message)
14
+ Bundler.ui.confirm("[GemsValidator::Success] - #{message}")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemsValidator
4
+ module Validate
5
+ class << self
6
+ def exec(gem)
7
+ @gem = gem
8
+ begin
9
+ is_blocked?
10
+ is_pending?
11
+ is_allowed?
12
+ GemsValidator::OutputMessage.success("A gem #{@gem.name} está homologada e pode ser instalada!")
13
+ rescue => error
14
+ raise GemsValidator::OutputMessage.error("Não foi possível instalar a gem #{@gem.name}. Motivo: #{error.to_s}")
15
+ end
16
+ end
17
+
18
+ private
19
+ def is_blocked?
20
+ if gems_from_service["blocked_gems"].keys.include?(@gem.name)
21
+ is_version_blocked?
22
+ raise "Essa gem foi bloqueada."
23
+ end
24
+ end
25
+
26
+ def is_version_blocked?
27
+ if gems_from_service["blocked_gems"][@gem.name]["version"]
28
+ blocked_version = gems_from_service["blocked_gems"][@gem.name]["version"]
29
+ if @gem.version.to_s == blocked_version
30
+ raise "A versão #{blocked_version} foi bloqueada."
31
+ end
32
+ end
33
+ end
34
+
35
+ def is_pending?
36
+ if gems_from_service["pending_gems"].keys.include?(@gem.name)
37
+ raise "Essa gem está aguardando aprovação."
38
+ end
39
+ end
40
+
41
+ def is_allowed?
42
+ if gems_from_service["allowed_gems"].keys.include?(@gem.name)
43
+ is_version_allowed?
44
+ is_deprecated?
45
+ else
46
+ raise "Essa gem não foi homologada."
47
+ end
48
+ end
49
+
50
+ def is_version_allowed?
51
+ if gems_from_service["allowed_gems"][@gem.name]["version"]
52
+ required_version = gems_from_service["allowed_gems"][@gem.name]["version"]
53
+ if @gem.version.to_s != required_version
54
+ raise "Essa gem só pode ser instalada na versão #{required_version}."
55
+ end
56
+ end
57
+ end
58
+
59
+ def is_deprecated?
60
+ if gems_from_service["allowed_gems"][@gem.name]["deprecated"]
61
+ message = gems_from_service["allowed_gems"][@gem.name]["deprecated_message"]
62
+ GemsValidator::OutputMessage.warn("A gem #{@gem.name} está depreciada. Motivo: #{message}")
63
+ end
64
+ end
65
+
66
+ def gems_service
67
+ @gems_service ||= GemsValidator::GemsService.new()
68
+ end
69
+
70
+ def gems_from_service
71
+ @gems_from_service ||= gems_service.get_gems()
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemsValidator
4
+ VERSION = "1.0.0.beta"
5
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler'
4
+ require 'net/http'
5
+ require 'uri'
6
+ require 'json'
7
+
8
+ require_relative "euax_gems_validator/audit-service"
9
+ require_relative "euax_gems_validator/output-message"
10
+ require_relative "euax_gems_validator/gems-service"
11
+ require_relative "euax_gems_validator/validate"
12
+ require_relative "euax_gems_validator/version"
13
+
14
+ module GemsValidator
15
+ class << self
16
+ def register
17
+ return if defined?(@registered) && @registered
18
+ @registered = true
19
+
20
+ auditService = GemsValidator::AuditService.new
21
+
22
+ Bundler::Plugin.add_hook('before-install') do |gem|
23
+ GemsValidator::Validate.exec(gem.spec)
24
+ auditService.is_a_vulnerable_gem?(gem.spec)
25
+ end
26
+ end
27
+ end
28
+ end
data/plugins.rb ADDED
@@ -0,0 +1,2 @@
1
+ require_relative "lib/euax_gems_validator"
2
+ GemsValidator.register
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: euax_gems_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.beta
5
+ platform: ruby
6
+ authors:
7
+ - henriquesml
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-11-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: euax_gems_validator
14
+ email:
15
+ - henrique_schmeller@hotmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - Dockerfile
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - Makefile
25
+ - README.md
26
+ - Rakefile
27
+ - docker-compose.yml
28
+ - lib/euax_gems_validator.rb
29
+ - lib/euax_gems_validator/audit-service.rb
30
+ - lib/euax_gems_validator/gems-service.rb
31
+ - lib/euax_gems_validator/output-message.rb
32
+ - lib/euax_gems_validator/validate.rb
33
+ - lib/euax_gems_validator/version.rb
34
+ - plugins.rb
35
+ homepage:
36
+ licenses: []
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.3.8
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">"
50
+ - !ruby/object:Gem::Version
51
+ version: 1.3.1
52
+ requirements: []
53
+ rubygems_version: 3.0.3
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: euax_gems_validator
57
+ test_files: []