Merge pull request #2450 from basecamp/flavorjones/coworker-audit-api
saas: Update audits1984 and allow the auditor token for LLM access to audits
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@ gem "stripe", "~> 18.0"
|
||||
gem "queenbee", bc: "queenbee-plugin"
|
||||
gem "fizzy-saas", path: "saas"
|
||||
gem "console1984", bc: "console1984"
|
||||
gem "audits1984", bc: "audits1984"
|
||||
gem "audits1984", bc: "audits1984", branch: "flavorjones/coworker-api"
|
||||
|
||||
# Telemetry
|
||||
gem "rails_structured_logging", bc: "rails-structured-logging"
|
||||
|
||||
+3
-1
@@ -1,10 +1,12 @@
|
||||
GIT
|
||||
remote: https://github.com/basecamp/audits1984
|
||||
revision: c790eaec0716c8df56b3d0ab5bf5d75e3e1b0ed0
|
||||
revision: 422b8ff25820c828b7cf09aff4923fd8cc2c6795
|
||||
branch: flavorjones/coworker-api
|
||||
specs:
|
||||
audits1984 (0.1.7)
|
||||
console1984
|
||||
importmap-rails (>= 1.2.1)
|
||||
jbuilder
|
||||
rinku
|
||||
rouge
|
||||
turbo-rails
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class Admin::AuditsController < ::AdminController
|
||||
private
|
||||
# Extend Fizzy's authentication to support auditor bearer tokens.
|
||||
def require_authentication
|
||||
authenticate_by_audit_bearer_token || super
|
||||
end
|
||||
|
||||
def authenticate_by_audit_bearer_token
|
||||
if auditor = auditor_from_bearer_token
|
||||
Current.identity = auditor
|
||||
end
|
||||
end
|
||||
|
||||
def find_current_auditor
|
||||
Current.identity
|
||||
end
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
class SaasAdminController < ::AdminController
|
||||
private
|
||||
def find_current_auditor
|
||||
Current.identity
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
# This migration comes from audits1984 (originally 20260126000000)
|
||||
class CreateAuditorTokens < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :audits1984_auditor_tokens do |t|
|
||||
t.uuid :auditor_id, null: false, index: { unique: true }
|
||||
t.string :token_digest, null: false
|
||||
t.datetime :expires_at, null: false
|
||||
|
||||
t.timestamps
|
||||
|
||||
t.index :token_digest, unique: true
|
||||
end
|
||||
end
|
||||
end
|
||||
+11
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.2].define(version: 2025_12_16_000000) do
|
||||
ActiveRecord::Schema[8.2].define(version: 2026_01_26_230838) do
|
||||
create_table "account_billing_waivers", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.uuid "account_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -43,6 +43,16 @@ ActiveRecord::Schema[8.2].define(version: 2025_12_16_000000) do
|
||||
t.index ["stripe_subscription_id"], name: "index_account_subscriptions_on_stripe_subscription_id", unique: true
|
||||
end
|
||||
|
||||
create_table "audits1984_auditor_tokens", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.uuid "auditor_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "expires_at", null: false
|
||||
t.string "token_digest", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["auditor_id"], name: "index_audits1984_auditor_tokens_on_auditor_id", unique: true
|
||||
t.index ["token_digest"], name: "index_audits1984_auditor_tokens_on_token_digest", unique: true
|
||||
end
|
||||
|
||||
create_table "audits1984_audits", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.uuid "auditor_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
|
||||
@@ -124,8 +124,9 @@ module Fizzy
|
||||
config.console1984.protected_environments = %i[ production beta staging ]
|
||||
config.console1984.ask_for_username_if_empty = true
|
||||
config.console1984.base_record_class = "::SaasRecord"
|
||||
config.console1984.incinerate_after = 60.days
|
||||
|
||||
config.audits1984.base_controller_class = "::SaasAdminController"
|
||||
config.audits1984.base_controller_class = "::Admin::AuditsController"
|
||||
config.audits1984.auditor_class = "::Identity"
|
||||
config.audits1984.auditor_name_attribute = :email_address
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
require "test_helper"
|
||||
|
||||
class Admin::AuditsControllerTest < ActionDispatch::IntegrationTest
|
||||
# Test authentication via the Audits1984::SessionsController#index endpoint,
|
||||
# which inherits from Admin::AuditsController through Audits1984::ApplicationController.
|
||||
|
||||
test "unauthenticated access is forbidden" do
|
||||
untenanted do
|
||||
get saas.admin_audits1984_path
|
||||
assert_redirected_to new_session_path
|
||||
end
|
||||
end
|
||||
|
||||
test "logged-in non-staff access is forbidden" do
|
||||
sign_in_as :jz
|
||||
|
||||
untenanted do
|
||||
get saas.admin_audits1984_path
|
||||
end
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "logged-in staff access is allowed" do
|
||||
sign_in_as :david
|
||||
|
||||
untenanted do
|
||||
get saas.admin_audits1984_path
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "invalid bearer token is forbidden" do
|
||||
untenanted do
|
||||
get saas.admin_audits1984_path, headers: { "Authorization" => "Bearer invalid_token" }
|
||||
end
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
test "valid bearer token is allowed" do
|
||||
token = Audits1984::AuditorToken.generate_for(identities(:david))
|
||||
|
||||
untenanted do
|
||||
get saas.admin_audits1984_path, headers: { "Authorization" => "Bearer #{token}" }
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "expired bearer token is forbidden" do
|
||||
token = Audits1984::AuditorToken.generate_for(identities(:david))
|
||||
Audits1984::AuditorToken.update_all(expires_at: 1.day.ago)
|
||||
|
||||
untenanted do
|
||||
get saas.admin_audits1984_path, headers: { "Authorization" => "Bearer #{token}" }
|
||||
end
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
test "bearer token for non-staff user is forbidden" do
|
||||
# Even with a valid token, non-staff users should be denied access.
|
||||
# This handles the case where a user's staff privileges are revoked
|
||||
# after a token was issued.
|
||||
token = Audits1984::AuditorToken.generate_for(identities(:jz))
|
||||
|
||||
untenanted do
|
||||
get saas.admin_audits1984_path, headers: { "Authorization" => "Bearer #{token}" }
|
||||
end
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user