Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3dcd263d43
|
||
|
|
eeb399ff83
|
||
|
|
7c4bad860a
|
No files matched your search
@@ -112,6 +112,7 @@ class Rs::OauthController < ApplicationController
|
||||
redirect_uri: redirect_uri,
|
||||
permissions: permissions,
|
||||
expire_at: expire_at,
|
||||
user_agent: request.user_agent,
|
||||
code_challenge: challenge,
|
||||
code_challenge_method: method
|
||||
)
|
||||
@@ -124,7 +125,8 @@ class Rs::OauthController < ApplicationController
|
||||
client_id: client_id,
|
||||
redirect_uri: redirect_uri,
|
||||
app_name: client_id,
|
||||
expire_at: expire_at
|
||||
expire_at: expire_at,
|
||||
user_agent: request.user_agent
|
||||
)
|
||||
|
||||
redirect_to url_with_state("#{redirect_uri}#access_token=#{auth.token}", state),
|
||||
|
||||
@@ -29,6 +29,8 @@ class Services::RsAuthsController < Services::BaseController
|
||||
current_user.address
|
||||
end
|
||||
|
||||
# Storage-first bearer token issuance (remoteStorage spec §11): the app
|
||||
# receives the address and runs the application-first flow itself.
|
||||
launch_url = "#{@auth.launch_url}#remotestorage=#{user_address}"
|
||||
|
||||
redirect_to launch_url, allow_other_host: true
|
||||
|
||||
@@ -36,7 +36,8 @@ module RsOauthManager
|
||||
client_id: auth_code.client_id,
|
||||
redirect_uri: auth_code.redirect_uri,
|
||||
app_name: auth_code.client_id,
|
||||
expire_at: auth_code.permission_expire_at
|
||||
expire_at: auth_code.permission_expire_at,
|
||||
user_agent: auth_code.user_agent
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module RsOauthManager
|
||||
class IssueCode < RsOauthManagerService
|
||||
def initialize(user:, client_id:, redirect_uri:, permissions:,
|
||||
code_challenge:, code_challenge_method: "S256",
|
||||
expire_at: nil)
|
||||
expire_at: nil, user_agent: nil)
|
||||
@user = user
|
||||
@client_id = client_id
|
||||
@redirect_uri = redirect_uri
|
||||
@@ -10,6 +10,7 @@ module RsOauthManager
|
||||
@code_challenge = code_challenge
|
||||
@code_challenge_method = code_challenge_method
|
||||
@expire_at = expire_at
|
||||
@user_agent = user_agent
|
||||
end
|
||||
|
||||
def call
|
||||
@@ -19,6 +20,7 @@ module RsOauthManager
|
||||
redirect_uri: @redirect_uri,
|
||||
permissions: @permissions,
|
||||
permission_expire_at: @expire_at,
|
||||
user_agent: @user_agent,
|
||||
code_challenge: @code_challenge,
|
||||
code_challenge_method: @code_challenge_method
|
||||
)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class AddUserAgentToRsAuthorizations < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :remote_storage_authorizations, :user_agent, :text
|
||||
add_column :rs_authorization_codes, :user_agent, :text
|
||||
end
|
||||
end
|
||||
+3
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2026_11_02_120000) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2026_11_02_130000) do
|
||||
create_table "active_storage_attachments", force: :cascade do |t|
|
||||
t.bigint "blob_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -110,6 +110,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_11_02_120000) do
|
||||
t.string "redirect_uri"
|
||||
t.string "token"
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "user_agent"
|
||||
t.integer "user_id", null: false
|
||||
t.integer "web_app_id"
|
||||
t.index ["permissions"], name: "index_remote_storage_authorizations_on_permissions"
|
||||
@@ -128,6 +129,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_11_02_120000) do
|
||||
t.text "permissions", default: "[]"
|
||||
t.string "redirect_uri", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "user_agent"
|
||||
t.integer "user_id", null: false
|
||||
t.index ["code_digest"], name: "index_rs_authorization_codes_on_code_digest", unique: true
|
||||
t.index ["user_id"], name: "index_rs_authorization_codes_on_user_id"
|
||||
|
||||
@@ -346,6 +346,7 @@ RSpec.describe Rs::OauthController, type: :controller do
|
||||
context "when user is signed in" do
|
||||
before do
|
||||
sign_in user
|
||||
request.user_agent = "RSpec Device"
|
||||
end
|
||||
|
||||
after do
|
||||
@@ -370,6 +371,10 @@ RSpec.describe Rs::OauthController, type: :controller do
|
||||
expect(@auth.permissions).to eq(%w(documents photos contacts:rw videos:r tasks/work:r))
|
||||
end
|
||||
|
||||
it "stores the device's user agent" do
|
||||
expect(@auth.user_agent).to eq("RSpec Device")
|
||||
end
|
||||
|
||||
it "redirects to the redirect_uri" do
|
||||
expect(response).to redirect_to("https://example.com#access_token=#{@auth.token}&state=foobar123")
|
||||
end
|
||||
@@ -499,6 +504,7 @@ RSpec.describe Rs::OauthController, type: :controller do
|
||||
expect(@code.permissions).to eq(%w(documents photos contacts:rw))
|
||||
expect(@code.code_challenge).to eq("E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM")
|
||||
expect(@code.code_challenge_method).to eq("S256")
|
||||
expect(@code.user_agent).to eq("RSpec Device")
|
||||
end
|
||||
|
||||
it "does not create a remote storage authorization" do
|
||||
|
||||
@@ -11,7 +11,7 @@ RSpec.describe Services::RsAuthsController, type: :controller do
|
||||
])
|
||||
end
|
||||
|
||||
describe "GET /services/storage/rs_auths/:id/launch_app" do
|
||||
describe "GET /services/storage/rs_auths/:id/launch_app (storage-first)" do
|
||||
context "when user is signed in" do
|
||||
before do
|
||||
sign_in user
|
||||
@@ -32,10 +32,14 @@ RSpec.describe Services::RsAuthsController, type: :controller do
|
||||
@auth.destroy
|
||||
end
|
||||
|
||||
it "redirects to the given URL with the correct RS URL fragment params" do
|
||||
it "hands the app the user address in the URL fragment" do
|
||||
launch_url = "https://app.example.com#remotestorage=#{user.address}"
|
||||
expect(response).to redirect_to(launch_url)
|
||||
end
|
||||
|
||||
it "does not hand over an access token" do
|
||||
expect(response.location).not_to include("access_token")
|
||||
end
|
||||
end
|
||||
|
||||
context "when remoteStorage is not enabled for the user" do
|
||||
|
||||
@@ -20,6 +20,7 @@ RSpec.describe RsOauthManager::ExchangeCode do
|
||||
permissions: %w(documents:rw),
|
||||
code_challenge: code_challenge,
|
||||
code_challenge_method: "S256",
|
||||
user_agent: "RSpec Device",
|
||||
**overrides
|
||||
)
|
||||
end
|
||||
@@ -43,6 +44,7 @@ RSpec.describe RsOauthManager::ExchangeCode do
|
||||
expect(auth.permissions).to eq(%w(documents:rw))
|
||||
expect(auth.client_id).to eq("example.com")
|
||||
expect(auth.token).to be_present
|
||||
expect(auth.user_agent).to eq("RSpec Device")
|
||||
expect(RsAuthorizationCode.exists?(code.id)).to be(false)
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ RSpec.describe RsOauthManager::IssueCode do
|
||||
permissions: %w(documents:rw),
|
||||
code_challenge: "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
|
||||
code_challenge_method: "S256",
|
||||
expire_at: 1.month.from_now
|
||||
expire_at: 1.month.from_now,
|
||||
user_agent: "RSpec Device"
|
||||
)
|
||||
end
|
||||
|
||||
@@ -21,6 +22,7 @@ RSpec.describe RsOauthManager::IssueCode do
|
||||
expect(subject.client_id).to eq("example.com")
|
||||
expect(subject.permissions).to eq(%w(documents:rw))
|
||||
expect(subject.code_challenge).to eq("E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM")
|
||||
expect(subject.user_agent).to eq("RSpec Device")
|
||||
end
|
||||
|
||||
it "does not create a remote storage authorization" do
|
||||
|
||||
Reference in new issue
Block a user