Class: OmniAuth::Strategies::Shopify
- Inherits:
-
Object
- Object
- OmniAuth::Strategies::Shopify
- Includes:
- OmniAuth::Strategy
- Defined in:
- lib/omniauth/strategies/shopify.rb
Overview
Authentication strategy for connecting with APIs constructed using the [OAuth 2.0 Specification](tools.ietf.org/html/draft-ietf-oauth-v2-10). You must generally register your application with the provider and utilize an application id and secret in order to authenticate using OAuth 2.0.
Defined Under Namespace
Classes: CallbackError
Constant Summary collapse
- DEFAULT_SCOPE =
Available scopes: content themes products customers orders script_tags shipping read_* or write_*
'read_products'
- SCOPE_DELIMITER =
','
- MINUTE =
60
- CODE_EXPIRES_AFTER =
10 * MINUTE
Instance Attribute Summary collapse
-
#access_token ⇒ Object
Returns the value of attribute access_token.
Class Method Summary collapse
- .encoded_params_for_signature(params) ⇒ Object
- .hmac_sign(encoded_params, secret) ⇒ Object
- .inherited(subclass) ⇒ Object
Instance Method Summary collapse
- #authorize_params ⇒ Object
- #callback_phase ⇒ Object
- #callback_url ⇒ Object
- #client ⇒ Object
- #fix_https ⇒ Object
- #normalized_scopes(scopes) ⇒ Object
- #request_phase ⇒ Object
- #setup_phase ⇒ Object
- #token_params ⇒ Object
- #valid_permissions?(token) ⇒ Boolean
- #valid_signature? ⇒ Boolean
- #valid_site? ⇒ Boolean
Instance Attribute Details
#access_token ⇒ Object
Returns the value of attribute access_token.
69 70 71 |
# File 'lib/omniauth/strategies/shopify.rb', line 69 def access_token @access_token end |
Class Method Details
.encoded_params_for_signature(params) ⇒ Object
156 157 158 159 160 161 |
# File 'lib/omniauth/strategies/shopify.rb', line 156 def self.encoded_params_for_signature(params) params = params.dup params.delete('hmac') params.delete('signature') # deprecated signature Rack::Utils.build_query(params.sort) end |
.hmac_sign(encoded_params, secret) ⇒ Object
163 164 165 |
# File 'lib/omniauth/strategies/shopify.rb', line 163 def self.hmac_sign(encoded_params, secret) OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, secret, encoded_params) end |
.inherited(subclass) ⇒ Object
18 19 20 |
# File 'lib/omniauth/strategies/shopify.rb', line 18 def self.inherited(subclass) OmniAuth::Strategy.included(subclass) end |
Instance Method Details
#authorize_params ⇒ Object
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/omniauth/strategies/shopify.rb', line 220 def .[:state] = SecureRandom.hex(24) if OmniAuth.config.test_mode @env ||= {} @env["rack.session"] ||= {} end params = . .merge(("authorize")) .merge() session["omniauth.pkce.verifier"] = .pkce_verifier if .pkce session["omniauth.state"] = params[:state] oauth_session["omniauth.state"] = params[:state] params[:scope] = normalized_scopes(params[:scope] || DEFAULT_SCOPE).join(SCOPE_DELIMITER) params[:grant_options] = ['per-user'] if [:per_user_permissions] params end |
#callback_phase ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/omniauth/strategies/shopify.rb', line 193 def callback_phase return fail!(:invalid_site, CallbackError.new(:invalid_site, "OAuth endpoint is not a myshopify site.")) unless valid_site? return fail!(:invalid_signature, CallbackError.new(:invalid_signature, "Signature does not match, it may have been tampered with.")) unless valid_signature? token = build_access_token unless (token) return fail!(:invalid_permissions, CallbackError.new(:invalid_permissions, "Requested API access mode does not match.")) end error = request.params["error_reason"] || request.params["error"] if !.provider_ignores_state && (request.params["state"].to_s.empty? || request.params["state"] != fetch_and_delete_omniauth_state) fail!(:csrf_detected, CallbackError.new(:csrf_detected, "CSRF detected")) elsif error fail!(error, CallbackError.new(request.params["error"], request.params["error_description"] || request.params["error_reason"], request.params["error_uri"])) else self.access_token = build_access_token self.access_token = access_token.refresh! if access_token.expired? super end rescue ::OAuth2::Error, CallbackError => e fail!(:invalid_credentials, e) rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e fail!(:timeout, e) rescue ::SocketError => e fail!(:failed_to_connect, e) end |
#callback_url ⇒ Object
242 243 244 |
# File 'lib/omniauth/strategies/shopify.rb', line 242 def callback_url [:callback_url] || full_host + script_name + callback_path end |
#client ⇒ Object
114 115 116 |
# File 'lib/omniauth/strategies/shopify.rb', line 114 def client ::OAuth2::Client.new(.client_id, .client_secret, deep_symbolize(.)) end |
#fix_https ⇒ Object
176 177 178 |
# File 'lib/omniauth/strategies/shopify.rb', line 176 def fix_https [:client_options][:site] = [:client_options][:site].gsub(/\Ahttp\:/, 'https:') end |
#normalized_scopes(scopes) ⇒ Object
150 151 152 153 154 |
# File 'lib/omniauth/strategies/shopify.rb', line 150 def normalized_scopes(scopes) scope_list = scopes.to_s.split(SCOPE_DELIMITER).map(&:strip).reject(&:empty?).uniq ignore_scopes = scope_list.map { |scope| scope =~ /\A(unauthenticated_)?write_(.*)\z/ && "#{$1}read_#{$2}" }.compact scope_list - ignore_scopes end |
#request_phase ⇒ Object
185 186 187 188 189 190 191 |
# File 'lib/omniauth/strategies/shopify.rb', line 185 def request_phase if valid_site? redirect client.auth_code.({:redirect_uri => callback_url}.merge()) else fail!(:invalid_site) end end |
#setup_phase ⇒ Object
180 181 182 183 |
# File 'lib/omniauth/strategies/shopify.rb', line 180 def setup_phase super fix_https end |
#token_params ⇒ Object
126 127 128 |
# File 'lib/omniauth/strategies/shopify.rb', line 126 def token_params .token_params.merge(("token")).merge(pkce_token_params) end |
#valid_permissions?(token) ⇒ Boolean
167 168 169 170 171 172 173 174 |
# File 'lib/omniauth/strategies/shopify.rb', line 167 def (token) return false unless token return true if [:per_user_permissions] && token['associated_user'] return true if ![:per_user_permissions] && !token['associated_user'] false end |
#valid_signature? ⇒ Boolean
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/omniauth/strategies/shopify.rb', line 134 def valid_signature? return false unless request.POST.empty? params = request.GET signature = params['hmac'] = params['timestamp'] return false unless signature && return false unless .to_i > Time.now.to_i - CODE_EXPIRES_AFTER new_secret = .client_secret old_secret = .old_client_secret validate_signature(new_secret) || (old_secret && validate_signature(old_secret)) end |
#valid_site? ⇒ Boolean
130 131 132 |
# File 'lib/omniauth/strategies/shopify.rb', line 130 def valid_site? !!(/\A(https|http)\:\/\/[a-zA-Z0-9][a-zA-Z0-9\-]*\.#{Regexp.quote([:myshopify_domain])}[\/]?\z/ =~ [:client_options][:site]) end |