Skip to content

Commit 4396d3d

Browse files
mwtrewadrian-rpf
andauthored
Add endpoint for Profile API authorisation check (#694)
## Status - Closes https://github.com/orgs/RaspberryPiFoundation/projects/51/views/11?pane=issue&itemId=159250789&issue=RaspberryPiFoundation%7Cdigital-editor-issues%7C1174 ## What's changed? - Add endpoint that Standalone can use to check if the current user has access to Profile API. ## Before deployment - Platform Capabilities need to merge and deploy RaspberryPiFoundation/profile#2024. --------- Co-authored-by: Adrian Lansdown <adrian.lansdown@raspberrypi.org>
1 parent 147df8d commit 4396d3d

4 files changed

Lines changed: 88 additions & 1 deletion

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
module Api
4+
class ProfileAuthCheckController < ApiController
5+
def index
6+
authorised = ProfileApiClient.check_auth(token: current_user&.token)
7+
8+
render json: { can_use_profile_api: authorised }, status: :ok
9+
rescue ProfileApiClient::UnauthorizedError
10+
render json: { can_use_profile_api: false }, status: :ok
11+
end
12+
end
13+
end

config/routes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
post '/google/auth/exchange-code', to: 'google_auth#exchange_code', defaults: { format: :json }
9999

100100
resources :features, only: %i[index]
101+
102+
resources :profile_auth_check, only: %i[index]
101103
end
102104

103105
resource :github_webhooks, only: :create, defaults: { formats: :json }

lib/profile_api_client.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,21 @@ def initialize(response)
3636
@response_status = response.status
3737
@response_headers = response.headers
3838
@response_body = response.body
39-
4039
super("Unexpected response from Profile API (status code #{response.status})")
4140
end
4241
end
4342

4443
class << self
44+
def check_auth(token:)
45+
return true if ENV['BYPASS_OAUTH'].present?
46+
47+
response = connection(token).get('/api/v1/access')
48+
49+
response.status == 200
50+
rescue Faraday::BadRequestError, Faraday::UnauthorizedError
51+
false
52+
end
53+
4554
def create_school(token:, id:, code:)
4655
return { 'id' => id, 'schoolCode' => code } if ENV['BYPASS_OAUTH'].present?
4756

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe 'Profile auth check API' do
6+
let(:headers) { { Authorization: UserProfileMock::TOKEN } }
7+
let(:school) { create(:school) }
8+
let(:student) { create(:student, school:) }
9+
let(:api_url) { 'http://example.com' }
10+
let(:api_key) { 'api-key' }
11+
12+
before do
13+
allow(ENV).to receive(:fetch).and_call_original
14+
allow(ENV).to receive(:fetch).with('IDENTITY_URL').and_return(api_url)
15+
allow(ENV).to receive(:fetch).with('PROFILE_API_KEY').and_return(api_key)
16+
end
17+
18+
describe 'GET /api/profile_auth_check' do
19+
context 'when the profile API authorises the current user' do
20+
it 'returns can_use_profile_api: true' do
21+
# Arrange
22+
authenticated_in_hydra_as(student)
23+
stub_request(:get, "#{ENV.fetch('IDENTITY_URL')}/api/v1/access").to_return(status: 200, headers:)
24+
25+
# Act
26+
get '/api/profile_auth_check', headers: headers
27+
28+
# Assert
29+
expect(response).to have_http_status(:ok)
30+
expect(response.parsed_body).to eq('can_use_profile_api' => true)
31+
end
32+
end
33+
34+
context 'when the profile API returns unauthorized' do
35+
it 'returns can_use_profile_api: false' do
36+
# Arrange
37+
authenticated_in_hydra_as(student)
38+
stub_request(:get, "#{ENV.fetch('IDENTITY_URL')}/api/v1/access").to_return(status: 401, headers:)
39+
40+
# Act
41+
get '/api/profile_auth_check', headers: headers
42+
43+
# Assert
44+
expect(response).to have_http_status(:ok)
45+
expect(response.parsed_body).to eq('can_use_profile_api' => false)
46+
end
47+
end
48+
49+
context 'when there is no current user' do
50+
it 'returns can_use_profile_api: false' do
51+
# Arrange
52+
stub_request(:get, "#{ENV.fetch('IDENTITY_URL')}/api/v1/access").to_return(status: 400, headers:)
53+
54+
# Act
55+
get '/api/profile_auth_check'
56+
57+
# Assert
58+
expect(response).to have_http_status(:ok)
59+
expect(response.parsed_body).to eq('can_use_profile_api' => false)
60+
end
61+
end
62+
end
63+
end

0 commit comments

Comments
 (0)