CI / Test (pull_request) Successful in 43s
- One card per app (grouped by client_id) showing distinct device and category counts; the whole card opens the details modal (with hover and focus highlight) instead of a separate Details button - Details modal: access list styled like the OAuth consent dialog via a shared RsScopeListComponent, plus per-token device, connected date and expiry, each with its own Revoke - "folder" -> "category" in the card, modal, consent dialog and the auth-created notification - Make revoke a real DELETE: it was a GET link that Turbo 8's prefetch-on-hover fired on its own, silently deleting authorizations. Missing or foreign authorizations now return 404 instead of 500. - Move "Launch app" to the app level (GET /services/storage/apps/:client_id/launch); no token id in the URL Part of #254
109 lines
3.4 KiB
Ruby
109 lines
3.4 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe Services::RsAuthsController, type: :controller do
|
|
let(:user) { create :user }
|
|
|
|
before do
|
|
allow_any_instance_of(AppCatalog::WebApp).to receive(:update_metadata).and_return(true)
|
|
allow_any_instance_of(RemoteStorageAuthorization).to receive(:remove_token_expiry_job).and_return(nil)
|
|
allow_any_instance_of(LdapService).to receive(:fetch_users).and_return([
|
|
{ services_enabled: ["remotestorage"] }
|
|
])
|
|
end
|
|
|
|
describe "GET /services/storage/apps/:client_id/launch (storage-first)" do
|
|
context "when user is signed in" do
|
|
before do
|
|
sign_in user
|
|
end
|
|
|
|
context "authorization exists" do
|
|
before do
|
|
@auth = user.remote_storage_authorizations.create!(
|
|
permissions: %w(documents), client_id: "app.example.com",
|
|
redirect_uri: "https://app.example.com",
|
|
expire_at: 2.days.from_now
|
|
)
|
|
|
|
get :launch_app, params: { client_id: @auth.client_id }
|
|
end
|
|
|
|
after do
|
|
@auth.destroy
|
|
end
|
|
|
|
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
|
|
before do
|
|
allow_any_instance_of(LdapService).to receive(:fetch_users).and_return([
|
|
{ services_enabled: [] }
|
|
])
|
|
|
|
get :launch_app, params: { client_id: "app.example.com" }
|
|
end
|
|
|
|
it "responds with forbidden" do
|
|
expect(response).to have_http_status(:forbidden)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "GET /services/storage/apps/:client_id/launch for an unknown app" do
|
|
before { sign_in user }
|
|
|
|
it "returns 404 instead of raising" do
|
|
get :launch_app, params: { client_id: "nonexistent.example.com" }
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
|
|
describe "DELETE /services/storage/rs_auths/:id" do
|
|
context "when user is signed in" do
|
|
before { sign_in user }
|
|
|
|
it "revokes the authorization" do
|
|
auth = user.remote_storage_authorizations.create!(
|
|
permissions: %w(documents), client_id: "app.example.com",
|
|
redirect_uri: "https://app.example.com", expire_at: 2.days.from_now
|
|
)
|
|
|
|
expect {
|
|
delete :destroy, params: { id: auth.id }
|
|
}.to change(RemoteStorageAuthorization, :count).by(-1)
|
|
|
|
expect(response).to redirect_to(apps_services_storage_url)
|
|
end
|
|
|
|
it "returns 404 for an unknown authorization" do
|
|
delete :destroy, params: { id: 0 }
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
|
|
it "returns 404 for another user's authorization" do
|
|
other = create :user, id: 99, cn: "otheruser", email: "other@example.com"
|
|
auth = other.remote_storage_authorizations.create!(
|
|
permissions: %w(documents), client_id: "app.example.com",
|
|
redirect_uri: "https://app.example.com"
|
|
)
|
|
|
|
delete :destroy, params: { id: auth.id }
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
expect(RemoteStorageAuthorization.exists?(auth.id)).to be(true)
|
|
end
|
|
end
|
|
end
|
|
end
|