Skip to content

Commit 6f61b2c

Browse files
authored
Merge pull request #3 from mirichan/master
Exposed `protected` Transaction data
2 parents 6fa69c1 + ac2abdf commit 6f61b2c

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

src/main/java/com/auth0/guardian/Guardian.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,34 @@ public Enrollment confirmEnroll(Transaction transaction, String otp)
108108

109109
return new Enrollment(transaction.getRecoveryCode());
110110
}
111+
112+
/**
113+
* Confirms an enrollment started with {@link Guardian#requestEnroll(String, EnrollmentType)}.
114+
* <p>
115+
* Use this method to confirm an enrollment transaction once the user scanned the QR code with a TOTP app (for a
116+
* transaction initiated with {@link EnrollmentType#TOTP()}) or when the user received the OTP code delivered to his
117+
* phone number by SMS (for a transaction initiated with {@link EnrollmentType#SMS(String)}).
118+
*
119+
* This overload is intended for stateless applications where {@link java.io.Serializable} is not acceptable,
120+
* avoiding the necessity of utilising poor practises to preserve {@link Transaction} between user actions.
121+
*
122+
* @param transactionToken the token associated with the transaction to confirm.
123+
* @param otp the code obtained from the TOTP app or delivered to the phone number by SMS
124+
* @throws IOException when there's a connection issue
125+
* @throws IllegalArgumentException when the transaction is not valid
126+
* @throws GuardianException when there's a Guardian specific issue (invalid otp for example)
127+
*/
128+
public void confirmEnroll(String transactionToken, String otp)
129+
throws IOException, IllegalArgumentException, GuardianException {
130+
if (transactionToken == null) {
131+
throw new IllegalArgumentException("Invalid enrollment transaction");
132+
}
133+
if (otp == null) {
134+
throw new IllegalArgumentException("Invalid OTP");
135+
}
136+
137+
apiClient
138+
.verifyOTP(transactionToken, otp)
139+
.execute();
140+
}
111141
}

src/main/java/com/auth0/guardian/Transaction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ public class Transaction implements Serializable {
4848
this.otpSecret = otpSecret;
4949
}
5050

51-
String getTransactionToken() {
51+
public String getTransactionToken() {
5252
return transactionToken;
5353
}
5454

55-
String getRecoveryCode() {
55+
public String getRecoveryCode() {
5656
return recoveryCode;
5757
}
5858

src/test/java/com/auth0/guardian/GuardianTest.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public void shouldFailConfirmationWhenTransationIsNull() throws Exception {
240240
server.emptyResponse();
241241

242242
guardian
243-
.confirmEnroll(null, OTP_CODE);
243+
.confirmEnroll((Transaction)null, OTP_CODE);
244244
}
245245

246246
@Test
@@ -264,4 +264,57 @@ public void shouldFailConfirmationWhenOtpIsNull() throws Exception {
264264
guardian
265265
.confirmEnroll(new Transaction("TRANSACTION_TOKEN", null, null), null);
266266
}
267+
268+
@Test
269+
public void shouldConfirmEnrollOverload() throws Exception {
270+
server.jsonResponse(MockServer.START_FLOW_VALID, 201);
271+
server.emptyResponse();
272+
273+
Transaction transaction = guardian
274+
.requestEnroll(ENROLLMENT_TICKET, EnrollmentType.TOTP());
275+
276+
guardian
277+
.confirmEnroll(transaction.getTransactionToken(), OTP_CODE);
278+
279+
RecordedRequest startFlowRequest = server.takeRequest();
280+
281+
assertThat(startFlowRequest, hasMethodAndPath("POST", "/api/start-flow"));
282+
assertThat(startFlowRequest, hasHeader("Content-Type", "application/json; charset=utf-8"));
283+
assertThat(startFlowRequest, hasHeader("Authorization", "Ticket id=\"ENROLLMENT_TICKET\""));
284+
285+
Map<String, Object> startFlowBody = bodyFromRequest(startFlowRequest);
286+
assertThat(startFlowBody, hasEntry("state_transport", (Object) "polling"));
287+
288+
RecordedRequest verifyOtpRequest = server.takeRequest();
289+
290+
assertThat(verifyOtpRequest, hasMethodAndPath("POST", "/api/verify-otp"));
291+
assertThat(verifyOtpRequest, hasHeader("Content-Type", "application/json; charset=utf-8"));
292+
assertThat(verifyOtpRequest, hasHeader("Authorization", "Bearer THE_TRANSACTION_TOKEN"));
293+
294+
Map<String, Object> verifyOtpBody = bodyFromRequest(verifyOtpRequest);
295+
assertThat(verifyOtpBody, hasEntry("type", (Object) "manual_input"));
296+
assertThat(verifyOtpBody, hasEntry("code", (Object) "OTP_CODE"));
297+
}
298+
299+
@Test
300+
public void shouldFailConfirmationOverloadWhenNoTokenIsProvided() throws Exception {
301+
exception.expect(IllegalArgumentException.class);
302+
exception.expectMessage("Invalid enrollment transaction");
303+
304+
server.emptyResponse();
305+
306+
guardian
307+
.confirmEnroll((String)null, OTP_CODE);
308+
}
309+
310+
@Test
311+
public void shouldFailConfirmationOverloadWhenOtpIsNull() throws Exception {
312+
exception.expect(IllegalArgumentException.class);
313+
exception.expectMessage("Invalid OTP");
314+
315+
server.emptyResponse();
316+
317+
guardian
318+
.confirmEnroll("TRANSACTION_TOKEN", null);
319+
}
267320
}

0 commit comments

Comments
 (0)