mirror of
https://github.com/System-End/theseus.git
synced 2026-04-19 16:38:18 +00:00
Add HCB OAuth and payment account controllers
- OAuth flow for linking HCB accounts - CRUD for payment accounts (user/org pairs) - Routes under /back_office/hcb/ - Use HCBV4::Client.from_credentials with proper token persistence
This commit is contained in:
parent
c0071a7593
commit
b574d57a80
5 changed files with 160 additions and 12 deletions
57
app/controllers/hcb/oauth_connections_controller.rb
Normal file
57
app/controllers/hcb/oauth_connections_controller.rb
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
class HCB::OauthConnectionsController < ApplicationController
|
||||
skip_after_action :verify_authorized, only: [:new, :callback, :destroy]
|
||||
|
||||
def new
|
||||
redirect_to hcb_oauth_authorize_url, allow_other_host: true
|
||||
end
|
||||
|
||||
def callback
|
||||
code = params[:code]
|
||||
if code.blank?
|
||||
redirect_to root_path, alert: "HCB authorization failed"
|
||||
return
|
||||
end
|
||||
|
||||
token = hcb_oauth_client.auth_code.get_token(
|
||||
code,
|
||||
redirect_uri: hcb_oauth_callback_url,
|
||||
)
|
||||
|
||||
connection = current_user.hcb_oauth_connection || current_user.build_hcb_oauth_connection
|
||||
connection.update!(
|
||||
access_token: token.token,
|
||||
refresh_token: token.refresh_token,
|
||||
expires_at: token.expires_at ? Time.at(token.expires_at) : nil,
|
||||
)
|
||||
|
||||
redirect_to hcb_payment_accounts_path, notice: "HCB account linked! Now create a payment account."
|
||||
end
|
||||
|
||||
def destroy
|
||||
current_user.hcb_oauth_connection&.destroy
|
||||
redirect_to root_path, notice: "HCB account unlinked"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def hcb_oauth_client
|
||||
@hcb_oauth_client ||= OAuth2::Client.new(
|
||||
Rails.application.credentials.dig(:hcb, :client_id),
|
||||
Rails.application.credentials.dig(:hcb, :client_secret),
|
||||
site: hcb_api_base,
|
||||
authorize_url: "/oauth/authorize",
|
||||
token_url: "/oauth/token",
|
||||
)
|
||||
end
|
||||
|
||||
def hcb_api_base
|
||||
Rails.application.credentials.dig(:hcb, :api_base) || "https://hcb.hackclub.com"
|
||||
end
|
||||
|
||||
def hcb_oauth_authorize_url
|
||||
hcb_oauth_client.auth_code.authorize_url(
|
||||
redirect_uri: hcb_oauth_callback_url,
|
||||
scope: "read write",
|
||||
)
|
||||
end
|
||||
end
|
||||
66
app/controllers/hcb/payment_accounts_controller.rb
Normal file
66
app/controllers/hcb/payment_accounts_controller.rb
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
class HCB::PaymentAccountsController < ApplicationController
|
||||
before_action :require_hcb_connection
|
||||
before_action :set_payment_account, only: [:show, :destroy]
|
||||
|
||||
def index
|
||||
@payment_accounts = current_user.hcb_payment_accounts
|
||||
@available_organizations = available_organizations
|
||||
end
|
||||
|
||||
def new
|
||||
@organizations = available_organizations
|
||||
@payment_account = current_user.hcb_payment_accounts.build
|
||||
end
|
||||
|
||||
def create
|
||||
org = find_organization(params[:organization_id])
|
||||
if org.nil?
|
||||
redirect_to new_hcb_payment_account_path, alert: "Organization not found"
|
||||
return
|
||||
end
|
||||
|
||||
@payment_account = current_user.hcb_payment_accounts.build(
|
||||
oauth_connection: current_user.hcb_oauth_connection,
|
||||
organization_id: org.id,
|
||||
organization_name: org.name,
|
||||
)
|
||||
|
||||
if @payment_account.save
|
||||
redirect_to hcb_payment_accounts_path, notice: "Payment account created for #{org.name}"
|
||||
else
|
||||
@organizations = available_organizations
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def destroy
|
||||
@payment_account.destroy
|
||||
redirect_to hcb_payment_accounts_path, notice: "Payment account removed"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_hcb_connection
|
||||
unless current_user.hcb_connected?
|
||||
redirect_to new_hcb_oauth_connection_path, alert: "Please link your HCB account first"
|
||||
end
|
||||
end
|
||||
|
||||
def set_payment_account
|
||||
@payment_account = current_user.hcb_payment_accounts.find(params[:id])
|
||||
end
|
||||
|
||||
def available_organizations
|
||||
current_user.hcb_oauth_connection.organizations
|
||||
rescue => e
|
||||
Rails.logger.error "Failed to fetch HCB organizations: #{e.message}"
|
||||
[]
|
||||
end
|
||||
|
||||
def find_organization(org_id)
|
||||
available_organizations.find { |o| o.id == org_id }
|
||||
end
|
||||
end
|
||||
|
|
@ -7,23 +7,38 @@ class HCB::OauthConnection < ApplicationRecord
|
|||
validates :user_id, uniqueness: true
|
||||
|
||||
def client
|
||||
@client ||= HCBV4::Client.new(
|
||||
@client ||= HCBV4::Client.from_credentials(
|
||||
client_id: Rails.application.credentials.dig(:hcb, :client_id),
|
||||
client_secret: Rails.application.credentials.dig(:hcb, :client_secret),
|
||||
access_token: access_token,
|
||||
refresh_token: refresh_token,
|
||||
expires_at: expires_at&.to_i,
|
||||
on_token_refresh: ->(new_access, new_refresh, new_expires) {
|
||||
update!(
|
||||
access_token: new_access,
|
||||
refresh_token: new_refresh,
|
||||
expires_at: Time.at(new_expires),
|
||||
)
|
||||
},
|
||||
base_url: hcb_api_base,
|
||||
)
|
||||
end
|
||||
|
||||
def organizations
|
||||
client.user.organizations
|
||||
result = client.organizations
|
||||
persist_refreshed_token!
|
||||
result
|
||||
end
|
||||
|
||||
def persist_refreshed_token!
|
||||
token = client.oauth_token
|
||||
return unless token.respond_to?(:token)
|
||||
|
||||
if token.token != access_token || token.refresh_token != refresh_token
|
||||
update!(
|
||||
access_token: token.token,
|
||||
refresh_token: token.refresh_token,
|
||||
expires_at: token.expires_at ? Time.at(token.expires_at) : nil,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def hcb_api_base
|
||||
Rails.application.credentials.dig(:hcb, :api_base) || "https://hcb.hackclub.com"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,10 +14,13 @@ class HCB::PaymentAccount < ApplicationRecord
|
|||
end
|
||||
|
||||
def create_disbursement!(amount_cents:, memo:)
|
||||
organization.create_transfer(
|
||||
result = client.create_disbursement(
|
||||
event_id: organization_id,
|
||||
to_organization_id: Rails.application.credentials.dig(:hcb, :recipient_org_id),
|
||||
amount_cents: amount_cents,
|
||||
recipient_organization_id: Rails.application.credentials.dig(:hcb, :recipient_org_id),
|
||||
memo: memo,
|
||||
name: memo,
|
||||
)
|
||||
oauth_connection.persist_refreshed_token!
|
||||
result
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -529,6 +529,13 @@ Rails.application.routes.draw do
|
|||
resources :payment_accounts
|
||||
resources :mailer_ids
|
||||
end
|
||||
|
||||
namespace :hcb do
|
||||
resource :oauth_connection, only: [:new, :destroy] do
|
||||
get :callback, on: :collection
|
||||
end
|
||||
resources :payment_accounts, only: [:index, :new, :create, :show, :destroy]
|
||||
end
|
||||
resources :source_tags
|
||||
namespace :warehouse do
|
||||
resources :templates
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue