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