Skip to content

Commit 28488a5

Browse files
Merge pull request #68 from privacyidea/67-update-poll-transaction-function
67 update poll transaction function
2 parents f590cbc + 5f48ebd commit 28488a5

6 files changed

Lines changed: 77 additions & 22 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2024 NetKnights GmbH - lukas.matusiewicz@netknights.it
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License here:
7+
* <a href="http://www.apache.org/licenses/LICENSE-2.0">License</a>
8+
* <p>
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package org.privacyidea;
16+
17+
public enum ChallengeStatus
18+
{
19+
accept, declined, pending, none
20+
}

src/main/java/org/privacyidea/JSONParser.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ public PIResponse parsePIResponse(String serverResponse)
129129
if (result != null)
130130
{
131131
String r = getString(result, AUTHENTICATION);
132-
for (AuthenticationStatus en : AuthenticationStatus.values())
132+
for (AuthenticationStatus as: AuthenticationStatus.values())
133133
{
134-
if (en.toString().equals(r))
134+
if (as.toString().equals(r))
135135
{
136-
response.authentication = en;
136+
response.authentication = as;
137137
}
138138
}
139139
response.status = getBoolean(result, STATUS);
@@ -174,6 +174,15 @@ else if ("interactive".equals(modeFromResponse))
174174
response.type = getString(detail, TYPE);
175175
response.otpLength = getInt(detail, OTPLEN);
176176

177+
String r = getString(detail, CHALLENGE_STATUS);
178+
for (ChallengeStatus cs: ChallengeStatus.values())
179+
{
180+
if (cs.toString().equals(r))
181+
{
182+
response.challengeStatus = cs;
183+
}
184+
}
185+
177186
JsonArray arrMessages = detail.getAsJsonArray(MESSAGES);
178187
if (arrMessages != null)
179188
{

src/main/java/org/privacyidea/PIConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ private PIConstants()
5050
public static final String PASSWORD = "password";
5151
public static final String PASS = "pass";
5252
public static final String SERIAL = "serial";
53+
public static final String CHALLENGE_STATUS = "challenge_status";
5354
public static final String TYPE = "type";
5455
public static final String TRANSACTION_ID = "transaction_id";
5556
public static final String REALM = "realm";

src/main/java/org/privacyidea/PIResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class PIResponse
3636
public List<Challenge> multiChallenge = new ArrayList<>();
3737
public String transactionID = "";
3838
public String serial = "";
39+
public ChallengeStatus challengeStatus = ChallengeStatus.none;
3940
public String image = "";
4041
public int id = 0;
4142
public String jsonRPCVersion = "";

src/main/java/org/privacyidea/PrivacyIDEA.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,17 @@ public PIResponse triggerChallenges(String username, Map<String, String> headers
229229
* Poll for status of the given transaction ID once.
230230
*
231231
* @param transactionID transaction ID to poll for
232-
* @return the status value, true or false
232+
* @return the challenge status or "ChallengeStatus.none" if error
233233
*/
234-
public boolean pollTransaction(String transactionID)
234+
public ChallengeStatus pollTransaction(String transactionID)
235235
{
236236
Objects.requireNonNull(transactionID, "TransactionID is required!");
237237

238238
Map<String, String> params = new LinkedHashMap<>();
239239
params.put(TRANSACTION_ID, transactionID);
240240
String response = runRequestAsync(ENDPOINT_POLLTRANSACTION, params, Collections.emptyMap(), false, GET);
241241
PIResponse piresponse = this.parser.parsePIResponse(response);
242-
return piresponse.value;
242+
return piresponse.challengeStatus;
243243
}
244244

245245
/**

src/test/java/org/privacyidea/TestPollTransaction.java

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.List;
2020
import java.util.concurrent.TimeUnit;
21+
22+
import org.jetbrains.annotations.NotNull;
2123
import org.junit.After;
2224
import org.junit.Before;
2325
import org.junit.Test;
@@ -111,19 +113,27 @@ public void testPushSynchronous() throws InterruptedException
111113

112114
assertEquals(2, initialResponse.messages.size());
113115

114-
// Set the server up to respond to the polling requests twice with false
115-
setPollTransactionResponse(false, 2);
116+
// Set the server up to respond to the polling requests twice with "pending"
117+
setPollTransactionResponse(ChallengeStatus.pending, 2);
116118

117-
// Polling is controlled by the code using the sdk
119+
// Polling is controlled by the code using the java-client
118120
for (int i = 0; i < 2; i++)
119121
{
120-
assertFalse(privacyIDEA.pollTransaction(initialResponse.transactionID));
122+
assertEquals(privacyIDEA.pollTransaction(initialResponse.transactionID), ChallengeStatus.pending);
121123
Thread.sleep(500);
122124
}
123125

124-
// Set the server to respond with true
125-
setPollTransactionResponse(true, 1);
126-
assertTrue(privacyIDEA.pollTransaction(initialResponse.transactionID));
126+
// Set the server to respond with "declined"
127+
setPollTransactionResponse(ChallengeStatus.declined, 1);
128+
assertEquals(privacyIDEA.pollTransaction(initialResponse.transactionID), ChallengeStatus.declined);
129+
130+
// Set the server to respond with "accept"
131+
setPollTransactionResponse(ChallengeStatus.accept, 1);
132+
assertEquals(privacyIDEA.pollTransaction(initialResponse.transactionID), ChallengeStatus.accept);
133+
134+
// Set the server to respond with "none" by not including or invalid challenge_status parameter
135+
setPollTransactionResponse(ChallengeStatus.none, 1);
136+
assertEquals(privacyIDEA.pollTransaction(initialResponse.transactionID), ChallengeStatus.none);
127137

128138
// Now the transaction has to be finalized manually
129139
setFinalizationResponse(initialResponse.transactionID);
@@ -148,25 +158,39 @@ private void setFinalizationResponse(String transactionID)
148158
.withBody(Utils.foundMatchingChallenge()));
149159
}
150160

151-
private void setPollTransactionResponse(boolean value, int times)
161+
private void setPollTransactionResponse(ChallengeStatus challengeStatus, int times)
152162
{
153-
String val = value ? "true" : "false";
163+
String challengeStatusParameter = getChallengeStatusParameter(challengeStatus);
154164
mockServer.when(HttpRequest.request()
155165
.withMethod("GET")
156166
.withPath("/validate/polltransaction")
157167
.withQueryStringParameter("transaction_id", "02659936574063359702"), Times.exactly(times))
158168
.respond(HttpResponse.response()
159-
.withBody("{\n" + " \"id\": 1,\n" + " \"jsonrpc\": \"2.0\",\n" +
160-
" \"result\": {\n" + " \"status\": true,\n" +
161-
" \"value\": " + val + "\n" + " },\n" +
162-
" \"time\": 1589446811.1909237,\n" +
163-
" \"version\": \"privacyIDEA 3.2.1\",\n" +
164-
" \"versionnumber\": \"3.2.1\",\n" +
165-
" \"signature\": \"rsa_sha256_pss:\"\n" + "}")
169+
.withBody("{\n\"id\": 1,\n\"jsonrpc\": \"2.0\",\n" + challengeStatusParameter +
170+
"\"result\": {\n\"status\": true\n},\n\"time\": 1589446811.1909237,\n\"version\": \"privacyIDEA 3.2.1\",\n" +
171+
"\"versionnumber\": \"3.2.1\",\n\"signature\": \"rsa_sha256_pss:\"\n}")
166172
.withDelay(TimeUnit.MILLISECONDS, 50));
167173
}
168174

175+
private static @NotNull String getChallengeStatusParameter(ChallengeStatus challengeStatus)
176+
{
177+
String challengeStatusParameter = "";
178+
if (challengeStatus == ChallengeStatus.accept)
179+
{
180+
challengeStatusParameter = "\"detail\": {\n\"challenge_status\": \"accept\"\n},\n";
181+
}
182+
else if (challengeStatus == ChallengeStatus.declined)
183+
{
184+
challengeStatusParameter = "\"detail\": {\n\"challenge_status\": \"declined\"\n},\n";
169185

186+
}
187+
else if (challengeStatus == ChallengeStatus.pending)
188+
{
189+
challengeStatusParameter = "\"detail\": {\n\"challenge_status\": \"pending\"\n},\n";
190+
}
191+
return challengeStatusParameter;
192+
}
193+
170194
@After
171195
public void tearDown()
172196
{

0 commit comments

Comments
 (0)