Skip to content

Commit

Permalink
feat: Changed Android billing to authentication by service account.
Browse files Browse the repository at this point in the history
  • Loading branch information
mathrunet committed Feb 14, 2024
1 parent 07f123f commit be5db12
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 36 deletions.
42 changes: 23 additions & 19 deletions packages/katana_cli/lib/action/purchase/purchase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ class PurchaseCliAction extends CliCommand with CliActionMixin {
final purchase = context.yaml.getAsMap("purchase");
final googlePlay = purchase.getAsMap("google_play");
final appStore = purchase.getAsMap("app_store");
final googlePlayClientId = googlePlay.get("oauth_client_id", "");
final googlePlayClientSecret = googlePlay.get("oauth_client_secret", "");
final googlePlayRefreshToken = googlePlay.get("refresh_token", "");
final googlePlayPubsubTopic = googlePlay.get("pubsub_topic", "");
final appStoreSharedSecret = appStore.get("shared_secret", "");
final firebase = context.yaml.getAsMap("firebase");
Expand All @@ -55,17 +52,29 @@ class PurchaseCliAction extends CliCommand with CliActionMixin {
final region = function.get("region", "");
final enableGooglePlay = googlePlay.get("enable", false);
final enableAppStore = appStore.get("enable", false);
late final String androidServiceAccountEmail;
late final String androidServiceAccountPrivateKey;
if (enableGooglePlay) {
if (googlePlayClientId.isEmpty || googlePlayClientSecret.isEmpty) {
final serviceAccountFile = await find(
Directory("android"),
RegExp("([a-z0-9_-]+).json"),
recursive: false,
);
if (serviceAccountFile == null) {
error(
"The item [purchase]->[google_play]->[oauth_client_id] or [purchase]->[google_play]->[oauth_client_secret] is empty. Please set it.",
"Json for service account not found, please refer to https://mathru.notion.site/Google-Play-Developer-df655aff2dfb49988b82feb7aae3c61b to set it up. サービスアカウント用のJsonが見つかりません。https://mathru.notion.site/Google-Play-Developer-df655aff2dfb49988b82feb7aae3c61b を参考に設定してください。",
);
return;
}
if (googlePlayRefreshToken.isEmpty) {
final serviceAccountMap =
(await serviceAccountFile.readAsString()).toJsonMap();
androidServiceAccountEmail = serviceAccountMap.get("client_email", "");
androidServiceAccountPrivateKey =
serviceAccountMap.get("private_key", "");
if (androidServiceAccountPrivateKey.isEmpty ||
androidServiceAccountEmail.isEmpty) {
error(
"The item [purchase]->[google_play]->[refresh_token] is empty. Please set it."
"After entering [purchase]->[google_play]->[oauth_client_id] and [purchase]->[google_play]->[oauth_client_secret], run `katana store android_token and run `katana store android_token` to get a refresh token.",
"Json for service account is broken, please refer to https://mathru.notion.site/Google-Play-Developer-df655aff2dfb49988b82feb7aae3c61b to set it up. サービスアカウント用のJsonが壊れています。https://mathru.notion.site/Google-Play-Developer-df655aff2dfb49988b を参考に設定してください。",
);
return;
}
Expand Down Expand Up @@ -211,8 +220,8 @@ class PurchaseCliAction extends CliCommand with CliActionMixin {
),
);
}
if (manifest.first.attributes
.any((p0) => p0.name.toString() != "xmlns:tools")) {
if (!manifest.first.attributes
.any((p0) => p0.name.toString() == "xmlns:tools")) {
manifest.first.attributes.add(
XmlAttribute(
XmlName("xmlns:tools"),
Expand Down Expand Up @@ -260,12 +269,6 @@ class PurchaseCliAction extends CliCommand with CliActionMixin {
label("Add firebase functions");
final functions = Fuctions();
await functions.load();
if (!functions.functions.any((e) => e.startsWith("androidAuthCode"))) {
functions.functions.add("androidAuthCode()");
}
if (!functions.functions.any((e) => e.startsWith("androidToken"))) {
functions.functions.add("androidToken()");
}
if (enableAppStore) {
if (!functions.functions
.any((e) => e.startsWith("consumableVerifyIOS"))) {
Expand Down Expand Up @@ -309,9 +312,10 @@ class PurchaseCliAction extends CliCommand with CliActionMixin {
await env.load();
env["PURCHASE_SUBSCRIPTIONPATH"] = "plugins/iap/subscription";
if (enableGooglePlay) {
env["PURCHASE_ANDROID_CLIENTID"] = googlePlayClientId;
env["PURCHASE_ANDROID_CLIENTSECRET"] = googlePlayClientSecret;
env["PURCHASE_ANDROID_REFRESHTOKEN"] = googlePlayRefreshToken;
env["PURCHASE_ANDROID_SERVICEACCOUNT_EMAIL"] =
androidServiceAccountEmail;
env["PURCHASE_ANDROID_SERVICEACCOUNT_PRIVATE_KEY"] =
androidServiceAccountPrivateKey;
}
if (enableAppStore) {
env["PURCHASE_IOS_SHAREDSECRET"] = appStoreSharedSecret;
Expand Down
1 change: 1 addition & 0 deletions packages/katana_cli/lib/command/store/android_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ part of "store.dart";
/// Obtain a refresh token for store billing on Google Play.
///
/// GooglePlayでストア課金を行うためのリフレッシュトークンを取得します。
@Deprecated("サービスアカウントを使用する方法に変更されました。")
class StoreAndroidTokenCliCommand extends CliCommand {
/// Obtain a refresh token for store billing on Google Play.
///
Expand Down
1 change: 0 additions & 1 deletion packages/katana_cli/lib/command/store/store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class StoreCliCommand extends CliCommandGroup {
@override
Map<String, CliCommand> get commands => const {
"screenshot": StoreScreenshotCliCommand(),
"android_token": StoreAndroidTokenCliCommand(),
"build": StoreAndroidBuildCliCommand(),
};
}
23 changes: 8 additions & 15 deletions packages/katana_cli/lib/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -537,31 +537,24 @@ purchase:
# Configure settings for Google Play billing.
# Follow the steps below to configure the settings.
# 1. Obtain the OAuth client ID and client secret based on the URL below.
# 1. Create a service account with permissions to GooglePlayConsole based on the URL below.
# https://mathru.notion.site/Android-1d4a60948a1446d7a82c010d96417a3d?pvs=4
# ※ You need to create an OAuth consent screen. Please create it from the following URL.
# https://console.cloud.google.com/apis/credentials/consent
# 2. Set `enable` to `true` and enter the values you obtained for `oauth_client_id` and `oauth_client_secret`.
# 3. Run `katana store android_token` to get a refresh token.
# 4. Enter the obtained refresh token in the `refresh_token` field.
# 5. Run `katana apply` to deploy the app and server.
# 6. Set the topic ID for notification to `pubsub_topic`.
# 2. Set `enable` to `true`.
# 3. Set the topic ID for the notification to `pubsub_topic`.
# 4. Run `katana apply` to deploy the app and server.
# GooglePlayの課金を行う場合の設定を行います。
# 下記の手順で設定を行います。
# 1. 下記URLを元にOAuthのクライアントIDとクライアントシークレットを取得します
# 1. 下記URLを元にGooglePlayConsoleに権限があるサービスアカウントを作成します
# https://mathru.notion.site/Android-1d4a60948a1446d7a82c010d96417a3d?pvs=4
# ※OAuthの同意画面を作成する必要があります。下記のURLから作成してください。
# https://console.cloud.google.com/apis/credentials/consent
# 2. `enable`を`true`にし、`oauth_client_id`と`oauth_client_secret`に取得した値を入力します。
# 3. `katana store android_token`を実行しリフレッシュトークンを取得します。
# 4. 取得したリフレッシュトークンを`refresh_token`に入力します。
# 5. `katana apply`を実行しアプリとサーバーのデプロイを行います。
# 6. 通知用のトピックIDを`pubsub_topic`に設定します。
# 2. `enable`を`true`にします。
# 3. 通知用のトピックIDを`pubsub_topic`に設定します。
# 4. `katana apply`を実行しアプリとサーバーのデプロイを行います。
google_play:
enable: false
oauth_client_id:
oauth_client_secret:
refresh_token:
pubsub_topic: purchasing
# Configure settings for AppStore billing.
Expand Down
2 changes: 1 addition & 1 deletion packages/katana_cli/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ packages:
path: "../katana"
relative: true
source: path
version: "2.11.0"
version: "2.12.1"
lints:
dependency: transitive
description:
Expand Down

0 comments on commit be5db12

Please sign in to comment.