Skip to content

Commit

Permalink
41 feature forward headers (#42)
Browse files Browse the repository at this point in the history
* forward headers implementation

* update tests

* update tests

* Update PrivacyIDEA.php
  • Loading branch information
lukasmatusiewicz authored Sep 6, 2023
1 parent 324a189 commit 0a2b099
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 24 deletions.
76 changes: 60 additions & 16 deletions src/PrivacyIDEA.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ public function __construct($userAgent, $serverURL)
* @param $username string
* @param $pass string this can be the OTP, but also the PIN to trigger a token or PIN+OTP depending on the configuration of the server.
* @param null $transactionID Optional transaction ID. Used to reference a challenge that was triggered beforehand.
* @param null $headers Optional headers array to forward to the server.
* @return PIResponse|null null if response was empty or malformed, or parameter missing
* @throws PIBadRequestException
*/
public function validateCheck($username, $pass, $transactionID = null)
public function validateCheck($username, $pass, $transactionID = null, $headers=null)
{
assert('string' === gettype($username));
assert('string' === gettype($pass));
Expand All @@ -79,12 +80,16 @@ public function validateCheck($username, $pass, $transactionID = null)
// Add transaction ID in case of challenge response
$params["transaction_id"] = $transactionID;
}
if (empty($headers))
{
$headers = array('');
}
if ($this->realm)
{
$params["realm"] = $this->realm;
}

$response = $this->sendRequest($params, array(''), 'POST', '/validate/check');
$response = $this->sendRequest($params, $headers, 'POST', '/validate/check');

$ret = PIResponse::fromJSON($response, $this);
if ($ret == null)
Expand All @@ -105,17 +110,18 @@ public function validateCheck($username, $pass, $transactionID = null)
* This function requires a service account to be set.
*
* @param string $username
* @param null $headers Optional headers array to forward to the server.
* @return PIResponse|null null if response was empty or malformed, or parameter missing
* @throws PIBadRequestException
*/
public function triggerChallenge($username)
public function triggerChallenge($username, $headers = null)
{
assert('string' === gettype($username));

if ($username)
{
$authToken = $this->getAuthToken();
$header = array("authorization:" . $authToken);
$authTokenHeader = array("authorization:" . $authToken);

$params = array("user" => $username);

Expand All @@ -124,7 +130,16 @@ public function triggerChallenge($username)
$params["realm"] = $this->realm;
}

$response = $this->sendRequest($params, $header, 'POST', '/validate/triggerchallenge');
if (!empty($headers))
{
$headers = array_merge($headers, $authTokenHeader);
}
else
{
$headers = $authTokenHeader;
}

$response = $this->sendRequest($params, $headers, 'POST', '/validate/triggerchallenge');

return PIResponse::fromJSON($response, $this);
}
Expand All @@ -139,17 +154,22 @@ public function triggerChallenge($username)
* Poll for the status of a transaction (challenge).
*
* @param $transactionID string transactionId of the push challenge that was triggered before
* @param null $headers Optional headers array to forward to the server.
* @return bool true if the Push request has been accepted, false otherwise.
* @throws PIBadRequestException
*/
public function pollTransaction($transactionID)
public function pollTransaction($transactionID, $headers = null)
{
assert('string' === gettype($transactionID));

if (!empty($transactionID))
{
$params = array("transaction_id" => $transactionID);
$responseJSON = $this->sendRequest($params, array(''), 'GET', '/validate/polltransaction');
if (empty($headers))
{
$headers = array('');
}
$responseJSON = $this->sendRequest($params, $headers, 'GET', '/validate/polltransaction');
$response = json_decode($responseJSON, true);
return $response['result']['value'];
}
Expand All @@ -167,10 +187,11 @@ public function pollTransaction($transactionID)
* @param string $genkey
* @param string $type
* @param string $description
* @param null $headers Optional headers array to forward to the server.
* @return mixed Object representing the response of the server or null if parameters are missing
* @throws PIBadRequestException
*/
public function enrollToken($username, $genkey, $type, $description = "") // No return type because mixed not allowed yet
public function enrollToken($username, $genkey, $type, $description = "", $headers = null) // No return type because mixed not allowed yet
{
assert('string' === gettype($username));
assert('string' === gettype($type));
Expand All @@ -196,10 +217,18 @@ public function enrollToken($username, $genkey, $type, $description = "") // No
$authToken = $this->getAuthToken();

// If error occurred in getAuthToken() - return this error in PIResponse object
$header = array("authorization:" . $authToken);
$authTokenHeader = array("authorization:" . $authToken);
if (!empty($headers))
{
$headers = array_merge($headers, $authTokenHeader);
}
else
{
$headers = $authTokenHeader;
}

// Check if user has token
$tokenInfo = json_decode($this->sendRequest(array("user" => $username, "realm" => $params["realm"]), $header, 'GET', '/token'));
$tokenInfo = json_decode($this->sendRequest(array("user" => $username, "realm" => $params["realm"]), $headers, 'GET', '/token'));

if (!empty($tokenInfo->result->value->tokens))
{
Expand All @@ -209,7 +238,7 @@ public function enrollToken($username, $genkey, $type, $description = "") // No
else
{
// Call /token/init endpoint and return the response
return json_decode($this->sendRequest($params, $header, 'POST', '/token/init'));
return json_decode($this->sendRequest($params, $headers, 'POST', '/token/init'));
}
}

Expand All @@ -220,10 +249,11 @@ public function enrollToken($username, $genkey, $type, $description = "") // No
* @param string $transactionID
* @param string $webAuthnSignResponse
* @param string $origin
* @param null $headers Optional headers array to forward to the server.
* @return PIResponse|null returns null if the response was empty or malformed
* @throws PIBadRequestException
*/
public function validateCheckWebAuthn($username, $transactionID, $webAuthnSignResponse, $origin)
public function validateCheckWebAuthn($username, $transactionID, $webAuthnSignResponse, $origin, $headers = null)
{
assert('string' === gettype($username));
assert('string' === gettype($transactionID));
Expand Down Expand Up @@ -259,9 +289,17 @@ public function validateCheckWebAuthn($username, $transactionID, $webAuthnSignRe
$params[ASSERTIONCLIENTEXTENSIONS] = $tmp[ASSERTIONCLIENTEXTENSIONS];
}

$header = array("Origin:" . $origin);
$originHeader = array("Origin:" . $origin);
if (!empty($headers))
{
$headers = array_merge($headers, $originHeader);
}
else
{
$headers = $originHeader;
}

$response = $this->sendRequest($params, $header, 'POST', '/validate/check');
$response = $this->sendRequest($params, $headers, 'POST', '/validate/check');

return PIResponse::fromJSON($response, $this);
}
Expand All @@ -279,10 +317,11 @@ public function validateCheckWebAuthn($username, $transactionID, $webAuthnSignRe
* @param string $username
* @param string $transactionID
* @param string $u2fSignResponse
* @param null $headers Optional headers array to forward to the server.
* @return PIResponse|null
* @throws PIBadRequestException
*/
public function validateCheckU2F($username, $transactionID, $u2fSignResponse)
public function validateCheckU2F($username, $transactionID, $u2fSignResponse, $headers = null)
{
assert('string' === gettype($username));
assert('string' === gettype($transactionID));
Expand All @@ -301,12 +340,17 @@ public function validateCheckU2F($username, $transactionID, $u2fSignResponse)
$params["realm"] = $this->realm;
}

if (!empty($headers))
{
$headers = array('');
}

// Additional U2F params from $u2fSignResponse
$tmp = json_decode($u2fSignResponse, true);
$params[CLIENTDATA] = $tmp["clientData"];
$params[SIGNATUREDATA] = $tmp["signatureData"];

$response = $this->sendRequest($params, array(), 'POST', '/validate/check');
$response = $this->sendRequest($params, $headers, 'POST', '/validate/check');

return PIResponse::fromJSON($response, $this);
}
Expand Down
3 changes: 2 additions & 1 deletion test/EnrollTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ public function testSuccess()
"testUser",
"1",
"totp",
"Enrolled for test");
"Enrolled for test",
array('accept-language:en'));

$this->assertNotNull($response);
$this->assertIsObject($response);
Expand Down
4 changes: 2 additions & 2 deletions test/PollTransactionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function testTriggerPushToken()
->end();
$this->http->setUp();

$response = $this->pi->validateCheck("testUser", "testPass");
$response = $this->pi->validateCheck("testUser", "testPass", null, array('accept-language:en'));

$this->assertEquals("Bitte geben Sie einen OTP-Wert ein: , Please confirm the authentication on your mobile device!", $response->message);
$this->assertEquals("Bitte geben Sie einen OTP-Wert ein: , Please confirm the authentication on your mobile device!", $response->messages);
Expand Down Expand Up @@ -80,7 +80,7 @@ public function testSuccess()
->end();
$this->http->setUp();

$response = $this->pi->pollTransaction("1234567890");
$response = $this->pi->pollTransaction("1234567890", array('accept-language:en'));

$this->assertNotNull($response);
$this->assertTrue($response);
Expand Down
2 changes: 1 addition & 1 deletion test/TriggerChallengeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function testTriggerChallengeSuccess()
*/
public function testNoServiceAccount()
{
$response = $this->pi->triggerchallenge("testUser");
$response = $this->pi->triggerchallenge("testUser", array('accept-language:en'));

$this->assertNull($response);
}
Expand Down
2 changes: 1 addition & 1 deletion test/ValidateCheckTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function testOTPSuccess()
->end();
$this->http->setUp();

$response = $this->pi->validateCheck("testUser", "testPass");
$response = $this->pi->validateCheck("testUser", "testPass", null, array('accept-language:en'));

$this->assertEquals("matching 1 tokens", $response->message);
$this->assertEquals(Utils::matchingOneTokenResponseBody(), $response->raw);
Expand Down
4 changes: 2 additions & 2 deletions test/ValidateCheckU2FTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function testTriggerU2F()
->end();
$this->http->setUp();

$response = $this->pi->validateCheck("testUser", "testPass");
$response = $this->pi->validateCheck("testUser", "testPass", null, array('accept-language:en'));

$this->assertEquals("Please confirm with your U2F token (Yubico U2F EE Serial 61730834)", $response->message);
$this->assertEquals("Please confirm with your U2F token (Yubico U2F EE Serial 61730834)", $response->messages);
Expand Down Expand Up @@ -82,7 +82,7 @@ public function testSuccess()
->end();
$this->http->setUp();

$response = $this->pi->validateCheckU2F("testUser", "12345678", Utils::u2fSignResponse());
$response = $this->pi->validateCheckU2F("testUser", "12345678", Utils::u2fSignResponse(), array('accept-language:en'));

$this->assertEquals("matching 1 tokens", $response->message);
$this->assertEquals(Utils::matchingOneTokenResponseBody(), $response->raw);
Expand Down
2 changes: 1 addition & 1 deletion test/ValidateCheckWebauthnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function testSuccess()
->end();
$this->http->setUp();

$response = $this->pi->validateCheckWebAuthn("testUser", "12345678", Utils::webauthnSignResponse(), "test.it");
$response = $this->pi->validateCheckWebAuthn("testUser", "12345678", Utils::webauthnSignResponse(), "test.it", array('accept-language:en'));

$this->assertNotNull($response);
$this->assertEquals(Utils::matchingOneTokenResponseBody(), $response->raw);
Expand Down

0 comments on commit 0a2b099

Please sign in to comment.