1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-21 21:10:56 +01:00

Introduce CAN_EDIT for ExternalAccount, and make CAN_VIEW more liberal

Summary:
Fixes T3732. Ref T1205. Ref T3116.

External accounts (like emails used as identities, Facebook accounts, LDAP accounts, etc.) are stored in "ExternalAccount" objects.

Currently, we have a very restrictive `CAN_VIEW` policy for ExternalAccounts, to add an extra layer of protection to make sure users can't use them in unintended ways. For example, it would be bad if a user could link their Phabricator account to a Facebook account without proper authentication. All of the controllers which do sensitive things have checks anyway, but a restrictive CAN_VIEW provided an extra layer of protection. Se T3116 for some discussion.

However, this means that when grey/external users take actions (via email, or via applications like Legalpad) other users can't load the account handles and can't see anything about the actor (they just see "Restricted External Account" or similar).

Balancing these concerns is mostly about not making a huge mess while doing it. This seems like a reasonable approach:

  - Add `CAN_EDIT` on these objects.
  - Make that very restricted, but open up `CAN_VIEW`.
  - Require `CAN_EDIT` any time we're going to do something authentication/identity related.

This is slightly easier to get wrong (forget CAN_EDIT) than other approaches, but pretty simple, and we always have extra checks in place anyway -- this is just a safety net.

I'm not quite sure how we should identify external accounts, so for now we're just rendering "Email User" or similar -- clearly not a bug, but not identifying. We can figure out what to render in the long term elsewhere.

Test Plan:
  - Viewed external accounts.
  - Linked an external account.
  - Refreshed an external account.
  - Edited profile picture.
  - Viewed sessions panel.
  - Published a bunch of stuff to Asana/JIRA.
  - Legalpad signature page now shows external accounts.

{F171595}

Reviewers: chad, btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T3732, T1205, T3116

Differential Revision: https://secure.phabricator.com/D9767
This commit is contained in:
epriestley 2014-07-10 10:18:10 -07:00
parent 02c3200867
commit e46826ad36
15 changed files with 281 additions and 174 deletions

View file

@ -8,7 +8,7 @@ return array(
'names' => 'names' =>
array( array(
'core.pkg.css' => 'c2c68e64', 'core.pkg.css' => 'c2c68e64',
'core.pkg.js' => 'f8ec7ddc', 'core.pkg.js' => '2b9e8efd',
'darkconsole.pkg.js' => 'df001cab', 'darkconsole.pkg.js' => 'df001cab',
'differential.pkg.css' => '4a93db37', 'differential.pkg.css' => '4a93db37',
'differential.pkg.js' => '7528cfc9', 'differential.pkg.js' => '7528cfc9',
@ -163,18 +163,18 @@ return array(
'rsrc/externals/font/fontawesome/fontawesome-webfont.woff' => 'a119ee5e', 'rsrc/externals/font/fontawesome/fontawesome-webfont.woff' => 'a119ee5e',
'rsrc/externals/font/sourcesans/SourceSansPro.woff' => '3614608c', 'rsrc/externals/font/sourcesans/SourceSansPro.woff' => '3614608c',
'rsrc/externals/font/sourcesans/SourceSansProBold.woff' => 'cbf46566', 'rsrc/externals/font/sourcesans/SourceSansProBold.woff' => 'cbf46566',
'rsrc/externals/javelin/core/Event.js' => '69815cac', 'rsrc/externals/javelin/core/Event.js' => '85ea0626',
'rsrc/externals/javelin/core/Stratcom.js' => 'c293f7b9', 'rsrc/externals/javelin/core/Stratcom.js' => '8b0ad945',
'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '717554e4', 'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '717554e4',
'rsrc/externals/javelin/core/__tests__/install.js' => 'c432ee85', 'rsrc/externals/javelin/core/__tests__/install.js' => 'c432ee85',
'rsrc/externals/javelin/core/__tests__/stratcom.js' => 'da194d4b', 'rsrc/externals/javelin/core/__tests__/stratcom.js' => 'da194d4b',
'rsrc/externals/javelin/core/__tests__/util.js' => 'd3b157a9', 'rsrc/externals/javelin/core/__tests__/util.js' => 'd3b157a9',
'rsrc/externals/javelin/core/init.js' => 'b88ab49e', 'rsrc/externals/javelin/core/init.js' => 'b88ab49e',
'rsrc/externals/javelin/core/init_node.js' => 'd7dde471', 'rsrc/externals/javelin/core/init_node.js' => 'd7dde471',
'rsrc/externals/javelin/core/install.js' => '52a92793', 'rsrc/externals/javelin/core/install.js' => '1ffb3a9c',
'rsrc/externals/javelin/core/util.js' => '65b0b249', 'rsrc/externals/javelin/core/util.js' => 'a23de73d',
'rsrc/externals/javelin/docs/Base.js' => '897bb199', 'rsrc/externals/javelin/docs/Base.js' => '74676256',
'rsrc/externals/javelin/docs/onload.js' => '81fb4862', 'rsrc/externals/javelin/docs/onload.js' => 'e819c479',
'rsrc/externals/javelin/ext/fx/Color.js' => '7e41274a', 'rsrc/externals/javelin/ext/fx/Color.js' => '7e41274a',
'rsrc/externals/javelin/ext/fx/FX.js' => '54b612ba', 'rsrc/externals/javelin/ext/fx/FX.js' => '54b612ba',
'rsrc/externals/javelin/ext/reactor/core/DynVal.js' => 'f6555212', 'rsrc/externals/javelin/ext/reactor/core/DynVal.js' => 'f6555212',
@ -193,31 +193,31 @@ return array(
'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => '7a94d6a5', 'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => '7a94d6a5',
'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '5426001c', 'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '5426001c',
'rsrc/externals/javelin/lib/Cookie.js' => '6b3dcf44', 'rsrc/externals/javelin/lib/Cookie.js' => '6b3dcf44',
'rsrc/externals/javelin/lib/DOM.js' => '07d99a3d', 'rsrc/externals/javelin/lib/DOM.js' => 'c4569c05',
'rsrc/externals/javelin/lib/History.js' => 'c60f4327', 'rsrc/externals/javelin/lib/History.js' => 'c60f4327',
'rsrc/externals/javelin/lib/JSON.js' => '08e56a4e', 'rsrc/externals/javelin/lib/JSON.js' => '69adf288',
'rsrc/externals/javelin/lib/Mask.js' => 'b9f26029', 'rsrc/externals/javelin/lib/Mask.js' => '8a41885b',
'rsrc/externals/javelin/lib/Request.js' => '7bad574b', 'rsrc/externals/javelin/lib/Request.js' => '97258e55',
'rsrc/externals/javelin/lib/Resource.js' => '0f81f8df', 'rsrc/externals/javelin/lib/Resource.js' => '0f81f8df',
'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692', 'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692',
'rsrc/externals/javelin/lib/Router.js' => '29274e2b', 'rsrc/externals/javelin/lib/Router.js' => '29274e2b',
'rsrc/externals/javelin/lib/URI.js' => 'd9a9b862', 'rsrc/externals/javelin/lib/URI.js' => '6eff08aa',
'rsrc/externals/javelin/lib/Vector.js' => 'bd0aedcd', 'rsrc/externals/javelin/lib/Vector.js' => '23cbb8ac',
'rsrc/externals/javelin/lib/Workflow.js' => '09b15cf1', 'rsrc/externals/javelin/lib/Workflow.js' => 'd149e002',
'rsrc/externals/javelin/lib/__tests__/Cookie.js' => '5ed109e8', 'rsrc/externals/javelin/lib/__tests__/Cookie.js' => '5ed109e8',
'rsrc/externals/javelin/lib/__tests__/DOM.js' => 'c984504b', 'rsrc/externals/javelin/lib/__tests__/DOM.js' => 'c984504b',
'rsrc/externals/javelin/lib/__tests__/JSON.js' => '2295d074', 'rsrc/externals/javelin/lib/__tests__/JSON.js' => '2295d074',
'rsrc/externals/javelin/lib/__tests__/URI.js' => '003ed329', 'rsrc/externals/javelin/lib/__tests__/URI.js' => '003ed329',
'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783', 'rsrc/externals/javelin/lib/__tests__/behavior.js' => '1ea62783',
'rsrc/externals/javelin/lib/behavior.js' => '8a3ed18b', 'rsrc/externals/javelin/lib/behavior.js' => '61cbc29a',
'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'e7c21fb3', 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => 'a5b67173',
'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => 'c54eeefb', 'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '61f72a3d',
'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => '5f850b5c', 'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'aa93c7b0',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '84f34ab1', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '503e17fd',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => 'a79b75a4', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '8b3fd187',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '66815d9c', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '54f314a0',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '62e18640', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '210aa43b',
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => 'cdde23f1', 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '316b8fa1',
'rsrc/externals/raphael/g.raphael.js' => '40dde778', 'rsrc/externals/raphael/g.raphael.js' => '40dde778',
'rsrc/externals/raphael/g.raphael.line.js' => '40da039e', 'rsrc/externals/raphael/g.raphael.line.js' => '40da039e',
'rsrc/externals/raphael/raphael.js' => '51ee6b43', 'rsrc/externals/raphael/raphael.js' => '51ee6b43',
@ -415,7 +415,7 @@ return array(
'rsrc/js/application/projects/behavior-project-create.js' => '065227cc', 'rsrc/js/application/projects/behavior-project-create.js' => '065227cc',
'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf', 'rsrc/js/application/releeph/releeph-preview-branch.js' => 'b2b4fbaf',
'rsrc/js/application/releeph/releeph-request-state-change.js' => 'ab836011', 'rsrc/js/application/releeph/releeph-request-state-change.js' => 'ab836011',
'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'cd9e7094', 'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'de2e896f',
'rsrc/js/application/repository/repository-crossreference.js' => 'f9539603', 'rsrc/js/application/repository/repository-crossreference.js' => 'f9539603',
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08', 'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => 'd6f54db0', 'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => 'd6f54db0',
@ -480,7 +480,7 @@ return array(
'rsrc/js/core/behavior-reveal-content.js' => '60821bc7', 'rsrc/js/core/behavior-reveal-content.js' => '60821bc7',
'rsrc/js/core/behavior-search-typeahead.js' => '5a376f34', 'rsrc/js/core/behavior-search-typeahead.js' => '5a376f34',
'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6', 'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6',
'rsrc/js/core/behavior-toggle-class.js' => 'a82a7769', 'rsrc/js/core/behavior-toggle-class.js' => 'e566f52c',
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884', 'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
'rsrc/js/core/behavior-tooltip.js' => '3ee3408b', 'rsrc/js/core/behavior-tooltip.js' => '3ee3408b',
'rsrc/js/core/behavior-watch-anchor.js' => '06e05112', 'rsrc/js/core/behavior-watch-anchor.js' => '06e05112',
@ -541,7 +541,7 @@ return array(
'herald-test-css' => '778b008e', 'herald-test-css' => '778b008e',
'inline-comment-summary-css' => '8cfd34e8', 'inline-comment-summary-css' => '8cfd34e8',
'javelin-aphlict' => '4a07e8e3', 'javelin-aphlict' => '4a07e8e3',
'javelin-behavior' => '8a3ed18b', 'javelin-behavior' => '61cbc29a',
'javelin-behavior-aphlict-dropdown' => 'f51afce0', 'javelin-behavior-aphlict-dropdown' => 'f51afce0',
'javelin-behavior-aphlict-listen' => 'a826c925', 'javelin-behavior-aphlict-listen' => 'a826c925',
'javelin-behavior-aphlict-status' => '58f7803f', 'javelin-behavior-aphlict-status' => '58f7803f',
@ -642,7 +642,7 @@ return array(
'javelin-behavior-refresh-csrf' => '7814b593', 'javelin-behavior-refresh-csrf' => '7814b593',
'javelin-behavior-releeph-preview-branch' => 'b2b4fbaf', 'javelin-behavior-releeph-preview-branch' => 'b2b4fbaf',
'javelin-behavior-releeph-request-state-change' => 'ab836011', 'javelin-behavior-releeph-request-state-change' => 'ab836011',
'javelin-behavior-releeph-request-typeahead' => 'cd9e7094', 'javelin-behavior-releeph-request-typeahead' => 'de2e896f',
'javelin-behavior-remarkup-preview' => 'f7379f45', 'javelin-behavior-remarkup-preview' => 'f7379f45',
'javelin-behavior-reorder-applications' => '76b9fc3e', 'javelin-behavior-reorder-applications' => '76b9fc3e',
'javelin-behavior-repository-crossreference' => 'f9539603', 'javelin-behavior-repository-crossreference' => 'f9539603',
@ -651,47 +651,47 @@ return array(
'javelin-behavior-slowvote-embed' => 'd6f54db0', 'javelin-behavior-slowvote-embed' => 'd6f54db0',
'javelin-behavior-stripe-payment-form' => '1693a296', 'javelin-behavior-stripe-payment-form' => '1693a296',
'javelin-behavior-test-payment-form' => 'ab8d2723', 'javelin-behavior-test-payment-form' => 'ab8d2723',
'javelin-behavior-toggle-class' => 'a82a7769', 'javelin-behavior-toggle-class' => 'e566f52c',
'javelin-behavior-view-placeholder' => '2fa810fc', 'javelin-behavior-view-placeholder' => '2fa810fc',
'javelin-behavior-workflow' => '0a3f3021', 'javelin-behavior-workflow' => '0a3f3021',
'javelin-color' => '7e41274a', 'javelin-color' => '7e41274a',
'javelin-cookie' => '6b3dcf44', 'javelin-cookie' => '6b3dcf44',
'javelin-diffusion-locate-file-source' => 'b42eddc7', 'javelin-diffusion-locate-file-source' => 'b42eddc7',
'javelin-dom' => '07d99a3d', 'javelin-dom' => 'c4569c05',
'javelin-dynval' => 'f6555212', 'javelin-dynval' => 'f6555212',
'javelin-event' => '69815cac', 'javelin-event' => '85ea0626',
'javelin-fx' => '54b612ba', 'javelin-fx' => '54b612ba',
'javelin-history' => 'c60f4327', 'javelin-history' => 'c60f4327',
'javelin-install' => '52a92793', 'javelin-install' => '1ffb3a9c',
'javelin-json' => '08e56a4e', 'javelin-json' => '69adf288',
'javelin-magical-init' => 'b88ab49e', 'javelin-magical-init' => 'b88ab49e',
'javelin-mask' => 'b9f26029', 'javelin-mask' => '8a41885b',
'javelin-reactor' => '77b1cf6f', 'javelin-reactor' => '77b1cf6f',
'javelin-reactor-dom' => 'b6d401d6', 'javelin-reactor-dom' => 'b6d401d6',
'javelin-reactor-node-calmer' => '76f4ebed', 'javelin-reactor-node-calmer' => '76f4ebed',
'javelin-reactornode' => 'b4c30592', 'javelin-reactornode' => 'b4c30592',
'javelin-request' => '7bad574b', 'javelin-request' => '97258e55',
'javelin-resource' => '0f81f8df', 'javelin-resource' => '0f81f8df',
'javelin-routable' => 'b3e7d692', 'javelin-routable' => 'b3e7d692',
'javelin-router' => '29274e2b', 'javelin-router' => '29274e2b',
'javelin-stratcom' => 'c293f7b9', 'javelin-stratcom' => '8b0ad945',
'javelin-tokenizer' => 'e7c21fb3', 'javelin-tokenizer' => 'a5b67173',
'javelin-typeahead' => 'c54eeefb', 'javelin-typeahead' => '61f72a3d',
'javelin-typeahead-composite-source' => '84f34ab1', 'javelin-typeahead-composite-source' => '503e17fd',
'javelin-typeahead-normalizer' => '5f850b5c', 'javelin-typeahead-normalizer' => 'aa93c7b0',
'javelin-typeahead-ondemand-source' => 'a79b75a4', 'javelin-typeahead-ondemand-source' => '8b3fd187',
'javelin-typeahead-preloaded-source' => '66815d9c', 'javelin-typeahead-preloaded-source' => '54f314a0',
'javelin-typeahead-source' => '62e18640', 'javelin-typeahead-source' => '210aa43b',
'javelin-typeahead-static-source' => 'cdde23f1', 'javelin-typeahead-static-source' => '316b8fa1',
'javelin-uri' => 'd9a9b862', 'javelin-uri' => '6eff08aa',
'javelin-util' => '65b0b249', 'javelin-util' => 'a23de73d',
'javelin-vector' => 'bd0aedcd', 'javelin-vector' => '23cbb8ac',
'javelin-view' => '0f764c35', 'javelin-view' => '0f764c35',
'javelin-view-html' => 'e5b406f9', 'javelin-view-html' => 'e5b406f9',
'javelin-view-interpreter' => '0c33c1a0', 'javelin-view-interpreter' => '0c33c1a0',
'javelin-view-renderer' => '6c2b09a2', 'javelin-view-renderer' => '6c2b09a2',
'javelin-view-visitor' => 'efe49472', 'javelin-view-visitor' => 'efe49472',
'javelin-workflow' => '09b15cf1', 'javelin-workflow' => 'd149e002',
'lightbox-attachment-css' => '7acac05d', 'lightbox-attachment-css' => '7acac05d',
'maniphest-batch-editor' => '8f380ebc', 'maniphest-batch-editor' => '8f380ebc',
'maniphest-report-css' => '6fc16517', 'maniphest-report-css' => '6fc16517',
@ -872,30 +872,6 @@ return array(
4 => 'javelin-util', 4 => 'javelin-util',
5 => 'phabricator-busy', 5 => 'phabricator-busy',
), ),
'07d99a3d' =>
array(
0 => 'javelin-magical-init',
1 => 'javelin-install',
2 => 'javelin-util',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
),
'08e56a4e' =>
array(
0 => 'javelin-install',
),
'09b15cf1' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-request',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-install',
5 => 'javelin-util',
6 => 'javelin-mask',
7 => 'javelin-uri',
8 => 'javelin-routable',
),
'0a3f3021' => '0a3f3021' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1015,6 +991,18 @@ return array(
1 => 'javelin-dom', 1 => 'javelin-dom',
2 => 'javelin-reactor-dom', 2 => 'javelin-reactor-dom',
), ),
'1ffb3a9c' =>
array(
0 => 'javelin-util',
1 => 'javelin-magical-init',
),
'210aa43b' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead-normalizer',
),
'2290aeef' => '2290aeef' =>
array( array(
0 => 'javelin-install', 0 => 'javelin-install',
@ -1029,6 +1017,11 @@ return array(
1 => 'javelin-dom', 1 => 'javelin-dom',
2 => 'javelin-vector', 2 => 'javelin-vector',
), ),
'23cbb8ac' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
),
'2926fff2' => '2926fff2' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1063,6 +1056,11 @@ return array(
2 => 'javelin-view-renderer', 2 => 'javelin-view-renderer',
3 => 'javelin-install', 3 => 'javelin-install',
), ),
'316b8fa1' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
),
'357b6e9b' => '357b6e9b' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1225,23 +1223,31 @@ return array(
1 => 'javelin-stratcom', 1 => 'javelin-stratcom',
2 => 'javelin-dom', 2 => 'javelin-dom',
), ),
'503e17fd' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
2 => 'javelin-util',
),
'519705ea' => '519705ea' =>
array( array(
0 => 'javelin-install', 0 => 'javelin-install',
1 => 'javelin-dom', 1 => 'javelin-dom',
2 => 'javelin-reactor-dom', 2 => 'javelin-reactor-dom',
), ),
'52a92793' =>
array(
0 => 'javelin-util',
1 => 'javelin-magical-init',
),
'54b612ba' => '54b612ba' =>
array( array(
0 => 'javelin-color', 0 => 'javelin-color',
1 => 'javelin-install', 1 => 'javelin-install',
2 => 'javelin-util', 2 => 'javelin-util',
), ),
'54f314a0' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-typeahead-source',
),
'558829c2' => '558829c2' =>
array( array(
0 => 'javelin-stratcom', 0 => 'javelin-stratcom',
@ -1288,10 +1294,6 @@ return array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
1 => 'javelin-stratcom', 1 => 'javelin-stratcom',
), ),
'5f850b5c' =>
array(
0 => 'javelin-install',
),
'5fefb143' => '5fefb143' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1312,12 +1314,17 @@ return array(
2 => 'javelin-dom', 2 => 'javelin-dom',
3 => 'javelin-workflow', 3 => 'javelin-workflow',
), ),
'62e18640' => '61cbc29a' =>
array(
0 => 'javelin-magical-init',
1 => 'javelin-util',
),
'61f72a3d' =>
array( array(
0 => 'javelin-install', 0 => 'javelin-install',
1 => 'javelin-util', 1 => 'javelin-dom',
2 => 'javelin-dom', 2 => 'javelin-vector',
3 => 'javelin-typeahead-normalizer', 3 => 'javelin-util',
), ),
'6453c869' => '6453c869' =>
array( array(
@ -1325,14 +1332,7 @@ return array(
1 => 'javelin-dom', 1 => 'javelin-dom',
2 => 'javelin-fx', 2 => 'javelin-fx',
), ),
'66815d9c' => '69adf288' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-typeahead-source',
),
'69815cac' =>
array( array(
0 => 'javelin-install', 0 => 'javelin-install',
), ),
@ -1360,6 +1360,12 @@ return array(
1 => 'javelin-dom', 1 => 'javelin-dom',
2 => 'javelin-util', 2 => 'javelin-util',
), ),
'6eff08aa' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
),
'710f209e' => '710f209e' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1433,17 +1439,6 @@ return array(
2 => 'javelin-stratcom', 2 => 'javelin-stratcom',
3 => 'javelin-util', 3 => 'javelin-util',
), ),
'7bad574b' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-behavior',
4 => 'javelin-json',
5 => 'javelin-dom',
6 => 'javelin-resource',
7 => 'javelin-routable',
),
'7c273581' => '7c273581' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1491,12 +1486,6 @@ return array(
3 => 'javelin-workflow', 3 => 'javelin-workflow',
4 => 'phabricator-draggable-list', 4 => 'phabricator-draggable-list',
), ),
'84f34ab1' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
2 => 'javelin-util',
),
'85ab3c8e' => '85ab3c8e' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1505,6 +1494,10 @@ return array(
3 => 'javelin-workflow', 3 => 'javelin-workflow',
4 => 'javelin-stratcom', 4 => 'javelin-stratcom',
), ),
'85ea0626' =>
array(
0 => 'javelin-install',
),
'880fa5ac' => '880fa5ac' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1524,10 +1517,24 @@ return array(
3 => 'javelin-view-interpreter', 3 => 'javelin-view-interpreter',
4 => 'javelin-view-renderer', 4 => 'javelin-view-renderer',
), ),
'8a3ed18b' => '8a41885b' =>
array( array(
0 => 'javelin-magical-init', 0 => 'javelin-install',
1 => 'javelin-dom',
),
'8b0ad945' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
2 => 'javelin-util',
3 => 'javelin-magical-init',
),
'8b3fd187' =>
array(
0 => 'javelin-install',
1 => 'javelin-util', 1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-typeahead-source',
), ),
'8d199d97' => '8d199d97' =>
array( array(
@ -1575,6 +1582,17 @@ return array(
3 => 'javelin-workflow', 3 => 'javelin-workflow',
4 => 'javelin-util', 4 => 'javelin-util',
), ),
'97258e55' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-behavior',
4 => 'javelin-json',
5 => 'javelin-dom',
6 => 'javelin-resource',
7 => 'javelin-routable',
),
'988040b4' => '988040b4' =>
array( array(
0 => 'javelin-install', 0 => 'javelin-install',
@ -1631,17 +1649,17 @@ return array(
3 => 'javelin-stratcom', 3 => 'javelin-stratcom',
4 => 'javelin-vector', 4 => 'javelin-vector',
), ),
'a5b67173' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
),
'a5d7cf86' => 'a5d7cf86' =>
array( array(
0 => 'javelin-dom', 0 => 'javelin-dom',
), ),
'a79b75a4' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-typeahead-source',
),
'a80d0378' => 'a80d0378' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1661,12 +1679,6 @@ return array(
8 => 'javelin-util', 8 => 'javelin-util',
9 => 'phabricator-notification', 9 => 'phabricator-notification',
), ),
'a82a7769' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'a8d8459d' => 'a8d8459d' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1697,6 +1709,10 @@ return array(
4 => 'javelin-util', 4 => 'javelin-util',
5 => 'phabricator-prefab', 5 => 'phabricator-prefab',
), ),
'aa93c7b0' =>
array(
0 => 'javelin-install',
),
'ab836011' => 'ab836011' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1782,22 +1798,12 @@ return array(
3 => 'javelin-dom', 3 => 'javelin-dom',
4 => 'phabricator-draggable-list', 4 => 'phabricator-draggable-list',
), ),
'b9f26029' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'bba9eedf' => 'bba9eedf' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
1 => 'javelin-stratcom', 1 => 'javelin-stratcom',
2 => 'javelin-dom', 2 => 'javelin-dom',
), ),
'bd0aedcd' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
),
'bd4c8dca' => 'bd4c8dca' =>
array( array(
0 => 'javelin-install', 0 => 'javelin-install',
@ -1828,19 +1834,13 @@ return array(
2 => 'javelin-util', 2 => 'javelin-util',
3 => 'phabricator-shaped-request', 3 => 'phabricator-shaped-request',
), ),
'c293f7b9' => 'c4569c05' =>
array( array(
0 => 'javelin-install', 0 => 'javelin-magical-init',
1 => 'javelin-event', 1 => 'javelin-install',
2 => 'javelin-util', 2 => 'javelin-util',
3 => 'javelin-magical-init', 3 => 'javelin-vector',
), 4 => 'javelin-stratcom',
'c54eeefb' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-util',
), ),
'c60f4327' => 'c60f4327' =>
array( array(
@ -1856,18 +1856,17 @@ return array(
2 => 'javelin-stratcom', 2 => 'javelin-stratcom',
3 => 'phabricator-phtize', 3 => 'phabricator-phtize',
), ),
'cd9e7094' => 'd149e002' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-stratcom',
1 => 'javelin-dom', 1 => 'javelin-request',
2 => 'javelin-typeahead', 2 => 'javelin-dom',
3 => 'javelin-typeahead-ondemand-source', 3 => 'javelin-vector',
4 => 'javelin-dom', 4 => 'javelin-install',
), 5 => 'javelin-util',
'cdde23f1' => 6 => 'javelin-mask',
array( 7 => 'javelin-uri',
0 => 'javelin-install', 8 => 'javelin-routable',
1 => 'javelin-typeahead-source',
), ),
'd19198c8' => 'd19198c8' =>
array( array(
@ -1926,12 +1925,6 @@ return array(
2 => 'javelin-util', 2 => 'javelin-util',
3 => 'phabricator-shaped-request', 3 => 'phabricator-shaped-request',
), ),
'd9a9b862' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
),
'dd7e8ef5' => 'dd7e8ef5' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1940,6 +1933,14 @@ return array(
3 => 'javelin-util', 3 => 'javelin-util',
4 => 'javelin-stratcom', 4 => 'javelin-stratcom',
), ),
'de2e896f' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-typeahead',
3 => 'javelin-typeahead-ondemand-source',
4 => 'javelin-dom',
),
'e10f8e18' => 'e10f8e18' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1970,6 +1971,12 @@ return array(
3 => 'javelin-dom', 3 => 'javelin-dom',
4 => 'javelin-uri', 4 => 'javelin-uri',
), ),
'e566f52c' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'e5822781' => 'e5822781' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',
@ -1985,13 +1992,6 @@ return array(
2 => 'javelin-view-visitor', 2 => 'javelin-view-visitor',
3 => 'javelin-util', 3 => 'javelin-util',
), ),
'e7c21fb3' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
),
'e9581f08' => 'e9581f08' =>
array( array(
0 => 'javelin-behavior', 0 => 'javelin-behavior',

View file

@ -143,12 +143,19 @@ abstract class PhabricatorAuthController extends PhabricatorController {
// be logged in yet, and because we want to tailor an error message to // be logged in yet, and because we want to tailor an error message to
// distinguish between "not usable" and "does not exist". We do explicit // distinguish between "not usable" and "does not exist". We do explicit
// checks later on to make sure this account is valid for the intended // checks later on to make sure this account is valid for the intended
// operation. // operation. This requires edit permission for completeness and consistency
// but it won't actually be meaningfully checked because we're using the
// ominpotent user.
$account = id(new PhabricatorExternalAccountQuery()) $account = id(new PhabricatorExternalAccountQuery())
->setViewer(PhabricatorUser::getOmnipotentUser()) ->setViewer(PhabricatorUser::getOmnipotentUser())
->withAccountSecrets(array($account_key)) ->withAccountSecrets(array($account_key))
->needImages(true) ->needImages(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne(); ->executeOne();
if (!$account) { if (!$account) {

View file

@ -36,7 +36,12 @@ final class PhabricatorAuthManagementRefreshWorkflow
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$query = id(new PhabricatorExternalAccountQuery()) $query = id(new PhabricatorExternalAccountQuery())
->setViewer($viewer); ->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
));
$username = $args->getArg('user'); $username = $args->getArg('user');
if (strlen($username)) { if (strlen($username)) {

View file

@ -1,5 +1,15 @@
<?php <?php
/**
* NOTE: When loading ExternalAccounts for use in an authetication context (that
* is, you're going to act as the account or link identities or anything like
* that) you should require CAN_EDIT capability even if you aren't actually
* editing the ExternalAccount.
*
* ExternalAccounts have a permissive CAN_VIEW policy (like users) because they
* interact directly with objects and can leave comments, sign documents, etc.
* However, CAN_EDIT is restricted to users who own the accounts.
*/
final class PhabricatorExternalAccountQuery final class PhabricatorExternalAccountQuery
extends PhabricatorCursorPagedPolicyAwareQuery { extends PhabricatorCursorPagedPolicyAwareQuery {

View file

@ -101,6 +101,11 @@ final class DifferentialLandingToGitHub
->withUserPHIDs(array($viewer->getPHID())) ->withUserPHIDs(array($viewer->getPHID()))
->withAccountTypes(array('github')) ->withAccountTypes(array('github'))
->withAccountDomains(array($repo_domain)) ->withAccountDomains(array($repo_domain))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne(); ->executeOne();
if (!$this->account) { if (!$this->account) {

View file

@ -37,6 +37,11 @@ final class DoorkeeperBridgeAsana extends DoorkeeperBridge {
->withUserPHIDs(array($viewer->getPHID())) ->withUserPHIDs(array($viewer->getPHID()))
->withAccountTypes(array($provider->getProviderType())) ->withAccountTypes(array($provider->getProviderType()))
->withAccountDomains(array($provider->getProviderDomain())) ->withAccountDomains(array($provider->getProviderDomain()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
if (!$accounts) { if (!$accounts) {

View file

@ -31,6 +31,11 @@ final class DoorkeeperBridgeJIRA extends DoorkeeperBridge {
->setViewer($viewer) ->setViewer($viewer)
->withUserPHIDs(array($viewer->getPHID())) ->withUserPHIDs(array($viewer->getPHID()))
->withAccountTypes(array($provider->getProviderType())) ->withAccountTypes(array($provider->getProviderType()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
if (!$accounts) { if (!$accounts) {

View file

@ -59,6 +59,11 @@ final class PhabricatorAsanaConfigOptions
->withUserPHIDs(array($viewer->getPHID())) ->withUserPHIDs(array($viewer->getPHID()))
->withAccountTypes(array($provider->getProviderType())) ->withAccountTypes(array($provider->getProviderType()))
->withAccountDomains(array($provider->getProviderDomain())) ->withAccountDomains(array($provider->getProviderDomain()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne(); ->executeOne();
if (!$account) { if (!$account) {
return null; return null;

View file

@ -524,6 +524,11 @@ final class DoorkeeperFeedWorkerAsana extends DoorkeeperFeedWorker {
->withUserPHIDs($all_phids) ->withUserPHIDs($all_phids)
->withAccountTypes(array($provider->getProviderType())) ->withAccountTypes(array($provider->getProviderType()))
->withAccountDomains(array($provider->getProviderDomain())) ->withAccountDomains(array($provider->getProviderDomain()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
foreach ($accounts as $account) { foreach ($accounts as $account) {
@ -549,6 +554,11 @@ final class DoorkeeperFeedWorkerAsana extends DoorkeeperFeedWorker {
->withUserPHIDs($user_phids) ->withUserPHIDs($user_phids)
->withAccountTypes(array($provider->getProviderType())) ->withAccountTypes(array($provider->getProviderType()))
->withAccountDomains(array($provider->getProviderDomain())) ->withAccountDomains(array($provider->getProviderDomain()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
// Reorder accounts in the original order. // Reorder accounts in the original order.

View file

@ -63,6 +63,11 @@ final class DoorkeeperFeedWorkerJIRA extends DoorkeeperFeedWorker {
->withUserPHIDs($try_users) ->withUserPHIDs($try_users)
->withAccountTypes(array($provider->getProviderType())) ->withAccountTypes(array($provider->getProviderType()))
->withAccountDomains(array($domain)) ->withAccountDomains(array($domain))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
// Reorder accounts in the original order. // Reorder accounts in the original order.
// TODO: This needs to be adjusted if/when we allow you to link multiple // TODO: This needs to be adjusted if/when we allow you to link multiple

View file

@ -107,6 +107,11 @@ abstract class PhabricatorMailReceiver {
->withAccountTypes(array('email')) ->withAccountTypes(array('email'))
->withAccountDomains(array($from_obj->getDomainName(), 'self')) ->withAccountDomains(array($from_obj->getDomainName(), 'self'))
->withAccountIDs(array($from_obj->getAddress())) ->withAccountIDs(array($from_obj->getAddress()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->loadOneOrCreate(); ->loadOneOrCreate();
return $xuser->getPhabricatorUser(); return $xuser->getPhabricatorUser();
} else { } else {

View file

@ -125,6 +125,11 @@ final class PhabricatorPeopleProfilePictureController
->setViewer($viewer) ->setViewer($viewer)
->withUserPHIDs(array($user->getPHID())) ->withUserPHIDs(array($user->getPHID()))
->needImages(true) ->needImages(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
foreach ($accounts as $account) { foreach ($accounts as $account) {

View file

@ -84,6 +84,25 @@ final class PhabricatorExternalAccount extends PhabricatorUserDAO
return true; return true;
} }
public function getDisplayName() {
if (strlen($this->displayName)) {
return $this->displayName;
}
// TODO: Figure out how much identifying information we're going to show
// to users about external accounts. For now, just show a string which is
// clearly not an error, but don't disclose any identifying information.
$map = array(
'email' => pht('Email User'),
);
$type = $this->getAccountType();
return idx($map, $type, pht('"%s" User', $type));
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */
@ -91,11 +110,17 @@ final class PhabricatorExternalAccount extends PhabricatorUserDAO
public function getCapabilities() { public function getCapabilities() {
return array( return array(
PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
); );
} }
public function getPolicy($capability) { public function getPolicy($capability) {
return PhabricatorPolicies::POLICY_NOONE; switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return PhabricatorPolicies::getMostOpenPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::POLICY_NOONE;
}
} }
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
@ -103,8 +128,13 @@ final class PhabricatorExternalAccount extends PhabricatorUserDAO
} }
public function describeAutomaticCapability($capability) { public function describeAutomaticCapability($capability) {
// TODO: (T603) This is complicated. switch ($capability) {
return null; case PhabricatorPolicyCapability::CAN_VIEW:
return null;
case PhabricatorPolicyCapability::CAN_EDIT:
return pht(
'External accounts can only be edited by the account owner.');
}
} }
} }

View file

@ -28,6 +28,11 @@ final class PhabricatorSettingsPanelExternalAccounts
->setViewer($viewer) ->setViewer($viewer)
->withUserPHIDs(array($viewer->getPHID())) ->withUserPHIDs(array($viewer->getPHID()))
->needImages(true) ->needImages(true)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
$linked_head = id(new PHUIHeaderView()) $linked_head = id(new PHUIHeaderView())

View file

@ -25,6 +25,11 @@ final class PhabricatorSettingsPanelSessions
$accounts = id(new PhabricatorExternalAccountQuery()) $accounts = id(new PhabricatorExternalAccountQuery())
->setViewer($viewer) ->setViewer($viewer)
->withUserPHIDs(array($viewer->getPHID())) ->withUserPHIDs(array($viewer->getPHID()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute(); ->execute();
$identity_phids = mpull($accounts, 'getPHID'); $identity_phids = mpull($accounts, 'getPHID');