Skip to content

Commit a69bbc1

Browse files
Connect the token authentication mechanism to Devise session tracking
1 parent 581affe commit a69bbc1

4 files changed

Lines changed: 40 additions & 19 deletions

File tree

app/controllers/concerns/reporting_api/token_authentication_concern.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ def authenticate_user_by_jwt!
4343
)
4444
)
4545
if @current_user
46-
session["user"] = data["user"]
4746
session["cis2_info"] = data["cis2_info"]
47+
48+
# Establish a Warden session with activity tracking
49+
# which enables Devise's timeoutable module
50+
sign_in @current_user, event: :authentication
51+
4852
authenticate_user!
4953
else
5054
session.clear

spec/controllers/concerns/reporting_api/token_authentication_concern_spec.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
def authenticate_user!
1313
end
1414

15+
def sign_in(user, options = {})
16+
end
17+
1518
def initialize(request: nil, session: {})
1619
@request = request
1720
@session = session
@@ -201,20 +204,20 @@ def current_user
201204
context "when a User exists with the values of id, session_token and reporting_api_session_token" do
202205
let(:user_id) { user.id }
203206

204-
it "copies the user key into session['user']" do
205-
an_object_which_includes_the_concern.send(:authenticate_user_by_jwt!)
206-
expect(an_object_which_includes_the_concern.session["user"]).to eq(
207-
user_info.first["data"]["user"]
208-
)
209-
end
210-
211207
it "copies the cis2_info key into session['cis2_info']" do
212208
an_object_which_includes_the_concern.send(:authenticate_user_by_jwt!)
213209
expect(
214210
an_object_which_includes_the_concern.session["cis2_info"]
215211
).to eq(user_info.first["data"]["cis2_info"])
216212
end
217213

214+
it "signs in the user through Devise/Warden" do
215+
expect(an_object_which_includes_the_concern).to receive(
216+
:sign_in
217+
).with(user, event: :authentication)
218+
an_object_which_includes_the_concern.send(:authenticate_user_by_jwt!)
219+
end
220+
218221
it "calls authenticate_user!" do
219222
expect(an_object_which_includes_the_concern).to receive(
220223
:authenticate_user!

spec/support/reporting_api_helper.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ module ReportingAPIHelper
44
def valid_jwt_payload
55
team = create(:team, :with_one_nurse)
66
user = team.users.first
7+
8+
# Ensure the user has session tokens required by Warden callbacks
9+
user.update!(
10+
session_token: SecureRandom.hex(32),
11+
reporting_api_session_token: SecureRandom.hex(32)
12+
)
13+
714
{
815
data: {
916
user: user.as_json,
@@ -16,12 +23,8 @@ def valid_jwt_payload
1623
}
1724
end
1825

19-
def valid_jwt
20-
JWT.encode(
21-
valid_jwt_payload,
22-
Settings.reporting_api.client_app.secret,
23-
"HS512"
24-
)
26+
def valid_jwt(payload = valid_jwt_payload)
27+
JWT.encode(payload, Settings.reporting_api.client_app.secret, "HS512")
2528
end
2629

2730
def invalid_jwt_payload

spec/support/shared_examples/a_reporting_api_controller.rb

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
# frozen_string_literal: true
22

33
shared_examples "a ReportingAPI controller" do
4-
let(:team) { create(:team, :with_one_nurse) }
5-
let(:user) { team.users.first }
6-
74
include ReportingAPIHelper
85

6+
# Extract the user from the JWT payload so we're testing with the same user
7+
# that was authenticated via JWT
8+
let(:jwt_payload) { valid_jwt_payload }
9+
let(:user) { User.find(jwt_payload[:data][:user]["id"]) }
10+
let(:team) { user.teams.first }
11+
912
context "when the reporting_api feature flag is disabled" do
1013
before { Flipper.disable(:reporting_api) }
1114

@@ -14,7 +17,7 @@
1417
let(:params) { { jwt: jwt } }
1518

1619
context "which is valid" do
17-
let(:jwt) { valid_jwt }
20+
let(:jwt) { valid_jwt(jwt_payload) }
1821

1922
it "responds with status :forbidden" do
2023
get :index, params: { jwt: jwt }
@@ -33,12 +36,20 @@
3336
let(:params) { { jwt: jwt } }
3437

3538
context "which is valid" do
36-
let(:jwt) { valid_jwt }
39+
let(:jwt) { valid_jwt(jwt_payload) }
3740

3841
it "responds with status 200" do
3942
get :index, params: { jwt: jwt }
4043
expect(response.status).to eq(200)
4144
end
45+
46+
it "establishes a Warden session with activity tracking" do
47+
get :index, params: { jwt: jwt }
48+
49+
expect(
50+
request.session.dig("warden.user.user.session", "last_request_at")
51+
).to be_a(Integer)
52+
end
4253
end
4354

4455
context "which is not valid" do

0 commit comments

Comments
 (0)