Bitriseで2FA認証後に複数アカウントのSandboxユーザーを扱う上で気をつけること

## 追記
執筆当時はhttps://github.com/bitrise-steplib/steps-fastlane でfastlaneのstepが公開されていることが知りませんでした。
steps-fastlaneのversion2.7.0を使用していたのでそちらのコードをみればどのようにbitrise上で扱っているかがわかります。

## Bitriseの2FA
BitriseではAppleIDに2FA(二段階認証)がかかっていたとしても[App Store Connect 2FA solved on Bitrise](https://blog.bitrise.io/app-store-connect-2fa-solved-on-bitrise)のように設定をすることで、セッションが有効な30日間は2FAをスキップすることが可能です。

ただ以下のようなSandboxユーザーを扱うケースでハマりました。

## ハマったこと

以下２つのアカウントがあるとします。

**2FAの設定をしていない**AppleID: `apple_id_not_2fa@test.com`
2FAの設定をしているAppleID: `apple_id_2fa@test.com`


**Bitrise上で紐付いているアカウントは`apple_id_2fa@test.com`とします。**

以下のような、２つのアカウントのSandboxユーザーを削除するfastlane actionを実行します。

```rb
# Fastfile
require 'spaceship'

lane :remove_sandbox_users do
  _remove_sandbox_users(username: "apple_id_not_2fa@test.com", password: "password", sandbox_user: "sandbox_not_2fa@test.com")
  _remove_sandbox_users(username: "apple_id_2fa@test.com", password: "password", sandbox_user: "sandbox_2fa@test.com")
end

private lane :_remove_sandbox_users do |options|
    Spaceship::Tunes.login(options[:username], options[:password])
    Spaceship::Tunes::SandboxTester.delete!([options[:sandbox_user]])
end
```

上記の`remove_sandbox_users`をBitrise上で実行すると、`sandbox_2fa@test.com`は削除されますが、2FAを有効にしていないアカウント側の**`sandbox_not_2fa@test.com`は削除されません**。

## 原因
Bitrise上で`apple_id_2fa@test.com`を紐付けた際に、おそらくBitriseの内部で`FASTLANE_SESSION`の設定とcookieが作成されています。
(ref: https://discuss.bitrise.io/t/two-factor-authentication-for-apple-id-itunes-connect-testflight-deploy/1180/25)


そのため2FAが設定されている`apple_id_2fa@test.com`の`FASTLANE_SESSION`が使用されたため、常に`apple_id_2fa@test.com`のログイン状態になり、`apple_id_not_2fa@test.com`上に作成したSandboxユーザーは削除されません。
(`FASTLANE_SESSION`が設定されている場合、https://github.com/fastlane/fastlane/blob/c821aa892157ad499b03dc7693877b978db9a64c/spaceship/lib/spaceship/client.rb#L431 で読み込まれます)

いくつか挙動に疑問を感じたため、以下のようなケースをローカルで実験しました。


## 実験
以下２つのファイルを利用して、Bitrise上ではなく、ローカル上で確認をしました。
またcookieは、`~/.fastlane/spaceship/**/cookie` のことを示しています。

```rb
# Fastfile
require 'spaceship'

lane: test_login do
  Spaceship::Tunes.login("apple_id_2fa@test.com", "password")
end
```



```.env
# fastlane/.env
FASTLANE_SESSION="fastlane_session value of apple_id_2fa@test.com"
```



1. `FASTLANE_SESSION=""`, cookieがない場合
2FA
<img width="449" alt="Screen Shot 2019-12-24 at 22.32.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116582/c6ace00b-9acf-68f2-4644-299ab5bc8aec.png">

2. `FASTLANE_SESSION=""`, 有効なcookieが存在する場合
2FAスキップ
<img width="384" alt="Screen Shot 2019-12-24 at 22.31.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116582/dfd9be09-6d5f-b9ee-9b0d-67e1a58632b6.png">


3. `FASTLANE_SESSION="fastlane_session value of apple_id_2fa@test.com"`, cookieがない場合
2FAスキップ
<img width="367" alt="Screen Shot 2019-12-24 at 22.30.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116582/d2e5ce41-2d34-6b23-8a1c-55b70b2a0906.png">



1以外は、2FAをスキップしてログインが成功していることがわかります。
表にまとめると以下のようになります。

|ケース|2FA Skip|
:-:|:-:
FASTLANE_SESSION="", cookieがない場合|✗
FASTLANE_SESSION=""=, 有効なcookieが存在する場合|◯
FASTLANE_SESSION="fastlane_session value of apple_id_2fa@test.com", cookieがない場合|◯



## 改善案
今回のケースの改善案として、Bitriseの`[Workflow]`→`[Env]`に移動して、対象のworkflowの`Environment Variables`に
`ENV["FASTLANE_SESSION"] = ""`
を設定します。

<img width="660" alt="Screen Shot 2019-12-24 at 23.03.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116582/383e2c1b-ef1e-0327-5c15-10d30d6abfd5.png">



これにより、Bitrise上で`2. FASTLANE_SESSION="", 有効なcookieが存在する場合`と同じ状態になるため

`apple_id_not_2fa@test.com`の場合:
`apple_id_not_2fa@test.com`で通常ログイン

`apple_id_2fa@test.com`の場合:
`apple_id_not_2fa@test.com`でcookieを利用してログイン

どちらのアカウントも問題なくログインすることができ、Sandboxユーザーの作成・削除を行えます。


## まとめ
複数のAppleID(2FAありなし)でSandboxユーザーを操作することはなかなかないと思いますが、もしこのようなことが起こった場合、`FASTLANE_SESSION`とcookieを確認してみることをおすすめします。

## 関連URL
- https://blog.bitrise.io/app-store-connect-2fa-solved-on-bitrise
- https://discuss.bitrise.io/t/two-factor-authentication-for-apple-id-itunes-connect-testflight-deploy/1180/25
- https://github.com/fastlane/fastlane/blob/master/spaceship/docs/AppStoreConnect.md#testers