aikido-ruby-client 0.0.1 → 0.0.2

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: e1aff36ac4f8ac9f17a073b5acfead422df83829a80e7f6f7ec3a8d68426214d
4
- data.tar.gz: 7a84efa160d1e3701ab301d04a71eb967f24e7cda172c9b34f60c34bd277e467
3
+ metadata.gz: 2195bf014566aa0b80fbbf1412abce1996457bd8a93a126280689e00bdf19d72
4
+ data.tar.gz: 2904c3cd13469f36ef32e3d74daf4a1eef837286f5f71047fc3bb53b0c23b400
5
5
  SHA512:
6
- metadata.gz: 5250c5726c5920423b88b31c982a792251fca565fca0996bee526a1e222e6dc38c27074482e93fa8752ef7a09ca89588e00f996bb4f85f3baf8369d884fc98bf
7
- data.tar.gz: f74ecf9b1df49a4e84608ed68900ded1dfa8b672e8a00cbdd5d762214bf670be3ba6117d60a21dc44a8bc5792d42498d4a574c19a4e2d18ce715a72c296e50b9
6
+ metadata.gz: 3e1e0ced53c59664ba1b3eb53f1711bf82da26e244c4fb8a8b48f05456799639314bb6d625e140802b36dc7f8d13e0e2c23cef34677aacee1ebc443cc09bf40b
7
+ data.tar.gz: c5cc2da2ed92067ef28e7c5a5b9fc6af21c8fb96675dd085b219ba26e4aa59a1a165218610104b0fd8d68345987ce7eda7807f072aad74384d9541f310fd8cd4
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml CHANGED
@@ -1,7 +1,12 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.7
3
3
  NewCops: enable
4
+ SuggestExtensions: false
4
5
 
5
6
  Naming/FileName:
6
7
  Exclude:
7
8
  - 'lib/aikido-ruby-client.rb'
