New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[supply] added support for refresh tokens as an authentication method #16414
base: master
Are you sure you want to change the base?
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
@googlebot I signed it! |
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
Nice. Is |
I named it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is super cool! I wasn’t able to get this to work tonight. I got an error of [!] Google Api Error: forbidden: The caller does not have permission - The caller does not have permission
. So that is probably on me somehow but I’m not sure exactly what yet. But I did leave some questions and requested some changes 😊
Thanks for all the work on this!
supply/lib/supply/options.rb
Outdated
@@ -116,6 +117,35 @@ def self.available_options | |||
UI.user_error!("Could not parse service account json JSON::ParseError") | |||
end | |||
end), | |||
FastlaneCore::ConfigItem.new(key: :json_token, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it make sense to call this refresh_token
. json_token
is a bit to similar to json_key
and I think it would cause some confusion 😊
supply/lib/supply/options.rb
Outdated
UI.user_error!("Could not find refresh token json file at path '#{File.expand_path(value)}'") unless File.exist?(File.expand_path(value)) | ||
UI.user_error!("'#{value}' doesn't seem to be a JSON file") unless FastlaneCore::Helper.json_file?(File.expand_path(value)) | ||
end), | ||
FastlaneCore::ConfigItem.new(key: :json_token_data, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this be refresh_token_data
supply/lib/supply/options.rb
Outdated
optional: true, | ||
description: "The path to a file containing refresh token JSON, used to authenticate with Google", | ||
code_gen_sensitive: true, | ||
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:json_token_file), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should look for same name as the option so refresh_token
supply/lib/supply/options.rb
Outdated
optional: true, | ||
description: "The raw refresh token JSON data used to authenticate with Google", | ||
code_gen_sensitive: true, | ||
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:json_token_data_raw), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this refresh_token_data
@@ -132,6 +132,14 @@ def json_key_data_raw(*args, &block) | |||
setter(:json_key_data_raw, *args, &block) | |||
end | |||
|
|||
def json_token_file(*args, &block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refresh_token
setter(:json_token_file, *args, &block) | ||
end | ||
|
||
def json_token_data_raw(*args, &block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refresh_token_data
if params[:json_token] || params[:json_token_data] | ||
auth_client = Google::Auth::UserRefreshCredentials.make_creds(json_key_io: service_account_json, scope: self.class::SCOPE) | ||
else | ||
auth_client = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: service_account_json, scope: self.class::SCOPE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is now failing for with NoMethodError: [!] undefined method
gsub' for nil:NilClass `. Did this break for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, I'd accidentally caused service_account_authentication
to return nil
when using a json key. Should be fixed now.
Renamed all instances of |
@moly Thanks for making those changes! Do you have any idea what could be causing my permission issue I mentioned above? 😇 I’m stumped lol |
@joshdholtz does your Google account have the right permissions for the android project you're using? It might need to have the "release manager" role or higher. I'll check my setup tomorrow and provide better step by step instructions. |
@joshdholtz I set up a new app today and couldn't reproduce your permission issue. Based on the error message, the only things I could think of is that either the google account you're using doesn't have the right permissions for the play store app you're targeting, or you didn't allow access to the api project on the oauth consent screen correctly. Here's the steps I used, my google account is the owner of the play store app.
|
Refactored a little to fix some failing tests |
Checklist
bundle exec rspec
from the root directory to see all new and existing tests passbundle exec rubocop -a
to ensure the code style is validMotivation and Context
Resolves issue #16352. In some corporate setups the play store page is not owned/managed internally, which can make it difficult to get access to the service account. Adding support for alternative authentication methods would make fastlane more useful in these situations.
Description
Adds two new parameters to the supply action,
json_token
andjson_token_data
. The former allows the user to provide a path to a json file containing the refresh token data, while the latter allows specifying the raw refresh token string directly. If either of these parameters are present, the supply client will useGoogle::Auth::UserRefreshCredentials.make_creds()
to authenticate with the play store api.Testing Steps
Generate a refresh token using the steps here: https://developers.google.com/android-publisher/authorization#generating_a_refresh_token
Create a json file with the following format:
Run:
bundle exec fastlane supply --json-token /path/to/json
You can also specify the parameter using the
SUPPLY_JSON_TOKEN
environment variable or by settingjson_token_file
in your AppFile.