bnvd_client 1.0.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 +7 -0
- data/README.md +125 -0
- data/lib/bnvd_client.rb +263 -0
- metadata +88 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b028965b9d29e0565fbce0895a43c80e043d0a8ba5c4e4d0333d1982190e7482
|
|
4
|
+
data.tar.gz: cbed124aef817b2b440a10c1f3a63e782dac06a3387522c39d9758dc1e288d2a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f7434ce1a4621a9630676751a7d6e0250f1e29f2128403d2459ebfc8c42dd96a709dd0090912d539db51bea20d733f1d992d95c1f243b619a6d704f101f4cede
|
|
7
|
+
data.tar.gz: 723baf902b93182b943d6e6f56eb90d5f63093c5f07a7669ea8d9049f5398da09cd3566a536e80535b577618dfbee7eec18267c53f1d7739d22bee194cb70c37
|
data/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# BNVD API Client - Ruby
|
|
2
|
+
|
|
3
|
+
Cliente oficial em Ruby para a API do Banco Nacional de Vulnerabilidades Cibernéticas (BNVD).
|
|
4
|
+
|
|
5
|
+
## Instalação
|
|
6
|
+
|
|
7
|
+
Adicione ao seu Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'bnvd_client'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Ou instale diretamente:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gem install bnvd_client
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Uso
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
require 'bnvd_client'
|
|
23
|
+
|
|
24
|
+
# Configurar cliente (URL padrão: https://bnvd.org/api/v1)
|
|
25
|
+
client = BNVD::Client.new(BNVD::Config.new)
|
|
26
|
+
|
|
27
|
+
# Ou com configuração customizada
|
|
28
|
+
# config = BNVD::Config.new(
|
|
29
|
+
# base_url: 'https://bnvd.org/api/v1',
|
|
30
|
+
# timeout: 30
|
|
31
|
+
# )
|
|
32
|
+
# client = BNVD::Client.new(config)
|
|
33
|
+
|
|
34
|
+
# Listar vulnerabilidades
|
|
35
|
+
result = client.list_vulnerabilities(
|
|
36
|
+
BNVD::SearchParams.new(
|
|
37
|
+
page: 1,
|
|
38
|
+
per_page: 20,
|
|
39
|
+
include_pt: true
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if result.success?
|
|
44
|
+
puts "Total: #{result.pagination['total']}"
|
|
45
|
+
result.data.each do |vuln|
|
|
46
|
+
puts vuln['cve']['id']
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Buscar vulnerabilidade específica
|
|
51
|
+
vuln = client.get_vulnerability('CVE-2024-12345')
|
|
52
|
+
|
|
53
|
+
# Buscar por ano
|
|
54
|
+
vulns_2024 = client.search_by_year(2024)
|
|
55
|
+
|
|
56
|
+
# Buscar por severidade
|
|
57
|
+
critical = client.search_by_severity(BNVD::Severity::CRITICAL)
|
|
58
|
+
|
|
59
|
+
# Buscar vulnerabilidades recentes
|
|
60
|
+
recent = client.get_recent_vulnerabilities(
|
|
61
|
+
BNVD::RecentSearchParams.new(days: 7)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Obter estatísticas
|
|
65
|
+
stats = client.get_stats
|
|
66
|
+
puts "Total de vulnerabilidades: #{stats.data['total_vulnerabilities']}"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Métodos Disponíveis
|
|
70
|
+
|
|
71
|
+
### Informações da API
|
|
72
|
+
- `get_api_info()` - Retorna informações sobre a API
|
|
73
|
+
|
|
74
|
+
### Vulnerabilidades
|
|
75
|
+
- `list_vulnerabilities(params)` - Lista todas as vulnerabilidades
|
|
76
|
+
- `get_vulnerability(cve_id, include_pt)` - Busca vulnerabilidade específica
|
|
77
|
+
- `get_recent_vulnerabilities(params)` - Vulnerabilidades recentes
|
|
78
|
+
- `get_top5_recent(include_pt)` - Top 5 mais recentes
|
|
79
|
+
- `search_by_year(year, params)` - Busca por ano
|
|
80
|
+
- `search_by_severity(severity, params)` - Busca por severidade
|
|
81
|
+
- `search_by_vendor(vendor, params)` - Busca por fabricante
|
|
82
|
+
|
|
83
|
+
### Estatísticas
|
|
84
|
+
- `get_stats()` - Estatísticas gerais
|
|
85
|
+
- `get_year_stats()` - Estatísticas por ano
|
|
86
|
+
|
|
87
|
+
### Notícias
|
|
88
|
+
- `list_noticias(params)` - Lista todas as notícias
|
|
89
|
+
- `get_recent_noticias(limit)` - Notícias recentes
|
|
90
|
+
- `get_noticia_by_slug(slug)` - Busca notícia por slug
|
|
91
|
+
|
|
92
|
+
### MITRE ATT&CK
|
|
93
|
+
- `get_mitre_info()` - Informações sobre o sistema MITRE
|
|
94
|
+
- `list_mitre_matrices()` - Lista matrizes disponíveis
|
|
95
|
+
- `get_mitre_matrix(name, include_pt)` - Retorna matriz específica
|
|
96
|
+
- `list_mitre_techniques(params)` - Lista técnicas
|
|
97
|
+
- `get_mitre_technique(id, include_pt)` - Detalhes de técnica
|
|
98
|
+
- `list_mitre_subtechniques(params)` - Lista subtécnicas
|
|
99
|
+
- `list_mitre_groups(params)` - Lista grupos de ameaças
|
|
100
|
+
- `get_mitre_group(id, include_pt)` - Detalhes de grupo
|
|
101
|
+
- `list_mitre_mitigations(params)` - Lista mitigações
|
|
102
|
+
- `get_mitre_mitigation(id, include_pt)` - Detalhes de mitigação
|
|
103
|
+
|
|
104
|
+
## Níveis de Severidade
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
BNVD::Severity::LOW # Baixa
|
|
108
|
+
BNVD::Severity::MEDIUM # Média
|
|
109
|
+
BNVD::Severity::HIGH # Alta
|
|
110
|
+
BNVD::Severity::CRITICAL # Crítica
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Tratamento de Erros
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
begin
|
|
117
|
+
result = client.get_vulnerability('CVE-INVALID')
|
|
118
|
+
rescue => e
|
|
119
|
+
puts "Erro: #{e.message}"
|
|
120
|
+
end
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Licença
|
|
124
|
+
|
|
125
|
+
MIT
|
data/lib/bnvd_client.rb
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# BNVD API Client - Ruby
|
|
4
|
+
# Cliente oficial para a API do Banco Nacional de Vulnerabilidades Cibernéticas
|
|
5
|
+
# @version 1.0.0
|
|
6
|
+
|
|
7
|
+
require 'net/http'
|
|
8
|
+
require 'json'
|
|
9
|
+
require 'uri'
|
|
10
|
+
|
|
11
|
+
module BNVD
|
|
12
|
+
# Níveis de severidade CVSS
|
|
13
|
+
module Severity
|
|
14
|
+
LOW = 'LOW'
|
|
15
|
+
MEDIUM = 'MEDIUM'
|
|
16
|
+
HIGH = 'HIGH'
|
|
17
|
+
CRITICAL = 'CRITICAL'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Configuração do cliente
|
|
21
|
+
class Config
|
|
22
|
+
attr_accessor :base_url, :timeout, :headers
|
|
23
|
+
|
|
24
|
+
def initialize(base_url: 'https://bnvd.org/api/v1', timeout: 30, headers: {})
|
|
25
|
+
@base_url = base_url
|
|
26
|
+
@timeout = timeout
|
|
27
|
+
@headers = {
|
|
28
|
+
'Content-Type' => 'application/json'
|
|
29
|
+
}.merge(headers)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Parâmetros de paginação
|
|
34
|
+
class PaginationParams
|
|
35
|
+
attr_accessor :page, :per_page
|
|
36
|
+
|
|
37
|
+
def initialize(page: nil, per_page: nil)
|
|
38
|
+
@page = page
|
|
39
|
+
@per_page = per_page
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def to_query_params
|
|
43
|
+
params = {}
|
|
44
|
+
params['page'] = @page.to_s if @page
|
|
45
|
+
params['per_page'] = @per_page.to_s if @per_page
|
|
46
|
+
params
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Parâmetros de busca
|
|
51
|
+
class SearchParams < PaginationParams
|
|
52
|
+
attr_accessor :year, :severity, :vendor, :include_pt
|
|
53
|
+
|
|
54
|
+
def initialize(page: nil, per_page: nil, year: nil, severity: nil, vendor: nil, include_pt: true)
|
|
55
|
+
super(page: page, per_page: per_page)
|
|
56
|
+
@year = year
|
|
57
|
+
@severity = severity
|
|
58
|
+
@vendor = vendor
|
|
59
|
+
@include_pt = include_pt
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_query_params
|
|
63
|
+
params = super
|
|
64
|
+
params['year'] = @year.to_s if @year
|
|
65
|
+
params['severity'] = @severity if @severity
|
|
66
|
+
params['vendor'] = @vendor if @vendor
|
|
67
|
+
params['include_pt'] = @include_pt.to_s if @include_pt
|
|
68
|
+
params
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Parâmetros de busca recente
|
|
73
|
+
class RecentSearchParams < PaginationParams
|
|
74
|
+
attr_accessor :days, :include_pt
|
|
75
|
+
|
|
76
|
+
def initialize(page: nil, per_page: nil, days: nil, include_pt: true)
|
|
77
|
+
super(page: page, per_page: per_page)
|
|
78
|
+
@days = days
|
|
79
|
+
@include_pt = include_pt
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def to_query_params
|
|
83
|
+
params = super
|
|
84
|
+
params['days'] = @days.to_s if @days
|
|
85
|
+
params['include_pt'] = @include_pt.to_s if @include_pt
|
|
86
|
+
params
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Resposta da API
|
|
91
|
+
class APIResponse
|
|
92
|
+
attr_reader :status, :data, :message, :pagination
|
|
93
|
+
|
|
94
|
+
def initialize(json)
|
|
95
|
+
@status = json['status']
|
|
96
|
+
@data = json['data']
|
|
97
|
+
@message = json['message']
|
|
98
|
+
@pagination = json['pagination']
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def success?
|
|
102
|
+
@status == 'success'
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def error?
|
|
106
|
+
@status == 'error'
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Cliente da API BNVD
|
|
111
|
+
class Client
|
|
112
|
+
def initialize(config)
|
|
113
|
+
@config = config
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Faz requisição HTTP para a API
|
|
117
|
+
def request(endpoint, params = {})
|
|
118
|
+
uri = URI.parse(@config.base_url + endpoint)
|
|
119
|
+
uri.query = URI.encode_www_form(params) unless params.empty?
|
|
120
|
+
|
|
121
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
122
|
+
http.use_ssl = uri.scheme == 'https'
|
|
123
|
+
http.read_timeout = @config.timeout
|
|
124
|
+
|
|
125
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
|
126
|
+
@config.headers.each { |key, value| request[key] = value }
|
|
127
|
+
|
|
128
|
+
response = http.request(request)
|
|
129
|
+
|
|
130
|
+
case response
|
|
131
|
+
when Net::HTTPSuccess
|
|
132
|
+
APIResponse.new(JSON.parse(response.body))
|
|
133
|
+
else
|
|
134
|
+
raise "HTTP Error: #{response.code} #{response.message}"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Retorna informações sobre a API
|
|
139
|
+
def get_api_info
|
|
140
|
+
request('/api/v1/')
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Lista todas as vulnerabilidades com suporte a paginação e filtros
|
|
144
|
+
def list_vulnerabilities(params = SearchParams.new)
|
|
145
|
+
query_params = params.is_a?(SearchParams) ? params.to_query_params : params
|
|
146
|
+
request('/api/v1/vulnerabilities', query_params)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Busca uma vulnerabilidade específica pelo CVE ID
|
|
150
|
+
def get_vulnerability(cve_id, include_pt: true)
|
|
151
|
+
request("/api/v1/vulnerabilities/#{cve_id}", { include_pt: include_pt })
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Busca vulnerabilidades recentes
|
|
155
|
+
def get_recent_vulnerabilities(params = RecentSearchParams.new)
|
|
156
|
+
query_params = params.is_a?(RecentSearchParams) ? params.to_query_params : params
|
|
157
|
+
request('/api/v1/search/recent', query_params)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Retorna as 5 vulnerabilidades mais recentes
|
|
161
|
+
def get_top5_recent(include_pt: true)
|
|
162
|
+
request('/api/v1/search/recent/5', { include_pt: include_pt })
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Busca vulnerabilidades por ano
|
|
166
|
+
def search_by_year(year, params = PaginationParams.new)
|
|
167
|
+
query_params = params.is_a?(PaginationParams) ? params.to_query_params : params
|
|
168
|
+
request("/api/v1/search/year/#{year}", query_params)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Busca vulnerabilidades por severidade
|
|
172
|
+
def search_by_severity(severity, params = PaginationParams.new)
|
|
173
|
+
query_params = params.is_a?(PaginationParams) ? params.to_query_params : params
|
|
174
|
+
request("/api/v1/search/severity/#{severity}", query_params)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Busca vulnerabilidades por vendor/fabricante
|
|
178
|
+
def search_by_vendor(vendor, params = PaginationParams.new)
|
|
179
|
+
query_params = params.is_a?(PaginationParams) ? params.to_query_params : params
|
|
180
|
+
request("/api/v1/search/vendor/#{vendor}", query_params)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Retorna estatísticas gerais
|
|
184
|
+
def get_stats
|
|
185
|
+
request('/api/v1/stats')
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Retorna estatísticas por ano
|
|
189
|
+
def get_year_stats
|
|
190
|
+
request('/api/v1/stats/years')
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# === Notícias ===
|
|
194
|
+
|
|
195
|
+
# Lista todas as notícias
|
|
196
|
+
def list_noticias(params = PaginationParams.new)
|
|
197
|
+
query_params = params.is_a?(PaginationParams) ? params.to_query_params : params
|
|
198
|
+
request('/api/v1/noticias', query_params)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Retorna notícias recentes
|
|
202
|
+
def get_recent_noticias(limit = 5)
|
|
203
|
+
request("/api/v1/noticias/recentes/#{limit}")
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Busca notícia por slug
|
|
207
|
+
def get_noticia_by_slug(slug)
|
|
208
|
+
request("/api/v1/noticias/#{slug}")
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# === MITRE ATT&CK ===
|
|
212
|
+
|
|
213
|
+
# Retorna informações sobre o sistema MITRE ATT&CK
|
|
214
|
+
def get_mitre_info
|
|
215
|
+
request('/api/v1/mitre')
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Lista todas as matrizes MITRE ATT&CK disponíveis
|
|
219
|
+
def list_mitre_matrices
|
|
220
|
+
request('/api/v1/mitre/matrices')
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Retorna uma matriz específica
|
|
224
|
+
def get_mitre_matrix(matrix_name, include_pt = true)
|
|
225
|
+
request("/api/v1/mitre/matrix/#{matrix_name}", { include_pt: include_pt })
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Lista todas as técnicas MITRE ATT&CK
|
|
229
|
+
def list_mitre_techniques(params = {})
|
|
230
|
+
request('/api/v1/mitre/techniques', params)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Retorna detalhes de uma técnica específica
|
|
234
|
+
def get_mitre_technique(technique_id, include_pt = true)
|
|
235
|
+
request("/api/v1/mitre/technique/#{technique_id}", { include_pt: include_pt })
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Lista todas as subtécnicas MITRE ATT&CK
|
|
239
|
+
def list_mitre_subtechniques(params = {})
|
|
240
|
+
request('/api/v1/mitre/subtechniques', params)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Lista todos os grupos de ameaças MITRE ATT&CK
|
|
244
|
+
def list_mitre_groups(params = {})
|
|
245
|
+
request('/api/v1/mitre/groups', params)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Retorna detalhes de um grupo específico
|
|
249
|
+
def get_mitre_group(group_id, include_pt = true)
|
|
250
|
+
request("/api/v1/mitre/group/#{group_id}", { include_pt: include_pt })
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Lista todas as mitigações MITRE ATT&CK
|
|
254
|
+
def list_mitre_mitigations(params = {})
|
|
255
|
+
request('/api/v1/mitre/mitigations', params)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Retorna detalhes de uma mitigação específica
|
|
259
|
+
def get_mitre_mitigation(mitigation_id, include_pt = true)
|
|
260
|
+
request("/api/v1/mitre/mitigation/#{mitigation_id}", { include_pt: include_pt })
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bnvd_client
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- BNVD Team
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: json
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.6'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '2.6'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rspec
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.12'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.12'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: webmock
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '3.18'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '3.18'
|
|
54
|
+
description: Cliente Ruby para a API do Banco Nacional de Vulnerabilidades Cibernéticas
|
|
55
|
+
(BNVD)
|
|
56
|
+
email:
|
|
57
|
+
- contato@bnvd.org
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- README.md
|
|
63
|
+
- lib/bnvd_client.rb
|
|
64
|
+
homepage: https://bnvd.org
|
|
65
|
+
licenses:
|
|
66
|
+
- MIT
|
|
67
|
+
metadata:
|
|
68
|
+
homepage_uri: https://bnvd.org
|
|
69
|
+
source_code_uri: https://github.com/azurejoga/bnvd/tree/main/api_clients/ruby
|
|
70
|
+
changelog_uri: https://github.com/azurejoga/bnvd/tree/main/api_clients/ruby/CHANGELOG.md
|
|
71
|
+
rdoc_options: []
|
|
72
|
+
require_paths:
|
|
73
|
+
- lib
|
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: 2.7.0
|
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
requirements: []
|
|
85
|
+
rubygems_version: 3.6.9
|
|
86
|
+
specification_version: 4
|
|
87
|
+
summary: Cliente oficial para a API do BNVD
|
|
88
|
+
test_files: []
|