/** * Accepts proof of identity from the client side Facebook SDK. * https://developers.facebook.com/docs/howtos/login/signed-request/#step2 * This will not work if your site doesn't have a proper * domain name (it will not work in dev, in most cases). */ public function executeFacebookLogin(sfWebRequest $request) { $fb = sfConfig::get('app_sfApplyPlugin_facebook'); $secret = isset($fb['secret']) ? $fb['secret'] : null; if (!$secret) { throw new sfException('app_sfApplyPlugin_facebook not configured, secret missing'); } $signed_request = $request->getParameter('signed_request'); list($encoded_sig, $payload) = explode('.', $signed_request, 2); // decode the data $sig = $this->base64UrlDecode($encoded_sig); $data = json_decode($this->base64UrlDecode($payload), true); // Contrary to FB docs we're not done yet, we have to // trade the 'code' in for an access token and then we // can query for information about the user $code = $data['code']; $url = "https://graph.facebook.com/oauth/access_token?" . http_build_query(array('client_id' => $fb['id'], 'redirect_uri' => '', 'client_secret' => $secret, 'code' => $code)); $accessToken = file_get_contents($url); parse_str($accessToken, $result); $accessToken = $result['access_token']; $me = json_decode(file_get_contents("https://graph.facebook.com/me?" . http_build_query(array('access_token' => $accessToken))), true); if (!isset($me['email'])) { $this->forward404(); } $email = $me['email']; $first_name = $me['first_name']; $last_name = $me['last_name']; $username = '******' . (isset($me['username']) ? $me['username'] : $me['id']); if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') { $this->forward404(); } // Adding the verification of the signed_request below $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true); if ($sig !== $expected_sig) { $this->forward404(); } $user = Doctrine::getTable('sfGuardUser')->findOneByEmailAddress($email); if (!$user) { $user = new sfGuardUser(); $user->setIsActive(true); $user->setPassword(aGuid::generate()); $user->setEmailAddress($email); $user->setUsername($username); } $user->setFirstName($firstName); $user->setLastName($lastName); $user->setEmailAddress($email); $user->save(); $this->getUser()->signIn($user); return $this->renderText('OK'); }
/** * DOCUMENT ME * @return mixed */ public static function getTaskUser() { $user = Doctrine::getTable('sfGuardUser')->findOneByUsername('ataskuser'); if (!$user) { $user = new sfGuardUser(); $user->setUsername('ataskuser'); // Set a good unique password just in case someone cluelessly sets the active flag. // This further ensures that no one can ever log in with this account $user->setPassword(aGuid::generate()); // Prevents normal login $user->setIsActive(false); $user->setIsSuperAdmin(true); $user->save(); } return $user; }
/** * DOCUMENT ME * @return mixed */ public static function getTemporaryFilename() { $filename = aGuid::generate(); $tempDir = self::getTemporaryFileFolder(); return $tempDir . DIRECTORY_SEPARATOR . $filename; }
/** * DOCUMENT ME * @param mixed $value * @return mixed */ protected function getExistsPersistidAndExtension($value) { // TODO: should cache this $exists = false; $extension = false; if (isset($value['persistid']) && strlen($value['persistid'])) { $persistid = $value['persistid']; $info = aValidatorFilePersistent::getFileInfo($persistid); if ($info) { $exists = true; if (isset($info['extension'])) { $extension = $info['extension']; } } } else { // One implementation, not two (to inevitably drift apart) $persistid = aGuid::generate(); } if (!$exists) { $defaultPreview = $this->hasOption('default-preview') ? $this->getOption('default-preview') : false; if ($defaultPreview) { $extension = pathinfo($defaultPreview, PATHINFO_EXTENSION); } } return array($exists, $persistid, $extension); }
/** * @param string $name The element name * @param string $value The value displayed in this widget * (i.e. the browser-side filename submitted * on a previous partially successful * validation of this form) * @param array $attributes An array of HTML attributes to be merged with the default HTML attributes * @param array $errors An array of errors for the field * * @return string An HTML tag string * * @see sfWidgetForm */ public function render($name, $value = null, $attributes = array(), $errors = array()) { $exists = false; if (isset($value['persistid']) && strlen($value['persistid'])) { $persistid = $value['persistid']; $info = aValidatorFilePersistent::getFileInfo($persistid); if ($info) { $exists = true; } } else { // One implementation, not two (to inevitably drift apart) $persistid = aGuid::generate(); } $result = ''; // hasOption just verifies that the option is valid, it doesn't check what, // if anything, was passed. Thanks to Lucjan Wilczewski $preview = $this->hasOption('image-preview') ? $this->getOption('image-preview') : false; $defaultPreview = $this->hasOption('default-preview') ? $this->getOption('default-preview') : false; if ($exists) { $defaultPreview = false; } if ($exists || $defaultPreview) { if ($preview) { // Note change of key $urlStem = sfConfig::get('app_aPersistentFileUpload_preview_url', '/uploads/uploaded_image_preview'); // This is the corresponding directory path. You have to override one // if you override the other. You override this one by setting // app_aToolkit_upload_uploaded_image_preview_dir $dir = aFiles::getUploadFolder("uploaded_image_preview"); // While we're here age off stale previews aValidatorFilePersistent::removeOldFiles($dir); $imagePreview = $this->getOption('image-preview'); if ($exists) { $source = $info['tmp_name']; } else { $source = $defaultPreview; } $info = aImageConverter::getInfo($source); if ($info) { $iwidth = $info['width']; $height = $info['height']; // This is safe - based on sniffed file contents and not a user supplied extension $format = $info['format']; list($iwidth, $iheight) = getimagesize($source); $dimensions = aDimensions::constrain($iwidth, $iheight, $format, $imagePreview); // A simple filename reveals less $imagename = "{$persistid}.{$format}"; $url = "{$urlStem}/{$imagename}"; $output = "{$dir}/{$imagename}"; if (isset($info['newfile']) && $info['newfile'] || !file_exists($output)) { if ($imagePreview['resizeType'] === 'c') { $method = 'cropOriginal'; } else { $method = 'scaleToFit'; } sfContext::getInstance()->getLogger()->info("YY calling converter method {$method} width " . $dimensions['width'] . ' height ' . $dimensions['height']); aImageConverter::$method($source, $output, $dimensions['width'], $dimensions['height']); sfContext::getInstance()->getLogger()->info("YY after converter"); } } if (isset($imagePreview['markup'])) { $markup = $imagePreview['markup']; } else { $markup = '<img src="%s" />'; } $result .= sprintf($markup, $url); } $result .= $this->getOption('existing-html'); } return $result . $this->renderTag('input', array_merge(array('type' => $this->getOption('type'), 'name' => $name . '[newfile]'), $attributes)) . $this->renderTag('input', array('type' => 'hidden', 'name' => $name . '[persistid]', 'value' => $persistid)); }
/** * DOCUMENT ME */ public function go() { $dir_iterator = new RecursiveDirectoryIterator($this->dir); $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); $count = 0; $mimeTypes = aMediaTools::getOption('mime_types'); // It comes back as a mapping of extensions to types, get the types $extensions = array_keys($mimeTypes); $mimeTypes = array_values($mimeTypes); foreach ($iterator as $sfile) { if ($sfile->isFile()) { $file = $sfile->getPathname(); if (preg_match('/(^|\\/)\\./', $file)) { # Silently ignore all dot folders to avoid trouble with svn and friends $this->giveFeedback("info", "Ignoring dotfile", $file); continue; } $pathinfo = pathinfo($file); // basename and filename seem backwards to me, but that's how it is in the PHP docs and // sure enough that's how it behaves if ($pathinfo['basename'] === 'Thumbs.db') { continue; } $vfp = new aValidatorFilePersistent(array('mime_types' => $mimeTypes, 'validated_file_class' => 'aValidatedFile', 'required' => false), array('mime_types' => 'The following file types are accepted: ' . implode(', ', $extensions))); $guid = aGuid::generate(); try { $vf = $vfp->clean(array('newfile' => array('tmp_name' => $file, 'name' => $pathinfo['basename']), 'persistid' => $guid)); } catch (Exception $e) { $this->giveFeedback("warning", "Not supported or corrupt", $file); continue; } $item = new aMediaItem(); // Split it up to make tags out of the portion of the path that isn't dir (i.e. the folder structure they used) $dir = $this->dir; $dir = preg_replace('/\\/$/', '', $dir) . '/'; $relevant = preg_replace('/^' . preg_quote($dir, '/') . '/', '', $file); // TODO: not Microsoft-friendly, might matter in some setting $components = preg_split('/\\//', $relevant); $tags = array_slice($components, 0, count($components) - 1); foreach ($tags as &$tag) { // We don't strictly need to be this harsh, but it's safe and definitely // takes care of some things we definitely can't allow, like periods // (which cause mod_rewrite problems with pretty Symfony URLs). // TODO: clean it up in a nicer way without being UTF8-clueless // (aTools::slugify is UTF8-safe) $tag = aTools::slugify($tag); } $item->title = aMediaTools::filenameToTitle($pathinfo['basename']); $item->setTags($tags); if (!strlen($item->title)) { $this->giveFeedback("error", "Files must have a basename", $file); continue; } // The preSaveImage / save / saveImage dance is necessary because // the sluggable behavior doesn't kick in until save and the image file // needs a slug based filename. if (!$item->preSaveFile($vf)) { $this->giveFeedback("error", "Save failed", $file); continue; } $item->save(); if (!$item->saveFile($vf)) { $this->giveFeedback("error", "Save failed", $file); $item->delete(); continue; } unlink($file); $count++; $this->giveFeedback("completed", $count, $file); } } $this->giveFeedback("total", $count); }
public static function obfuscateMailtoInstance($user, $domain, $label) { // We get some weird escaping problems without the trims $user = trim($user); $domain = trim($domain); $guid = aGuid::generate(); $href = self::jsEscape("mailto:{$user}@{$domain}"); $label = self::jsEscape(trim($label)); // ACHTUNG: this is carefully crafted to avoid introducing extra whitespace return "<a href='#' id='{$guid}'></a><script type='text/javascript' charset='utf-8'>\n \t var e = document.getElementById('{$guid}');\n e.setAttribute('href', '{$href}');\n e.innerHTML = '{$label}';\n </script>"; }
/** * DOCUMENT ME * @param sfWebRequest $request * @return mixed */ public function executeEditVideo(sfWebRequest $request) { $this->forward404Unless(aMediaTools::userHasUploadPrivilege()); $item = null; $this->slug = false; $this->popularTags = PluginTagTable::getPopulars(null, array('sort_by_popularity' => true), false, 10); if (sfConfig::get('app_a_all_tags', true)) { $this->allTags = PluginTagTable::getAllTagNameWithCount(); } else { $this->allTags = array(); } if ($request->hasParameter('slug')) { $item = $this->getItem(); $this->slug = $item->getSlug(); } if ($item) { $this->forward404Unless($item->userHasPrivilege('edit')); } $this->item = $item; $embed = false; $parameters = $request->getParameter('a_media_item'); if ($parameters) { $files = $request->getFiles('a_media_item'); $this->form = new aMediaVideoForm($item); if (isset($parameters['embed'])) { // We need to do some prevalidation of the embed code so we can prestuff the // file, title, tags and description widgets $result = $this->form->classifyEmbed($parameters['embed']); if (isset($result['thumbnail'])) { $thumbnail = $result['thumbnail']; if (!isset($parameters['title']) && !isset($parameters['tags']) && !isset($parameters['description']) && !isset($parameters['credit'])) { $parameters['title'] = $result['serviceInfo']['title']; // We want tags to be lower case, and slashes break routes in most server configs. $parameters['tags'] = str_replace('/', '-', aString::strtolower($result['serviceInfo']['tags'])); $parameters['description'] = aHtml::textToHtml($result['serviceInfo']['description']); $parameters['credit'] = $result['serviceInfo']['credit']; } } } // On the first pass with a youtube video we just make the service's thumbnail the // default thumbnail. We don't force them to use it. This allows more code reuse // (Moving this after the bind is necessary to keep it from being overwritten) if (isset($thumbnail)) { // OMG file widgets can't have defaults! Ah, but our persistent file widget can $tmpFile = aFiles::getTemporaryFilename(); file_put_contents($tmpFile, file_get_contents($thumbnail)); $vfp = new aValidatorFilePersistent(); $guid = aGuid::generate(); $vfp->clean(array('newfile' => array('tmp_name' => $tmpFile), 'persistid' => $guid)); // You can't mess about with widget defaults after a bind, but you // *can* tweak the array you're about to bind with $parameters['file']['persistid'] = $guid; } $this->form->bind($parameters, $files); do { // first_pass forces the user to interact with the form // at least once. Used when we're coming from a // YouTube search and we already technically have a // valid form but want the user to think about whether // the title is adequate and perhaps add a description, // tags, etc. if ($this->hasRequestParameter('first_pass') || !$this->form->isValid()) { break; } $thumbnail = $this->form->getValue('file'); // The base implementation for saving files gets confused when // $file is not set, a situation that our code tolerates as useful // because if you're updating a record containing an image you // often don't need to submit a new one. unset($this->form['file']); $object = $this->form->getObject(); if ($thumbnail) { $object->preSaveFile($thumbnail->getTempName()); } $this->form->save(); if ($thumbnail) { $object->saveFile($thumbnail->getTempName()); } return $this->redirect("aMedia/resumeWithPage"); } while (false); } }