Class: ShopifyCLI::IdentityAuth

Inherits:
Object
  • Object
show all
Includes:
SmartProperties
Defined in:
lib/shopify_cli/identity_auth.rb,
lib/shopify_cli/identity_auth/servlet.rb,
lib/shopify_cli/identity_auth/env_auth_token.rb

Defined Under Namespace

Classes: EnvAuthToken, Error, LocalRequest, Servlet, Timeout

Constant Summary collapse

DEFAULT_PORT =
3456
REDIRECT_HOST =
"http://127.0.0.1:#{DEFAULT_PORT}"
APPLICATION_SCOPES =
{
  "shopify" => %w[https://api.shopify.com/auth/shop.admin.graphql https://api.shopify.com/auth/shop.admin.themes https://api.shopify.com/auth/partners.collaborator-relationships.readonly],
  "storefront_renderer_production" => %w[https://api.shopify.com/auth/shop.storefront-renderer.devtools],
  "partners" => %w[https://api.shopify.com/auth/partners.app.cli.access],
}
APPLICATION_CLIENT_IDS =
{
  "shopify" => "7ee65a63608843c577db8b23c4d7316ea0a01bd2f7594f8a9c06ea668c1b775c",
  "storefront_renderer_production" => "ee139b3d-5861-4d45-b387-1bc3ada7811c",
  "partners" => "271e16d403dfa18082ffb3d197bd2b5f4479c3fc32736d69296829cbb28d41a6",
}
DEV_APPLICATION_CLIENT_IDS =
{
  "shopify" => "e92482cebb9bfb9fb5a0199cc770fde3de6c8d16b798ee73e36c9d815e070e52",
  "storefront_renderer_production" => "46f603de-894f-488d-9471-5b721280ff49",
  "partners" => "df89d73339ac3c6c5f0a98d9ca93260763e384d51d6038da129889c308973978",
}
EXCHANGE_TOKENS =
APPLICATION_SCOPES.keys.map do |key|
  "#{key}_exchange_token".to_sym
end
IDENTITY_ACCESS_TOKENS =
%i[
  identity_access_token
  identity_refresh_token
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#response_queryObject

Returns the value of attribute response_query.



57
58
59
# File 'lib/shopify_cli/identity_auth.rb', line 57

def response_query
  @response_query
end

Class Method Details

.authenticated?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/shopify_cli/identity_auth.rb', line 115

def self.authenticated?
  environment_auth_token? || IDENTITY_ACCESS_TOKENS.all? { |key| ShopifyCLI::DB.exists?(key) }
end

.delete_tokens_and_keysObject



147
148
149
150
# File 'lib/shopify_cli/identity_auth.rb', line 147

def self.delete_tokens_and_keys
  ShopifyCLI::DB.del(*IDENTITY_ACCESS_TOKENS)
  ShopifyCLI::DB.del(*EXCHANGE_TOKENS)
end

.environment_auth_token?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/shopify_cli/identity_auth.rb', line 111

def self.environment_auth_token?
  !!Environment.auth_token
end

Instance Method Details

#attempt_reauthenticateObject



124
125
126
# File 'lib/shopify_cli/identity_auth.rb', line 124

def attempt_reauthenticate
  refresh_exchange_tokens || refresh_access_tokens
end

#authenticate(spinner: false) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/shopify_cli/identity_auth.rb', line 59

def authenticate(spinner: false)
  return if with_spinner(spinner, ctx.message("core.login.spinner.initiating")) do
    attempt_reauthenticate
  end

  initiate_authentication

  begin
    request_access_token(code: receive_access_code)
  rescue IdentityAuth::Timeout => e
    ctx.abort(e.message)
  end
  with_spinner(spinner, ctx.message("core.login.spinner.finalizing")) do
    request_exchange_tokens
  end
end

#code_challengeObject



128
129
130
131
132
133
# File 'lib/shopify_cli/identity_auth.rb', line 128

def code_challenge
  @code_challenge ||= Base64.urlsafe_encode64(
    OpenSSL::Digest::SHA256.digest(code_verifier),
    padding: false,
  )
end

#exchange_partners_auth_token(subject_token) ⇒ Object



102
103
104
105
106
107
108
109
# File 'lib/shopify_cli/identity_auth.rb', line 102

def exchange_partners_auth_token(subject_token)
  application = "partners"
  request_exchange_token(
    audience: client_id_for_application(application),
    scopes: APPLICATION_SCOPES[application],
    subject_token: subject_token,
  )
end

#fetch_or_auth_partners_tokenObject



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/shopify_cli/identity_auth.rb', line 88

def fetch_or_auth_partners_token
  if EnvAuthToken.partners_token_present?
    return Environment.auth_token if Environment.run_as_subprocess?
    return EnvAuthToken.fetch_exchanged_partners_token do |env_token|
      exchange_partners_auth_token(env_token)
    end
  end

  ShopifyCLI::DB.get(:partners_exchange_token) do
    IdentityAuth.new(ctx: ctx).authenticate
    ShopifyCLI::DB.get(:partners_exchange_token)
  end
end

#reauthenticateObject



119
120
121
122
# File 'lib/shopify_cli/identity_auth.rb', line 119

def reauthenticate
  return if attempt_reauthenticate
  ctx.abort(ctx.message("core.identity_auth.error.reauthenticate", ShopifyCLI::TOOL_NAME))
end

#serverObject



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/shopify_cli/identity_auth.rb', line 135

def server
  @server ||= begin
    server = WEBrick::HTTPServer.new(
      Port: DEFAULT_PORT,
      Logger: WEBrick::Log.new(File.open(File::NULL, "w")),
      AccessLog: [],
    )
    server.mount("/", Servlet, self, state_token)
    server
  end
end

#with_spinner(spinner, message, &block) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/shopify_cli/identity_auth.rb', line 76

def with_spinner(spinner, message, &block)
  result = nil
  if spinner
    CLI::UI::Spinner.spin(message) do
      result = block.call
    end
  else
    result = block.call
  end
  result
end