[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class ConduitConnectConduitAPIMethod extends ConduitAPIMethod { 4 5 public function getAPIMethodName() { 6 return 'conduit.connect'; 7 } 8 9 public function shouldRequireAuthentication() { 10 return false; 11 } 12 13 public function shouldAllowUnguardedWrites() { 14 return true; 15 } 16 17 public function getMethodDescription() { 18 return 'Connect a session-based client.'; 19 } 20 21 public function defineParamTypes() { 22 return array( 23 'client' => 'required string', 24 'clientVersion' => 'required int', 25 'clientDescription' => 'optional string', 26 'user' => 'optional string', 27 'authToken' => 'optional int', 28 'authSignature' => 'optional string', 29 'host' => 'deprecated', 30 ); 31 } 32 33 public function defineReturnType() { 34 return 'dict<string, any>'; 35 } 36 37 public function defineErrorTypes() { 38 return array( 39 'ERR-BAD-VERSION' => 40 'Client/server version mismatch. Upgrade your server or downgrade '. 41 'your client.', 42 'NEW-ARC-VERSION' => 43 'Client/server version mismatch. Upgrade your client.', 44 'ERR-UNKNOWN-CLIENT' => 45 'Client is unknown.', 46 'ERR-INVALID-USER' => 47 'The username you are attempting to authenticate with is not valid.', 48 'ERR-INVALID-CERTIFICATE' => 49 'Your authentication certificate for this server is invalid.', 50 'ERR-INVALID-TOKEN' => 51 "The challenge token you are authenticating with is outside of the ". 52 "allowed time range. Either your system clock is out of whack or ". 53 "you're executing a replay attack.", 54 'ERR-NO-CERTIFICATE' => 'This server requires authentication.', 55 ); 56 } 57 58 protected function execute(ConduitAPIRequest $request) { 59 $client = $request->getValue('client'); 60 $client_version = (int)$request->getValue('clientVersion'); 61 $client_description = (string)$request->getValue('clientDescription'); 62 $client_description = id(new PhutilUTF8StringTruncator()) 63 ->setMaximumCodepoints(255) 64 ->truncateString($client_description); 65 $username = (string)$request->getValue('user'); 66 67 // Log the connection, regardless of the outcome of checks below. 68 $connection = new PhabricatorConduitConnectionLog(); 69 $connection->setClient($client); 70 $connection->setClientVersion($client_version); 71 $connection->setClientDescription($client_description); 72 $connection->setUsername($username); 73 $connection->save(); 74 75 switch ($client) { 76 case 'arc': 77 $server_version = 6; 78 $supported_versions = array( 79 $server_version => true, 80 // Client version 5 introduced "user.query" call 81 4 => true, 82 // Client version 6 introduced "diffusion.getlintmessages" call 83 5 => true, 84 ); 85 86 if (empty($supported_versions[$client_version])) { 87 if ($server_version < $client_version) { 88 $ex = new ConduitException('ERR-BAD-VERSION'); 89 $ex->setErrorDescription( 90 "Your 'arc' client version is '{$client_version}', which ". 91 "is newer than the server version, '{$server_version}'. ". 92 "Upgrade your Phabricator install."); 93 } else { 94 $ex = new ConduitException('NEW-ARC-VERSION'); 95 $ex->setErrorDescription( 96 "A new version of arc is available! You need to upgrade ". 97 "to connect to this server (you are running version ". 98 "{$client_version}, the server is running version ". 99 "{$server_version})."); 100 } 101 throw $ex; 102 } 103 break; 104 default: 105 // Allow new clients by default. 106 break; 107 } 108 109 $token = $request->getValue('authToken'); 110 $signature = $request->getValue('authSignature'); 111 112 $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username); 113 if (!$user) { 114 throw new ConduitException('ERR-INVALID-USER'); 115 } 116 117 $session_key = null; 118 if ($token && $signature) { 119 $threshold = 60 * 15; 120 $now = time(); 121 if (abs($token - $now) > $threshold) { 122 throw id(new ConduitException('ERR-INVALID-TOKEN')) 123 ->setErrorDescription( 124 pht( 125 'The request you submitted is signed with a timestamp, but that '. 126 'timestamp is not within %s of the current time. The '. 127 'signed timestamp is %s (%s), and the current server time is '. 128 '%s (%s). This is a difference of %s seconds, but the '. 129 'timestamp must differ from the server time by no more than '. 130 '%s seconds. Your client or server clock may not be set '. 131 'correctly.', 132 phutil_format_relative_time($threshold), 133 $token, 134 date('r', $token), 135 $now, 136 date('r', $now), 137 ($token - $now), 138 $threshold)); 139 } 140 $valid = sha1($token.$user->getConduitCertificate()); 141 if ($valid != $signature) { 142 throw new ConduitException('ERR-INVALID-CERTIFICATE'); 143 } 144 $session_key = id(new PhabricatorAuthSessionEngine())->establishSession( 145 PhabricatorAuthSession::TYPE_CONDUIT, 146 $user->getPHID(), 147 $partial = false); 148 } else { 149 throw new ConduitException('ERR-NO-CERTIFICATE'); 150 } 151 152 return array( 153 'connectionID' => $connection->getID(), 154 'sessionKey' => $session_key, 155 'userPHID' => $user->getPHID(), 156 ); 157 } 158 159 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |