PageRenderTime 125ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/app/src/main/java/info/blockchain/wallet/datamanagers/AuthDataManager.java

https://gitlab.com/github-cloud-corporation/My-Wallet-V3-Android
Java | 219 lines | 171 code | 39 blank | 9 comment | 10 complexity | 8f0bcf6277b8b867ebfd4933f79a54e4 MD5 | raw file
  1. package info.blockchain.wallet.datamanagers;
  2. import android.support.annotation.VisibleForTesting;
  3. import info.blockchain.api.Access;
  4. import info.blockchain.wallet.access.AccessState;
  5. import info.blockchain.wallet.payload.Payload;
  6. import info.blockchain.wallet.payload.PayloadManager;
  7. import info.blockchain.wallet.rxjava.RxUtil;
  8. import info.blockchain.wallet.util.AESUtilWrapper;
  9. import info.blockchain.wallet.util.AppUtil;
  10. import info.blockchain.wallet.util.CharSequenceX;
  11. import info.blockchain.wallet.util.PrefsUtil;
  12. import org.json.JSONException;
  13. import org.json.JSONObject;
  14. import java.util.concurrent.TimeUnit;
  15. import javax.inject.Inject;
  16. import piuk.blockchain.android.di.Injector;
  17. import rx.Observable;
  18. import rx.Subscriber;
  19. import rx.android.schedulers.AndroidSchedulers;
  20. import rx.schedulers.Schedulers;
  21. public class AuthDataManager {
  22. @Inject protected PayloadManager mPayloadManager;
  23. @Inject protected PrefsUtil mPrefsUtil;
  24. @Inject protected Access mAccess;
  25. @Inject protected AppUtil mAppUtil;
  26. @Inject protected AESUtilWrapper mAESUtil;
  27. @Inject protected AccessState mAccessState;
  28. @VisibleForTesting protected int timer;
  29. public AuthDataManager() {
  30. Injector.getInstance().getAppComponent().inject(this);
  31. }
  32. public Observable<String> getEncryptedPayload(String guid, String sessionId) {
  33. return Observable.fromCallable(() -> mAccess.getEncryptedPayload(guid, sessionId))
  34. .compose(RxUtil.applySchedulers());
  35. }
  36. public Observable<String> getSessionId(String guid) {
  37. return Observable.fromCallable(() -> mAccess.getSessionId(guid))
  38. .compose(RxUtil.applySchedulers());
  39. }
  40. public Observable<Void> updatePayload(String sharedKey, String guid, CharSequenceX password) {
  41. return getUpdatePayloadObservable(sharedKey, guid, password)
  42. .compose(RxUtil.applySchedulers());
  43. }
  44. public Observable<CharSequenceX> validatePin(String pin) {
  45. return Observable.fromCallable(() -> mAccessState.validatePIN(pin))
  46. .compose(RxUtil.applySchedulers());
  47. }
  48. public Observable<Boolean> createPin(CharSequenceX password, String pin) {
  49. return Observable.fromCallable(() -> mAccessState.createPIN(password, pin))
  50. .compose(RxUtil.applySchedulers());
  51. }
  52. public Observable<Payload> createHdWallet(String password, String walletName) {
  53. return Observable.fromCallable(() -> mPayloadManager.createHDWallet(password, walletName))
  54. .compose(RxUtil.applySchedulers())
  55. .doOnNext(payload -> mAppUtil.setNewlyCreated(true));
  56. }
  57. public Observable<String> startPollingAuthStatus(String guid) {
  58. // Get session id
  59. return getSessionId(guid)
  60. // return Observable that emits ticks every two seconds, pass in Session ID
  61. .flatMap(sessionId -> Observable.interval(2, TimeUnit.SECONDS)
  62. // For each emission from the timer, try to get the payload
  63. .map(tick -> getEncryptedPayload(guid, sessionId).toBlocking().first())
  64. // If auth not required, emit payload
  65. .filter(s -> !s.equals(Access.KEY_AUTH_REQUIRED))
  66. // If error called, emit Auth Required
  67. .onErrorReturn(throwable -> Observable.just(Access.KEY_AUTH_REQUIRED).toBlocking().first())
  68. // Make sure threading is correct
  69. .compose(RxUtil.applySchedulers())
  70. // Only emit the first object
  71. .first());
  72. }
  73. private Observable<Void> getUpdatePayloadObservable(String sharedKey, String guid, CharSequenceX password) {
  74. return Observable.defer(() -> Observable.create(subscriber -> {
  75. try {
  76. mPayloadManager.initiatePayload(
  77. sharedKey,
  78. guid,
  79. password,
  80. new PayloadManager.InitiatePayloadListener() {
  81. @Override
  82. public void onInitSuccess() {
  83. mPayloadManager.setTempPassword(password);
  84. subscriber.onNext(null);
  85. subscriber.onCompleted();
  86. }
  87. @Override
  88. public void onInitPairFail() {
  89. subscriber.onError(new PairFailThrowable());
  90. }
  91. @Override
  92. public void onInitCreateFail(String s) {
  93. subscriber.onError(new CreateFailThrowable());
  94. }
  95. });
  96. } catch (Exception e) {
  97. subscriber.onError(new Throwable(e));
  98. }
  99. }));
  100. }
  101. public Observable<Integer> createCheckEmailTimer() {
  102. timer = 2 * 60;
  103. return Observable.interval(0, 1, TimeUnit.SECONDS, Schedulers.io())
  104. .observeOn(AndroidSchedulers.mainThread())
  105. .map(aLong -> timer--)
  106. .takeUntil(aLong -> timer < 0);
  107. }
  108. public void attemptDecryptPayload(CharSequenceX password, String guid, String payload, DecryptPayloadListener listener) {
  109. try {
  110. JSONObject jsonObject = new JSONObject(payload);
  111. if (jsonObject.has("payload")) {
  112. String encrypted_payload = jsonObject.getString("payload");
  113. int iterations = PayloadManager.WalletPbkdf2Iterations;
  114. if (jsonObject.has("pbkdf2_iterations")) {
  115. iterations = jsonObject.getInt("pbkdf2_iterations");
  116. }
  117. String decrypted_payload = null;
  118. try {
  119. decrypted_payload = mAESUtil.decrypt(encrypted_payload, password, iterations);
  120. } catch (Exception e) {
  121. listener.onFatalError();
  122. }
  123. if (decrypted_payload != null) {
  124. JSONObject decryptedJsonObject = new JSONObject(decrypted_payload);
  125. if (decryptedJsonObject.has("sharedKey")) {
  126. mPrefsUtil.setValue(PrefsUtil.KEY_GUID, guid);
  127. mPayloadManager.setTempPassword(password);
  128. String sharedKey = decryptedJsonObject.getString("sharedKey");
  129. mAppUtil.setSharedKey(sharedKey);
  130. updatePayload(sharedKey, guid, password)
  131. .compose(RxUtil.applySchedulers())
  132. .subscribe(new Subscriber<Void>() {
  133. @Override
  134. public void onCompleted() {
  135. mPrefsUtil.setValue(PrefsUtil.KEY_EMAIL_VERIFIED, true);
  136. listener.onSuccess();
  137. }
  138. @Override
  139. public void onError(Throwable e) {
  140. if (e instanceof CreateFailThrowable) {
  141. listener.onCreateFail();
  142. } else if (e instanceof PairFailThrowable) {
  143. listener.onPairFail();
  144. } else {
  145. listener.onFatalError();
  146. }
  147. }
  148. @Override
  149. public void onNext(Void aVoid) {
  150. // No-op
  151. }
  152. });
  153. }
  154. } else {
  155. // Decryption failed
  156. listener.onAuthFail();
  157. }
  158. }
  159. } catch (JSONException e) {
  160. listener.onFatalError();
  161. }
  162. }
  163. class PairFailThrowable extends Throwable {
  164. PairFailThrowable() {
  165. super();
  166. }
  167. }
  168. class CreateFailThrowable extends Throwable {
  169. CreateFailThrowable() {
  170. super();
  171. }
  172. }
  173. public interface DecryptPayloadListener {
  174. void onSuccess();
  175. void onPairFail();
  176. void onCreateFail();
  177. void onAuthFail();
  178. void onFatalError();
  179. }
  180. }