'required string', 'host' => 'required string', ); } protected function defineReturnType() { return 'dict'; } protected function defineErrorTypes() { return array( 'ERR-BAD-TOKEN' => pht('Token does not exist or has expired.'), 'ERR-RATE-LIMIT' => pht( 'You have made too many invalid token requests recently. Wait before '. 'making more.'), ); } protected function execute(ConduitAPIRequest $request) { $failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP( PhabricatorConduitCertificateFailureUserLogType::LOGTYPE, 60 * 5); if (count($failed_attempts) > 5) { $this->logFailure($request); throw new ConduitException('ERR-RATE-LIMIT'); } $info = null; $token = $request->getValue('token'); if ($token !== null) { $info = id(new PhabricatorConduitCertificateToken())->loadOneWhere( 'token = %s', trim($token)); } if (!$info || $info->getDateCreated() < time() - (60 * 15)) { $this->logFailure($request, $info); throw new ConduitException('ERR-BAD-TOKEN'); } else { $log = PhabricatorUserLog::initializeNewLog( $request->getUser(), $info->getUserPHID(), PhabricatorConduitCertificateUserLogType::LOGTYPE) ->save(); } $user = id(new PhabricatorUser())->loadOneWhere( 'phid = %s', $info->getUserPHID()); if (!$user) { throw new Exception(pht('Certificate token points to an invalid user!')); } return array( 'username' => $user->getUserName(), 'certificate' => $user->getConduitCertificate(), ); } private function logFailure( ConduitAPIRequest $request, ?PhabricatorConduitCertificateToken $info = null) { $log = PhabricatorUserLog::initializeNewLog( $request->getUser(), $info ? $info->getUserPHID() : '-', PhabricatorConduitCertificateFailureUserLogType::LOGTYPE) ->save(); } }