X-Git-Url: https://git.mxchange.org/?p=mailer.git;a=blobdiff_plain;f=inc%2Flibs%2Fwernis_functions.php;h=263e40935d67291ca4f4e33c84b604d0e37058ce;hp=ff782fac567f9dbf6643cae438b06893ad6e0e46;hb=99966a712b3b3d8b521524762e153353d1d20bd4;hpb=87229cb5d7b5396793e85fd0b4172d473195835c diff --git a/inc/libs/wernis_functions.php b/inc/libs/wernis_functions.php index ff782fac56..263e40935d 100644 --- a/inc/libs/wernis_functions.php +++ b/inc/libs/wernis_functions.php @@ -219,15 +219,15 @@ function doAdminTestWernisApi () { // Prepare the request data $requestData = array( - 't_uid' => getWernisRefid(), - 't_md5' => getWernisPassMd5() + 't_uid' => getWernisRefid(), + 't_md5' => getWernisPassMd5() ); // Return the result from the lower functions $return = sendWernisApiRequest('balance.php', $requestData); // Did it went smoothly? - if ($return['status'] == 'OK') { + if (isHttpResponseStatusOkay($return)) { // All fine! $result = TRUE; } else { @@ -240,7 +240,7 @@ function doAdminTestWernisApi () { } // Widthdraw this amount -function executeWernisWithdraw ($wdsId, $userMd5, $amount) { +function executeWernisApiWithdraw ($wdsId, $userMd5, $amount) { // Is the sponsor extension installed? if (!isWernisWithdrawActive()) { if (!isExtensionActive('sponsor')) { @@ -268,7 +268,8 @@ function executeWernisWithdraw ($wdsId, $userMd5, $amount) { // Return the result from the lower functions $return = sendWernisApiRequest('book.php', $requestData); - if ($return['status'] == 'OK') { + // Did it went smoothly? + if (isHttpResponseStatusOkay($return)) { // All fine! $result = TRUE; @@ -287,7 +288,7 @@ function executeWernisWithdraw ($wdsId, $userMd5, $amount) { } // Payout this amount -function executeWernisPayout ($wdsId, $amount) { +function executeWernisApiPayout ($wdsId, $amount) { // Default is failed attempt $result = FALSE; @@ -304,7 +305,7 @@ function executeWernisPayout ($wdsId, $amount) { // Return the result from the lower functions $return = sendWernisApiRequest('book.php', $requestData); - if ($return['status'] == 'OK') { + if (isHttpResponseStatusOkay($return)) { // All fine! $result = TRUE; @@ -323,7 +324,7 @@ function executeWernisPayout ($wdsId, $amount) { } // Execute auth.php request -function executeWernisAuth ($wernisId, $wernisPassword) { +function executeWernisApiAuth ($wernisId, $wernisPassword) { // Prepare request data $requestData = array( 't_uid' => bigintval($wernisId), @@ -337,6 +338,32 @@ function executeWernisAuth ($wernisId, $wernisPassword) { return $return; } +// Execute get.php reguest with given auth data (not all are used) +function executeWernisApiGet ($authData, $subRequest, $fields) { + // It must be an array + assert(is_array($authData)); + + // Check required array elements + assert(isset($authData['wernis_userid'])); + assert(isset($authData['api_auth_key'])); + assert(isset($authData['api_redirect_challenge'])); + + // Then create request array + $requestData = array( + 'sub_request' => $subRequest, + 'fields' => $fields, + 't_uid' => bigintval($authData['wernis_userid']), + 'auth_key' => $authData['api_auth_key'], + 'challenge' => $authData['api_redirect_challenge'] + ); + + // Call get.php + $return = sendWernisApiRequest('get.php', $requestData); + + // Return full array + return $return; +} + // Translate the status IN/OUT function translateWernisTransferStatus ($status) { // Default status is unknown @@ -431,11 +458,11 @@ function doDisplayWernisUserRegistrationForm () { displayMessage('{--GUEST_WERNIS_REGISTRATION_PASSWORD_NOT_SET--}'); } else { // So far, all fine, then let's do the call-back on auth.php ... - $response = executeWernisAuth(postRequestElement('wernis_id'), postRequestElement('wernis_password')); + $response = executeWernisApiAuth(postRequestElement('wernis_id'), postRequestElement('wernis_password')); // Was the status okay? - if ((isset($response['status'])) && ($response['status'] == 'OK') && (!empty($response['response']))) { - // All fine, then analyze response + if (isHttpResponseStatusOkay($response)) { + // All fine, then analyze API response $args = convertApiResponseToArray($response['response'], '&', '='); // Is status set? @@ -455,7 +482,9 @@ function doDisplayWernisUserRegistrationForm () { // Then call it $status = call_user_func($callbackFunction, $args); - die(__FUNCTION__ . ': status[' . gettype($status) . ']=' . $status); + + // @TODO Something more to do here? + die(__FUNCTION__ . ':' . __LINE__ . ': status[' . gettype($status) . ']=' . $status . ' - Unfinished.'); } else { // Something bad happened displayMessage($response['message']); @@ -463,17 +492,17 @@ function doDisplayWernisUserRegistrationForm () { } } // END - if - // Is the form not sent? (E.g. missing form fields) + // Is there a challenge + response? if ((isGetRequestElementSet('status')) && (isGetRequestElementSet('challenge')) && (isGetRequestElementSet('__challenge_response'))) { // Redirect from modules.php?module=auth, so validate challenge response ... // 1) Get first 24 characters = salt $salt = substr(getRequestElement('__challenge_response'), 0, 24); - // 2) Generate hash again - $response = $salt . hashSha256($salt . getWernisApiMd5() . getRequestElement('challenge')); + // 2) Generate hash for challenge response + $challengeResponse = $salt . hashSha256($salt . getWernisApiMd5() . getRequestElement('challenge')); // Is the response valid? - if ($response != getRequestElement('__challenge_response')) { + if ($challengeResponse != getRequestElement('__challenge_response')) { // Not valid displayMessage('{--GUEST_WERNIS_REGISTRATION_INVALID_CHALLENGE_RESPONSE--}'); return; @@ -481,13 +510,240 @@ function doDisplayWernisUserRegistrationForm () { /* * Now, that the challenge-response is the same, the challenge itself - * is also the same. So get.php can be called. + * is also the same. Next get the data from wernis_regs table by + * challenge. There is currently no other way to get the data as there + * is no Wernis user id provided. Later on the stored challenge response + * can be compared with provided. */ - die('!ojk'); + $return = doWernisFinishUserRegistration(getRequestElement('challenge'), getRequestElement('__challenge_response'), getRequestElement('status')); + + // Is the registration finished? + if ($return === FALSE) { + // No, then abort here silently as the function should have already displayed a message + return; + } // END - if } elseif (!isFormSent('register')) { // Form not send, so load form template - loadTemplate('guest_wernis_registration_form'); + loadTemplate('guest_wernis_registration_rpc_form'); + } +} + +// Finish user registration with WDS66 API +function doWernisFinishUserRegistration ($challenge, $challengeResponse, $status) { + // Is the status 1? (= all fine with API call) + if ($status == '1') { + // Get mapped data based on challenge + $return = getWernisMappedDataFromApiByChallenge($challenge, $status); + + // Is the array filled? + if ((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']['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'); + + // Display form + loadTemplate('guest_wernis_registration_form', FALSE, $return['mapped_data']); + + // All fine + return TRUE; + } else { + // Something unexpected happened (e.g. no API requests left) + displayMessage($return['message']); + return FALSE; + } + } else { + // Status does not need to be changed + die(__FUNCTION__ . ':' . __LINE__ . ': Reached!'); + } +} + +// "Getter" for mapped data by calling the API and given challenge and status +function getWernisMappedDataFromApiByChallenge ($challenge, $status) { + // Get stored registration data + $rows = getWernisRegistrationDataByKey('api_redirect_challenge', $challenge); + + // Zero result found? + if (count($rows) == 0) { + // Nothing found + displayMessage('{--GUEST_WERNIS_REGISTRATION_ZERO_ROWS_FOUND--}'); + + // Display form + loadTemplate('guest_wernis_registration_rpc_form'); + return array(); + } // END - if + + // Init array + $return = array( + // Mapped data + 'mapped_data' => array(), + // Any error message from API + 'message' => '' + ); + + // Has the auth status changed? + if ($rows[0]['api_auth_status'] != 'ACCEPTED') { + /* + * The authorization of this application has been accepted, so + * update it and ignore result from function because the update + * will always run. + */ + updateWernisRegistrationDataByKey('api_auth_status', 'api_redirect_challenge', $challenge, 'ACCEPTED'); + } // 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? + 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)); + + // And decode it (all steps separated to later "easily" debug them) + $decodedData = base64_decode($encodedData); + + /* + * Do some checks on the decoded string, it should be a + * serialized array with 10 entries (see above + * executeWernisApiGet() call). + */ + assert(substr($decodedData, 0, 6) == 'a:10:{'); + assert(substr($decodedData, -1, 1) == '}'); + + // The array seems to be fine, unserialize it + $userData = unserialize($decodedData); + + // All mappings WDS66->mailer + $mappings = array( + 'vorname' => 'surname', + 'name' => 'family', + 'strasse' => 'street_nr', + 'plz' => 'zip', + 'ort' => 'city', + 'email' => 'email', + 'birth_day' => 'birth_day', + 'birth_month' => 'birth_month', + 'birth_year' => 'birth_year', + 'werber' => 'wernis_refid' + ); + + // Map all WDS66 entries into mailer entries + foreach ($mappings as $from => $to) { + // All must exist + if (!isset($userData[$from])) { + // Element $from does not exist + reportBug(__FUNCTION__, __LINE__, 'Cannot map from=' . $from . ' -> to=' . $to . ': element does not exist.'); + } // END - if + + // "Map" all + $return['mapped_data'][$to] = convertEmptyToNull($userData[$from]); + } // END - foreach + + // Both arrays must have same size + assert(count($userData) == count($return['mapped_data'])); + + // Now add userid from WDS66 + $return['mapped_data']['wernis_userid'] = bigintval($rows[0]['wernis_userid']); + } else { + // Something bad happened so copy the message + $return['message'] = $response['message']; + } + + // Return mapped data array + return $return; +} + +// Updates auth status by given key/value pair +function updateWernisRegistrationDataByKey ($updatedColumn, $key, $oldValue, $newValue) { + // Run the update + sqlQueryEscaped("UPDATE + `{?_MYSQL_PREFIX?}_wernis_regs` +SET + `%s` = '%s' +WHERE + `%s` = '%s' AND + `%s` != '%s' +LIMIT 1", + array( + $updatedColumn, + $newValue, + $key, + $oldValue, + $updatedColumn, + $oldValue + ), __FUNCTION__, __LINE__ + ); + + // Check if rows as been affected + return ifSqlHasZeroAffectedRows(); +} + +// "Getter" for Wernis registration data by given key and value +function getWernisRegistrationDataByKey ($key, $value, $limit = 1) { + // Init array + $rows = array(); + + // Now search for it + $result = sqlQueryEscaped("SELECT + `local_userid`, + `wernis_userid`, + `api_auth_status`, + `api_auth_key`, + `api_redirect_challenge`, + UNIX_TIMESTAMP(`record_inserted`) AS `record_inserted` +FROM + `{?_MYSQL_PREFIX?}_wernis_regs` +WHERE + `%s`='%s' +ORDER BY + `id` +LIMIT %d", + array( + $key, + $value, + $limit + ), __FUNCTION__, __LINE__ + ); + + // Is there an entry? + if (sqlNumRows($result) > 0) { + // At least one entry has been found, so loop through all + while ($row = sqlFetchArray($result)) { + // Add it + array_push($rows, $row); + } // END - while + } // END - if + + // Free result + sqlFreeResult($result); + + // Return found entries + return $rows; +} + +// Do local user registration with data from WDS66 API +function doWernisUserRegistration () { + // Call generic registration function + $status = doGenericUserRegistration(); + + // Does this went fine? + if ($status === FALSE) { + // No, then abort here silently + return FALSE; } // END - if + + // Make sure the user id is valid + assert(isset($GLOBALS['register_userid'])); + assert(isValidId($GLOBALS['register_userid'])); + + // Generic registration is finished, so add more data: } //----------------------------------------------------------------------------- @@ -496,8 +752,12 @@ function doDisplayWernisUserRegistrationForm () { // Handler for auth_status=PENDING function doWernisAuthPending ($args) { - // auth_key must be set + // $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)); @@ -522,9 +782,6 @@ function doWernisAuthPending ($args) { $challenge ), __FUNCTION__, __LINE__ ); - - // Should be inserted - assert(sqlAffectedRows() == 1); } else { // Update challenge sqlQueryEscaped("UPDATE @@ -542,15 +799,26 @@ LIMIT 1", bigintval($args['wernis_userid']) ), __FUNCTION__, __LINE__ ); - - // Should always be updated - assert(sqlAffectedRows() == 1); } + // Should always update/insert + assert(sqlAffectedRows() == 1); + // 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); } +// Handler for auth_status=ACCEPTED +function doWernisAuthAccepted ($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'])); + die(__FUNCTION__ . ':' . __LINE__ . '
' . print_r($args, TRUE) . '
'); +} + //----------------------------------------------------------------------------- // Wrapper functions //-----------------------------------------------------------------------------