Ejemplo n.º 1
0
function copyObjectWithSortedKeys($value)
{
    if (is_array($value)) {
        return array_map("copyObjectWithSortedKeys", $value);
    } else {
        if (is_object($value)) {
            $valueCopyWithSortedKeys = array();
            foreach ($value as $key => $value) {
                $valueCopyWithSortedKeys[$key] = copyObjectWithSortedKeys($value);
            }
            ksort($valueCopyWithSortedKeys);
            return $valueCopyWithSortedKeys;
        } else {
            return $value;
        }
    }
}
Ejemplo n.º 2
0
function pointrel20150417_storeMessage($apiRequest)
{
    global $wpdb;
    $message = $apiRequest->message;
    // error_log("Called pointrel20150417_storeMessage with: " . json_encode($message));
    $journalIdentifier = $apiRequest->journalIdentifier;
    // Check if topicIdentifier is not defined to avoid PHP warning
    if (isset($message->_topicIdentifier)) {
        $topicIdentifier = $message->_topicIdentifier;
    } else {
        $topicIdentifier = null;
    }
    faiIfNotAuthorized("write", $journalIdentifier, $topicIdentifier);
    $table_name = tableNameForJournal($journalIdentifier);
    $receivedTimestamp = getCurrentUniqueTimestamp();
    // Need to calculate SHA and length without trace and in canonical form as utf-8 encoded
    $oldSHA256AndLength = $message->__pointrel_sha256AndLength;
    $oldTrace = $message->__pointrel_trace;
    if ($oldTrace && !is_array($oldTrace)) {
        wp_send_json(makeFailureResponse(400, "Bad Request: trace field should be an array if it is defined"));
    }
    if (!$oldTrace) {
        $oldTrace = array();
    }
    // Calculate the sha256AndLength without the pointrel fields
    // Remove all "__pointrel_" tags from the top level, which includes sha256AndLength and trace and any other local metadata
    $cloneArray = $message;
    foreach ($cloneArray as $key => $value) {
        if (startsWith($key, "__pointrel_")) {
            unset($message->{$key});
        }
    }
    $canonicalMessageWithoutHashAndTrace = copyObjectWithSortedKeys($message);
    // $canonicalFormInUTF8 = my_json_encode($canonicalMessageWithoutHashAndTrace, JSON_UNESCAPED_UNICODE);
    $canonicalFormInUTF8 = my_json_encode($canonicalMessageWithoutHashAndTrace);
    $sha256AndLength = hash('sha256', $canonicalFormInUTF8) . "_" . strlen($canonicalFormInUTF8);
    if ($oldSHA256AndLength && $oldSHA256AndLength !== $sha256AndLength) {
        error_log("Problem with new calculated SHA not matching old supplied one: {$oldSHA256AndLength} new: {$sha256AndLength} ");
        error_log("canonicalFormInUTF8 was: {$canonicalFormInUTF8}");
        wp_send_json(makeFailureResponse(400, "Bad Request: sha256AndLength was supplied in message but it does not match the calculated value; old: {$oldSHA256AndLength} new: {$sha256AndLength}"));
    }
    if (isSHA256AndLengthIndexed($journalIdentifier, $sha256AndLength)) {
        wp_send_json(makeFailureResponse(409, "Conflict: The message already exists on the server", array("sha256AndLength" => $sha256AndLength)));
    }
    $message->__pointrel_sha256AndLength = $sha256AndLength;
    // TODO: Determine server name
    $serverName = "UNFINISHED_SERVER_NAME";
    // Maybe could improve on this; see: http://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php
    $senderIPAddress = $_SERVER['REMOTE_ADDR'];
    $userIdentifier = wp_get_current_user()->user_login;
    $receivedTimestamp = getCurrentUniqueTimestamp();
    // Put in some local information
    // TODO: More thinking about the meaning of a trace???
    // TODO: Add more info about who stored this information
    // TODO: Maybe add other things, like requester IP or user identifier?
    $traceEntry = array("receivedByJournalIdentifier" => $journalIdentifier, "receivedByServer" => $serverName, "senderIPAddress" => $senderIPAddress, "userIdentifier" => $userIdentifier, "receivedTimestamp" => $receivedTimestamp);
    $oldTrace[] = $traceEntry;
    $message->__pointrel_trace = $oldTrace;
    $canonicalMessage = copyObjectWithSortedKeys($message);
    // $messageText = my_json_encode($canonicalMessage, JSON_UNESCAPED_UNICODE);
    $messageText = my_json_encode($canonicalMessage);
    // TODO: Check for empty topic and maybe act differently
    $topicSHA256 = hash('sha256', $topicIdentifier);
    $topicTimestamp = $message->_topicTimestamp;
    /*
        id int(9) UNSIGNED NOT NULL AUTO_INCREMENT,
        sha256_and_length char(73) NOT NULL,
        received_timestamp char(30) NOT NULL, 
        topic_sha256 char(64) NOT NULL,
        topic_timestamp char(30) NOT NULL,
        message mediumtext NOT NULL,
    */
    // TODO: Remove this
    // error_log("pointrel20150417_storeMessage: everything OK and ready to store -- but not storing for now as test");
    // throw new Exception("storing disabled for now while test canonical JSON SHA calculation");
    $wpdb->insert($table_name, array('sha256_and_length' => $sha256AndLength, 'received_timestamp' => $receivedTimestamp, 'topic_sha256' => $topicSHA256, 'topic_timestamp' => $topicTimestamp, 'message' => $messageText));
    $insert_id = $wpdb->insert_id;
    // error_log("pointrel20150417_storeMessage inserted row " . $insert_id);
    $response = makeSuccessResponse(200, "Success", array('detail' => 'Wrote content', 'sha256AndLength' => $sha256AndLength, 'receivedTimestamp' => $receivedTimestamp, 'insert_id' => $insert_id));
    wp_send_json($response);
}