9
+
10
+ Metrics/BlockLength:
11
+ Exclude:
12
+ - 'spec/**/*.rb'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.0.2](https://github.com/anakinj/aikido-ruby-client/tree/v0.0.2) (2024-03-10)
4
+
5
+ **Features:**
6
+
7
+ - More api methods
8
+ - Pagination support
9
+ - Specs backed by VCR recordings
10
+
3
11
  ## [v0.0.1](https://github.com/anakinj/aikido-ruby-client/tree/v0.0.1) (2024-03-10)
4
12
 
5
13
  **Features:**
data/exe/aikido CHANGED
@@ -6,3 +6,4 @@ require 'aikido-ruby-client'
6
6
  client = Aikido::Client.new
7
7
 
8
8
  puts client.issues
9
+ puts client.code_repositories.to_a
data/lib/aikido/client.rb CHANGED
@@ -2,35 +2,68 @@
2
2
 
3
3
  require 'httpx'
4
4
 
5
+ require_relative 'errors'
6
+ require_relative 'paginated_response'
7
+
5
8
  module Aikido
6
9
  # HTTP Client to interact with the Aikido API
7
10
  # Official documentation: https://apidocs.aikido.dev/
8
11
  class Client
9
12
  def initialize(client_id: nil, client_secret: nil)
10
- @client_id = client_id || ENV.fetch('AIKIDO_CLIENT_ID', nil)
13
+ @client_id = client_id || ENV.fetch('AIKIDO_CLIENT_ID', nil)
11
14
  @client_secret = client_secret || ENV.fetch('AIKIDO_CLIENT_SECRET', nil)
12
15
  end
13
16
 
14
17
  def authorize
15
- http.plugin(:basic_auth).basic_auth(@client_id, @client_secret).post('/oauth/token',
16
- json: { grant_type: 'client_credentials' })
18
+ handle_response!(http.plugin(:basic_auth)
19
+ .basic_auth(@client_id, @client_secret)
20
+ .post('/oauth/token', json: { grant_type: 'client_credentials' }))
21
+ end
22
+
23
+ def workspace
24
+ get('/public/v1/workspace').json
25
+ end
26
+
27
+ def clouds
28
+ PaginatedResponse.new do |page|
29
+ get('/public/v1/clouds', params: { page: page }).json
30
+ end
17
31
  end
18
32
 
19
33
  def issues(params: {})
20
- authed_http.get('/public/v1/issues/export', params: params).json
34
+ get('/public/v1/issues/export', params: params).json
21
35
  end
22
36
 
23
37
  def issue(id)
24
- authed_http.get("/public/v1/issues/#{id.to_i}").json
38
+ get("/public/v1/issues/#{id.to_i}").json
39
+ end
40
+
41
+ def issue_groups
42
+ PaginatedResponse.new do |page|
43
+ get('/public/v1/open-issue-groups', params: { page: page }).json
44
+ end
45
+ end
46
+
47
+ def issue_group(id)
48
+ get("/public/v1/issues/groups/#{id.to_i}").json
25
49
  end
26
50
 
27
- def repositories
28
- # TODO: Paginated response
29
- authed_http.get('/public/v1/repositories/code', params: params).json
51
+ def code_repositories
52
+ PaginatedResponse.new do |page|
53
+ get('/public/v1/repositories/code', params: { page: page }).json
54
+ end
55
+ end
56
+
57
+ def code_repository_sbom(id, format: 'csv')
58
+ get("repositories/code/#{id.to_i}/licenses/export", params: { format: format }).body
30
59
  end
31
60
 
32
61
  private
33
62
 
63
+ def get(path, params: {})
64
+ handle_response!(authed_http.get(path, params: params))
65
+ end
66
+
34
67
  def authed_http
35
68
  http.plugin(:auth).bearer_auth(auth_token)
36
69
  end
@@ -47,5 +80,23 @@ module Aikido
47
80
  # TODO: Handle token expiration
48
81
  @auth_token ||= authorize.json['access_token']
49
82
  end
83
+
84
+ def handle_response!(response)
85
+ case response.status
86
+ when 200..299
87
+ response
88
+ else
89
+ raise_response_error!(response)
90
+ end
91
+ end
92
+
93
+ def raise_response_error!(response)
94
+ case response.status
95
+ when 401
96
+ raise Errors::UnauthorizedError, response
97
+ else
98
+ raise Errors::ApiError, response
99
+ end
100
+ end
50
101
  end
51
102
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aikido
4
+ module Errors
5
+ AikidoError = Class.new(StandardError)
6
+
7
+ # Represents an error that occurred while making an API request.
8
+ class ApiError < AikidoError
9
+ def initialize(response)
10
+ @response = response
11
+ super("API Error: #{response.status}")
12
+ end
13
+
14
+ def message
15
+ if @response.json['error_description']
16
+ "#{super} - #{@response.json['error_description']}"
17
+ else
18
+ super
19
+ end
20
+ end
21
+ end
22
+ UnauthorizedError = Class.new(ApiError)
23
+ NotFoundError = Class.new(ApiError)
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aikido
4
+ # Represents a reponse that is paginated
5
+ class PaginatedResponse
6
+ include Enumerable
7
+
8
+ def initialize(&block)
9
+ @page_loader = block
10
+ @pages = []
11
+ load_page(0)
12
+ end
13
+
14
+ def each(&block)
15
+ return enum_for(:each) unless block_given?
16
+
17
+ loop.with_index do |_, index|
18
+ page = load_page(index)
19
+ break if page.empty?
20
+
21
+ page.each(&block)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def load_page(page)
28
+ @pages[page] ||= @page_loader.call(page)
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aikido
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aikido-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joakim Antman
@@ -32,6 +32,7 @@ executables:
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
+ - ".rspec"
35
36
  - ".rubocop.yml"
36
37
  - CHANGELOG.md
37
38
  - LICENSE.txt
@@ -40,6 +41,8 @@ files:
40
41
  - exe/aikido
41
42
  - lib/aikido-ruby-client.rb
42
43
  - lib/aikido/client.rb
44
+ - lib/aikido/errors.rb
45
+ - lib/aikido/paginated_response.rb
43
46
  - lib/aikido/version.rb
44
47
  homepage: https://github.com/anakinj/aikido-ruby-client
45
48
  licenses:
@@ -47,7 +50,7 @@ licenses:
47
50
  metadata:
48
51
  homepage_uri: https://github.com/anakinj/aikido-ruby-client
49
52
  source_code_uri: https://github.com/anakinj
50
- changelog_uri: https://github.com/anakinj/jwk-loader/blob/0.0.1/CHANGELOG.md
53
+ changelog_uri: https://github.com/anakinj/jwk-loader/blob/0.0.2/CHANGELOG.md
51
54
  rubygems_mfa_required: 'true'
52
55
  post_install_message:
53
56
  rdoc_options: []