diff --git a/src/PIBadRequestException.php b/src/PIBadRequestException.php index f042d16e2f2422a903e0793da75a9420a341d552..0b7d677ae9d670a4963fc37344e6a186d37ff5ef 100644 --- a/src/PIBadRequestException.php +++ b/src/PIBadRequestException.php @@ -1,8 +1,6 @@ <?php -namespace PrivacyIdea\PHPClient; +//namespace PrivacyIdea\PHPClient; -class PIBadRequestException extends \Exception {} -{ - -} \ No newline at end of file +class PIBadRequestException extends Exception +{} diff --git a/src/PIChallenge.php b/src/PIChallenge.php index 14f294ebeb71220bfe82a984337f57e7ae2c2d3f..7fbb5c54bdecd8894d54b48f9f78ed37f724383c 100644 --- a/src/PIChallenge.php +++ b/src/PIChallenge.php @@ -1,21 +1,27 @@ <?php -namespace PrivacyIdea\PHPClient; +//namespace PrivacyIdea\PHPClient; class PIChallenge { - /* @var string Token's type. */ + /* @var string Type of the token this challenge is for. */ public $type = ""; - /* @var string Message from single challenge. */ + + /* @var string Message for this challenge. */ public $message = ""; - /* @var string */ + + /* @var string TransactionId to reference this challenge in later requests. */ public $transactionID = ""; - /* @var string Token's serial. */ + + /* @var string Serial of the token this challenge is for. */ public $serial = ""; - /* @var string */ + + /* @var string Arbitrary attributes that can be appended to the challenge by the server. */ public $attributes = ""; + /* @var string JSON format */ public $webAuthnSignRequest = ""; + /* @var string JSON format */ public $u2fSignRequest = ""; } \ No newline at end of file diff --git a/src/PILog.php b/src/PILog.php index 1809fb2fa0aa379dddfa0c471e32a1a7fdbc4896..8f6df5e088b628961cf3945f23406895e40cc5e6 100644 --- a/src/PILog.php +++ b/src/PILog.php @@ -1,10 +1,9 @@ <?php -namespace PrivacyIdea\PHPClient; +//namespace PrivacyIdea\PHPClient; /** - * Interface PILog - * Call the functions that collect debug and error messages + * Logging interface. This is used to relay the log messages of the PHP-Client to the logger implementation of the project that uses the client. */ interface PILog { diff --git a/src/PIResponse.php b/src/PIResponse.php index a0d08fe78b536659bf72197e3667290a33ad0385..8b7a79d695be72ebd109a75dcda4469bfbe93929 100644 --- a/src/PIResponse.php +++ b/src/PIResponse.php @@ -1,35 +1,45 @@ <?php -namespace PrivacyIdea\PHPClient; +//namespace PrivacyIdea\PHPClient; class PIResponse { - /* @var string All tokens messages which are sent by PI and can be used in UI to help user interact with service. */ + /* @var string Combined messages of all triggered token. */ public $messages = ""; - /* @var string PI message. */ + + /* @var string Message from the response. Should be shown to the user. */ public $message = ""; - /* @var string Transaction ID which is needed by some PI API requests. */ + + /* @var string TransactionID is used to reference the challenges contained in this response in later requests. */ public $transactionID = ""; - /* @var string This is the raw PI response in JSON format. */ + + /* @var string Raw response in JSON format. */ public $raw = ""; - /* @var array Here are all triggered challenges delivered as object of PIChallenge class. */ + + /* @var array Array of PIChallenge objects representing triggered token challenges. */ public $multiChallenge = array(); - /* @var bool The status indicates if the request was processed correctly by the server. */ + + /* @var bool Status indicates if the request was processed successfully by the server. */ public $status = false; - /* @var bool The value tell us if authentication was successful. */ + + /* @var bool Value is true if the authentication was successful. */ public $value = false; - /* @var array All interesting details about user which can be shown in the UI at the end of the authentication. */ + + /* @var array Additional attributes of the user that can be sent by the server. */ public $detailAndAttributes = array(); - /* @var string PI error code will be delivered here. */ + + /* @var string If an error occurred, the error code will be set. */ public $errorCode; - /* @var string PI error message will be delivered here. */ + + /* @var string If an error occurred, the error message will be set. */ public $errorMessage; /** - * Prepare a good readable PI response and return it as an object + * Create a PIResponse object from the json response of the server. + * * @param $json * @param PrivacyIDEA $privacyIDEA - * @return PIResponse|null + * @return PIResponse|null returns null if the response of the server is empty or malformed */ public static function fromJSON($json, PrivacyIDEA $privacyIDEA) { @@ -37,25 +47,22 @@ class PIResponse if ($json == null || $json == "") { - $privacyIDEA->errorLog("PrivacyIDEA - PIResponse: No response from PI."); + $privacyIDEA->errorLog("Response from server is empty."); return null; } - // Build an PIResponse object and decode the response from JSON to PHP $ret = new PIResponse(); $map = json_decode($json, true); - // If wrong response format - throw error if ($map == null) { - $privacyIDEA->errorLog("PrivacyIDEA - PIResponse: Response from PI was in wrong format. JSON expected."); + $privacyIDEA->errorLog("Response from the server is malformed:\n" . $json); return null; } - // Prepare raw JSON Response if needed $ret->raw = $json; - // Possibility to show an error message from PI server if no value + // If value is not present, an error occurred if (!isset($map['result']['value'])) { $ret->errorCode = $map['result']['error']['code']; @@ -63,7 +70,6 @@ class PIResponse return $ret; } - // Set information from PI response to property if (isset($map['detail']['messages'])) { $ret->messages = implode(", ", array_unique($map['detail']['messages'])) ?: ""; @@ -79,7 +85,7 @@ class PIResponse $ret->status = $map['result']['status'] ?: false; $ret->value = $map['result']['value'] ?: false; - // Prepare attributes and detail + // Attributes and detail if (!empty($map['detail']['user'])) { $attributes = $map['detail']['user']; @@ -93,7 +99,7 @@ class PIResponse $ret->detailAndAttributes = array("detail" => $detail, "attributes" => $attributes); } - // Set all challenges to objects and set it all to one array + // Add any challenges to multiChallenge if (isset($map['detail']['multi_challenge'])) { $mc = $map['detail']['multi_challenge']; @@ -128,7 +134,7 @@ class PIResponse } /** - * Get array with all triggered token types. + * Get an array with all triggered token types. * @return array */ public function triggeredTokenTypes() @@ -142,7 +148,7 @@ class PIResponse } /** - * Get OTP message if OTP token(s) triggered. + * Get the message of any token that is not Push or WebAuthn. Those are OTP token requiring an input field. * @return string */ public function otpMessage() @@ -158,7 +164,7 @@ class PIResponse } /** - * Get push message if push token triggered. + * Get the Push token message if any were triggered. * @return string */ public function pushMessage() @@ -174,7 +180,7 @@ class PIResponse } /** - * Get WebAuthn message if that kind of token triggered. + * Get the WebAuthn token message if any were triggered. * @return string */ public function webauthnMessage() @@ -190,8 +196,8 @@ class PIResponse } /** - * Get WebAuthn Sign Request which comes in PIResponse if WebAuthn token is triggered. - * @return string + * Get the WebAuthnSignRequest for any triggered WebAuthn token. If none were triggered, this returns an empty string. + * @return string WebAuthnSignRequest or empty string */ public function webAuthnSignRequest() { @@ -209,11 +215,21 @@ class PIResponse $arr[] = $challenge->attributes['webAuthnSignRequest']['allowCredentials'][0]; } } - $webauthn->allowCredentials = $arr; - - return json_encode($webauthn); + if (empty($webauthn)) + { + return ""; + } + else + { + $webauthn->allowCredentials = $arr; + return json_encode($webauthn); + } } + /** + * Get the U2FSignRequest for any triggered U2F token. If none were triggered, this returns an empty string. + * @return string U2FSignRequest or empty string + */ public function u2fSignRequest() { $ret = ""; diff --git a/src/PrivacyIDEA.php b/src/PrivacyIDEA.php index 6c4b868198ce0d7c44a3aa74a248653c3ed3493d..5276b69a5ccf088d2a59d4552240f834be3d5c78 100644 --- a/src/PrivacyIDEA.php +++ b/src/PrivacyIDEA.php @@ -1,6 +1,6 @@ <?php -namespace PrivacyIdea\PHPClient; +//namespace PrivacyIdea\PHPClient; const AUTHENTICATORDATA = "authenticatordata"; const CLIENTDATA = "clientdata"; @@ -18,28 +18,36 @@ const ASSERTIONCLIENTEXTENSIONS = "assertionclientextensions"; */ class PrivacyIDEA { - /* @var string Plugins name which must to be verified in privacyIDEA. */ + /* @var string UserAgent to use in requests made to privacyIDEA. */ public $userAgent = ""; - /* @var string This is the URL to your privacyIDEA server. */ + + /* @var string URL of the privacyIDEA server. */ public $serverURL = ""; + /* @var string Here is realm of users account. */ public $realm = ""; - /* @var bool You can decide if you want to verify your ssl certificate. */ + + /* @var bool Host verification can be disabled in SSL. */ public $sslVerifyHost = true; - /* @var bool You can decide if you want to verify your ssl certificate. */ + + /* @var bool Peer verification can be disabled in SSL. */ public $sslVerifyPeer = true; - /* @var string Username to your service account. You need it to get auth token which is needed by some PI API requests. */ + + /* @var string Account name for a service account to the privacyIDEA server. This is required to use the /validate/triggerchallenge endpoint. */ public $serviceAccountName = ""; - /* @var string Password to your service account. You need it to get auth token which is needed by some PI API requests. */ + + /* @var string Password for a service account to the privacyIDEA server. This is required to use the /validate/triggerchallenge endpoint. */ public $serviceAccountPass = ""; - /* @var string If needed you can add it too. */ + + /* @var string Realm for a service account to the privacyIDEA server. This is required to use the /validate/triggerchallenge endpoint. This is optional. */ public $serviceAccountRealm = ""; - /* @var object This object will deliver PI debug and error messages to your plugin so you can log it wherever you want. */ + + /* @var object Implementation of the PILog interface. */ public $logger = null; /** * PrivacyIDEA constructor. - * @param $userAgent string the user agent that should set in the http header + * @param $userAgent string the user agent that should be used for the requests made * @param $serverURL string the url of the privacyIDEA server */ public function __construct($userAgent, $serverURL) @@ -49,36 +57,12 @@ class PrivacyIDEA } /** - * This function collect the debug messages and send it to PILog.php - * @param $message - */ - function debugLog($message) - { - if ($this->logger != null) - { - $this->logger->piDebug($message); - } - } - - /** - * This function collect the error messages and send it to PILog.php - * @param $message - */ - function errorLog($message) - { - if ($this->logger != null) - { - $this->logger->piError($message); - } - } - - /** - * Handle validateCheck using user's username, password and if challenge response - transaction_id. + * Try to authenticate the user with the /validate/check endpoint. * - * @param $username string Must be set - * @param $pass string Must be set + * @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. - * @return PIResponse|null This method returns an PIResponse object which contains all the useful information from the PI server. In case of error returns null. + * @return PIResponse|null null if response was empty or malformed, or parameter missing * @throws PIBadRequestException */ public function validateCheck($username, $pass, $transactionID = null) @@ -86,17 +70,14 @@ class PrivacyIDEA assert('string' === gettype($username)); assert('string' === gettype($pass)); - // Log entry of the validateCheck() - $this->debugLog("validateCheck() with user=" . $username . ", pass=" . $pass . " and if is set transactionID " . $transactionID); - - //Check if parameters are set + // Check if parameters are set if (!empty($username) || !empty($pass)) { $params["user"] = $username; $params["pass"] = $pass; if (!empty($transactionID)) { - //Add transaction ID in case of challenge response + // Add transaction ID in case of challenge response $params["transaction_id"] = $transactionID; } if ($this->realm) @@ -104,20 +85,18 @@ class PrivacyIDEA $params["realm"] = $this->realm; } - //Call send_request function to handle an API Request using $parameters and return it. $response = $this->sendRequest($params, array(''), 'POST', '/validate/check'); - //Return the response from /validate/check as PIResponse object $ret = PIResponse::fromJSON($response, $this); if ($ret == null) { - $this->debugLog("privacyIDEA - Validate Check: no response from PI-server"); + $this->debugLog("Server did not respond."); } return $ret; - } else + } + else { - //Handle debug message if $username is empty - $this->debugLog("privacyIDEA - Validate Check: params incomplete!"); + $this->debugLog("Missing username or pass for /validate/check."); } return null; } @@ -127,84 +106,69 @@ class PrivacyIDEA * This function requires a service account to be set. * * @param string $username - * @return PIResponse|null This method returns an PIResponse object which contains all the useful information from the PI server. + * @return PIResponse|null null if response was empty or malformed, or parameter missing * @throws PIBadRequestException */ public function triggerChallenge($username) { assert('string' === gettype($username)); - // Log entry of the pollTransaction() - $this->debugLog("triggerChallenge() with username=" . $username); - if ($username) { $authToken = $this->getAuthToken(); - // If error occurred in getAuthToken() - return this error in PIResponse object $header = array("authorization:" . $authToken); - $parameter = array("user" => $username); - - //Call /validate/triggerchallenge with username as parameter and return it. - $response = $this->sendRequest($parameter, $header, 'POST', '/validate/triggerchallenge'); + $params = array("user" => $username); - //Return the response from /validate/triggerchallenge as PIResponse object - $ret = PIResponse::fromJSON($response, $this); - - if ($ret == null) + if ($this->realm) { - $this->debugLog("privacyIDEA - Trigger Challenge: no response from PI-server"); + $params["realm"] = $this->realm; } - return $ret; - } else + $response = $this->sendRequest($params, $header, 'POST', '/validate/triggerchallenge'); + + return PIResponse::fromJSON($response, $this); + } + else { - //Handle debug message if empty $username - $this->debugLog("privacyIDEA - Trigger Challenge: no username"); + $this->debugLog("Username missing!"); } return null; } /** - * Call /validate/polltransaction using transaction_id + * Poll for the status of a transaction (challenge). * - * @param $transactionID string An unique ID which is needed by some API requests. - * @return bool Returns true if PUSH is accepted, false otherwise. + * @param $transactionID string transactionId of the push challenge that was triggered before + * @return bool true if the Push request has been accepted, false otherwise. * @throws PIBadRequestException */ public function pollTransaction($transactionID) { assert('string' === gettype($transactionID)); - // Log entry of the pollTransaction() - $this->debugLog("pollTransaction() with transaction ID=" . $transactionID); - if (!empty($transactionID)) { $params = array("transaction_id" => $transactionID); - // Call /validate/polltransaction using transactionID and decode it from JSON $responseJSON = $this->sendRequest($params, array(''), 'GET', '/validate/polltransaction'); $response = json_decode($responseJSON, true); - //Return the response from /validate/polltransaction return $response['result']['value']; - - } else + } + else { - //Handle debug message if $transactionID is empty - $this->debugLog("privacyIDEA - Poll Transaction: No transaction ID"); + $this->debugLog("TransactionID missing!"); } return false; } /** - * Check if user already has token - * Enroll a new token + * Check if user already has token and if not, enroll a new token * * @param string $username * @param string $genkey * @param string $type * @param string $description - * @return mixed + * @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 @@ -217,14 +181,11 @@ class PrivacyIDEA assert('string' === gettype($description)); } - // Log entry of the enrollToken() - $this->debugLog("privacyIDEA - enrollToken() with user=" . $username . ", genkey=" . $genkey . ", type=" . $type . ", description=" . $description); - // Check if parameters contain the required keys if (empty($username) || empty($type)) { - $this->debugLog("privacyIDEA - Enroll Token: Token enrollment not possible because params are not complete"); - return array(); + $this->debugLog("Token enrollment not possible because parameters are not complete"); + return null; } $params["user"] = $username; @@ -242,24 +203,24 @@ class PrivacyIDEA if (!empty($tokenInfo->result->value->tokens)) { - $this->debugLog("privacyIDEA - Enroll Token: User already has a token. No need to enroll a new one."); - return array(); - - } else + $this->debugLog("enrollToken: User already has a token."); + return null; + } + else { - // Call /token/init endpoint and return the PI response + // Call /token/init endpoint and return the response return json_decode($this->sendRequest($params, $header, 'POST', '/token/init')); } } /** - * Sends a request to /validate/check with the data required to authenticate a WebAuthn token. + * Sends a request to /validate/check with the data required to authenticate with a WebAuthn token. * * @param string $username * @param string $transactionID * @param string $webAuthnSignResponse * @param string $origin - * @return PIResponse|null + * @return PIResponse|null returns null if the response was empty or malformed * @throws PIBadRequestException */ public function validateCheckWebAuthn($username, $transactionID, $webAuthnSignResponse, $origin) @@ -269,13 +230,8 @@ class PrivacyIDEA assert('string' === gettype($webAuthnSignResponse)); assert('string' === gettype($origin)); - // Log entry of the validateCheckWebAuthn() - $this->debugLog("ValidateCheckWebAuthn with user=" . $username . ", transactionID=" . $transactionID . ", WebAuthnSignResponse=" . $webAuthnSignResponse . ", origin=" . $origin); - - // Check if parameters are set if (!empty($username) || !empty($transactionID)) { - // Compose standard validate/check params $params["user"] = $username; $params["pass"] = ""; @@ -307,25 +263,18 @@ class PrivacyIDEA $response = $this->sendRequest($params, $header, 'POST', '/validate/check'); - //Return the response from /validate/check as PIResponse object - $ret = PIResponse::fromJSON($response, $this); - - if ($ret == null) - { - $this->debugLog("privacyIDEA - WebAuthn: no response from PI-server"); - } - return $ret; - - } else + return PIResponse::fromJSON($response, $this); + } + else { - //Handle debug message if $username is empty - $this->debugLog("privacyIDEA - WebAuthn: params incomplete!"); + // Handle debug message if $username is empty + $this->debugLog("validateCheckWebAuthn: parameters are incomplete!"); } return null; } /** - * Sends a request to /validate/check with the data required to authenticate a U2F token. + * Sends a request to /validate/check with the data required to authenticate with an U2F token. * * @param string $username * @param string $transactionID @@ -339,13 +288,9 @@ class PrivacyIDEA assert('string' === gettype($transactionID)); assert('string' === gettype($u2fSignResponse)); - // Log entry of validateCheckU2F - $this->debugLog("ValidateCheckU2F with user=" . $username . ", transactionID=" . $transactionID . ", u2fSignResponse=" . $u2fSignResponse); - - // Check if parameters are set + // Check if required parameters are set if (!empty($username) || !empty($transactionID) || !empty($u2fSignResponse)) { - // Compose standard validate/check params $params["user"] = $username; $params["pass"] = ""; @@ -363,19 +308,11 @@ class PrivacyIDEA $response = $this->sendRequest($params, array(), 'POST', '/validate/check'); - //Return the response from /validate/check as PIResponse object - $ret = PIResponse::fromJSON($response, $this); - - if ($ret == null) - { - $this->debugLog("privacyIDEA - U2F: no response from PI-server"); - } - return $ret; - - } else + return PIResponse::fromJSON($response, $this); + } + else { - //Handle debug message if $username is empty - $this->debugLog("privacyIDEA - U2F: params incomplete!"); + $this->debugLog("validateCheckU2F parameters are incomplete!"); } return null; } @@ -390,21 +327,19 @@ class PrivacyIDEA } /** - * Retrieves an auth token from the server using the service account. The auth token is required to make certain requests to privacyIDEA. - * If no service account is set or an error occurred, this function returns false. + * Retrieves an auth token from the server using the service account. An auth token is required for some requests to privacyIDEA. * - * @return string|bool|PIResponse the auth token or false. - * @throws PIBadRequestException + * @return string the auth token or empty string if the response did not contain a token or no service account is configured. + * @throws PIBadRequestException if an error occurs during the request */ public function getAuthToken() { if (!$this->serviceAccountAvailable()) { - $this->errorLog("Cannot retrieve auth token without service account"); - return false; + $this->errorLog("Cannot retrieve auth token without service account!"); + return ""; } - // To get auth token from server use API Request: /auth with added service account and service pass $params = array( "username" => $this->serviceAccountName, "password" => $this->serviceAccountPass @@ -415,29 +350,26 @@ class PrivacyIDEA $params["realm"] = $this->serviceAccountRealm; } - // Call /auth endpoint and decode the response from JSON to PHP $response = json_decode($this->sendRequest($params, array(''), 'POST', '/auth'), true); if (!empty($response['result']['value'])) { - // Get auth token from response->result->value->token and return the token - return $response['result']['value']['token']; + return @$response['result']['value']['token'] ?: ""; } - // If no response return false - $this->debugLog("privacyIDEA - getAuthToken: No response from PI-Server"); - return false; + $this->debugLog("/auth response did not contain a auth token."); + return ""; } /** - * Prepare send_request and make curl_init. + * Send a request to an endpoint with the specified parameters and headers. * - * @param $params array request parameters in an array - * @param $headers array headers fields in array - * @param $httpMethod string + * @param $params array request parameters + * @param $headers array headers fields + * @param $httpMethod string GET or POST * @param $endpoint string endpoint of the privacyIDEA API (e.g. /validate/check) - * @return string returns string with response from server or an empty string if error occurs - * @throws PIBadRequestException + * @return string returns a string with the response from server + * @throws PIBadRequestException if an error occurres */ public function sendRequest(array $params, array $headers, $httpMethod, $endpoint) { @@ -446,14 +378,11 @@ class PrivacyIDEA assert('string' === gettype($httpMethod)); assert('string' === gettype($endpoint)); - $this->debugLog("Sending HEADER: " . http_build_query($headers, '', ', ') . ", with " . $httpMethod . " to " . $endpoint); - $this->debugLog("And PARAMS: " . http_build_query($params, '', ', ')); - - $curlInstance = curl_init(); + $this->debugLog("Sending " . http_build_query($params, '', ', ') . " to " . $endpoint); - // Compose an API Request using privacyIDEA's URL from config and endpoint created in function $completeUrl = $this->serverURL . $endpoint; + $curlInstance = curl_init(); curl_setopt($curlInstance, CURLOPT_URL, $completeUrl); curl_setopt($curlInstance, CURLOPT_HEADER, true); if ($headers) @@ -466,8 +395,8 @@ class PrivacyIDEA { curl_setopt($curlInstance, CURLOPT_POST, true); curl_setopt($curlInstance, CURLOPT_POSTFIELDS, $params); - - } elseif ($httpMethod === "GET") + } + elseif ($httpMethod === "GET") { $paramsStr = '?'; if (!empty($params)) @@ -480,12 +409,12 @@ class PrivacyIDEA curl_setopt($curlInstance, CURLOPT_URL, $completeUrl . $paramsStr); } - // Check if you should to verify privacyIDEA's SSL certificate in your config - // If true - do it, if false - don't verify + // Disable host and/or peer verification for SSL if configured. if ($this->sslVerifyHost === true) { curl_setopt($curlInstance, CURLOPT_SSL_VERIFYHOST, 2); - } else + } + else { curl_setopt($curlInstance, CURLOPT_SSL_VERIFYHOST, 0); } @@ -493,35 +422,58 @@ class PrivacyIDEA if ($this->sslVerifyPeer === true) { curl_setopt($curlInstance, CURLOPT_SSL_VERIFYPEER, 2); - } else + } + else { curl_setopt($curlInstance, CURLOPT_SSL_VERIFYPEER, 0); } - //Store response in the variable $response = curl_exec($curlInstance); if (!$response) { - //Handle error if no response and return an empty string + // Handle error $curlErrno = curl_errno($curlInstance); - $this->errorLog("privacyIDEA-SDK: Bad request to PI server. " . curl_error($curlInstance) . " errno: " . $curlErrno); + $this->errorLog("Bad request: " . curl_error($curlInstance) . " errno: " . $curlErrno); throw new PIBadRequestException("Unable to reach the authentication server (" . $curlErrno . ")"); } $headerSize = curl_getinfo($curlInstance, CURLINFO_HEADER_SIZE); $ret = substr($response, $headerSize); + curl_close($curlInstance); // Log the response - if ($endpoint != "/auth") + if ($endpoint != "/auth" && $this->logger != null) { $retJson = json_decode($ret, true); $this->debugLog($endpoint . " returned " . json_encode($retJson, JSON_PRETTY_PRINT)); } - curl_close($curlInstance); - - //Return decoded response from API Request + // Return decoded response return $ret; } + + /** + * This function relays messages to the PILogger implementation + * @param $message + */ + function debugLog($message) + { + if ($this->logger != null) + { + $this->logger->piDebug("privacyIDEA-PHP-Client: " . $message); + } + } + + /** + * This function relays messages to the PILogger implementation + * @param $message + */ + function errorLog($message) + { + if ($this->logger != null) + { + $this->logger->piError("privacyIDEA-PHP-Client: " . $message); + } + } } \ No newline at end of file