getSocket(ZMQ::SOCKET_PUB, "pub-a-dub-dub"); $queue->setSockOpt(ZMQ::SOCKOPT_LINGER, $config['zmq_linger']); if (is_array($config['relay_inbound'])) { // API for fedmsg >= 0.5.2 // TODO - be more robust here and if connecting to the first one fails, try // the next, and the next, and etc... $queue->connect($config['relay_inbound'][0]); } else { // API for fedmsg <= 0.5.1 $queue->connect($config['relay_inbound']); } # Go to sleep for a brief moment.. just long enough to let our zmq socket # initialize. if (array_key_exists('post_init_sleep', $config)) { usleep($config['post_init_sleep'] * 1000000); } return true; } # Register our hooks with mediawiki $wgHooks['ArticleSaveComplete'][] = 'article_save'; $wgHooks['UploadComplete'][] = 'upload_complete'; # This is a reimplementation of the python code in fedmsg/crypto.py # That file is authoritative. Changes there should be reflected here. function sign_message($message_obj) { global $config; # This is required so that the string we sign is identical in python and in # php. Ordereddict is used there; ksort here. deep_ksort($message_obj); # It would be best to pass JSON_UNESCAPE_SLASHES as an option here, but it is # not available until php-5.4 $message = json_encode($message_obj); # In the meantime, we'll remove escaped slashes ourselves. This is # necessary in order to produce the exact same encoding as python (so that our # signatures match for validation). $message = stripcslashes($message); # Use this to debug message signature problems. What a pain... #wfErrorLog($message . "\r\n", '/var/tmp/wiki-fedmsg-messages.log' ); # Step 0) - Find our cert. $fqdn = gethostname(); $tokens = explode('.', $fqdn); $hostname = $tokens[0]; $ssldir = $config['ssldir']; $certname = $config['certnames']['mediawiki.'.$hostname]; # Step 1) - Load and encode the X509 cert $cert_obj = openssl_x509_read(file_get_contents( $ssldir.'/'.$certname.".crt" )); $cert = ""; openssl_x509_export($cert_obj, $cert); $cert = base64_encode($cert); # Step 2) - Load and sign the jsonified message with the RSA private key $rsa_private = openssl_get_privatekey(file_get_contents( $ssldir.'/'.$certname.".key" )); $signature = ""; openssl_sign($message, $signature, $rsa_private); $signature = base64_encode($signature); # Step 3) - Stuff it back in the message and return $message_obj['signature'] = $signature; $message_obj['certificate'] = $cert; $message_obj['crypto'] = 'x509'; return $message_obj; } function emit_message($subtopic, $message) { global $config, $queue; # Re-implement some of the logc from fedmsg/core.py # We'll have to be careful to keep this up to date. $prefix = "org.fedoraproject." . $config['environment'] . ".wiki."; $topic = $prefix . $subtopic; $message_obj = array( "topic" => $topic, "msg" => $message, "timestamp" => round(time(), 3), "msg_id" => date("Y") . "-" . uuid_create(), "username" => "apache", # TODO -> we don't have a good way to increment this counter from php yet. "i" => 1, ); if (array_key_exists('sign_messages', $config) and to_bool($config['sign_messages'])) { $message_obj = sign_message($message_obj); } $envelope = json_encode($message_obj); $queue->send($topic, ZMQ::MODE_SNDMORE); $queue->send($envelope); } function article_save( &$article, &$user, $text, $summary, $minoredit, $watchthis, $sectionanchor, &$flags, $revision, &$status, $baseRevId ) { # If for some reason or another we can't create our socket, then bail. if (!initialize()) { return false; } $topic = "article.edit"; $title = $article->getTitle(); if ( $title->getNsText() ) { $titletext = $title->getNsText() . ":" . $title->getText(); } else { $titletext = $title->getText(); } if ( is_object($revision) ) { $url = $title->getFullURL('diff=prev&oldid=' . $revision->getId()); } else { $url = $title->getFullURL(); } # Just send on all the information we can... change the attr names to be # more pythonic in style, though. $msg = array( "title" => $titletext, "user" => $user->getName(), "minor_edit" => $minoredit, "watch_this" => $watchthis, "section_anchor" => $sectionanchor, "revision" => $revision, "base_rev_id" => $baseRevId, "url" => $url, #"summary" => $summary, # We *used* to send this, but it mucked things up. # https://fedorahosted.org/fedora-infrastructure/ticket/3738#comment:7 #"text" => $text, # We *could* send this, but it's a lot of spam. # TODO - flags? # TODO - status? ); emit_message($topic, $msg); return true; } function upload_complete(&$image) { # If for some reason or another we can't create our socket, then bail. if (!initialize()) { return false; } $topic = "upload.complete"; $msg = array( "file_exists" => $image->getLocalFile()->fileExists, // 1 or 0 "media_type" => $image->getLocalFile()->media_type, // examples: "AUDIO", "VIDEO", ... "mime" => $image->getLocalFile()->mime, // example: audio/mp3 "major_mime" => $image->getLocalFile()->major_mime, // e.g. audio "minor_mime" => $image->getLocalFile()->minor_mime, // e.g. mp3 "size" => $image->getLocalFile()->size, //in bytes, e.g. 2412586 "user_id" => $image->getLocalFile()->user, // int userId "user_text" => $image->getLocalFile()->user_text, // the username "description" => $image->getLocalFile()->description, "url" => $image->getLocalFile()->url, // gives the relavive url for direct access of the uploaded media ); # I know it seems peculiar to have an array here with only one element. # https://github.com/fedora-infra/fedmsg_meta_fedora_infrastructure/pull/174 $msg['title'] = array( "mPrefixedText" => $image->getLocalFile()->getTitle()->getPrefixedText(), ); emit_message($topic, $msg); return true; } ?>