mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-15 01:50:55 +01:00
(stable) Promote 2018 Week 4
This commit is contained in:
commit
4bf1bc2563
203 changed files with 6006 additions and 1673 deletions
1
bin/bulk
Symbolic link
1
bin/bulk
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../scripts/setup/manage_bulk.php
|
|
@ -9,16 +9,16 @@ return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'conpherence.pkg.css' => 'e68cf1fa',
|
'conpherence.pkg.css' => 'e68cf1fa',
|
||||||
'conpherence.pkg.js' => '15191c65',
|
'conpherence.pkg.js' => '15191c65',
|
||||||
'core.pkg.css' => 'fdb27ef9',
|
'core.pkg.css' => '075f9867',
|
||||||
'core.pkg.js' => '4c79d74f',
|
'core.pkg.js' => '4c79d74f',
|
||||||
'darkconsole.pkg.js' => '1f9a31bc',
|
'darkconsole.pkg.js' => '1f9a31bc',
|
||||||
'differential.pkg.css' => '45951e9e',
|
'differential.pkg.css' => '45951e9e',
|
||||||
'differential.pkg.js' => '500a75c5',
|
'differential.pkg.js' => '19ee9979',
|
||||||
'diffusion.pkg.css' => 'a2d17c7d',
|
'diffusion.pkg.css' => 'a2d17c7d',
|
||||||
'diffusion.pkg.js' => '6134c5a1',
|
'diffusion.pkg.js' => '6134c5a1',
|
||||||
'favicon.ico' => '30672e08',
|
'favicon.ico' => '30672e08',
|
||||||
'maniphest.pkg.css' => '4845691a',
|
'maniphest.pkg.css' => '4845691a',
|
||||||
'maniphest.pkg.js' => '5ab2753f',
|
'maniphest.pkg.js' => '4d7e79c8',
|
||||||
'rsrc/audio/basic/alert.mp3' => '98461568',
|
'rsrc/audio/basic/alert.mp3' => '98461568',
|
||||||
'rsrc/audio/basic/bing.mp3' => 'ab8603a5',
|
'rsrc/audio/basic/bing.mp3' => 'ab8603a5',
|
||||||
'rsrc/audio/basic/pock.mp3' => '0cc772f5',
|
'rsrc/audio/basic/pock.mp3' => '0cc772f5',
|
||||||
|
@ -81,7 +81,6 @@ return array(
|
||||||
'rsrc/css/application/harbormaster/harbormaster.css' => 'f491c9f4',
|
'rsrc/css/application/harbormaster/harbormaster.css' => 'f491c9f4',
|
||||||
'rsrc/css/application/herald/herald-test.css' => 'a52e323e',
|
'rsrc/css/application/herald/herald-test.css' => 'a52e323e',
|
||||||
'rsrc/css/application/herald/herald.css' => 'cd8d0134',
|
'rsrc/css/application/herald/herald.css' => 'cd8d0134',
|
||||||
'rsrc/css/application/maniphest/batch-editor.css' => 'b0f0b6d5',
|
|
||||||
'rsrc/css/application/maniphest/report.css' => '9b9580b7',
|
'rsrc/css/application/maniphest/report.css' => '9b9580b7',
|
||||||
'rsrc/css/application/maniphest/task-edit.css' => 'fda62a9b',
|
'rsrc/css/application/maniphest/task-edit.css' => 'fda62a9b',
|
||||||
'rsrc/css/application/maniphest/task-summary.css' => '11cc5344',
|
'rsrc/css/application/maniphest/task-summary.css' => '11cc5344',
|
||||||
|
@ -135,14 +134,15 @@ return array(
|
||||||
'rsrc/css/phui/object-item/phui-oi-color.css' => 'cd2b9b77',
|
'rsrc/css/phui/object-item/phui-oi-color.css' => 'cd2b9b77',
|
||||||
'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => '08f4ccc3',
|
'rsrc/css/phui/object-item/phui-oi-drag-ui.css' => '08f4ccc3',
|
||||||
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '9d9685d6',
|
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '9d9685d6',
|
||||||
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'bf094950',
|
'rsrc/css/phui/object-item/phui-oi-list-view.css' => '6ae18df0',
|
||||||
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea',
|
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => 'a8beebea',
|
||||||
'rsrc/css/phui/phui-action-list.css' => 'f7f61a34',
|
'rsrc/css/phui/phui-action-list.css' => 'f7f61a34',
|
||||||
'rsrc/css/phui/phui-action-panel.css' => 'b4798122',
|
'rsrc/css/phui/phui-action-panel.css' => 'b4798122',
|
||||||
'rsrc/css/phui/phui-badge.css' => '22c0cf4f',
|
'rsrc/css/phui/phui-badge.css' => '22c0cf4f',
|
||||||
'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3',
|
'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3',
|
||||||
'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c',
|
'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c',
|
||||||
'rsrc/css/phui/phui-box.css' => '9f3745fb',
|
'rsrc/css/phui/phui-box.css' => '4bd6cdb9',
|
||||||
|
'rsrc/css/phui/phui-bulk-editor.css' => '9a81e5d5',
|
||||||
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
|
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
|
||||||
'rsrc/css/phui/phui-cms.css' => '504b4b23',
|
'rsrc/css/phui/phui-cms.css' => '504b4b23',
|
||||||
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
|
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
|
||||||
|
@ -416,11 +416,10 @@ return array(
|
||||||
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
|
'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef',
|
||||||
'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab',
|
'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab',
|
||||||
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
|
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
|
||||||
'rsrc/js/application/herald/HeraldRuleEditor.js' => '2dff5579',
|
'rsrc/js/application/herald/HeraldRuleEditor.js' => 'dca75c0e',
|
||||||
'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec',
|
'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec',
|
||||||
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
|
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
|
||||||
'rsrc/js/application/maniphest/behavior-batch-editor.js' => '782ab6e7',
|
'rsrc/js/application/maniphest/behavior-batch-selector.js' => 'ad54037e',
|
||||||
'rsrc/js/application/maniphest/behavior-batch-selector.js' => '0825c27a',
|
|
||||||
'rsrc/js/application/maniphest/behavior-line-chart.js' => 'e4232876',
|
'rsrc/js/application/maniphest/behavior-line-chart.js' => 'e4232876',
|
||||||
'rsrc/js/application/maniphest/behavior-list-edit.js' => 'a9f88de2',
|
'rsrc/js/application/maniphest/behavior-list-edit.js' => 'a9f88de2',
|
||||||
'rsrc/js/application/maniphest/behavior-subpriorityeditor.js' => '71237763',
|
'rsrc/js/application/maniphest/behavior-subpriorityeditor.js' => '71237763',
|
||||||
|
@ -444,7 +443,7 @@ return array(
|
||||||
'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' => 'a0b57eb8',
|
'rsrc/js/application/releeph/releeph-request-state-change.js' => 'a0b57eb8',
|
||||||
'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'de2e896f',
|
'rsrc/js/application/releeph/releeph-request-typeahead.js' => 'de2e896f',
|
||||||
'rsrc/js/application/repository/repository-crossreference.js' => '7fe9bc12',
|
'rsrc/js/application/repository/repository-crossreference.js' => '2ab10a76',
|
||||||
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
|
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
|
||||||
'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' => '887ad43f',
|
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
|
||||||
|
@ -477,6 +476,7 @@ return array(
|
||||||
'rsrc/js/core/behavior-audio-source.js' => '59b251eb',
|
'rsrc/js/core/behavior-audio-source.js' => '59b251eb',
|
||||||
'rsrc/js/core/behavior-autofocus.js' => '7319e029',
|
'rsrc/js/core/behavior-autofocus.js' => '7319e029',
|
||||||
'rsrc/js/core/behavior-badge-view.js' => '8ff5e24c',
|
'rsrc/js/core/behavior-badge-view.js' => '8ff5e24c',
|
||||||
|
'rsrc/js/core/behavior-bulk-editor.js' => '66a6def1',
|
||||||
'rsrc/js/core/behavior-choose-control.js' => '327a00d1',
|
'rsrc/js/core/behavior-choose-control.js' => '327a00d1',
|
||||||
'rsrc/js/core/behavior-copy.js' => 'b0b8f86d',
|
'rsrc/js/core/behavior-copy.js' => 'b0b8f86d',
|
||||||
'rsrc/js/core/behavior-detect-timezone.js' => '4c193c96',
|
'rsrc/js/core/behavior-detect-timezone.js' => '4c193c96',
|
||||||
|
@ -523,6 +523,7 @@ return array(
|
||||||
'rsrc/js/core/phtize.js' => 'd254d646',
|
'rsrc/js/core/phtize.js' => 'd254d646',
|
||||||
'rsrc/js/phui/behavior-phui-dropdown-menu.js' => 'b95d6f7d',
|
'rsrc/js/phui/behavior-phui-dropdown-menu.js' => 'b95d6f7d',
|
||||||
'rsrc/js/phui/behavior-phui-file-upload.js' => 'b003d4fb',
|
'rsrc/js/phui/behavior-phui-file-upload.js' => 'b003d4fb',
|
||||||
|
'rsrc/js/phui/behavior-phui-selectable-list.js' => '464259a2',
|
||||||
'rsrc/js/phui/behavior-phui-submenu.js' => 'a6f7a73b',
|
'rsrc/js/phui/behavior-phui-submenu.js' => 'a6f7a73b',
|
||||||
'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9',
|
'rsrc/js/phui/behavior-phui-tab-group.js' => '0a0b10e9',
|
||||||
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
|
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
|
||||||
|
@ -531,7 +532,7 @@ return array(
|
||||||
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
|
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
|
||||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
|
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
|
||||||
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
|
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
|
||||||
'rsrc/js/phuix/PHUIXFormControl.js' => '83e03671',
|
'rsrc/js/phuix/PHUIXFormControl.js' => '1dd0870c',
|
||||||
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
|
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
|
||||||
),
|
),
|
||||||
'symbols' => array(
|
'symbols' => array(
|
||||||
|
@ -579,7 +580,7 @@ return array(
|
||||||
'global-drag-and-drop-css' => 'b556a948',
|
'global-drag-and-drop-css' => 'b556a948',
|
||||||
'harbormaster-css' => 'f491c9f4',
|
'harbormaster-css' => 'f491c9f4',
|
||||||
'herald-css' => 'cd8d0134',
|
'herald-css' => 'cd8d0134',
|
||||||
'herald-rule-editor' => '2dff5579',
|
'herald-rule-editor' => 'dca75c0e',
|
||||||
'herald-test-css' => 'a52e323e',
|
'herald-test-css' => 'a52e323e',
|
||||||
'inline-comment-summary-css' => 'f23d4e8f',
|
'inline-comment-summary-css' => 'f23d4e8f',
|
||||||
'javelin-aphlict' => 'e1d4b11a',
|
'javelin-aphlict' => 'e1d4b11a',
|
||||||
|
@ -594,6 +595,7 @@ return array(
|
||||||
'javelin-behavior-audio-source' => '59b251eb',
|
'javelin-behavior-audio-source' => '59b251eb',
|
||||||
'javelin-behavior-audit-preview' => 'd835b03a',
|
'javelin-behavior-audit-preview' => 'd835b03a',
|
||||||
'javelin-behavior-badge-view' => '8ff5e24c',
|
'javelin-behavior-badge-view' => '8ff5e24c',
|
||||||
|
'javelin-behavior-bulk-editor' => '66a6def1',
|
||||||
'javelin-behavior-bulk-job-reload' => 'edf8a145',
|
'javelin-behavior-bulk-job-reload' => 'edf8a145',
|
||||||
'javelin-behavior-calendar-month-view' => 'fe33e256',
|
'javelin-behavior-calendar-month-view' => 'fe33e256',
|
||||||
'javelin-behavior-choose-control' => '327a00d1',
|
'javelin-behavior-choose-control' => '327a00d1',
|
||||||
|
@ -641,8 +643,7 @@ return array(
|
||||||
'javelin-behavior-lightbox-attachments' => '560f41da',
|
'javelin-behavior-lightbox-attachments' => '560f41da',
|
||||||
'javelin-behavior-line-chart' => 'e4232876',
|
'javelin-behavior-line-chart' => 'e4232876',
|
||||||
'javelin-behavior-load-blame' => '42126667',
|
'javelin-behavior-load-blame' => '42126667',
|
||||||
'javelin-behavior-maniphest-batch-editor' => '782ab6e7',
|
'javelin-behavior-maniphest-batch-selector' => 'ad54037e',
|
||||||
'javelin-behavior-maniphest-batch-selector' => '0825c27a',
|
|
||||||
'javelin-behavior-maniphest-list-editor' => 'a9f88de2',
|
'javelin-behavior-maniphest-list-editor' => 'a9f88de2',
|
||||||
'javelin-behavior-maniphest-subpriority-editor' => '71237763',
|
'javelin-behavior-maniphest-subpriority-editor' => '71237763',
|
||||||
'javelin-behavior-owners-path-editor' => '7a68dda3',
|
'javelin-behavior-owners-path-editor' => '7a68dda3',
|
||||||
|
@ -673,6 +674,7 @@ return array(
|
||||||
'javelin-behavior-phui-dropdown-menu' => 'b95d6f7d',
|
'javelin-behavior-phui-dropdown-menu' => 'b95d6f7d',
|
||||||
'javelin-behavior-phui-file-upload' => 'b003d4fb',
|
'javelin-behavior-phui-file-upload' => 'b003d4fb',
|
||||||
'javelin-behavior-phui-hovercards' => 'bcaccd64',
|
'javelin-behavior-phui-hovercards' => 'bcaccd64',
|
||||||
|
'javelin-behavior-phui-selectable-list' => '464259a2',
|
||||||
'javelin-behavior-phui-submenu' => 'a6f7a73b',
|
'javelin-behavior-phui-submenu' => 'a6f7a73b',
|
||||||
'javelin-behavior-phui-tab-group' => '0a0b10e9',
|
'javelin-behavior-phui-tab-group' => '0a0b10e9',
|
||||||
'javelin-behavior-phuix-example' => '68af71ca',
|
'javelin-behavior-phuix-example' => '68af71ca',
|
||||||
|
@ -690,7 +692,7 @@ return array(
|
||||||
'javelin-behavior-reorder-applications' => '76b9fc3e',
|
'javelin-behavior-reorder-applications' => '76b9fc3e',
|
||||||
'javelin-behavior-reorder-columns' => 'e1d25dfb',
|
'javelin-behavior-reorder-columns' => 'e1d25dfb',
|
||||||
'javelin-behavior-reorder-profile-menu-items' => 'e2e0a072',
|
'javelin-behavior-reorder-profile-menu-items' => 'e2e0a072',
|
||||||
'javelin-behavior-repository-crossreference' => '7fe9bc12',
|
'javelin-behavior-repository-crossreference' => '2ab10a76',
|
||||||
'javelin-behavior-scrollbar' => '834a1173',
|
'javelin-behavior-scrollbar' => '834a1173',
|
||||||
'javelin-behavior-search-reorder-queries' => 'e9581f08',
|
'javelin-behavior-search-reorder-queries' => 'e9581f08',
|
||||||
'javelin-behavior-select-content' => 'bf5374ef',
|
'javelin-behavior-select-content' => 'bf5374ef',
|
||||||
|
@ -754,7 +756,6 @@ return array(
|
||||||
'javelin-workboard-column' => '758b4758',
|
'javelin-workboard-column' => '758b4758',
|
||||||
'javelin-workboard-controller' => '26167537',
|
'javelin-workboard-controller' => '26167537',
|
||||||
'javelin-workflow' => '1e911d0f',
|
'javelin-workflow' => '1e911d0f',
|
||||||
'maniphest-batch-editor' => 'b0f0b6d5',
|
|
||||||
'maniphest-report-css' => '9b9580b7',
|
'maniphest-report-css' => '9b9580b7',
|
||||||
'maniphest-task-edit-css' => 'fda62a9b',
|
'maniphest-task-edit-css' => 'fda62a9b',
|
||||||
'maniphest-task-summary-css' => '11cc5344',
|
'maniphest-task-summary-css' => '11cc5344',
|
||||||
|
@ -820,7 +821,8 @@ return array(
|
||||||
'phui-badge-view-css' => '22c0cf4f',
|
'phui-badge-view-css' => '22c0cf4f',
|
||||||
'phui-basic-nav-view-css' => '98c11ab3',
|
'phui-basic-nav-view-css' => '98c11ab3',
|
||||||
'phui-big-info-view-css' => 'acc3492c',
|
'phui-big-info-view-css' => 'acc3492c',
|
||||||
'phui-box-css' => '9f3745fb',
|
'phui-box-css' => '4bd6cdb9',
|
||||||
|
'phui-bulk-editor-css' => '9a81e5d5',
|
||||||
'phui-button-bar-css' => 'f1ff5494',
|
'phui-button-bar-css' => 'f1ff5494',
|
||||||
'phui-button-css' => '1863cc6e',
|
'phui-button-css' => '1863cc6e',
|
||||||
'phui-button-simple-css' => '8e1baf68',
|
'phui-button-simple-css' => '8e1baf68',
|
||||||
|
@ -860,7 +862,7 @@ return array(
|
||||||
'phui-oi-color-css' => 'cd2b9b77',
|
'phui-oi-color-css' => 'cd2b9b77',
|
||||||
'phui-oi-drag-ui-css' => '08f4ccc3',
|
'phui-oi-drag-ui-css' => '08f4ccc3',
|
||||||
'phui-oi-flush-ui-css' => '9d9685d6',
|
'phui-oi-flush-ui-css' => '9d9685d6',
|
||||||
'phui-oi-list-view-css' => 'bf094950',
|
'phui-oi-list-view-css' => '6ae18df0',
|
||||||
'phui-oi-simple-ui-css' => 'a8beebea',
|
'phui-oi-simple-ui-css' => 'a8beebea',
|
||||||
'phui-pager-css' => 'edcbc226',
|
'phui-pager-css' => 'edcbc226',
|
||||||
'phui-pinboard-view-css' => '2495140e',
|
'phui-pinboard-view-css' => '2495140e',
|
||||||
|
@ -882,7 +884,7 @@ return array(
|
||||||
'phuix-autocomplete' => 'e0731603',
|
'phuix-autocomplete' => 'e0731603',
|
||||||
'phuix-button-view' => '8a91e1ac',
|
'phuix-button-view' => '8a91e1ac',
|
||||||
'phuix-dropdown-menu' => '04b2ae03',
|
'phuix-dropdown-menu' => '04b2ae03',
|
||||||
'phuix-form-control-view' => '83e03671',
|
'phuix-form-control-view' => '1dd0870c',
|
||||||
'phuix-icon-view' => 'bff6884b',
|
'phuix-icon-view' => 'bff6884b',
|
||||||
'policy-css' => '957ea14c',
|
'policy-css' => '957ea14c',
|
||||||
'policy-edit-css' => '815c66f7',
|
'policy-edit-css' => '815c66f7',
|
||||||
|
@ -958,12 +960,6 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-workflow',
|
'javelin-workflow',
|
||||||
),
|
),
|
||||||
'0825c27a' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-util',
|
|
||||||
),
|
|
||||||
'08f4ccc3' => array(
|
'08f4ccc3' => array(
|
||||||
'phui-oi-list-view-css',
|
'phui-oi-list-view-css',
|
||||||
),
|
),
|
||||||
|
@ -1033,6 +1029,10 @@ return array(
|
||||||
'javelin-request',
|
'javelin-request',
|
||||||
'javelin-uri',
|
'javelin-uri',
|
||||||
),
|
),
|
||||||
|
'1dd0870c' => array(
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-dom',
|
||||||
|
),
|
||||||
'1e911d0f' => array(
|
'1e911d0f' => array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-request',
|
'javelin-request',
|
||||||
|
@ -1088,6 +1088,12 @@ return array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
),
|
),
|
||||||
|
'2ab10a76' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-uri',
|
||||||
|
),
|
||||||
'2ae077e1' => array(
|
'2ae077e1' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1106,15 +1112,6 @@ return array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-event',
|
'javelin-event',
|
||||||
),
|
),
|
||||||
'2dff5579' => array(
|
|
||||||
'multirow-row-manager',
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-json',
|
|
||||||
'phabricator-prefab',
|
|
||||||
),
|
|
||||||
'2ee659ce' => array(
|
'2ee659ce' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
),
|
),
|
||||||
|
@ -1226,6 +1223,11 @@ return array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
|
'464259a2' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-dom',
|
||||||
|
),
|
||||||
'469c0d9e' => array(
|
'469c0d9e' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1422,6 +1424,14 @@ return array(
|
||||||
'javelin-workflow',
|
'javelin-workflow',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
|
'66a6def1' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-util',
|
||||||
|
'multirow-row-manager',
|
||||||
|
'javelin-json',
|
||||||
|
'phuix-form-control-view',
|
||||||
|
),
|
||||||
'680ea2c8' => array(
|
'680ea2c8' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1523,14 +1533,6 @@ return array(
|
||||||
'javelin-request',
|
'javelin-request',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
),
|
),
|
||||||
'782ab6e7' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-util',
|
|
||||||
'phabricator-prefab',
|
|
||||||
'multirow-row-manager',
|
|
||||||
'javelin-json',
|
|
||||||
),
|
|
||||||
'7927a7d3' => array(
|
'7927a7d3' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-quicksand',
|
'javelin-quicksand',
|
||||||
|
@ -1559,20 +1561,10 @@ return array(
|
||||||
'7f243deb' => array(
|
'7f243deb' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
),
|
),
|
||||||
'7fe9bc12' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-uri',
|
|
||||||
),
|
|
||||||
'834a1173' => array(
|
'834a1173' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-scrollbar',
|
'javelin-scrollbar',
|
||||||
),
|
),
|
||||||
'83e03671' => array(
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-dom',
|
|
||||||
),
|
|
||||||
'8499b6ab' => array(
|
'8499b6ab' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1808,6 +1800,12 @@ return array(
|
||||||
'phuix-autocomplete',
|
'phuix-autocomplete',
|
||||||
'javelin-mask',
|
'javelin-mask',
|
||||||
),
|
),
|
||||||
|
'ad54037e' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-util',
|
||||||
|
),
|
||||||
'b003d4fb' => array(
|
'b003d4fb' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
|
@ -2023,6 +2021,15 @@ return array(
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
'phabricator-shaped-request',
|
'phabricator-shaped-request',
|
||||||
),
|
),
|
||||||
|
'dca75c0e' => array(
|
||||||
|
'multirow-row-manager',
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-json',
|
||||||
|
'phabricator-prefab',
|
||||||
|
),
|
||||||
'de2e896f' => array(
|
'de2e896f' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
|
|
@ -1,27 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$table = new PhabricatorRepositoryVCSPassword();
|
// This migration once upgraded VCS password hashing, but the table was
|
||||||
$conn_w = $table->establishConnection('w');
|
// later removed in 2018 (see T13043).
|
||||||
|
|
||||||
echo pht('Upgrading password hashing for VCS passwords.')."\n";
|
// Since almost four years have passed since this migration, the cost of
|
||||||
|
// losing this data is very small (users just need to reset their passwords),
|
||||||
|
// and a version of this migration against the modern schema isn't easy to
|
||||||
|
// implement or test, just skip the migration.
|
||||||
|
|
||||||
$best_hasher = PhabricatorPasswordHasher::getBestHasher();
|
// This means that installs which upgrade from a version of Phabricator
|
||||||
foreach (new LiskMigrationIterator($table) as $password) {
|
// released prior to Feb 2014 to a version of Phabricator relased after
|
||||||
$id = $password->getID();
|
// Jan 2018 will need to have users reset VCS passwords.
|
||||||
|
|
||||||
echo pht('Migrating VCS password %d...', $id)."\n";
|
|
||||||
|
|
||||||
$input_hash = $password->getPasswordHash();
|
|
||||||
$input_envelope = new PhutilOpaqueEnvelope($input_hash);
|
|
||||||
|
|
||||||
$storage_hash = $best_hasher->getPasswordHashForStorage($input_envelope);
|
|
||||||
|
|
||||||
queryfx(
|
|
||||||
$conn_w,
|
|
||||||
'UPDATE %T SET passwordHash = %s WHERE id = %d',
|
|
||||||
$table->getTableName(),
|
|
||||||
$storage_hash->openEnvelope(),
|
|
||||||
$id);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo pht('Done.')."\n";
|
|
||||||
|
|
2
resources/sql/autopatches/20180119.bulk.01.silent.sql
Normal file
2
resources/sql/autopatches/20180119.bulk.01.silent.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_worker.worker_bulkjob
|
||||||
|
ADD isSilent BOOL NOT NULL;
|
10
resources/sql/autopatches/20180120.auth.01.password.sql
Normal file
10
resources/sql/autopatches/20180120.auth.01.password.sql
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_auth.auth_password (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARBINARY(64) NOT NULL,
|
||||||
|
objectPHID VARBINARY(64) NOT NULL,
|
||||||
|
passwordType VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
passwordHash VARCHAR(128) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
isRevoked BOOL NOT NULL,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,19 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_auth.auth_passwordtransaction (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARBINARY(64) NOT NULL,
|
||||||
|
authorPHID VARBINARY(64) NOT NULL,
|
||||||
|
objectPHID VARBINARY(64) NOT NULL,
|
||||||
|
viewPolicy VARBINARY(64) NOT NULL,
|
||||||
|
editPolicy VARBINARY(64) NOT NULL,
|
||||||
|
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||||
|
commentVersion INT UNSIGNED NOT NULL,
|
||||||
|
transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (`phid`),
|
||||||
|
KEY `key_object` (`objectPHID`)
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
6
resources/sql/autopatches/20180120.auth.03.vcsdata.sql
Normal file
6
resources/sql/autopatches/20180120.auth.03.vcsdata.sql
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
INSERT INTO {$NAMESPACE}_auth.auth_password
|
||||||
|
(objectPHID, phid, passwordType, passwordHash, isRevoked,
|
||||||
|
dateCreated, dateModified)
|
||||||
|
SELECT userPHID, CONCAT('XVCS', id), 'vcs', passwordHash, 0,
|
||||||
|
dateCreated, dateModified
|
||||||
|
FROM {$NAMESPACE}_repository.repository_vcspassword;
|
24
resources/sql/autopatches/20180120.auth.04.vcsphid.php
Normal file
24
resources/sql/autopatches/20180120.auth.04.vcsphid.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Populate VCS passwords (which we copied from the old "VCS Password" table
|
||||||
|
// in the last migration) with new PHIDs.
|
||||||
|
|
||||||
|
$table = new PhabricatorAuthPassword();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
$password_type = PhabricatorAuthPasswordPHIDType::TYPECONST;
|
||||||
|
|
||||||
|
foreach (new LiskMigrationIterator($table) as $row) {
|
||||||
|
if (phid_get_type($row->getPHID()) == $password_type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_phid = $row->generatePHID();
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'UPDATE %T SET phid = %s WHERE id = %d',
|
||||||
|
$table->getTableName(),
|
||||||
|
$new_phid,
|
||||||
|
$row->getID());
|
||||||
|
}
|
1
resources/sql/autopatches/20180121.auth.01.vcsnuke.sql
Normal file
1
resources/sql/autopatches/20180121.auth.01.vcsnuke.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
DROP TABLE {$NAMESPACE}_repository.repository_vcspassword;
|
2
resources/sql/autopatches/20180121.auth.02.passsalt.sql
Normal file
2
resources/sql/autopatches/20180121.auth.02.passsalt.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_auth.auth_password
|
||||||
|
ADD passwordSalt VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,7 @@
|
||||||
|
INSERT INTO {$NAMESPACE}_auth.auth_password
|
||||||
|
(objectPHID, phid, passwordType, passwordHash, passwordSalt, isRevoked,
|
||||||
|
dateCreated, dateModified)
|
||||||
|
SELECT phid, CONCAT('XACCOUNT', id), 'account', passwordHash, passwordSalt, 0,
|
||||||
|
dateCreated, dateModified
|
||||||
|
FROM {$NAMESPACE}_user.user
|
||||||
|
WHERE passwordHash != '';
|
24
resources/sql/autopatches/20180121.auth.04.accountphid.php
Normal file
24
resources/sql/autopatches/20180121.auth.04.accountphid.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Populate account passwords (which we copied from the user table in the last
|
||||||
|
// migration) with new PHIDs.
|
||||||
|
|
||||||
|
$table = new PhabricatorAuthPassword();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
$password_type = PhabricatorAuthPasswordPHIDType::TYPECONST;
|
||||||
|
|
||||||
|
foreach (new LiskMigrationIterator($table) as $row) {
|
||||||
|
if (phid_get_type($row->getPHID()) == $password_type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_phid = $row->generatePHID();
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'UPDATE %T SET phid = %s WHERE id = %d',
|
||||||
|
$table->getTableName(),
|
||||||
|
$new_phid,
|
||||||
|
$row->getID());
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_user.user
|
||||||
|
DROP passwordSalt;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_user.user
|
||||||
|
DROP passwordHash;
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_auth.auth_password
|
||||||
|
ADD legacyDigestFormat VARCHAR(32) COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,4 @@
|
||||||
|
UPDATE {$NAMESPACE}_auth.auth_password
|
||||||
|
SET legacyDigestFormat = 'v1'
|
||||||
|
WHERE passwordType IN ('vcs', 'account')
|
||||||
|
AND legacyDigestFormat IS NULL;
|
26
resources/sql/autopatches/20180124.herald.01.repetition.sql
Normal file
26
resources/sql/autopatches/20180124.herald.01.repetition.sql
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* This column was previously "uint32?" with these values:
|
||||||
|
|
||||||
|
1: run every time
|
||||||
|
0: run only the first time
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
UPDATE {$NAMESPACE}_herald.herald_rule
|
||||||
|
SET repetitionPolicy = '1'
|
||||||
|
WHERE repetitionPolicy IS NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_herald.herald_rule
|
||||||
|
CHANGE repetitionPolicy
|
||||||
|
repetitionPolicy VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};
|
||||||
|
|
||||||
|
/* If the old value was "0", the new value is "first". */
|
||||||
|
|
||||||
|
UPDATE {$NAMESPACE}_herald.herald_rule
|
||||||
|
SET repetitionPolicy = 'first'
|
||||||
|
WHERE repetitionPolicy = '0';
|
||||||
|
|
||||||
|
/* If the old value was anything else, the new value is "every". */
|
||||||
|
|
||||||
|
UPDATE {$NAMESPACE}_herald.herald_rule
|
||||||
|
SET repetitionPolicy = 'every'
|
||||||
|
WHERE repetitionPolicy NOT IN ('first', '0');
|
|
@ -1,39 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
echo pht('Cleaning up old Herald rule applied rows...')."\n";
|
// Once, this migration deleted some unnecessary rows written by Herald before
|
||||||
$table = new HeraldRule();
|
// January 2012. These rows don't hurt anything, they just cluttered up the
|
||||||
$table->openTransaction();
|
// database a bit.
|
||||||
$table->beginReadLocking();
|
|
||||||
|
|
||||||
$rules = $table->loadAll();
|
// The migration was removed in January 2018 to make maintenance on rule
|
||||||
foreach ($rules as $key => $rule) {
|
// repetition policies easier.
|
||||||
$first_policy = HeraldRepetitionPolicyConfig::toInt(
|
|
||||||
HeraldRepetitionPolicyConfig::FIRST);
|
|
||||||
if ($rule->getRepetitionPolicy() != $first_policy) {
|
|
||||||
unset($rules[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$conn_w = $table->establishConnection('w');
|
|
||||||
|
|
||||||
$clause = '';
|
|
||||||
if ($rules) {
|
|
||||||
$clause = qsprintf(
|
|
||||||
$conn_w,
|
|
||||||
'WHERE ruleID NOT IN (%Ld)',
|
|
||||||
mpull($rules, 'getID'));
|
|
||||||
}
|
|
||||||
|
|
||||||
echo pht('This may take a moment')."\n";
|
|
||||||
do {
|
|
||||||
queryfx(
|
|
||||||
$conn_w,
|
|
||||||
'DELETE FROM %T %Q LIMIT 1000',
|
|
||||||
HeraldRule::TABLE_RULE_APPLIED,
|
|
||||||
$clause);
|
|
||||||
echo '.';
|
|
||||||
} while ($conn_w->getAffectedRows());
|
|
||||||
|
|
||||||
$table->endReadLocking();
|
|
||||||
$table->saveTransaction();
|
|
||||||
echo "\n".pht('Done.')."\n";
|
|
||||||
|
|
1
scripts/manage_bulk.php
Symbolic link
1
scripts/manage_bulk.php
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../scripts/setup/manage_bulk.php
|
21
scripts/setup/manage_bulk.php
Executable file
21
scripts/setup/manage_bulk.php
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$root = dirname(dirname(dirname(__FILE__)));
|
||||||
|
require_once $root.'/scripts/__init_script__.php';
|
||||||
|
|
||||||
|
$args = new PhutilArgumentParser($argv);
|
||||||
|
$args->setTagline(pht('manage bulk jobs'));
|
||||||
|
$args->setSynopsis(<<<EOSYNOPSIS
|
||||||
|
**bulk** __command__ [__options__]
|
||||||
|
Manage and debug bulk jobs.
|
||||||
|
|
||||||
|
EOSYNOPSIS
|
||||||
|
);
|
||||||
|
$args->parseStandardArguments();
|
||||||
|
|
||||||
|
$workflows = id(new PhutilClassMapQuery())
|
||||||
|
->setAncestorClass('PhabricatorBulkManagementWorkflow')
|
||||||
|
->execute();
|
||||||
|
$workflows[] = new PhutilHelpArgumentWorkflow();
|
||||||
|
$args->parseWorkflows($workflows);
|
|
@ -245,7 +245,7 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
$workflow = $parsed_args->parseWorkflows($workflows);
|
$workflow = $parsed_args->parseWorkflows($workflows);
|
||||||
$workflow->setUser($user);
|
$workflow->setSSHUser($user);
|
||||||
$workflow->setOriginalArguments($original_argv);
|
$workflow->setOriginalArguments($original_argv);
|
||||||
$workflow->setIsClusterRequest($is_cluster_request);
|
$workflow->setIsClusterRequest($is_cluster_request);
|
||||||
|
|
||||||
|
|
|
@ -112,17 +112,6 @@ if ($is_new) {
|
||||||
$create_email = $email;
|
$create_email = $email;
|
||||||
}
|
}
|
||||||
|
|
||||||
$changed_pass = false;
|
|
||||||
// This disables local echo, so the user's password is not shown as they type
|
|
||||||
// it.
|
|
||||||
phutil_passthru('stty -echo');
|
|
||||||
$password = phutil_console_prompt(
|
|
||||||
pht('Enter a password for this user [blank to leave unchanged]:'));
|
|
||||||
phutil_passthru('stty echo');
|
|
||||||
if (strlen($password)) {
|
|
||||||
$changed_pass = $password;
|
|
||||||
}
|
|
||||||
|
|
||||||
$is_system_agent = $user->getIsSystemAgent();
|
$is_system_agent = $user->getIsSystemAgent();
|
||||||
$set_system_agent = phutil_console_confirm(
|
$set_system_agent = phutil_console_confirm(
|
||||||
pht('Is this user a bot?'),
|
pht('Is this user a bot?'),
|
||||||
|
@ -158,10 +147,6 @@ printf($tpl, pht('Real Name'), $original->getRealName(), $user->getRealName());
|
||||||
if ($is_new) {
|
if ($is_new) {
|
||||||
printf($tpl, pht('Email'), '', $create_email);
|
printf($tpl, pht('Email'), '', $create_email);
|
||||||
}
|
}
|
||||||
printf($tpl, pht('Password'), null,
|
|
||||||
($changed_pass !== false)
|
|
||||||
? pht('Updated')
|
|
||||||
: pht('Unchanged'));
|
|
||||||
|
|
||||||
printf(
|
printf(
|
||||||
$tpl,
|
$tpl,
|
||||||
|
@ -218,11 +203,6 @@ $user->openTransaction();
|
||||||
$editor->makeAdminUser($user, $set_admin);
|
$editor->makeAdminUser($user, $set_admin);
|
||||||
$editor->makeSystemAgentUser($user, $set_system_agent);
|
$editor->makeSystemAgentUser($user, $set_system_agent);
|
||||||
|
|
||||||
if ($changed_pass !== false) {
|
|
||||||
$envelope = new PhutilOpaqueEnvelope($changed_pass);
|
|
||||||
$editor->changePassword($user, $envelope);
|
|
||||||
}
|
|
||||||
|
|
||||||
$user->saveTransaction();
|
$user->saveTransaction();
|
||||||
|
|
||||||
echo pht('Saved changes.')."\n";
|
echo pht('Saved changes.')."\n";
|
||||||
|
|
|
@ -222,6 +222,12 @@ phutil_register_library_map(array(
|
||||||
'AuditConduitAPIMethod' => 'applications/audit/conduit/AuditConduitAPIMethod.php',
|
'AuditConduitAPIMethod' => 'applications/audit/conduit/AuditConduitAPIMethod.php',
|
||||||
'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php',
|
'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php',
|
||||||
'AuthManageProvidersCapability' => 'applications/auth/capability/AuthManageProvidersCapability.php',
|
'AuthManageProvidersCapability' => 'applications/auth/capability/AuthManageProvidersCapability.php',
|
||||||
|
'BulkParameterType' => 'applications/transactions/bulk/type/BulkParameterType.php',
|
||||||
|
'BulkPointsParameterType' => 'applications/transactions/bulk/type/BulkPointsParameterType.php',
|
||||||
|
'BulkRemarkupParameterType' => 'applications/transactions/bulk/type/BulkRemarkupParameterType.php',
|
||||||
|
'BulkSelectParameterType' => 'applications/transactions/bulk/type/BulkSelectParameterType.php',
|
||||||
|
'BulkStringParameterType' => 'applications/transactions/bulk/type/BulkStringParameterType.php',
|
||||||
|
'BulkTokenizerParameterType' => 'applications/transactions/bulk/type/BulkTokenizerParameterType.php',
|
||||||
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
|
'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
|
||||||
'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php',
|
'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php',
|
||||||
'CelerityAPI' => 'applications/celerity/CelerityAPI.php',
|
'CelerityAPI' => 'applications/celerity/CelerityAPI.php',
|
||||||
|
@ -584,6 +590,7 @@ phutil_register_library_map(array(
|
||||||
'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php',
|
'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php',
|
||||||
'DifferentialRevisionStatusDatasource' => 'applications/differential/typeahead/DifferentialRevisionStatusDatasource.php',
|
'DifferentialRevisionStatusDatasource' => 'applications/differential/typeahead/DifferentialRevisionStatusDatasource.php',
|
||||||
'DifferentialRevisionStatusFunctionDatasource' => 'applications/differential/typeahead/DifferentialRevisionStatusFunctionDatasource.php',
|
'DifferentialRevisionStatusFunctionDatasource' => 'applications/differential/typeahead/DifferentialRevisionStatusFunctionDatasource.php',
|
||||||
|
'DifferentialRevisionStatusHeraldField' => 'applications/differential/herald/DifferentialRevisionStatusHeraldField.php',
|
||||||
'DifferentialRevisionStatusTransaction' => 'applications/differential/xaction/DifferentialRevisionStatusTransaction.php',
|
'DifferentialRevisionStatusTransaction' => 'applications/differential/xaction/DifferentialRevisionStatusTransaction.php',
|
||||||
'DifferentialRevisionSummaryHeraldField' => 'applications/differential/herald/DifferentialRevisionSummaryHeraldField.php',
|
'DifferentialRevisionSummaryHeraldField' => 'applications/differential/herald/DifferentialRevisionSummaryHeraldField.php',
|
||||||
'DifferentialRevisionSummaryTransaction' => 'applications/differential/xaction/DifferentialRevisionSummaryTransaction.php',
|
'DifferentialRevisionSummaryTransaction' => 'applications/differential/xaction/DifferentialRevisionSummaryTransaction.php',
|
||||||
|
@ -758,6 +765,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionLintCountQuery' => 'applications/diffusion/query/DiffusionLintCountQuery.php',
|
'DiffusionLintCountQuery' => 'applications/diffusion/query/DiffusionLintCountQuery.php',
|
||||||
'DiffusionLintSaveRunner' => 'applications/diffusion/DiffusionLintSaveRunner.php',
|
'DiffusionLintSaveRunner' => 'applications/diffusion/DiffusionLintSaveRunner.php',
|
||||||
'DiffusionLocalRepositoryFilter' => 'applications/diffusion/data/DiffusionLocalRepositoryFilter.php',
|
'DiffusionLocalRepositoryFilter' => 'applications/diffusion/data/DiffusionLocalRepositoryFilter.php',
|
||||||
|
'DiffusionLogController' => 'applications/diffusion/controller/DiffusionLogController.php',
|
||||||
'DiffusionLookSoonConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionLookSoonConduitAPIMethod.php',
|
'DiffusionLookSoonConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionLookSoonConduitAPIMethod.php',
|
||||||
'DiffusionLowLevelCommitFieldsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitFieldsQuery.php',
|
'DiffusionLowLevelCommitFieldsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitFieldsQuery.php',
|
||||||
'DiffusionLowLevelCommitQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitQuery.php',
|
'DiffusionLowLevelCommitQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitQuery.php',
|
||||||
|
@ -825,9 +833,11 @@ phutil_register_library_map(array(
|
||||||
'DiffusionPreCommitRefTypeHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefTypeHeraldField.php',
|
'DiffusionPreCommitRefTypeHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitRefTypeHeraldField.php',
|
||||||
'DiffusionPreCommitUsesGitLFSHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitUsesGitLFSHeraldField.php',
|
'DiffusionPreCommitUsesGitLFSHeraldField' => 'applications/diffusion/herald/DiffusionPreCommitUsesGitLFSHeraldField.php',
|
||||||
'DiffusionPullEventGarbageCollector' => 'applications/diffusion/garbagecollector/DiffusionPullEventGarbageCollector.php',
|
'DiffusionPullEventGarbageCollector' => 'applications/diffusion/garbagecollector/DiffusionPullEventGarbageCollector.php',
|
||||||
|
'DiffusionPullLogListController' => 'applications/diffusion/controller/DiffusionPullLogListController.php',
|
||||||
|
'DiffusionPullLogListView' => 'applications/diffusion/view/DiffusionPullLogListView.php',
|
||||||
|
'DiffusionPullLogSearchEngine' => 'applications/diffusion/query/DiffusionPullLogSearchEngine.php',
|
||||||
'DiffusionPushCapability' => 'applications/diffusion/capability/DiffusionPushCapability.php',
|
'DiffusionPushCapability' => 'applications/diffusion/capability/DiffusionPushCapability.php',
|
||||||
'DiffusionPushEventViewController' => 'applications/diffusion/controller/DiffusionPushEventViewController.php',
|
'DiffusionPushEventViewController' => 'applications/diffusion/controller/DiffusionPushEventViewController.php',
|
||||||
'DiffusionPushLogController' => 'applications/diffusion/controller/DiffusionPushLogController.php',
|
|
||||||
'DiffusionPushLogListController' => 'applications/diffusion/controller/DiffusionPushLogListController.php',
|
'DiffusionPushLogListController' => 'applications/diffusion/controller/DiffusionPushLogListController.php',
|
||||||
'DiffusionPushLogListView' => 'applications/diffusion/view/DiffusionPushLogListView.php',
|
'DiffusionPushLogListView' => 'applications/diffusion/view/DiffusionPushLogListView.php',
|
||||||
'DiffusionPythonExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionPythonExternalSymbolsSource.php',
|
'DiffusionPythonExternalSymbolsSource' => 'applications/diffusion/symbol/DiffusionPythonExternalSymbolsSource.php',
|
||||||
|
@ -1351,7 +1361,9 @@ phutil_register_library_map(array(
|
||||||
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
||||||
'HeraldContentSourceField' => 'applications/herald/field/HeraldContentSourceField.php',
|
'HeraldContentSourceField' => 'applications/herald/field/HeraldContentSourceField.php',
|
||||||
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
||||||
|
'HeraldCoreStateReasons' => 'applications/herald/state/HeraldCoreStateReasons.php',
|
||||||
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
||||||
|
'HeraldDeprecatedFieldGroup' => 'applications/herald/field/HeraldDeprecatedFieldGroup.php',
|
||||||
'HeraldDifferentialAdapter' => 'applications/differential/herald/HeraldDifferentialAdapter.php',
|
'HeraldDifferentialAdapter' => 'applications/differential/herald/HeraldDifferentialAdapter.php',
|
||||||
'HeraldDifferentialDiffAdapter' => 'applications/differential/herald/HeraldDifferentialDiffAdapter.php',
|
'HeraldDifferentialDiffAdapter' => 'applications/differential/herald/HeraldDifferentialDiffAdapter.php',
|
||||||
'HeraldDifferentialRevisionAdapter' => 'applications/differential/herald/HeraldDifferentialRevisionAdapter.php',
|
'HeraldDifferentialRevisionAdapter' => 'applications/differential/herald/HeraldDifferentialRevisionAdapter.php',
|
||||||
|
@ -1389,7 +1401,6 @@ phutil_register_library_map(array(
|
||||||
'HeraldRelatedFieldGroup' => 'applications/herald/field/HeraldRelatedFieldGroup.php',
|
'HeraldRelatedFieldGroup' => 'applications/herald/field/HeraldRelatedFieldGroup.php',
|
||||||
'HeraldRemarkupFieldValue' => 'applications/herald/value/HeraldRemarkupFieldValue.php',
|
'HeraldRemarkupFieldValue' => 'applications/herald/value/HeraldRemarkupFieldValue.php',
|
||||||
'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php',
|
'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php',
|
||||||
'HeraldRepetitionPolicyConfig' => 'applications/herald/config/HeraldRepetitionPolicyConfig.php',
|
|
||||||
'HeraldRule' => 'applications/herald/storage/HeraldRule.php',
|
'HeraldRule' => 'applications/herald/storage/HeraldRule.php',
|
||||||
'HeraldRuleController' => 'applications/herald/controller/HeraldRuleController.php',
|
'HeraldRuleController' => 'applications/herald/controller/HeraldRuleController.php',
|
||||||
'HeraldRuleDatasource' => 'applications/herald/typeahead/HeraldRuleDatasource.php',
|
'HeraldRuleDatasource' => 'applications/herald/typeahead/HeraldRuleDatasource.php',
|
||||||
|
@ -1487,8 +1498,8 @@ phutil_register_library_map(array(
|
||||||
'MacroQueryConduitAPIMethod' => 'applications/macro/conduit/MacroQueryConduitAPIMethod.php',
|
'MacroQueryConduitAPIMethod' => 'applications/macro/conduit/MacroQueryConduitAPIMethod.php',
|
||||||
'ManiphestAssignEmailCommand' => 'applications/maniphest/command/ManiphestAssignEmailCommand.php',
|
'ManiphestAssignEmailCommand' => 'applications/maniphest/command/ManiphestAssignEmailCommand.php',
|
||||||
'ManiphestAssigneeDatasource' => 'applications/maniphest/typeahead/ManiphestAssigneeDatasource.php',
|
'ManiphestAssigneeDatasource' => 'applications/maniphest/typeahead/ManiphestAssigneeDatasource.php',
|
||||||
'ManiphestBatchEditController' => 'applications/maniphest/controller/ManiphestBatchEditController.php',
|
|
||||||
'ManiphestBulkEditCapability' => 'applications/maniphest/capability/ManiphestBulkEditCapability.php',
|
'ManiphestBulkEditCapability' => 'applications/maniphest/capability/ManiphestBulkEditCapability.php',
|
||||||
|
'ManiphestBulkEditController' => 'applications/maniphest/controller/ManiphestBulkEditController.php',
|
||||||
'ManiphestClaimEmailCommand' => 'applications/maniphest/command/ManiphestClaimEmailCommand.php',
|
'ManiphestClaimEmailCommand' => 'applications/maniphest/command/ManiphestClaimEmailCommand.php',
|
||||||
'ManiphestCloseEmailCommand' => 'applications/maniphest/command/ManiphestCloseEmailCommand.php',
|
'ManiphestCloseEmailCommand' => 'applications/maniphest/command/ManiphestCloseEmailCommand.php',
|
||||||
'ManiphestConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestConduitAPIMethod.php',
|
'ManiphestConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestConduitAPIMethod.php',
|
||||||
|
@ -1547,6 +1558,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskAttachTransaction' => 'applications/maniphest/xaction/ManiphestTaskAttachTransaction.php',
|
'ManiphestTaskAttachTransaction' => 'applications/maniphest/xaction/ManiphestTaskAttachTransaction.php',
|
||||||
'ManiphestTaskAuthorHeraldField' => 'applications/maniphest/herald/ManiphestTaskAuthorHeraldField.php',
|
'ManiphestTaskAuthorHeraldField' => 'applications/maniphest/herald/ManiphestTaskAuthorHeraldField.php',
|
||||||
'ManiphestTaskAuthorPolicyRule' => 'applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php',
|
'ManiphestTaskAuthorPolicyRule' => 'applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php',
|
||||||
|
'ManiphestTaskBulkEngine' => 'applications/maniphest/bulk/ManiphestTaskBulkEngine.php',
|
||||||
'ManiphestTaskCloseAsDuplicateRelationship' => 'applications/maniphest/relationship/ManiphestTaskCloseAsDuplicateRelationship.php',
|
'ManiphestTaskCloseAsDuplicateRelationship' => 'applications/maniphest/relationship/ManiphestTaskCloseAsDuplicateRelationship.php',
|
||||||
'ManiphestTaskClosedStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskClosedStatusDatasource.php',
|
'ManiphestTaskClosedStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskClosedStatusDatasource.php',
|
||||||
'ManiphestTaskCoverImageTransaction' => 'applications/maniphest/xaction/ManiphestTaskCoverImageTransaction.php',
|
'ManiphestTaskCoverImageTransaction' => 'applications/maniphest/xaction/ManiphestTaskCoverImageTransaction.php',
|
||||||
|
@ -1556,7 +1568,6 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskDescriptionTransaction' => 'applications/maniphest/xaction/ManiphestTaskDescriptionTransaction.php',
|
'ManiphestTaskDescriptionTransaction' => 'applications/maniphest/xaction/ManiphestTaskDescriptionTransaction.php',
|
||||||
'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php',
|
'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php',
|
||||||
'ManiphestTaskEdgeTransaction' => 'applications/maniphest/xaction/ManiphestTaskEdgeTransaction.php',
|
'ManiphestTaskEdgeTransaction' => 'applications/maniphest/xaction/ManiphestTaskEdgeTransaction.php',
|
||||||
'ManiphestTaskEditBulkJobType' => 'applications/maniphest/bulk/ManiphestTaskEditBulkJobType.php',
|
|
||||||
'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php',
|
'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php',
|
||||||
'ManiphestTaskEditEngineLock' => 'applications/maniphest/editor/ManiphestTaskEditEngineLock.php',
|
'ManiphestTaskEditEngineLock' => 'applications/maniphest/editor/ManiphestTaskEditEngineLock.php',
|
||||||
'ManiphestTaskFerretEngine' => 'applications/maniphest/search/ManiphestTaskFerretEngine.php',
|
'ManiphestTaskFerretEngine' => 'applications/maniphest/search/ManiphestTaskFerretEngine.php',
|
||||||
|
@ -2026,6 +2037,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthApplication' => 'applications/auth/application/PhabricatorAuthApplication.php',
|
'PhabricatorAuthApplication' => 'applications/auth/application/PhabricatorAuthApplication.php',
|
||||||
'PhabricatorAuthAuthFactorPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php',
|
'PhabricatorAuthAuthFactorPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php',
|
||||||
'PhabricatorAuthAuthProviderPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php',
|
'PhabricatorAuthAuthProviderPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php',
|
||||||
|
'PhabricatorAuthChangePasswordAction' => 'applications/auth/action/PhabricatorAuthChangePasswordAction.php',
|
||||||
'PhabricatorAuthConduitAPIMethod' => 'applications/auth/conduit/PhabricatorAuthConduitAPIMethod.php',
|
'PhabricatorAuthConduitAPIMethod' => 'applications/auth/conduit/PhabricatorAuthConduitAPIMethod.php',
|
||||||
'PhabricatorAuthConduitTokenRevoker' => 'applications/auth/revoker/PhabricatorAuthConduitTokenRevoker.php',
|
'PhabricatorAuthConduitTokenRevoker' => 'applications/auth/revoker/PhabricatorAuthConduitTokenRevoker.php',
|
||||||
'PhabricatorAuthConfirmLinkController' => 'applications/auth/controller/PhabricatorAuthConfirmLinkController.php',
|
'PhabricatorAuthConfirmLinkController' => 'applications/auth/controller/PhabricatorAuthConfirmLinkController.php',
|
||||||
|
@ -2082,7 +2094,21 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
|
'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
|
||||||
'PhabricatorAuthOneTimeLoginController' => 'applications/auth/controller/PhabricatorAuthOneTimeLoginController.php',
|
'PhabricatorAuthOneTimeLoginController' => 'applications/auth/controller/PhabricatorAuthOneTimeLoginController.php',
|
||||||
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthOneTimeLoginTemporaryTokenType.php',
|
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthOneTimeLoginTemporaryTokenType.php',
|
||||||
|
'PhabricatorAuthPassword' => 'applications/auth/storage/PhabricatorAuthPassword.php',
|
||||||
|
'PhabricatorAuthPasswordEditor' => 'applications/auth/editor/PhabricatorAuthPasswordEditor.php',
|
||||||
|
'PhabricatorAuthPasswordEngine' => 'applications/auth/engine/PhabricatorAuthPasswordEngine.php',
|
||||||
|
'PhabricatorAuthPasswordException' => 'applications/auth/password/PhabricatorAuthPasswordException.php',
|
||||||
|
'PhabricatorAuthPasswordHashInterface' => 'applications/auth/password/PhabricatorAuthPasswordHashInterface.php',
|
||||||
|
'PhabricatorAuthPasswordPHIDType' => 'applications/auth/phid/PhabricatorAuthPasswordPHIDType.php',
|
||||||
|
'PhabricatorAuthPasswordQuery' => 'applications/auth/query/PhabricatorAuthPasswordQuery.php',
|
||||||
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthPasswordResetTemporaryTokenType.php',
|
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthPasswordResetTemporaryTokenType.php',
|
||||||
|
'PhabricatorAuthPasswordRevokeTransaction' => 'applications/auth/xaction/PhabricatorAuthPasswordRevokeTransaction.php',
|
||||||
|
'PhabricatorAuthPasswordRevoker' => 'applications/auth/revoker/PhabricatorAuthPasswordRevoker.php',
|
||||||
|
'PhabricatorAuthPasswordTestCase' => 'applications/auth/__tests__/PhabricatorAuthPasswordTestCase.php',
|
||||||
|
'PhabricatorAuthPasswordTransaction' => 'applications/auth/storage/PhabricatorAuthPasswordTransaction.php',
|
||||||
|
'PhabricatorAuthPasswordTransactionQuery' => 'applications/auth/query/PhabricatorAuthPasswordTransactionQuery.php',
|
||||||
|
'PhabricatorAuthPasswordTransactionType' => 'applications/auth/xaction/PhabricatorAuthPasswordTransactionType.php',
|
||||||
|
'PhabricatorAuthPasswordUpgradeTransaction' => 'applications/auth/xaction/PhabricatorAuthPasswordUpgradeTransaction.php',
|
||||||
'PhabricatorAuthProvider' => 'applications/auth/provider/PhabricatorAuthProvider.php',
|
'PhabricatorAuthProvider' => 'applications/auth/provider/PhabricatorAuthProvider.php',
|
||||||
'PhabricatorAuthProviderConfig' => 'applications/auth/storage/PhabricatorAuthProviderConfig.php',
|
'PhabricatorAuthProviderConfig' => 'applications/auth/storage/PhabricatorAuthProviderConfig.php',
|
||||||
'PhabricatorAuthProviderConfigController' => 'applications/auth/controller/config/PhabricatorAuthProviderConfigController.php',
|
'PhabricatorAuthProviderConfigController' => 'applications/auth/controller/config/PhabricatorAuthProviderConfigController.php',
|
||||||
|
@ -2098,7 +2124,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthRevoker' => 'applications/auth/revoker/PhabricatorAuthRevoker.php',
|
'PhabricatorAuthRevoker' => 'applications/auth/revoker/PhabricatorAuthRevoker.php',
|
||||||
'PhabricatorAuthSSHKey' => 'applications/auth/storage/PhabricatorAuthSSHKey.php',
|
'PhabricatorAuthSSHKey' => 'applications/auth/storage/PhabricatorAuthSSHKey.php',
|
||||||
'PhabricatorAuthSSHKeyController' => 'applications/auth/controller/PhabricatorAuthSSHKeyController.php',
|
'PhabricatorAuthSSHKeyController' => 'applications/auth/controller/PhabricatorAuthSSHKeyController.php',
|
||||||
'PhabricatorAuthSSHKeyDeactivateController' => 'applications/auth/controller/PhabricatorAuthSSHKeyDeactivateController.php',
|
|
||||||
'PhabricatorAuthSSHKeyEditController' => 'applications/auth/controller/PhabricatorAuthSSHKeyEditController.php',
|
'PhabricatorAuthSSHKeyEditController' => 'applications/auth/controller/PhabricatorAuthSSHKeyEditController.php',
|
||||||
'PhabricatorAuthSSHKeyEditor' => 'applications/auth/editor/PhabricatorAuthSSHKeyEditor.php',
|
'PhabricatorAuthSSHKeyEditor' => 'applications/auth/editor/PhabricatorAuthSSHKeyEditor.php',
|
||||||
'PhabricatorAuthSSHKeyGenerateController' => 'applications/auth/controller/PhabricatorAuthSSHKeyGenerateController.php',
|
'PhabricatorAuthSSHKeyGenerateController' => 'applications/auth/controller/PhabricatorAuthSSHKeyGenerateController.php',
|
||||||
|
@ -2106,12 +2131,15 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSSHKeyPHIDType' => 'applications/auth/phid/PhabricatorAuthSSHKeyPHIDType.php',
|
'PhabricatorAuthSSHKeyPHIDType' => 'applications/auth/phid/PhabricatorAuthSSHKeyPHIDType.php',
|
||||||
'PhabricatorAuthSSHKeyQuery' => 'applications/auth/query/PhabricatorAuthSSHKeyQuery.php',
|
'PhabricatorAuthSSHKeyQuery' => 'applications/auth/query/PhabricatorAuthSSHKeyQuery.php',
|
||||||
'PhabricatorAuthSSHKeyReplyHandler' => 'applications/auth/mail/PhabricatorAuthSSHKeyReplyHandler.php',
|
'PhabricatorAuthSSHKeyReplyHandler' => 'applications/auth/mail/PhabricatorAuthSSHKeyReplyHandler.php',
|
||||||
|
'PhabricatorAuthSSHKeyRevokeController' => 'applications/auth/controller/PhabricatorAuthSSHKeyRevokeController.php',
|
||||||
'PhabricatorAuthSSHKeySearchEngine' => 'applications/auth/query/PhabricatorAuthSSHKeySearchEngine.php',
|
'PhabricatorAuthSSHKeySearchEngine' => 'applications/auth/query/PhabricatorAuthSSHKeySearchEngine.php',
|
||||||
'PhabricatorAuthSSHKeyTableView' => 'applications/auth/view/PhabricatorAuthSSHKeyTableView.php',
|
'PhabricatorAuthSSHKeyTableView' => 'applications/auth/view/PhabricatorAuthSSHKeyTableView.php',
|
||||||
|
'PhabricatorAuthSSHKeyTestCase' => 'applications/auth/__tests__/PhabricatorAuthSSHKeyTestCase.php',
|
||||||
'PhabricatorAuthSSHKeyTransaction' => 'applications/auth/storage/PhabricatorAuthSSHKeyTransaction.php',
|
'PhabricatorAuthSSHKeyTransaction' => 'applications/auth/storage/PhabricatorAuthSSHKeyTransaction.php',
|
||||||
'PhabricatorAuthSSHKeyTransactionQuery' => 'applications/auth/query/PhabricatorAuthSSHKeyTransactionQuery.php',
|
'PhabricatorAuthSSHKeyTransactionQuery' => 'applications/auth/query/PhabricatorAuthSSHKeyTransactionQuery.php',
|
||||||
'PhabricatorAuthSSHKeyViewController' => 'applications/auth/controller/PhabricatorAuthSSHKeyViewController.php',
|
'PhabricatorAuthSSHKeyViewController' => 'applications/auth/controller/PhabricatorAuthSSHKeyViewController.php',
|
||||||
'PhabricatorAuthSSHPublicKey' => 'applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php',
|
'PhabricatorAuthSSHPublicKey' => 'applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php',
|
||||||
|
'PhabricatorAuthSSHRevoker' => 'applications/auth/revoker/PhabricatorAuthSSHRevoker.php',
|
||||||
'PhabricatorAuthSession' => 'applications/auth/storage/PhabricatorAuthSession.php',
|
'PhabricatorAuthSession' => 'applications/auth/storage/PhabricatorAuthSession.php',
|
||||||
'PhabricatorAuthSessionEngine' => 'applications/auth/engine/PhabricatorAuthSessionEngine.php',
|
'PhabricatorAuthSessionEngine' => 'applications/auth/engine/PhabricatorAuthSessionEngine.php',
|
||||||
'PhabricatorAuthSessionEngineExtension' => 'applications/auth/engine/PhabricatorAuthSessionEngineExtension.php',
|
'PhabricatorAuthSessionEngineExtension' => 'applications/auth/engine/PhabricatorAuthSessionEngineExtension.php',
|
||||||
|
@ -2119,6 +2147,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSessionGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthSessionGarbageCollector.php',
|
'PhabricatorAuthSessionGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthSessionGarbageCollector.php',
|
||||||
'PhabricatorAuthSessionInfo' => 'applications/auth/data/PhabricatorAuthSessionInfo.php',
|
'PhabricatorAuthSessionInfo' => 'applications/auth/data/PhabricatorAuthSessionInfo.php',
|
||||||
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
|
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
|
||||||
|
'PhabricatorAuthSessionRevoker' => 'applications/auth/revoker/PhabricatorAuthSessionRevoker.php',
|
||||||
'PhabricatorAuthSetPasswordController' => 'applications/auth/controller/PhabricatorAuthSetPasswordController.php',
|
'PhabricatorAuthSetPasswordController' => 'applications/auth/controller/PhabricatorAuthSetPasswordController.php',
|
||||||
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
|
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
|
||||||
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
||||||
|
@ -2126,6 +2155,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
|
'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
|
||||||
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
|
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
|
||||||
'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
|
'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
|
||||||
|
'PhabricatorAuthTemporaryTokenRevoker' => 'applications/auth/revoker/PhabricatorAuthTemporaryTokenRevoker.php',
|
||||||
'PhabricatorAuthTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenType.php',
|
'PhabricatorAuthTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenType.php',
|
||||||
'PhabricatorAuthTemporaryTokenTypeModule' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php',
|
'PhabricatorAuthTemporaryTokenTypeModule' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php',
|
||||||
'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
|
'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
|
||||||
|
@ -2198,6 +2228,11 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorBuiltinFileCachePurger' => 'applications/cache/purger/PhabricatorBuiltinFileCachePurger.php',
|
'PhabricatorBuiltinFileCachePurger' => 'applications/cache/purger/PhabricatorBuiltinFileCachePurger.php',
|
||||||
'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php',
|
'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php',
|
||||||
'PhabricatorBulkContentSource' => 'infrastructure/daemon/contentsource/PhabricatorBulkContentSource.php',
|
'PhabricatorBulkContentSource' => 'infrastructure/daemon/contentsource/PhabricatorBulkContentSource.php',
|
||||||
|
'PhabricatorBulkEditGroup' => 'applications/transactions/bulk/PhabricatorBulkEditGroup.php',
|
||||||
|
'PhabricatorBulkEngine' => 'applications/transactions/bulk/PhabricatorBulkEngine.php',
|
||||||
|
'PhabricatorBulkManagementMakeSilentWorkflow' => 'applications/transactions/bulk/management/PhabricatorBulkManagementMakeSilentWorkflow.php',
|
||||||
|
'PhabricatorBulkManagementWorkflow' => 'applications/transactions/bulk/management/PhabricatorBulkManagementWorkflow.php',
|
||||||
|
'PhabricatorCSVExportFormat' => 'infrastructure/export/PhabricatorCSVExportFormat.php',
|
||||||
'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
|
'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
|
||||||
'PhabricatorCacheEngine' => 'applications/system/engine/PhabricatorCacheEngine.php',
|
'PhabricatorCacheEngine' => 'applications/system/engine/PhabricatorCacheEngine.php',
|
||||||
'PhabricatorCacheEngineExtension' => 'applications/system/engine/PhabricatorCacheEngineExtension.php',
|
'PhabricatorCacheEngineExtension' => 'applications/system/engine/PhabricatorCacheEngineExtension.php',
|
||||||
|
@ -2727,6 +2762,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorEdgesDestructionEngineExtension' => 'infrastructure/edges/engineextension/PhabricatorEdgesDestructionEngineExtension.php',
|
'PhabricatorEdgesDestructionEngineExtension' => 'infrastructure/edges/engineextension/PhabricatorEdgesDestructionEngineExtension.php',
|
||||||
'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php',
|
'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php',
|
||||||
'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php',
|
'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php',
|
||||||
|
'PhabricatorEditEngineBulkJobType' => 'applications/transactions/bulk/PhabricatorEditEngineBulkJobType.php',
|
||||||
'PhabricatorEditEngineCheckboxesCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCheckboxesCommentAction.php',
|
'PhabricatorEditEngineCheckboxesCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCheckboxesCommentAction.php',
|
||||||
'PhabricatorEditEngineColumnsCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php',
|
'PhabricatorEditEngineColumnsCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php',
|
||||||
'PhabricatorEditEngineCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php',
|
'PhabricatorEditEngineCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php',
|
||||||
|
@ -2802,12 +2838,15 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php',
|
'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php',
|
||||||
'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php',
|
'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php',
|
||||||
'PhabricatorEpochEditField' => 'applications/transactions/editfield/PhabricatorEpochEditField.php',
|
'PhabricatorEpochEditField' => 'applications/transactions/editfield/PhabricatorEpochEditField.php',
|
||||||
|
'PhabricatorEpochExportField' => 'infrastructure/export/PhabricatorEpochExportField.php',
|
||||||
'PhabricatorEvent' => 'infrastructure/events/PhabricatorEvent.php',
|
'PhabricatorEvent' => 'infrastructure/events/PhabricatorEvent.php',
|
||||||
'PhabricatorEventEngine' => 'infrastructure/events/PhabricatorEventEngine.php',
|
'PhabricatorEventEngine' => 'infrastructure/events/PhabricatorEventEngine.php',
|
||||||
'PhabricatorEventListener' => 'infrastructure/events/PhabricatorEventListener.php',
|
'PhabricatorEventListener' => 'infrastructure/events/PhabricatorEventListener.php',
|
||||||
'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
|
'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
|
||||||
'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
|
'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
|
||||||
'PhabricatorExecFutureFileUploadSource' => 'applications/files/uploadsource/PhabricatorExecFutureFileUploadSource.php',
|
'PhabricatorExecFutureFileUploadSource' => 'applications/files/uploadsource/PhabricatorExecFutureFileUploadSource.php',
|
||||||
|
'PhabricatorExportField' => 'infrastructure/export/PhabricatorExportField.php',
|
||||||
|
'PhabricatorExportFormat' => 'infrastructure/export/PhabricatorExportFormat.php',
|
||||||
'PhabricatorExtendedPolicyInterface' => 'applications/policy/interface/PhabricatorExtendedPolicyInterface.php',
|
'PhabricatorExtendedPolicyInterface' => 'applications/policy/interface/PhabricatorExtendedPolicyInterface.php',
|
||||||
'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
|
'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
|
||||||
'PhabricatorExtensionsSetupCheck' => 'applications/config/check/PhabricatorExtensionsSetupCheck.php',
|
'PhabricatorExtensionsSetupCheck' => 'applications/config/check/PhabricatorExtensionsSetupCheck.php',
|
||||||
|
@ -2927,6 +2966,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileUploadDialogController' => 'applications/files/controller/PhabricatorFileUploadDialogController.php',
|
'PhabricatorFileUploadDialogController' => 'applications/files/controller/PhabricatorFileUploadDialogController.php',
|
||||||
'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php',
|
'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php',
|
||||||
'PhabricatorFileUploadSource' => 'applications/files/uploadsource/PhabricatorFileUploadSource.php',
|
'PhabricatorFileUploadSource' => 'applications/files/uploadsource/PhabricatorFileUploadSource.php',
|
||||||
|
'PhabricatorFileUploadSourceByteLimitException' => 'applications/files/uploadsource/PhabricatorFileUploadSourceByteLimitException.php',
|
||||||
'PhabricatorFileinfoSetupCheck' => 'applications/config/check/PhabricatorFileinfoSetupCheck.php',
|
'PhabricatorFileinfoSetupCheck' => 'applications/config/check/PhabricatorFileinfoSetupCheck.php',
|
||||||
'PhabricatorFilesApplication' => 'applications/files/application/PhabricatorFilesApplication.php',
|
'PhabricatorFilesApplication' => 'applications/files/application/PhabricatorFilesApplication.php',
|
||||||
'PhabricatorFilesApplicationStorageEnginePanel' => 'applications/files/applicationpanel/PhabricatorFilesApplicationStorageEnginePanel.php',
|
'PhabricatorFilesApplicationStorageEnginePanel' => 'applications/files/applicationpanel/PhabricatorFilesApplicationStorageEnginePanel.php',
|
||||||
|
@ -3026,6 +3066,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorHomeProfileMenuItem' => 'applications/home/menuitem/PhabricatorHomeProfileMenuItem.php',
|
'PhabricatorHomeProfileMenuItem' => 'applications/home/menuitem/PhabricatorHomeProfileMenuItem.php',
|
||||||
'PhabricatorHovercardEngineExtension' => 'applications/search/engineextension/PhabricatorHovercardEngineExtension.php',
|
'PhabricatorHovercardEngineExtension' => 'applications/search/engineextension/PhabricatorHovercardEngineExtension.php',
|
||||||
'PhabricatorHovercardEngineExtensionModule' => 'applications/search/engineextension/PhabricatorHovercardEngineExtensionModule.php',
|
'PhabricatorHovercardEngineExtensionModule' => 'applications/search/engineextension/PhabricatorHovercardEngineExtensionModule.php',
|
||||||
|
'PhabricatorIDExportField' => 'infrastructure/export/PhabricatorIDExportField.php',
|
||||||
'PhabricatorIDsSearchEngineExtension' => 'applications/search/engineextension/PhabricatorIDsSearchEngineExtension.php',
|
'PhabricatorIDsSearchEngineExtension' => 'applications/search/engineextension/PhabricatorIDsSearchEngineExtension.php',
|
||||||
'PhabricatorIDsSearchField' => 'applications/search/field/PhabricatorIDsSearchField.php',
|
'PhabricatorIDsSearchField' => 'applications/search/field/PhabricatorIDsSearchField.php',
|
||||||
'PhabricatorIconDatasource' => 'applications/files/typeahead/PhabricatorIconDatasource.php',
|
'PhabricatorIconDatasource' => 'applications/files/typeahead/PhabricatorIconDatasource.php',
|
||||||
|
@ -3049,6 +3090,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php',
|
'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php',
|
||||||
'PhabricatorInstructionsEditField' => 'applications/transactions/editfield/PhabricatorInstructionsEditField.php',
|
'PhabricatorInstructionsEditField' => 'applications/transactions/editfield/PhabricatorInstructionsEditField.php',
|
||||||
'PhabricatorIntConfigType' => 'applications/config/type/PhabricatorIntConfigType.php',
|
'PhabricatorIntConfigType' => 'applications/config/type/PhabricatorIntConfigType.php',
|
||||||
|
'PhabricatorIntExportField' => 'infrastructure/export/PhabricatorIntExportField.php',
|
||||||
'PhabricatorInternalSetting' => 'applications/settings/setting/PhabricatorInternalSetting.php',
|
'PhabricatorInternalSetting' => 'applications/settings/setting/PhabricatorInternalSetting.php',
|
||||||
'PhabricatorInternationalizationManagementExtractWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementExtractWorkflow.php',
|
'PhabricatorInternationalizationManagementExtractWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementExtractWorkflow.php',
|
||||||
'PhabricatorInternationalizationManagementWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php',
|
'PhabricatorInternationalizationManagementWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php',
|
||||||
|
@ -3058,6 +3100,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorIteratorFileUploadSource' => 'applications/files/uploadsource/PhabricatorIteratorFileUploadSource.php',
|
'PhabricatorIteratorFileUploadSource' => 'applications/files/uploadsource/PhabricatorIteratorFileUploadSource.php',
|
||||||
'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php',
|
'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php',
|
||||||
'PhabricatorJSONConfigType' => 'applications/config/type/PhabricatorJSONConfigType.php',
|
'PhabricatorJSONConfigType' => 'applications/config/type/PhabricatorJSONConfigType.php',
|
||||||
|
'PhabricatorJSONExportFormat' => 'infrastructure/export/PhabricatorJSONExportFormat.php',
|
||||||
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
|
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
|
||||||
'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php',
|
'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php',
|
||||||
'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
|
'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
|
||||||
|
@ -3377,6 +3420,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
|
'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
|
||||||
'PhabricatorPHID' => 'applications/phid/storage/PhabricatorPHID.php',
|
'PhabricatorPHID' => 'applications/phid/storage/PhabricatorPHID.php',
|
||||||
'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php',
|
'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php',
|
||||||
|
'PhabricatorPHIDExportField' => 'infrastructure/export/PhabricatorPHIDExportField.php',
|
||||||
'PhabricatorPHIDInterface' => 'applications/phid/interface/PhabricatorPHIDInterface.php',
|
'PhabricatorPHIDInterface' => 'applications/phid/interface/PhabricatorPHIDInterface.php',
|
||||||
'PhabricatorPHIDListEditField' => 'applications/transactions/editfield/PhabricatorPHIDListEditField.php',
|
'PhabricatorPHIDListEditField' => 'applications/transactions/editfield/PhabricatorPHIDListEditField.php',
|
||||||
'PhabricatorPHIDListEditType' => 'applications/transactions/edittype/PhabricatorPHIDListEditType.php',
|
'PhabricatorPHIDListEditType' => 'applications/transactions/edittype/PhabricatorPHIDListEditType.php',
|
||||||
|
@ -3465,6 +3509,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPagerUIExample' => 'applications/uiexample/examples/PhabricatorPagerUIExample.php',
|
'PhabricatorPagerUIExample' => 'applications/uiexample/examples/PhabricatorPagerUIExample.php',
|
||||||
'PhabricatorPassphraseApplication' => 'applications/passphrase/application/PhabricatorPassphraseApplication.php',
|
'PhabricatorPassphraseApplication' => 'applications/passphrase/application/PhabricatorPassphraseApplication.php',
|
||||||
'PhabricatorPasswordAuthProvider' => 'applications/auth/provider/PhabricatorPasswordAuthProvider.php',
|
'PhabricatorPasswordAuthProvider' => 'applications/auth/provider/PhabricatorPasswordAuthProvider.php',
|
||||||
|
'PhabricatorPasswordDestructionEngineExtension' => 'applications/auth/extension/PhabricatorPasswordDestructionEngineExtension.php',
|
||||||
'PhabricatorPasswordHasher' => 'infrastructure/util/password/PhabricatorPasswordHasher.php',
|
'PhabricatorPasswordHasher' => 'infrastructure/util/password/PhabricatorPasswordHasher.php',
|
||||||
'PhabricatorPasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php',
|
'PhabricatorPasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php',
|
||||||
'PhabricatorPasswordHasherUnavailableException' => 'infrastructure/util/password/PhabricatorPasswordHasherUnavailableException.php',
|
'PhabricatorPasswordHasherUnavailableException' => 'infrastructure/util/password/PhabricatorPasswordHasherUnavailableException.php',
|
||||||
|
@ -3915,7 +3960,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
|
'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
|
||||||
'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php',
|
'PhabricatorRepositoryURITransaction' => 'applications/repository/storage/PhabricatorRepositoryURITransaction.php',
|
||||||
'PhabricatorRepositoryURITransactionQuery' => 'applications/repository/query/PhabricatorRepositoryURITransactionQuery.php',
|
'PhabricatorRepositoryURITransactionQuery' => 'applications/repository/query/PhabricatorRepositoryURITransactionQuery.php',
|
||||||
'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php',
|
|
||||||
'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php',
|
'PhabricatorRepositoryWorkingCopyVersion' => 'applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php',
|
||||||
'PhabricatorRequestExceptionHandler' => 'aphront/handler/PhabricatorRequestExceptionHandler.php',
|
'PhabricatorRequestExceptionHandler' => 'aphront/handler/PhabricatorRequestExceptionHandler.php',
|
||||||
'PhabricatorResourceSite' => 'aphront/site/PhabricatorResourceSite.php',
|
'PhabricatorResourceSite' => 'aphront/site/PhabricatorResourceSite.php',
|
||||||
|
@ -4142,6 +4186,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorStorageSchemaSpec' => 'infrastructure/storage/schema/PhabricatorStorageSchemaSpec.php',
|
'PhabricatorStorageSchemaSpec' => 'infrastructure/storage/schema/PhabricatorStorageSchemaSpec.php',
|
||||||
'PhabricatorStorageSetupCheck' => 'applications/config/check/PhabricatorStorageSetupCheck.php',
|
'PhabricatorStorageSetupCheck' => 'applications/config/check/PhabricatorStorageSetupCheck.php',
|
||||||
'PhabricatorStringConfigType' => 'applications/config/type/PhabricatorStringConfigType.php',
|
'PhabricatorStringConfigType' => 'applications/config/type/PhabricatorStringConfigType.php',
|
||||||
|
'PhabricatorStringExportField' => 'infrastructure/export/PhabricatorStringExportField.php',
|
||||||
'PhabricatorStringListConfigType' => 'applications/config/type/PhabricatorStringListConfigType.php',
|
'PhabricatorStringListConfigType' => 'applications/config/type/PhabricatorStringListConfigType.php',
|
||||||
'PhabricatorStringListEditField' => 'applications/transactions/editfield/PhabricatorStringListEditField.php',
|
'PhabricatorStringListEditField' => 'applications/transactions/editfield/PhabricatorStringListEditField.php',
|
||||||
'PhabricatorStringSetting' => 'applications/settings/setting/PhabricatorStringSetting.php',
|
'PhabricatorStringSetting' => 'applications/settings/setting/PhabricatorStringSetting.php',
|
||||||
|
@ -4205,6 +4250,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorTextAreaEditField' => 'applications/transactions/editfield/PhabricatorTextAreaEditField.php',
|
'PhabricatorTextAreaEditField' => 'applications/transactions/editfield/PhabricatorTextAreaEditField.php',
|
||||||
'PhabricatorTextConfigType' => 'applications/config/type/PhabricatorTextConfigType.php',
|
'PhabricatorTextConfigType' => 'applications/config/type/PhabricatorTextConfigType.php',
|
||||||
'PhabricatorTextEditField' => 'applications/transactions/editfield/PhabricatorTextEditField.php',
|
'PhabricatorTextEditField' => 'applications/transactions/editfield/PhabricatorTextEditField.php',
|
||||||
|
'PhabricatorTextExportFormat' => 'infrastructure/export/PhabricatorTextExportFormat.php',
|
||||||
'PhabricatorTextListConfigType' => 'applications/config/type/PhabricatorTextListConfigType.php',
|
'PhabricatorTextListConfigType' => 'applications/config/type/PhabricatorTextListConfigType.php',
|
||||||
'PhabricatorTime' => 'infrastructure/time/PhabricatorTime.php',
|
'PhabricatorTime' => 'infrastructure/time/PhabricatorTime.php',
|
||||||
'PhabricatorTimeFormatSetting' => 'applications/settings/setting/PhabricatorTimeFormatSetting.php',
|
'PhabricatorTimeFormatSetting' => 'applications/settings/setting/PhabricatorTimeFormatSetting.php',
|
||||||
|
@ -5239,6 +5285,12 @@ phutil_register_library_map(array(
|
||||||
'AuditConduitAPIMethod' => 'ConduitAPIMethod',
|
'AuditConduitAPIMethod' => 'ConduitAPIMethod',
|
||||||
'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod',
|
'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod',
|
||||||
'AuthManageProvidersCapability' => 'PhabricatorPolicyCapability',
|
'AuthManageProvidersCapability' => 'PhabricatorPolicyCapability',
|
||||||
|
'BulkParameterType' => 'Phobject',
|
||||||
|
'BulkPointsParameterType' => 'BulkParameterType',
|
||||||
|
'BulkRemarkupParameterType' => 'BulkParameterType',
|
||||||
|
'BulkSelectParameterType' => 'BulkParameterType',
|
||||||
|
'BulkStringParameterType' => 'BulkParameterType',
|
||||||
|
'BulkTokenizerParameterType' => 'BulkParameterType',
|
||||||
'CalendarTimeUtil' => 'Phobject',
|
'CalendarTimeUtil' => 'Phobject',
|
||||||
'CalendarTimeUtilTestCase' => 'PhabricatorTestCase',
|
'CalendarTimeUtilTestCase' => 'PhabricatorTestCase',
|
||||||
'CelerityAPI' => 'Phobject',
|
'CelerityAPI' => 'Phobject',
|
||||||
|
@ -5650,6 +5702,7 @@ phutil_register_library_map(array(
|
||||||
'DifferentialRevisionStatus' => 'Phobject',
|
'DifferentialRevisionStatus' => 'Phobject',
|
||||||
'DifferentialRevisionStatusDatasource' => 'PhabricatorTypeaheadDatasource',
|
'DifferentialRevisionStatusDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||||
'DifferentialRevisionStatusFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
'DifferentialRevisionStatusFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||||
|
'DifferentialRevisionStatusHeraldField' => 'DifferentialRevisionHeraldField',
|
||||||
'DifferentialRevisionStatusTransaction' => 'DifferentialRevisionTransactionType',
|
'DifferentialRevisionStatusTransaction' => 'DifferentialRevisionTransactionType',
|
||||||
'DifferentialRevisionSummaryHeraldField' => 'DifferentialRevisionHeraldField',
|
'DifferentialRevisionSummaryHeraldField' => 'DifferentialRevisionHeraldField',
|
||||||
'DifferentialRevisionSummaryTransaction' => 'DifferentialRevisionTransactionType',
|
'DifferentialRevisionSummaryTransaction' => 'DifferentialRevisionTransactionType',
|
||||||
|
@ -5827,6 +5880,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionLintCountQuery' => 'PhabricatorQuery',
|
'DiffusionLintCountQuery' => 'PhabricatorQuery',
|
||||||
'DiffusionLintSaveRunner' => 'Phobject',
|
'DiffusionLintSaveRunner' => 'Phobject',
|
||||||
'DiffusionLocalRepositoryFilter' => 'Phobject',
|
'DiffusionLocalRepositoryFilter' => 'Phobject',
|
||||||
|
'DiffusionLogController' => 'DiffusionController',
|
||||||
'DiffusionLookSoonConduitAPIMethod' => 'DiffusionConduitAPIMethod',
|
'DiffusionLookSoonConduitAPIMethod' => 'DiffusionConduitAPIMethod',
|
||||||
'DiffusionLowLevelCommitFieldsQuery' => 'DiffusionLowLevelQuery',
|
'DiffusionLowLevelCommitFieldsQuery' => 'DiffusionLowLevelQuery',
|
||||||
'DiffusionLowLevelCommitQuery' => 'DiffusionLowLevelQuery',
|
'DiffusionLowLevelCommitQuery' => 'DiffusionLowLevelQuery',
|
||||||
|
@ -5894,10 +5948,12 @@ phutil_register_library_map(array(
|
||||||
'DiffusionPreCommitRefTypeHeraldField' => 'DiffusionPreCommitRefHeraldField',
|
'DiffusionPreCommitRefTypeHeraldField' => 'DiffusionPreCommitRefHeraldField',
|
||||||
'DiffusionPreCommitUsesGitLFSHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
'DiffusionPreCommitUsesGitLFSHeraldField' => 'DiffusionPreCommitContentHeraldField',
|
||||||
'DiffusionPullEventGarbageCollector' => 'PhabricatorGarbageCollector',
|
'DiffusionPullEventGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
|
'DiffusionPullLogListController' => 'DiffusionLogController',
|
||||||
|
'DiffusionPullLogListView' => 'AphrontView',
|
||||||
|
'DiffusionPullLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'DiffusionPushCapability' => 'PhabricatorPolicyCapability',
|
'DiffusionPushCapability' => 'PhabricatorPolicyCapability',
|
||||||
'DiffusionPushEventViewController' => 'DiffusionPushLogController',
|
'DiffusionPushEventViewController' => 'DiffusionLogController',
|
||||||
'DiffusionPushLogController' => 'DiffusionController',
|
'DiffusionPushLogListController' => 'DiffusionLogController',
|
||||||
'DiffusionPushLogListController' => 'DiffusionPushLogController',
|
|
||||||
'DiffusionPushLogListView' => 'AphrontView',
|
'DiffusionPushLogListView' => 'AphrontView',
|
||||||
'DiffusionPythonExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
|
'DiffusionPythonExternalSymbolsSource' => 'DiffusionExternalSymbolsSource',
|
||||||
'DiffusionQuery' => 'PhabricatorQuery',
|
'DiffusionQuery' => 'PhabricatorQuery',
|
||||||
|
@ -6516,7 +6572,9 @@ phutil_register_library_map(array(
|
||||||
'HeraldConditionTranscript' => 'Phobject',
|
'HeraldConditionTranscript' => 'Phobject',
|
||||||
'HeraldContentSourceField' => 'HeraldField',
|
'HeraldContentSourceField' => 'HeraldField',
|
||||||
'HeraldController' => 'PhabricatorController',
|
'HeraldController' => 'PhabricatorController',
|
||||||
|
'HeraldCoreStateReasons' => 'HeraldStateReasons',
|
||||||
'HeraldDAO' => 'PhabricatorLiskDAO',
|
'HeraldDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'HeraldDeprecatedFieldGroup' => 'HeraldFieldGroup',
|
||||||
'HeraldDifferentialAdapter' => 'HeraldAdapter',
|
'HeraldDifferentialAdapter' => 'HeraldAdapter',
|
||||||
'HeraldDifferentialDiffAdapter' => 'HeraldDifferentialAdapter',
|
'HeraldDifferentialDiffAdapter' => 'HeraldDifferentialAdapter',
|
||||||
'HeraldDifferentialRevisionAdapter' => array(
|
'HeraldDifferentialRevisionAdapter' => array(
|
||||||
|
@ -6557,7 +6615,6 @@ phutil_register_library_map(array(
|
||||||
'HeraldRelatedFieldGroup' => 'HeraldFieldGroup',
|
'HeraldRelatedFieldGroup' => 'HeraldFieldGroup',
|
||||||
'HeraldRemarkupFieldValue' => 'HeraldFieldValue',
|
'HeraldRemarkupFieldValue' => 'HeraldFieldValue',
|
||||||
'HeraldRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
'HeraldRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||||
'HeraldRepetitionPolicyConfig' => 'Phobject',
|
|
||||||
'HeraldRule' => array(
|
'HeraldRule' => array(
|
||||||
'HeraldDAO',
|
'HeraldDAO',
|
||||||
'PhabricatorApplicationTransactionInterface',
|
'PhabricatorApplicationTransactionInterface',
|
||||||
|
@ -6678,8 +6735,8 @@ phutil_register_library_map(array(
|
||||||
'MacroQueryConduitAPIMethod' => 'MacroConduitAPIMethod',
|
'MacroQueryConduitAPIMethod' => 'MacroConduitAPIMethod',
|
||||||
'ManiphestAssignEmailCommand' => 'ManiphestEmailCommand',
|
'ManiphestAssignEmailCommand' => 'ManiphestEmailCommand',
|
||||||
'ManiphestAssigneeDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
'ManiphestAssigneeDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||||
'ManiphestBatchEditController' => 'ManiphestController',
|
|
||||||
'ManiphestBulkEditCapability' => 'PhabricatorPolicyCapability',
|
'ManiphestBulkEditCapability' => 'PhabricatorPolicyCapability',
|
||||||
|
'ManiphestBulkEditController' => 'ManiphestController',
|
||||||
'ManiphestClaimEmailCommand' => 'ManiphestEmailCommand',
|
'ManiphestClaimEmailCommand' => 'ManiphestEmailCommand',
|
||||||
'ManiphestCloseEmailCommand' => 'ManiphestEmailCommand',
|
'ManiphestCloseEmailCommand' => 'ManiphestEmailCommand',
|
||||||
'ManiphestConduitAPIMethod' => 'ConduitAPIMethod',
|
'ManiphestConduitAPIMethod' => 'ConduitAPIMethod',
|
||||||
|
@ -6761,6 +6818,7 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskAttachTransaction' => 'ManiphestTaskTransactionType',
|
'ManiphestTaskAttachTransaction' => 'ManiphestTaskTransactionType',
|
||||||
'ManiphestTaskAuthorHeraldField' => 'ManiphestTaskHeraldField',
|
'ManiphestTaskAuthorHeraldField' => 'ManiphestTaskHeraldField',
|
||||||
'ManiphestTaskAuthorPolicyRule' => 'PhabricatorPolicyRule',
|
'ManiphestTaskAuthorPolicyRule' => 'PhabricatorPolicyRule',
|
||||||
|
'ManiphestTaskBulkEngine' => 'PhabricatorBulkEngine',
|
||||||
'ManiphestTaskCloseAsDuplicateRelationship' => 'ManiphestTaskRelationship',
|
'ManiphestTaskCloseAsDuplicateRelationship' => 'ManiphestTaskRelationship',
|
||||||
'ManiphestTaskClosedStatusDatasource' => 'PhabricatorTypeaheadDatasource',
|
'ManiphestTaskClosedStatusDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||||
'ManiphestTaskCoverImageTransaction' => 'ManiphestTaskTransactionType',
|
'ManiphestTaskCoverImageTransaction' => 'ManiphestTaskTransactionType',
|
||||||
|
@ -6770,7 +6828,6 @@ phutil_register_library_map(array(
|
||||||
'ManiphestTaskDescriptionTransaction' => 'ManiphestTaskTransactionType',
|
'ManiphestTaskDescriptionTransaction' => 'ManiphestTaskTransactionType',
|
||||||
'ManiphestTaskDetailController' => 'ManiphestController',
|
'ManiphestTaskDetailController' => 'ManiphestController',
|
||||||
'ManiphestTaskEdgeTransaction' => 'ManiphestTaskTransactionType',
|
'ManiphestTaskEdgeTransaction' => 'ManiphestTaskTransactionType',
|
||||||
'ManiphestTaskEditBulkJobType' => 'PhabricatorWorkerBulkJobType',
|
|
||||||
'ManiphestTaskEditController' => 'ManiphestController',
|
'ManiphestTaskEditController' => 'ManiphestController',
|
||||||
'ManiphestTaskEditEngineLock' => 'PhabricatorEditEngineLock',
|
'ManiphestTaskEditEngineLock' => 'PhabricatorEditEngineLock',
|
||||||
'ManiphestTaskFerretEngine' => 'PhabricatorFerretEngine',
|
'ManiphestTaskFerretEngine' => 'PhabricatorFerretEngine',
|
||||||
|
@ -7284,6 +7341,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthApplication' => 'PhabricatorApplication',
|
'PhabricatorAuthApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorAuthAuthFactorPHIDType' => 'PhabricatorPHIDType',
|
'PhabricatorAuthAuthFactorPHIDType' => 'PhabricatorPHIDType',
|
||||||
'PhabricatorAuthAuthProviderPHIDType' => 'PhabricatorPHIDType',
|
'PhabricatorAuthAuthProviderPHIDType' => 'PhabricatorPHIDType',
|
||||||
|
'PhabricatorAuthChangePasswordAction' => 'PhabricatorSystemAction',
|
||||||
'PhabricatorAuthConduitAPIMethod' => 'ConduitAPIMethod',
|
'PhabricatorAuthConduitAPIMethod' => 'ConduitAPIMethod',
|
||||||
'PhabricatorAuthConduitTokenRevoker' => 'PhabricatorAuthRevoker',
|
'PhabricatorAuthConduitTokenRevoker' => 'PhabricatorAuthRevoker',
|
||||||
'PhabricatorAuthConfirmLinkController' => 'PhabricatorAuthController',
|
'PhabricatorAuthConfirmLinkController' => 'PhabricatorAuthController',
|
||||||
|
@ -7343,7 +7401,25 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
|
'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthOneTimeLoginController' => 'PhabricatorAuthController',
|
'PhabricatorAuthOneTimeLoginController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
|
'PhabricatorAuthPassword' => array(
|
||||||
|
'PhabricatorAuthDAO',
|
||||||
|
'PhabricatorPolicyInterface',
|
||||||
|
'PhabricatorDestructibleInterface',
|
||||||
|
'PhabricatorApplicationTransactionInterface',
|
||||||
|
),
|
||||||
|
'PhabricatorAuthPasswordEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
|
'PhabricatorAuthPasswordEngine' => 'Phobject',
|
||||||
|
'PhabricatorAuthPasswordException' => 'Exception',
|
||||||
|
'PhabricatorAuthPasswordPHIDType' => 'PhabricatorPHIDType',
|
||||||
|
'PhabricatorAuthPasswordQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
|
'PhabricatorAuthPasswordRevokeTransaction' => 'PhabricatorAuthPasswordTransactionType',
|
||||||
|
'PhabricatorAuthPasswordRevoker' => 'PhabricatorAuthRevoker',
|
||||||
|
'PhabricatorAuthPasswordTestCase' => 'PhabricatorTestCase',
|
||||||
|
'PhabricatorAuthPasswordTransaction' => 'PhabricatorModularTransaction',
|
||||||
|
'PhabricatorAuthPasswordTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
|
'PhabricatorAuthPasswordTransactionType' => 'PhabricatorModularTransactionType',
|
||||||
|
'PhabricatorAuthPasswordUpgradeTransaction' => 'PhabricatorAuthPasswordTransactionType',
|
||||||
'PhabricatorAuthProvider' => 'Phobject',
|
'PhabricatorAuthProvider' => 'Phobject',
|
||||||
'PhabricatorAuthProviderConfig' => array(
|
'PhabricatorAuthProviderConfig' => array(
|
||||||
'PhabricatorAuthDAO',
|
'PhabricatorAuthDAO',
|
||||||
|
@ -7368,7 +7444,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationTransactionInterface',
|
'PhabricatorApplicationTransactionInterface',
|
||||||
),
|
),
|
||||||
'PhabricatorAuthSSHKeyController' => 'PhabricatorAuthController',
|
'PhabricatorAuthSSHKeyController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthSSHKeyDeactivateController' => 'PhabricatorAuthSSHKeyController',
|
|
||||||
'PhabricatorAuthSSHKeyEditController' => 'PhabricatorAuthSSHKeyController',
|
'PhabricatorAuthSSHKeyEditController' => 'PhabricatorAuthSSHKeyController',
|
||||||
'PhabricatorAuthSSHKeyEditor' => 'PhabricatorApplicationTransactionEditor',
|
'PhabricatorAuthSSHKeyEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
'PhabricatorAuthSSHKeyGenerateController' => 'PhabricatorAuthSSHKeyController',
|
'PhabricatorAuthSSHKeyGenerateController' => 'PhabricatorAuthSSHKeyController',
|
||||||
|
@ -7376,12 +7451,15 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSSHKeyPHIDType' => 'PhabricatorPHIDType',
|
'PhabricatorAuthSSHKeyPHIDType' => 'PhabricatorPHIDType',
|
||||||
'PhabricatorAuthSSHKeyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorAuthSSHKeyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorAuthSSHKeyReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
'PhabricatorAuthSSHKeyReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||||
|
'PhabricatorAuthSSHKeyRevokeController' => 'PhabricatorAuthSSHKeyController',
|
||||||
'PhabricatorAuthSSHKeySearchEngine' => 'PhabricatorApplicationSearchEngine',
|
'PhabricatorAuthSSHKeySearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhabricatorAuthSSHKeyTableView' => 'AphrontView',
|
'PhabricatorAuthSSHKeyTableView' => 'AphrontView',
|
||||||
|
'PhabricatorAuthSSHKeyTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorAuthSSHKeyTransaction' => 'PhabricatorApplicationTransaction',
|
'PhabricatorAuthSSHKeyTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
'PhabricatorAuthSSHKeyTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'PhabricatorAuthSSHKeyTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'PhabricatorAuthSSHKeyViewController' => 'PhabricatorAuthSSHKeyController',
|
'PhabricatorAuthSSHKeyViewController' => 'PhabricatorAuthSSHKeyController',
|
||||||
'PhabricatorAuthSSHPublicKey' => 'Phobject',
|
'PhabricatorAuthSSHPublicKey' => 'Phobject',
|
||||||
|
'PhabricatorAuthSSHRevoker' => 'PhabricatorAuthRevoker',
|
||||||
'PhabricatorAuthSession' => array(
|
'PhabricatorAuthSession' => array(
|
||||||
'PhabricatorAuthDAO',
|
'PhabricatorAuthDAO',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
|
@ -7392,6 +7470,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSessionGarbageCollector' => 'PhabricatorGarbageCollector',
|
'PhabricatorAuthSessionGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorAuthSessionInfo' => 'Phobject',
|
'PhabricatorAuthSessionInfo' => 'Phobject',
|
||||||
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorAuthSessionRevoker' => 'PhabricatorAuthRevoker',
|
||||||
'PhabricatorAuthSetPasswordController' => 'PhabricatorAuthController',
|
'PhabricatorAuthSetPasswordController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
||||||
|
@ -7402,6 +7481,7 @@ phutil_register_library_map(array(
|
||||||
),
|
),
|
||||||
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
|
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorAuthTemporaryTokenRevoker' => 'PhabricatorAuthRevoker',
|
||||||
'PhabricatorAuthTemporaryTokenType' => 'Phobject',
|
'PhabricatorAuthTemporaryTokenType' => 'Phobject',
|
||||||
'PhabricatorAuthTemporaryTokenTypeModule' => 'PhabricatorConfigModule',
|
'PhabricatorAuthTemporaryTokenTypeModule' => 'PhabricatorConfigModule',
|
||||||
'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
|
'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
|
||||||
|
@ -7487,6 +7567,11 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorBuiltinFileCachePurger' => 'PhabricatorCachePurger',
|
'PhabricatorBuiltinFileCachePurger' => 'PhabricatorCachePurger',
|
||||||
'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
|
'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
|
||||||
'PhabricatorBulkContentSource' => 'PhabricatorContentSource',
|
'PhabricatorBulkContentSource' => 'PhabricatorContentSource',
|
||||||
|
'PhabricatorBulkEditGroup' => 'Phobject',
|
||||||
|
'PhabricatorBulkEngine' => 'Phobject',
|
||||||
|
'PhabricatorBulkManagementMakeSilentWorkflow' => 'PhabricatorBulkManagementWorkflow',
|
||||||
|
'PhabricatorBulkManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
|
'PhabricatorCSVExportFormat' => 'PhabricatorExportFormat',
|
||||||
'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorCacheEngine' => 'Phobject',
|
'PhabricatorCacheEngine' => 'Phobject',
|
||||||
'PhabricatorCacheEngineExtension' => 'Phobject',
|
'PhabricatorCacheEngineExtension' => 'Phobject',
|
||||||
|
@ -8106,6 +8191,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
'PhabricatorEditEngineAPIMethod' => 'ConduitAPIMethod',
|
'PhabricatorEditEngineAPIMethod' => 'ConduitAPIMethod',
|
||||||
|
'PhabricatorEditEngineBulkJobType' => 'PhabricatorWorkerBulkJobType',
|
||||||
'PhabricatorEditEngineCheckboxesCommentAction' => 'PhabricatorEditEngineCommentAction',
|
'PhabricatorEditEngineCheckboxesCommentAction' => 'PhabricatorEditEngineCommentAction',
|
||||||
'PhabricatorEditEngineColumnsCommentAction' => 'PhabricatorEditEngineCommentAction',
|
'PhabricatorEditEngineColumnsCommentAction' => 'PhabricatorEditEngineCommentAction',
|
||||||
'PhabricatorEditEngineCommentAction' => 'Phobject',
|
'PhabricatorEditEngineCommentAction' => 'Phobject',
|
||||||
|
@ -8182,12 +8268,15 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorEnv' => 'Phobject',
|
'PhabricatorEnv' => 'Phobject',
|
||||||
'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
|
'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorEpochEditField' => 'PhabricatorEditField',
|
'PhabricatorEpochEditField' => 'PhabricatorEditField',
|
||||||
|
'PhabricatorEpochExportField' => 'PhabricatorExportField',
|
||||||
'PhabricatorEvent' => 'PhutilEvent',
|
'PhabricatorEvent' => 'PhutilEvent',
|
||||||
'PhabricatorEventEngine' => 'Phobject',
|
'PhabricatorEventEngine' => 'Phobject',
|
||||||
'PhabricatorEventListener' => 'PhutilEventListener',
|
'PhabricatorEventListener' => 'PhutilEventListener',
|
||||||
'PhabricatorEventType' => 'PhutilEventType',
|
'PhabricatorEventType' => 'PhutilEventType',
|
||||||
'PhabricatorExampleEventListener' => 'PhabricatorEventListener',
|
'PhabricatorExampleEventListener' => 'PhabricatorEventListener',
|
||||||
'PhabricatorExecFutureFileUploadSource' => 'PhabricatorFileUploadSource',
|
'PhabricatorExecFutureFileUploadSource' => 'PhabricatorFileUploadSource',
|
||||||
|
'PhabricatorExportField' => 'Phobject',
|
||||||
|
'PhabricatorExportFormat' => 'Phobject',
|
||||||
'PhabricatorExtendingPhabricatorConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorExtendingPhabricatorConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorExtensionsSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorExtensionsSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorExternalAccount' => array(
|
'PhabricatorExternalAccount' => array(
|
||||||
|
@ -8340,6 +8429,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFileUploadDialogController' => 'PhabricatorFileController',
|
'PhabricatorFileUploadDialogController' => 'PhabricatorFileController',
|
||||||
'PhabricatorFileUploadException' => 'Exception',
|
'PhabricatorFileUploadException' => 'Exception',
|
||||||
'PhabricatorFileUploadSource' => 'Phobject',
|
'PhabricatorFileUploadSource' => 'Phobject',
|
||||||
|
'PhabricatorFileUploadSourceByteLimitException' => 'Exception',
|
||||||
'PhabricatorFileinfoSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorFileinfoSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorFilesApplication' => 'PhabricatorApplication',
|
'PhabricatorFilesApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorFilesApplicationStorageEnginePanel' => 'PhabricatorApplicationConfigurationPanel',
|
'PhabricatorFilesApplicationStorageEnginePanel' => 'PhabricatorApplicationConfigurationPanel',
|
||||||
|
@ -8447,6 +8537,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorHomeProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
'PhabricatorHomeProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||||
'PhabricatorHovercardEngineExtension' => 'Phobject',
|
'PhabricatorHovercardEngineExtension' => 'Phobject',
|
||||||
'PhabricatorHovercardEngineExtensionModule' => 'PhabricatorConfigModule',
|
'PhabricatorHovercardEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||||
|
'PhabricatorIDExportField' => 'PhabricatorExportField',
|
||||||
'PhabricatorIDsSearchEngineExtension' => 'PhabricatorSearchEngineExtension',
|
'PhabricatorIDsSearchEngineExtension' => 'PhabricatorSearchEngineExtension',
|
||||||
'PhabricatorIDsSearchField' => 'PhabricatorSearchField',
|
'PhabricatorIDsSearchField' => 'PhabricatorSearchField',
|
||||||
'PhabricatorIconDatasource' => 'PhabricatorTypeaheadDatasource',
|
'PhabricatorIconDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||||
|
@ -8469,6 +8560,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorInlineSummaryView' => 'AphrontView',
|
'PhabricatorInlineSummaryView' => 'AphrontView',
|
||||||
'PhabricatorInstructionsEditField' => 'PhabricatorEditField',
|
'PhabricatorInstructionsEditField' => 'PhabricatorEditField',
|
||||||
'PhabricatorIntConfigType' => 'PhabricatorTextConfigType',
|
'PhabricatorIntConfigType' => 'PhabricatorTextConfigType',
|
||||||
|
'PhabricatorIntExportField' => 'PhabricatorExportField',
|
||||||
'PhabricatorInternalSetting' => 'PhabricatorSetting',
|
'PhabricatorInternalSetting' => 'PhabricatorSetting',
|
||||||
'PhabricatorInternationalizationManagementExtractWorkflow' => 'PhabricatorInternationalizationManagementWorkflow',
|
'PhabricatorInternationalizationManagementExtractWorkflow' => 'PhabricatorInternationalizationManagementWorkflow',
|
||||||
'PhabricatorInternationalizationManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorInternationalizationManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
|
@ -8478,6 +8570,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorIteratorFileUploadSource' => 'PhabricatorFileUploadSource',
|
'PhabricatorIteratorFileUploadSource' => 'PhabricatorFileUploadSource',
|
||||||
'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider',
|
'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider',
|
||||||
'PhabricatorJSONConfigType' => 'PhabricatorTextConfigType',
|
'PhabricatorJSONConfigType' => 'PhabricatorTextConfigType',
|
||||||
|
'PhabricatorJSONExportFormat' => 'PhabricatorExportFormat',
|
||||||
'PhabricatorJavelinLinter' => 'ArcanistLinter',
|
'PhabricatorJavelinLinter' => 'ArcanistLinter',
|
||||||
'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType',
|
'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType',
|
||||||
'PhabricatorJumpNavHandler' => 'Phobject',
|
'PhabricatorJumpNavHandler' => 'Phobject',
|
||||||
|
@ -8837,6 +8930,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorPHID' => 'Phobject',
|
'PhabricatorPHID' => 'Phobject',
|
||||||
'PhabricatorPHIDConstants' => 'Phobject',
|
'PhabricatorPHIDConstants' => 'Phobject',
|
||||||
|
'PhabricatorPHIDExportField' => 'PhabricatorExportField',
|
||||||
'PhabricatorPHIDListEditField' => 'PhabricatorEditField',
|
'PhabricatorPHIDListEditField' => 'PhabricatorEditField',
|
||||||
'PhabricatorPHIDListEditType' => 'PhabricatorEditType',
|
'PhabricatorPHIDListEditType' => 'PhabricatorEditType',
|
||||||
'PhabricatorPHIDResolver' => 'Phobject',
|
'PhabricatorPHIDResolver' => 'Phobject',
|
||||||
|
@ -8952,6 +9046,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPagerUIExample' => 'PhabricatorUIExample',
|
'PhabricatorPagerUIExample' => 'PhabricatorUIExample',
|
||||||
'PhabricatorPassphraseApplication' => 'PhabricatorApplication',
|
'PhabricatorPassphraseApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorPasswordAuthProvider' => 'PhabricatorAuthProvider',
|
'PhabricatorPasswordAuthProvider' => 'PhabricatorAuthProvider',
|
||||||
|
'PhabricatorPasswordDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
||||||
'PhabricatorPasswordHasher' => 'Phobject',
|
'PhabricatorPasswordHasher' => 'Phobject',
|
||||||
'PhabricatorPasswordHasherTestCase' => 'PhabricatorTestCase',
|
'PhabricatorPasswordHasherTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorPasswordHasherUnavailableException' => 'Exception',
|
'PhabricatorPasswordHasherUnavailableException' => 'Exception',
|
||||||
|
@ -9530,7 +9625,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
|
'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction',
|
'PhabricatorRepositoryURITransaction' => 'PhabricatorApplicationTransaction',
|
||||||
'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'PhabricatorRepositoryURITransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO',
|
|
||||||
'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO',
|
'PhabricatorRepositoryWorkingCopyVersion' => 'PhabricatorRepositoryDAO',
|
||||||
'PhabricatorRequestExceptionHandler' => 'AphrontRequestExceptionHandler',
|
'PhabricatorRequestExceptionHandler' => 'AphrontRequestExceptionHandler',
|
||||||
'PhabricatorResourceSite' => 'PhabricatorSite',
|
'PhabricatorResourceSite' => 'PhabricatorSite',
|
||||||
|
@ -9554,7 +9648,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSSHKeysSettingsPanel' => 'PhabricatorSettingsPanel',
|
'PhabricatorSSHKeysSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||||
'PhabricatorSSHLog' => 'Phobject',
|
'PhabricatorSSHLog' => 'Phobject',
|
||||||
'PhabricatorSSHPassthruCommand' => 'Phobject',
|
'PhabricatorSSHPassthruCommand' => 'Phobject',
|
||||||
'PhabricatorSSHWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorSSHWorkflow' => 'PhutilArgumentWorkflow',
|
||||||
'PhabricatorSavedQuery' => array(
|
'PhabricatorSavedQuery' => array(
|
||||||
'PhabricatorSearchDAO',
|
'PhabricatorSearchDAO',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
|
@ -9776,6 +9870,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorStorageSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
'PhabricatorStorageSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||||
'PhabricatorStorageSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorStorageSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorStringConfigType' => 'PhabricatorTextConfigType',
|
'PhabricatorStringConfigType' => 'PhabricatorTextConfigType',
|
||||||
|
'PhabricatorStringExportField' => 'PhabricatorExportField',
|
||||||
'PhabricatorStringListConfigType' => 'PhabricatorTextListConfigType',
|
'PhabricatorStringListConfigType' => 'PhabricatorTextListConfigType',
|
||||||
'PhabricatorStringListEditField' => 'PhabricatorEditField',
|
'PhabricatorStringListEditField' => 'PhabricatorEditField',
|
||||||
'PhabricatorStringSetting' => 'PhabricatorSetting',
|
'PhabricatorStringSetting' => 'PhabricatorSetting',
|
||||||
|
@ -9838,6 +9933,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorTextAreaEditField' => 'PhabricatorEditField',
|
'PhabricatorTextAreaEditField' => 'PhabricatorEditField',
|
||||||
'PhabricatorTextConfigType' => 'PhabricatorConfigType',
|
'PhabricatorTextConfigType' => 'PhabricatorConfigType',
|
||||||
'PhabricatorTextEditField' => 'PhabricatorEditField',
|
'PhabricatorTextEditField' => 'PhabricatorEditField',
|
||||||
|
'PhabricatorTextExportFormat' => 'PhabricatorExportFormat',
|
||||||
'PhabricatorTextListConfigType' => 'PhabricatorTextConfigType',
|
'PhabricatorTextListConfigType' => 'PhabricatorTextConfigType',
|
||||||
'PhabricatorTime' => 'Phobject',
|
'PhabricatorTime' => 'Phobject',
|
||||||
'PhabricatorTimeFormatSetting' => 'PhabricatorSelectSetting',
|
'PhabricatorTimeFormatSetting' => 'PhabricatorSelectSetting',
|
||||||
|
@ -9931,6 +10027,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFulltextInterface',
|
'PhabricatorFulltextInterface',
|
||||||
'PhabricatorFerretInterface',
|
'PhabricatorFerretInterface',
|
||||||
'PhabricatorConduitResultInterface',
|
'PhabricatorConduitResultInterface',
|
||||||
|
'PhabricatorAuthPasswordHashInterface',
|
||||||
),
|
),
|
||||||
'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType',
|
'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType',
|
||||||
'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField',
|
'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField',
|
||||||
|
|
|
@ -0,0 +1,208 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordTestCase extends PhabricatorTestCase {
|
||||||
|
|
||||||
|
protected function getPhabricatorTestCaseConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCompare() {
|
||||||
|
$password1 = new PhutilOpaqueEnvelope('hunter2');
|
||||||
|
$password2 = new PhutilOpaqueEnvelope('hunter3');
|
||||||
|
|
||||||
|
$user = $this->generateNewTestUser();
|
||||||
|
$type = PhabricatorAuthPassword::PASSWORD_TYPE_TEST;
|
||||||
|
|
||||||
|
$pass = PhabricatorAuthPassword::initializeNewPassword($user, $type)
|
||||||
|
->setPassword($password1, $user)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$pass->comparePassword($password1, $user),
|
||||||
|
pht('Good password should match.'));
|
||||||
|
|
||||||
|
$this->assertFalse(
|
||||||
|
$pass->comparePassword($password2, $user),
|
||||||
|
pht('Bad password should not match.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPasswordEngine() {
|
||||||
|
$password1 = new PhutilOpaqueEnvelope('the quick');
|
||||||
|
$password2 = new PhutilOpaqueEnvelope('brown fox');
|
||||||
|
|
||||||
|
$user = $this->generateNewTestUser();
|
||||||
|
$test_type = PhabricatorAuthPassword::PASSWORD_TYPE_TEST;
|
||||||
|
$account_type = PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT;
|
||||||
|
$content_source = $this->newContentSource();
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
|
->setViewer($user)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setPasswordType($test_type)
|
||||||
|
->setObject($user);
|
||||||
|
|
||||||
|
$account_engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
|
->setViewer($user)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setPasswordType($account_type)
|
||||||
|
->setObject($user);
|
||||||
|
|
||||||
|
// We haven't set any passwords yet, so both passwords should be
|
||||||
|
// invalid.
|
||||||
|
$this->assertFalse($engine->isValidPassword($password1));
|
||||||
|
$this->assertFalse($engine->isValidPassword($password2));
|
||||||
|
|
||||||
|
$pass = PhabricatorAuthPassword::initializeNewPassword($user, $test_type)
|
||||||
|
->setPassword($password1, $user)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
// The password should now be valid.
|
||||||
|
$this->assertTrue($engine->isValidPassword($password1));
|
||||||
|
$this->assertFalse($engine->isValidPassword($password2));
|
||||||
|
|
||||||
|
// But, since the password is a "test" password, it should not be a valid
|
||||||
|
// "account" password.
|
||||||
|
$this->assertFalse($account_engine->isValidPassword($password1));
|
||||||
|
$this->assertFalse($account_engine->isValidPassword($password2));
|
||||||
|
|
||||||
|
// Both passwords are unique for the "test" engine, since an active
|
||||||
|
// password of a given type doesn't collide with itself.
|
||||||
|
$this->assertTrue($engine->isUniquePassword($password1));
|
||||||
|
$this->assertTrue($engine->isUniquePassword($password2));
|
||||||
|
|
||||||
|
// The "test" password is no longer unique for the "account" engine.
|
||||||
|
$this->assertFalse($account_engine->isUniquePassword($password1));
|
||||||
|
$this->assertTrue($account_engine->isUniquePassword($password2));
|
||||||
|
|
||||||
|
$this->revokePassword($user, $pass);
|
||||||
|
|
||||||
|
// Now that we've revoked the password, it should no longer be valid.
|
||||||
|
$this->assertFalse($engine->isValidPassword($password1));
|
||||||
|
$this->assertFalse($engine->isValidPassword($password2));
|
||||||
|
|
||||||
|
// But it should be a revoked password.
|
||||||
|
$this->assertTrue($engine->isRevokedPassword($password1));
|
||||||
|
$this->assertFalse($engine->isRevokedPassword($password2));
|
||||||
|
|
||||||
|
// It should be revoked for both roles: revoking a "test" password also
|
||||||
|
// prevents you from choosing it as a new "account" password.
|
||||||
|
$this->assertTrue($account_engine->isRevokedPassword($password1));
|
||||||
|
$this->assertFalse($account_engine->isValidPassword($password2));
|
||||||
|
|
||||||
|
// The revoked password makes this password non-unique for all account
|
||||||
|
// types.
|
||||||
|
$this->assertFalse($engine->isUniquePassword($password1));
|
||||||
|
$this->assertTrue($engine->isUniquePassword($password2));
|
||||||
|
$this->assertFalse($account_engine->isUniquePassword($password1));
|
||||||
|
$this->assertTrue($account_engine->isUniquePassword($password2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPasswordUpgrade() {
|
||||||
|
$weak_hasher = new PhabricatorIteratedMD5PasswordHasher();
|
||||||
|
|
||||||
|
// Make sure we have two different hashers, and that the second one is
|
||||||
|
// stronger than iterated MD5. The most common reason this would fail is
|
||||||
|
// if an install does not have bcrypt available.
|
||||||
|
$strong_hasher = PhabricatorPasswordHasher::getBestHasher();
|
||||||
|
if ($strong_hasher->getStrength() <= $weak_hasher->getStrength()) {
|
||||||
|
$this->assertSkipped(
|
||||||
|
pht(
|
||||||
|
'Multiple password hashers of different strengths are not '.
|
||||||
|
'available, so hash upgrading can not be tested.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$envelope = new PhutilOpaqueEnvelope('lunar1997');
|
||||||
|
|
||||||
|
$user = $this->generateNewTestUser();
|
||||||
|
$type = PhabricatorAuthPassword::PASSWORD_TYPE_TEST;
|
||||||
|
$content_source = $this->newContentSource();
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
|
->setViewer($user)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setPasswordType($type)
|
||||||
|
->setObject($user);
|
||||||
|
|
||||||
|
$password = PhabricatorAuthPassword::initializeNewPassword($user, $type)
|
||||||
|
->setPasswordWithHasher($envelope, $user, $weak_hasher)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
$weak_name = $weak_hasher->getHashName();
|
||||||
|
$strong_name = $strong_hasher->getHashName();
|
||||||
|
|
||||||
|
// Since we explicitly used the weak hasher, the password should have
|
||||||
|
// been hashed with it.
|
||||||
|
$actual_hasher = $password->getHasher();
|
||||||
|
$this->assertEqual($weak_name, $actual_hasher->getHashName());
|
||||||
|
|
||||||
|
$is_valid = $engine
|
||||||
|
->setUpgradeHashers(false)
|
||||||
|
->isValidPassword($envelope, $user);
|
||||||
|
$password->reload();
|
||||||
|
|
||||||
|
// Since we disabled hasher upgrading, the password should not have been
|
||||||
|
// rehashed.
|
||||||
|
$this->assertTrue($is_valid);
|
||||||
|
$actual_hasher = $password->getHasher();
|
||||||
|
$this->assertEqual($weak_name, $actual_hasher->getHashName());
|
||||||
|
|
||||||
|
$is_valid = $engine
|
||||||
|
->setUpgradeHashers(true)
|
||||||
|
->isValidPassword($envelope, $user);
|
||||||
|
$password->reload();
|
||||||
|
|
||||||
|
// Now that we enabled hasher upgrading, the password should have been
|
||||||
|
// automatically rehashed into the stronger format.
|
||||||
|
$this->assertTrue($is_valid);
|
||||||
|
$actual_hasher = $password->getHasher();
|
||||||
|
$this->assertEqual($strong_name, $actual_hasher->getHashName());
|
||||||
|
|
||||||
|
// We should also have an "upgrade" transaction in the transaction record
|
||||||
|
// now which records the two hasher names.
|
||||||
|
$xactions = id(new PhabricatorAuthPasswordTransactionQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->withObjectPHIDs(array($password->getPHID()))
|
||||||
|
->withTransactionTypes(
|
||||||
|
array(
|
||||||
|
PhabricatorAuthPasswordUpgradeTransaction::TRANSACTIONTYPE,
|
||||||
|
))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$this->assertEqual(1, count($xactions));
|
||||||
|
$xaction = head($xactions);
|
||||||
|
|
||||||
|
$this->assertEqual($weak_name, $xaction->getOldValue());
|
||||||
|
$this->assertEqual($strong_name, $xaction->getNewValue());
|
||||||
|
|
||||||
|
$is_valid = $engine
|
||||||
|
->isValidPassword($envelope, $user);
|
||||||
|
|
||||||
|
// Finally, the password should still be valid after all the dust has
|
||||||
|
// settled.
|
||||||
|
$this->assertTrue($is_valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function revokePassword(
|
||||||
|
PhabricatorUser $actor,
|
||||||
|
PhabricatorAuthPassword $password) {
|
||||||
|
|
||||||
|
$content_source = $this->newContentSource();
|
||||||
|
$revoke_type = PhabricatorAuthPasswordRevokeTransaction::TRANSACTIONTYPE;
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
|
||||||
|
$xactions[] = $password->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType($revoke_type)
|
||||||
|
->setNewValue(true);
|
||||||
|
|
||||||
|
$editor = $password->getApplicationTransactionEditor()
|
||||||
|
->setActor($actor)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->applyTransactions($password, $xactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthSSHKeyTestCase extends PhabricatorTestCase {
|
||||||
|
|
||||||
|
protected function getPhabricatorTestCaseConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRevokeSSHKey() {
|
||||||
|
$user = $this->generateNewTestUser();
|
||||||
|
$raw_key = 'ssh-rsa hunter2';
|
||||||
|
|
||||||
|
$ssh_key = PhabricatorAuthSSHKey::initializeNewSSHKey($user, $user);
|
||||||
|
|
||||||
|
// Add the key to the user's account.
|
||||||
|
$xactions = array();
|
||||||
|
$xactions[] = $ssh_key->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_NAME)
|
||||||
|
->setNewValue('key1');
|
||||||
|
$xactions[] = $ssh_key->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_KEY)
|
||||||
|
->setNewValue($raw_key);
|
||||||
|
$this->applyTransactions($user, $ssh_key, $xactions);
|
||||||
|
|
||||||
|
$ssh_key->reload();
|
||||||
|
$this->assertTrue((bool)$ssh_key->getIsActive());
|
||||||
|
|
||||||
|
// Revoke it.
|
||||||
|
$xactions = array();
|
||||||
|
$xactions[] = $ssh_key->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_DEACTIVATE)
|
||||||
|
->setNewValue(true);
|
||||||
|
$this->applyTransactions($user, $ssh_key, $xactions);
|
||||||
|
|
||||||
|
$ssh_key->reload();
|
||||||
|
$this->assertFalse((bool)$ssh_key->getIsActive());
|
||||||
|
|
||||||
|
// Try to add the revoked key back. This should fail with a validation
|
||||||
|
// error because the key was previously revoked by the user.
|
||||||
|
$revoked_key = PhabricatorAuthSSHKey::initializeNewSSHKey($user, $user);
|
||||||
|
$xactions = array();
|
||||||
|
$xactions[] = $ssh_key->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_NAME)
|
||||||
|
->setNewValue('key2');
|
||||||
|
$xactions[] = $ssh_key->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_KEY)
|
||||||
|
->setNewValue($raw_key);
|
||||||
|
|
||||||
|
$caught = null;
|
||||||
|
try {
|
||||||
|
$this->applyTransactions($user, $ssh_key, $xactions);
|
||||||
|
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||||
|
$errors = $ex->getErrors();
|
||||||
|
$this->assertEqual(1, count($errors));
|
||||||
|
$caught = head($errors)->getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEqual(PhabricatorAuthSSHKeyTransaction::TYPE_KEY, $caught);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function applyTransactions(
|
||||||
|
PhabricatorUser $actor,
|
||||||
|
PhabricatorAuthSSHKey $key,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$content_source = $this->newContentSource();
|
||||||
|
|
||||||
|
$editor = $key->getApplicationTransactionEditor()
|
||||||
|
->setActor($actor)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->applyTransactions($key, $xactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthChangePasswordAction
|
||||||
|
extends PhabricatorSystemAction {
|
||||||
|
|
||||||
|
const TYPECONST = 'auth.password';
|
||||||
|
|
||||||
|
public function getActionConstant() {
|
||||||
|
return self::TYPECONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScoreThreshold() {
|
||||||
|
return 20 / phutil_units('1 hour in seconds');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLimitExplanation() {
|
||||||
|
return pht(
|
||||||
|
'You have failed to enter the correct account password too often in '.
|
||||||
|
'a short period of time.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -80,8 +80,8 @@ final class PhabricatorAuthApplication extends PhabricatorApplication {
|
||||||
'generate/' => 'PhabricatorAuthSSHKeyGenerateController',
|
'generate/' => 'PhabricatorAuthSSHKeyGenerateController',
|
||||||
'upload/' => 'PhabricatorAuthSSHKeyEditController',
|
'upload/' => 'PhabricatorAuthSSHKeyEditController',
|
||||||
'edit/(?P<id>\d+)/' => 'PhabricatorAuthSSHKeyEditController',
|
'edit/(?P<id>\d+)/' => 'PhabricatorAuthSSHKeyEditController',
|
||||||
'deactivate/(?P<id>\d+)/'
|
'revoke/(?P<id>\d+)/'
|
||||||
=> 'PhabricatorAuthSSHKeyDeactivateController',
|
=> 'PhabricatorAuthSSHKeyRevokeController',
|
||||||
'view/(?P<id>\d+)/' => 'PhabricatorAuthSSHKeyViewController',
|
'view/(?P<id>\d+)/' => 'PhabricatorAuthSSHKeyViewController',
|
||||||
),
|
),
|
||||||
'password/' => 'PhabricatorAuthSetPasswordController',
|
'password/' => 'PhabricatorAuthSetPasswordController',
|
||||||
|
|
|
@ -61,6 +61,9 @@ final class PhabricatorAuthRegisterController
|
||||||
$default_username = $account->getUsername();
|
$default_username = $account->getUsername();
|
||||||
$default_realname = $account->getRealName();
|
$default_realname = $account->getRealName();
|
||||||
|
|
||||||
|
$account_type = PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT;
|
||||||
|
$content_source = PhabricatorContentSource::newFromRequest($request);
|
||||||
|
|
||||||
$default_email = $account->getEmail();
|
$default_email = $account->getEmail();
|
||||||
|
|
||||||
if ($invite) {
|
if ($invite) {
|
||||||
|
@ -285,27 +288,22 @@ final class PhabricatorAuthRegisterController
|
||||||
if ($must_set_password) {
|
if ($must_set_password) {
|
||||||
$value_password = $request->getStr('password');
|
$value_password = $request->getStr('password');
|
||||||
$value_confirm = $request->getStr('confirm');
|
$value_confirm = $request->getStr('confirm');
|
||||||
if (!strlen($value_password)) {
|
|
||||||
$e_password = pht('Required');
|
|
||||||
$errors[] = pht('You must choose a password.');
|
|
||||||
} else if ($value_password !== $value_confirm) {
|
|
||||||
$e_password = pht('No Match');
|
|
||||||
$errors[] = pht('Password and confirmation must match.');
|
|
||||||
} else if (strlen($value_password) < $min_len) {
|
|
||||||
$e_password = pht('Too Short');
|
|
||||||
$errors[] = pht(
|
|
||||||
'Password is too short (must be at least %d characters long).',
|
|
||||||
$min_len);
|
|
||||||
} else if (
|
|
||||||
PhabricatorCommonPasswords::isCommonPassword($value_password)) {
|
|
||||||
|
|
||||||
$e_password = pht('Very Weak');
|
$password_envelope = new PhutilOpaqueEnvelope($value_password);
|
||||||
$errors[] = pht(
|
$confirm_envelope = new PhutilOpaqueEnvelope($value_confirm);
|
||||||
'Password is pathologically weak. This password is one of the '.
|
|
||||||
'most common passwords in use, and is extremely easy for '.
|
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
'attackers to guess. You must choose a stronger password.');
|
->setViewer($user)
|
||||||
} else {
|
->setContentSource($content_source)
|
||||||
|
->setPasswordType($account_type)
|
||||||
|
->setObject($user);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$engine->checkNewPassword($password_envelope, $confirm_envelope);
|
||||||
$e_password = null;
|
$e_password = null;
|
||||||
|
} catch (PhabricatorAuthPasswordException $ex) {
|
||||||
|
$errors[] = $ex->getMessage();
|
||||||
|
$e_password = $ex->getPasswordError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,8 +406,13 @@ final class PhabricatorAuthRegisterController
|
||||||
|
|
||||||
$editor->createNewUser($user, $email_obj, $allow_reassign_email);
|
$editor->createNewUser($user, $email_obj, $allow_reassign_email);
|
||||||
if ($must_set_password) {
|
if ($must_set_password) {
|
||||||
$envelope = new PhutilOpaqueEnvelope($value_password);
|
$password_object = PhabricatorAuthPassword::initializeNewPassword(
|
||||||
$editor->changePassword($user, $envelope);
|
$user,
|
||||||
|
$account_type);
|
||||||
|
|
||||||
|
$password_object
|
||||||
|
->setPassword($password_envelope, $user)
|
||||||
|
->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($is_setup) {
|
if ($is_setup) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhabricatorAuthSSHKeyDeactivateController
|
final class PhabricatorAuthSSHKeyRevokeController
|
||||||
extends PhabricatorAuthSSHKeyController {
|
extends PhabricatorAuthSSHKeyController {
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
@ -46,14 +46,14 @@ final class PhabricatorAuthSSHKeyDeactivateController
|
||||||
$name = phutil_tag('strong', array(), $key->getName());
|
$name = phutil_tag('strong', array(), $key->getName());
|
||||||
|
|
||||||
return $this->newDialog()
|
return $this->newDialog()
|
||||||
->setTitle(pht('Deactivate SSH Public Key'))
|
->setTitle(pht('Revoke SSH Public Key'))
|
||||||
->appendParagraph(
|
->appendParagraph(
|
||||||
pht(
|
pht(
|
||||||
'The key "%s" will be permanently deactivated, and you will no '.
|
'The key "%s" will be permanently revoked, and you will no '.
|
||||||
'longer be able to use the corresponding private key to '.
|
'longer be able to use the corresponding private key to '.
|
||||||
'authenticate.',
|
'authenticate.',
|
||||||
$name))
|
$name))
|
||||||
->addSubmitButton(pht('Deactivate Public Key'))
|
->addSubmitButton(pht('Revoke Public Key'))
|
||||||
->addCancelButton($cancel_uri);
|
->addCancelButton($cancel_uri);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ final class PhabricatorAuthSSHKeyViewController
|
||||||
if ($ssh_key->getIsActive()) {
|
if ($ssh_key->getIsActive()) {
|
||||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||||
} else {
|
} else {
|
||||||
$header->setStatus('fa-ban', 'dark', pht('Deactivated'));
|
$header->setStatus('fa-ban', 'dark', pht('Revoked'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$header->addActionLink(
|
$header->addActionLink(
|
||||||
|
@ -80,7 +80,7 @@ final class PhabricatorAuthSSHKeyViewController
|
||||||
$id = $ssh_key->getID();
|
$id = $ssh_key->getID();
|
||||||
|
|
||||||
$edit_uri = $this->getApplicationURI("sshkey/edit/{$id}/");
|
$edit_uri = $this->getApplicationURI("sshkey/edit/{$id}/");
|
||||||
$deactivate_uri = $this->getApplicationURI("sshkey/deactivate/{$id}/");
|
$revoke_uri = $this->getApplicationURI("sshkey/revoke/{$id}/");
|
||||||
|
|
||||||
$curtain = $this->newCurtainView($ssh_key);
|
$curtain = $this->newCurtainView($ssh_key);
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ final class PhabricatorAuthSSHKeyViewController
|
||||||
$curtain->addAction(
|
$curtain->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setIcon('fa-times')
|
->setIcon('fa-times')
|
||||||
->setName(pht('Deactivate SSH Key'))
|
->setName(pht('Revoke SSH Key'))
|
||||||
->setHref($deactivate_uri)
|
->setHref($revoke_uri)
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_edit));
|
->setDisabled(!$can_edit));
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,30 @@ final class PhabricatorAuthSetPasswordController
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
|
$content_source = PhabricatorContentSource::newFromRequest($request);
|
||||||
$min_len = (int)$min_len;
|
$account_type = PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT;
|
||||||
|
|
||||||
|
$password_objects = id(new PhabricatorAuthPasswordQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withObjectPHIDs(array($viewer->getPHID()))
|
||||||
|
->withPasswordTypes(array($account_type))
|
||||||
|
->withIsRevoked(false)
|
||||||
|
->execute();
|
||||||
|
if ($password_objects) {
|
||||||
|
$password_object = head($password_objects);
|
||||||
|
$has_password = true;
|
||||||
|
} else {
|
||||||
|
$password_object = PhabricatorAuthPassword::initializeNewPassword(
|
||||||
|
$viewer,
|
||||||
|
$account_type);
|
||||||
|
$has_password = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setPasswordType($account_type)
|
||||||
|
->setObject($viewer);
|
||||||
|
|
||||||
$e_password = true;
|
$e_password = true;
|
||||||
$e_confirm = true;
|
$e_confirm = true;
|
||||||
|
@ -50,46 +72,23 @@ final class PhabricatorAuthSetPasswordController
|
||||||
$password = $request->getStr('password');
|
$password = $request->getStr('password');
|
||||||
$confirm = $request->getStr('confirm');
|
$confirm = $request->getStr('confirm');
|
||||||
|
|
||||||
|
$password_envelope = new PhutilOpaqueEnvelope($password);
|
||||||
|
$confirm_envelope = new PhutilOpaqueEnvelope($confirm);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$engine->checkNewPassword($password_envelope, $confirm_envelope, true);
|
||||||
$e_password = null;
|
$e_password = null;
|
||||||
$e_confirm = null;
|
$e_confirm = null;
|
||||||
|
} catch (PhabricatorAuthPasswordException $ex) {
|
||||||
if (!strlen($password)) {
|
$errors[] = $ex->getMessage();
|
||||||
$errors[] = pht('You must choose a password or skip this step.');
|
$e_password = $ex->getPasswordError();
|
||||||
$e_password = pht('Required');
|
$e_confirm = $ex->getConfirmError();
|
||||||
} else if (strlen($password) < $min_len) {
|
|
||||||
$errors[] = pht(
|
|
||||||
'The selected password is too short. Passwords must be a minimum '.
|
|
||||||
'of %s characters.',
|
|
||||||
new PhutilNumber($min_len));
|
|
||||||
$e_password = pht('Too Short');
|
|
||||||
} else if (!strlen($confirm)) {
|
|
||||||
$errors[] = pht('You must confirm the selecetd password.');
|
|
||||||
$e_confirm = pht('Required');
|
|
||||||
} else if ($password !== $confirm) {
|
|
||||||
$errors[] = pht('The password and confirmation do not match.');
|
|
||||||
$e_password = pht('Invalid');
|
|
||||||
$e_confirm = pht('Invalid');
|
|
||||||
} else if (PhabricatorCommonPasswords::isCommonPassword($password)) {
|
|
||||||
$e_password = pht('Very Weak');
|
|
||||||
$errors[] = pht(
|
|
||||||
'The selected password is very weak: it is one of the most common '.
|
|
||||||
'passwords in use. Choose a stronger password.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$envelope = new PhutilOpaqueEnvelope($password);
|
$password_object
|
||||||
|
->setPassword($password_envelope, $viewer)
|
||||||
// This write is unguarded because the CSRF token has already
|
->save();
|
||||||
// been checked in the call to $request->isFormPost() and
|
|
||||||
// the CSRF token depends on the password hash, so when it
|
|
||||||
// is changed here the CSRF token check will fail.
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
|
||||||
|
|
||||||
id(new PhabricatorUserEditor())
|
|
||||||
->setActor($viewer)
|
|
||||||
->changePassword($viewer, $envelope);
|
|
||||||
|
|
||||||
unset($unguarded);
|
|
||||||
|
|
||||||
// Destroy the token.
|
// Destroy the token.
|
||||||
$auth_token->delete();
|
$auth_token->delete();
|
||||||
|
@ -98,12 +97,15 @@ final class PhabricatorAuthSetPasswordController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
|
||||||
|
$min_len = (int)$min_len;
|
||||||
|
|
||||||
$len_caption = null;
|
$len_caption = null;
|
||||||
if ($min_len) {
|
if ($min_len) {
|
||||||
$len_caption = pht('Minimum password length: %d characters.', $min_len);
|
$len_caption = pht('Minimum password length: %d characters.', $min_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($viewer->hasPassword()) {
|
if ($has_password) {
|
||||||
$title = pht('Reset Password');
|
$title = pht('Reset Password');
|
||||||
$crumb = pht('Reset Password');
|
$crumb = pht('Reset Password');
|
||||||
$submit = pht('Reset Password');
|
$submit = pht('Reset Password');
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordEditor
|
||||||
|
extends PhabricatorApplicationTransactionEditor {
|
||||||
|
|
||||||
|
private $oldHasher;
|
||||||
|
|
||||||
|
public function setOldHasher(PhabricatorPasswordHasher $old_hasher) {
|
||||||
|
$this->oldHasher = $old_hasher;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOldHasher() {
|
||||||
|
return $this->oldHasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEditorApplicationClass() {
|
||||||
|
return 'PhabricatorAuthApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEditorObjectsDescription() {
|
||||||
|
return pht('Passwords');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreateObjectTitle($author, $object) {
|
||||||
|
return pht('%s created this password.', $author);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreateObjectTitleForFeed($author, $object) {
|
||||||
|
return pht('%s created %s.', $author, $object);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,17 @@
|
||||||
final class PhabricatorAuthSSHKeyEditor
|
final class PhabricatorAuthSSHKeyEditor
|
||||||
extends PhabricatorApplicationTransactionEditor {
|
extends PhabricatorApplicationTransactionEditor {
|
||||||
|
|
||||||
|
private $isAdministrativeEdit;
|
||||||
|
|
||||||
|
public function setIsAdministrativeEdit($is_administrative_edit) {
|
||||||
|
$this->isAdministrativeEdit = $is_administrative_edit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsAdministrativeEdit() {
|
||||||
|
return $this->isAdministrativeEdit;
|
||||||
|
}
|
||||||
|
|
||||||
public function getEditorApplicationClass() {
|
public function getEditorApplicationClass() {
|
||||||
return 'PhabricatorAuthApplication';
|
return 'PhabricatorAuthApplication';
|
||||||
}
|
}
|
||||||
|
@ -93,6 +104,7 @@ final class PhabricatorAuthSSHKeyEditor
|
||||||
array $xactions) {
|
array $xactions) {
|
||||||
|
|
||||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||||
|
$viewer = $this->requireActor();
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case PhabricatorAuthSSHKeyTransaction::TYPE_NAME:
|
case PhabricatorAuthSSHKeyTransaction::TYPE_NAME:
|
||||||
|
@ -138,6 +150,30 @@ final class PhabricatorAuthSSHKeyEditor
|
||||||
pht('Invalid'),
|
pht('Invalid'),
|
||||||
$ex->getMessage(),
|
$ex->getMessage(),
|
||||||
$xaction);
|
$xaction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The database does not have a unique key on just the <keyBody>
|
||||||
|
// column because we allow multiple accounts to revoke the same
|
||||||
|
// key, so we can't rely on database constraints to prevent users
|
||||||
|
// from adding keys that are on the revocation list back to their
|
||||||
|
// accounts. Explicitly check for a revoked copy of the key.
|
||||||
|
|
||||||
|
$revoked_keys = id(new PhabricatorAuthSSHKeyQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withObjectPHIDs(array($object->getObjectPHID()))
|
||||||
|
->withIsActive(0)
|
||||||
|
->withKeys(array($public_key))
|
||||||
|
->execute();
|
||||||
|
if ($revoked_keys) {
|
||||||
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Revoked'),
|
||||||
|
pht(
|
||||||
|
'This key has been revoked. Choose or generate a new, '.
|
||||||
|
'unique key.'),
|
||||||
|
$xaction);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,11 +275,13 @@ final class PhabricatorAuthSSHKeyEditor
|
||||||
|
|
||||||
$body = parent::buildMailBody($object, $xactions);
|
$body = parent::buildMailBody($object, $xactions);
|
||||||
|
|
||||||
|
if (!$this->getIsAdministrativeEdit()) {
|
||||||
$body->addTextSection(
|
$body->addTextSection(
|
||||||
pht('SECURITY WARNING'),
|
pht('SECURITY WARNING'),
|
||||||
pht(
|
pht(
|
||||||
'If you do not recognize this change, it may indicate your account '.
|
'If you do not recognize this change, it may indicate your account '.
|
||||||
'has been compromised.'));
|
'has been compromised.'));
|
||||||
|
}
|
||||||
|
|
||||||
$detail_uri = $object->getURI();
|
$detail_uri = $object->getURI();
|
||||||
$detail_uri = PhabricatorEnv::getProductionURI($detail_uri);
|
$detail_uri = PhabricatorEnv::getProductionURI($detail_uri);
|
||||||
|
@ -253,4 +291,17 @@ final class PhabricatorAuthSSHKeyEditor
|
||||||
return $body;
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function getCustomWorkerState() {
|
||||||
|
return array(
|
||||||
|
'isAdministrativeEdit' => $this->isAdministrativeEdit,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadCustomWorkerState(array $state) {
|
||||||
|
$this->isAdministrativeEdit = idx($state, 'isAdministrativeEdit');
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
320
src/applications/auth/engine/PhabricatorAuthPasswordEngine.php
Normal file
320
src/applications/auth/engine/PhabricatorAuthPasswordEngine.php
Normal file
|
@ -0,0 +1,320 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordEngine
|
||||||
|
extends Phobject {
|
||||||
|
|
||||||
|
private $viewer;
|
||||||
|
private $contentSource;
|
||||||
|
private $object;
|
||||||
|
private $passwordType;
|
||||||
|
private $upgradeHashers = true;
|
||||||
|
|
||||||
|
public function setViewer(PhabricatorUser $viewer) {
|
||||||
|
$this->viewer = $viewer;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViewer() {
|
||||||
|
return $this->viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setContentSource(PhabricatorContentSource $content_source) {
|
||||||
|
$this->contentSource = $content_source;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContentSource() {
|
||||||
|
return $this->contentSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setObject(PhabricatorAuthPasswordHashInterface $object) {
|
||||||
|
$this->object = $object;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObject() {
|
||||||
|
return $this->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPasswordType($password_type) {
|
||||||
|
$this->passwordType = $password_type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPasswordType() {
|
||||||
|
return $this->passwordType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUpgradeHashers($upgrade_hashers) {
|
||||||
|
$this->upgradeHashers = $upgrade_hashers;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUpgradeHashers() {
|
||||||
|
return $this->upgradeHashers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkNewPassword(
|
||||||
|
PhutilOpaqueEnvelope $password,
|
||||||
|
PhutilOpaqueEnvelope $confirm,
|
||||||
|
$can_skip = false) {
|
||||||
|
|
||||||
|
$raw_password = $password->openEnvelope();
|
||||||
|
|
||||||
|
if (!strlen($raw_password)) {
|
||||||
|
if ($can_skip) {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht('You must choose a password or skip this step.'),
|
||||||
|
pht('Required'));
|
||||||
|
} else {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht('You must choose a password.'),
|
||||||
|
pht('Required'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
|
||||||
|
$min_len = (int)$min_len;
|
||||||
|
if ($min_len) {
|
||||||
|
if (strlen($raw_password) < $min_len) {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht(
|
||||||
|
'The selected password is too short. Passwords must be a minimum '.
|
||||||
|
'of %s characters long.',
|
||||||
|
new PhutilNumber($min_len)),
|
||||||
|
pht('Too Short'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw_confirm = $confirm->openEnvelope();
|
||||||
|
|
||||||
|
if (!strlen($raw_confirm)) {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht('You must confirm the selected password.'),
|
||||||
|
null,
|
||||||
|
pht('Required'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($raw_password !== $raw_confirm) {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht('The password and confirmation do not match.'),
|
||||||
|
pht('Invalid'),
|
||||||
|
pht('Invalid'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhabricatorCommonPasswords::isCommonPassword($raw_password)) {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht(
|
||||||
|
'The selected password is very weak: it is one of the most common '.
|
||||||
|
'passwords in use. Choose a stronger password.'),
|
||||||
|
pht('Very Weak'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're creating a brand new object (like registering a new user)
|
||||||
|
// and it does not have a PHID yet, it isn't possible for it to have any
|
||||||
|
// revoked passwords or colliding passwords either, so we can skip these
|
||||||
|
// checks.
|
||||||
|
|
||||||
|
if ($this->getObject()->getPHID()) {
|
||||||
|
if ($this->isRevokedPassword($password)) {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht(
|
||||||
|
'The password you entered has been revoked. You can not reuse '.
|
||||||
|
'a password which has been revoked. Choose a new password.'),
|
||||||
|
pht('Revoked'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isUniquePassword($password)) {
|
||||||
|
throw new PhabricatorAuthPasswordException(
|
||||||
|
pht(
|
||||||
|
'The password you entered is the same as another password '.
|
||||||
|
'associated with your account. Each password must be unique.'),
|
||||||
|
pht('Not Unique'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isValidPassword(PhutilOpaqueEnvelope $envelope) {
|
||||||
|
$this->requireSetup();
|
||||||
|
|
||||||
|
$password_type = $this->getPasswordType();
|
||||||
|
|
||||||
|
$passwords = $this->newQuery()
|
||||||
|
->withPasswordTypes(array($password_type))
|
||||||
|
->withIsRevoked(false)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$matches = $this->getMatches($envelope, $passwords);
|
||||||
|
if (!$matches) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->shouldUpgradeHashers()) {
|
||||||
|
$this->upgradeHashers($envelope, $matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isUniquePassword(PhutilOpaqueEnvelope $envelope) {
|
||||||
|
$this->requireSetup();
|
||||||
|
|
||||||
|
$password_type = $this->getPasswordType();
|
||||||
|
|
||||||
|
// To test that the password is unique, we're loading all active and
|
||||||
|
// revoked passwords for all roles for the given user, then throwing out
|
||||||
|
// the active passwords for the current role (so a password can't
|
||||||
|
// collide with itself).
|
||||||
|
|
||||||
|
// Note that two different objects can have the same password (say,
|
||||||
|
// users @alice and @bailey). We're only preventing @alice from using
|
||||||
|
// the same password for everything.
|
||||||
|
|
||||||
|
$passwords = $this->newQuery()
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
foreach ($passwords as $key => $password) {
|
||||||
|
$same_type = ($password->getPasswordType() === $password_type);
|
||||||
|
$is_active = !$password->getIsRevoked();
|
||||||
|
|
||||||
|
if ($same_type && $is_active) {
|
||||||
|
unset($passwords[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$matches = $this->getMatches($envelope, $passwords);
|
||||||
|
|
||||||
|
return !$matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isRevokedPassword(PhutilOpaqueEnvelope $envelope) {
|
||||||
|
$this->requireSetup();
|
||||||
|
|
||||||
|
// To test if a password is revoked, we're loading all revoked passwords
|
||||||
|
// across all roles for the given user. If a password was revoked in one
|
||||||
|
// role, you can't reuse it in a different role.
|
||||||
|
|
||||||
|
$passwords = $this->newQuery()
|
||||||
|
->withIsRevoked(true)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$matches = $this->getMatches($envelope, $passwords);
|
||||||
|
|
||||||
|
return (bool)$matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function requireSetup() {
|
||||||
|
if (!$this->getObject()) {
|
||||||
|
throw new PhutilInvalidStateException('setObject');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->getPasswordType()) {
|
||||||
|
throw new PhutilInvalidStateException('setPasswordType');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->getViewer()) {
|
||||||
|
throw new PhutilInvalidStateException('setViewer');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->shouldUpgradeHashers()) {
|
||||||
|
if (!$this->getContentSource()) {
|
||||||
|
throw new PhutilInvalidStateException('setContentSource');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldUpgradeHashers() {
|
||||||
|
if (!$this->getUpgradeHashers()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PhabricatorEnv::isReadOnly()) {
|
||||||
|
// Don't try to upgrade hashers if we're in read-only mode, since we
|
||||||
|
// won't be able to write the new hash to the database.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function newQuery() {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$object = $this->getObject();
|
||||||
|
$password_type = $this->getPasswordType();
|
||||||
|
|
||||||
|
return id(new PhabricatorAuthPasswordQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withObjectPHIDs(array($object->getPHID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getMatches(
|
||||||
|
PhutilOpaqueEnvelope $envelope,
|
||||||
|
array $passwords) {
|
||||||
|
|
||||||
|
$object = $this->getObject();
|
||||||
|
|
||||||
|
$matches = array();
|
||||||
|
foreach ($passwords as $password) {
|
||||||
|
try {
|
||||||
|
$is_match = $password->comparePassword($envelope, $object);
|
||||||
|
} catch (PhabricatorPasswordHasherUnavailableException $ex) {
|
||||||
|
$is_match = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_match) {
|
||||||
|
$matches[] = $password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $matches;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function upgradeHashers(
|
||||||
|
PhutilOpaqueEnvelope $envelope,
|
||||||
|
array $passwords) {
|
||||||
|
|
||||||
|
assert_instances_of($passwords, 'PhabricatorAuthPassword');
|
||||||
|
|
||||||
|
$need_upgrade = array();
|
||||||
|
foreach ($passwords as $password) {
|
||||||
|
if (!$password->canUpgrade()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$need_upgrade[] = $password;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$need_upgrade) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$upgrade_type = PhabricatorAuthPasswordUpgradeTransaction::TRANSACTIONTYPE;
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$content_source = $this->getContentSource();
|
||||||
|
|
||||||
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
foreach ($need_upgrade as $password) {
|
||||||
|
|
||||||
|
// This does the actual upgrade. We then apply a transaction to make
|
||||||
|
// the upgrade more visible and auditable.
|
||||||
|
$old_hasher = $password->getHasher();
|
||||||
|
$password->upgradePasswordHasher($envelope, $this->getObject());
|
||||||
|
$new_hasher = $password->getHasher();
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
|
||||||
|
$xactions[] = $password->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType($upgrade_type)
|
||||||
|
->setNewValue($new_hasher->getHashName());
|
||||||
|
|
||||||
|
$editor = $password->getApplicationTransactionEditor()
|
||||||
|
->setActor($viewer)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setOldHasher($old_hasher)
|
||||||
|
->applyTransactions($password, $xactions);
|
||||||
|
}
|
||||||
|
unset($unguarded);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPasswordDestructionEngineExtension
|
||||||
|
extends PhabricatorDestructionEngineExtension {
|
||||||
|
|
||||||
|
const EXTENSIONKEY = 'passwords';
|
||||||
|
|
||||||
|
public function getExtensionName() {
|
||||||
|
return pht('Passwords');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroyObject(
|
||||||
|
PhabricatorDestructionEngine $engine,
|
||||||
|
$object) {
|
||||||
|
|
||||||
|
$viewer = $engine->getViewer();
|
||||||
|
$object_phid = $object->getPHID();
|
||||||
|
|
||||||
|
$passwords = id(new PhabricatorAuthPasswordQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withObjectPHIDs(array($object_phid))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
foreach ($passwords as $password) {
|
||||||
|
$engine->destroyObject($password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,8 +9,8 @@ final class PhabricatorAuthManagementRecoverWorkflow
|
||||||
->setExamples('**recover** __username__')
|
->setExamples('**recover** __username__')
|
||||||
->setSynopsis(
|
->setSynopsis(
|
||||||
pht(
|
pht(
|
||||||
'Recover access to an administrative account if you have locked '.
|
'Recover access to an account if you have locked yourself out '.
|
||||||
'yourself out of Phabricator.'))
|
'of Phabricator.'))
|
||||||
->setArguments(
|
->setArguments(
|
||||||
array(
|
array(
|
||||||
'username' => array(
|
'username' => array(
|
||||||
|
@ -21,23 +21,6 @@ final class PhabricatorAuthManagementRecoverWorkflow
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute(PhutilArgumentParser $args) {
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
|
||||||
$can_recover = id(new PhabricatorPeopleQuery())
|
|
||||||
->setViewer($this->getViewer())
|
|
||||||
->withIsAdmin(true)
|
|
||||||
->execute();
|
|
||||||
if (!$can_recover) {
|
|
||||||
throw new PhutilArgumentUsageException(
|
|
||||||
pht(
|
|
||||||
'This Phabricator installation has no recoverable administrator '.
|
|
||||||
'accounts. You can use `%s` to create a new administrator '.
|
|
||||||
'account or make an existing user an administrator.',
|
|
||||||
'bin/accountadmin'));
|
|
||||||
}
|
|
||||||
$can_recover = mpull($can_recover, 'getUsername');
|
|
||||||
sort($can_recover);
|
|
||||||
$can_recover = implode(', ', $can_recover);
|
|
||||||
|
|
||||||
$usernames = $args->getArg('username');
|
$usernames = $args->getArg('username');
|
||||||
if (!$usernames) {
|
if (!$usernames) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
|
@ -57,18 +40,8 @@ final class PhabricatorAuthManagementRecoverWorkflow
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
pht(
|
pht(
|
||||||
'No such user "%s". Recoverable administrator accounts are: %s.',
|
'No such user "%s" to recover.',
|
||||||
$username,
|
$username));
|
||||||
$can_recover));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$user->getIsAdmin()) {
|
|
||||||
throw new PhutilArgumentUsageException(
|
|
||||||
pht(
|
|
||||||
'You can only recover administrator accounts, but %s is not an '.
|
|
||||||
'administrator. Recoverable administrator accounts are: %s.',
|
|
||||||
$username,
|
|
||||||
$can_recover));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$user->canEstablishWebSessions()) {
|
if (!$user->canEstablishWebSessions()) {
|
||||||
|
|
|
@ -7,7 +7,8 @@ final class PhabricatorAuthManagementRevokeWorkflow
|
||||||
$this
|
$this
|
||||||
->setName('revoke')
|
->setName('revoke')
|
||||||
->setExamples(
|
->setExamples(
|
||||||
"**revoke** --type __type__ --from __user__\n".
|
"**revoke** --list\n".
|
||||||
|
"**revoke** --type __type__ --from __@user__\n".
|
||||||
"**revoke** --everything --everywhere")
|
"**revoke** --everything --everywhere")
|
||||||
->setSynopsis(
|
->setSynopsis(
|
||||||
pht(
|
pht(
|
||||||
|
@ -16,15 +17,20 @@ final class PhabricatorAuthManagementRevokeWorkflow
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
'name' => 'from',
|
'name' => 'from',
|
||||||
'param' => 'user',
|
'param' => 'object',
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
'Revoke credentials for the specified user.'),
|
'Revoke credentials for the specified object. To revoke '.
|
||||||
|
'credentials for a user, use "@username".'),
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'type',
|
'name' => 'type',
|
||||||
'param' => 'type',
|
'param' => 'type',
|
||||||
|
'help' => pht('Revoke credentials of the given type.'),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'list',
|
||||||
'help' => pht(
|
'help' => pht(
|
||||||
'Revoke credentials of the given type.'),
|
'List information about available credential revokers.'),
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'name' => 'everything',
|
'name' => 'everything',
|
||||||
|
@ -34,21 +40,37 @@ final class PhabricatorAuthManagementRevokeWorkflow
|
||||||
'name' => 'everywhere',
|
'name' => 'everywhere',
|
||||||
'help' => pht('Revoke from all credential owners.'),
|
'help' => pht('Revoke from all credential owners.'),
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'force',
|
||||||
|
'help' => pht('Revoke credentials without prompting.'),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute(PhutilArgumentParser $args) {
|
public function execute(PhutilArgumentParser $args) {
|
||||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$all_types = PhabricatorAuthRevoker::getAllRevokers();
|
$all_types = PhabricatorAuthRevoker::getAllRevokers();
|
||||||
|
$is_force = $args->getArg('force');
|
||||||
|
|
||||||
|
// The "--list" flag is compatible with revoker selection flags like
|
||||||
|
// "--type" to filter the list, but not compatible with target selection
|
||||||
|
// flags like "--from".
|
||||||
|
$is_list = $args->getArg('list');
|
||||||
|
|
||||||
$type = $args->getArg('type');
|
$type = $args->getArg('type');
|
||||||
$is_everything = $args->getArg('everything');
|
$is_everything = $args->getArg('everything');
|
||||||
if (!strlen($type) && !$is_everything) {
|
if (!strlen($type) && !$is_everything) {
|
||||||
|
if ($is_list) {
|
||||||
|
// By default, "bin/revoke --list" implies "--everything".
|
||||||
|
$types = $all_types;
|
||||||
|
} else {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
pht(
|
pht(
|
||||||
'Specify the credential type to revoke with "--type" or specify '.
|
'Specify the credential type to revoke with "--type" or specify '.
|
||||||
'"--everything".'));
|
'"--everything". Use "--list" to list available credential '.
|
||||||
|
'types.'));
|
||||||
|
}
|
||||||
} else if (strlen($type) && $is_everything) {
|
} else if (strlen($type) && $is_everything) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
pht(
|
pht(
|
||||||
|
@ -70,6 +92,32 @@ final class PhabricatorAuthManagementRevokeWorkflow
|
||||||
|
|
||||||
$is_everywhere = $args->getArg('everywhere');
|
$is_everywhere = $args->getArg('everywhere');
|
||||||
$from = $args->getArg('from');
|
$from = $args->getArg('from');
|
||||||
|
|
||||||
|
if ($is_list) {
|
||||||
|
if (strlen($from) || $is_everywhere) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'You can not "--list" and revoke credentials (with "--from" or '.
|
||||||
|
'"--everywhere") in the same operation.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_list) {
|
||||||
|
$last_key = last_key($types);
|
||||||
|
foreach ($types as $key => $type) {
|
||||||
|
echo tsprintf(
|
||||||
|
"**%s** (%s)\n\n",
|
||||||
|
$type->getRevokerKey(),
|
||||||
|
$type->getRevokerName());
|
||||||
|
|
||||||
|
id(new PhutilConsoleBlock())
|
||||||
|
->addParagraph(tsprintf('%B', $type->getRevokerDescription()))
|
||||||
|
->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
$target = null;
|
$target = null;
|
||||||
if (!strlen($from) && !$is_everywhere) {
|
if (!strlen($from) && !$is_everywhere) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
|
@ -97,7 +145,7 @@ final class PhabricatorAuthManagementRevokeWorkflow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($is_everywhere) {
|
if ($is_everywhere && !$is_force) {
|
||||||
echo id(new PhutilConsoleBlock())
|
echo id(new PhutilConsoleBlock())
|
||||||
->addParagraph(
|
->addParagraph(
|
||||||
pht(
|
pht(
|
||||||
|
@ -128,6 +176,13 @@ final class PhabricatorAuthManagementRevokeWorkflow
|
||||||
'Destroyed %s credential(s) of type "%s".',
|
'Destroyed %s credential(s) of type "%s".',
|
||||||
new PhutilNumber($count),
|
new PhutilNumber($count),
|
||||||
$type->getRevokerKey()));
|
$type->getRevokerKey()));
|
||||||
|
|
||||||
|
$guidance = $type->getRevokerNextSteps();
|
||||||
|
if ($guidance !== null) {
|
||||||
|
echo tsprintf(
|
||||||
|
"%s\n",
|
||||||
|
$guidance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo tsprintf(
|
echo tsprintf(
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordException
|
||||||
|
extends Exception {
|
||||||
|
|
||||||
|
private $passwordError;
|
||||||
|
private $confirmErorr;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
$message,
|
||||||
|
$password_error,
|
||||||
|
$confirm_error = null) {
|
||||||
|
|
||||||
|
$this->passwordError = $password_error;
|
||||||
|
$this->confirmError = $confirm_error;
|
||||||
|
|
||||||
|
parent::__construct($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPasswordError() {
|
||||||
|
return $this->passwordError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfirmError() {
|
||||||
|
return $this->confirmError;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
interface PhabricatorAuthPasswordHashInterface {
|
||||||
|
|
||||||
|
public function newPasswordDigest(
|
||||||
|
PhutilOpaqueEnvelope $envelope,
|
||||||
|
PhabricatorAuthPassword $password);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordPHIDType extends PhabricatorPHIDType {
|
||||||
|
|
||||||
|
const TYPECONST = 'APAS';
|
||||||
|
|
||||||
|
public function getTypeName() {
|
||||||
|
return pht('Auth Password');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newObject() {
|
||||||
|
return new PhabricatorAuthPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPHIDTypeApplicationClass() {
|
||||||
|
return 'PhabricatorAuthApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildQueryForObjects(
|
||||||
|
PhabricatorObjectQuery $query,
|
||||||
|
array $phids) {
|
||||||
|
return id(new PhabricatorAuthPasswordQuery())
|
||||||
|
->withPHIDs($phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadHandles(
|
||||||
|
PhabricatorHandleQuery $query,
|
||||||
|
array $handles,
|
||||||
|
array $objects) {
|
||||||
|
|
||||||
|
foreach ($handles as $phid => $handle) {
|
||||||
|
$password = $objects[$phid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -253,6 +253,7 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||||
|
|
||||||
$request = $controller->getRequest();
|
$request = $controller->getRequest();
|
||||||
$viewer = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
|
$content_source = PhabricatorContentSource::newFromRequest($request);
|
||||||
|
|
||||||
$require_captcha = false;
|
$require_captcha = false;
|
||||||
$captcha_valid = false;
|
$captcha_valid = false;
|
||||||
|
@ -285,22 +286,16 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$envelope = new PhutilOpaqueEnvelope($request->getStr('password'));
|
$envelope = new PhutilOpaqueEnvelope($request->getStr('password'));
|
||||||
if ($user->comparePassword($envelope)) {
|
|
||||||
|
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
|
->setViewer($user)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setPasswordType(PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT)
|
||||||
|
->setObject($user);
|
||||||
|
|
||||||
|
if ($engine->isValidPassword($envelope)) {
|
||||||
$account = $this->loadOrCreateAccount($user->getPHID());
|
$account = $this->loadOrCreateAccount($user->getPHID());
|
||||||
$log_user = $user;
|
$log_user = $user;
|
||||||
|
|
||||||
// If the user's password is stored using a less-than-optimal
|
|
||||||
// hash, upgrade them to the strongest available hash.
|
|
||||||
|
|
||||||
$hash_envelope = new PhutilOpaqueEnvelope(
|
|
||||||
$user->getPasswordHash());
|
|
||||||
if (PhabricatorPasswordHasher::canUpgradeHash($hash_envelope)) {
|
|
||||||
$user->setPassword($envelope);
|
|
||||||
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
|
||||||
$user->save();
|
|
||||||
unset($unguarded);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
114
src/applications/auth/query/PhabricatorAuthPasswordQuery.php
Normal file
114
src/applications/auth/query/PhabricatorAuthPasswordQuery.php
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $ids;
|
||||||
|
private $phids;
|
||||||
|
private $objectPHIDs;
|
||||||
|
private $passwordTypes;
|
||||||
|
private $isRevoked;
|
||||||
|
|
||||||
|
public function withIDs(array $ids) {
|
||||||
|
$this->ids = $ids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withPHIDs(array $phids) {
|
||||||
|
$this->phids = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withObjectPHIDs(array $object_phids) {
|
||||||
|
$this->objectPHIDs = $object_phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withPasswordTypes(array $types) {
|
||||||
|
$this->passwordTypes = $types;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withIsRevoked($is_revoked) {
|
||||||
|
$this->isRevoked = $is_revoked;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newResultObject() {
|
||||||
|
return new PhabricatorAuthPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadPage() {
|
||||||
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
|
if ($this->ids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'id IN (%Ld)',
|
||||||
|
$this->ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->phids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'phid IN (%Ls)',
|
||||||
|
$this->phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->objectPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'objectPHID IN (%Ls)',
|
||||||
|
$this->objectPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->passwordTypes !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'passwordType IN (%Ls)',
|
||||||
|
$this->passwordTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isRevoked !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'isRevoked = %d',
|
||||||
|
(int)$this->isRevoked);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function willFilterPage(array $passwords) {
|
||||||
|
$object_phids = mpull($passwords, 'getObjectPHID');
|
||||||
|
|
||||||
|
$objects = id(new PhabricatorObjectQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->setParentQuery($this)
|
||||||
|
->withPHIDs($object_phids)
|
||||||
|
->execute();
|
||||||
|
$objects = mpull($objects, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($passwords as $key => $password) {
|
||||||
|
$object = idx($objects, $password->getObjectPHID());
|
||||||
|
if (!$object) {
|
||||||
|
unset($passwords[$key]);
|
||||||
|
$this->didRejectResult($password);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$password->attachObject($object);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $passwords;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryApplicationClass() {
|
||||||
|
return 'PhabricatorAuthApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordTransactionQuery
|
||||||
|
extends PhabricatorApplicationTransactionQuery {
|
||||||
|
|
||||||
|
public function getTemplateApplicationTransaction() {
|
||||||
|
return new PhabricatorAuthPasswordTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,19 @@ final class PhabricatorAuthConduitTokenRevoker
|
||||||
|
|
||||||
const REVOKERKEY = 'conduit';
|
const REVOKERKEY = 'conduit';
|
||||||
|
|
||||||
|
public function getRevokerName() {
|
||||||
|
return pht('Conduit API Tokens');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRevokerDescription() {
|
||||||
|
return pht(
|
||||||
|
"Revokes all Conduit API tokens used to access the API.\n\n".
|
||||||
|
"Users will need to use `arc install-certificate` to install new ".
|
||||||
|
"API tokens before `arc` commands will work. Bots and scripts which ".
|
||||||
|
"access the API will need to have new tokens generated and ".
|
||||||
|
"installed.");
|
||||||
|
}
|
||||||
|
|
||||||
public function revokeAllCredentials() {
|
public function revokeAllCredentials() {
|
||||||
$table = id(new PhabricatorConduitToken());
|
$table = id(new PhabricatorConduitToken());
|
||||||
$conn = $table->establishConnection('w');
|
$conn = $table->establishConnection('w');
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordRevoker
|
||||||
|
extends PhabricatorAuthRevoker {
|
||||||
|
|
||||||
|
const REVOKERKEY = 'password';
|
||||||
|
|
||||||
|
public function getRevokerName() {
|
||||||
|
return pht('Passwords');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRevokerDescription() {
|
||||||
|
return pht(
|
||||||
|
"Revokes all stored passwords.\n\n".
|
||||||
|
"Account passwords and VCS passwords (used to access repositories ".
|
||||||
|
"over HTTP) will both be revoked. Passwords for any third party ".
|
||||||
|
"applications which use shared password infrastructure will also ".
|
||||||
|
"be revoked.\n\n".
|
||||||
|
"Users will need to reset account passwords, possibly by using the ".
|
||||||
|
"\"Forgot Password?\" link on the login page. They will also need ".
|
||||||
|
"to reset VCS passwords.\n\n".
|
||||||
|
"Passwords are revoked, not just removed. Users will be unable to ".
|
||||||
|
"select the passwords they used previously and must choose new, ".
|
||||||
|
"unique passwords.\n\n".
|
||||||
|
"Revoking passwords will not terminate outstanding login sessions. ".
|
||||||
|
"Use the \"session\" revoker in conjunction with this revoker to force ".
|
||||||
|
"users to login again.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRevokerNextSteps() {
|
||||||
|
return pht(
|
||||||
|
'NOTE: Revoking passwords does not terminate existing sessions which '.
|
||||||
|
'were established using the old passwords. To terminate existing '.
|
||||||
|
'sessions, run the "session" revoker now.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeAllCredentials() {
|
||||||
|
$query = new PhabricatorAuthPasswordQuery();
|
||||||
|
return $this->revokeWithQuery($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeCredentialsFrom($object) {
|
||||||
|
$query = id(new PhabricatorAuthPasswordQuery())
|
||||||
|
->withObjectPHIDs(array($object->getPHID()));
|
||||||
|
return $this->revokeWithQuery($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function revokeWithQuery(PhabricatorAuthPasswordQuery $query) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$passwords = $query
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIsRevoked(false)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$content_source = PhabricatorContentSource::newForSource(
|
||||||
|
PhabricatorDaemonContentSource::SOURCECONST);
|
||||||
|
|
||||||
|
$revoke_type = PhabricatorAuthPasswordRevokeTransaction::TRANSACTIONTYPE;
|
||||||
|
|
||||||
|
$auth_phid = id(new PhabricatorAuthApplication())->getPHID();
|
||||||
|
foreach ($passwords as $password) {
|
||||||
|
$xactions = array();
|
||||||
|
|
||||||
|
$xactions[] = $password->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType($revoke_type)
|
||||||
|
->setNewValue(true);
|
||||||
|
|
||||||
|
$editor = $password->getApplicationTransactionEditor()
|
||||||
|
->setActor($viewer)
|
||||||
|
->setActingAsPHID($auth_phid)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->applyTransactions($password, $xactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count($passwords);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,9 +5,16 @@ abstract class PhabricatorAuthRevoker
|
||||||
|
|
||||||
private $viewer;
|
private $viewer;
|
||||||
|
|
||||||
abstract public function revokeAlLCredentials();
|
abstract public function revokeAllCredentials();
|
||||||
abstract public function revokeCredentialsFrom($object);
|
abstract public function revokeCredentialsFrom($object);
|
||||||
|
|
||||||
|
abstract public function getRevokerName();
|
||||||
|
abstract public function getRevokerDescription();
|
||||||
|
|
||||||
|
public function getRevokerNextSteps() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function setViewer(PhabricatorUser $viewer) {
|
public function setViewer(PhabricatorUser $viewer) {
|
||||||
$this->viewer = $viewer;
|
$this->viewer = $viewer;
|
||||||
return $this;
|
return $this;
|
||||||
|
|
65
src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php
Normal file
65
src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthSSHRevoker
|
||||||
|
extends PhabricatorAuthRevoker {
|
||||||
|
|
||||||
|
const REVOKERKEY = 'ssh';
|
||||||
|
|
||||||
|
public function getRevokerName() {
|
||||||
|
return pht('SSH Keys');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRevokerDescription() {
|
||||||
|
return pht(
|
||||||
|
"Revokes all SSH public keys.\n\n".
|
||||||
|
"SSH public keys are revoked, not just removed. Users will need to ".
|
||||||
|
"generate and upload new, unique keys before they can access ".
|
||||||
|
"repositories or other services over SSH.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeAllCredentials() {
|
||||||
|
$query = new PhabricatorAuthSSHKeyQuery();
|
||||||
|
return $this->revokeWithQuery($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeCredentialsFrom($object) {
|
||||||
|
$query = id(new PhabricatorAuthSSHKeyQuery())
|
||||||
|
->withObjectPHIDs(array($object->getPHID()));
|
||||||
|
|
||||||
|
return $this->revokeWithQuery($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function revokeWithQuery(PhabricatorAuthSSHKeyQuery $query) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
// We're only going to revoke keys which have not already been revoked.
|
||||||
|
|
||||||
|
$ssh_keys = $query
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIsActive(true)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$content_source = PhabricatorContentSource::newForSource(
|
||||||
|
PhabricatorDaemonContentSource::SOURCECONST);
|
||||||
|
|
||||||
|
$auth_phid = id(new PhabricatorAuthApplication())->getPHID();
|
||||||
|
foreach ($ssh_keys as $ssh_key) {
|
||||||
|
$xactions = array();
|
||||||
|
$xactions[] = $ssh_key->getApplicationTransactionTemplate()
|
||||||
|
->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_DEACTIVATE)
|
||||||
|
->setNewValue(1);
|
||||||
|
|
||||||
|
$editor = $ssh_key->getApplicationTransactionEditor()
|
||||||
|
->setActor($viewer)
|
||||||
|
->setActingAsPHID($auth_phid)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContinueOnMissingFields(true)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setIsAdministrativeEdit(true)
|
||||||
|
->applyTransactions($ssh_key, $xactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count($ssh_keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthSessionRevoker
|
||||||
|
extends PhabricatorAuthRevoker {
|
||||||
|
|
||||||
|
const REVOKERKEY = 'session';
|
||||||
|
|
||||||
|
public function getRevokerName() {
|
||||||
|
return pht('Sessions');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRevokerDescription() {
|
||||||
|
return pht(
|
||||||
|
"Revokes all active login sessions.\n\n".
|
||||||
|
"Affected users will be logged out and need to log in again.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeAllCredentials() {
|
||||||
|
$table = new PhabricatorAuthSession();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'DELETE FROM %T',
|
||||||
|
$table->getTableName());
|
||||||
|
|
||||||
|
return $conn->getAffectedRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeCredentialsFrom($object) {
|
||||||
|
$table = new PhabricatorAuthSession();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'DELETE FROM %T WHERE userPHID = %s',
|
||||||
|
$table->getTableName(),
|
||||||
|
$object->getPHID());
|
||||||
|
|
||||||
|
return $conn->getAffectedRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthTemporaryTokenRevoker
|
||||||
|
extends PhabricatorAuthRevoker {
|
||||||
|
|
||||||
|
const REVOKERKEY = 'temporary';
|
||||||
|
|
||||||
|
public function getRevokerName() {
|
||||||
|
return pht('Temporary Tokens');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRevokerDescription() {
|
||||||
|
return pht(
|
||||||
|
"Revokes temporary authentication tokens.\n\n".
|
||||||
|
"Temporary tokens are used in password reset mail, welcome mail, and ".
|
||||||
|
"by some other systems like Git LFS. Revoking temporary tokens will ".
|
||||||
|
"invalidate existing links in password reset and invite mail that ".
|
||||||
|
"was sent before the revocation occurred.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeAllCredentials() {
|
||||||
|
$table = new PhabricatorAuthTemporaryToken();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'DELETE FROM %T',
|
||||||
|
$table->getTableName());
|
||||||
|
|
||||||
|
return $conn->getAffectedRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revokeCredentialsFrom($object) {
|
||||||
|
$table = new PhabricatorAuthTemporaryToken();
|
||||||
|
$conn = $table->establishConnection('w');
|
||||||
|
|
||||||
|
queryfx(
|
||||||
|
$conn,
|
||||||
|
'DELETE FROM %T WHERE tokenResource = %s',
|
||||||
|
$table->getTableName(),
|
||||||
|
$object->getPHID());
|
||||||
|
|
||||||
|
return $conn->getAffectedRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
235
src/applications/auth/storage/PhabricatorAuthPassword.php
Normal file
235
src/applications/auth/storage/PhabricatorAuthPassword.php
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPassword
|
||||||
|
extends PhabricatorAuthDAO
|
||||||
|
implements
|
||||||
|
PhabricatorPolicyInterface,
|
||||||
|
PhabricatorDestructibleInterface,
|
||||||
|
PhabricatorApplicationTransactionInterface {
|
||||||
|
|
||||||
|
protected $objectPHID;
|
||||||
|
protected $passwordType;
|
||||||
|
protected $passwordHash;
|
||||||
|
protected $passwordSalt;
|
||||||
|
protected $isRevoked;
|
||||||
|
protected $legacyDigestFormat;
|
||||||
|
|
||||||
|
private $object = self::ATTACHABLE;
|
||||||
|
|
||||||
|
const PASSWORD_TYPE_ACCOUNT = 'account';
|
||||||
|
const PASSWORD_TYPE_VCS = 'vcs';
|
||||||
|
const PASSWORD_TYPE_TEST = 'test';
|
||||||
|
|
||||||
|
public static function initializeNewPassword(
|
||||||
|
PhabricatorAuthPasswordHashInterface $object,
|
||||||
|
$type) {
|
||||||
|
|
||||||
|
return id(new self())
|
||||||
|
->setObjectPHID($object->getPHID())
|
||||||
|
->attachObject($object)
|
||||||
|
->setPasswordType($type)
|
||||||
|
->setIsRevoked(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
|
'passwordType' => 'text64',
|
||||||
|
'passwordHash' => 'text128',
|
||||||
|
'passwordSalt' => 'text64',
|
||||||
|
'isRevoked' => 'bool',
|
||||||
|
'legacyDigestFormat' => 'text32?',
|
||||||
|
),
|
||||||
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
|
'key_role' => array(
|
||||||
|
'columns' => array('objectPHID', 'passwordType'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPHIDType() {
|
||||||
|
return PhabricatorAuthPasswordPHIDType::TYPECONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObject() {
|
||||||
|
return $this->assertAttached($this->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attachObject($object) {
|
||||||
|
$this->object = $object;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHasher() {
|
||||||
|
$hash = $this->newPasswordEnvelope();
|
||||||
|
return PhabricatorPasswordHasher::getHasherForHash($hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canUpgrade() {
|
||||||
|
// If this password uses a legacy digest format, we can upgrade it to the
|
||||||
|
// new digest format even if a better hasher isn't available.
|
||||||
|
if ($this->getLegacyDigestFormat() !== null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hash = $this->newPasswordEnvelope();
|
||||||
|
return PhabricatorPasswordHasher::canUpgradeHash($hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function upgradePasswordHasher(
|
||||||
|
PhutilOpaqueEnvelope $envelope,
|
||||||
|
PhabricatorAuthPasswordHashInterface $object) {
|
||||||
|
|
||||||
|
// Before we make changes, double check that this is really the correct
|
||||||
|
// password. It could be really bad if we "upgraded" a password and changed
|
||||||
|
// the secret!
|
||||||
|
|
||||||
|
if (!$this->comparePassword($envelope, $object)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Attempting to upgrade password hasher, but the password for the '.
|
||||||
|
'upgrade is not the stored credential!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setPassword($envelope, $object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPassword(
|
||||||
|
PhutilOpaqueEnvelope $password,
|
||||||
|
PhabricatorAuthPasswordHashInterface $object) {
|
||||||
|
|
||||||
|
$hasher = PhabricatorPasswordHasher::getBestHasher();
|
||||||
|
return $this->setPasswordWithHasher($password, $object, $hasher);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPasswordWithHasher(
|
||||||
|
PhutilOpaqueEnvelope $password,
|
||||||
|
PhabricatorAuthPasswordHashInterface $object,
|
||||||
|
PhabricatorPasswordHasher $hasher) {
|
||||||
|
|
||||||
|
if (!strlen($password->openEnvelope())) {
|
||||||
|
throw new Exception(
|
||||||
|
pht('Attempting to set an empty password!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate (or regenerate) the salt first.
|
||||||
|
$new_salt = Filesystem::readRandomCharacters(64);
|
||||||
|
$this->setPasswordSalt($new_salt);
|
||||||
|
|
||||||
|
// Clear any legacy digest format to force a modern digest.
|
||||||
|
$this->setLegacyDigestFormat(null);
|
||||||
|
|
||||||
|
$digest = $this->digestPassword($password, $object);
|
||||||
|
$hash = $hasher->getPasswordHashForStorage($digest);
|
||||||
|
$raw_hash = $hash->openEnvelope();
|
||||||
|
|
||||||
|
return $this->setPasswordHash($raw_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function comparePassword(
|
||||||
|
PhutilOpaqueEnvelope $password,
|
||||||
|
PhabricatorAuthPasswordHashInterface $object) {
|
||||||
|
|
||||||
|
$digest = $this->digestPassword($password, $object);
|
||||||
|
$hash = $this->newPasswordEnvelope();
|
||||||
|
|
||||||
|
return PhabricatorPasswordHasher::comparePassword($digest, $hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newPasswordEnvelope() {
|
||||||
|
return new PhutilOpaqueEnvelope($this->getPasswordHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function digestPassword(
|
||||||
|
PhutilOpaqueEnvelope $password,
|
||||||
|
PhabricatorAuthPasswordHashInterface $object) {
|
||||||
|
|
||||||
|
$object_phid = $object->getPHID();
|
||||||
|
|
||||||
|
if ($this->getObjectPHID() !== $object->getPHID()) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'This password is associated with an object PHID ("%s") for '.
|
||||||
|
'a different object than the provided one ("%s").',
|
||||||
|
$this->getObjectPHID(),
|
||||||
|
$object->getPHID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$digest = $object->newPasswordDigest($password, $this);
|
||||||
|
|
||||||
|
if (!($digest instanceof PhutilOpaqueEnvelope)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Failed to digest password: object ("%s") did not return an '.
|
||||||
|
'opaque envelope with a password digest.',
|
||||||
|
$object->getPHID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getCapabilities() {
|
||||||
|
return array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPolicy($capability) {
|
||||||
|
return PhabricatorPolicies::getMostOpenPolicy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
|
||||||
|
return array(
|
||||||
|
array($this->getObject(), PhabricatorPolicyCapability::CAN_VIEW),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function destroyObjectPermanently(
|
||||||
|
PhabricatorDestructionEngine $engine) {
|
||||||
|
$this->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getApplicationTransactionEditor() {
|
||||||
|
return new PhabricatorAuthPasswordEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionObject() {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionTemplate() {
|
||||||
|
return new PhabricatorAuthPasswordTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function willRenderTimeline(
|
||||||
|
PhabricatorApplicationTransactionView $timeline,
|
||||||
|
AphrontRequest $request) {
|
||||||
|
|
||||||
|
return $timeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordTransaction
|
||||||
|
extends PhabricatorModularTransaction {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'auth';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionType() {
|
||||||
|
return PhabricatorAuthPasswordPHIDType::TYPECONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionCommentObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBaseTransactionClass() {
|
||||||
|
return 'PhabricatorAuthPasswordTransactionType';
|
||||||
|
}
|
||||||
|
}
|
|
@ -139,7 +139,7 @@ final class PhabricatorAuthSSHKey
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
if (!$this->getIsACtive()) {
|
if (!$this->getIsACtive()) {
|
||||||
return pht(
|
return pht(
|
||||||
'Deactivated SSH keys can not be edited or reactivated.');
|
'Revoked SSH keys can not be edited or reinstated.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return pht(
|
return pht(
|
||||||
|
|
|
@ -43,11 +43,11 @@ final class PhabricatorAuthSSHKeyTransaction
|
||||||
case self::TYPE_DEACTIVATE:
|
case self::TYPE_DEACTIVATE:
|
||||||
if ($new) {
|
if ($new) {
|
||||||
return pht(
|
return pht(
|
||||||
'%s deactivated this key.',
|
'%s revoked this key.',
|
||||||
$this->renderHandleLink($author_phid));
|
$this->renderHandleLink($author_phid));
|
||||||
} else {
|
} else {
|
||||||
return pht(
|
return pht(
|
||||||
'%s activated this key.',
|
'%s reinstated this key.',
|
||||||
$this->renderHandleLink($author_phid));
|
$this->renderHandleLink($author_phid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordRevokeTransaction
|
||||||
|
extends PhabricatorAuthPasswordTransactionType {
|
||||||
|
|
||||||
|
const TRANSACTIONTYPE = 'password.revoke';
|
||||||
|
|
||||||
|
public function generateOldValue($object) {
|
||||||
|
return (bool)$object->getIsRevoked();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateNewValue($object, $value) {
|
||||||
|
return (bool)$value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyInternalEffects($object, $value) {
|
||||||
|
$object->setIsRevoked((int)$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
if ($this->getNewValue()) {
|
||||||
|
return pht(
|
||||||
|
'%s revoked this password.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
} else {
|
||||||
|
return pht(
|
||||||
|
'%s removed this password from the revocation list.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorAuthPasswordTransactionType
|
||||||
|
extends PhabricatorModularTransactionType {}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthPasswordUpgradeTransaction
|
||||||
|
extends PhabricatorAuthPasswordTransactionType {
|
||||||
|
|
||||||
|
const TRANSACTIONTYPE = 'password.upgrade';
|
||||||
|
|
||||||
|
public function generateOldValue($object) {
|
||||||
|
$old_hasher = $this->getEditor()->getOldHasher();
|
||||||
|
|
||||||
|
if (!$old_hasher) {
|
||||||
|
throw new PhutilInvalidStateException('setOldHasher');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $old_hasher->getHashName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateNewValue($object, $value) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
return pht(
|
||||||
|
'%s upgraded the hash algorithm for this password from "%s" to "%s".',
|
||||||
|
$this->renderAuthor(),
|
||||||
|
$this->renderOldValue(),
|
||||||
|
$this->renderNewValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -618,10 +618,14 @@ abstract class PhabricatorApplication
|
||||||
')?';
|
')?';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getQueryRoutePattern($base = null) {
|
protected function getBulkRoutePattern($base = null) {
|
||||||
return $base.'(?:query/(?P<queryKey>[^/]+)/)?';
|
return $base.'(?:query/(?P<queryKey>[^/]+)/)?';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getQueryRoutePattern($base = null) {
|
||||||
|
return $base.'(?:query/(?P<queryKey>[^/]+)/(?:(?P<queryAction>[^/]+)/)?)?';
|
||||||
|
}
|
||||||
|
|
||||||
protected function getProfileMenuRouting($controller) {
|
protected function getProfileMenuRouting($controller) {
|
||||||
$edit_route = $this->getEditRoutePattern();
|
$edit_route = $this->getEditRoutePattern();
|
||||||
|
|
||||||
|
|
|
@ -49,13 +49,6 @@ final class PhabricatorCalendarEventHeraldAdapter extends HeraldAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRepetitionOptions() {
|
|
||||||
return array(
|
|
||||||
HeraldRepetitionPolicyConfig::EVERY,
|
|
||||||
HeraldRepetitionPolicyConfig::FIRST,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHeraldName() {
|
public function getHeraldName() {
|
||||||
return $this->getObject()->getMonogram();
|
return $this->getObject()->getMonogram();
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ final class ConduitSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$call = new ConduitCall($method, $params);
|
$call = new ConduitCall($method, $params);
|
||||||
$call->setUser($this->getUser());
|
$call->setUser($this->getSSHUser());
|
||||||
|
|
||||||
$result = $call->execute();
|
$result = $call->execute();
|
||||||
} catch (ConduitException $ex) {
|
} catch (ConduitException $ex) {
|
||||||
|
@ -77,7 +77,7 @@ final class ConduitSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
|
|
||||||
$connection_id = idx($metadata, 'connectionID');
|
$connection_id = idx($metadata, 'connectionID');
|
||||||
$log = id(new PhabricatorConduitMethodCallLog())
|
$log = id(new PhabricatorConduitMethodCallLog())
|
||||||
->setCallerPHID($this->getUser()->getPHID())
|
->setCallerPHID($this->getSSHUser()->getPHID())
|
||||||
->setConnectionID($connection_id)
|
->setConnectionID($connection_id)
|
||||||
->setMethod($method)
|
->setMethod($method)
|
||||||
->setError((string)$error_code)
|
->setError((string)$error_code)
|
||||||
|
|
|
@ -18,7 +18,8 @@ final class PhabricatorGDSetupCheck extends PhabricatorSetupCheck {
|
||||||
|
|
||||||
$this->newIssue('extension.gd')
|
$this->newIssue('extension.gd')
|
||||||
->setName(pht("Missing '%s' Extension", 'gd'))
|
->setName(pht("Missing '%s' Extension", 'gd'))
|
||||||
->setMessage($message);
|
->setMessage($message)
|
||||||
|
->addPHPExtension('gd');
|
||||||
} else {
|
} else {
|
||||||
$image_type_map = array(
|
$image_type_map = array(
|
||||||
'imagecreatefrompng' => 'PNG',
|
'imagecreatefrompng' => 'PNG',
|
||||||
|
|
|
@ -49,13 +49,22 @@ final class PhabricatorDaemonBulkJobMonitorController
|
||||||
return id(new AphrontRedirectResponse())
|
return id(new AphrontRedirectResponse())
|
||||||
->setURI($job->getMonitorURI());
|
->setURI($job->getMonitorURI());
|
||||||
} else {
|
} else {
|
||||||
return $this->newDialog()
|
$dialog = $this->newDialog()
|
||||||
->setTitle(pht('Confirm Bulk Job'))
|
->setTitle(pht('Confirm Bulk Job'));
|
||||||
->appendParagraph($job->getDescriptionForConfirm())
|
|
||||||
|
$confirm = $job->getDescriptionForConfirm();
|
||||||
|
$confirm = (array)$confirm;
|
||||||
|
foreach ($confirm as $paragraph) {
|
||||||
|
$dialog->appendParagraph($paragraph);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog
|
||||||
->appendParagraph(
|
->appendParagraph(
|
||||||
pht('Start work on this bulk job?'))
|
pht('Start work on this bulk job?'))
|
||||||
->addCancelButton($job->getManageURI(), pht('Details'))
|
->addCancelButton($job->getManageURI(), pht('Details'))
|
||||||
->addSubmitButton(pht('Start Work'));
|
->addSubmitButton(pht('Start Work'));
|
||||||
|
|
||||||
|
return $dialog;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return $this->newDialog()
|
return $this->newDialog()
|
||||||
|
|
|
@ -79,13 +79,20 @@ final class PhabricatorWorkerTaskDetailController
|
||||||
->appendChild($view);
|
->appendChild($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPropertyListView(
|
private function buildPropertyListView(PhabricatorWorkerTask $task) {
|
||||||
PhabricatorWorkerTask $task) {
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
|
||||||
|
|
||||||
$view = new PHUIPropertyListView();
|
$view = new PHUIPropertyListView();
|
||||||
|
|
||||||
|
$object_phid = $task->getObjectPHID();
|
||||||
|
if ($object_phid) {
|
||||||
|
$handles = $viewer->loadHandles(array($object_phid));
|
||||||
|
$handle = $handles[$object_phid];
|
||||||
|
if ($handle->isComplete()) {
|
||||||
|
$view->addProperty(pht('Object'), $handle->renderLink());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($task->isArchived()) {
|
if ($task->isArchived()) {
|
||||||
switch ($task->getResult()) {
|
switch ($task->getResult()) {
|
||||||
case PhabricatorWorkerArchiveTask::RESULT_SUCCESS:
|
case PhabricatorWorkerArchiveTask::RESULT_SUCCESS:
|
||||||
|
|
|
@ -106,9 +106,11 @@ final class DifferentialCreateCommentConduitAPIMethod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: The legacy "silent" flag is now ignored and has no effect. See
|
||||||
|
// T13042.
|
||||||
|
|
||||||
$editor = id(new DifferentialTransactionEditor())
|
$editor = id(new DifferentialTransactionEditor())
|
||||||
->setActor($viewer)
|
->setActor($viewer)
|
||||||
->setDisableEmail($request->getValue('silent'))
|
|
||||||
->setContentSource($request->newContentSource())
|
->setContentSource($request->newContentSource())
|
||||||
->setContinueOnNoEffect(true)
|
->setContinueOnNoEffect(true)
|
||||||
->setContinueOnMissingFields(true);
|
->setContinueOnMissingFields(true);
|
||||||
|
|
|
@ -700,20 +700,26 @@ final class DifferentialTransactionEditor
|
||||||
->addHeader('Thread-Topic', $thread_topic);
|
->addHeader('Thread-Topic', $thread_topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildMailBody(
|
protected function getTransactionsForMail(
|
||||||
PhabricatorLiskDAO $object,
|
PhabricatorLiskDAO $object,
|
||||||
array $xactions) {
|
array $xactions) {
|
||||||
|
|
||||||
$viewer = $this->requireActor();
|
|
||||||
|
|
||||||
// If this is the first time we're sending mail about this revision, we
|
// If this is the first time we're sending mail about this revision, we
|
||||||
// generate mail for all prior transactions, not just whatever is being
|
// generate mail for all prior transactions, not just whatever is being
|
||||||
// applied now. This gets the "added reviewers" lines and other relevant
|
// applied now. This gets the "added reviewers" lines and other relevant
|
||||||
// information into the mail.
|
// information into the mail.
|
||||||
if ($this->isFirstBroadcast()) {
|
if ($this->isFirstBroadcast()) {
|
||||||
$xactions = $this->loadUnbroadcastTransactions($object);
|
return $this->loadUnbroadcastTransactions($object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $xactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildMailBody(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
array $xactions) {
|
||||||
|
|
||||||
|
$viewer = $this->requireActor();
|
||||||
|
|
||||||
$body = new PhabricatorMetaMTAMailBody();
|
$body = new PhabricatorMetaMTAMailBody();
|
||||||
$body->setViewer($this->requireActor());
|
$body->setViewer($this->requireActor());
|
||||||
|
|
||||||
|
@ -1565,9 +1571,29 @@ final class DifferentialTransactionEditor
|
||||||
|
|
||||||
|
|
||||||
protected function didApplyTransactions($object, array $xactions) {
|
protected function didApplyTransactions($object, array $xactions) {
|
||||||
|
// In a moment, we're going to try to publish draft revisions which have
|
||||||
|
// completed all their builds. However, we only want to do that if the
|
||||||
|
// actor is either the revision author or an omnipotent user (generally,
|
||||||
|
// the Harbormaster application).
|
||||||
|
|
||||||
|
// If we let any actor publish the revision as a side effect of other
|
||||||
|
// changes then an unlucky third party who innocently comments on the draft
|
||||||
|
// can end up racing Harbormaster and promoting the revision. At best, this
|
||||||
|
// is confusing. It can also run into validation problems with the "Request
|
||||||
|
// Review" transaction. See PHI309 for some discussion.
|
||||||
|
$author_phid = $object->getAuthorPHID();
|
||||||
|
$viewer = $this->requireActor();
|
||||||
|
$can_undraft =
|
||||||
|
($this->getActingAsPHID() === $author_phid) ||
|
||||||
|
($viewer->isOmnipotent());
|
||||||
|
|
||||||
// If a draft revision has no outstanding builds and we're automatically
|
// If a draft revision has no outstanding builds and we're automatically
|
||||||
// making drafts public after builds finish, make the revision public.
|
// making drafts public after builds finish, make the revision public.
|
||||||
|
if ($can_undraft) {
|
||||||
$auto_undraft = !$object->getHoldAsDraft();
|
$auto_undraft = !$object->getHoldAsDraft();
|
||||||
|
} else {
|
||||||
|
$auto_undraft = false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($object->isDraft() && $auto_undraft) {
|
if ($object->isDraft() && $auto_undraft) {
|
||||||
$active_builds = $this->hasActiveBuilds($object);
|
$active_builds = $this->hasActiveBuilds($object);
|
||||||
|
@ -1575,7 +1601,6 @@ final class DifferentialTransactionEditor
|
||||||
// When Harbormaster moves a revision out of the draft state, we
|
// When Harbormaster moves a revision out of the draft state, we
|
||||||
// attribute the action to the revision author since this is more
|
// attribute the action to the revision author since this is more
|
||||||
// natural and more useful.
|
// natural and more useful.
|
||||||
$author_phid = $object->getAuthorPHID();
|
|
||||||
|
|
||||||
// Additionally, we change the acting PHID for the transaction set
|
// Additionally, we change the acting PHID for the transaction set
|
||||||
// to the author if it isn't already a user so that mail comes from
|
// to the author if it isn't already a user so that mail comes from
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DifferentialRevisionStatusHeraldField
|
||||||
|
extends DifferentialRevisionHeraldField {
|
||||||
|
|
||||||
|
const FIELDCONST = 'revision.status';
|
||||||
|
|
||||||
|
public function getHeraldFieldName() {
|
||||||
|
return pht('Revision status');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeraldFieldValue($object) {
|
||||||
|
return $object->getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHeraldFieldStandardType() {
|
||||||
|
return self::STANDARD_PHID;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDatasource() {
|
||||||
|
return new DifferentialRevisionStatusDatasource();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDatasourceValueMap() {
|
||||||
|
$map = DifferentialRevisionStatus::getAll();
|
||||||
|
return mpull($map, 'getDisplayName', 'getKey');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -53,12 +53,6 @@ final class HeraldDifferentialDiffAdapter extends HeraldDifferentialAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRepetitionOptions() {
|
|
||||||
return array(
|
|
||||||
HeraldRepetitionPolicyConfig::FIRST,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHeraldName() {
|
public function getHeraldName() {
|
||||||
return pht('New Diff');
|
return pht('New Diff');
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,13 +69,6 @@ final class HeraldDifferentialRevisionAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRepetitionOptions() {
|
|
||||||
return array(
|
|
||||||
HeraldRepetitionPolicyConfig::EVERY,
|
|
||||||
HeraldRepetitionPolicyConfig::FIRST,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function newLegacyAdapter(
|
public static function newLegacyAdapter(
|
||||||
DifferentialRevision $revision,
|
DifferentialRevision $revision,
|
||||||
DifferentialDiff $diff) {
|
DifferentialDiff $diff) {
|
||||||
|
|
|
@ -173,7 +173,7 @@ final class DifferentialChangeset
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAnchorName() {
|
public function getAnchorName() {
|
||||||
return 'change-'.PhabricatorHash::digestForIndex($this->getFilename());
|
return 'change-'.PhabricatorHash::digestForAnchor($this->getFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAbsoluteRepositoryPath(
|
public function getAbsoluteRepositoryPath(
|
||||||
|
|
|
@ -100,6 +100,13 @@ final class DifferentialTransaction
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DifferentialRevisionRequestReviewTransaction::TRANSACTIONTYPE:
|
||||||
|
// Don't hide the initial "X requested review: ..." transaction from
|
||||||
|
// mail or feed even when it occurs during creation. We need this
|
||||||
|
// transaction to survive so we'll generate mail and feed stories when
|
||||||
|
// revisions immediately leave the draft state. See T13035 for
|
||||||
|
// discussion.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::shouldHide();
|
return parent::shouldHide();
|
||||||
|
@ -111,12 +118,6 @@ final class DifferentialTransaction
|
||||||
// Don't hide the initial "X added reviewers: ..." transaction during
|
// Don't hide the initial "X added reviewers: ..." transaction during
|
||||||
// object creation from mail. See T12118 and PHI54.
|
// object creation from mail. See T12118 and PHI54.
|
||||||
return false;
|
return false;
|
||||||
case DifferentialRevisionRequestReviewTransaction::TRANSACTIONTYPE:
|
|
||||||
// Don't hide the initial "X requested review: ..." transaction from
|
|
||||||
// mail even when it occurs during creation. We need this transaction
|
|
||||||
// to survive so we'll generate mail when revisions immediately leave
|
|
||||||
// the draft state. See T13035 for discussion.
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::shouldHideForMail($xactions);
|
return parent::shouldHideForMail($xactions);
|
||||||
|
|
|
@ -204,6 +204,7 @@ final class DifferentialChangesetDetailView extends AphrontView {
|
||||||
'loaded' => $this->getLoaded(),
|
'loaded' => $this->getLoaded(),
|
||||||
'undoTemplates' => hsprintf('%s', $renderer->renderUndoTemplates()),
|
'undoTemplates' => hsprintf('%s', $renderer->renderUndoTemplates()),
|
||||||
'displayPath' => hsprintf('%s', $display_parts),
|
'displayPath' => hsprintf('%s', $display_parts),
|
||||||
|
'path' => $display_filename,
|
||||||
'icon' => $display_icon,
|
'icon' => $display_icon,
|
||||||
),
|
),
|
||||||
'class' => $class,
|
'class' => $class,
|
||||||
|
|
|
@ -124,6 +124,9 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DiffusionPushLogListController',
|
'(?:query/(?P<queryKey>[^/]+)/)?' => 'DiffusionPushLogListController',
|
||||||
'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController',
|
'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController',
|
||||||
),
|
),
|
||||||
|
'pulllog/' => array(
|
||||||
|
$this->getQueryRoutePattern() => 'DiffusionPullLogListController',
|
||||||
|
),
|
||||||
'(?P<repositoryCallsign>[A-Z]+)' => $repository_routes,
|
'(?P<repositoryCallsign>[A-Z]+)' => $repository_routes,
|
||||||
'(?P<repositoryID>[1-9]\d*)' => $repository_routes,
|
'(?P<repositoryID>[1-9]\d*)' => $repository_routes,
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,12 @@ final class DiffusionSearchQueryConduitAPIMethod
|
||||||
$limit = $request->getValue('limit');
|
$limit = $request->getValue('limit');
|
||||||
$offset = $request->getValue('offset');
|
$offset = $request->getValue('offset');
|
||||||
|
|
||||||
|
// Starting with Git 2.16.0, Git assumes passing an empty argument is
|
||||||
|
// an error and recommends you pass "." instead.
|
||||||
|
if (!strlen($path)) {
|
||||||
|
$path = '.';
|
||||||
|
}
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
$future = $repository->getLocalCommandFuture(
|
$future = $repository->getLocalCommandFuture(
|
||||||
// NOTE: --perl-regexp is available only with libpcre compiled in.
|
// NOTE: --perl-regexp is available only with libpcre compiled in.
|
||||||
|
|
|
@ -658,6 +658,11 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
->appendChild($corpus)
|
->appendChild($corpus)
|
||||||
->addClass('diffusion-mobile-view')
|
->addClass('diffusion-mobile-view')
|
||||||
|
->addSigil('diffusion-file-content-view')
|
||||||
|
->setMetadata(
|
||||||
|
array(
|
||||||
|
'path' => $this->getDiffusionRequest()->getPath(),
|
||||||
|
))
|
||||||
->setCollapsed(true);
|
->setCollapsed(true);
|
||||||
|
|
||||||
$messages = array();
|
$messages = array();
|
||||||
|
@ -947,6 +952,10 @@ final class DiffusionBrowseController extends DiffusionController {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($revision_ids as $commit_phid => $revision_id) {
|
foreach ($revision_ids as $commit_phid => $revision_id) {
|
||||||
|
// If the viewer can't actually see this revision, skip it.
|
||||||
|
if (!isset($revisions[$revision_id])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$revision_map[$commit_map[$commit_phid]] = $revision_id;
|
$revision_map[$commit_map[$commit_phid]] = $revision_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
abstract class DiffusionPushLogController extends DiffusionController {
|
abstract class DiffusionLogController extends DiffusionController {
|
||||||
|
|
||||||
protected function shouldLoadDiffusionRequest() {
|
protected function shouldLoadDiffusionRequest() {
|
||||||
return false;
|
return false;
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionPullLogListController
|
||||||
|
extends DiffusionLogController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
return id(new DiffusionPullLogSearchEngine())
|
||||||
|
->setController($this)
|
||||||
|
->buildResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class DiffusionPushEventViewController
|
final class DiffusionPushEventViewController
|
||||||
extends DiffusionPushLogController {
|
extends DiffusionLogController {
|
||||||
|
|
||||||
public function shouldAllowPublic() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class DiffusionPushLogListController extends DiffusionPushLogController {
|
final class DiffusionPushLogListController
|
||||||
|
extends DiffusionLogController {
|
||||||
public function shouldAllowPublic() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
return id(new PhabricatorRepositoryPushLogSearchEngine())
|
return id(new PhabricatorRepositoryPushLogSearchEngine())
|
||||||
|
|
|
@ -365,7 +365,7 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
|
|
||||||
if ($repository->isHosted()) {
|
if ($repository->isHosted()) {
|
||||||
$push_uri = $this->getApplicationURI(
|
$push_uri = $this->getApplicationURI(
|
||||||
'pushlog/?repositories='.$repository->getMonogram());
|
'pushlog/?repositories='.$repository->getPHID());
|
||||||
|
|
||||||
$action_view->addAction(
|
$action_view->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
|
@ -374,6 +374,15 @@ final class DiffusionRepositoryController extends DiffusionController {
|
||||||
->setHref($push_uri));
|
->setHref($push_uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$pull_uri = $this->getApplicationURI(
|
||||||
|
'pulllog/?repositories='.$repository->getPHID());
|
||||||
|
|
||||||
|
$action_view->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('View Pull Logs'))
|
||||||
|
->setIcon('fa-list-alt')
|
||||||
|
->setHref($pull_uri));
|
||||||
|
|
||||||
return $action_view;
|
return $action_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,15 +104,29 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
try {
|
try {
|
||||||
$remote_addr = $request->getRemoteAddress();
|
$remote_addr = $request->getRemoteAddress();
|
||||||
|
|
||||||
|
if ($request->isHTTPS()) {
|
||||||
|
$remote_protocol = PhabricatorRepositoryPullEvent::PROTOCOL_HTTPS;
|
||||||
|
} else {
|
||||||
|
$remote_protocol = PhabricatorRepositoryPullEvent::PROTOCOL_HTTP;
|
||||||
|
}
|
||||||
|
|
||||||
$pull_event = id(new PhabricatorRepositoryPullEvent())
|
$pull_event = id(new PhabricatorRepositoryPullEvent())
|
||||||
->setEpoch(PhabricatorTime::getNow())
|
->setEpoch(PhabricatorTime::getNow())
|
||||||
->setRemoteAddress($remote_addr)
|
->setRemoteAddress($remote_addr)
|
||||||
->setRemoteProtocol('http');
|
->setRemoteProtocol($remote_protocol);
|
||||||
|
|
||||||
if ($response) {
|
if ($response) {
|
||||||
|
$response_code = $response->getHTTPResponseCode();
|
||||||
|
|
||||||
|
if ($response_code == 200) {
|
||||||
$pull_event
|
$pull_event
|
||||||
->setResultType('wild')
|
->setResultType(PhabricatorRepositoryPullEvent::RESULT_PULL)
|
||||||
->setResultCode($response->getHTTPResponseCode());
|
->setResultCode($response_code);
|
||||||
|
} else {
|
||||||
|
$pull_event
|
||||||
|
->setResultType(PhabricatorRepositoryPullEvent::RESULT_ERROR)
|
||||||
|
->setResultCode($response_code);
|
||||||
|
}
|
||||||
|
|
||||||
if ($response instanceof PhabricatorVCSResponse) {
|
if ($response instanceof PhabricatorVCSResponse) {
|
||||||
$pull_event->setProperties(
|
$pull_event->setProperties(
|
||||||
|
@ -122,7 +136,7 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$pull_event
|
$pull_event
|
||||||
->setResultType('exception')
|
->setResultType(PhabricatorRepositoryPullEvent::RESULT_EXCEPTION)
|
||||||
->setResultCode(500)
|
->setResultCode(500)
|
||||||
->setProperties(
|
->setProperties(
|
||||||
array(
|
array(
|
||||||
|
@ -715,30 +729,19 @@ final class DiffusionServeController extends DiffusionController {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$password_entry = id(new PhabricatorRepositoryVCSPassword())
|
$request = $this->getRequest();
|
||||||
->loadOneWhere('userPHID = %s', $user->getPHID());
|
$content_source = PhabricatorContentSource::newFromRequest($request);
|
||||||
if (!$password_entry) {
|
|
||||||
// User doesn't have a password set.
|
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
|
->setViewer($user)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setPasswordType(PhabricatorAuthPassword::PASSWORD_TYPE_VCS)
|
||||||
|
->setObject($user);
|
||||||
|
|
||||||
|
if (!$engine->isValidPassword($password)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$password_entry->comparePassword($password, $user)) {
|
|
||||||
// Password doesn't match.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user's password is stored using a less-than-optimal hash, upgrade
|
|
||||||
// them to the strongest available hash.
|
|
||||||
|
|
||||||
$hash_envelope = new PhutilOpaqueEnvelope(
|
|
||||||
$password_entry->getPasswordHash());
|
|
||||||
if (PhabricatorPasswordHasher::canUpgradeHash($hash_envelope)) {
|
|
||||||
$password_entry->setPassword($password, $user);
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
|
||||||
$password_entry->save();
|
|
||||||
unset($unguarded);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ final class DiffusionSymbolController extends DiffusionController {
|
||||||
$query->setLanguage($request->getStr('lang'));
|
$query->setLanguage($request->getStr('lang'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$repos = array();
|
||||||
if ($request->getStr('repositories')) {
|
if ($request->getStr('repositories')) {
|
||||||
$phids = $request->getStr('repositories');
|
$phids = $request->getStr('repositories');
|
||||||
$phids = explode(',', $phids);
|
$phids = explode(',', $phids);
|
||||||
|
@ -33,9 +34,9 @@ final class DiffusionSymbolController extends DiffusionController {
|
||||||
->withPHIDs($phids)
|
->withPHIDs($phids)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$repos = mpull($repos, 'getPHID');
|
$repo_phids = mpull($repos, 'getPHID');
|
||||||
if ($repos) {
|
if ($repo_phids) {
|
||||||
$query->withRepositoryPHIDs($repos);
|
$query->withRepositoryPHIDs($repo_phids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,6 @@ final class DiffusionSymbolController extends DiffusionController {
|
||||||
|
|
||||||
$symbols = $query->execute();
|
$symbols = $query->execute();
|
||||||
|
|
||||||
|
|
||||||
$external_query = id(new DiffusionExternalSymbolQuery())
|
$external_query = id(new DiffusionExternalSymbolQuery())
|
||||||
->withNames(array($name));
|
->withNames(array($name));
|
||||||
|
|
||||||
|
@ -61,13 +61,51 @@ final class DiffusionSymbolController extends DiffusionController {
|
||||||
$external_query->withLanguages(array($request->getStr('lang')));
|
$external_query->withLanguages(array($request->getStr('lang')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($request->getStr('path')) {
|
||||||
|
$external_query->withPaths(array($request->getStr('path')));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->getInt('line')) {
|
||||||
|
$external_query->withLines(array($request->getInt('line')));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->getInt('char')) {
|
||||||
|
$external_query->withCharacterPositions(
|
||||||
|
array(
|
||||||
|
$request->getInt('char'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($repos) {
|
||||||
|
$external_query->withRepositories($repos);
|
||||||
|
}
|
||||||
|
|
||||||
$external_sources = id(new PhutilClassMapQuery())
|
$external_sources = id(new PhutilClassMapQuery())
|
||||||
->setAncestorClass('DiffusionExternalSymbolsSource')
|
->setAncestorClass('DiffusionExternalSymbolsSource')
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$results = array($symbols);
|
$results = array($symbols);
|
||||||
foreach ($external_sources as $source) {
|
foreach ($external_sources as $source) {
|
||||||
$results[] = $source->executeQuery($external_query);
|
$source_results = $source->executeQuery($external_query);
|
||||||
|
|
||||||
|
if (!is_array($source_results)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Expected a list of results from external symbol source "%s".',
|
||||||
|
get_class($source)));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
assert_instances_of($source_results, 'PhabricatorRepositorySymbol');
|
||||||
|
} catch (InvalidArgumentException $ex) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Expected a list of PhabricatorRepositorySymbol objects '.
|
||||||
|
'from external symbol source "%s".',
|
||||||
|
get_class($source)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$results[] = $source_results;
|
||||||
}
|
}
|
||||||
$symbols = array_mergev($results);
|
$symbols = array_mergev($results);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,11 @@ final class DiffusionCommitReviewerHeraldField
|
||||||
const FIELDCONST = 'diffusion.commit.reviewer';
|
const FIELDCONST = 'diffusion.commit.reviewer';
|
||||||
|
|
||||||
public function getHeraldFieldName() {
|
public function getHeraldFieldName() {
|
||||||
return pht('Reviewer');
|
return pht('Reviewer (Deprecated)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFieldGroupKey() {
|
||||||
|
return HeraldDeprecatedFieldGroup::FIELDGROUPKEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHeraldFieldValue($object) {
|
public function getHeraldFieldValue($object) {
|
||||||
|
|
|
@ -209,7 +209,7 @@ final class HeraldCommitAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadCommitDiff() {
|
private function loadCommitDiff() {
|
||||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$byte_limit = self::getEnormousByteLimit();
|
$byte_limit = self::getEnormousByteLimit();
|
||||||
$time_limit = self::getEnormousTimeLimit();
|
$time_limit = self::getEnormousTimeLimit();
|
||||||
|
|
|
@ -35,13 +35,20 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
||||||
$request,
|
$request,
|
||||||
'/settings/');
|
'/settings/');
|
||||||
|
|
||||||
$vcspassword = id(new PhabricatorRepositoryVCSPassword())
|
$vcs_type = PhabricatorAuthPassword::PASSWORD_TYPE_VCS;
|
||||||
->loadOneWhere(
|
|
||||||
'userPHID = %s',
|
$vcspasswords = id(new PhabricatorAuthPasswordQuery())
|
||||||
$user->getPHID());
|
->setViewer($viewer)
|
||||||
if (!$vcspassword) {
|
->withObjectPHIDs(array($user->getPHID()))
|
||||||
$vcspassword = id(new PhabricatorRepositoryVCSPassword());
|
->withPasswordTypes(array($vcs_type))
|
||||||
$vcspassword->setUserPHID($user->getPHID());
|
->withIsRevoked(false)
|
||||||
|
->execute();
|
||||||
|
if ($vcspasswords) {
|
||||||
|
$vcspassword = head($vcspasswords);
|
||||||
|
} else {
|
||||||
|
$vcspassword = PhabricatorAuthPassword::initializeNewPassword(
|
||||||
|
$user,
|
||||||
|
$vcs_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
$panel_uri = $this->getPanelURI('?saved=true');
|
$panel_uri = $this->getPanelURI('?saved=true');
|
||||||
|
@ -51,6 +58,19 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
||||||
$e_password = true;
|
$e_password = true;
|
||||||
$e_confirm = true;
|
$e_confirm = true;
|
||||||
|
|
||||||
|
$content_source = PhabricatorContentSource::newFromRequest($request);
|
||||||
|
|
||||||
|
// NOTE: This test is against $viewer (not $user), so that the error
|
||||||
|
// message below makes sense in the case that the two are different,
|
||||||
|
// and because an admin reusing their own password is bad, while
|
||||||
|
// system agents generally do not have passwords anyway.
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setObject($viewer)
|
||||||
|
->setPasswordType($vcs_type);
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
if ($request->isFormPost()) {
|
||||||
if ($request->getBool('remove')) {
|
if ($request->getBool('remove')) {
|
||||||
if ($vcspassword->getID()) {
|
if ($vcspassword->getID()) {
|
||||||
|
@ -61,64 +81,28 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
||||||
|
|
||||||
$new_password = $request->getStr('password');
|
$new_password = $request->getStr('password');
|
||||||
$confirm = $request->getStr('confirm');
|
$confirm = $request->getStr('confirm');
|
||||||
if (!strlen($new_password)) {
|
|
||||||
$e_password = pht('Required');
|
|
||||||
$errors[] = pht('Password is required.');
|
|
||||||
} else {
|
|
||||||
$e_password = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strlen($confirm)) {
|
|
||||||
$e_confirm = pht('Required');
|
|
||||||
$errors[] = pht('You must confirm the new password.');
|
|
||||||
} else {
|
|
||||||
$e_confirm = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors) {
|
|
||||||
$envelope = new PhutilOpaqueEnvelope($new_password);
|
$envelope = new PhutilOpaqueEnvelope($new_password);
|
||||||
|
$confirm_envelope = new PhutilOpaqueEnvelope($confirm);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// NOTE: This test is against $viewer (not $user), so that the error
|
$engine->checkNewPassword($envelope, $confirm_envelope);
|
||||||
// message below makes sense in the case that the two are different,
|
$e_password = null;
|
||||||
// and because an admin reusing their own password is bad, while
|
$e_confirm = null;
|
||||||
// system agents generally do not have passwords anyway.
|
} catch (PhabricatorAuthPasswordException $ex) {
|
||||||
|
$errors[] = $ex->getMessage();
|
||||||
$same_password = $viewer->comparePassword($envelope);
|
$e_password = $ex->getPasswordError();
|
||||||
} catch (PhabricatorPasswordHasherUnavailableException $ex) {
|
$e_confirm = $ex->getConfirmError();
|
||||||
// If we're missing the hasher, just let the user continue.
|
|
||||||
$same_password = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($new_password !== $confirm) {
|
|
||||||
$e_password = pht('Does Not Match');
|
|
||||||
$e_confirm = pht('Does Not Match');
|
|
||||||
$errors[] = pht('Password and confirmation do not match.');
|
|
||||||
} else if ($same_password) {
|
|
||||||
$e_password = pht('Not Unique');
|
|
||||||
$e_confirm = pht('Not Unique');
|
|
||||||
$errors[] = pht(
|
|
||||||
'This password is the same as another password associated '.
|
|
||||||
'with your account. You must use a unique password for '.
|
|
||||||
'VCS access.');
|
|
||||||
} else if (
|
|
||||||
PhabricatorCommonPasswords::isCommonPassword($new_password)) {
|
|
||||||
$e_password = pht('Very Weak');
|
|
||||||
$e_confirm = pht('Very Weak');
|
|
||||||
$errors[] = pht(
|
|
||||||
'This password is extremely weak: it is one of the most common '.
|
|
||||||
'passwords in use. Choose a stronger password.');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$vcspassword->setPassword($envelope, $user);
|
$vcspassword
|
||||||
$vcspassword->save();
|
->setPassword($envelope, $user)
|
||||||
|
->save();
|
||||||
|
|
||||||
return id(new AphrontRedirectResponse())->setURI($panel_uri);
|
return id(new AphrontRedirectResponse())->setURI($panel_uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$title = pht('Set VCS Password');
|
$title = pht('Set VCS Password');
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ final class DiffusionGitCommandEngine
|
||||||
$env['HOME'] = PhabricatorEnv::getEmptyCWD();
|
$env['HOME'] = PhabricatorEnv::getEmptyCWD();
|
||||||
|
|
||||||
$env['GIT_SSH'] = $this->getSSHWrapper();
|
$env['GIT_SSH'] = $this->getSSHWrapper();
|
||||||
|
$env['GIT_SSH_VARIANT'] = 'ssh';
|
||||||
|
|
||||||
if ($this->isAnyHTTPProtocol()) {
|
if ($this->isAnyHTTPProtocol()) {
|
||||||
$uri = $this->getURI();
|
$uri = $this->getURI();
|
||||||
|
|
|
@ -88,7 +88,7 @@ abstract class DiffusionFileFutureQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected function executeQuery() {
|
final protected function executeQuery() {
|
||||||
$future = $this->newQueryFuture();
|
$future = $this->newConfiguredQueryFuture();
|
||||||
|
|
||||||
$drequest = $this->getRequest();
|
$drequest = $this->getRequest();
|
||||||
|
|
||||||
|
@ -105,6 +105,11 @@ abstract class DiffusionFileFutureQuery
|
||||||
->setViewPolicy(PhabricatorPolicies::POLICY_NOONE)
|
->setViewPolicy(PhabricatorPolicies::POLICY_NOONE)
|
||||||
->setExecFuture($future);
|
->setExecFuture($future);
|
||||||
|
|
||||||
|
$byte_limit = $this->getByteLimit();
|
||||||
|
if ($byte_limit) {
|
||||||
|
$source->setByteLimit($byte_limit);
|
||||||
|
}
|
||||||
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
$file = $source->uploadFile();
|
$file = $source->uploadFile();
|
||||||
unset($unguarded);
|
unset($unguarded);
|
||||||
|
@ -116,18 +121,8 @@ abstract class DiffusionFileFutureQuery
|
||||||
|
|
||||||
$this->didHitTimeLimit = true;
|
$this->didHitTimeLimit = true;
|
||||||
$file = null;
|
$file = null;
|
||||||
}
|
} catch (PhabricatorFileUploadSourceByteLimitException $ex) {
|
||||||
|
|
||||||
$byte_limit = $this->getByteLimit();
|
|
||||||
|
|
||||||
if ($byte_limit && ($file->getByteSize() > $byte_limit)) {
|
|
||||||
$this->didHitByteLimit = true;
|
$this->didHitByteLimit = true;
|
||||||
|
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
|
||||||
id(new PhabricatorDestructionEngine())
|
|
||||||
->destroyObject($file);
|
|
||||||
unset($unguarded);
|
|
||||||
|
|
||||||
$file = null;
|
$file = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,11 +136,6 @@ abstract class DiffusionFileFutureQuery
|
||||||
$future->setTimeout($this->getTimeout());
|
$future->setTimeout($this->getTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
$byte_limit = $this->getByteLimit();
|
|
||||||
if ($byte_limit) {
|
|
||||||
$future->setStdoutSizeLimit($byte_limit + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $future;
|
return $future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionPullLogSearchEngine
|
||||||
|
extends PhabricatorApplicationSearchEngine {
|
||||||
|
|
||||||
|
public function getResultTypeDescription() {
|
||||||
|
return pht('Pull Logs');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationClassName() {
|
||||||
|
return 'PhabricatorDiffusionApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newQuery() {
|
||||||
|
return new PhabricatorRepositoryPullEventQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildQueryFromParameters(array $map) {
|
||||||
|
$query = $this->newQuery();
|
||||||
|
|
||||||
|
if ($map['repositoryPHIDs']) {
|
||||||
|
$query->withRepositoryPHIDs($map['repositoryPHIDs']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($map['pullerPHIDs']) {
|
||||||
|
$query->withPullerPHIDs($map['pullerPHIDs']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildCustomSearchFields() {
|
||||||
|
return array(
|
||||||
|
id(new PhabricatorSearchDatasourceField())
|
||||||
|
->setDatasource(new DiffusionRepositoryDatasource())
|
||||||
|
->setKey('repositoryPHIDs')
|
||||||
|
->setAliases(array('repository', 'repositories', 'repositoryPHID'))
|
||||||
|
->setLabel(pht('Repositories'))
|
||||||
|
->setDescription(
|
||||||
|
pht('Search for pull logs for specific repositories.')),
|
||||||
|
id(new PhabricatorUsersSearchField())
|
||||||
|
->setKey('pullerPHIDs')
|
||||||
|
->setAliases(array('puller', 'pullers', 'pullerPHID'))
|
||||||
|
->setLabel(pht('Pullers'))
|
||||||
|
->setDescription(
|
||||||
|
pht('Search for pull logs by specific users.')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newExportFields() {
|
||||||
|
return array(
|
||||||
|
id(new PhabricatorIDExportField())
|
||||||
|
->setKey('id')
|
||||||
|
->setLabel(pht('ID')),
|
||||||
|
id(new PhabricatorPHIDExportField())
|
||||||
|
->setKey('phid')
|
||||||
|
->setLabel(pht('PHID')),
|
||||||
|
id(new PhabricatorPHIDExportField())
|
||||||
|
->setKey('repositoryPHID')
|
||||||
|
->setLabel(pht('Repository PHID')),
|
||||||
|
id(new PhabricatorStringExportField())
|
||||||
|
->setKey('repository')
|
||||||
|
->setLabel(pht('Repository')),
|
||||||
|
id(new PhabricatorPHIDExportField())
|
||||||
|
->setKey('pullerPHID')
|
||||||
|
->setLabel(pht('Puller PHID')),
|
||||||
|
id(new PhabricatorStringExportField())
|
||||||
|
->setKey('puller')
|
||||||
|
->setLabel(pht('Puller')),
|
||||||
|
id(new PhabricatorStringExportField())
|
||||||
|
->setKey('protocol')
|
||||||
|
->setLabel(pht('Protocol')),
|
||||||
|
id(new PhabricatorStringExportField())
|
||||||
|
->setKey('result')
|
||||||
|
->setLabel(pht('Result')),
|
||||||
|
id(new PhabricatorIntExportField())
|
||||||
|
->setKey('code')
|
||||||
|
->setLabel(pht('Code')),
|
||||||
|
id(new PhabricatorEpochExportField())
|
||||||
|
->setKey('date')
|
||||||
|
->setLabel(pht('Date')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newExport(array $events) {
|
||||||
|
$viewer = $this->requireViewer();
|
||||||
|
|
||||||
|
$phids = array();
|
||||||
|
foreach ($events as $event) {
|
||||||
|
if ($event->getPullerPHID()) {
|
||||||
|
$phids[] = $event->getPullerPHID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$handles = $viewer->loadHandles($phids);
|
||||||
|
|
||||||
|
$export = array();
|
||||||
|
foreach ($events as $event) {
|
||||||
|
$repository = $event->getRepository();
|
||||||
|
if ($repository) {
|
||||||
|
$repository_phid = $repository->getPHID();
|
||||||
|
$repository_name = $repository->getDisplayName();
|
||||||
|
} else {
|
||||||
|
$repository_phid = null;
|
||||||
|
$repository_name = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$puller_phid = $event->getPullerPHID();
|
||||||
|
if ($puller_phid) {
|
||||||
|
$puller_name = $handles[$puller_phid]->getName();
|
||||||
|
} else {
|
||||||
|
$puller_name = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$export[] = array(
|
||||||
|
'id' => $event->getID(),
|
||||||
|
'phid' => $event->getPHID(),
|
||||||
|
'repositoryPHID' => $repository_phid,
|
||||||
|
'repository' => $repository_name,
|
||||||
|
'pullerPHID' => $puller_phid,
|
||||||
|
'puller' => $puller_name,
|
||||||
|
'protocol' => $event->getRemoteProtocol(),
|
||||||
|
'result' => $event->getResultType(),
|
||||||
|
'code' => $event->getResultCode(),
|
||||||
|
'date' => $event->getEpoch(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $export;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getURI($path) {
|
||||||
|
return '/diffusion/pulllog/'.$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getBuiltinQueryNames() {
|
||||||
|
return array(
|
||||||
|
'all' => pht('All Pull Logs'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromBuiltin($query_key) {
|
||||||
|
$query = $this->newSavedQuery();
|
||||||
|
$query->setQueryKey($query_key);
|
||||||
|
|
||||||
|
switch ($query_key) {
|
||||||
|
case 'all':
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderResultList(
|
||||||
|
array $logs,
|
||||||
|
PhabricatorSavedQuery $query,
|
||||||
|
array $handles) {
|
||||||
|
|
||||||
|
$table = id(new DiffusionPullLogListView())
|
||||||
|
->setViewer($this->requireViewer())
|
||||||
|
->setLogs($logs);
|
||||||
|
|
||||||
|
return id(new PhabricatorApplicationSearchResultView())
|
||||||
|
->setTable($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ final class DiffusionGitReceivePackSSHWorkflow extends DiffusionGitSSHWorkflow {
|
||||||
|
|
||||||
protected function executeRepositoryOperations() {
|
protected function executeRepositoryOperations() {
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$viewer = $this->getUser();
|
$viewer = $this->getSSHUser();
|
||||||
$device = AlmanacKeys::getLiveDevice();
|
$device = AlmanacKeys::getLiveDevice();
|
||||||
|
|
||||||
// This is a write, and must have write access.
|
// This is a write, and must have write access.
|
||||||
|
|
|
@ -15,7 +15,7 @@ final class DiffusionGitUploadPackSSHWorkflow extends DiffusionGitSSHWorkflow {
|
||||||
|
|
||||||
protected function executeRepositoryOperations() {
|
protected function executeRepositoryOperations() {
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$viewer = $this->getUser();
|
$viewer = $this->getSSHUser();
|
||||||
$device = AlmanacKeys::getLiveDevice();
|
$device = AlmanacKeys::getLiveDevice();
|
||||||
|
|
||||||
$skip_sync = $this->shouldSkipReadSynchronization();
|
$skip_sync = $this->shouldSkipReadSynchronization();
|
||||||
|
@ -61,11 +61,11 @@ final class DiffusionGitUploadPackSSHWorkflow extends DiffusionGitSSHWorkflow {
|
||||||
|
|
||||||
if ($err) {
|
if ($err) {
|
||||||
$pull_event
|
$pull_event
|
||||||
->setResultType('error')
|
->setResultType(PhabricatorRepositoryPullEvent::RESULT_ERROR)
|
||||||
->setResultCode($err);
|
->setResultCode($err);
|
||||||
} else {
|
} else {
|
||||||
$pull_event
|
$pull_event
|
||||||
->setResultType('pull')
|
->setResultType(PhabricatorRepositoryPullEvent::RESULT_PULL)
|
||||||
->setResultCode(0);
|
->setResultCode(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
|
|
||||||
public function getEnvironment() {
|
public function getEnvironment() {
|
||||||
$env = array(
|
$env = array(
|
||||||
DiffusionCommitHookEngine::ENV_USER => $this->getUser()->getUsername(),
|
DiffusionCommitHookEngine::ENV_USER => $this->getSSHUser()->getUsername(),
|
||||||
DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL => 'ssh',
|
DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL => 'ssh',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -122,14 +122,14 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
$key_path,
|
$key_path,
|
||||||
$port,
|
$port,
|
||||||
$host,
|
$host,
|
||||||
'@'.$this->getUser()->getUsername(),
|
'@'.$this->getSSHUser()->getUsername(),
|
||||||
$this->getOriginalArguments());
|
$this->getOriginalArguments());
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function execute(PhutilArgumentParser $args) {
|
final public function execute(PhutilArgumentParser $args) {
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
|
|
||||||
$viewer = $this->getUser();
|
$viewer = $this->getSSHUser();
|
||||||
$have_diffusion = PhabricatorApplication::isClassInstalledForViewer(
|
$have_diffusion = PhabricatorApplication::isClassInstalledForViewer(
|
||||||
'PhabricatorDiffusionApplication',
|
'PhabricatorDiffusionApplication',
|
||||||
$viewer);
|
$viewer);
|
||||||
|
@ -164,7 +164,7 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadRepositoryWithPath($path, $vcs) {
|
protected function loadRepositoryWithPath($path, $vcs) {
|
||||||
$viewer = $this->getUser();
|
$viewer = $this->getSSHUser();
|
||||||
|
|
||||||
$info = PhabricatorRepository::parseRepositoryServicePath($path, $vcs);
|
$info = PhabricatorRepository::parseRepositoryServicePath($path, $vcs);
|
||||||
if ($info === null) {
|
if ($info === null) {
|
||||||
|
@ -214,7 +214,7 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$viewer = $this->getUser();
|
$viewer = $this->getSSHUser();
|
||||||
|
|
||||||
if ($viewer->isOmnipotent()) {
|
if ($viewer->isOmnipotent()) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
@ -252,7 +252,7 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function shouldSkipReadSynchronization() {
|
protected function shouldSkipReadSynchronization() {
|
||||||
$viewer = $this->getUser();
|
$viewer = $this->getSSHUser();
|
||||||
|
|
||||||
// Currently, the only case where devices interact over SSH without
|
// Currently, the only case where devices interact over SSH without
|
||||||
// assuming user credentials is when synchronizing before a read. These
|
// assuming user credentials is when synchronizing before a read. These
|
||||||
|
@ -265,14 +265,14 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newPullEvent() {
|
protected function newPullEvent() {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getSSHUser();
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
$remote_address = $this->getSSHRemoteAddress();
|
$remote_address = $this->getSSHRemoteAddress();
|
||||||
|
|
||||||
return id(new PhabricatorRepositoryPullEvent())
|
return id(new PhabricatorRepositoryPullEvent())
|
||||||
->setEpoch(PhabricatorTime::getNow())
|
->setEpoch(PhabricatorTime::getNow())
|
||||||
->setRemoteAddress($remote_address)
|
->setRemoteAddress($remote_address)
|
||||||
->setRemoteProtocol('ssh')
|
->setRemoteProtocol(PhabricatorRepositoryPullEvent::PROTOCOL_SSH)
|
||||||
->setPullerPHID($viewer->getPHID())
|
->setPullerPHID($viewer->getPHID())
|
||||||
->setRepositoryPHID($repository->getPHID());
|
->setRepositoryPHID($repository->getPHID());
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ final class DiffusionSubversionServeSSHWorkflow
|
||||||
} else {
|
} else {
|
||||||
$command = csprintf(
|
$command = csprintf(
|
||||||
'svnserve -t --tunnel-user=%s',
|
'svnserve -t --tunnel-user=%s',
|
||||||
$this->getUser()->getUsername());
|
$this->getSSHUser()->getUsername());
|
||||||
$cwd = PhabricatorEnv::getEmptyCWD();
|
$cwd = PhabricatorEnv::getEmptyCWD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,93 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class DiffusionExternalSymbolQuery extends Phobject {
|
final class DiffusionExternalSymbolQuery extends Phobject {
|
||||||
|
|
||||||
private $languages = array();
|
private $languages = array();
|
||||||
private $types = array();
|
private $types = array();
|
||||||
private $names = array();
|
private $names = array();
|
||||||
private $contexts = array();
|
private $contexts = array();
|
||||||
|
private $paths = array();
|
||||||
|
private $lines = array();
|
||||||
|
private $repositories = array();
|
||||||
|
private $characterPositions = array();
|
||||||
|
|
||||||
public function withLanguages(array $languages) {
|
public function withLanguages(array $languages) {
|
||||||
$this->languages = $languages;
|
$this->languages = $languages;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withTypes(array $types) {
|
public function withTypes(array $types) {
|
||||||
$this->types = $types;
|
$this->types = $types;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withNames(array $names) {
|
public function withNames(array $names) {
|
||||||
$this->names = $names;
|
$this->names = $names;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withContexts(array $contexts) {
|
public function withContexts(array $contexts) {
|
||||||
$this->contexts = $contexts;
|
$this->contexts = $contexts;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withPaths(array $paths) {
|
||||||
|
$this->paths = $paths;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withLines(array $lines) {
|
||||||
|
$this->lines = $lines;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withCharacterPositions(array $positions) {
|
||||||
|
$this->characterPositions = $positions;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withRepositories(array $repositories) {
|
||||||
|
assert_instances_of($repositories, 'PhabricatorRepository');
|
||||||
|
$this->repositories = $repositories;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getLanguages() {
|
public function getLanguages() {
|
||||||
return $this->languages;
|
return $this->languages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTypes() {
|
public function getTypes() {
|
||||||
return $this->types;
|
return $this->types;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNames() {
|
public function getNames() {
|
||||||
return $this->names;
|
return $this->names;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getContexts() {
|
public function getContexts() {
|
||||||
return $this->contexts;
|
return $this->contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPaths() {
|
||||||
|
return $this->paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLines() {
|
||||||
|
return $this->lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRepositories() {
|
||||||
|
return $this->repositories;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCharacterPositions() {
|
||||||
|
return $this->characterPositions;
|
||||||
|
}
|
||||||
|
|
||||||
public function matchesAnyLanguage(array $languages) {
|
public function matchesAnyLanguage(array $languages) {
|
||||||
return (!$this->languages) || array_intersect($languages, $this->languages);
|
return (!$this->languages) || array_intersect($languages, $this->languages);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function matchesAnyType(array $types) {
|
public function matchesAnyType(array $types) {
|
||||||
return (!$this->types) || array_intersect($types, $this->types);
|
return (!$this->types) || array_intersect($types, $this->types);
|
||||||
}
|
}
|
||||||
|
|
115
src/applications/diffusion/view/DiffusionPullLogListView.php
Normal file
115
src/applications/diffusion/view/DiffusionPullLogListView.php
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionPullLogListView extends AphrontView {
|
||||||
|
|
||||||
|
private $logs;
|
||||||
|
|
||||||
|
public function setLogs(array $logs) {
|
||||||
|
assert_instances_of($logs, 'PhabricatorRepositoryPullEvent');
|
||||||
|
$this->logs = $logs;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() {
|
||||||
|
$events = $this->logs;
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$handle_phids = array();
|
||||||
|
foreach ($events as $event) {
|
||||||
|
if ($event->getPullerPHID()) {
|
||||||
|
$handle_phids[] = $event->getPullerPHID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$handles = $viewer->loadHandles($handle_phids);
|
||||||
|
|
||||||
|
// Figure out which repositories are editable. We only let you see remote
|
||||||
|
// IPs if you have edit capability on a repository.
|
||||||
|
$editable_repos = array();
|
||||||
|
if ($events) {
|
||||||
|
$editable_repos = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->withPHIDs(mpull($events, 'getRepositoryPHID'))
|
||||||
|
->execute();
|
||||||
|
$editable_repos = mpull($editable_repos, null, 'getPHID');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
$any_host = false;
|
||||||
|
foreach ($events as $event) {
|
||||||
|
if ($event->getRepositoryPHID()) {
|
||||||
|
$repository = $event->getRepository();
|
||||||
|
} else {
|
||||||
|
$repository = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reveal this if it's valid and the user can edit the repository. For
|
||||||
|
// invalid requests you currently have to go fishing in the database.
|
||||||
|
$remote_address = '-';
|
||||||
|
if ($repository) {
|
||||||
|
if (isset($editable_repos[$event->getRepositoryPHID()])) {
|
||||||
|
$remote_address = $event->getRemoteAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$event_id = $event->getID();
|
||||||
|
|
||||||
|
$repository_link = null;
|
||||||
|
if ($repository) {
|
||||||
|
$repository_link = phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $repository->getURI(),
|
||||||
|
),
|
||||||
|
$repository->getDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
$puller_link = null;
|
||||||
|
if ($event->getPullerPHID()) {
|
||||||
|
$puller_link = $viewer->renderHandle($event->getPullerPHID());
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
$event_id,
|
||||||
|
$repository_link,
|
||||||
|
$puller_link,
|
||||||
|
$remote_address,
|
||||||
|
$event->getRemoteProtocolDisplayName(),
|
||||||
|
$event->newResultIcon(),
|
||||||
|
$event->getResultCode(),
|
||||||
|
phabricator_datetime($event->getEpoch(), $viewer),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = id(new AphrontTableView($rows))
|
||||||
|
->setHeaders(
|
||||||
|
array(
|
||||||
|
pht('Pull'),
|
||||||
|
pht('Repository'),
|
||||||
|
pht('Puller'),
|
||||||
|
pht('From'),
|
||||||
|
pht('Via'),
|
||||||
|
null,
|
||||||
|
pht('Code'),
|
||||||
|
pht('Date'),
|
||||||
|
))
|
||||||
|
->setColumnClasses(
|
||||||
|
array(
|
||||||
|
'n',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'n',
|
||||||
|
'wide',
|
||||||
|
'',
|
||||||
|
'n',
|
||||||
|
'right',
|
||||||
|
));
|
||||||
|
|
||||||
|
return $table;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ abstract class PhabricatorFileUploadSource
|
||||||
private $shouldChunk;
|
private $shouldChunk;
|
||||||
private $didRewind;
|
private $didRewind;
|
||||||
private $totalBytesWritten = 0;
|
private $totalBytesWritten = 0;
|
||||||
|
private $totalBytesRead = 0;
|
||||||
|
private $byteLimit = 0;
|
||||||
|
|
||||||
public function setName($name) {
|
public function setName($name) {
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
@ -40,6 +42,15 @@ abstract class PhabricatorFileUploadSource
|
||||||
return $this->viewPolicy;
|
return $this->viewPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setByteLimit($byte_limit) {
|
||||||
|
$this->byteLimit = $byte_limit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getByteLimit() {
|
||||||
|
return $this->byteLimit;
|
||||||
|
}
|
||||||
|
|
||||||
public function uploadFile() {
|
public function uploadFile() {
|
||||||
if (!$this->shouldChunkFile()) {
|
if (!$this->shouldChunkFile()) {
|
||||||
return $this->writeSingleFile();
|
return $this->writeSingleFile();
|
||||||
|
@ -81,8 +92,15 @@ abstract class PhabricatorFileUploadSource
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$read_bytes = $data->current();
|
||||||
|
$this->totalBytesRead += strlen($read_bytes);
|
||||||
|
|
||||||
|
if ($this->byteLimit && ($this->totalBytesRead > $this->byteLimit)) {
|
||||||
|
throw new PhabricatorFileUploadSourceByteLimitException();
|
||||||
|
}
|
||||||
|
|
||||||
$rope = $this->getRope();
|
$rope = $this->getRope();
|
||||||
$rope->append($data->current());
|
$rope->append($read_bytes);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -160,8 +178,10 @@ abstract class PhabricatorFileUploadSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have extra bytes at the end, write them.
|
// If we have extra bytes at the end, write them. Note that it's possible
|
||||||
if ($rope->getByteLength()) {
|
// that we have more than one chunk of bytes left if the read was very
|
||||||
|
// fast.
|
||||||
|
while ($rope->getByteLength()) {
|
||||||
$this->writeChunk($file, $engine);
|
$this->writeChunk($file, $engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorFileUploadSourceByteLimitException
|
||||||
|
extends Exception {}
|
|
@ -38,6 +38,7 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
private $actionMap;
|
private $actionMap;
|
||||||
private $edgeCache = array();
|
private $edgeCache = array();
|
||||||
private $forbiddenActions = array();
|
private $forbiddenActions = array();
|
||||||
|
private $viewer;
|
||||||
|
|
||||||
public function getEmailPHIDs() {
|
public function getEmailPHIDs() {
|
||||||
return array_values($this->emailPHIDs);
|
return array_values($this->emailPHIDs);
|
||||||
|
@ -55,10 +56,29 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setViewer(PhabricatorUser $viewer) {
|
||||||
|
$this->viewer = $viewer;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViewer() {
|
||||||
|
// See PHI276. Normally, Herald runs without regard for policy checks.
|
||||||
|
// However, we use a real viewer during test console runs: this makes
|
||||||
|
// intracluster calls to Diffusion APIs work even if web nodes don't
|
||||||
|
// have privileged credentials.
|
||||||
|
|
||||||
|
if ($this->viewer) {
|
||||||
|
return $this->viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PhabricatorUser::getOmnipotentUser();
|
||||||
|
}
|
||||||
|
|
||||||
public function setContentSource(PhabricatorContentSource $content_source) {
|
public function setContentSource(PhabricatorContentSource $content_source) {
|
||||||
$this->contentSource = $content_source;
|
$this->contentSource = $content_source;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getContentSource() {
|
public function getContentSource() {
|
||||||
return $this->contentSource;
|
return $this->contentSource;
|
||||||
}
|
}
|
||||||
|
@ -764,9 +784,20 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
|
|
||||||
|
|
||||||
public function getRepetitionOptions() {
|
public function getRepetitionOptions() {
|
||||||
return array(
|
$options = array();
|
||||||
HeraldRepetitionPolicyConfig::EVERY,
|
|
||||||
);
|
$options[] = HeraldRule::REPEAT_EVERY;
|
||||||
|
|
||||||
|
// Some rules, like pre-commit rules, only ever fire once. It doesn't
|
||||||
|
// make sense to use state-based repetition policies like "only the first
|
||||||
|
// time" for these rules.
|
||||||
|
|
||||||
|
if (!$this->isSingleEventAdapter()) {
|
||||||
|
$options[] = HeraldRule::REPEAT_FIRST;
|
||||||
|
$options[] = HeraldRule::REPEAT_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initializeNewAdapter() {
|
protected function initializeNewAdapter() {
|
||||||
|
@ -887,15 +918,15 @@ abstract class HeraldAdapter extends Phobject {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
$integer_code_for_every = HeraldRepetitionPolicyConfig::toInt(
|
if ($rule->isRepeatFirst()) {
|
||||||
HeraldRepetitionPolicyConfig::EVERY);
|
$action_text = pht(
|
||||||
|
'Take these actions the first time this rule matches:');
|
||||||
if ($rule->getRepetitionPolicy() == $integer_code_for_every) {
|
} else if ($rule->isRepeatOnChange()) {
|
||||||
$action_text =
|
$action_text = pht(
|
||||||
pht('Take these actions every time this rule matches:');
|
'Take these actions if this rule did not match the last time:');
|
||||||
} else {
|
} else {
|
||||||
$action_text =
|
$action_text = pht(
|
||||||
pht('Take these actions the first time this rule matches:');
|
'Take these actions every time this rule matches:');
|
||||||
}
|
}
|
||||||
|
|
||||||
$action_title = phutil_tag(
|
$action_title = phutil_tag(
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class HeraldRepetitionPolicyConfig extends Phobject {
|
|
||||||
|
|
||||||
const FIRST = 'first'; // only execute the first time (no repeating)
|
|
||||||
const EVERY = 'every'; // repeat every time
|
|
||||||
|
|
||||||
private static $policyIntMap = array(
|
|
||||||
self::FIRST => 0,
|
|
||||||
self::EVERY => 1,
|
|
||||||
);
|
|
||||||
|
|
||||||
public static function getMap() {
|
|
||||||
return array(
|
|
||||||
self::EVERY => pht('every time'),
|
|
||||||
self::FIRST => pht('only the first time'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function toInt($str) {
|
|
||||||
return idx(self::$policyIntMap, $str, self::$policyIntMap[self::EVERY]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function toString($int) {
|
|
||||||
return idx(array_flip(self::$policyIntMap), $int, self::EVERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -218,7 +218,7 @@ final class HeraldRuleController extends HeraldController {
|
||||||
),
|
),
|
||||||
pht('New Action')))
|
pht('New Action')))
|
||||||
->setDescription(pht(
|
->setDescription(pht(
|
||||||
'Take these actions %s this rule matches:',
|
'Take these actions %s',
|
||||||
$repetition_selector))
|
$repetition_selector))
|
||||||
->setContent(javelin_tag(
|
->setContent(javelin_tag(
|
||||||
'table',
|
'table',
|
||||||
|
@ -373,8 +373,7 @@ final class HeraldRuleController extends HeraldController {
|
||||||
// mutate current rule, so it would be sent to the client in the right state
|
// mutate current rule, so it would be sent to the client in the right state
|
||||||
$rule->setMustMatchAll((int)$match_all);
|
$rule->setMustMatchAll((int)$match_all);
|
||||||
$rule->setName($new_name);
|
$rule->setName($new_name);
|
||||||
$rule->setRepetitionPolicy(
|
$rule->setRepetitionPolicyStringConstant($repetition_policy_param);
|
||||||
HeraldRepetitionPolicyConfig::toInt($repetition_policy_param));
|
|
||||||
$rule->attachConditions($conditions);
|
$rule->attachConditions($conditions);
|
||||||
$rule->attachActions($actions);
|
$rule->attachActions($actions);
|
||||||
|
|
||||||
|
@ -594,11 +593,10 @@ final class HeraldRuleController extends HeraldController {
|
||||||
* time) this rule matches..." element.
|
* time) this rule matches..." element.
|
||||||
*/
|
*/
|
||||||
private function renderRepetitionSelector($rule, HeraldAdapter $adapter) {
|
private function renderRepetitionSelector($rule, HeraldAdapter $adapter) {
|
||||||
$repetition_policy = HeraldRepetitionPolicyConfig::toString(
|
$repetition_policy = $rule->getRepetitionPolicyStringConstant();
|
||||||
$rule->getRepetitionPolicy());
|
|
||||||
|
|
||||||
$repetition_options = $adapter->getRepetitionOptions();
|
$repetition_options = $adapter->getRepetitionOptions();
|
||||||
$repetition_names = HeraldRepetitionPolicyConfig::getMap();
|
$repetition_names = HeraldRule::getRepetitionPolicySelectOptionMap();
|
||||||
$repetition_map = array_select_keys($repetition_names, $repetition_options);
|
$repetition_map = array_select_keys($repetition_names, $repetition_options);
|
||||||
|
|
||||||
if (count($repetition_map) < 2) {
|
if (count($repetition_map) < 2) {
|
||||||
|
|
|
@ -39,7 +39,9 @@ final class HeraldTestConsoleController extends HeraldController {
|
||||||
$object = $this->getTestObject();
|
$object = $this->getTestObject();
|
||||||
$adapter = $this->getTestAdapter();
|
$adapter = $this->getTestAdapter();
|
||||||
|
|
||||||
$adapter->setIsNewObject(false);
|
$adapter
|
||||||
|
->setIsNewObject(false)
|
||||||
|
->setViewer($viewer);
|
||||||
|
|
||||||
$rules = id(new HeraldRuleQuery())
|
$rules = id(new HeraldRuleQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
|
|
|
@ -66,8 +66,10 @@ final class HeraldRuleEditor
|
||||||
$object->setMustMatchAll((int)$new_state['match_all']);
|
$object->setMustMatchAll((int)$new_state['match_all']);
|
||||||
$object->attachConditions($new_state['conditions']);
|
$object->attachConditions($new_state['conditions']);
|
||||||
$object->attachActions($new_state['actions']);
|
$object->attachActions($new_state['actions']);
|
||||||
$object->setRepetitionPolicy(
|
|
||||||
HeraldRepetitionPolicyConfig::toInt($new_state['repetition_policy']));
|
$new_repetition = $new_state['repetition_policy'];
|
||||||
|
$object->setRepetitionPolicyStringConstant($new_repetition);
|
||||||
|
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ final class HeraldRuleSerializer extends Phobject {
|
||||||
(bool)$rule->getMustMatchAll(),
|
(bool)$rule->getMustMatchAll(),
|
||||||
$rule->getConditions(),
|
$rule->getConditions(),
|
||||||
$rule->getActions(),
|
$rule->getActions(),
|
||||||
HeraldRepetitionPolicyConfig::toString($rule->getRepetitionPolicy()));
|
$rule->getRepetitionPolicyStringConstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function serializeRuleComponents(
|
public function serializeRuleComponents(
|
||||||
|
|
|
@ -14,6 +14,7 @@ final class HeraldEngine extends Phobject {
|
||||||
|
|
||||||
private $forbiddenFields = array();
|
private $forbiddenFields = array();
|
||||||
private $forbiddenActions = array();
|
private $forbiddenActions = array();
|
||||||
|
private $skipEffects = array();
|
||||||
|
|
||||||
public function setDryRun($dry_run) {
|
public function setDryRun($dry_run) {
|
||||||
$this->dryRun = $dry_run;
|
$this->dryRun = $dry_run;
|
||||||
|
@ -68,9 +69,7 @@ final class HeraldEngine extends Phobject {
|
||||||
foreach ($rules as $phid => $rule) {
|
foreach ($rules as $phid => $rule) {
|
||||||
$this->stack = array();
|
$this->stack = array();
|
||||||
|
|
||||||
$policy_first = HeraldRepetitionPolicyConfig::FIRST;
|
$is_first_only = $rule->isRepeatFirst();
|
||||||
$policy_first_int = HeraldRepetitionPolicyConfig::toInt($policy_first);
|
|
||||||
$is_first_only = ($rule->getRepetitionPolicy() == $policy_first_int);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!$this->getDryRun() &&
|
if (!$this->getDryRun() &&
|
||||||
|
@ -173,15 +172,31 @@ final class HeraldEngine extends Phobject {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rules = mpull($rules, null, 'getID');
|
// Update the "applied" state table. How this table works depends on the
|
||||||
$applied_ids = array();
|
// repetition policy for the rule.
|
||||||
$first_policy = HeraldRepetitionPolicyConfig::toInt(
|
//
|
||||||
HeraldRepetitionPolicyConfig::FIRST);
|
// REPEAT_EVERY: We delete existing rows for the rule, then write nothing.
|
||||||
|
// This policy doesn't use any state.
|
||||||
|
//
|
||||||
|
// REPEAT_FIRST: We keep existing rows, then write additional rows for
|
||||||
|
// rules which fired. This policy accumulates state over the life of the
|
||||||
|
// object.
|
||||||
|
//
|
||||||
|
// REPEAT_CHANGE: We delete existing rows, then write all the rows which
|
||||||
|
// matched. This policy only uses the state from the previous run.
|
||||||
|
|
||||||
// Mark all the rules that have had their effects applied as having been
|
$rules = mpull($rules, null, 'getID');
|
||||||
// executed for the current object.
|
|
||||||
$rule_ids = mpull($xscripts, 'getRuleID');
|
$rule_ids = mpull($xscripts, 'getRuleID');
|
||||||
|
|
||||||
|
$delete_ids = array();
|
||||||
|
foreach ($rules as $rule_id => $rule) {
|
||||||
|
if ($rule->isRepeatFirst()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$delete_ids[] = $rule_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$applied_ids = array();
|
||||||
foreach ($rule_ids as $rule_id) {
|
foreach ($rule_ids as $rule_id) {
|
||||||
if (!$rule_id) {
|
if (!$rule_id) {
|
||||||
// Some apply transcripts are purely informational and not associated
|
// Some apply transcripts are purely informational and not associated
|
||||||
|
@ -194,13 +209,30 @@ final class HeraldEngine extends Phobject {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($rule->getRepetitionPolicy() == $first_policy) {
|
if ($rule->isRepeatFirst() || $rule->isRepeatOnChange()) {
|
||||||
$applied_ids[] = $rule_id;
|
$applied_ids[] = $rule_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($applied_ids) {
|
// Also include "only if this rule did not match the last time" rules
|
||||||
|
// which matched but were skipped in the "applied" list.
|
||||||
|
foreach ($this->skipEffects as $rule_id => $ignored) {
|
||||||
|
$applied_ids[] = $rule_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($delete_ids || $applied_ids) {
|
||||||
$conn_w = id(new HeraldRule())->establishConnection('w');
|
$conn_w = id(new HeraldRule())->establishConnection('w');
|
||||||
|
|
||||||
|
if ($delete_ids) {
|
||||||
|
queryfx(
|
||||||
|
$conn_w,
|
||||||
|
'DELETE FROM %T WHERE phid = %s AND ruleID IN (%Ld)',
|
||||||
|
HeraldRule::TABLE_RULE_APPLIED,
|
||||||
|
$adapter->getPHID(),
|
||||||
|
$delete_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($applied_ids) {
|
||||||
$sql = array();
|
$sql = array();
|
||||||
foreach ($applied_ids as $id) {
|
foreach ($applied_ids as $id) {
|
||||||
$sql[] = qsprintf(
|
$sql[] = qsprintf(
|
||||||
|
@ -216,6 +248,7 @@ final class HeraldEngine extends Phobject {
|
||||||
implode(', ', $sql));
|
implode(', ', $sql));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getTranscript() {
|
public function getTranscript() {
|
||||||
$this->transcript->save();
|
$this->transcript->save();
|
||||||
|
@ -315,6 +348,30 @@ final class HeraldEngine extends Phobject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this rule matched, and is set to run "if it did not match the last
|
||||||
|
// time", and we matched the last time, we're going to return a match in
|
||||||
|
// the transcript but set a flag so we don't actually apply any effects.
|
||||||
|
|
||||||
|
// We need the rule to match so that storage gets updated properly. If we
|
||||||
|
// just pretend the rule didn't match it won't cause any effects (which
|
||||||
|
// is correct), but it also won't set the "it matched" flag in storage,
|
||||||
|
// so the next run after this one would incorrectly trigger again.
|
||||||
|
|
||||||
|
$is_dry_run = $this->getDryRun();
|
||||||
|
if ($result && !$is_dry_run) {
|
||||||
|
$is_on_change = $rule->isRepeatOnChange();
|
||||||
|
if ($is_on_change) {
|
||||||
|
$did_apply = $rule->getRuleApplied($object->getPHID());
|
||||||
|
if ($did_apply) {
|
||||||
|
$reason = pht(
|
||||||
|
'This rule matched, but did not take any actions because it '.
|
||||||
|
'is configured to act only if it did not match the last time.');
|
||||||
|
|
||||||
|
$this->skipEffects[$rule->getID()] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->newRuleTranscript($rule)
|
$this->newRuleTranscript($rule)
|
||||||
->setResult($result)
|
->setResult($result)
|
||||||
->setReason($reason);
|
->setReason($reason);
|
||||||
|
@ -367,6 +424,11 @@ final class HeraldEngine extends Phobject {
|
||||||
HeraldRule $rule,
|
HeraldRule $rule,
|
||||||
HeraldAdapter $object) {
|
HeraldAdapter $object) {
|
||||||
|
|
||||||
|
$rule_id = $rule->getID();
|
||||||
|
if (isset($this->skipEffects[$rule_id])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
$effects = array();
|
$effects = array();
|
||||||
foreach ($rule->getActions() as $action) {
|
foreach ($rule->getActions() as $action) {
|
||||||
$effect = id(new HeraldEffect())
|
$effect = id(new HeraldEffect())
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue