public function processRequest()
 {
     // No CSRF for SendGrid.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $request = $this->getRequest();
     $user = $request->getUser();
     $raw_headers = $request->getStr('headers');
     $raw_headers = explode("\n", rtrim($raw_headers));
     $raw_dict = array();
     foreach (array_filter($raw_headers) as $header) {
         list($name, $value) = explode(':', $header, 2);
         $raw_dict[$name] = ltrim($value);
     }
     $headers = array('to' => $request->getStr('to'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject')) + $raw_dict;
     $received = new PhabricatorMetaMTAReceivedMail();
     $received->setHeaders($headers);
     $received->setBodies(array('text' => $request->getStr('text'), 'html' => $request->getStr('from')));
     $file_phids = array();
     foreach ($_FILES as $file_raw) {
         try {
             $file = PhabricatorFile::newFromPHPUpload($file_raw, array('authorPHID' => $user->getPHID()));
             $file_phids[] = $file->getPHID();
         } catch (Exception $ex) {
             phlog($ex);
         }
     }
     $received->setAttachments($file_phids);
     $received->save();
     $received->processReceivedMail();
     $response = new AphrontWebpageResponse();
     $response->setContent("Got it! Thanks, SendGrid!\n");
     return $response;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession($viewer, $this->getRequest(), '/');
     // Ideally we'd like to verify this, but it's fine to leave it unguarded
     // for now and verifying it would need some Ajax junk or for the user to
     // click a button or similar.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $old_token = id(new PhabricatorConduitCertificateToken())->loadOneWhere('userPHID = %s', $viewer->getPHID());
     if ($old_token) {
         $old_token->delete();
     }
     $token = id(new PhabricatorConduitCertificateToken())->setUserPHID($viewer->getPHID())->setToken(Filesystem::readRandomCharacters(40))->save();
     unset($unguarded);
     $pre_instructions = pht('Copy and paste this token into the prompt given to you by ' . '`arc install-certificate`');
     $post_instructions = pht('After you copy and paste this token, `arc` will complete ' . 'the certificate install process for you.');
     Javelin::initBehavior('select-on-click');
     $form = id(new AphrontFormView())->setUser($viewer)->appendRemarkupInstructions($pre_instructions)->appendChild(id(new AphrontFormTextAreaControl())->setLabel(pht('Token'))->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)->setReadonly(true)->setSigil('select-on-click')->setValue($token->getToken()))->appendRemarkupInstructions($post_instructions);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Install Certificate'));
     $crumbs->setBorder(true);
     $object_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Certificate Token'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form);
     $title = pht('Certificate Install Token');
     $header = id(new PHUIHeaderView())->setHeader($title);
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter($object_box);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view);
 }
 public function processRequest()
 {
     if (!PhabricatorEnv::getEnvConfig('files.enable-proxy')) {
         return new Aphront400Response();
     }
     $request = $this->getRequest();
     $uri = $request->getStr('uri');
     $proxy = id(new PhabricatorFileProxyImage())->loadOneWhere('uri = %s', $uri);
     if (!$proxy) {
         // This write is fine to skip CSRF checks for, we're just building a
         // cache of some remote image.
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         $file = PhabricatorFile::newFromFileDownload($uri, nonempty(basename($uri), 'proxied-file'));
         if ($file) {
             $proxy = new PhabricatorFileProxyImage();
             $proxy->setURI($uri);
             $proxy->setFilePHID($file->getPHID());
             $proxy->save();
         }
         unset($unguarded);
     }
     if ($proxy) {
         $file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $proxy->getFilePHID());
         if ($file) {
             $view_uri = $file->getBestURI();
         } else {
             $bad_phid = $proxy->getFilePHID();
             throw new Exception("Unable to load file with phid {$bad_phid}.");
         }
         return id(new AphrontRedirectResponse())->setURI($view_uri);
     }
     return new Aphront400Response();
 }
 public function setKeys(array $keys, $ttl = null)
 {
     if (PhabricatorEnv::isReadOnly()) {
         return;
     }
     if ($keys) {
         $map = $this->digestKeys(array_keys($keys));
         $conn_w = $this->establishConnection('w');
         $sql = array();
         foreach ($map as $key => $hash) {
             $value = $keys[$key];
             list($format, $storage_value) = $this->willWriteValue($key, $value);
             $sql[] = qsprintf($conn_w, '(%s, %s, %s, %B, %d, %nd)', $hash, $key, $format, $storage_value, time(), $ttl ? time() + $ttl : null);
         }
         $guard = AphrontWriteGuard::beginScopedUnguardedWrites();
         foreach (PhabricatorLiskDAO::chunkSQL($sql) as $chunk) {
             queryfx($conn_w, 'INSERT INTO %T
           (cacheKeyHash, cacheKey, cacheFormat, cacheData,
             cacheCreated, cacheExpires) VALUES %Q
           ON DUPLICATE KEY UPDATE
             cacheKey = VALUES(cacheKey),
             cacheFormat = VALUES(cacheFormat),
             cacheData = VALUES(cacheData),
             cacheCreated = VALUES(cacheCreated),
             cacheExpires = VALUES(cacheExpires)', $this->getTableName(), $chunk);
         }
         unset($guard);
     }
     return $this;
 }
 protected function getResult(ConduitAPIRequest $request)
 {
     $drequest = $this->getDiffusionRequest();
     $file_query = DiffusionFileContentQuery::newFromDiffusionRequest($drequest);
     $timeout = $request->getValue('timeout');
     if ($timeout) {
         $file_query->setTimeout($timeout);
     }
     $byte_limit = $request->getValue('byteLimit');
     if ($byte_limit) {
         $file_query->setByteLimit($byte_limit);
     }
     $file = $file_query->execute();
     $too_slow = (bool) $file_query->getExceededTimeLimit();
     $too_huge = (bool) $file_query->getExceededByteLimit();
     $file_phid = null;
     if (!$too_slow && !$too_huge) {
         $repository = $drequest->getRepository();
         $repository_phid = $repository->getPHID();
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         $file->attachToObject($repository_phid);
         unset($unguarded);
         $file_phid = $file->getPHID();
     }
     return array('tooSlow' => $too_slow, 'tooHuge' => $too_huge, 'filePHID' => $file_phid);
 }
 public function handleRequest(AphrontRequest $request)
 {
     // No CSRF for Mailgun.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     if (!$this->verifyMessage()) {
         throw new Exception(pht('Mail signature is not valid. Check your Mailgun API key.'));
     }
     $user = $request->getUser();
     $raw_headers = $request->getStr('headers');
     $raw_headers = explode("\n", rtrim($raw_headers));
     $raw_dict = array();
     foreach (array_filter($raw_headers) as $header) {
         list($name, $value) = explode(':', $header, 2);
         $raw_dict[$name] = ltrim($value);
     }
     $headers = array('to' => $request->getStr('recipient'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject')) + $raw_dict;
     $received = new PhabricatorMetaMTAReceivedMail();
     $received->setHeaders($headers);
     $received->setBodies(array('text' => $request->getStr('stripped-text'), 'html' => $request->getStr('stripped-html')));
     $file_phids = array();
     foreach ($_FILES as $file_raw) {
         try {
             $file = PhabricatorFile::newFromPHPUpload($file_raw, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
             $file_phids[] = $file->getPHID();
         } catch (Exception $ex) {
             phlog($ex);
         }
     }
     $received->setAttachments($file_phids);
     $received->save();
     $received->processReceivedMail();
     $response = new AphrontWebpageResponse();
     $response->setContent(pht("Got it! Thanks, Mailgun!\n"));
     return $response;
 }
 protected function loadPage()
 {
     $table = new PhortuneProduct();
     $conn = $table->establishConnection('r');
     $rows = queryfx_all($conn, 'SELECT * FROM %T %Q %Q %Q', $table->getTableName(), $this->buildWhereClause($conn), $this->buildOrderClause($conn), $this->buildLimitClause($conn));
     $page = $table->loadAllFromArray($rows);
     // NOTE: We're loading product implementations here, but also creating any
     // products which do not yet exist.
     $class_map = mgroup($page, 'getProductClass');
     if ($this->refMap) {
         $class_map += array_fill_keys(array_keys($this->refMap), array());
     }
     foreach ($class_map as $class => $products) {
         $refs = mpull($products, null, 'getProductRef');
         if (isset($this->refMap[$class])) {
             $refs += array_fill_keys($this->refMap[$class], null);
         }
         $implementations = newv($class, array())->loadImplementationsForRefs($this->getViewer(), array_keys($refs));
         $implementations = mpull($implementations, null, 'getRef');
         foreach ($implementations as $ref => $implementation) {
             $product = idx($refs, $ref);
             if ($product === null) {
                 // If this product does not exist yet, create it and add it to the
                 // result page.
                 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
                 $product = PhortuneProduct::initializeNewProduct()->setProductClass($class)->setProductRef($ref)->save();
                 unset($unguarded);
                 $page[] = $product;
             }
             $product->attachImplementation($implementation);
         }
     }
     return $page;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $editable = $this->getAccountEditable();
     // There's no sense in showing a change password panel if the user
     // can't change their password
     if (!$editable || !PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) {
         return new Aphront400Response();
     }
     $errors = array();
     if ($request->isFormPost()) {
         if ($user->comparePassword($request->getStr('old_pw'))) {
             $pass = $request->getStr('new_pw');
             $conf = $request->getStr('conf_pw');
             if ($pass === $conf) {
                 if (strlen($pass)) {
                     $user->setPassword($pass);
                     // This write is unguarded because the CSRF token has already
                     // been checked in the call to $request->isFormPost() and
                     // the CSRF token depends on the password hash, so when it
                     // is changed here the CSRF token check will fail.
                     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
                     $user->save();
                     unset($unguarded);
                     return id(new AphrontRedirectResponse())->setURI('/settings/page/password/?saved=true');
                 } else {
                     $errors[] = 'Your new password is too short.';
                 }
             } else {
                 $errors[] = 'New password and confirmation do not match.';
             }
         } else {
             $errors[] = 'The old password you entered is incorrect.';
         }
     }
     $notice = null;
     if (!$errors) {
         if ($request->getStr('saved')) {
             $notice = new AphrontErrorView();
             $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
             $notice->setTitle('Changes Saved');
             $notice->appendChild('<p>Your password has been updated.</p>');
         }
     } else {
         $notice = new AphrontErrorView();
         $notice->setTitle('Error Changing Password');
         $notice->setErrors($errors);
     }
     $form = new AphrontFormView();
     $form->setUser($user)->appendChild(id(new AphrontFormPasswordControl())->setLabel('Old Password')->setName('old_pw'));
     $form->appendChild(id(new AphrontFormPasswordControl())->setLabel('New Password')->setName('new_pw'));
     $form->appendChild(id(new AphrontFormPasswordControl())->setLabel('Confirm Password')->setName('conf_pw'));
     $form->appendChild(id(new AphrontFormSubmitControl())->setValue('Save'));
     $panel = new AphrontPanelView();
     $panel->setHeader('Change Password');
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $panel->appendChild($form);
     return id(new AphrontNullView())->appendChild(array($notice, $panel));
 }
 public static function generateMacro($viewer, $macro_name, $upper_text, $lower_text)
 {
     $macro = id(new PhabricatorMacroQuery())->setViewer($viewer)->withNames(array($macro_name))->needFiles(true)->executeOne();
     if (!$macro) {
         return false;
     }
     $file = $macro->getFile();
     $upper_text = strtoupper($upper_text);
     $lower_text = strtoupper($lower_text);
     $mixed_text = md5($upper_text) . ':' . md5($lower_text);
     $hash = 'meme' . hash('sha256', $mixed_text);
     $xform = id(new PhabricatorTransformedFile())->loadOneWhere('originalphid=%s and transform=%s', $file->getPHID(), $hash);
     if ($xform) {
         $memefile = id(new PhabricatorFileQuery())->setViewer($viewer)->withPHIDs(array($xform->getTransformedPHID()))->executeOne();
         if ($memefile) {
             return $memefile->getBestURI();
         }
     }
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $transformers = new PhabricatorImageTransformer();
     $newfile = $transformers->executeMemeTransform($file, $upper_text, $lower_text);
     $xfile = new PhabricatorTransformedFile();
     $xfile->setOriginalPHID($file->getPHID());
     $xfile->setTransformedPHID($newfile->getPHID());
     $xfile->setTransform($hash);
     $xfile->save();
     return $newfile->getBestURI();
 }
 /**
  * @phutil-external-symbol class PhabricatorStartup
  */
 public function handleRequest(AphrontRequest $request)
 {
     $raw_body = PhabricatorStartup::getRawInput();
     $body = phutil_json_decode($raw_body);
     $payload = $body['payload'];
     $parameters = idx($payload, 'build_parameters');
     if (!$parameters) {
         $parameters = array();
     }
     $target_phid = idx($parameters, 'HARBORMASTER_BUILD_TARGET_PHID');
     // NOTE: We'll get callbacks here for builds we triggered, but also for
     // arbitrary builds the system executes for other reasons. So it's normal
     // to get some notifications with no Build Target PHID. We just ignore
     // these under the assumption that they're routine builds caused by events
     // like branch updates.
     if ($target_phid) {
         $viewer = PhabricatorUser::getOmnipotentUser();
         $target = id(new HarbormasterBuildTargetQuery())->setViewer($viewer)->withPHIDs(array($target_phid))->needBuildSteps(true)->executeOne();
         if ($target) {
             $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
             $this->updateTarget($target, $payload);
         }
     }
     $response = new AphrontWebpageResponse();
     $response->setContent(pht("Request OK\n"));
     return $response;
 }
 /**
  * Deletes the file from local disk, if it exists.
  * @task impl
  */
 public function deleteFile($handle)
 {
     $path = $this->getLocalDiskFileStorageFullPath($handle);
     if (Filesystem::pathExists($path)) {
         AphrontWriteGuard::willWrite();
         Filesystem::remove($path);
     }
 }
 public function processRequest()
 {
     $viewer = $this->getRequest()->getUser();
     // NOTE: This is a public/CDN endpoint, and permission to see files is
     // controlled by knowing the secret key, not by authentication.
     $file = id(new PhabricatorFileQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs(array($this->phid))->executeOne();
     if (!$file) {
         return new Aphront404Response();
     }
     if (!$file->validateSecretKey($this->key)) {
         return new Aphront403Response();
     }
     $xform = id(new PhabricatorTransformedFile())->loadOneWhere('originalPHID = %s AND transform = %s', $this->phid, $this->transform);
     if ($xform) {
         return $this->buildTransformedFileResponse($xform);
     }
     $type = $file->getMimeType();
     if (!$file->isViewableInBrowser() || !$file->isTransformableImage()) {
         return $this->buildDefaultTransformation($file);
     }
     // We're essentially just building a cache here and don't need CSRF
     // protection.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     switch ($this->transform) {
         case 'thumb-profile':
             $xformed_file = $this->executeThumbTransform($file, 50, 50);
             break;
         case 'thumb-280x210':
             $xformed_file = $this->executeThumbTransform($file, 280, 210);
             break;
         case 'thumb-220x165':
             $xformed_file = $this->executeThumbTransform($file, 220, 165);
             break;
         case 'preview-100':
             $xformed_file = $this->executePreviewTransform($file, 100);
             break;
         case 'preview-220':
             $xformed_file = $this->executePreviewTransform($file, 220);
             break;
         case 'thumb-160x120':
             $xformed_file = $this->executeThumbTransform($file, 160, 120);
             break;
         case 'thumb-60x45':
             $xformed_file = $this->executeThumbTransform($file, 60, 45);
             break;
         default:
             return new Aphront400Response();
     }
     if (!$xformed_file) {
         return new Aphront400Response();
     }
     $xform = new PhabricatorTransformedFile();
     $xform->setOriginalPHID($this->phid);
     $xform->setTransform($this->transform);
     $xform->setTransformedPHID($xformed_file->getPHID());
     $xform->save();
     return $this->buildTransformedFileResponse($xform);
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     if ($request->getStr('jump') != 'no') {
         $response = PhabricatorJumpNavHandler::getJumpResponse($viewer, $request->getStr('query'));
         if ($response) {
             return $response;
         }
     }
     $engine = new PhabricatorSearchApplicationSearchEngine();
     $engine->setViewer($viewer);
     // If we're coming from primary search, do some special handling to
     // interpret the scope selector and query.
     if ($request->getBool('search:primary')) {
         // If there's no query, just take the user to advanced search.
         if (!strlen($request->getStr('query'))) {
             $advanced_uri = '/search/query/advanced/';
             return id(new AphrontRedirectResponse())->setURI($advanced_uri);
         }
         // First, load or construct a template for the search by examining
         // the current search scope.
         $scope = $request->getStr('search:scope');
         $saved = null;
         if ($scope == self::SCOPE_CURRENT_APPLICATION) {
             $application = id(new PhabricatorApplicationQuery())->setViewer($viewer)->withClasses(array($request->getStr('search:application')))->executeOne();
             if ($application) {
                 $types = $application->getApplicationSearchDocumentTypes();
                 if ($types) {
                     $saved = id(new PhabricatorSavedQuery())->setEngineClassName(get_class($engine))->setParameter('types', $types)->setParameter('statuses', array('open'));
                 }
             }
         }
         if (!$saved && !$engine->isBuiltinQuery($scope)) {
             $saved = id(new PhabricatorSavedQueryQuery())->setViewer($viewer)->withQueryKeys(array($scope))->executeOne();
         }
         if (!$saved) {
             if (!$engine->isBuiltinQuery($scope)) {
                 $scope = 'all';
             }
             $saved = $engine->buildSavedQueryFromBuiltin($scope);
         }
         // Add the user's query, then save this as a new saved query and send
         // the user to the results page.
         $saved->setParameter('query', $request->getStr('query'));
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         try {
             $saved->setID(null)->save();
         } catch (AphrontDuplicateKeyQueryException $ex) {
             // Ignore, this is just a repeated search.
         }
         unset($unguarded);
         $query_key = $saved->getQueryKey();
         $results_uri = $engine->getQueryResultsPageURI($query_key) . '#R';
         return id(new AphrontRedirectResponse())->setURI($results_uri);
     }
     $controller = id(new PhabricatorApplicationSearchController())->setQueryKey($request->getURIData('queryKey'))->setSearchEngine($engine)->setNavigation($this->buildSideNavView());
     return $this->delegateToController($controller);
 }
 /**
  * Delete a blob from Amazon S3.
  */
 public function deleteFile($handle)
 {
     AphrontWriteGuard::willWrite();
     $s3 = $this->newS3API();
     $profiler = PhutilServiceProfiler::getInstance();
     $call_id = $profiler->beginServiceCall(array('type' => 's3', 'method' => 'deleteObject'));
     $s3->deleteObject($this->getBucketName(), $handle);
     $profiler->endServiceCall($call_id, array());
 }
 /**
  * Delete a blob from Amazon S3.
  */
 public function deleteFile($handle)
 {
     $s3 = $this->newS3API();
     AphrontWriteGuard::willWrite();
     $profiler = PhutilServiceProfiler::getInstance();
     $call_id = $profiler->beginServiceCall(array('type' => 's3', 'method' => 'deleteObject'));
     $s3->setParametersForDeleteObject($handle)->resolve();
     $profiler->endServiceCall($call_id, array());
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $aid = $request->getURIData('aid');
     $bid = $request->getURIData('bid');
     // If "aid" is "x", then it means the user wants to generate
     // a patch of an empty file to the version specified by "bid".
     $ids = array($aid, $bid);
     if ($aid === 'x') {
         $ids = array($bid);
     }
     $versions = id(new PhragmentFragmentVersionQuery())->setViewer($viewer)->withIDs($ids)->execute();
     $version_a = null;
     if ($aid !== 'x') {
         $version_a = idx($versions, $aid, null);
         if ($version_a === null) {
             return new Aphront404Response();
         }
     }
     $version_b = idx($versions, $bid, null);
     if ($version_b === null) {
         return new Aphront404Response();
     }
     $file_phids = array();
     if ($version_a !== null) {
         $file_phids[] = $version_a->getFilePHID();
     }
     $file_phids[] = $version_b->getFilePHID();
     $files = id(new PhabricatorFileQuery())->setViewer($viewer)->withPHIDs($file_phids)->execute();
     $files = mpull($files, null, 'getPHID');
     $file_a = null;
     if ($version_a != null) {
         $file_a = idx($files, $version_a->getFilePHID(), null);
     }
     $file_b = idx($files, $version_b->getFilePHID(), null);
     $patch = PhragmentPatchUtil::calculatePatch($file_a, $file_b);
     if ($patch === null) {
         // There are no differences between the two files, so we output
         // an empty patch.
         $patch = '';
     }
     $a_sequence = 'x';
     if ($version_a !== null) {
         $a_sequence = $version_a->getSequence();
     }
     $name = $version_b->getFragment()->getName() . '.' . $a_sequence . '.' . $version_b->getSequence() . '.patch';
     $return = $version_b->getURI();
     if ($request->getExists('return')) {
         $return = $request->getStr('return');
     }
     $result = PhabricatorFile::buildFromFileDataOrHash($patch, array('name' => $name, 'mime-type' => 'text/plain', 'ttl' => time() + 60 * 60 * 24));
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $result->attachToObject($version_b->getFragmentPHID());
     unset($unguarded);
     return id(new AphrontRedirectResponse())->setURI($result->getDownloadURI($return));
 }
 public static function updateObjectNotificationViews(PhabricatorUser $user, $object_phid)
 {
     if (PhabricatorEnv::getEnvConfig('notification.enabled')) {
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         $notification_table = new PhabricatorFeedStoryNotification();
         $conn = $notification_table->establishConnection('w');
         queryfx($conn, "UPDATE %T\n         SET hasViewed = 1\n         WHERE userPHID = %s\n           AND primaryObjectPHID = %s\n           AND hasViewed = 0", $notification_table->getTableName(), $user->getPHID(), $object_phid);
         unset($unguarded);
     }
 }
 public function render()
 {
     $rows = array();
     if (!$this->user) {
         throw new Exception("Call setUser() before rendering!");
     }
     foreach ($this->daemonLogs as $log) {
         $epoch = $log->getDateCreated();
         $status = $log->getStatus();
         if ($log->getHost() == php_uname('n') && $status != PhabricatorDaemonLog::STATUS_EXITED && $status != PhabricatorDaemonLog::STATUS_DEAD) {
             $pid = $log->getPID();
             $is_running = PhabricatorDaemonReference::isProcessRunning($pid);
             if (!$is_running) {
                 $guard = AphrontWriteGuard::beginScopedUnguardedWrites();
                 $log->setStatus(PhabricatorDaemonLog::STATUS_DEAD);
                 $log->save();
                 unset($guard);
                 $status = PhabricatorDaemonLog::STATUS_DEAD;
             }
         }
         $heartbeat_timeout = $log->getDateModified() + 3 * PhutilDaemonOverseer::HEARTBEAT_WAIT;
         if ($status == PhabricatorDaemonLog::STATUS_RUNNING && $heartbeat_timeout < time()) {
             $status = PhabricatorDaemonLog::STATUS_UNKNOWN;
         }
         switch ($status) {
             case PhabricatorDaemonLog::STATUS_RUNNING:
                 $style = 'color: #00cc00';
                 $title = 'Running';
                 $symbol = '&bull;';
                 break;
             case PhabricatorDaemonLog::STATUS_DEAD:
                 $style = 'color: #cc0000';
                 $title = 'Died';
                 $symbol = '&bull;';
                 break;
             case PhabricatorDaemonLog::STATUS_EXITED:
                 $style = 'color: #000000';
                 $title = 'Exited';
                 $symbol = '&bull;';
                 break;
             case PhabricatorDaemonLog::STATUS_UNKNOWN:
             default:
                 // fallthrough
                 $style = 'color: #888888';
                 $title = 'Unknown';
                 $symbol = '?';
         }
         $running = phutil_render_tag('span', array('style' => $style, 'title' => $title), $symbol);
         $rows[] = array($running, phutil_escape_html($log->getDaemon()), phutil_escape_html($log->getHost()), $log->getPID(), phabricator_date($epoch, $this->user), phabricator_time($epoch, $this->user), phutil_render_tag('a', array('href' => '/daemon/log/' . $log->getID() . '/', 'class' => 'button small grey'), 'View Log'));
     }
     $daemon_table = new AphrontTableView($rows);
     $daemon_table->setHeaders(array('', 'Daemon', 'Host', 'PID', 'Date', 'Time', 'View'));
     $daemon_table->setColumnClasses(array('', 'wide wrap', '', '', '', 'right', 'action'));
     return $daemon_table->render();
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession($viewer, $request, '/');
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $token = PhabricatorConduitToken::initializeNewToken($viewer->getPHID(), PhabricatorConduitToken::TYPE_COMMANDLINE);
     $token->save();
     unset($unguarded);
     $form = id(new AphrontFormView())->setUser($viewer)->appendRemarkupInstructions(pht('Copy-paste the API Token below to grant access to your account.'))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('API Token'))->setValue($token->getToken()))->appendRemarkupInstructions(pht('This will authorize the requesting script to act on your behalf ' . 'permanently, like giving the script your account password.'))->appendRemarkupInstructions(pht('If you change your mind, you can revoke this token later in ' . '{nav icon=wrench,name=Settings > Conduit API Tokens}.'));
     return $this->newDialog()->setTitle(pht('Grant Account Access'))->setWidth(AphrontDialogView::WIDTH_FULL)->appendForm($form)->addCancelButton('/');
 }
 public function processAddFactorForm(AphrontFormView $form, AphrontRequest $request, PhabricatorUser $user)
 {
     $totp_token_type = PhabricatorAuthTOTPKeyTemporaryTokenType::TOKENTYPE;
     $key = $request->getStr('totpkey');
     if (strlen($key)) {
         // If the user is providing a key, make sure it's a key we generated.
         // This raises the barrier to theoretical attacks where an attacker might
         // provide a known key (such attacks are already prevented by CSRF, but
         // this is a second barrier to overcome).
         // (We store and verify the hash of the key, not the key itself, to limit
         // how useful the data in the table is to an attacker.)
         $temporary_token = id(new PhabricatorAuthTemporaryTokenQuery())->setViewer($user)->withTokenResources(array($user->getPHID()))->withTokenTypes(array($totp_token_type))->withExpired(false)->withTokenCodes(array(PhabricatorHash::digest($key)))->executeOne();
         if (!$temporary_token) {
             // If we don't have a matching token, regenerate the key below.
             $key = null;
         }
     }
     if (!strlen($key)) {
         $key = self::generateNewTOTPKey();
         // Mark this key as one we generated, so the user is allowed to submit
         // a response for it.
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         id(new PhabricatorAuthTemporaryToken())->setTokenResource($user->getPHID())->setTokenType($totp_token_type)->setTokenExpires(time() + phutil_units('1 hour in seconds'))->setTokenCode(PhabricatorHash::digest($key))->save();
         unset($unguarded);
     }
     $code = $request->getStr('totpcode');
     $e_code = true;
     if ($request->getExists('totp')) {
         $okay = self::verifyTOTPCode($user, new PhutilOpaqueEnvelope($key), $code);
         if ($okay) {
             $config = $this->newConfigForUser($user)->setFactorName(pht('Mobile App (TOTP)'))->setFactorSecret($key);
             return $config;
         } else {
             if (!strlen($code)) {
                 $e_code = pht('Required');
             } else {
                 $e_code = pht('Invalid');
             }
         }
     }
     $form->addHiddenInput('totp', true);
     $form->addHiddenInput('totpkey', $key);
     $form->appendRemarkupInstructions(pht('First, download an authenticator application on your phone. Two ' . 'applications which work well are **Authy** and **Google ' . 'Authenticator**, but any other TOTP application should also work.'));
     $form->appendInstructions(pht('Launch the application on your phone, and add a new entry for ' . 'this Phabricator install. When prompted, scan the QR code or ' . 'manually enter the key shown below into the application.'));
     $prod_uri = new PhutilURI(PhabricatorEnv::getProductionURI('/'));
     $issuer = $prod_uri->getDomain();
     $uri = urisprintf('otpauth://totp/%s:%s?secret=%s&issuer=%s', $issuer, $user->getUsername(), $key, $issuer);
     $qrcode = $this->renderQRCode($uri);
     $form->appendChild($qrcode);
     $form->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Key'))->setValue(phutil_tag('strong', array(), $key)));
     $form->appendInstructions(pht('(If given an option, select that this key is "Time Based", not ' . '"Counter Based".)'));
     $form->appendInstructions(pht('After entering the key, the application should display a numeric ' . 'code. Enter that code below to confirm that you have configured ' . 'the authenticator correctly:'));
     $form->appendChild(id(new PHUIFormNumberControl())->setLabel(pht('TOTP Code'))->setName('totpcode')->setValue($code)->setError($e_code));
 }
 public function saveQuery(PhabricatorSavedQuery $query)
 {
     $query->setEngineClassName(get_class($this));
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     try {
         $query->save();
     } catch (AphrontDuplicateKeyQueryException $ex) {
         // Ignore, this is just a repeated search.
     }
     unset($unguarded);
 }
 public static function clearCacheForAllUsers($key)
 {
     if (PhabricatorEnv::isReadOnly()) {
         return;
     }
     $table = new self();
     $conn_w = $table->establishConnection('w');
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     queryfx($conn_w, 'DELETE FROM %T WHERE cacheIndex = %s', $table->getTableName(), PhabricatorHash::digestForIndex($key));
     unset($unguarded);
 }
 private function newFile(DiffusionRequest $drequest, $content)
 {
     $path = $drequest->getPath();
     $name = basename($path);
     $repository = $drequest->getRepository();
     $repository_phid = $repository->getPHID();
     $file = PhabricatorFile::buildFromFileDataOrHash($content, array('name' => $name, 'ttl' => time() + phutil_units('48 hours in seconds'), 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE));
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $file->attachToObject($repository_phid);
     unset($unguarded);
     return $file;
 }
Example #24
0
 /**
  * Find locked services which are bound to this device, updating the device
  * lock flag if necessary.
  *
  * @return list<phid> List of locking service PHIDs.
  */
 public function rebuildDeviceLocks()
 {
     $services = id(new AlmanacServiceQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withDevicePHIDs(array($this->getPHID()))->withLocked(true)->execute();
     $locked = (bool) count($services);
     if ($locked != $this->getIsLocked()) {
         $this->setIsLocked((int) $locked);
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         queryfx($this->establishConnection('w'), 'UPDATE %T SET isLocked = %d WHERE id = %d', $this->getTableName(), $this->getIsLocked(), $this->getID());
         unset($unguarded);
     }
     return $this;
 }
 public function pullRefs(array $refs)
 {
     $token = $this->getGitHubAccessToken();
     if (!strlen($token)) {
         return null;
     }
     $template = id(new PhutilGitHubFuture())->setAccessToken($token);
     $futures = array();
     $id_map = mpull($refs, 'getObjectID', 'getObjectKey');
     foreach ($id_map as $key => $id) {
         list($user, $repository, $number) = $this->parseGitHubIssueID($id);
         $uri = "/repos/{$user}/{$repository}/issues/{$number}";
         $data = array();
         $futures[$key] = id(clone $template)->setRawGitHubQuery($uri, $data);
     }
     $results = array();
     $failed = array();
     foreach (new FutureIterator($futures) as $key => $future) {
         try {
             $results[$key] = $future->resolve();
         } catch (Exception $ex) {
             if ($ex instanceof HTTPFutureResponseStatus && $ex->getStatusCode() == 404) {
                 // TODO: Do we end up here for deleted objects and invisible
                 // objects?
             } else {
                 phlog($ex);
                 $failed[$key] = $ex;
             }
         }
     }
     $viewer = $this->getViewer();
     foreach ($refs as $ref) {
         $ref->setAttribute('name', pht('GitHub Issue %s', $ref->getObjectID()));
         $did_fail = idx($failed, $ref->getObjectKey());
         if ($did_fail) {
             $ref->setSyncFailed(true);
             continue;
         }
         $result = idx($results, $ref->getObjectKey());
         if (!$result) {
             continue;
         }
         $body = $result->getBody();
         $ref->setIsVisible(true);
         $ref->setAttribute('api.raw', $body);
         $ref->setAttribute('name', $body['title']);
         $obj = $ref->getExternalObject();
         $this->fillObjectFromData($obj, $result);
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         $obj->save();
         unset($unguarded);
     }
 }
Example #26
0
 protected function willRun()
 {
     parent::willRun();
     // This stores unbounded amounts of log data; make it discard instead so
     // that daemons do not require unbounded amounts of memory.
     DarkConsoleErrorLogPluginAPI::enableDiscardMode();
     $phabricator = phutil_get_library_root('phabricator');
     $root = dirname($phabricator);
     require_once $root . '/scripts/__init_env__.php';
     // Daemons may perform writes.
     AphrontWriteGuard::allowDangerousUnguardedWrites(true);
 }
 public function handleRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $latest_conpherences = array();
     $latest_participant = id(new ConpherenceParticipantQuery())->withParticipantPHIDs(array($user->getPHID()))->setLimit(6)->execute();
     if ($latest_participant) {
         $conpherence_phids = mpull($latest_participant, 'getConpherencePHID');
         $latest_conpherences = id(new ConpherenceThreadQuery())->setViewer($user)->withPHIDs($conpherence_phids)->needCropPics(true)->needParticipantCache(true)->execute();
         $latest_conpherences = mpull($latest_conpherences, null, 'getPHID');
         $latest_conpherences = array_select_keys($latest_conpherences, $conpherence_phids);
     }
     $conpherence = null;
     $should_404 = false;
     if ($request->getInt('id')) {
         $conpherence = id(new ConpherenceThreadQuery())->setViewer($user)->withIDs(array($request->getInt('id')))->needCropPics(true)->needTransactions(true)->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT)->executeOne();
         $should_404 = true;
     } else {
         if ($latest_participant) {
             $participant = head($latest_participant);
             $conpherence = id(new ConpherenceThreadQuery())->setViewer($user)->withPHIDs(array($participant->getConpherencePHID()))->needCropPics(true)->needTransactions(true)->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT)->executeOne();
             $should_404 = true;
         }
     }
     $durable_column = id(new ConpherenceDurableColumnView())->setUser($user)->setVisible(true);
     if (!$conpherence) {
         if ($should_404) {
             return new Aphront404Response();
         }
         $conpherence_id = null;
         $conpherence_phid = null;
         $latest_transaction_id = null;
         $can_edit = false;
     } else {
         $this->setConpherence($conpherence);
         $participant = $conpherence->getParticipant($user->getPHID());
         $transactions = $conpherence->getTransactions();
         $latest_transaction = head($transactions);
         $write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
         $participant->markUpToDate($conpherence, $latest_transaction);
         unset($write_guard);
         $draft = PhabricatorDraft::newFromUserAndKey($user, $conpherence->getPHID());
         $durable_column->setDraft($draft)->setSelectedConpherence($conpherence)->setConpherences($latest_conpherences);
         $conpherence_id = $conpherence->getID();
         $conpherence_phid = $conpherence->getPHID();
         $latest_transaction_id = $latest_transaction->getID();
         $can_edit = PhabricatorPolicyFilter::hasCapability($user, $conpherence, PhabricatorPolicyCapability::CAN_EDIT);
     }
     $dropdown_query = id(new AphlictDropdownDataQuery())->setViewer($user);
     $dropdown_query->execute();
     $response = array('content' => hsprintf('%s', $durable_column), 'threadID' => $conpherence_id, 'threadPHID' => $conpherence_phid, 'latestTransactionID' => $latest_transaction_id, 'canEdit' => $can_edit, 'aphlictDropdownData' => array($dropdown_query->getNotificationData(), $dropdown_query->getConpherenceData()));
     return id(new AphrontAjaxResponse())->setContent($response);
 }
