public function processRequest()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $conn_table = new PhabricatorConduitConnectionLog();
     $call_table = new PhabricatorConduitMethodCallLog();
     $conn_r = $call_table->establishConnection('r');
     $pager = new AphrontCursorPagerView();
     $pager->readFromRequest($request);
     $pager->setPageSize(500);
     $query = id(new PhabricatorConduitLogQuery())->setViewer($viewer);
     $methods = $request->getStrList('methods');
     if ($methods) {
         $query->withMethods($methods);
     }
     $calls = $query->executeWithCursorPager($pager);
     $conn_ids = array_filter(mpull($calls, 'getConnectionID'));
     $conns = array();
     if ($conn_ids) {
         $conns = $conn_table->loadAllWhere('id IN (%Ld)', $conn_ids);
     }
     $table = $this->renderCallTable($calls, $conns);
     $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Call Logs'))->appendChild($table);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Call Logs'));
     return $this->buildApplicationPage(array($crumbs, $box, $pager), array('title' => pht('Conduit Logs')));
 }
 protected function collectGarbage()
 {
     $table = new PhabricatorConduitConnectionLog();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'DELETE FROM %T WHERE dateCreated < %d
     ORDER BY dateCreated ASC LIMIT 100', $table->getTableName(), $this->getGarbageEpoch());
     return $conn_w->getAffectedRows() == 100;
 }
 public function collectGarbage()
 {
     $key = 'gcdaemon.ttl.conduit-logs';
     $ttl = PhabricatorEnv::getEnvConfig($key);
     if ($ttl <= 0) {
         return false;
     }
     $table = new PhabricatorConduitConnectionLog();
     $conn_w = $table->establishConnection('w');
     queryfx($conn_w, 'DELETE FROM %T WHERE dateCreated < %d
     ORDER BY dateCreated ASC LIMIT 100', $table->getTableName(), time() - $ttl);
     return $conn_w->getAffectedRows() == 100;
 }
 private function renderCallTable(array $calls, array $conns)
 {
     $user = $this->getRequest()->getUser();
     $rows = array();
     foreach ($calls as $call) {
         $conn = idx($conns, $call->getConnectionID());
         if (!$conn) {
             // If there's no connection, use an empty object.
             $conn = new PhabricatorConduitConnectionLog();
         }
         $rows[] = array($call->getConnectionID(), phutil_escape_html($conn->getUserName()), phutil_escape_html($call->getMethod()), phutil_escape_html($call->getError()), number_format($call->getDuration()) . ' us', phabricator_datetime($call->getDateCreated(), $user));
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('Connection', 'User', 'Method', 'Error', 'Duration', 'Date'));
     $table->setColumnClasses(array('', '', 'wide', '', 'n', 'right'));
     return $table;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $client = $request->getValue('client');
     $client_version = (int) $request->getValue('clientVersion');
     $client_description = (string) $request->getValue('clientDescription');
     $client_description = id(new PhutilUTF8StringTruncator())->setMaximumBytes(255)->truncateString($client_description);
     $username = (string) $request->getValue('user');
     // Log the connection, regardless of the outcome of checks below.
     $connection = new PhabricatorConduitConnectionLog();
     $connection->setClient($client);
     $connection->setClientVersion($client_version);
     $connection->setClientDescription($client_description);
     $connection->setUsername($username);
     $connection->save();
     switch ($client) {
         case 'arc':
             $server_version = 6;
             $supported_versions = array($server_version => true, 4 => true, 5 => true);
             if (empty($supported_versions[$client_version])) {
                 if ($server_version < $client_version) {
                     $ex = new ConduitException('ERR-BAD-VERSION');
                     $ex->setErrorDescription(pht("Your '%s' client version is '%d', which is newer than the " . "server version, '%d'. Upgrade your Phabricator install.", 'arc', $client_version, $server_version));
                 } else {
                     $ex = new ConduitException('NEW-ARC-VERSION');
                     $ex->setErrorDescription(pht('A new version of arc is available! You need to upgrade ' . 'to connect to this server (you are running version ' . '%d, the server is running version %d).', $client_version, $server_version));
                 }
                 throw $ex;
             }
             break;
         default:
             // Allow new clients by default.
             break;
     }
     $token = $request->getValue('authToken');
     $signature = $request->getValue('authSignature');
     $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username);
     if (!$user) {
         throw new ConduitException('ERR-INVALID-USER');
     }
     $session_key = null;
     if ($token && $signature) {
         $threshold = 60 * 15;
         $now = time();
         if (abs($token - $now) > $threshold) {
             throw id(new ConduitException('ERR-INVALID-TOKEN'))->setErrorDescription(pht('The request you submitted is signed with a timestamp, but that ' . 'timestamp is not within %s of the current time. The ' . 'signed timestamp is %s (%s), and the current server time is ' . '%s (%s). This is a difference of %s seconds, but the ' . 'timestamp must differ from the server time by no more than ' . '%s seconds. Your client or server clock may not be set ' . 'correctly.', phutil_format_relative_time($threshold), $token, date('r', $token), $now, date('r', $now), $token - $now, $threshold));
         }
         $valid = sha1($token . $user->getConduitCertificate());
         if (!phutil_hashes_are_identical($valid, $signature)) {
             throw new ConduitException('ERR-INVALID-CERTIFICATE');
         }
         $session_key = id(new PhabricatorAuthSessionEngine())->establishSession(PhabricatorAuthSession::TYPE_CONDUIT, $user->getPHID(), $partial = false);
     } else {
         throw new ConduitException('ERR-NO-CERTIFICATE');
     }
     return array('connectionID' => $connection->getID(), 'sessionKey' => $session_key, 'userPHID' => $user->getPHID());
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $this->validateHost($request->getValue('host'));
     $client = $request->getValue('client');
     $client_version = (int) $request->getValue('clientVersion');
     $client_description = (string) $request->getValue('clientDescription');
     $username = (string) $request->getValue('user');
     // Log the connection, regardless of the outcome of checks below.
     $connection = new PhabricatorConduitConnectionLog();
     $connection->setClient($client);
     $connection->setClientVersion($client_version);
     $connection->setClientDescription($client_description);
     $connection->setUsername($username);
     $connection->save();
     switch ($client) {
         case 'arc':
             $server_version = 3;
             switch ($client_version) {
                 case $server_version:
                     break;
                 default:
                     $ex = new ConduitException('ERR-BAD-VERSION');
                     if ($server_version < $client_version) {
                         $upgrade = "Upgrade your Phabricator install.";
                     } else {
                         $upgrade = "Upgrade your 'arc' client.";
                     }
                     $ex->setErrorDescription("Your 'arc' client version is '{$client_version}', but this " . "server expects version '{$server_version}'. {$upgrade}");
                     throw $ex;
             }
             break;
         default:
             // Allow new clients by default.
             break;
     }
     $token = $request->getValue('authToken');
     $signature = $request->getValue('authSignature');
     $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username);
     if (!$user) {
         throw new ConduitException('ERR-INVALID-USER');
     }
     $session_key = null;
     if ($token && $signature) {
         if (abs($token - time()) > 60 * 15) {
             throw new ConduitException('ERR-INVALID-TOKEN');
         }
         $valid = sha1($token . $user->getConduitCertificate());
         if ($valid != $signature) {
             throw new ConduitException('ERR-INVALID-CERTIFICATE');
         }
         $session_key = $user->establishSession('conduit');
     } else {
         throw new ConduitException('ERR-NO-CERTIFICATE');
     }
     return array('connectionID' => $connection->getID(), 'sessionKey' => $session_key, 'userPHID' => $user->getPHID());
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $this->validateHost($request->getValue('host'));
     $client = $request->getValue('client');
     $client_version = (int) $request->getValue('clientVersion');
     $client_description = (string) $request->getValue('clientDescription');
     $username = (string) $request->getValue('user');
     // Log the connection, regardless of the outcome of checks below.
     $connection = new PhabricatorConduitConnectionLog();
     $connection->setClient($client);
     $connection->setClientVersion($client_version);
     $connection->setClientDescription($client_description);
     $connection->setUsername($username);
     $connection->save();
     switch ($client) {
         case 'arc':
             $server_version = 5;
             $supported_versions = array($server_version => true, 4 => true);
             if (empty($supported_versions[$client_version])) {
                 if ($server_version < $client_version) {
                     $ex = new ConduitException('ERR-BAD-VERSION');
                     $ex->setErrorDescription("Your 'arc' client version is '{$client_version}', which " . "is newer than the server version, '{$server_version}'. " . "Upgrade your Phabricator install.");
                 } else {
                     $ex = new ConduitException('NEW-ARC-VERSION');
                     $ex->setErrorDescription("A new version of arc is available! You need to upgrade " . "to connect to this server (you are running version " . "{$client_version}, the server is running version " . "{$server_version}).");
                 }
                 throw $ex;
             }
             break;
         default:
             // Allow new clients by default.
             break;
     }
     $token = $request->getValue('authToken');
     $signature = $request->getValue('authSignature');
     $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username);
     if (!$user) {
         throw new ConduitException('ERR-INVALID-USER');
     }
     $session_key = null;
     if ($token && $signature) {
         if (abs($token - time()) > 60 * 15) {
             throw new ConduitException('ERR-INVALID-TOKEN');
         }
         $valid = sha1($token . $user->getConduitCertificate());
         if ($valid != $signature) {
             throw new ConduitException('ERR-INVALID-CERTIFICATE');
         }
         $session_key = $user->establishSession('conduit');
     } else {
         throw new ConduitException('ERR-NO-CERTIFICATE');
     }
     return array('connectionID' => $connection->getID(), 'sessionKey' => $session_key, 'userPHID' => $user->getPHID());
 }