spree_api 5.6.1 → 6.0.0.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +28 -0
- data/Rakefile +1 -1
- data/app/controllers/concerns/spree/api/v3/address_params.rb +17 -0
- data/app/controllers/concerns/spree/api/v3/admin/product_listing.rb +46 -0
- data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +110 -0
- data/app/controllers/concerns/spree/api/v3/admin/receivable_actions.rb +68 -0
- data/app/controllers/concerns/spree/api/v3/admin/reporting_authorization.rb +27 -0
- data/app/controllers/concerns/spree/api/v3/admin/role_grant_guard.rb +69 -33
- data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +86 -0
- data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +97 -0
- data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +12 -6
- data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +91 -0
- data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +20 -5
- data/app/controllers/concerns/spree/api/v3/api_key_authentication.rb +41 -5
- data/app/controllers/concerns/spree/api/v3/authentication_strategies.rb +48 -0
- data/app/controllers/concerns/spree/api/v3/bulk_operations.rb +4 -6
- data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +52 -16
- data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +37 -0
- data/app/controllers/concerns/spree/api/v3/current_password_confirmation.rb +41 -0
- data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +35 -0
- data/app/controllers/concerns/spree/api/v3/error_handler.rb +53 -11
- data/app/controllers/concerns/spree/api/v3/idempotent.rb +10 -4
- data/app/controllers/concerns/spree/api/v3/items_payload.rb +54 -0
- data/app/controllers/concerns/spree/api/v3/jwt_authentication.rb +23 -3
- data/app/controllers/concerns/spree/api/v3/key_store_context.rb +31 -0
- data/app/controllers/concerns/spree/api/v3/locale_and_currency.rb +3 -3
- data/app/controllers/concerns/spree/api/v3/order_lock.rb +22 -3
- data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +112 -0
- data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +105 -0
- data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +117 -0
- data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +157 -0
- data/app/controllers/concerns/spree/api/v3/orders/post_sale_actions.rb +76 -0
- data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +116 -0
- data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +128 -0
- data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +7 -4
- data/app/controllers/concerns/spree/api/v3/permission_serialization.rb +42 -0
- data/app/controllers/concerns/spree/api/v3/rate_limit_headers.rb +40 -6
- data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +80 -26
- data/app/controllers/concerns/spree/api/v3/seller/auth_cookies.rb +62 -0
- data/app/controllers/concerns/spree/api/v3/seller/seller_context.rb +127 -0
- data/app/controllers/concerns/spree/api/v3/seller_authentication.rb +40 -0
- data/app/controllers/concerns/spree/api/v3/storefront_access.rb +38 -0
- data/app/controllers/concerns/spree/api/v3/streams_shipping_label.rb +37 -0
- data/app/controllers/concerns/spree/api/v3/tax_identifier_validation.rb +41 -0
- data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +11 -14
- data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +18 -9
- data/app/controllers/spree/api/v3/admin/auth_controller.rb +138 -22
- data/app/controllers/spree/api/v3/admin/base_controller.rb +2 -0
- data/app/controllers/spree/api/v3/admin/catalog_assignments_controller.rb +27 -0
- data/app/controllers/spree/api/v3/admin/catalogs/base_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +40 -0
- data/app/controllers/spree/api/v3/admin/catalogs/products_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +75 -0
- data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +191 -0
- data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +28 -41
- data/app/controllers/spree/api/v3/admin/categories_controller.rb +16 -7
- data/app/controllers/spree/api/v3/admin/channels_controller.rb +50 -2
- data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/claims_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/collection_rules_controller.rb +40 -0
- data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +101 -0
- data/app/controllers/spree/api/v3/admin/collections_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/commission_lines_controller.rb +39 -0
- data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +174 -0
- data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +65 -0
- data/app/controllers/spree/api/v3/admin/companies/base_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/companies/invitations_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +137 -0
- data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +46 -0
- data/app/controllers/spree/api/v3/admin/companies_controller.rb +59 -0
- data/app/controllers/spree/api/v3/admin/concerns/external_references.rb +166 -0
- data/app/controllers/spree/api/v3/admin/consent_records_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/countries_controller.rb +12 -4
- data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +19 -4
- data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +5 -5
- data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +4 -4
- data/app/controllers/spree/api/v3/admin/customers/base_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +2 -3
- data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/admin/customers_controller.rb +190 -11
- data/app/controllers/spree/api/v3/admin/dashboard_controller.rb +24 -20
- data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +60 -0
- data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +54 -0
- data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +114 -0
- data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +243 -0
- data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +80 -0
- data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +116 -0
- data/app/controllers/spree/api/v3/admin/digital_links_controller.rb +48 -0
- data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +17 -3
- data/app/controllers/spree/api/v3/admin/exchanges_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/exports_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +3 -2
- data/app/controllers/spree/api/v3/admin/imports_controller.rb +71 -8
- data/app/controllers/spree/api/v3/admin/integrations_controller.rb +67 -0
- data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +5 -5
- data/app/controllers/spree/api/v3/admin/invitations_controller.rb +5 -1
- data/app/controllers/spree/api/v3/admin/locales_controller.rb +3 -1
- data/app/controllers/spree/api/v3/admin/markets_controller.rb +9 -5
- data/app/controllers/spree/api/v3/admin/me_controller.rb +4 -30
- data/app/controllers/spree/api/v3/admin/media_controller.rb +88 -38
- data/app/controllers/spree/api/v3/admin/media_library_controller.rb +156 -0
- data/app/controllers/spree/api/v3/admin/option_types_controller.rb +1 -0
- data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/order_groups_controller.rb +43 -0
- data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +86 -0
- data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +99 -0
- data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +62 -0
- data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +83 -0
- data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +45 -67
- data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +40 -22
- data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +75 -0
- data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +36 -18
- data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +39 -18
- data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +70 -0
- data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/orders/tax_identifiers_controller.rb +41 -0
- data/app/controllers/spree/api/v3/admin/orders/tax_lines_controller.rb +32 -0
- data/app/controllers/spree/api/v3/admin/orders_controller.rb +164 -33
- data/app/controllers/spree/api/v3/admin/package_types_controller.rb +39 -0
- data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +15 -4
- data/app/controllers/spree/api/v3/admin/payout_providers_controller.rb +27 -0
- data/app/controllers/spree/api/v3/admin/permissions_controller.rb +30 -0
- data/app/controllers/spree/api/v3/admin/policies_controller.rb +42 -0
- data/app/controllers/spree/api/v3/admin/price_lists/products_controller.rb +93 -0
- data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +43 -29
- data/app/controllers/spree/api/v3/admin/prices_controller.rb +41 -4
- data/app/controllers/spree/api/v3/admin/product_types_controller.rb +93 -0
- data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +148 -0
- data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +24 -3
- data/app/controllers/spree/api/v3/admin/products_controller.rb +149 -33
- data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +6 -2
- data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/promotions_controller.rb +1 -5
- data/app/controllers/spree/api/v3/admin/purchase_orders/stock_receipts_controller.rb +32 -0
- data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +161 -0
- data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +45 -0
- data/app/controllers/spree/api/v3/admin/reporting_controller.rb +95 -0
- data/app/controllers/spree/api/v3/admin/resource_controller.rb +27 -10
- data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/returns_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/roles_controller.rb +50 -6
- data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +83 -0
- data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +139 -0
- data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +115 -0
- data/app/controllers/spree/api/v3/admin/seller_transfers_controller.rb +36 -0
- data/app/controllers/spree/api/v3/admin/sellers/balances_controller.rb +44 -0
- data/app/controllers/spree/api/v3/admin/sellers/invitations_controller.rb +77 -0
- data/app/controllers/spree/api/v3/admin/sellers/payouts_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/sellers/team_controller.rb +64 -0
- data/app/controllers/spree/api/v3/admin/sellers_controller.rb +197 -0
- data/app/controllers/spree/api/v3/admin/setup_controller.rb +239 -0
- data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +172 -0
- data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +3 -2
- data/app/controllers/spree/api/v3/admin/stock_movements_controller.rb +37 -0
- data/app/controllers/spree/api/v3/admin/stock_reservations_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/stock_transfers/stock_receipts_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +134 -38
- data/app/controllers/spree/api/v3/admin/store_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/store_credits/events_controller.rb +47 -0
- data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +87 -0
- data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +30 -0
- data/app/controllers/spree/api/v3/admin/tags_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +4 -0
- data/app/controllers/spree/api/v3/admin/tax_providers_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/translatable_resources_controller.rb +37 -9
- data/app/controllers/spree/api/v3/admin/translations_controller.rb +10 -5
- data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +150 -0
- data/app/controllers/spree/api/v3/admin/variants_controller.rb +11 -4
- data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +1 -1
- data/app/controllers/spree/api/v3/base_controller.rb +74 -16
- data/app/controllers/spree/api/v3/resource_controller.rb +170 -39
- data/app/controllers/spree/api/v3/seller/auth_controller.rb +169 -0
- data/app/controllers/spree/api/v3/seller/balances_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/base_controller.rb +25 -0
- data/app/controllers/spree/api/v3/seller/claim_reasons_controller.rb +20 -0
- data/app/controllers/spree/api/v3/seller/countries_controller.rb +38 -0
- data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +265 -0
- data/app/controllers/spree/api/v3/seller/delivery_profiles_controller.rb +65 -0
- data/app/controllers/spree/api/v3/seller/delivery_zones_controller.rb +41 -0
- data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +21 -0
- data/app/controllers/spree/api/v3/seller/exports_controller.rb +195 -0
- data/app/controllers/spree/api/v3/seller/import_rows_controller.rb +49 -0
- data/app/controllers/spree/api/v3/seller/imports_controller.rb +317 -0
- data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +152 -0
- data/app/controllers/spree/api/v3/seller/invitations_controller.rb +71 -0
- data/app/controllers/spree/api/v3/seller/me_controller.rb +72 -0
- data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +111 -0
- data/app/controllers/spree/api/v3/seller/order_cancellation_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/seller/orders/base_controller.rb +44 -0
- data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +45 -0
- data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +38 -0
- data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +50 -0
- data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +79 -0
- data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +55 -0
- data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +82 -0
- data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +44 -0
- data/app/controllers/spree/api/v3/seller/orders_controller.rb +199 -0
- data/app/controllers/spree/api/v3/seller/package_types_controller.rb +100 -0
- data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +155 -0
- data/app/controllers/spree/api/v3/seller/payouts_controller.rb +47 -0
- data/app/controllers/spree/api/v3/seller/policies_controller.rb +57 -0
- data/app/controllers/spree/api/v3/seller/product_types_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/products_controller.rb +394 -0
- data/app/controllers/spree/api/v3/seller/profile_controller.rb +137 -0
- data/app/controllers/spree/api/v3/seller/reasons_controller.rb +45 -0
- data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +95 -0
- data/app/controllers/spree/api/v3/seller/resource_controller.rb +75 -0
- data/app/controllers/spree/api/v3/seller/return_reasons_controller.rb +20 -0
- data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +56 -0
- data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +48 -0
- data/app/controllers/spree/api/v3/seller/team_controller.rb +103 -0
- data/app/controllers/spree/api/v3/seller/tracking_carriers_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/transfers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/store/account/companies_controller.rb +42 -0
- data/app/controllers/spree/api/v3/store/auth_controller.rb +21 -34
- data/app/controllers/spree/api/v3/store/base_controller.rb +4 -0
- data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +24 -2
- data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +41 -15
- data/app/controllers/spree/api/v3/store/carts/items_controller.rb +53 -20
- data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +36 -20
- data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +111 -0
- data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +2 -2
- data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +96 -0
- data/app/controllers/spree/api/v3/store/carts_controller.rb +57 -12
- data/app/controllers/spree/api/v3/store/categories_controller.rb +6 -3
- data/app/controllers/spree/api/v3/store/collections/products_controller.rb +59 -0
- data/app/controllers/spree/api/v3/store/collections_controller.rb +36 -0
- data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +81 -0
- data/app/controllers/spree/api/v3/store/companies/base_controller.rb +24 -0
- data/app/controllers/spree/api/v3/store/companies/invitations_controller.rb +50 -0
- data/app/controllers/spree/api/v3/store/companies/members_controller.rb +66 -0
- data/app/controllers/spree/api/v3/store/companies/orders_controller.rb +28 -0
- data/app/controllers/spree/api/v3/store/companies_controller.rb +47 -0
- data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +90 -0
- data/app/controllers/spree/api/v3/store/countries_controller.rb +8 -6
- data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +3 -1
- data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +78 -0
- data/app/controllers/spree/api/v3/store/customer/digital_links_controller.rb +52 -0
- data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +6 -0
- data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +7 -3
- data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +3 -3
- data/app/controllers/spree/api/v3/store/customer/store_credits_controller.rb +0 -3
- data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +91 -0
- data/app/controllers/spree/api/v3/store/customers_controller.rb +26 -31
- data/app/controllers/spree/api/v3/store/data_feeds_controller.rb +11 -0
- data/app/controllers/spree/api/v3/store/data_request_downloads_controller.rb +58 -0
- data/app/controllers/spree/api/v3/store/delivery_methods_controller.rb +108 -0
- data/app/controllers/spree/api/v3/store/digital_links_controller.rb +105 -0
- data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +5 -9
- data/app/controllers/spree/api/v3/store/markets_controller.rb +4 -4
- data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +8 -9
- data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +94 -0
- data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +116 -0
- data/app/controllers/spree/api/v3/store/orders/tax_identifiers_controller.rb +46 -0
- data/app/controllers/spree/api/v3/store/orders_controller.rb +12 -15
- data/app/controllers/spree/api/v3/store/products/filters_controller.rb +10 -3
- data/app/controllers/spree/api/v3/store/products_controller.rb +25 -6
- data/app/controllers/spree/api/v3/store/resource_controller.rb +2 -0
- data/app/controllers/spree/api/v3/store/sellers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +9 -6
- data/app/controllers/spree/api/v3/store/wishlists_controller.rb +3 -3
- data/app/controllers/spree/api/v3/webhooks/fulfillments_controller.rb +88 -0
- data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +5 -2
- data/app/controllers/spree/api/v3/webhooks/payouts_controller.rb +61 -0
- data/app/models/spree/api/data_request_urls.rb +25 -0
- data/app/models/spree/api/digital_link_urls.rb +26 -0
- data/app/serializers/spree/api/v3/address_serializer.rb +17 -5
- data/app/serializers/spree/api/v3/admin/actor_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/admin/address_serializer.rb +27 -4
- data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +13 -10
- data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +15 -2
- data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/cart_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/catalog_assignment_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/admin/catalog_product_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/catalog_product_term_serializer.rb +38 -0
- data/app/serializers/spree/api/v3/admin/catalog_quantity_rule_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/catalog_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/category_serializer.rb +3 -2
- data/app/serializers/spree/api/v3/admin/channel_serializer.rb +15 -1
- data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/claim_reason_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/claim_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/admin/collection_rule_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/admin/collection_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +67 -0
- data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +69 -0
- data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +61 -0
- data/app/serializers/spree/api/v3/admin/company_invitation_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/company_membership_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/company_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/concerns/external_references_attribute.rb +33 -0
- data/app/serializers/spree/api/v3/admin/consent_record_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/admin/country_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/custom_field_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/customer_serializer.rb +23 -22
- data/app/serializers/spree/api/v3/admin/dashboard_counter_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/admin/data_request_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +66 -1
- data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/delivery_origin_group_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/delivery_profile_serializer.rb +65 -0
- data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +10 -1
- data/app/serializers/spree/api/v3/admin/delivery_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/admin/delivery_zone_member_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/delivery_zone_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/digital_asset_serializer.rb +59 -0
- data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -4
- data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/export_serializer.rb +20 -1
- data/app/serializers/spree/api/v3/admin/fee_serializer.rb +14 -0
- data/app/serializers/spree/api/v3/admin/freight_summary_line_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/freight_summary_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_item_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +31 -9
- data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +2 -3
- data/app/serializers/spree/api/v3/admin/import_serializer.rb +15 -2
- data/app/serializers/spree/api/v3/admin/integration_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +4 -4
- data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +46 -5
- data/app/serializers/spree/api/v3/admin/market_serializer.rb +5 -1
- data/app/serializers/spree/api/v3/admin/media_serializer.rb +50 -2
- data/app/serializers/spree/api/v3/admin/membership_product_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +126 -31
- data/app/serializers/spree/api/v3/admin/package_type_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +8 -2
- data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -0
- data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +41 -0
- data/app/serializers/spree/api/v3/admin/permission_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/policy_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/admin/price_list_product_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +20 -8
- data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +2 -12
- data/app/serializers/spree/api/v3/admin/price_serializer.rb +3 -0
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +54 -8
- data/app/serializers/spree/api/v3/admin/product_submission_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/product_type_custom_field_definition_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/admin/product_type_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +6 -12
- data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +17 -15
- data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +80 -0
- data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +94 -0
- data/app/serializers/spree/api/v3/admin/refund_reason_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/admin/refund_serializer.rb +6 -5
- data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +72 -0
- data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/return_reason_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/return_serializer.rb +58 -0
- data/app/serializers/spree/api/v3/admin/role_serializer.rb +24 -6
- data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_serializer.rb +68 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_status_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_submission_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/seller_serializer.rb +92 -0
- data/app/serializers/spree/api/v3/admin/seller_team_member_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +82 -0
- data/app/serializers/spree/api/v3/admin/state_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/stock_level_serializer.rb +65 -0
- data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +20 -4
- data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +116 -0
- data/app/serializers/spree/api/v3/admin/stock_receipt_item_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/stock_receipt_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +5 -5
- data/app/serializers/spree/api/v3/admin/stock_transfer_item_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/stock_transfer_serializer.rb +36 -16
- data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +42 -7
- data/app/serializers/spree/api/v3/admin/store_serializer.rb +65 -1
- data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +67 -0
- data/app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb +43 -0
- data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +49 -0
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +49 -8
- data/app/serializers/spree/api/v3/applied_promotion_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/base_serializer.rb +61 -2
- data/app/serializers/spree/api/v3/cart_serializer.rb +90 -12
- data/app/serializers/spree/api/v3/category_serializer.rb +3 -3
- data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/claim_reason_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/claim_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/collection_serializer.rb +41 -0
- data/app/serializers/spree/api/v3/company_invitation_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/company_membership_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/company_serializer.rb +33 -0
- data/app/serializers/spree/api/v3/custom_field_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/customer_serializer.rb +9 -1
- data/app/serializers/spree/api/v3/data_request_event_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/data_request_serializer.rb +40 -0
- data/app/serializers/spree/api/v3/delivery_method_serializer.rb +12 -2
- data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +34 -17
- data/app/serializers/spree/api/v3/delivery_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/delivery_zone_serializer.rb +13 -0
- data/app/serializers/spree/api/v3/digital_asset_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/digital_link_serializer.rb +6 -2
- data/app/serializers/spree/api/v3/discount_serializer.rb +21 -7
- data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/exchange_serializer.rb +61 -0
- data/app/serializers/spree/api/v3/fee_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/freight_summary_serializer.rb +38 -0
- data/app/serializers/spree/api/v3/fulfillment_serializer.rb +28 -15
- data/app/serializers/spree/api/v3/gift_card_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/import_row_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/import_serializer.rb +18 -4
- data/app/serializers/spree/api/v3/invitation_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/line_item_serializer.rb +18 -1
- data/app/serializers/spree/api/v3/market_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/{asset_serializer.rb → media_event_serializer.rb} +4 -4
- data/app/serializers/spree/api/v3/media_serializer.rb +48 -7
- data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/option_type_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/order_group_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/order_serializer.rb +58 -6
- data/app/serializers/spree/api/v3/payment_method_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/payment_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/payment_session_serializer.rb +10 -3
- data/app/serializers/spree/api/v3/payment_setup_session_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/policy_serializer.rb +7 -2
- data/app/serializers/spree/api/v3/product_filter_option_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/product_serializer.rb +42 -10
- data/app/serializers/spree/api/v3/product_type_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/purchase_order_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/refund_serializer.rb +9 -3
- data/app/serializers/spree/api/v3/return_line_item_serializer.rb +42 -0
- data/app/serializers/spree/api/v3/return_reason_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/return_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/seller/balance_serializer.rb +35 -0
- data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/seller/claim_serializer.rb +25 -0
- data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +59 -0
- data/app/serializers/spree/api/v3/seller/delivery_profile_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +35 -0
- data/app/serializers/spree/api/v3/seller/delivery_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/delivery_zone_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/seller/export_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/seller/fulfillment_item_serializer.rb +43 -0
- data/app/serializers/spree/api/v3/seller/fulfillment_serializer.rb +76 -0
- data/app/serializers/spree/api/v3/seller/import_mapping_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/seller/import_row_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/import_serializer.rb +77 -0
- data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/media_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/seller/order_serializer.rb +119 -0
- data/app/serializers/spree/api/v3/seller/package_type_serializer.rb +52 -0
- data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/seller/payout_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/seller/policy_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/seller/product_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/seller/product_submission_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/seller/product_type_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/profile_serializer.rb +77 -0
- data/app/serializers/spree/api/v3/seller/reason_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/seller/requirement_custom_field_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/seller/requirement_status_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/seller/requirement_submission_serializer.rb +33 -0
- data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/seller/return_serializer.rb +51 -0
- data/app/serializers/spree/api/v3/seller/shipping_label_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/seller/stock_level_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/tax_identifier_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/seller/team_member_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +49 -0
- data/app/serializers/spree/api/v3/seller/variant_serializer.rb +71 -0
- data/app/serializers/spree/api/v3/seller_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/shipping_label_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/{stock_item_serializer.rb → stock_level_serializer.rb} +5 -5
- data/app/serializers/spree/api/v3/stock_location_serializer.rb +11 -7
- data/app/serializers/spree/api/v3/stock_movement_serializer.rb +8 -15
- data/app/serializers/spree/api/v3/stock_receipt_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/stock_transfer_serializer.rb +6 -6
- data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/supplier_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/tax_identifier_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/tax_line_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/variant_serializer.rb +52 -2
- data/app/serializers/spree/api/v3/wishlist_item_serializer.rb +6 -6
- data/app/serializers/spree/api/v3/wishlist_serializer.rb +1 -1
- data/app/services/spree/api/v3/filters_aggregator.rb +14 -12
- data/app/services/spree/webhooks/deliver_webhook.rb +62 -26
- data/app/subscribers/spree/webhook_event_subscriber.rb +9 -5
- data/config/brakeman.ignore +1 -1
- data/config/initializers/typelizer.rb +51 -4
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +730 -22
- data/lib/spree/api/configuration.rb +19 -19
- data/lib/spree/api/dependencies.rb +174 -227
- data/lib/spree/api/engine.rb +6 -0
- data/lib/spree/api/openapi/schema_helper.rb +179 -13
- data/lib/spree/api/testing_support/v3/base.rb +45 -15
- data/lib/spree/api.rb +10 -4
- data/lib/typelizer/open_enums.rb +35 -0
- metadata +342 -27
- data/app/controllers/spree/api/v3/admin/orders/adjustments_controller.rb +0 -25
- data/app/controllers/spree/api/v3/admin/stock_items_controller.rb +0 -42
- data/app/controllers/spree/api/v3/admin/store_credit_categories_controller.rb +0 -21
- data/app/controllers/spree/api/v3/store/digitals_controller.rb +0 -38
- data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +0 -24
- data/app/serializers/spree/api/v3/admin/dashboard_analytics_serializer.rb +0 -143
- data/app/serializers/spree/api/v3/admin/reimbursement_serializer.rb +0 -15
- data/app/serializers/spree/api/v3/admin/return_authorization_serializer.rb +0 -19
- data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +0 -34
- data/app/serializers/spree/api/v3/admin/store_credit_category_serializer.rb +0 -19
- data/app/serializers/spree/api/v3/customer_return_serializer.rb +0 -17
- data/app/serializers/spree/api/v3/digital_serializer.rb +0 -17
- data/app/serializers/spree/api/v3/reimbursement_serializer.rb +0 -27
- data/app/serializers/spree/api/v3/report_serializer.rb +0 -34
- data/app/serializers/spree/api/v3/return_authorization_serializer.rb +0 -31
- data/app/serializers/spree/api/v3/return_item_serializer.rb +0 -53
- data/app/serializers/spree/api/v3/shipping_category_serializer.rb +0 -11
|
@@ -37,7 +37,15 @@ module Spree
|
|
|
37
37
|
# tags, etc.) or for specific actions (`only: :index`) when an
|
|
38
38
|
# action authorizes another way, e.g. by filtering its collection
|
|
39
39
|
# per-type (exports).
|
|
40
|
-
|
|
40
|
+
#
|
|
41
|
+
# `jwt_only: true` narrows the exemption to JWT staff: secret API
|
|
42
|
+
# keys still have their scope enforced. Use it for shell data a
|
|
43
|
+
# signed-in staff member reads to render the dashboard (the store
|
|
44
|
+
# itself) but which a scope-limited integration key has no business
|
|
45
|
+
# reading outside its granted scope.
|
|
46
|
+
def skip_scope_check!(only: nil, jwt_only: false)
|
|
47
|
+
self._scope_check_skip_jwt_only = jwt_only
|
|
48
|
+
|
|
41
49
|
if only
|
|
42
50
|
self._scope_check_skipped_actions = Array(only).map(&:to_s)
|
|
43
51
|
else
|
|
@@ -50,6 +58,7 @@ module Spree
|
|
|
50
58
|
class_attribute :_scoped_resource, instance_accessor: false
|
|
51
59
|
class_attribute :_scope_check_skipped, instance_accessor: false, default: false
|
|
52
60
|
class_attribute :_scope_check_skipped_actions, instance_accessor: false
|
|
61
|
+
class_attribute :_scope_check_skip_jwt_only, instance_accessor: false, default: false
|
|
53
62
|
before_action :authorize_api_key_scope!
|
|
54
63
|
end
|
|
55
64
|
|
|
@@ -58,9 +67,12 @@ module Spree
|
|
|
58
67
|
def authorize_api_key_scope!
|
|
59
68
|
# Endpoints explicitly exempt from the scope mechanism (auth, me, public
|
|
60
69
|
# invitation acceptance, per-type-filtered exports, etc.) opt out first,
|
|
61
|
-
# before any key resolution or enforcement.
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
# before any key resolution or enforcement. A `jwt_only` skip is the
|
|
71
|
+
# exception: it exempts JWT staff but still enforces scope for secret
|
|
72
|
+
# keys, so it must fall through to key resolution below.
|
|
73
|
+
if scope_check_skipped_for_action? && !self.class._scope_check_skip_jwt_only
|
|
74
|
+
return
|
|
75
|
+
end
|
|
64
76
|
|
|
65
77
|
# Fail CLOSED, not open. A nil `current_api_key` legitimately means a
|
|
66
78
|
# non-secret-key request (JWT admin / publishable) authorized by other
|
|
@@ -73,15 +85,25 @@ module Spree
|
|
|
73
85
|
resolve_current_api_key_for_scope_check!
|
|
74
86
|
|
|
75
87
|
unless current_api_key
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
if secret_key_request?
|
|
89
|
+
# A secret-key token was presented but did not resolve to a live key
|
|
90
|
+
# for this store — reject rather than silently skip the scope check.
|
|
91
|
+
return render_error(
|
|
92
|
+
code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:invalid_token],
|
|
93
|
+
message: 'Valid secret API key required',
|
|
94
|
+
status: :unauthorized
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# A `jwt_only` skip exempts the JWT/publishable principal we now know
|
|
99
|
+
# this is (no secret key resolved) — shell data the dashboard reads
|
|
100
|
+
# without a specific scope.
|
|
101
|
+
return if scope_check_skipped_for_action? && self.class._scope_check_skip_jwt_only
|
|
102
|
+
|
|
103
|
+
# JWT staff pass through the same key gate as secret keys: their
|
|
104
|
+
# roles' catalog keys play the role scopes play for keys, so both
|
|
105
|
+
# principals share one enforcement contract per controller.
|
|
106
|
+
return authorize_staff_permission!
|
|
85
107
|
end
|
|
86
108
|
|
|
87
109
|
resource = scoped_resource_name
|
|
@@ -101,27 +123,59 @@ module Spree
|
|
|
101
123
|
)
|
|
102
124
|
end
|
|
103
125
|
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
# The JWT half of the key gate. The staffer's expanded role keys come
|
|
127
|
+
# from Spree::Ability#permission_keys; a custom ability class without
|
|
128
|
+
# that method falls back to plain CanCanCan `authorize!` enforcement.
|
|
129
|
+
def authorize_staff_permission!
|
|
130
|
+
return unless current_user
|
|
131
|
+
|
|
132
|
+
resource = scoped_resource_name
|
|
133
|
+
# Fail closed, mirroring the secret-key path: admin controllers must
|
|
134
|
+
# declare their scope (or skip explicitly).
|
|
135
|
+
raise MissingScopedResource, self.class unless resource
|
|
136
|
+
|
|
137
|
+
ability = current_ability
|
|
138
|
+
return unless ability.respond_to?(:permission_keys)
|
|
139
|
+
|
|
140
|
+
required = "#{action_kind}_#{resource}"
|
|
141
|
+
# Scope names outside the catalog (the exports/imports `:all`
|
|
142
|
+
# fallback, host-registered types) defer to CanCanCan's `authorize!`
|
|
143
|
+
# — the caller stays gated per subject, just not by key.
|
|
144
|
+
return unless Spree.permissions.key?(required)
|
|
145
|
+
return if ability.permission_keys.include?(required)
|
|
146
|
+
|
|
147
|
+
Rails.logger.info do
|
|
148
|
+
"[Spree] Access denied: user=#{current_user.id} required=#{required} " \
|
|
149
|
+
"held=#{ability.permission_keys.join(',')}"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
render_error(
|
|
153
|
+
code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:access_denied],
|
|
154
|
+
message: "Missing permission: #{required}",
|
|
155
|
+
status: :forbidden,
|
|
156
|
+
details: { required_permission: required }
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Whether the current action opted out of scope checks via
|
|
161
|
+
# `skip_scope_check!` (whole-controller or `only:`). Independent of the
|
|
162
|
+
# `jwt_only` qualifier, which the caller weighs separately.
|
|
163
|
+
def scope_check_skipped_for_action?
|
|
164
|
+
self.class._scope_check_skipped ||
|
|
165
|
+
self.class._scope_check_skipped_actions&.include?(action_name) || false
|
|
111
166
|
end
|
|
112
167
|
|
|
113
168
|
# Resolves the request's secret API key into `@current_api_key` if a
|
|
114
169
|
# secret-key token is present and it hasn't been resolved yet, so the scope
|
|
115
|
-
# check does not depend on `authenticate_admin!` having already run.
|
|
116
|
-
# the
|
|
117
|
-
#
|
|
118
|
-
# nothing.
|
|
170
|
+
# check does not depend on `authenticate_admin!` having already run. Uses
|
|
171
|
+
# the same memoized lookup as AdminAuthentication (the key selects the
|
|
172
|
+
# request's store — see Admin::StoreContext), and is idempotent: when the
|
|
173
|
+
# key is already loaded (guard runs after auth) it does nothing.
|
|
119
174
|
def resolve_current_api_key_for_scope_check!
|
|
120
175
|
return if @current_api_key
|
|
121
176
|
return unless secret_key_request?
|
|
122
177
|
|
|
123
|
-
|
|
124
|
-
@current_api_key = key if key && key.store_id == current_store.id
|
|
178
|
+
@current_api_key = secret_api_key
|
|
125
179
|
end
|
|
126
180
|
|
|
127
181
|
# The resource name used in scope strings (`read_<name>` / `write_<name>`).
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Seller
|
|
5
|
+
# Cookie-based delivery for seller refresh tokens.
|
|
6
|
+
#
|
|
7
|
+
# Both the name and the path differ from the admin cookie, and both
|
|
8
|
+
# matter: a shared name would let one browser's admin session be
|
|
9
|
+
# redeemed on the seller panel, and the path is what stops each
|
|
10
|
+
# surface's cookie being sent to the other's endpoints. Together with
|
|
11
|
+
# the audience stamped on the token itself, a session belongs to
|
|
12
|
+
# exactly one surface.
|
|
13
|
+
#
|
|
14
|
+
# The CSRF reasoning is the admin concern's, unchanged: SameSite plus
|
|
15
|
+
# the Spree::AllowedOrigin allowlist. A seller dashboard served from an
|
|
16
|
+
# origin outside that allowlist would need its own answer.
|
|
17
|
+
module AuthCookies
|
|
18
|
+
extend ActiveSupport::Concern
|
|
19
|
+
|
|
20
|
+
# ActionController::API drops Cookies — re-include it on the auth
|
|
21
|
+
# controller only; the rest of the branch stays stateless.
|
|
22
|
+
included do
|
|
23
|
+
include ActionController::Cookies
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
REFRESH_COOKIE_NAME = :spree_seller_refresh_token
|
|
27
|
+
COOKIE_PATH = '/api/v3/seller/auth'.freeze
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def set_refresh_cookie(refresh_token)
|
|
32
|
+
cookies.signed[REFRESH_COOKIE_NAME] = base_cookie_attributes.merge(
|
|
33
|
+
value: refresh_token.token,
|
|
34
|
+
expires: refresh_token.expires_at,
|
|
35
|
+
path: COOKIE_PATH,
|
|
36
|
+
httponly: true
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def clear_refresh_cookie
|
|
41
|
+
cookies.delete(REFRESH_COOKIE_NAME, path: COOKIE_PATH)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def refresh_token_from_cookie
|
|
45
|
+
cookies.signed[REFRESH_COOKIE_NAME].presence
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Keyed off the request scheme, not the Rails env: Rails silently
|
|
49
|
+
# refuses to write a Secure cookie on a non-SSL request, so an app
|
|
50
|
+
# served over plain http would never receive one at all.
|
|
51
|
+
def base_cookie_attributes
|
|
52
|
+
if request.ssl?
|
|
53
|
+
{ secure: true, same_site: :none }
|
|
54
|
+
else
|
|
55
|
+
{ secure: false, same_site: :lax }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Seller
|
|
5
|
+
# Resolves which seller a request acts as.
|
|
6
|
+
#
|
|
7
|
+
# The inverse of the admin branch's store context: there, the store is
|
|
8
|
+
# named by a header or a key and falls back to the default. Here the
|
|
9
|
+
# seller is named by the header, membership is checked against it, and
|
|
10
|
+
# the store is *derived* from the seller — never sent, never defaulted.
|
|
11
|
+
# A request that names no seller the caller belongs to has no tenant at
|
|
12
|
+
# all, which is an error rather than a default.
|
|
13
|
+
#
|
|
14
|
+
# Included into both branch anchors (BaseController and
|
|
15
|
+
# ResourceController) — parallel chains, so a concern on one is not on
|
|
16
|
+
# the other.
|
|
17
|
+
module SellerContext
|
|
18
|
+
extend ActiveSupport::Concern
|
|
19
|
+
|
|
20
|
+
SELLER_HEADER = 'X-Spree-Seller-Id'.freeze
|
|
21
|
+
|
|
22
|
+
# Prepended, like the admin branch's store context, because the
|
|
23
|
+
# shared base chain reads the store while setting up locale and
|
|
24
|
+
# currency — before any ordinary callback runs.
|
|
25
|
+
#
|
|
26
|
+
# Resolving a seller needs the caller, so this identifies them first
|
|
27
|
+
# by calling `authenticate_user`, which is idempotent and is the same
|
|
28
|
+
# method the authentication callback runs later. That later callback
|
|
29
|
+
# remains the authority on whether the request may proceed; this only
|
|
30
|
+
# establishes the tenant early enough for the chain beneath it.
|
|
31
|
+
included do
|
|
32
|
+
prepend_before_action :set_current_seller_context
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# The seller this request acts as, or nil when the header names none
|
|
36
|
+
# the caller belongs to.
|
|
37
|
+
#
|
|
38
|
+
# @return [Spree::Seller, nil]
|
|
39
|
+
# `||=` rather than a `defined?` memo on purpose: a nil must not
|
|
40
|
+
# stick. The locale/currency chain reads `current_store` — and so
|
|
41
|
+
# this — before authentication has run, and caching that first miss
|
|
42
|
+
# would leave a controller which skips the context callback
|
|
43
|
+
# (MeController) permanently seller-less even with a valid header.
|
|
44
|
+
def current_seller
|
|
45
|
+
@current_seller ||= resolve_current_seller
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Derived from the seller, so a seller can never widen their reach by
|
|
49
|
+
# sending a store header.
|
|
50
|
+
#
|
|
51
|
+
# Falls back to the default store only when no seller resolved — such
|
|
52
|
+
# a request is already being rejected, and the chain beneath this
|
|
53
|
+
# (locale and currency setup) reads the store before the rejection
|
|
54
|
+
# renders. Nothing tenant-bearing is served through the fallback.
|
|
55
|
+
#
|
|
56
|
+
# @return [Spree::Store, nil]
|
|
57
|
+
def current_store
|
|
58
|
+
current_seller&.store || Spree::Store.default
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# The orders this seller has actually sold.
|
|
62
|
+
#
|
|
63
|
+
# A draft is either a checkout still in flight or the operator's own
|
|
64
|
+
# working document. Neither is this seller's, so neither is reachable
|
|
65
|
+
# from any endpoint on this branch — including the nested ones, which
|
|
66
|
+
# is why this lives here rather than in one controller's `scope`.
|
|
67
|
+
#
|
|
68
|
+
# @return [ActiveRecord::Relation]
|
|
69
|
+
def current_seller_orders
|
|
70
|
+
current_seller.orders.not_drafts
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def set_current_seller_context
|
|
76
|
+
# Identify the caller before resolving their seller. Safe to call
|
|
77
|
+
# here: it only populates @current_user, and the authentication
|
|
78
|
+
# callback still decides whether an unidentified request proceeds.
|
|
79
|
+
authenticate_user
|
|
80
|
+
|
|
81
|
+
# Assigned even when nil: leaving the previous request's value on a
|
|
82
|
+
# reused thread would expose another tenant to anything reading it
|
|
83
|
+
# before the rejection lands.
|
|
84
|
+
Spree::Current.store = current_store
|
|
85
|
+
|
|
86
|
+
# An unauthenticated request has no seller to resolve, and saying
|
|
87
|
+
# so is authentication's job — let it answer with a 401 rather than
|
|
88
|
+
# reporting a missing tenant.
|
|
89
|
+
return true if current_user.nil?
|
|
90
|
+
|
|
91
|
+
require_current_seller!
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def require_current_seller!
|
|
95
|
+
return true if current_seller
|
|
96
|
+
|
|
97
|
+
render_error(
|
|
98
|
+
code: ErrorHandler::ERROR_CODES[:access_denied],
|
|
99
|
+
message: Spree.t(:seller_access_denied),
|
|
100
|
+
status: :forbidden
|
|
101
|
+
)
|
|
102
|
+
false
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Membership is holding a role the seller owns — the same question
|
|
106
|
+
# the store back office asks, pointed at a different resource. A
|
|
107
|
+
# header naming a seller the caller has no role on resolves to
|
|
108
|
+
# nothing, so it reads as "no such seller" rather than "denied",
|
|
109
|
+
# which is also what stops the header being used to enumerate.
|
|
110
|
+
def resolve_current_seller
|
|
111
|
+
return nil if seller_id_header.blank?
|
|
112
|
+
return nil unless current_user.respond_to?(:sellers)
|
|
113
|
+
|
|
114
|
+
id = Spree::Seller.decode_own_prefixed_id(seller_id_header)
|
|
115
|
+
return nil if id.blank?
|
|
116
|
+
|
|
117
|
+
current_user.sellers.find_by(id: id)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def seller_id_header
|
|
121
|
+
request.headers[SELLER_HEADER]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# Authentication for the marketplace seller panel.
|
|
5
|
+
#
|
|
6
|
+
# Deliberately not a subclass or variant of AdminAuthentication: a seller
|
|
7
|
+
# holds no secret API key (keys are store-bound and grant `manage :all`),
|
|
8
|
+
# so this surface is JWT-only and the key path simply does not exist here.
|
|
9
|
+
module SellerAuthentication
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
after_action :set_no_store_cache
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
# Rejects an admin or storefront token before any seller is resolved.
|
|
19
|
+
def expected_audience
|
|
20
|
+
Spree::Api::V3::JwtAuthentication::JWT_AUDIENCE_SELLER
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Capability comes from the roles the seller holds *on this seller*.
|
|
24
|
+
# Passing the resource is what stops a store role — or the store's
|
|
25
|
+
# `admin` super-role — being read here (see Spree::Ability).
|
|
26
|
+
def ability_options
|
|
27
|
+
{ store: current_store, resource: current_seller }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def authenticate_seller!
|
|
31
|
+
require_authentication!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def set_no_store_cache
|
|
35
|
+
response.headers['Cache-Control'] = 'private, no-store'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# Storefront access checks backed by Spree::Storefront::AccessPolicy —
|
|
5
|
+
# the Store API's replacement for CanCanCan. Ownership scoping remains
|
|
6
|
+
# the primary enforcement; these helpers cover the checks a scope cannot
|
|
7
|
+
# express (guest-token access to a specific cart or order).
|
|
8
|
+
module StorefrontAccess
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
protected
|
|
12
|
+
|
|
13
|
+
def storefront_access_policy
|
|
14
|
+
@storefront_access_policy ||= Spree.storefront_access_policy_class.new(
|
|
15
|
+
user: current_user,
|
|
16
|
+
store: current_store
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @raise [Spree::Storefront::AccessDenied] when the caller can neither
|
|
21
|
+
# prove ownership nor (for carts/orders) present the guest token
|
|
22
|
+
def authorize_storefront_read!(record, token: nil)
|
|
23
|
+
return if storefront_access_policy.readable?(record, token: token)
|
|
24
|
+
|
|
25
|
+
raise Spree::Storefront::AccessDenied
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @raise [Spree::Storefront::AccessDenied] when unreadable — or, for
|
|
29
|
+
# carts and orders, already completed
|
|
30
|
+
def authorize_storefront_write!(record, token: nil)
|
|
31
|
+
return if storefront_access_policy.writable?(record, token: token)
|
|
32
|
+
|
|
33
|
+
raise Spree::Storefront::AccessDenied
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# Serving a label file, shared by every surface that offers one — the
|
|
5
|
+
# operator's, the seller's and the customer's return download.
|
|
6
|
+
#
|
|
7
|
+
# The bytes are streamed rather than redirected to storage, so the
|
|
8
|
+
# credentials that reached the action are what protects the file. The
|
|
9
|
+
# one exception is a label whose file is still being fetched from the
|
|
10
|
+
# carrier: until it lands, the carrier's own copy stands in.
|
|
11
|
+
#
|
|
12
|
+
# Deliberately carries no scope of its own — the caller has already
|
|
13
|
+
# fetched and authorized the label.
|
|
14
|
+
module StreamsShippingLabel
|
|
15
|
+
extend ActiveSupport::Concern
|
|
16
|
+
|
|
17
|
+
# @param shipping_label [Spree::ShippingLabel]
|
|
18
|
+
# @yield when there is nothing to serve, so each surface answers in
|
|
19
|
+
# its own vocabulary (a 404 for a customer, a 422 for staff)
|
|
20
|
+
def stream_shipping_label(shipping_label, &on_missing)
|
|
21
|
+
if shipping_label.file.attached?
|
|
22
|
+
send_data(
|
|
23
|
+
shipping_label.file.download,
|
|
24
|
+
filename: shipping_label.download_filename,
|
|
25
|
+
type: shipping_label.file.content_type || 'application/octet-stream',
|
|
26
|
+
disposition: 'attachment'
|
|
27
|
+
)
|
|
28
|
+
elsif shipping_label.file_pending?
|
|
29
|
+
redirect_to shipping_label.file_url, allow_other_host: true
|
|
30
|
+
else
|
|
31
|
+
on_missing.call
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# The re-check action, shared by every surface where a registration is
|
|
5
|
+
# managed: nested under a customer, under a company, and the seller's
|
|
6
|
+
# own panel.
|
|
7
|
+
#
|
|
8
|
+
# Separate from the number-changed path, which the model stamps and a
|
|
9
|
+
# subscriber queues. This is staff asking "is it still valid now" — a
|
|
10
|
+
# number verified last year may have been deregistered since — so it
|
|
11
|
+
# queues a check without the number having changed.
|
|
12
|
+
module TaxIdentifierValidation
|
|
13
|
+
extend ActiveSupport::Concern
|
|
14
|
+
|
|
15
|
+
def validate
|
|
16
|
+
authorize_resource!(@resource, :update)
|
|
17
|
+
|
|
18
|
+
# A kind can be format-checked here and still have no registry to
|
|
19
|
+
# ask — core ships exactly that for EU VAT — so the message says
|
|
20
|
+
# what is missing rather than claiming nothing is registered.
|
|
21
|
+
unless @resource.validatable?
|
|
22
|
+
render_error(
|
|
23
|
+
code: 'tax_id_not_validatable',
|
|
24
|
+
message: "No registry validator is installed for tax identifier kind '#{@resource.kind}'",
|
|
25
|
+
status: :unprocessable_content
|
|
26
|
+
)
|
|
27
|
+
return
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Marked pending before the job is queued, not after: the job can
|
|
31
|
+
# finish first, and writing 'pending' afterwards would bury the
|
|
32
|
+
# verdict it just recorded.
|
|
33
|
+
@resource.update_columns(validation_status: 'pending', validated_at: nil, updated_at: Time.current)
|
|
34
|
+
Spree::TaxIdentifiers::ValidateJob.perform_later(@resource.id)
|
|
35
|
+
|
|
36
|
+
render json: serialize_resource(@resource.reload), status: :accepted
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -10,7 +10,9 @@ module Spree
|
|
|
10
10
|
class AdminUsersController < ResourceController
|
|
11
11
|
include Spree::Api::V3::Admin::RoleGrantGuard
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
# Staff management is the escalation path — its own scope pair,
|
|
14
|
+
# grantable separately from store configuration (6.0-admin-rbac.md).
|
|
15
|
+
scoped_resource :staff
|
|
14
16
|
|
|
15
17
|
# POST is not exposed — staff are created via invitations.
|
|
16
18
|
def create
|
|
@@ -22,7 +24,7 @@ module Spree
|
|
|
22
24
|
# the account globally. The user keeps access to any other stores.
|
|
23
25
|
def destroy
|
|
24
26
|
authorize!(:destroy, @resource)
|
|
25
|
-
@resource.role_users.where(
|
|
27
|
+
@resource.role_users.where(role: current_store.roles).destroy_all
|
|
26
28
|
head :no_content
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -60,7 +62,7 @@ module Spree
|
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
def collection_includes
|
|
63
|
-
[{
|
|
65
|
+
[{ spree_roles: :resource, avatar_attachment: :blob }]
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
# Restrict to users with a role assignment on the current store.
|
|
@@ -69,10 +71,7 @@ module Spree
|
|
|
69
71
|
# host-app-defined and may contain `json` columns, which Postgres
|
|
70
72
|
# cannot compare for equality.
|
|
71
73
|
def scope
|
|
72
|
-
staff_ids = model_class.
|
|
73
|
-
joins(:role_users).
|
|
74
|
-
where(Spree::RoleUser.table_name => { resource: current_store }).
|
|
75
|
-
select(:id)
|
|
74
|
+
staff_ids = model_class.joins(:spree_roles).merge(current_store.roles).select(:id)
|
|
76
75
|
|
|
77
76
|
model_class.
|
|
78
77
|
where(id: staff_ids).
|
|
@@ -93,17 +92,15 @@ module Spree
|
|
|
93
92
|
# Reconcile the user's roles on this store to match `desired_role_ids`.
|
|
94
93
|
# Adds missing assignments and removes extras — no-op for unchanged.
|
|
95
94
|
def apply_role_ids(desired_role_ids)
|
|
96
|
-
|
|
95
|
+
store_roles = current_store.roles
|
|
96
|
+
current = @resource.role_users.where(role: store_roles).pluck(:role_id).map(&:to_s)
|
|
97
97
|
target = desired_role_ids.map(&:to_s)
|
|
98
98
|
|
|
99
|
-
(target - current).each do |
|
|
100
|
-
|
|
101
|
-
@resource.role_users.find_or_create_by!(role: role, resource: current_store) if role
|
|
99
|
+
store_roles.where(id: target - current).each do |role|
|
|
100
|
+
@resource.role_users.find_or_create_by!(role: role)
|
|
102
101
|
end
|
|
103
102
|
|
|
104
|
-
(current - target).
|
|
105
|
-
@resource.role_users.where(role_id: role_id, resource: current_store).destroy_all
|
|
106
|
-
end
|
|
103
|
+
@resource.role_users.where(role: store_roles.where(id: current - target)).destroy_all
|
|
107
104
|
end
|
|
108
105
|
end
|
|
109
106
|
end
|
|
@@ -3,6 +3,8 @@ module Spree
|
|
|
3
3
|
module V3
|
|
4
4
|
module Admin
|
|
5
5
|
class ApiKeysController < ResourceController
|
|
6
|
+
include Spree::Api::V3::Admin::RoleGrantGuard
|
|
7
|
+
|
|
6
8
|
# Dedicated scope — key management is credential-administration, not
|
|
7
9
|
# store configuration. A `write_settings` key must not be able to
|
|
8
10
|
# revoke or destroy higher-privileged keys.
|
|
@@ -13,14 +15,19 @@ module Spree
|
|
|
13
15
|
skip_scope_check! only: :current
|
|
14
16
|
|
|
15
17
|
# POST /api/v3/admin/api_keys
|
|
16
|
-
# Prevents scope amplification: a key minted via a
|
|
17
|
-
# only carry scopes that key already holds
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
# too, even if an `X-Spree-Api-Key` header was also sent.
|
|
18
|
+
# Prevents scope amplification for BOTH principals: a key minted via a
|
|
19
|
+
# secret API key can only carry scopes that key already holds, and a
|
|
20
|
+
# JWT staffer can only mint scopes within their own roles' permission
|
|
21
|
+
# keys (admin-role holders are unbounded). Scopes and role permissions
|
|
22
|
+
# share the catalog vocabulary, so both compare as expanded key sets.
|
|
22
23
|
def create
|
|
23
|
-
if scope_limited_principal?
|
|
24
|
+
if scope_limited_principal?
|
|
25
|
+
excess = requested_scopes.reject { |s| current_api_key.has_scope?(s) }
|
|
26
|
+
else
|
|
27
|
+
excess = excess_permission_keys(requested_scopes)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if excess.any?
|
|
24
31
|
return render_error(
|
|
25
32
|
code: ERROR_CODES[:access_denied],
|
|
26
33
|
message: "Cannot grant scopes beyond your own: #{excess.join(', ')}",
|
|
@@ -40,7 +47,7 @@ module Spree
|
|
|
40
47
|
@resource = find_resource
|
|
41
48
|
authorize!(:update, @resource)
|
|
42
49
|
|
|
43
|
-
@resource.revoke!(
|
|
50
|
+
@resource.revoke!(current_actor)
|
|
44
51
|
render json: serialize_resource(@resource)
|
|
45
52
|
end
|
|
46
53
|
|
|
@@ -83,7 +90,7 @@ module Spree
|
|
|
83
90
|
# happens in `before_validation :generate_token` on the model.
|
|
84
91
|
def build_resource
|
|
85
92
|
scope.new(permitted_params).tap do |key|
|
|
86
|
-
key.created_by =
|
|
93
|
+
key.created_by = current_actor
|
|
87
94
|
end
|
|
88
95
|
end
|
|
89
96
|
|
|
@@ -91,6 +98,8 @@ module Spree
|
|
|
91
98
|
# lives on Spree::ApiKey); update is limited to the human-facing `name`.
|
|
92
99
|
# Stripping them here keeps them out of mass assignment so a rename
|
|
93
100
|
# returns 200 rather than 422.
|
|
101
|
+
# No extension union: an API key's scopes and type are the authorization
|
|
102
|
+
# surface itself, not extensible resource data.
|
|
94
103
|
def permitted_params
|
|
95
104
|
return params.permit(:name) if action_name == 'update'
|
|
96
105
|
|