Example #28
0
 public static function createNewAccount(PhabricatorUser $actor, PhabricatorContentSource $content_source)
 {
     $account = self::initializeNewAccount($actor);
     $xactions = array();
     $xactions[] = id(new PhortuneAccountTransaction())->setTransactionType(PhortuneAccountTransaction::TYPE_NAME)->setNewValue(pht('Default Account'));
     $xactions[] = id(new PhortuneAccountTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', PhortuneAccountHasMemberEdgeType::EDGECONST)->setNewValue(array('=' => array($actor->getPHID() => $actor->getPHID())));
     $editor = id(new PhortuneAccountEditor())->setActor($actor)->setContentSource($content_source);
     // We create an account for you the first time you visit Phortune.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $editor->applyTransactions($account, $xactions);
     unset($unguarded);
     return $account;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $show_prototypes = PhabricatorEnv::getEnvConfig('phabricator.show-prototypes');
     if (!$show_prototypes) {
         throw new Exception(pht('Show prototypes is disabled.
       Set `phabricator.show-prototypes` to `true` to use the image proxy'));
     }
     $viewer = $request->getViewer();
     $img_uri = $request->getStr('uri');
     // Validate the URI before doing anything
     PhabricatorEnv::requireValidRemoteURIForLink($img_uri);
     $uri = new PhutilURI($img_uri);
     $proto = $uri->getProtocol();
     if (!in_array($proto, array('http', 'https'))) {
         throw new Exception(pht('The provided image URI must be either http or https'));
     }
     // Check if we already have the specified image URI downloaded
     $cached_request = id(new PhabricatorFileExternalRequest())->loadOneWhere('uriIndex = %s', PhabricatorHash::digestForIndex($img_uri));
     if ($cached_request) {
         return $this->getExternalResponse($cached_request);
     }
     $ttl = PhabricatorTime::getNow() + phutil_units('7 days in seconds');
     $external_request = id(new PhabricatorFileExternalRequest())->setURI($img_uri)->setTTL($ttl);
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     // Cache missed so we'll need to validate and download the image
     try {
         // Rate limit outbound fetches to make this mechanism less useful for
         // scanning networks and ports.
         PhabricatorSystemActionEngine::willTakeAction(array($viewer->getPHID()), new PhabricatorFilesOutboundRequestAction(), 1);
         $file = PhabricatorFile::newFromFileDownload($uri, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 'canCDN' => true));
         if (!$file->isViewableImage()) {
             $mime_type = $file->getMimeType();
             $engine = new PhabricatorDestructionEngine();
             $engine->destroyObject($file);
             $file = null;
             throw new Exception(pht('The URI "%s" does not correspond to a valid image file, got ' . 'a file with MIME type "%s". You must specify the URI of a ' . 'valid image file.', $uri, $mime_type));
         } else {
             $file->save();
         }
         $external_request->setIsSuccessful(true)->setFilePHID($file->getPHID())->save();
         unset($unguarded);
         return $this->getExternalResponse($external_request);
     } catch (HTTPFutureHTTPResponseStatus $status) {
         $external_request->setIsSuccessful(false)->setResponseMessage($status->getMessage())->save();
         return $this->getExternalResponse($external_request);
     } catch (Exception $ex) {
         // Not actually saving the request in this case
         $external_request->setResponseMessage($ex->getMessage());
         return $this->getExternalResponse($external_request);
     }
 }
 public static function initializeScriptEnvironment()
 {
     self::initializeCommonEnvironment();
     // NOTE: This is dangerous in general, but we know we're in a script context
     // and are not vulnerable to CSRF.
     AphrontWriteGuard::allowDangerousUnguardedWrites(true);
     // There are several places where we log information (about errors, events,
     // service calls, etc.) for analysis via DarkConsole or similar. These are
     // useful for web requests, but grow unboundedly in long-running scripts and
     // daemons. Discard data as it arrives in these cases.
     PhutilServiceProfiler::getInstance()->enableDiscardMode();
     DarkConsoleErrorLogPluginAPI::enableDiscardMode();
     DarkConsoleEventPluginAPI::enableDiscardMode();
 }