* $Author:: $ *
* -------------------------------------------------------------------- *
* Copyright (c) 2003 - 2009 by Roland Haeder *
- * Copyright (c) 2009 - 2013 by Mailer Developer Team *
+ * Copyright (c) 2009 - 2016 by Mailer Developer Team *
* For more information visit: http://mxchange.org *
* *
* This program is free software; you can redistribute it and/or modify *
}
// Sends out a request to the API and returns it's result
-function sendWernisApiRequest ($scriptName, $requestData = array()) {
+function sendWernisApiRequest ($scriptName, $requestData = []) {
+ // Debug call
+ //* DEBUG */ reportBug(__FUNCTION__, __LINE__, 'scriptName=' . $scriptName . ',requestData=<pre>' . print_r($requestData, TRUE) . '</pre>');
+
// Is the requestData an array?
if (!is_array($requestData)) {
// Then abort here!
// Get the raw response from the lower function
$response = sendHttpPostRequest($requestString, $requestData);
+ // Debug message
+ //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, sprintf('isDeveloperSystem()=%d', intval(isDeveloperSystem())));
+
+ // Log response only for development
+ if (isDeveloperSystem()) {
+ // Log whole message
+ logDebugMessage(__FUNCTION__, __LINE__, sprintf('response[%s]=%s', gettype($response), print_r($response, TRUE)));
+ } // END - if
+
// Check the response header if all is fine
if (!isHttpStatusOkay($response[0])) {
// Something bad happend... :(
$data = explode('=', $responseLine);
// Default return array (should not stay empty)
- $return = array();
+ $return = [];
// We use only the first two entries (which shall be fine)
if ($data[0] === 'error') {
- // The request has failed... :(
- switch ($data[1]) {
+ // The request has failed...
+ $status = $data[1];
+ $extraData = '';
+
+ // Explode status code
+ $exploded = explode(':', $status);
+
+ // More extra data found?
+ if (count($exploded) > 1) {
+ // Then set all
+ $status = $exploded[0];
+ $extraData = $exploded[1];
+ } // END - if
+
+ switch ($status) {
case '404': // Invalid API id
case 'AUTH': // Authorization has failed
$return = array(
);
break;
+ case 'AUTH-STATUS': // Unexpected auth status
+ // Switch on extra data
+ switch ($extraData) {
+ case 'ACCEPTED':
+ $return = array(
+ 'status' => 'api_auth_status_accepted',
+ 'message' => '{--WERNIS_API_REQUEST_FAILED_AUTH_STATUS_ACCEPTED--}'
+ );
+ break;
+
+ case 'REJECTED':
+ $return = array(
+ 'status' => 'api_auth_status_rejected',
+ 'message' => '{--WERNIS_API_REQUEST_FAILED_AUTH_STATUS_REJECTED--}'
+ );
+ break;
+
+ case 'UNKNOWN':
+ $return = array(
+ 'status' => 'api_auth_status_unknown',
+ 'message' => '{--WERNIS_API_REQUEST_FAILED_AUTH_STATUS_UNKNOWN--}'
+ );
+ break;
+
+ default: // Unknown
+ $return = array(
+ 'status' => 'api_auth_status_failed',
+ 'message' => getMaskedMessage('WERNIS_API_REQUEST_FAILED_AUTH_STATUS', $extraData)
+ );
+ break;
+ } // END - switch
+ break;
+
default: // Unknown error (maybe new?)
logDebugMessage(__FUNCTION__, __LINE__, sprintf('Unknown error %s from WDS66 API received.', $data[1]));
$return = array(
'message' => '{%message,WERNIS_API_REQUEST_FAILED=' . $data[1] . '%}'
);
break;
- }
+ } // END - switch
} else {
- // All fine here
- $return = array(
- 'status' => 'OK',
- 'response' => $responseLine
- );
+ // All fine, then analyze API response
+ $return = convertApiResponseToArray($responseLine, '&', '=');
+
+ // Nothing is fine now
+ $return['status'] = 'generic_failed';
+ $return['message'] = '--WERNIS_API_REQUEST_FAILED_GENERIC--}';
+
+ // Are 'encrypted', 'key' and 'iv' set?
+ //* DEBUG-DIE */ die(__FUNCTION__ . ':return=<pre>' . print_r($return, TRUE) . '</pre>');
+ if ((isset($return['encrypted'])) && (isset($return['key'])) && (isset($return['iv']))) {
+ // Fully decode it (URL-encoded BASE64)
+ $decoded = decodeString($return['encrypted']);
+ $iv = decodeString($return['iv']);
+
+ // Generate decryption key
+ $decryptionKey = generateWernisDecryptionKey($return['key']);
+
+ // Decrypt string
+ $decrypted = decrytStringByCipher($decoded, getWernisEncryptionAlgorithm(), getWernisEncryptionMode(), $decryptionKey, $iv);
+ //* DEBUG-DIE */ die('key="' . $return['key'] . '"<br />decryptionKey="' . $decryptionKey . '"<br />decoded="' . $decoded . '"<br />decrypted="' . $decrypted . '"');
+
+ // First char must be an &
+ assert(substr($decrypted, 0, 1) == '&');
+
+ // Now the string needs to be turned into an array, first explode all &
+ $elements = explode('&', $decrypted);
+
+ // And remove first element
+ array_shift($elements);
+ //* DEBUG-DIE */ die('elements=<pre>' . print_r($elements, TRUE) . '</pre>');
+
+ // Now "walk" all ements
+ foreach ($elements as $idx => $element) {
+ // Explode element
+ $keyValue = explode('=', $element);
+
+ // Make sure it is valid
+ assert(count($keyValue) == 2);
+
+ // Now handle all over
+ $return[$keyValue[0]] = $keyValue[1];
+ } // END - foreach
+
+ // Remove encryption stuff
+ unset($return['encrypted'], $return['key'], $return['iv']);
+ } // END - if
+
+ // All fine ...
+ $return['status'] = 'OK';
+ $return['message'] = NULL;
}
// Return the result
+ //* DEBUG-DIE */ die(__FUNCTION__ . ':return=<pre>' . print_r($return, TRUE) . '</pre>');
return $return;
}
'sub_request' => $subRequest,
'fields' => $fields,
't_uid' => bigintval($authData['wernis_userid']),
+ 't_md5' => getWernisPassMd5(),
'auth_key' => $authData['api_auth_key'],
'challenge' => $authData['api_redirect_challenge']
);
return $return;
}
+// Translate auth status
+function translateWernisAuthStatu ($status) {
+ return '{%message,WERNIS_AUTH_STATUS_' . strtoupper($status) . '%}';
+}
+
// Translate the status IN/OUT
function translateWernisTransferStatus ($status) {
// Default status is unknown
- $return = '{%message,WERNIS_STATUS_UNKNWOWN=' . $status . '%}';
+ $return = '{%message,WERNIS_TRANSFER_STATUS_UNKNWOWN=' . $status . '%}';
// Construct message id
- $messageId = 'WERNIS_STATUS_' . $status;
+ $messageId = 'WERNIS_TRANSFER_STATUS_' . $status;
// Is it there?
if (isMessageIdValid($messageId)) {
displayMessage('{--GUEST_WERNIS_REGISTRATION_PASSWORD_NOT_SET--}');
} else {
// So far, all fine, then let's do the call-back on auth.php ...
- $response = executeWernisApiAuth(postRequestElement('wernis_id'), postRequestElement('wernis_password'));
+ $args = executeWernisApiAuth(postRequestElement('wernis_id'), postRequestElement('wernis_password'));
- // Was the status okay?
- if (isHttpResponseStatusOkay($response)) {
- // All fine, then analyze API response
- $args = convertApiResponseToArray($response['response'], '&', '=');
-
- // Is status set?
+ // Status was okay?
+ if (isHttpResponseStatusOkay($args)) {
+ // Is auth_status set?
+ //* DEBUG-DIE */ die('response=<pre>' . print_r($response, TRUE) . '</pre>,args=' . '<pre>'.print_r($args, TRUE).'</pre>');
assert(isset($args['auth_status']));
// Add WDS66 userid
die(__FUNCTION__ . ':' . __LINE__ . ': status[' . gettype($status) . ']=' . $status . ' - Unfinished.');
} else {
// Something bad happened
- displayMessage($response['message']);
+ displayMessage($args['message']);
}
}
} // END - if
// Is the status 1? (= all fine with API call)
if ($status == '1') {
// Get mapped data based on challenge
- $return = getWernisMappedDataFromApiByChallenge($challenge, $status);
+ $return = getWernisMappedDataFromApiByChallenge($challenge, $challengeResponse, $status);
// Is the array filled?
- if ((count($return['mapped_data']) > 0) && (empty($return['message']))) {
+ //* DEBUG-DIE */ die(__METHOD__ . ':return=<pre>' . print_r($return, TRUE) . '</pre> - EXIT!');
+ if ((isset($return['mapped_data'])) && (count($return['mapped_data']) > 0) && (empty($return['message']))) {
// Set must-fillout fields
$return['mapped_data'] = runFilterChain('register_must_fillout', $return['mapped_data']);
// Add missing elements
- $return['mapped_data']['gender'] = NULL;
+ $return['mapped_data']['sex'] = NULL;
$return['mapped_data']['birthday_selection'] = generateDayMonthYearSelectionBox($return['mapped_data']['birth_day'], $return['mapped_data']['birth_month'], $return['mapped_data']['birth_year']);
$return['mapped_data']['challenge'] = getRequestElement('challenge');
$return['mapped_data']['__challenge_response'] = getRequestElement('__challenge_response');
return FALSE;
}
} else {
- // Status does not need to be changed
- die(__FUNCTION__ . ':' . __LINE__ . ': Reached!');
+ // Not accepted
+ displayMessage('{--GUEST_WERNIS_REGISTRATION_AUTH_REJECTED--}');
}
}
// "Getter" for mapped data by calling the API and given challenge and status
-function getWernisMappedDataFromApiByChallenge ($challenge, $status) {
+function getWernisMappedDataFromApiByChallenge ($challenge, $challengeResponse, $status) {
// Get stored registration data
$rows = getWernisRegistrationDataByKey('api_redirect_challenge', $challenge);
// Display form
loadTemplate('guest_wernis_registration_rpc_form');
- return array();
+ return [];
} // END - if
// Init array
$return = array(
// Mapped data
- 'mapped_data' => array(),
+ 'mapped_data' => [],
// Any error message from API
'message' => ''
);
* will always run.
*/
updateWernisRegistrationDataByKey('api_auth_status', 'api_redirect_challenge', $challenge, 'ACCEPTED');
+ updateWernisRegistrationDataByKey('api_challenge_response', 'api_redirect_challenge', $challenge, $challengeResponse);
} // END - if
// Now call "get.php"
$response = executeWernisApiGet($rows[0], 'data', 'vorname|name|strasse|plz|ort|birth_day|birth_month|birth_year|email|werber');
// Was the status okay?
+ //* DEBUG-DIE */ die(__FUNCTION__ . ':response=<pre>' . print_r($response, TRUE) . '</pre>');
if (isHttpResponseStatusOkay($response)) {
// API returned non-errous response, 'data=' must be found
- assert(substr($response['response'], 0, 5) == 'data=');
-
- // And remove it, this is now BASE64-encoded
- $encodedData = urldecode(substr($response['response'], 5));
+ assert(isset($response['data']));
// And decode it (all steps separated to later "easily" debug them)
- $decodedData = base64_decode($encodedData);
+ $decodedData = base64_decode(urldecode($response['data']));
+ //* DEBUG-DIE */ die(__FUNCTION__ . ':decodedData=' . $decodedData);
/*
* Do some checks on the decoded string, it should be a
// The array seems to be fine, unserialize it
$userData = unserialize($decodedData);
+ //* DEBUG-DIE */ die(__METHOD__ . ':userData=<pre>' . print_r($userData, TRUE) . '</pre> - EXIT!');
// All mappings WDS66->mailer
$mappings = array(
reportBug(__FUNCTION__, __LINE__, 'Cannot map from=' . $from . ' -> to=' . $to . ': element does not exist.');
} // END - if
- // "Map" all
+ // "Map" all and make empty strings to NULL
$return['mapped_data'][$to] = convertEmptyToNull($userData[$from]);
} // END - foreach
}
// Return mapped data array
+ //* DEBUG-DIE */ die(__METHOD__ . ':return=<pre>' . print_r($return, TRUE) . '</pre> - EXIT!');
return $return;
}
sqlQueryEscaped("UPDATE
`{?_MYSQL_PREFIX?}_wernis_regs`
SET
- `%s`='%s'
+ `%s` = '%s'
WHERE
- `%s`='%s' AND
+ `%s` = '%s' AND
`%s` != '%s'
LIMIT 1",
array(
$updatedColumn,
$newValue,
$key,
+ $oldValue,
$updatedColumn,
$oldValue
), __FUNCTION__, __LINE__
// "Getter" for Wernis registration data by given key and value
function getWernisRegistrationDataByKey ($key, $value, $limit = 1) {
// Init array
- $rows = array();
+ $rows = [];
// Now search for it
$result = sqlQueryEscaped("SELECT
`api_auth_status`,
`api_auth_key`,
`api_redirect_challenge`,
+ `api_challenge_response`,
UNIX_TIMESTAMP(`record_inserted`) AS `record_inserted`
FROM
`{?_MYSQL_PREFIX?}_wernis_regs`
WHERE
`%s`='%s'
ORDER BY
- `id`
+ `id` ASC
LIMIT %d",
array(
$key,
// Generic registration is finished, so add more data:
}
-//-----------------------------------------------------------------------------
-// Auth status callback functions
-//-----------------------------------------------------------------------------
+// Generates decrption key based on private key, public key and API key
+function generateWernisDecryptionKey ($publicKey) {
+ // Generate key from most known data
+ $key = hashSha256(sprintf(
+ '%s:%s:%s',
+ getWernisApiMd5(),
+ getWernisPrivateKey(),
+ $publicKey
+ ));
+
+ // Return it
+ return $key;
+}
-// Handler for auth_status=PENDING
-function doWernisAuthPending ($args) {
- // $args must always be an array
+// Registers or updates Wernis registration data
+function registerUpdateWernisRegistrationCall ($args, $challenge, $status) {
+ // Make sure the required array elements are there
assert(is_array($args));
-
- // auth_key and wernis_userid must be set
assert(isset($args['auth_key']));
assert(isset($args['wernis_userid']));
- // Generate a challenge that will be added to the URL
- $challenge = hashSha256(generatePassword(128));
-
// Search entry in database by auth_key
if (countSumTotalData($args['auth_key'], 'wernis_regs', 'id', 'api_auth_key', TRUE) == 0) {
// "Register" this call
`api_redirect_challenge`
) VALUES (
%s,
- 'PENDING',
+ '%s',
'%s',
'%s'
)",
array(
bigintval($args['wernis_userid']),
+ $status,
$args['auth_key'],
$challenge
), __FUNCTION__, __LINE__
sqlQueryEscaped("UPDATE
`{?_MYSQL_PREFIX?}_wernis_regs`
SET
- `api_redirect_challenge`='%s'
+ `api_redirect_challenge`='%s',
+ `api_auth_status`='%s'
WHERE
`api_auth_key`='%s' AND
`wernis_userid`=%s
- `api_auth_status`='PENDING'
LIMIT 1",
array(
$challenge,
+ $status,
$args['auth_key'],
bigintval($args['wernis_userid'])
), __FUNCTION__, __LINE__
);
}
- // Should always update/insert
- assert(sqlAffectedRows() == 1);
+ // Return whether something has been inserted or updated
+ return (sqlAffectedRows() == 1);
+}
+
+//-----------------------------------------------------------------------------
+// Auth status callback functions
+//-----------------------------------------------------------------------------
+
+// Handler for auth_status=PENDING
+function doWernisAuthPending ($args) {
+ // $args must always be an array
+ assert(is_array($args));
+
+ // auth_key and wernis_userid must be set
+ assert(isset($args['auth_key']));
+ assert(isset($args['wernis_userid']));
+
+ // Generate a challenge that will be added to the URL
+ $challenge = hashSha256(generatePassword(128));
+
+ // Register or update the record
+ $registered = registerUpdateWernisRegistrationCall($args, $challenge, 'PENDING');
+
+ // Should always register/update
+ assert($registered === TRUE);
// Redirect to WDS66 module=auth ...
- redirectToUrl(getWernisBaseUrl() . '/modules.php?module=auth&auth_key=' . $args['auth_key'] . '&params=' . urlencode(base64_encode('&module=' . getModule() . '&what=' . getWhat())) . '&challenge=' . $challenge);
+ //* DEBUG-DIE */ die(__FUNCTION__ . ':' . __LINE__ . '<pre>' . print_r($args, TRUE) . '</pre>');
+ redirectToUrl(getWernisBaseUrl() . '/modules.php?module=auth&auth_key=' . trim($args['auth_key']) . '&params=' . urlencode(base64_encode('&module=' . getModule() . '&what=' . getWhat())) . '&challenge=' . $challenge, FALSE, FALSE);
}
// Handler for auth_status=ACCEPTED
// auth_key and wernis_userid must be set
assert(isset($args['auth_key']));
assert(isset($args['wernis_userid']));
- die(__FUNCTION__ . ':' . __LINE__ . '<pre>' . print_r($args, TRUE) . '</pre>');
+
+ // Get registration data by auth_key
+ $rows = getWernisRegistrationDataByKey('api_auth_key', $args['auth_key']);
+
+ // Is developer system?
+ if (isDeveloperSystem()) {
+ // Log whole rows array
+ logDebugMessage(__FUNCTION__, __LINE__, sprintf('args[%s]=%s,rows[%s]=%s', gettype($args), print_r($args, TRUE), gettype($rows), print_r($rows, TRUE)));
+ } // END - if
+
+ // Is rows empty?
+ if (count($rows) == 0) {
+ // Generate challenge
+ $challenge = hashSha256(generatePassword(128));
+
+ // Then register it ...
+ $registered = registerUpdateWernisRegistrationCall($args, $challenge, $args['auth_status']);
+
+ // Should always register/update
+ assert($registered === TRUE);
+
+ // ... and redirect to module=auth
+ redirectToUrl(getWernisBaseUrl() . '/modules.php?module=auth&auth_key=' . trim($args['auth_key']) . '&params=' . urlencode(base64_encode('&module=' . getModule() . '&what=' . getWhat())) . '&challenge=' . $challenge, FALSE, FALSE);
+ } // END - if
+
+ // The userid should be same
+ assert(isset($rows[0]['wernis_userid']));
+ assert($rows[0]['wernis_userid'] === $args['wernis_userid']);
+
+ // Check both challenge + response
+ assert(isset($rows[0]['api_redirect_challenge']));
+ assert(isset($rows[0]['api_challenge_response']));
+
+ // Both are fine, so get the data
+ $return = doWernisFinishUserRegistration($rows[0]['api_redirect_challenge'], $rows[0]['api_challenge_response'], '1');
+
+ // All fine?
+ if ($return === FALSE) {
+ // @TODO Should not happen???
+ reportBug(__FUNCTION__, __LINE__, 'args=<pre>' . print_r($args, TRUE) . '</pre>rows=<pre>' . print_r($rows, TRUE) . '</pre> - Failed!');
+ } // END - if
+
+ // Generate URL
+ $url = basename(detectRequestUri()) . '&challenge=' . $rows[0]['api_redirect_challenge'] . '&__challenge_response=' . $rows[0]['api_challenge_response'] . '&status=1';
+
+ // Redirect to URL
+ redirectToUrl($url);
+}
+
+//------------------------------------------------------------------------------
+// Template helper functions
+//------------------------------------------------------------------------------
+
+// Template helper to generate a selection box for encryption alogrithms
+function doTemplateSelectWernisEncryptionAlgorithm ($templateName, $clear = FALSE, $default = NULL) {
+ // Get all available algorithms
+ $algorithms = getSupportedEncryptionAlgorithms();
+ //* DEBUG-DIE */ die('algorithms=<pre>' . print_r($algorithms, TRUE) . '</pre>');
+
+ // Init array
+ $options = [];
+
+ // And fill it
+ foreach ($algorithms as $key => $dummy) {
+ $options[$key] = array('algorithms' => $key);
+ } // END - if
+
+ // Handle it over to generateSelectionBoxFromArray()
+ $content = generateSelectionBoxFromArray($options, 'wernis_encryption_algorithm', 'algorithms', '', '_wernis', '', $default, '', TRUE, FALSE);
+
+ // Return prepared content
+ return $content;
+}
+
+// Template helper to generate a selection box for encryption alogrithms
+function doTemplateSelectWernisEncryptionMode ($templateName, $clear = FALSE, $default = NULL) {
+ // Get all available modes
+ $modes = getSupportedEncryptionModes();
+
+ // Init array
+ $options = [];
+
+ // And fill it
+ foreach ($modes as $key => $dummy) {
+ $options[$key] = array('modes' => $key);
+ } // END - if
+
+ // Handle it over to generateSelectionBoxFromArray()
+ $content = generateSelectionBoxFromArray($options, 'wernis_encryption_mode', 'modes', '', '_wernis', '', $default, '', TRUE, FALSE);
+
+ // Return prepared content
+ return $content;
}
//-----------------------------------------------------------------------------
return $GLOBALS[__FUNCTION__];
}
+// Wrapper function for 'wernis_encryption_algorithm'
+function getWernisEncryptionAlgorithm () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Get config entry
+ $GLOBALS[__FUNCTION__] = getConfig('wernis_encryption_algorithm');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Wrapper function for 'wernis_encryption_mode'
+function getWernisEncryptionMode () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Get config entry
+ $GLOBALS[__FUNCTION__] = getConfig('wernis_encryption_mode');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
+// Wrapper function for 'wernis_private_key'
+function getWernisPrivateKey () {
+ // Is there cache?
+ if (!isset($GLOBALS[__FUNCTION__])) {
+ // Get config entry
+ $GLOBALS[__FUNCTION__] = getConfig('wernis_private_key');
+ } // END - if
+
+ // Return cache
+ return $GLOBALS[__FUNCTION__];
+}
+
// [EOF]
?>