Skip to content

Commit a7464f6

Browse files
committed
Tie access token directly to session
We need to present them differently in the session list and prevent them from being deleted
1 parent 95708c7 commit a7464f6

File tree

8 files changed

+20
-17
lines changed

8 files changed

+20
-17
lines changed

app/controllers/concerns/authentication.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def require_authentication
4545
end
4646

4747
def resume_session
48-
if session = find_session_by_cookie || find_or_start_session_by_bearer_token
48+
if session = find_session_by_cookie || find_session_by_bearer_token
4949
set_current_session session
5050
end
5151
end
@@ -54,7 +54,7 @@ def find_session_by_cookie
5454
Session.find_signed(cookies.signed[:session_token])
5555
end
5656

57-
def find_or_start_session_by_bearer_token
57+
def find_session_by_bearer_token
5858
if request_authorized_by_bearer_token?
5959
Identity::AccessToken.find_by(token: authorization_bearer_token)&.session
6060
end
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
class Identity::AccessToken < ApplicationRecord
22
belongs_to :identity
3+
belongs_to :session
34

45
has_secure_token
56
enum :permission, %w[ read write ].index_by(&:itself), default: :read
67

7-
def session
8-
identity.sessions.find_or_create_by! user_agent: session_user_agent
9-
end
8+
before_validation :build_session, on: :create
109

1110
private
12-
# Overload the user_agent identification for access token session reuse.
13-
# This allows us to easily reuse a single session record per access token.
14-
def session_user_agent
15-
"access-token-#{id}"
11+
def build_session
12+
self.session = identity.sessions.build(user_agent: "Access Token")
1613
end
1714
end

db/migrate/20251201132341_create_identity_access_tokens.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ class CreateIdentityAccessTokens < ActiveRecord::Migration[8.2]
22
def change
33
create_table :identity_access_tokens, id: :uuid do |t|
44
t.uuid :identity_id, null: false
5+
t.uuid :session_id, null: false
56
t.string :token
67
t.string :permission
78
t.text :description

db/schema.rb

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

db/schema_sqlite.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@
315315
t.text "description", limit: 65535
316316
t.uuid "identity_id", null: false
317317
t.string "permission", limit: 255
318+
t.uuid "session_id", null: false
318319
t.string "token", limit: 255
319320
t.datetime "updated_at", null: false
320321
t.index ["identity_id"], name: "index_access_token_on_identity_id"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
jasons_api_token:
22
identity: jason
3+
session: jason_api
34
token: 018cf1425682700098f24f0799e3fe20
45
description: My Superscript
56
permission: read
67

78
davids_api_token:
89
identity: david
10+
session: david_api
911
token: x18cf1425682700098f24f0799e3fe20
1012
description: My Superscript
1113
permission: write

test/fixtures/sessions.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
david:
22
identity: david
33

4+
david_api:
5+
identity: david
6+
47
kevin:
58
identity: kevin
69

@@ -9,3 +12,6 @@ jz:
912

1013
jason:
1114
identity: jason
15+
16+
jason_api:
17+
identity: jason
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
require "test_helper"
22

33
class Identity::AccessTokenTest < ActiveSupport::TestCase
4-
test "only one session at the time" do
5-
assert_changes -> { Session.count }, +1 do
6-
identity_access_tokens(:jasons_api_token).session
7-
end
8-
9-
assert_no_changes -> { Session.count } do
10-
identity_access_tokens(:jasons_api_token).session
11-
end
4+
test "new access token comes with a session" do
5+
access_token = identities(:david).access_tokens.create!
6+
assert_equal "Access Token", identities(:david).sessions.last.user_agent
127
end
138
end

0 commit comments

Comments
 (0)