Class: Spree::Admin::SquareOauthController
- Inherits:
-
BaseController
- Object
- BaseController
- Spree::Admin::SquareOauthController
- Defined in:
- app/controllers/spree/admin/square_oauth_controller.rb
Overview
Self-service "Connect to Square" flow for the current store — the OAuth replacement for hand-generating SQUARE_ACCESS_TOKEN in .env. Square requires multi-merchant apps to use OAuth rather than personal access tokens (a prerequisite for App Marketplace listing), and this is the admin-facing half of that: authorize -> callback -> store an encrypted SpreeSquare::Credential -> SpreeSquare::Client picks it up automatically from here on (see Client.for_store).
Instance Method Summary collapse
- #callback ⇒ Object
-
#connect ⇒ Object
Kicks off the OAuth authorization-code flow: redirect the admin's browser to Square's own consent page.
- #destroy ⇒ Object
- #show ⇒ Object
Instance Method Details
#callback ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'app/controllers/spree/admin/square_oauth_controller.rb', line 32 def callback expected_state = session.delete(:square_oauth_state) if params[:error].present? flash[:error] = Spree.t(:square_oauth_denied, default: "Square authorization was cancelled: #{params[:error_description] || params[:error]}") return redirect_to admin_square_oauth_path end if expected_state.blank? || !ActiveSupport::SecurityUtils.secure_compare(expected_state, params[:state].to_s) flash[:error] = Spree.t(:square_oauth_state_mismatch, default: 'Square authorization could not be verified (invalid state) — please try connecting again.') return redirect_to admin_square_oauth_path end response = SpreeSquare::OauthClient.exchange_code(code: params[:code], redirect_uri: admin_callback_square_oauth_url) save_credential!(response) flash[:success] = Spree.t(:square_oauth_connected, default: 'Connected to Square.') redirect_to admin_square_oauth_path rescue Square::Errors::ResponseError => e Rails.logger.error("[SpreeSquare] OAuth token exchange failed: #{e.}") flash[:error] = Spree.t(:square_oauth_exchange_failed, default: 'Could not connect to Square — please try again.') redirect_to admin_square_oauth_path end |
#connect ⇒ Object
Kicks off the OAuth authorization-code flow: redirect the admin's
browser to Square's own consent page. state is a CSRF token,
verified on the way back in #callback — without it, an attacker
could trick an admin into connecting the attacker's Square account
to this store by crafting their own callback link.
22 23 24 25 26 27 28 29 30 |
# File 'app/controllers/spree/admin/square_oauth_controller.rb', line 22 def connect state = SecureRandom.hex(24) session[:square_oauth_state] = state redirect_to SpreeSquare::OauthClient.( redirect_uri: admin_callback_square_oauth_url, state: state ), allow_other_host: true end |
#destroy ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'app/controllers/spree/admin/square_oauth_controller.rb', line 56 def destroy credential = SpreeSquare::Credential.find_by(store: current_store) if credential begin SpreeSquare::OauthClient.revoke(credential) rescue StandardError => e # A failed remote revoke (token already invalid, network blip) # shouldn't trap the admin into a "disconnect" button that never # works — the local side is what actually stops this store's # syncing, so proceed to destroy the row regardless. Rails.logger.warn("[SpreeSquare] OAuth revoke failed, disconnecting locally anyway: #{e.}") end credential.destroy! end flash[:success] = Spree.t(:square_oauth_disconnected, default: 'Disconnected from Square.') redirect_to admin_square_oauth_path end |
#show ⇒ Object
13 14 15 |
# File 'app/controllers/spree/admin/square_oauth_controller.rb', line 13 def show @credential = SpreeSquare::Credential.find_by(store: current_store) end |