fetch token introspection
Co-authored-by: François VANTOMME <akarzim@gmail.com>
This commit is contained in:
parent
620a5374e8
commit
87cb16093f
5 changed files with 182 additions and 0 deletions
34
app/lib/api_particulier/api.rb
Normal file
34
app/lib/api_particulier/api.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
class APIParticulier::API
|
||||
include APIParticulier::Error
|
||||
|
||||
INTROSPECT_RESOURCE_NAME = "introspect"
|
||||
|
||||
TIMEOUT = 20
|
||||
|
||||
def initialize(token)
|
||||
@token = token
|
||||
end
|
||||
|
||||
def scopes
|
||||
get(INTROSPECT_RESOURCE_NAME)[:scopes]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get(resource_name, params = {})
|
||||
url = [API_PARTICULIER_URL, resource_name].join("/")
|
||||
|
||||
response = Typhoeus.get(url,
|
||||
headers: { accept: "application/json", "X-API-Key": @token },
|
||||
params: params,
|
||||
timeout: TIMEOUT)
|
||||
|
||||
if response.success?
|
||||
JSON.parse(response.body, symbolize_names: true)
|
||||
elsif response.code == 401
|
||||
raise Unauthorized.new(response)
|
||||
else
|
||||
raise RequestFailed.new(response)
|
||||
end
|
||||
end
|
||||
end
|
32
app/lib/api_particulier/error.rb
Normal file
32
app/lib/api_particulier/error.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
module APIParticulier
|
||||
module Error
|
||||
class HttpError < ::StandardError
|
||||
def initialize(response)
|
||||
connect_time = response.connect_time
|
||||
curl_message = response.return_message
|
||||
http_error_code = response.code
|
||||
datetime = response.headers.fetch('Date', DateTime.current.inspect)
|
||||
total_time = response.total_time
|
||||
|
||||
uri = URI.parse(response.effective_url)
|
||||
url = "#{uri.host}#{uri.path}"
|
||||
|
||||
msg = <<~TEXT
|
||||
url: #{url}
|
||||
HTTP error code: #{http_error_code}
|
||||
#{response.body}
|
||||
curl message: #{curl_message}
|
||||
total time: #{total_time}
|
||||
connect time: #{connect_time}
|
||||
datetime: #{datetime}
|
||||
TEXT
|
||||
|
||||
super(msg)
|
||||
end
|
||||
end
|
||||
|
||||
class RequestFailed < HttpError; end
|
||||
|
||||
class Unauthorized < HttpError; end
|
||||
end
|
||||
end
|
44
spec/fixtures/cassettes/api_particulier/success/introspect.yml
vendored
Normal file
44
spec/fixtures/cassettes/api_particulier/success/introspect.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: https://particulier.api.gouv.fr/api/introspect
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- demarches-simplifiees.fr
|
||||
Accept:
|
||||
- application/json
|
||||
X-Api-Key:
|
||||
- d7e9c9f4c3ca00caadde31f50fd4521a
|
||||
Expect:
|
||||
- ''
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Date:
|
||||
- Tue, 16 Mar 2021 15:25:24 GMT
|
||||
Content-Type:
|
||||
- application/json
|
||||
Content-Length:
|
||||
- '228'
|
||||
Connection:
|
||||
- keep-alive
|
||||
Keep-Alive:
|
||||
- timeout=5
|
||||
X-Gravitee-Request-Id:
|
||||
- 0e4dd327-de40-4052-8dd3-27de401052c4
|
||||
X-Gravitee-Transaction-Id:
|
||||
- cc30bb74-6516-46d9-b0bb-746516d6d904
|
||||
Strict-Transport-Security:
|
||||
- max-age=15552000
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"_id":"1d99db5a-a099-4314-ad2f-2707c6b505a6","name":"Application de
|
||||
sandbox","scopes":["dgfip_avis_imposition","dgfip_adresse","cnaf_allocataires","cnaf_enfants","cnaf_adresse","cnaf_quotient_familial","mesri_statut_etudiant"]}'
|
||||
recorded_at: Tue, 16 Mar 2021 15:25:24 GMT
|
||||
recorded_with: VCR 6.0.0
|
44
spec/fixtures/cassettes/api_particulier/unauthorized/introspect.yml
vendored
Normal file
44
spec/fixtures/cassettes/api_particulier/unauthorized/introspect.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: https://particulier.api.gouv.fr/api/introspect
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- demarches-simplifiees.fr
|
||||
Accept:
|
||||
- application/json
|
||||
X-Api-Key:
|
||||
- d7e9c9f4c3ca00caadde31f50fd4521a
|
||||
Expect:
|
||||
- ''
|
||||
response:
|
||||
status:
|
||||
code: 401
|
||||
message: ''
|
||||
headers:
|
||||
Server:
|
||||
- nginx
|
||||
Date:
|
||||
- Wed, 15 Sep 2021 10:02:12 GMT
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Content-Length:
|
||||
- '134'
|
||||
X-Powered-By:
|
||||
- Express
|
||||
Vary:
|
||||
- Origin
|
||||
Etag:
|
||||
- W/"86-FwFf7uuVKCSJkazn1ZHnY1yVYUo"
|
||||
Strict-Transport-Security:
|
||||
- max-age=15724800; includeSubdomains
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: >
|
||||
{"error":"acces_denied","reason":"Token not found or inactive","message":"Votre jeton d'API n'a pas été trouvé ou n'est pas actif"}
|
||||
recorded_at: Wed, 15 Sep 2021 10:02:12 GMT
|
||||
recorded_with: VCR 6.0.0
|
28
spec/lib/api_particulier/api_spec.rb
Normal file
28
spec/lib/api_particulier/api_spec.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
describe APIParticulier::API do
|
||||
let(:token) { "d7e9c9f4c3ca00caadde31f50fd4521a" }
|
||||
let(:api) { APIParticulier::API.new(token) }
|
||||
|
||||
before { stub_const("API_PARTICULIER_URL", "https://particulier.api.gouv.fr/api") }
|
||||
|
||||
describe "scopes" do
|
||||
subject { api.scopes }
|
||||
|
||||
it "doit retourner une liste de scopes" do
|
||||
VCR.use_cassette("api_particulier/success/introspect") do
|
||||
expect(subject).to match_array(['dgfip_avis_imposition', 'dgfip_adresse', 'cnaf_allocataires', 'cnaf_enfants', 'cnaf_adresse', 'cnaf_quotient_familial', 'mesri_statut_etudiant'])
|
||||
end
|
||||
end
|
||||
|
||||
it "returns an unauthorized exception" do
|
||||
VCR.use_cassette("api_particulier/unauthorized/introspect") do
|
||||
begin
|
||||
subject
|
||||
rescue APIParticulier::Error::Unauthorized => e
|
||||
expect(e.message).to include('url: particulier.api.gouv.fr/api/introspect')
|
||||
expect(e.message).to include('HTTP error code: 401')
|
||||
expect(e.message).to include("Votre jeton d'API n'a pas été trouvé ou n'est pas actif")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue