protected function executeRepositoryOperations()
 {
     $operation = $this->getLFSOperationArgument();
     // NOTE: We aren't checking write access here, even for "upload". The
     // HTTP endpoint should be able to do that for us.
     switch ($operation) {
         case 'upload':
         case 'download':
             break;
         default:
             throw new Exception(pht('Git LFS operation "%s" is not supported by this server.', $operation));
     }
     $repository = $this->getRepository();
     if (!$repository->isGit()) {
         throw new Exception(pht('Repository "%s" is not a Git repository. Git LFS is only ' . 'supported for Git repositories.', $repository->getDisplayName()));
     }
     if (!$repository->canUseGitLFS()) {
         throw new Exception(pht('Git LFS is not enabled for this repository.'));
     }
     // NOTE: This is usually the same as the default URI (which does not
     // need to be specified in the response), but the protocol or domain may
     // differ in some situations.
     $lfs_uri = $repository->getGitLFSURI('info/lfs');
     // Generate a temporary token to allow the user to acces LFS over HTTP.
     // This works even if normal HTTP repository operations are not available
     // on this host, and does not require the user to have a VCS password.
     $user = $this->getUser();
     $authorization = DiffusionGitLFSTemporaryTokenType::newHTTPAuthorization($repository, $user, $operation);
     $headers = array('authorization' => $authorization);
     $result = array('header' => $headers, 'href' => $lfs_uri);
     $result = phutil_json_encode($result);
     $this->writeIO($result);
     $this->waitForGitClient();
     return 0;
 }
 public function newValueForUsers($key, array $users)
 {
     $viewer = $this->getViewer();
     $users = mpull($users, null, 'getPHID');
     $user_phids = array_keys($users);
     $preferences = id(new PhabricatorUserPreferencesQuery())->setViewer($viewer)->withUsers($users)->needSyntheticPreferences(true)->execute();
     $preferences = mpull($preferences, null, 'getUserPHID');
     $all_settings = PhabricatorSetting::getAllSettings();
     $settings = array();
     foreach ($users as $user_phid => $user) {
         $preference = idx($preferences, $user_phid);
         if (!$preference) {
             continue;
         }
         foreach ($all_settings as $key => $setting) {
             $value = $preference->getSettingValue($key);
             // As an optimization, we omit the value from the cache if it is
             // exactly the same as the hardcoded default.
             $default_value = id(clone $setting)->setViewer($user)->getSettingDefaultValue();
             if ($value === $default_value) {
                 continue;
             }
             $settings[$user_phid][$key] = $value;
         }
     }
     $results = array();
     foreach ($user_phids as $user_phid) {
         $value = idx($settings, $user_phid, array());
         $results[$user_phid] = phutil_json_encode($value);
     }
     return $results;
 }
 public function readRequest(PhabricatorConfigOption $option, AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $view_policy = PhabricatorPolicies::POLICY_PUBLIC;
     if ($request->getBool('removeLogo')) {
         $logo_image_phid = null;
     } else {
         if ($request->getFileExists('logoImage')) {
             $logo_image = PhabricatorFile::newFromPHPUpload(idx($_FILES, 'logoImage'), array('name' => 'logo', 'authorPHID' => $viewer->getPHID(), 'viewPolicy' => $view_policy, 'canCDN' => true, 'isExplicitUpload' => true));
             $logo_image_phid = $logo_image->getPHID();
         } else {
             $logo_image_phid = self::getLogoImagePHID();
         }
     }
     $wordmark_text = $request->getStr('wordmarkText');
     $value = array('logoImagePHID' => $logo_image_phid, 'wordmarkText' => $wordmark_text);
     $errors = array();
     $e_value = null;
     try {
         $this->validateOption($option, $value);
     } catch (Exception $ex) {
         $e_value = pht('Invalid');
         $errors[] = $ex->getMessage();
         $value = array();
     }
     return array($e_value, $errors, $value, phutil_json_encode($value));
 }
 public function execute(PhutilArgumentParser $args)
 {
     $console = PhutilConsole::getConsole();
     $repos = id(new PhabricatorRepositoryQuery())->setViewer($this->getViewer())->execute();
     if (!$repos) {
         $console->writeErr("%s\n", pht('There are no repositories.'));
         return 0;
     }
     $from = $args->getArg('from');
     if (!strlen($from)) {
         throw new Exception(pht('You must specify a path prefix to move from with --from.'));
     }
     $to = $args->getArg('to');
     if (!strlen($to)) {
         throw new Exception(pht('You must specify a path prefix to move to with --to.'));
     }
     $rows = array();
     $any_changes = false;
     foreach ($repos as $repo) {
         $src = $repo->getLocalPath();
         $row = array('repository' => $repo, 'move' => false, 'monogram' => $repo->getMonogram(), 'src' => $src, 'dst' => '');
         if (strncmp($src, $from, strlen($from))) {
             $row['action'] = pht('Ignore');
         } else {
             $dst = $to . substr($src, strlen($from));
             $row['action'] = phutil_console_format('**%s**', pht('Move'));
             $row['dst'] = $dst;
             $row['move'] = true;
             $any_changes = true;
         }
         $rows[] = $row;
     }
     $table = id(new PhutilConsoleTable())->addColumn('action', array('title' => pht('Action')))->addColumn('monogram', array('title' => pht('Repository')))->addColumn('src', array('title' => pht('Src')))->addColumn('dst', array('title' => pht('dst')))->setBorders(true);
     foreach ($rows as $row) {
         $display = array_select_keys($row, array('action', 'monogram', 'src', 'dst'));
         $table->addRow($display);
     }
     $table->draw();
     if (!$any_changes) {
         $console->writeOut(pht('No matching repositories.') . "\n");
         return 0;
     }
     $prompt = pht('Apply these changes?');
     if (!phutil_console_confirm($prompt)) {
         throw new Exception(pht('Declining to apply changes.'));
     }
     foreach ($rows as $row) {
         if (empty($row['move'])) {
             continue;
         }
         $repo = $row['repository'];
         $details = $repo->getDetails();
         $details['local-path'] = $row['dst'];
         queryfx($repo->establishConnection('w'), 'UPDATE %T SET details = %s WHERE id = %d', $repo->getTableName(), phutil_json_encode($details), $repo->getID());
     }
     $console->writeOut(pht('Applied changes.') . "\n");
     return 0;
 }
 private function formatStorageProperties(PhutilOpaqueEnvelope $key_envelope, PhutilOpaqueEnvelope $iv_envelope)
 {
     // Encode the raw binary data with base64 so we can wrap it in JSON.
     $data = array('iv.base64' => base64_encode($iv_envelope->openEnvelope()), 'key.base64' => base64_encode($key_envelope->openEnvelope()));
     // Encode the base64 data with JSON.
     $data_clear = phutil_json_encode($data);
     // Encrypt the block key with the master key, using a unique IV.
     $data_iv = self::newAES256IV();
     $key_name = $this->getMasterKeyName();
     $master_key = $this->getMasterKeyMaterial($key_name);
     $data_cipher = $this->encryptData($data_clear, $master_key, $data_iv);
     return array('key.name' => $key_name, 'iv.base64' => base64_encode($data_iv->openEnvelope()), 'payload.base64' => base64_encode($data_cipher));
 }
 /**
  * Before a write, set the "isWriting" flag.
  *
  * This allows us to detect when we lose a node partway through a write and
  * may have committed and acknowledged a write on a node that lost the lock
  * partway through the write and is no longer reachable.
  *
  * In particular, if a node loses its connection to the datbase the global
  * lock is released by default. This is a durable lock which stays locked
  * by default.
  */
 public static function willWrite(AphrontDatabaseConnection $locked_connection, $repository_phid, $device_phid, array $write_properties, $lock_owner)
 {
     $version = new self();
     $table = $version->getTableName();
     queryfx($locked_connection, 'INSERT INTO %T
     (repositoryPHID, devicePHID, repositoryVersion, isWriting,
       writeProperties, lockOwner)
     VALUES
     (%s, %s, %d, %d, %s, %s)
     ON DUPLICATE KEY UPDATE
       isWriting = VALUES(isWriting),
       writeProperties = VALUES(writeProperties),
       lockOwner = VALUES(lockOwner)', $table, $repository_phid, $device_phid, 0, 1, phutil_json_encode($write_properties), $lock_owner);
 }
 public static final function setOpenSetupIssueKeys(array $keys, $update_database)
 {
     $cache = PhabricatorCaches::getSetupCache();
     $cache->setKey('phabricator.setup.issue-keys', $keys);
     if ($update_database) {
         $db_cache = new PhabricatorKeyValueDatabaseCache();
         try {
             $json = phutil_json_encode($keys);
             $db_cache->setKey('phabricator.setup.issue-keys', $json);
         } catch (Exception $ex) {
             // Ignore any write failures, since they likely just indicate that we
             // have a database-related setup issue that needs to be resolved.
         }
     }
 }
Example #8
0
 /**
  * Applies configured serialization to a dictionary of values.
  *
  * @task util
  */
 protected function applyLiskDataSerialization(array &$data, $deserialize)
 {
     $serialization = $this->getConfigOption(self::CONFIG_SERIALIZATION);
     if ($serialization) {
         foreach (array_intersect_key($serialization, $data) as $col => $format) {
             switch ($format) {
                 case self::SERIALIZATION_NONE:
                     break;
                 case self::SERIALIZATION_PHP:
                     if ($deserialize) {
                         $data[$col] = unserialize($data[$col]);
                     } else {
                         $data[$col] = serialize($data[$col]);
                     }
                     break;
                 case self::SERIALIZATION_JSON:
                     if ($deserialize) {
                         $data[$col] = json_decode($data[$col], true);
                     } else {
                         $data[$col] = phutil_json_encode($data[$col]);
                     }
                     break;
                 default:
                     throw new Exception(pht("Unknown serialization format '%s'.", $format));
             }
         }
     }
 }
 public function setContent(array $content)
 {
     $this->content = phutil_json_encode($content);
     return $this;
 }
 public function postMessage(array $data)
 {
     if (!$this->isAdminServer()) {
         throw new Exception(pht('Unable to post message: this is not an admin server!'));
     }
     $server_uri = $this->getURI('/');
     $payload = phutil_json_encode($data);
     id(new HTTPSFuture($server_uri, $payload))->setMethod('POST')->setTimeout(2)->resolvex();
 }
 public function getPartitionStateForCommit()
 {
     $state = PhabricatorEnv::getEnvConfig('cluster.databases');
     foreach ($state as $key => $value) {
         // Don't store passwords, since we don't care if they differ and
         // users may find it surprising.
         unset($state[$key]['pass']);
     }
     return phutil_json_encode($state);
 }
    $phid = $row['phid'];
    $pref_row = queryfx_one($conn_w, 'SELECT preferences FROM %T WHERE userPHID = %s', $prefs_table->getTableName(), $phid);
    if ($pref_row) {
        try {
            $prefs = phutil_json_decode($pref_row['preferences']);
        } catch (Exception $ex) {
            $prefs = array();
        }
    } else {
        $prefs = array();
    }
    $zone = $row['timezoneIdentifier'];
    if (strlen($zone)) {
        $prefs[PhabricatorTimezoneSetting::SETTINGKEY] = $zone;
    }
    $pronoun = $row['sex'];
    if (strlen($pronoun)) {
        $prefs[PhabricatorPronounSetting::SETTINGKEY] = $pronoun;
    }
    $translation = $row['translation'];
    if (strlen($translation)) {
        $prefs[PhabricatorTranslationSetting::SETTINGKEY] = $translation;
    }
    if ($prefs) {
        queryfx($conn_w, 'INSERT INTO %T (phid, userPHID, preferences, dateModified, dateCreated)
        VALUES (%s, %s, %s, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())
        ON DUPLICATE KEY UPDATE preferences = VALUES(preferences)', $prefs_table->getTableName(), $prefs_table->generatePHID(), $phid, phutil_json_encode($prefs));
    }
}
$prefs_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES;
PhabricatorUserCache::clearCacheForAllUsers($prefs_key);
<?php

$table = new PhabricatorCalendarEventTransaction();
$conn_w = $table->establishConnection('w');
echo pht("Restructuring calendar invite transactions...\n");
foreach (new LiskMigrationIterator($table) as $txn) {
    $type = PhabricatorCalendarEventInviteTransaction::TRANSACTIONTYPE;
    if ($txn->getTransactionType() != $type) {
        continue;
    }
    $old_value = array_keys($txn->getOldValue());
    $orig_new = $txn->getNewValue();
    $status_uninvited = 'uninvited';
    foreach ($orig_new as $key => $status) {
        if ($status == $status_uninvited) {
            unset($orig_new[$key]);
        }
    }
    $new_value = array_keys($orig_new);
    queryfx($conn_w, 'UPDATE %T SET ' . 'oldValue = %s, newValue = %s' . 'WHERE id = %d', $table->getTableName(), phutil_json_encode($old_value), phutil_json_encode($new_value), $txn->getID());
}
echo pht('Done.') . "\n";
 public function testJSONEncode()
 {
     $in = array('example' => "Not Valid UTF8: €");
     $caught = null;
     try {
         $value = phutil_json_encode($in);
     } catch (Exception $ex) {
         $caught = $ex;
     }
     $this->assertTrue($caught instanceof Exception);
 }
 public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target)
 {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $buildable = $build->getBuildable();
     $object = $buildable->getBuildableObject();
     $object_phid = $object->getPHID();
     if (!$object instanceof HarbormasterCircleCIBuildableInterface) {
         throw new Exception(pht('Object ("%s") does not implement interface "%s". Only objects ' . 'which implement this interface can be built with CircleCI.', $object_phid, 'HarbormasterCircleCIBuildableInterface'));
     }
     $github_uri = $object->getCircleCIGitHubRepositoryURI();
     $build_type = $object->getCircleCIBuildIdentifierType();
     $build_identifier = $object->getCircleCIBuildIdentifier();
     $path = self::getGitHubPath($github_uri);
     if ($path === null) {
         throw new Exception(pht('Object ("%s") claims "%s" is a GitHub repository URI, but the ' . 'domain does not appear to be GitHub.', $object_phid, $github_uri));
     }
     $path_parts = trim($path, '/');
     $path_parts = explode('/', $path_parts);
     if (count($path_parts) < 2) {
         throw new Exception(pht('Object ("%s") claims "%s" is a GitHub repository URI, but the ' . 'path ("%s") does not have enough components (expected at least ' . 'two).', $object_phid, $github_uri, $path));
     }
     list($github_namespace, $github_name) = $path_parts;
     $github_name = preg_replace('(\\.git$)', '', $github_name);
     $credential_phid = $this->getSetting('token');
     $api_token = id(new PassphraseCredentialQuery())->setViewer($viewer)->withPHIDs(array($credential_phid))->needSecrets(true)->executeOne();
     if (!$api_token) {
         throw new Exception(pht('Unable to load API token ("%s")!', $credential_phid));
     }
     // When we pass "revision", the branch is ignored (and does not even need
     // to exist), and only shows up in the UI. Use a cute string which will
     // certainly never break anything or cause any kind of problem.
     $ship = "🚢";
     $branch = "{$ship}Harbormaster";
     $token = $api_token->getSecret()->openEnvelope();
     $parts = array('https://circleci.com/api/v1/project', phutil_escape_uri($github_namespace), phutil_escape_uri($github_name) . "?circle-token={$token}");
     $uri = implode('/', $parts);
     $data_structure = array();
     switch ($build_type) {
         case 'tag':
             $data_structure['tag'] = $build_identifier;
             break;
         case 'revision':
             $data_structure['revision'] = $build_identifier;
             break;
         default:
             throw new Exception(pht('Unknown CircleCI build type "%s". Expected "%s" or "%s".', $build_type, 'tag', 'revision'));
     }
     $data_structure['build_parameters'] = array('HARBORMASTER_BUILD_TARGET_PHID' => $build_target->getPHID());
     $json_data = phutil_json_encode($data_structure);
     $future = id(new HTTPSFuture($uri, $json_data))->setMethod('POST')->addHeader('Content-Type', 'application/json')->addHeader('Accept', 'application/json')->setTimeout(60);
     $this->resolveFutures($build, $build_target, array($future));
     $this->logHTTPResponse($build, $build_target, $future, pht('CircleCI'));
     list($status, $body) = $future->resolve();
     if ($status->isError()) {
         throw new HarbormasterBuildFailureException();
     }
     $response = phutil_json_decode($body);
     $build_uri = idx($response, 'build_url');
     if (!$build_uri) {
         throw new Exception(pht('CircleCI did not return a "%s"!', 'build_url'));
     }
     $target_phid = $build_target->getPHID();
     // Write an artifact to create a link to the external build in CircleCI.
     $api_method = 'harbormaster.createartifact';
     $api_params = array('buildTargetPHID' => $target_phid, 'artifactType' => HarbormasterURIArtifact::ARTIFACTCONST, 'artifactKey' => 'circleci.uri', 'artifactData' => array('uri' => $build_uri, 'name' => pht('View in CircleCI'), 'ui.external' => true));
     id(new ConduitCall($api_method, $api_params))->setUser($viewer)->execute();
 }
<?php

$table = new PhabricatorUserPreferences();
$conn_w = $table->establishConnection('w');
// Convert "Mail Format", "Re Prefix" and "Vary Subjects" mail settings to
// string constants to avoid weird stuff where we store "true" and "false" as
// strings in the database.
// Each of these keys will be converted to the first value if present and
// truthy, or the second value if present and falsey.
$remap = array('html-emails' => array('html', 'text'), 're-prefix' => array('re', 'none'), 'vary-subject' => array('vary', 'static'));
foreach (new LiskMigrationIterator($table) as $row) {
    $dict = $row->getPreferences();
    $should_update = false;
    foreach ($remap as $key => $value) {
        if (isset($dict[$key])) {
            if ($dict[$key]) {
                $dict[$key] = $value[0];
            } else {
                $dict[$key] = $value[1];
            }
            $should_update = true;
        }
    }
    if (!$should_update) {
        continue;
    }
    queryfx($conn_w, 'UPDATE %T SET preferences = %s WHERE id = %d', $table->getTableName(), phutil_json_encode($dict), $row->getID());
}
$prefs_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES;
PhabricatorUserCache::clearCacheForAllUsers($prefs_key);
Example #17
0
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case AlmanacTransaction::TYPE_PROPERTY_UPDATE:
             foreach ($xactions as $xaction) {
                 $property_key = $xaction->getMetadataValue('almanac.property');
                 $message = null;
                 try {
                     AlmanacNames::validateName($property_key);
                 } catch (Exception $ex) {
                     $message = $ex->getMessage();
                 }
                 if ($message !== null) {
                     $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), $message, $xaction);
                     $errors[] = $error;
                     continue;
                 }
                 $new_value = $xaction->getNewValue();
                 try {
                     phutil_json_encode($new_value);
                 } catch (Exception $ex) {
                     $message = pht('Almanac property values must be representable in JSON. %s', $ex->getMessage());
                 }
                 if ($message !== null) {
                     $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), $message, $xaction);
                     $errors[] = $error;
                     continue;
                 }
             }
             break;
         case AlmanacTransaction::TYPE_PROPERTY_REMOVE:
             // NOTE: No name validation on removals since it's OK to delete
             // an invalid property that somehow came into existence.
             break;
     }
     return $errors;
 }
    }
    $end_datetime = PhutilCalendarAbsoluteDateTime::newFromEpoch($utc_max);
    if ($is_all_day) {
        $end_datetime->setIsAllDay(true);
    }
    if ($utc_until) {
        $until_datetime = PhutilCalendarAbsoluteDateTime::newFromEpoch($utc_until);
    } else {
        $until_datetime = null;
    }
    $parameters['startDateTime'] = $start_datetime->toDictionary();
    $parameters['endDateTime'] = $end_datetime->toDictionary();
    if ($until_datetime) {
        $parameters['untilDateTime'] = $until_datetime->toDictionary();
    }
    queryfx($conn, 'UPDATE %T SET parameters = %s WHERE id = %d', $table_name, phutil_json_encode($parameters), $row['id']);
}
// Generate UTC epochs for all events. We can't readily do this one at a
// time because instance UTC epochs rely on having the parent event.
$viewer = PhabricatorUser::getOmnipotentUser();
$all_events = id(new PhabricatorCalendarEventQuery())->setViewer($viewer)->execute();
foreach ($all_events as $event) {
    if ($event->getUTCInitialEpoch()) {
        // Already migrated.
        continue;
    }
    try {
        $event->updateUTCEpochs();
    } catch (Exception $ex) {
        continue;
    }
 private function loadSnippets(array $pastes)
 {
     $cache = new PhabricatorKeyValueDatabaseCache();
     $cache = new PhutilKeyValueCacheProfiler($cache);
     $cache->setProfiler(PhutilServiceProfiler::getInstance());
     $keys = array();
     foreach ($pastes as $paste) {
         $keys[] = $this->getSnippetCacheKey($paste);
     }
     $caches = $cache->getKeys($keys);
     $need_raw = array();
     $have_cache = array();
     foreach ($pastes as $paste) {
         $key = $this->getSnippetCacheKey($paste);
         if (isset($caches[$key])) {
             $snippet_data = phutil_json_decode($caches[$key], true);
             $snippet = new PhabricatorPasteSnippet(phutil_safe_html($snippet_data['content']), $snippet_data['type']);
             $paste->attachSnippet($snippet);
             $have_cache[$paste->getPHID()] = true;
         } else {
             $need_raw[$key] = $paste;
         }
     }
     if (!$need_raw) {
         return $pastes;
     }
     $write_data = array();
     $have_raw = $this->loadRawContent($need_raw);
     $have_raw = mpull($have_raw, null, 'getPHID');
     foreach ($pastes as $key => $paste) {
         $paste_phid = $paste->getPHID();
         if (isset($have_cache[$paste_phid])) {
             continue;
         }
         if (empty($have_raw[$paste_phid])) {
             unset($pastes[$key]);
             continue;
         }
         $snippet = $this->buildSnippet($paste);
         $paste->attachSnippet($snippet);
         $snippet_data = array('content' => (string) $snippet->getContent(), 'type' => (string) $snippet->getType());
         $write_data[$this->getSnippetCacheKey($paste)] = phutil_json_encode($snippet_data);
     }
     if ($write_data) {
         $cache->setKeys($write_data);
     }
     return $pastes;
 }
Example #20
0
 public static function encodeJSONForHTTPResponse(array $object)
 {
     array_walk_recursive($object, array(__CLASS__, 'processValueForJSONEncoding'));
     $response = phutil_json_encode($object);
     // Prevent content sniffing attacks by encoding "<" and ">", so browsers
     // won't try to execute the document as HTML even if they ignore
     // Content-Type and X-Content-Type-Options. See T865.
     $response = str_replace(array('<', '>'), array('\\u003c', '\\u003e'), $response);
     return $response;
 }
 public final function serialize()
 {
     return phutil_json_encode(array('source' => $this->getSource(), 'params' => $this->params));
 }
Example #22
0
 private function submitChangesToStagingArea($id)
 {
     $result = $this->pushChangesToStagingArea($id);
     // We'll either get a failure constant on error, or a list of pushed
     // refs on success.
     $ok = is_array($result);
     if ($ok) {
         $staging = array('status' => self::STAGING_PUSHED, 'refs' => $result);
     } else {
         $staging = array('status' => $result, 'refs' => array());
     }
     $this->updateDiffProperty('arc.staging', phutil_json_encode($staging));
 }
<?php

$table = new AlmanacProperty();
$conn_w = $table->establishConnection('w');
// We're going to JSON-encode the value in each row: previously rows stored
// plain strings, but now they store JSON, so we need to update them.
foreach (new LiskMigrationIterator($table) as $property) {
    $key = $property->getFieldName();
    $current_row = queryfx_one($conn_w, 'SELECT fieldValue FROM %T WHERE id = %d', $table->getTableName(), $property->getID());
    if (!$current_row) {
        continue;
    }
    queryfx($conn_w, 'UPDATE %T SET fieldValue = %s WHERE id = %d', $table->getTableName(), phutil_json_encode($current_row['fieldValue']), $property->getID());
}