19
19
import com .google .android .gms .tasks .Continuation ;
20
20
import com .google .android .gms .tasks .Task ;
21
21
import com .google .android .gms .tasks .Tasks ;
22
+ import com .google .android .play .core .integrity .IntegrityManager ;
23
+ import com .google .android .play .core .integrity .IntegrityManagerFactory ;
24
+ import com .google .android .play .core .integrity .IntegrityTokenRequest ;
25
+ import com .google .android .play .core .integrity .IntegrityTokenResponse ;
22
26
import com .google .firebase .FirebaseApp ;
23
27
import com .google .firebase .appcheck .AppCheckProvider ;
24
28
import com .google .firebase .appcheck .AppCheckToken ;
@@ -33,19 +37,26 @@ public class PlayIntegrityAppCheckProvider implements AppCheckProvider {
33
37
34
38
private static final String UTF_8 = "UTF-8" ;
35
39
40
+ private final IntegrityManager integrityManager ;
36
41
private final NetworkClient networkClient ;
37
42
private final ExecutorService backgroundExecutor ;
38
43
private final RetryManager retryManager ;
39
44
40
45
public PlayIntegrityAppCheckProvider (@ NonNull FirebaseApp firebaseApp ) {
41
- this (new NetworkClient (firebaseApp ), Executors .newCachedThreadPool (), new RetryManager ());
46
+ this (
47
+ IntegrityManagerFactory .create (firebaseApp .getApplicationContext ()),
48
+ new NetworkClient (firebaseApp ),
49
+ Executors .newCachedThreadPool (),
50
+ new RetryManager ());
42
51
}
43
52
44
53
@ VisibleForTesting
45
54
PlayIntegrityAppCheckProvider (
55
+ @ NonNull IntegrityManager integrityManager ,
46
56
@ NonNull NetworkClient networkClient ,
47
57
@ NonNull ExecutorService backgroundExecutor ,
48
58
@ NonNull RetryManager retryManager ) {
59
+ this .integrityManager = integrityManager ;
49
60
this .networkClient = networkClient ;
50
61
this .backgroundExecutor = backgroundExecutor ;
51
62
this .retryManager = retryManager ;
@@ -54,24 +65,60 @@ public PlayIntegrityAppCheckProvider(@NonNull FirebaseApp firebaseApp) {
54
65
@ NonNull
55
66
@ Override
56
67
public Task <AppCheckToken > getToken () {
57
- // TODO(rosalyntan): Obtain the Play Integrity challenge nonce.
58
- ExchangePlayIntegrityTokenRequest request =
59
- new ExchangePlayIntegrityTokenRequest ("placeholder" );
60
- Task <AppCheckTokenResponse > networkTask =
68
+ return getPlayIntegrityAttestation ()
69
+ .continueWithTask (
70
+ new Continuation <IntegrityTokenResponse , Task <AppCheckTokenResponse >>() {
71
+ @ Override
72
+ public Task <AppCheckTokenResponse > then (@ NonNull Task <IntegrityTokenResponse > task ) {
73
+ if (task .isSuccessful ()) {
74
+ ExchangePlayIntegrityTokenRequest request =
75
+ new ExchangePlayIntegrityTokenRequest (task .getResult ().token ());
76
+ return Tasks .call (
77
+ backgroundExecutor ,
78
+ () ->
79
+ networkClient .exchangeAttestationForAppCheckToken (
80
+ request .toJsonString ().getBytes (UTF_8 ),
81
+ NetworkClient .PLAY_INTEGRITY ,
82
+ retryManager ));
83
+ }
84
+ return Tasks .forException (task .getException ());
85
+ }
86
+ })
87
+ .continueWithTask (
88
+ new Continuation <AppCheckTokenResponse , Task <AppCheckToken >>() {
89
+ @ Override
90
+ public Task <AppCheckToken > then (@ NonNull Task <AppCheckTokenResponse > task ) {
91
+ if (task .isSuccessful ()) {
92
+ return Tasks .forResult (
93
+ DefaultAppCheckToken .constructFromAppCheckTokenResponse (task .getResult ()));
94
+ }
95
+ // TODO: Surface more error details.
96
+ return Tasks .forException (task .getException ());
97
+ }
98
+ });
99
+ }
100
+
101
+ @ NonNull
102
+ Task <IntegrityTokenResponse > getPlayIntegrityAttestation () {
103
+ GeneratePlayIntegrityChallengeRequest generateChallengeRequest =
104
+ new GeneratePlayIntegrityChallengeRequest ();
105
+ Task <GeneratePlayIntegrityChallengeResponse > generateChallengeTask =
61
106
Tasks .call (
62
107
backgroundExecutor ,
63
108
() ->
64
- networkClient .exchangeAttestationForAppCheckToken (
65
- request .toJsonString ().getBytes (UTF_8 ),
66
- NetworkClient .PLAY_INTEGRITY ,
67
- retryManager ));
68
- return networkTask .continueWithTask (
69
- new Continuation <AppCheckTokenResponse , Task <AppCheckToken >>() {
109
+ GeneratePlayIntegrityChallengeResponse .fromJsonString (
110
+ networkClient .generatePlayIntegrityChallenge (
111
+ generateChallengeRequest .toJsonString ().getBytes (UTF_8 ), retryManager )));
112
+ return generateChallengeTask .continueWithTask (
113
+ new Continuation <GeneratePlayIntegrityChallengeResponse , Task <IntegrityTokenResponse >>() {
70
114
@ Override
71
- public Task <AppCheckToken > then (@ NonNull Task <AppCheckTokenResponse > task ) {
115
+ public Task <IntegrityTokenResponse > then (
116
+ @ NonNull Task <GeneratePlayIntegrityChallengeResponse > task ) {
72
117
if (task .isSuccessful ()) {
73
- return Tasks .forResult (
74
- DefaultAppCheckToken .constructFromAppCheckTokenResponse (task .getResult ()));
118
+ return integrityManager .requestIntegrityToken (
119
+ IntegrityTokenRequest .builder ()
120
+ .setNonce (task .getResult ().getChallenge ())
121
+ .build ());
75
122
}
76
123
// TODO: Surface more error details.
77
124
return Tasks .forException (task .getException ());
0 commit comments