7878import org .thoughtcrime .securesms .notifications .NotificationChannels ;
7979import org .thoughtcrime .securesms .permissions .Permissions ;
8080import org .thoughtcrime .securesms .push .AccountManagerFactory ;
81+ import org .thoughtcrime .securesms .registration .CaptchaActivity ;
8182import org .thoughtcrime .securesms .service .DirectoryRefreshListener ;
8283import org .thoughtcrime .securesms .service .RotateSignedPreKeyListener ;
8384import org .thoughtcrime .securesms .service .VerificationCodeParser ;
9697import org .whispersystems .libsignal .util .KeyHelper ;
9798import org .whispersystems .libsignal .util .guava .Optional ;
9899import org .whispersystems .signalservice .api .SignalServiceAccountManager ;
100+ import org .whispersystems .signalservice .api .push .exceptions .CaptchaRequiredException ;
99101import org .whispersystems .signalservice .api .push .exceptions .RateLimitException ;
100102import org .whispersystems .signalservice .api .util .PhoneNumberFormatter ;
101103import org .whispersystems .signalservice .internal .push .LockedException ;
117119public class RegistrationActivity extends BaseActionBarActivity implements VerificationCodeView .OnCodeEnteredListener {
118120
119121 private static final int PICK_COUNTRY = 1 ;
122+ private static final int CAPTCHA = 24601 ;
120123 private static final int SCENE_TRANSITION_DURATION = 250 ;
121124 private static final int DEBUG_TAP_TARGET = 8 ;
122125 private static final int DEBUG_TAP_ANNOUNCE = 4 ;
@@ -185,6 +188,16 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
185188 this .countryCode .setText (String .valueOf (data .getIntExtra ("country_code" , 1 )));
186189 setCountryDisplay (data .getStringExtra ("country_name" ));
187190 setCountryFormatter (data .getIntExtra ("country_code" , 1 ));
191+ } else if (requestCode == CAPTCHA && resultCode == RESULT_OK && data != null ) {
192+ registrationState = new RegistrationState (Optional .fromNullable (data .getStringExtra (CaptchaActivity .KEY_TOKEN )), registrationState );
193+
194+ if (data .getBooleanExtra (CaptchaActivity .KEY_IS_SMS , true )) {
195+ handleRegister ();
196+ } else {
197+ handlePhoneCallRequest ();
198+ }
199+ } else if (requestCode == CAPTCHA ) {
200+ Toast .makeText (this , R .string .RegistrationActivity_failed_to_verify_the_captcha , Toast .LENGTH_LONG ).show ();
188201 }
189202 }
190203
@@ -226,7 +239,7 @@ private void initializeResources() {
226239 this .pinForgotButton = findViewById (R .id .forgot_button );
227240 this .pinClarificationContainer = findViewById (R .id .pin_clarification_container );
228241
229- this .registrationState = new RegistrationState (RegistrationState .State .INITIAL , null , null , null );
242+ this .registrationState = new RegistrationState (RegistrationState .State .INITIAL , null , null , Optional . absent (), Optional . absent () );
230243
231244 this .countryCode .addTextChangedListener (new CountryCodeChangedListener ());
232245 this .number .addTextChangedListener (new NumberChangedListener ());
@@ -388,13 +401,14 @@ private void handleRestore(BackupUtil.BackupInfo backup) {
388401 restoreButton .setIndeterminateProgressMode (true );
389402 restoreButton .setProgress (50 );
390403
404+ final String passphrase = prompt .getText ().toString ();
405+
391406 new AsyncTask <Void , Void , BackupImportResult >() {
392407 @ Override
393408 protected BackupImportResult doInBackground (Void ... voids ) {
394409 try {
395- Context context = RegistrationActivity .this ;
396- String passphrase = prompt .getText ().toString ();
397- SQLiteDatabase database = DatabaseFactory .getBackupDatabase (context );
410+ Context context = RegistrationActivity .this ;
411+ SQLiteDatabase database = DatabaseFactory .getBackupDatabase (context );
398412
399413 FullBackupImporter .importFile (context ,
400414 AttachmentSecretProvider .getInstance (context ).getOrCreateAttachmentSecret (),
@@ -498,9 +512,9 @@ private void handleRequestVerification(@NonNull String e164number, boolean gcmSu
498512
499513 @ SuppressLint ("StaticFieldLeak" )
500514 private void requestVerificationCode (@ NonNull String e164number , boolean gcmSupported , boolean smsRetrieverSupported ) {
501- new AsyncTask <Void , Void , Pair < String , Optional < String >> > () {
515+ new AsyncTask <Void , Void , VerificationRequestResult > () {
502516 @ Override
503- protected @ Nullable Pair < String , Optional < String >> doInBackground (Void ... voids ) {
517+ protected @ NonNull VerificationRequestResult doInBackground (Void ... voids ) {
504518 try {
505519 markAsVerifying (true );
506520
@@ -515,29 +529,34 @@ private void requestVerificationCode(@NonNull String e164number, boolean gcmSupp
515529 }
516530
517531 accountManager = AccountManagerFactory .createManager (RegistrationActivity .this , e164number , password );
518- accountManager .requestSmsVerificationCode (smsRetrieverSupported );
532+ accountManager .requestSmsVerificationCode (smsRetrieverSupported , registrationState . captchaToken );
519533
520- return new Pair <> (password , fcmToken );
534+ return new VerificationRequestResult (password , fcmToken , Optional . absent () );
521535 } catch (IOException e ) {
522536 Log .w (TAG , "Error during account registration" , e );
523- return null ;
537+ return new VerificationRequestResult ( null , Optional . absent (), Optional . of ( e )) ;
524538 }
525539 }
526540
527- protected void onPostExecute (@ Nullable Pair <String , Optional <String >> result ) {
528- if (result == null ) {
541+ protected void onPostExecute (@ NonNull VerificationRequestResult result ) {
542+ if (result .exception .isPresent () && result .exception .get () instanceof CaptchaRequiredException ) {
543+ requestCaptcha (true );
544+ } else if (result .exception .isPresent ()) {
529545 Toast .makeText (RegistrationActivity .this , R .string .RegistrationActivity_unable_to_connect_to_service , Toast .LENGTH_LONG ).show ();
530546 createButton .setIndeterminateProgressMode (false );
531547 createButton .setProgress (0 );
532- return ;
548+ } else {
549+ registrationState = new RegistrationState (RegistrationState .State .VERIFYING , e164number , result .password , result .fcmToken , Optional .absent ());
550+ displayVerificationView (e164number , 64 );
533551 }
534-
535- registrationState = new RegistrationState (RegistrationState .State .VERIFYING , e164number , result .first , result .second );
536- displayVerificationView (e164number , 64 );
537552 }
538553 }.executeOnExecutor (AsyncTask .THREAD_POOL_EXECUTOR );
539554 }
540555
556+ private void requestCaptcha (boolean isSms ) {
557+ startActivityForResult (CaptchaActivity .getIntent (this , isSms ), CAPTCHA );
558+ }
559+
541560 private void handleVerificationCodeReceived (@ Nullable String code ) {
542561 List <Integer > parsedCode = convertVerificationCodeToDigits (code );
543562
@@ -693,7 +712,9 @@ private void handlePhoneCallRequest() {
693712 @ Override
694713 protected Void doInBackground (Void ... voids ) {
695714 try {
696- accountManager .requestVoiceVerificationCode (Locale .getDefault ());
715+ accountManager .requestVoiceVerificationCode (Locale .getDefault (), registrationState .captchaToken );
716+ } catch (CaptchaRequiredException e ) {
717+ requestCaptcha (false );
697718 } catch (IOException e ) {
698719 Log .w (TAG , e );
699720 }
@@ -892,7 +913,7 @@ public void onAnimationEnd(Animator animation) {
892913 @ Override
893914 public void onClick (View widget ) {
894915 displayInitialView (false );
895- registrationState = new RegistrationState (RegistrationState .State .INITIAL , null , null , null );
916+ registrationState = new RegistrationState (RegistrationState .State .INITIAL , null , null , Optional . absent (), Optional . absent () );
896917 }
897918
898919 @ Override
@@ -1157,28 +1178,51 @@ public void onClick(View v) {
11571178 }
11581179 }
11591180
1181+ private static class VerificationRequestResult {
1182+ private final String password ;
1183+ private final Optional <String > fcmToken ;
1184+ private final Optional <IOException > exception ;
1185+
1186+ private VerificationRequestResult (String password , Optional <String > fcmToken , Optional <IOException > exception ) {
1187+ this .password = password ;
1188+ this .fcmToken = fcmToken ;
1189+ this .exception = exception ;
1190+ }
1191+ }
1192+
11601193 private static class RegistrationState {
11611194 private enum State {
11621195 INITIAL , VERIFYING , CHECKING , PIN
11631196 }
11641197
1165- private final State state ;
1166- private final String e164number ;
1167- private final String password ;
1198+ private final State state ;
1199+ private final String e164number ;
1200+ private final String password ;
11681201 private final Optional <String > gcmToken ;
1169-
1170- RegistrationState (State state , String e164number , String password , Optional <String > gcmToken ) {
1171- this .state = state ;
1172- this .e164number = e164number ;
1173- this .password = password ;
1174- this .gcmToken = gcmToken ;
1202+ private final Optional <String > captchaToken ;
1203+
1204+ RegistrationState (State state , String e164number , String password , Optional <String > gcmToken , Optional <String > captchaToken ) {
1205+ this .state = state ;
1206+ this .e164number = e164number ;
1207+ this .password = password ;
1208+ this .gcmToken = gcmToken ;
1209+ this .captchaToken = captchaToken ;
11751210 }
11761211
11771212 RegistrationState (State state , RegistrationState previous ) {
1178- this .state = state ;
1179- this .e164number = previous .e164number ;
1180- this .password = previous .password ;
1181- this .gcmToken = previous .gcmToken ;
1213+ this .state = state ;
1214+ this .e164number = previous .e164number ;
1215+ this .password = previous .password ;
1216+ this .gcmToken = previous .gcmToken ;
1217+ this .captchaToken = previous .captchaToken ;
1218+ }
1219+
1220+ RegistrationState (Optional <String > captchaToken , RegistrationState previous ) {
1221+ this .state = previous .state ;
1222+ this .e164number = previous .e164number ;
1223+ this .password = previous .password ;
1224+ this .gcmToken = previous .gcmToken ;
1225+ this .captchaToken = captchaToken ;
11821226 }
11831227 }
11841228
0 commit comments