public function postComment(Services_User_Record $svcUserRecord, array $user, array $comment) { $result = new Dto_FormResult(); $commentDao = $this->_daoFactory->getCommentDao(); # Make sure the anonymous user and reserved usernames cannot post content if (!$svcUserRecord->allowedToPost($user)) { $result->addError(_("You need to login to be able to post comments")); } # if # Retrieve the users' private key $user['privatekey'] = $svcUserRecord->getUserPrivateRsaKey($user['userid']); /* * We'll get the messageid's with <>'s but we always strip * them in Spotweb, so remove them */ $comment['newmessageid'] = substr($comment['newmessageid'], 1, -1); # we won't bother when the hashcash is not properly calculcated if (substr(sha1('<' . $comment['newmessageid'] . '>'), 0, 4) != '0000') { $result->addError(_('Hash was not calculated properly')); } # if # Body cannot be either empty or very short $comment['body'] = trim($comment['body']); if (strlen($comment['body']) < 2) { $result->addError(_('Please enter a comment')); } # if if (strlen($comment['body']) > 1024 * 10) { $result->addError(_('Comment is too long')); } # if # Rating must be within range if ($comment['rating'] > 10 || $comment['rating'] < 0) { $result->addError(_('Invalid rating')); } # if /* * The "newmessageid" is based upon the messageid we are replying to, * this is to make sure a user cannot reuse an calculated hashcash * for an spam attack on different posts */ $replyToPart = substr($comment['inreplyto'], 0, strpos($comment['inreplyto'], '@')); if (substr($comment['newmessageid'], 0, strlen($replyToPart)) != $replyToPart) { $result->addError(_('Replay attack!?')); } # if /* * Make sure the random message we require in the system has not been * used recently to prevent one calculated hashcash to be reused again * and again */ if (!$commentDao->isCommentMessageIdUnique($comment['newmessageid'])) { $result->addError(_('Replay attack!?')); } # if # Make sure a newmessageid contains a certain length if (strlen($comment['newmessageid']) < 10) { $result->addError(_('MessageID too short!?')); } # if # Retrieve the spot to which we are commenting $svcProvFullSpot = new Services_Providers_FullSpot($this->_daoFactory->getSpotDao(), $this->_nntp_hdr); $fullSpot = $svcProvFullSpot->fetchFullSpot($comment['inreplyto'], $user['userid']); # Add the title as a comment property $comment['title'] = 'Re: ' . $fullSpot['title']; /* * Body is UTF-8 (we instruct the browser to do everything in UTF-8), but * usenet wants its body in iso-8859-1. * * The database requires UTF8 again, so we keep seperate bodies for * the database and for the system */ $dbComment = $comment; $comment['body'] = utf8_decode($comment['body']); # and actually post the comment if ($result->isSuccess()) { try { $this->_nntp_post->postComment($user, $this->_settings->get('privatekey'), $this->_settings->get('comment_group'), $comment); $commentDao->addPostedComment($user['userid'], $dbComment); } catch (Exception $x) { $result->addError($x->getMessage()); } # catch } # if return $result; }
public function postSpamReport(Services_User_Record $svcUserRecord, array $user, array $report) { $result = new Dto_FormResult(); $spotReportDao = $this->_daoFactory->getSpotReportDao(); # Make sure the anonymous user and reserved usernames cannot post content if (!$svcUserRecord->allowedToPost($user)) { $result->addError(_("You need to login to be able to report spam")); } # if # Retrieve the users' private key $user['privatekey'] = $svcUserRecord->getUserPrivateRsaKey($user['userid']); # Make sure no spam report has already been posted by this user to prevent flooding if ($spotReportDao->isReportPlaced($report['inreplyto'], $user['userid'])) { $result->addError(_('This spot has already been reported')); } # if /* * We'll get the messageid's with <>'s but we always strip * them in Spotweb, so remove them */ $report['newmessageid'] = substr($report['newmessageid'], 1, -1); # retrieve the spot this is a report of $svcProvFullSpot = new Services_Providers_FullSpot($this->_daoFactory, $this->_nntp_hdr); $fullSpot = $svcProvFullSpot->fetchFullSpot($report['inreplyto'], $user['userid']); # we won't bother when the hashcash is not properly calculcated if (substr(sha1('<' . $report['newmessageid'] . '>'), 0, 4) != '0000') { $result->addError(_('Hash was not calculated properly')); } # if # Body cannot be empty or very short $report['body'] = trim($report['body']); if (strlen($report['body']) < 2) { $result->addError(_('Please provide a reason why this Spot should be reported')); } # if # controleer dat de messageid waarop we replyen overeenkomt # met het newMessageid om replay-attacks te voorkomen. $replyToPart = substr($report['inreplyto'], 0, strpos($report['inreplyto'], '@')); if (substr($report['newmessageid'], 0, strlen($replyToPart)) != $replyToPart) { $result->addError(_('Replay attack!?')); } # if /* * Make sure the random message we require in the system has not been * used recently to prevent one calculated hashcash to be reused again * and again */ if (!$spotReportDao->isReportMessageIdUnique($report['newmessageid'])) { $result->addError(_('Replay attack!?')); } # if # Make sure a newmessageid consists of a certain length if (strlen($report['newmessageid']) < 10) { $result->addError(_('MessageID too short!?')); } # if /* * Body is UTF-8 (we instruct the browser to do everything in UTF-*), but * usenet wants its body in UTF-8. * * The database requires UTF8 again, so we keep seperate bodies for * the database and for the system */ $dbReport = $report; $report['body'] = utf8_decode($report['body']); $report['title'] = 'REPORT <' . $report['inreplyto'] . '> ' . $fullSpot['title']; # en post daadwerkelijk de report if ($result->isSuccess()) { $this->_nntp_post->reportSpotAsSpam($user, $this->_settings->get('privatekey'), $this->_settings->get('report_group'), $report); $spotReportDao->addPostedReport($user['userid'], $dbReport); } # if return $result; }
public function postSpot(Services_User_Record $svcUserRecord, array $user, array $spot, $imageFilename, $nzbFilename) { $result = new Dto_FormResult(); $spotDao = $this->_daoFactory->getSpotDao(); # Make sure the anonymous user and reserved usernames cannot post content if (!$svcUserRecord->allowedToPost($user)) { $result->addError(_("You need to login to be able to post spots")); } # if # Retrieve the users' private key $user['privatekey'] = $svcUserRecord->getUserPrivateRsaKey($user['userid']); $hdr_newsgroup = $this->_settings->get('hdr_group'); $bin_newsgroup = $this->_settings->get('nzb_group'); /* * We'll get the messageid's with <>'s but we always strip * them in Spotweb, so remove them */ $spot['newmessageid'] = substr($spot['newmessageid'], 1, -1); /* $hdr_newsgroup = 'alt.test'; $bin_newsgroup = 'alt.test'; */ # If the hashcash doesn't match, we will never post it if (substr(sha1('<' . $spot['newmessageid'] . '>'), 0, 4) != '0000') { $result->addError(_('Hash was not calculated properly')); } # if # Verify several properties from the caller $result->addData('spot', $spot); $result = $this->_spotValidator->verifyTitle($result); $result = $this->_spotValidator->verifyBody($result); $result = $this->_spotValidator->verifyCategories($result); $result = $this->_spotValidator->verifyWebsite($result); $result = $this->_spotValidator->verifyTag($result); /* * Retrieve the spot information from the result, * and remove it again. We do not want to send the * whole spot back to the caller */ $spot = $result->getData('spot'); $result->removeData('spot'); # Read the contents of image so we can check it $imageContents = file_get_contents($imageFilename); # the image should be below 1MB if (strlen($imageContents) > 1024 * 1024) { $result->addError(_('Uploaded image is too large (maximum 1MB)')); } # if /* * Get some image information, if it fails, this is an * error as well */ $tmpGdImageSize = getimagesize($imageFilename); if ($tmpGdImageSize === false) { $result->addError(_('Uploaded image was not recognized as an image')); } else { $imageInfo = array('width' => $tmpGdImageSize[0], 'height' => $tmpGdImageSize[1]); } # if /* * Load the NZB file as an XML file so we can make sure * it's a valid XML and NZB file and we can determine the * filesize */ $nzbFileContents = file_get_contents($nzbFilename); $nzbXml = simplexml_load_string($nzbFileContents); # Do some basic sanity checking for some required NZB elements if (empty($nzbXml->file)) { $result->addError(_('Incorrect NZB file')); } # if # and determine the total filesize $spot['filesize'] = 0; foreach ($nzbXml->file as $file) { foreach ($file->segments->segment as $seg) { $spot['filesize'] += (int) $seg['bytes']; } # foreach } # foreach /* * Make sure we didn't use this messageid recently or at all, this * prevents people from not recalculating the hashcash in order to spam * the system */ if (!$spotDao->isNewSpotMessageIdUnique($spot['newmessageid'])) { $result->addError(_('Replay attack!?')); } # if # Make sure a newmessageid contains a certain length if (strlen($spot['newmessageid']) < 10) { $result->addError(_('MessageID too short!?')); } # if # We require the keyid 7 because it is selfsigned $spot['key'] = 7; # Poster's username $spot['poster'] = $user['username']; # actually post the spot if ($result->isSuccess()) { /* * Retrieve the image information and post the image to * the appropriate newsgroup so we have the messageid list of * images */ $imgSegmentList = $this->_nntp_post->postBinaryMessage($user, $bin_newsgroup, $imageContents, ''); $imageInfo['segments'] = $imgSegmentList; # Post the NZB file to the appropriate newsgroups $nzbSegmentList = $this->_nntp_post->postBinaryMessage($user, $bin_newsgroup, gzdeflate($nzbFileContents), ''); # Convert the current Spotnet info, to an XML structure $spotCreator = new Services_Format_Creation(); $spotXml = $spotCreator->convertSpotToXml($spot, $imageInfo, $nzbSegmentList); $spot['spotxml'] = $spotXml; # And actually post to the newsgroups $this->_nntp_post->postFullSpot($user, $this->_settings->get('privatekey'), $hdr_newsgroup, $spot); $spotDao->addPostedSpot($user['userid'], $spot, $spotXml); } # if return $result; }