Files
phabricator/src/applications/conduit/query/PhabricatorConduitTokenQuery.php

129 lines
2.8 KiB
PHP
Raw Normal View History

Add Conduit Tokens to make authentication in Conduit somewhat more sane Summary: Ref T5955. Summary of intended changes: **Improve Granularity of Authorization**: Currently, users have one Conduit Certificate. This isn't very flexible, and means that you can't ever generate an API token with limited permissions or IP block controls (see T6706). This moves toward a world where you can generate multiple tokens, revoke them individually, and assign disparate privileges to them. **Standardize Token Management**: This moves Conduit to work the same way that sessions, OAuth authorizations, and temporary tokens already work, instead of being this crazy bizarre mess. **Make Authentication Faster**: Authentication currently requires a handshake (conduit.connect) to establish a session, like the web UI. This is unnecessary from a security point of view and puts an extra round trip in front of all Conduit activity. Essentially no other API anywhere works like this. **Make Authentication Simpler**: The handshake is complex, and involves deriving hashes. The session is also complex, and creates issues like T4377. Handshake and session management require different inputs. **Make Token Management Simpler**: The certificate is this huge long thing right now, which is not necessary from a security perspective. There are separate Arcanist handshake tokens, but they have a different set of issues. We can move forward to a token management world where neither of these problems exist. **Lower Protocol Barrier**: The simplest possible API client is very complex right now. It should be `curl`. Simplifying authentication is a necessary step toward this. **Unblock T2783**: T2783 is blocked on nodes in the cluster making authenticated API calls to other nodes. This provides a simpler way forward than the handshake mess (or enormous-hack-mess) which would currently be required. Test Plan: - Generated tokens. - Generated tokens for a bot account. - Terminated tokens (and for a bot account). - Terminated all tokens (and for a bot account). - Ran GC and saw it reap all the expired tokens. NOTE: These tokens can not actually be used to authenticate yet! {F249658} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5955 Differential Revision: https://secure.phabricator.com/D10985
2014-12-15 11:14:23 -08:00
<?php
final class PhabricatorConduitTokenQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $objectPHIDs;
private $expired;
Accept Conduit tokens as an authentication mechanism Summary: - Ref T5955. Accept the tokens introduced in D10985 as an authentication token. - Ref T3628. Permit simple `curl`-compatible decoding of parameters. Test Plan: - Ran some sensible `curl` API commands: ``` epriestley@orbital ~/dev/phabricator $ curl -g "http://local.phacility.com/api/user.whoami?api.token=api-f7dfpoyelk4mmz6vxcueb6hcbtbk" ; echo {"result":{"phid":"PHID-USER-cvfydnwadpdj7vdon36z","userName":"admin","realName":"asdf","image":"http:\/\/local.phacility.com\/res\/1410737307T\/phabricator\/3eb28cd9\/rsrc\/image\/avatar.png","uri":"http:\/\/local.phacility.com\/p\/admin\/","roles":["admin","verified","approved","activated"]},"error_code":null,"error_info":null} ``` ``` epriestley@orbital ~/dev/phabricator $ curl -g "http://local.phacility.com/api/differential.query?api.token=api-f7dfpoyelk4mmz6vxcueb6hcbtbk&ids[]=1" ; echo {"result":[{"id":"1","phid":"PHID-DREV-v3a67ixww3ccg5lqbxee","title":"zxcb","uri":"http:\/\/local.phacility.com\/D1","dateCreated":"1418405590","dateModified":"1418405590","authorPHID":"PHID-USER-cvfydnwadpdj7vdon36z","status":"0","statusName":"Needs Review","branch":null,"summary":"","testPlan":"zxcb","lineCount":"6","activeDiffPHID":"PHID-DIFF-pzbtc5rw6pe5j2kxtlr2","diffs":["1"],"commits":[],"reviewers":[],"ccs":[],"hashes":[],"auxiliary":{"phabricator:projects":[],"phabricator:depends-on":[],"organization.sqlmigration":null},"arcanistProjectPHID":null,"repositoryPHID":null,"sourcePath":null}],"error_code":null,"error_info":null} ``` - Ran older-style commands like `arc list` against the local install. - Ran commands via web console. - Added and ran a unit test to make sure nothing is using forbidden parameter names. - Terminated a token and verified it no longer works. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T3628, T5955 Differential Revision: https://secure.phabricator.com/D10986
2014-12-15 11:14:41 -08:00
private $tokens;
private $tokenTypes;
Add Conduit Tokens to make authentication in Conduit somewhat more sane Summary: Ref T5955. Summary of intended changes: **Improve Granularity of Authorization**: Currently, users have one Conduit Certificate. This isn't very flexible, and means that you can't ever generate an API token with limited permissions or IP block controls (see T6706). This moves toward a world where you can generate multiple tokens, revoke them individually, and assign disparate privileges to them. **Standardize Token Management**: This moves Conduit to work the same way that sessions, OAuth authorizations, and temporary tokens already work, instead of being this crazy bizarre mess. **Make Authentication Faster**: Authentication currently requires a handshake (conduit.connect) to establish a session, like the web UI. This is unnecessary from a security point of view and puts an extra round trip in front of all Conduit activity. Essentially no other API anywhere works like this. **Make Authentication Simpler**: The handshake is complex, and involves deriving hashes. The session is also complex, and creates issues like T4377. Handshake and session management require different inputs. **Make Token Management Simpler**: The certificate is this huge long thing right now, which is not necessary from a security perspective. There are separate Arcanist handshake tokens, but they have a different set of issues. We can move forward to a token management world where neither of these problems exist. **Lower Protocol Barrier**: The simplest possible API client is very complex right now. It should be `curl`. Simplifying authentication is a necessary step toward this. **Unblock T2783**: T2783 is blocked on nodes in the cluster making authenticated API calls to other nodes. This provides a simpler way forward than the handshake mess (or enormous-hack-mess) which would currently be required. Test Plan: - Generated tokens. - Generated tokens for a bot account. - Terminated tokens (and for a bot account). - Terminated all tokens (and for a bot account). - Ran GC and saw it reap all the expired tokens. NOTE: These tokens can not actually be used to authenticate yet! {F249658} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5955 Differential Revision: https://secure.phabricator.com/D10985
2014-12-15 11:14:23 -08:00
public function withExpired($expired) {
$this->expired = $expired;
return $this;
}
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withObjectPHIDs(array $phids) {
$this->objectPHIDs = $phids;
return $this;
}
Accept Conduit tokens as an authentication mechanism Summary: - Ref T5955. Accept the tokens introduced in D10985 as an authentication token. - Ref T3628. Permit simple `curl`-compatible decoding of parameters. Test Plan: - Ran some sensible `curl` API commands: ``` epriestley@orbital ~/dev/phabricator $ curl -g "http://local.phacility.com/api/user.whoami?api.token=api-f7dfpoyelk4mmz6vxcueb6hcbtbk" ; echo {"result":{"phid":"PHID-USER-cvfydnwadpdj7vdon36z","userName":"admin","realName":"asdf","image":"http:\/\/local.phacility.com\/res\/1410737307T\/phabricator\/3eb28cd9\/rsrc\/image\/avatar.png","uri":"http:\/\/local.phacility.com\/p\/admin\/","roles":["admin","verified","approved","activated"]},"error_code":null,"error_info":null} ``` ``` epriestley@orbital ~/dev/phabricator $ curl -g "http://local.phacility.com/api/differential.query?api.token=api-f7dfpoyelk4mmz6vxcueb6hcbtbk&ids[]=1" ; echo {"result":[{"id":"1","phid":"PHID-DREV-v3a67ixww3ccg5lqbxee","title":"zxcb","uri":"http:\/\/local.phacility.com\/D1","dateCreated":"1418405590","dateModified":"1418405590","authorPHID":"PHID-USER-cvfydnwadpdj7vdon36z","status":"0","statusName":"Needs Review","branch":null,"summary":"","testPlan":"zxcb","lineCount":"6","activeDiffPHID":"PHID-DIFF-pzbtc5rw6pe5j2kxtlr2","diffs":["1"],"commits":[],"reviewers":[],"ccs":[],"hashes":[],"auxiliary":{"phabricator:projects":[],"phabricator:depends-on":[],"organization.sqlmigration":null},"arcanistProjectPHID":null,"repositoryPHID":null,"sourcePath":null}],"error_code":null,"error_info":null} ``` - Ran older-style commands like `arc list` against the local install. - Ran commands via web console. - Added and ran a unit test to make sure nothing is using forbidden parameter names. - Terminated a token and verified it no longer works. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T3628, T5955 Differential Revision: https://secure.phabricator.com/D10986
2014-12-15 11:14:41 -08:00
public function withTokens(array $tokens) {
$this->tokens = $tokens;
return $this;
}
public function withTokenTypes(array $types) {
$this->tokenTypes = $types;
return $this;
}
protected function loadPage() {
Add Conduit Tokens to make authentication in Conduit somewhat more sane Summary: Ref T5955. Summary of intended changes: **Improve Granularity of Authorization**: Currently, users have one Conduit Certificate. This isn't very flexible, and means that you can't ever generate an API token with limited permissions or IP block controls (see T6706). This moves toward a world where you can generate multiple tokens, revoke them individually, and assign disparate privileges to them. **Standardize Token Management**: This moves Conduit to work the same way that sessions, OAuth authorizations, and temporary tokens already work, instead of being this crazy bizarre mess. **Make Authentication Faster**: Authentication currently requires a handshake (conduit.connect) to establish a session, like the web UI. This is unnecessary from a security point of view and puts an extra round trip in front of all Conduit activity. Essentially no other API anywhere works like this. **Make Authentication Simpler**: The handshake is complex, and involves deriving hashes. The session is also complex, and creates issues like T4377. Handshake and session management require different inputs. **Make Token Management Simpler**: The certificate is this huge long thing right now, which is not necessary from a security perspective. There are separate Arcanist handshake tokens, but they have a different set of issues. We can move forward to a token management world where neither of these problems exist. **Lower Protocol Barrier**: The simplest possible API client is very complex right now. It should be `curl`. Simplifying authentication is a necessary step toward this. **Unblock T2783**: T2783 is blocked on nodes in the cluster making authenticated API calls to other nodes. This provides a simpler way forward than the handshake mess (or enormous-hack-mess) which would currently be required. Test Plan: - Generated tokens. - Generated tokens for a bot account. - Terminated tokens (and for a bot account). - Terminated all tokens (and for a bot account). - Ran GC and saw it reap all the expired tokens. NOTE: These tokens can not actually be used to authenticate yet! {F249658} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5955 Differential Revision: https://secure.phabricator.com/D10985
2014-12-15 11:14:23 -08:00
$table = new PhabricatorConduitToken();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);;
}
private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
'id IN (%Ld)',
$this->ids);
}
if ($this->objectPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
'objectPHID IN (%Ls)',
$this->objectPHIDs);
}
Accept Conduit tokens as an authentication mechanism Summary: - Ref T5955. Accept the tokens introduced in D10985 as an authentication token. - Ref T3628. Permit simple `curl`-compatible decoding of parameters. Test Plan: - Ran some sensible `curl` API commands: ``` epriestley@orbital ~/dev/phabricator $ curl -g "http://local.phacility.com/api/user.whoami?api.token=api-f7dfpoyelk4mmz6vxcueb6hcbtbk" ; echo {"result":{"phid":"PHID-USER-cvfydnwadpdj7vdon36z","userName":"admin","realName":"asdf","image":"http:\/\/local.phacility.com\/res\/1410737307T\/phabricator\/3eb28cd9\/rsrc\/image\/avatar.png","uri":"http:\/\/local.phacility.com\/p\/admin\/","roles":["admin","verified","approved","activated"]},"error_code":null,"error_info":null} ``` ``` epriestley@orbital ~/dev/phabricator $ curl -g "http://local.phacility.com/api/differential.query?api.token=api-f7dfpoyelk4mmz6vxcueb6hcbtbk&ids[]=1" ; echo {"result":[{"id":"1","phid":"PHID-DREV-v3a67ixww3ccg5lqbxee","title":"zxcb","uri":"http:\/\/local.phacility.com\/D1","dateCreated":"1418405590","dateModified":"1418405590","authorPHID":"PHID-USER-cvfydnwadpdj7vdon36z","status":"0","statusName":"Needs Review","branch":null,"summary":"","testPlan":"zxcb","lineCount":"6","activeDiffPHID":"PHID-DIFF-pzbtc5rw6pe5j2kxtlr2","diffs":["1"],"commits":[],"reviewers":[],"ccs":[],"hashes":[],"auxiliary":{"phabricator:projects":[],"phabricator:depends-on":[],"organization.sqlmigration":null},"arcanistProjectPHID":null,"repositoryPHID":null,"sourcePath":null}],"error_code":null,"error_info":null} ``` - Ran older-style commands like `arc list` against the local install. - Ran commands via web console. - Added and ran a unit test to make sure nothing is using forbidden parameter names. - Terminated a token and verified it no longer works. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T3628, T5955 Differential Revision: https://secure.phabricator.com/D10986
2014-12-15 11:14:41 -08:00
if ($this->tokens !== null) {
$where[] = qsprintf(
$conn_r,
'token IN (%Ls)',
$this->tokens);
}
if ($this->tokenTypes !== null) {
$where[] = qsprintf(
$conn_r,
'tokenType IN (%Ls)',
$this->tokenTypes);
}
Add Conduit Tokens to make authentication in Conduit somewhat more sane Summary: Ref T5955. Summary of intended changes: **Improve Granularity of Authorization**: Currently, users have one Conduit Certificate. This isn't very flexible, and means that you can't ever generate an API token with limited permissions or IP block controls (see T6706). This moves toward a world where you can generate multiple tokens, revoke them individually, and assign disparate privileges to them. **Standardize Token Management**: This moves Conduit to work the same way that sessions, OAuth authorizations, and temporary tokens already work, instead of being this crazy bizarre mess. **Make Authentication Faster**: Authentication currently requires a handshake (conduit.connect) to establish a session, like the web UI. This is unnecessary from a security point of view and puts an extra round trip in front of all Conduit activity. Essentially no other API anywhere works like this. **Make Authentication Simpler**: The handshake is complex, and involves deriving hashes. The session is also complex, and creates issues like T4377. Handshake and session management require different inputs. **Make Token Management Simpler**: The certificate is this huge long thing right now, which is not necessary from a security perspective. There are separate Arcanist handshake tokens, but they have a different set of issues. We can move forward to a token management world where neither of these problems exist. **Lower Protocol Barrier**: The simplest possible API client is very complex right now. It should be `curl`. Simplifying authentication is a necessary step toward this. **Unblock T2783**: T2783 is blocked on nodes in the cluster making authenticated API calls to other nodes. This provides a simpler way forward than the handshake mess (or enormous-hack-mess) which would currently be required. Test Plan: - Generated tokens. - Generated tokens for a bot account. - Terminated tokens (and for a bot account). - Terminated all tokens (and for a bot account). - Ran GC and saw it reap all the expired tokens. NOTE: These tokens can not actually be used to authenticate yet! {F249658} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5955 Differential Revision: https://secure.phabricator.com/D10985
2014-12-15 11:14:23 -08:00
if ($this->expired !== null) {
if ($this->expired) {
$where[] = qsprintf(
$conn_r,
'expires <= %d',
PhabricatorTime::getNow());
} else {
$where[] = qsprintf(
$conn_r,
'expires IS NULL OR expires > %d',
PhabricatorTime::getNow());
}
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
}
protected function willFilterPage(array $tokens) {
$object_phids = mpull($tokens, 'getObjectPHID');
$objects = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($object_phids)
->execute();
$objects = mpull($objects, null, 'getPHID');
foreach ($tokens as $key => $token) {
$object = idx($objects, $token->getObjectPHID(), null);
if (!$object) {
$this->didRejectResult($token);
unset($tokens[$key]);
continue;
}
$token->attachObject($object);
}
return $tokens;
}
public function getQueryApplicationClass() {
return 'PhabricatorConduitApplication';
}
}