public function updateSpotXml($fullSpot, $updatesToApply) { $result = new Dto_FormResult(); /* * before we merge we first want to clean the form from the stuff * we don't want to merge with the original spot */ $spot = $this->cleanseUpdates($updatesToApply); /* * subcat must be an array so let's make it an array if it is not, * otherwise we get in trouble in the verifyCategories() method */ if (!is_array($spot['subcatb'])) { $spot['subcatb'] = array(); } if (!is_array($spot['subcatc'])) { $spot['subcatc'] = array(); } if (!is_array($spot['subcatd'])) { $spot['subcatd'] = array(); } # 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'); if ($result->isSuccess()) { # We now merge the cleaned edit form into the original spot $spot = array_merge($fullSpot, $spot); $imageInfo = array('height' => $spot['image']['height'], 'width' => $spot['image']['width'], 'segments' => $spot['image']['segment']); $nzbSegmentList = $spot['nzb']; # Parse the updated spot to an XML structure $spotCreator = new Services_Format_Creation(); $spotXml = $spotCreator->convertSpotToXml($spot, $imageInfo, $nzbSegmentList); $result->addData('spotxml', $spotXml); } # 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; }
function validateSettings($settings) { $result = new Dto_FormResult(); # Define arrays with valid settings $validNntpEnc = array(false, 'ssl', 'tls'); $validModerationAction = array('disable', 'act', 'markspot'); $validRetentionTypes = array('fullonly', 'everything'); # Get the given value for NNTP encryption $settings['nntp_nzb']['enc'] = isset($settings['nntp_nzb']['enc']['switch']) ? $settings['nntp_nzb']['enc']['select'] : false; $settings['nntp_hdr']['enc'] = isset($settings['nntp_hdr']['enc']['switch']) ? $settings['nntp_hdr']['enc']['select'] : false; $settings['nntp_post']['enc'] = isset($settings['nntp_post']['enc']['switch']) ? $settings['nntp_post']['enc']['select'] : false; # Trim human-entered text fields $settings['nntp_nzb']['host'] = trim($settings['nntp_nzb']['host']); $settings['nntp_hdr']['host'] = trim($settings['nntp_hdr']['host']); $settings['nntp_post']['host'] = trim($settings['nntp_post']['host']); # Verify settings with the previous declared arrays if (in_array($settings['nntp_nzb']['enc'], $validNntpEnc) === false || in_array($settings['nntp_hdr']['enc'], $validNntpEnc) === false || in_array($settings['nntp_post']['enc'], $validNntpEnc) === false) { $result->addError(_('Invalid encryption setting')); } # if if (in_array($settings['spot_moderation'], $validModerationAction) === false) { $result->addError(_('Invalid spot moderation setting')); } # if if (in_array($settings['retentiontype'], $validRetentionTypes) === false) { $result->addError(_('Invalid spot retentiontype setting')); } # if # Verify settings $settings['cookie_expires'] = (int) $settings['cookie_expires']; if ($settings['cookie_expires'] < 0) { $result->addError(_('Invalid cookie_expires setting')); } # if $settings['retention'] = (int) $settings['retention']; if ($settings['retention'] < 0) { $result->addError(_('Invalid retention setting')); } # if $settings['retrieve_newer_than'] = strtotime($settings['retrieve_newer_than']); if ($settings['retrieve_newer_than'] === false || $settings['retrieve_newer_than'] > time()) { $result->addError(_('Invalid retrieve_newer_than setting')); } elseif ($settings['retrieve_newer_than'] < 1230789600) { /* We don't allow settings earlier than january 1st 2009 */ $settings['retrieve_newer_than'] = 1230789600; } # elseif $settings['retrieve_increment'] = (int) $settings['retrieve_increment']; if ($settings['retrieve_increment'] < 1) { $result->addError(_('Invalid retrieve_increment setting')); } # if # check the mailaddress if (!filter_var($settings['systemfrommail'], FILTER_VALIDATE_EMAIL)) { $result->addError(_('Not a valid email address')); } # if # We don't want to save megabyts of CSS, so put a limit to the size if (strlen($settings['customcss'] > 1024 * 10)) { $result->addError(_('Custom CSS is too large')); } # if # Convert other settings (usually checkboxes) to be simply boolean settings $settings['deny_robots'] = isset($settings['deny_robots']) ? true : false; $settings['sendwelcomemail'] = isset($settings['sendwelcomemail']) ? true : false; $settings['nntp_nzb']['buggy'] = isset($settings['nntp_nzb']['buggy']) ? true : false; $settings['nntp_hdr']['buggy'] = isset($settings['nntp_hdr']['buggy']) ? true : false; $settings['nntp_post']['buggy'] = isset($settings['nntp_post']['buggy']) ? true : false; $settings['retrieve_full'] = isset($settings['retrieve_full']) ? true : false; $settings['prefetch_image'] = isset($settings['prefetch_image']) ? true : false; $settings['prefetch_nzb'] = isset($settings['prefetch_nzb']) ? true : false; $settings['retrieve_comments'] = isset($settings['retrieve_comments']) ? true : false; $settings['retrieve_full_comments'] = isset($settings['retrieve_full_comments']) ? true : false; $settings['retrieve_reports'] = isset($settings['retrieve_reports']) ? true : false; $settings['enable_timing'] = isset($settings['enable_timing']) ? true : false; $settings['enable_stacktrace'] = isset($settings['enable_stacktrace']) ? true : false; $settings['prepare_statistics'] = isset($settings['prepare_statistics']) ? true : false; $settings['external_blacklist'] = isset($settings['external_blacklist']) ? true : false; $settings['external_whitelist'] = isset($settings['external_whitelist']) ? true : false; $settings['imageover_subcats'] = isset($settings['imageover_subcats']) ? true : false; # Default server settings if they won't be used if (!isset($settings['nntp_hdr']['use'])) { $settings['nntp_hdr'] = array('host' => '', 'user' => '', 'pass' => '', 'enc' => false, 'port' => 119, 'buggy' => false); } # if if (!isset($settings['nntp_post']['use'])) { $settings['nntp_post'] = array('host' => '', 'user' => '', 'pass' => '', 'enc' => false, 'port' => 119, 'buggy' => false); } # if /* * Remove dummy preferences */ unset($settings['nntp_hdr']['use'], $settings['nntp_post']['use']); /* * We want to pass the updated settings back to the caller because * we fixed several stuff. */ $result->addData('settings', $settings); return $result; }
/** * Make sure the correct categories are chosen * * @param Dto_FormResult $result * @return Dto_FormResult */ public function verifyCategories(Dto_FormResult $result) { $spot = $result->getData('spot'); /* Make sure the category is valid * We use array_key_exists() to allow for gaps in the category numbering. This is an intentional * deviation from similar code used in Services_Posting_Spot.php */ if (!array_key_exists($spot['category'], SpotCategories::$_head_categories)) { $result->addError(sprintf(_('Incorrect headcategory (%s)'), $spot['category'])); } # if # Make sure the subcategories are in the proper format if (is_array($spot['subcata']) || is_array($spot['subcatz']) || !is_array($spot['subcatb']) || !is_array($spot['subcatc']) || !is_array($spot['subcatd'])) { $result->addError(_('Invalid subcategories given')); } # if # create a list of the chosen subcategories $spot['subcatlist'] = array_merge(array($spot['subcata']), $spot['subcatb'], $spot['subcatc'], $spot['subcatd']); /* * Loop through all subcategories and check if they are valid in * our list of subcategories */ $subCatSplitted = array('a' => array(), 'b' => array(), 'c' => array(), 'd' => array(), 'z' => array()); foreach ($spot['subcatlist'] as $subCat) { $subcats = explode('_', $subCat); # If not in our format if (count($subcats) != 3) { $result->addError(sprintf(_('Incorrect subcategories (%s)'), $subCat)); } else { $subCatLetter = substr($subcats[2], 0, 1); $subCatSplitted[$subCatLetter][] = $subCat; if (!isset(SpotCategories::$_categories[$spot['category']][$subCatLetter][substr($subcats[2], 1)])) { $result->addError(sprintf(_('Incorrect subcategories (%s)'), $subCat . ' !! ' . $subCatLetter . ' !! ' . substr($subcats[2], 1))); } # if } # else } # foreach /* * Make sure all subcategories are in the format we expect, for * example we strip the 'cat' part and strip the z-subcat */ $subcatCount = count($spot['subcatlist']); for ($i = 0; $i < $subcatCount; $i++) { $subcats = explode('_', $spot['subcatlist'][$i]); # If not in our format if (count($subcats) != 3) { $result->addError(sprintf(_('Incorrect subcategories (%s)'), $spot['subcatlist'][$i])); } else { $spot['subcatlist'][$i] = substr($subcats[2], 0, 1) . str_pad(substr($subcats[2], 1), 2, '0', STR_PAD_LEFT); # Explicitly add the 'z'-category - we derive it from the full categorynames we already have $zcatStr = substr($subcats[1], 0, 1) . str_pad(substr($subcats[1], 1), 2, '0', STR_PAD_LEFT); if (is_numeric(substr($subcats[1], 1)) && array_search($zcatStr, $spot['subcatlist']) === false) { $spot['subcatlist'][] = $zcatStr; } # if } # else } # for # Make sure the spot isn't being posted in many categories if (count($subCatSplitted['a']) > 1) { $result->addError(_('You can only specify one format for a spot')); } # if # Make sure the spot has at least a format if (count($subCatSplitted['a']) < 1) { $result->addError(_('You need to specify a format for a spot')); } # if # Make sure the spot isn't being posted for too many categories if (count($spot['subcatlist']) > 10) { $result->addError(_('Too many categories')); } # if # Make sure the spot isn't being posted for too many categories # The "A"-subcategory, and the "Z" subcategory are always selected by # the form, so we need to check for 3 if (count($spot['subcatlist']) < 3) { $result->addError(_('At least one category need to be selected')); } # if $result->addData('spot', $spot); return $result; }
function validateUserPreferences($prefs, $currentPrefs) { $result = new Dto_FormResult(); # Define several arrays with valid settings $validDateFormats = array('human', '%a, %d-%b-%Y (%H:%M)', '%d-%m-%Y (%H:%M)'); $validTemplates = array_keys($this->_settings->get('valid_templates')); $validDefaultSorts = array('', 'stamp'); $validLanguages = array_keys($this->_settings->get('system_languages')); # Check per page setting $prefs['perpage'] = (int) $prefs['perpage']; if ($prefs['perpage'] < 2 || $prefs['perpage'] > 250) { $result->addError(_('Invalid preference value (perpage)')); } # if # Controleer basis settings if (in_array($prefs['date_formatting'], $validDateFormats) === false) { $result->addError(_('Invalid user preference value (date_formatting)')); } # if if (in_array($prefs['normal_template'], $validTemplates) === false) { $result->addError(_('Invalid user preference value (template)')); } # if if (in_array($prefs['mobile_template'], $validTemplates) === false) { $result->addError(_('Invalid user preference value (template)')); } # if if (in_array($prefs['tablet_template'], $validTemplates) === false) { $result->addError(_('Invalid user preference value (template)')); } # if if (in_array($prefs['user_language'], $validLanguages) === false) { $result->addError(_('Invalid user preference value (language)')); } # if if (in_array($prefs['defaultsortfield'], $validDefaultSorts) === false) { $result->addError(_('Invalid user preference value (defaultsortfield)')); } # if # when an sabnzbd host is entered, it has to be a valid URL if ($prefs['nzbhandling']['action'] == 'client-sabnzbd' || $prefs['nzbhandling']['action'] == 'push-sabnzbd') { $tmpHost = parse_url($prefs['nzbhandling']['sabnzbd']['url']); if ($tmpHost === false | !isset($tmpHost['scheme']) || $tmpHost['scheme'] != 'http' && $tmpHost['scheme'] != 'https') { $result->addError(_('sabnzbd host is not a valid URL')); } # if # SABnzbd URL should always end with a s slash if (substr($prefs['nzbhandling']['sabnzbd']['url'], -1) !== '/') { $prefs['nzbhandling']['sabnzbd']['url'] .= '/'; } # if } # if # when an nzbget host is entered, it has to be a valid URL if ($prefs['nzbhandling']['action'] == 'nzbget') { if (empty($prefs['nzbhandling']['nzbget']['host'])) { $result->addError(_("Host entered for nzbget is not valid")); } # if if (empty($prefs['nzbhandling']['nzbget']['port'])) { $result->addError(_("Port entered for nzbget is not valid")); } # if } # if # Twitter tokens are never posted by the form, but they shouldn't be tossed out $prefs['notifications']['twitter']['screen_name'] = $currentPrefs['notifications']['twitter']['screen_name']; $prefs['notifications']['twitter']['access_token'] = $currentPrefs['notifications']['twitter']['access_token']; $prefs['notifications']['twitter']['access_token_secret'] = $currentPrefs['notifications']['twitter']['access_token_secret']; $prefs['notifications']['twitter']['request_token'] = $currentPrefs['notifications']['twitter']['request_token']; $prefs['notifications']['twitter']['request_token_secret'] = $currentPrefs['notifications']['twitter']['request_token_secret']; # We don't want to save megabyts of CSS, so put a limit to the size if (strlen($prefs['customcss'] > 1024 * 10)) { $result->addError(_('Custom CSS is too large')); } # if # We don't want to save megabytes of default newspot body, so limit it if (strlen($prefs['newspotdefault_tag'] > 90)) { $result->addError(_('Default value for a spots\' tag is too long')); } # if if (strlen($prefs['newspotdefault_body'] > 9000)) { $result->addError(_('Default value for a spots\' body is too long')); } # if # When a 'runcommand' or 'save' action is chosen, 'local_dir' is a mandatry setting if ($prefs['nzbhandling']['action'] == 'save' || $prefs['nzbhandling']['action'] == 'runcommand') { if (empty($prefs['nzbhandling']['local_dir'])) { $result->addError(_('When NZB handling is either "save" or "runcommand" the directory must be entered')); } # if } # if # When a 'runcommand' action is chosen, 'command' is a mandatry setting if ($prefs['nzbhandling']['action'] == 'runcommand') { if (empty($prefs['nzbhandling']['command'])) { $result->addError(_('When NZB handling is "runcommand" a command must be entered')); } # if } # if # For the 'growl' notification provider, a host is mandatory if ($prefs['notifications']['growl']['enabled']) { if (empty($prefs['notifications']['growl']['host'])) { $result->addError(_('Growl notifications require a growl host to be entered')); } # if } # if # 'Notify My Android' requires an API key if ($prefs['notifications']['nma']['enabled']) { if (empty($prefs['notifications']['nma']['api'])) { $result->addError(_('"Notify My Android" notifications require an API key')); } # if } # if # 'Notifo' requires both a username and apikey if ($prefs['notifications']['notifo']['enabled']) { if (empty($prefs['notifications']['notifo']['username'])) { $result->addError(_('"Notifo" notifications require an username to be entered')); } # if if (empty($prefs['notifications']['notifo']['api'])) { $result->addError(_('"Notifo" notifications require an api key to be entered')); } # if } # if # 'Prowl' requires an API key if ($prefs['notifications']['prowl']['enabled']) { if (empty($prefs['notifications']['prowl']['apikey'])) { $result->addError(_('"Prowl" notifications require an API key to be entered')); } # if } # if # To use Twitter, an twitter account should be defined if ($prefs['notifications']['twitter']['enabled']) { if (empty($prefs['notifications']['twitter']['access_token']) || empty($prefs['notifications']['twitter']['access_token_secret'])) { $result->addError(_('To use twitter you need to enter and validate a twitter account')); } # if } # if /* Make sure a valid value for minimum_reportcount is entered */ if (!is_numeric($prefs['minimum_reportcount']) || $prefs['minimum_reportcount'] > 10) { $result->addError(_('Invalid value for minimum_reportcount')); } # if /* * We want to return the fixed up preferences to the caller */ $result->addData('prefs', $prefs); return $result; }
public function xmlToFilters($xmlStr) { $filterList = array(); /* * Parse the XML file */ $xml = @new SimpleXMLElement($xmlStr); # We can only parse version 1.0 of the filters if ((string) $xml->version != '1.0') { return $filterList; } # if # and try to process all of the filters foreach ($xml->xpath('/spotwebfilter/filters/filter') as $filterItem) { $filter['id'] = (string) $filterItem->id; $filter['title'] = (string) $filterItem->title; $filter['icon'] = (string) $filterItem->icon; $filter['tparent'] = (string) $filterItem->parent; $filter['torder'] = (string) $filterItem->order; $filter['filtertype'] = 'filter'; $filter['sorton'] = ''; $filter['sortorder'] = ''; $filter['tree'] = ''; $filter['enablenotify'] = (string) $filterItem->enablenotify; $filter['children'] = array(); /* * start with the tree items */ $treeStr = ""; foreach ($filterItem->xpath('tree/item') as $treeItem) { $treeType = (string) $treeItem->attributes()->type; if ($treeType == 'exclude') { $treeStr .= ',!' . $treeItem[0]; } elseif ($treeType == 'strongnot') { $treeStr .= ',~' . $treeItem[0]; } elseif ($treeType == 'include') { $treeStr .= ',' . $treeItem[0]; } # if } # foreach if (strlen($treeStr) > 1) { $treeStr = substr($treeStr, 1); } # if $filter['tree'] = $treeStr; /* * now parse the values (textsearches etc) */ $filterValues = array(); foreach ($filterItem->xpath('values/item') as $valueItem) { $filterValues[] = urlencode((string) $valueItem->fieldname . ':' . (string) $valueItem->operator . ':' . (string) $valueItem->booloper . ':' . (string) $valueItem->value); } # foreach $filter['valuelist'] = $filterValues; /* * Sorting elements are optional */ if ($filterItem->sort) { $filter['sorton'] = (string) $filterItem->sort->item->fieldname; $filter['sortorder'] = (string) $filterItem->sort->item->direction; } # if $filterList[$filter['id']] = $filter; } # foreach /* * Now create a tree out of it. We cannot do this the same way * as in SpotDb because we cannot create references to the XPATH * function */ foreach ($filterList as $idx => &$filter) { if ($filter['tparent'] != 0 && isset($filterList[$filter['tparent']])) { $filterList[$filter['tparent']]['children'][] =& $filter; } # if } # foreach /* * we have to run it in two passes because unsetting it * will result in an incorrect result on an nested-nested * list */ foreach ($filterList as $idx => &$filter) { if ($filter['tparent'] != 0 && isset($filterList[$filter['tparent']])) { unset($filterList[$filter['id']]); } # if } # foreach /* * Create a new result object */ $result = new Dto_FormResult('success'); $result->addData('filters', $filterList); return $result; }