Compare commits
568 Commits
blender-tw
...
blender-tw
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
436e69f1d0 | ||
| 5db4b6f01a | |||
| 5aabb434b1 | |||
| eced78a591 | |||
| fb3e6ba493 | |||
| 284204e6bb | |||
| 1df20d771c | |||
| 6fa976f749 | |||
| 8808cf8e8c | |||
| f72b9824f3 | |||
| ac94643ac7 | |||
| ce3c14919d | |||
| c9fb4c2945 | |||
| 57099f29d1 | |||
| acfdc33789 | |||
| a5efb1e8cd | |||
| e0bd65be95 | |||
| 1bcc201b0a | |||
| b2d7879162 | |||
| 775a1c2eef | |||
| bd07cea6a6 | |||
| 6139ce1841 | |||
| c38766c17f | |||
|
|
d203a1004c | ||
|
|
5b1dd96e40 | ||
|
|
36075f6ce5 | ||
|
|
f686a0b827 | ||
|
|
a529efa5b8 | ||
|
|
3635a11f84 | ||
|
|
959a835b95 | ||
|
|
4fd0628fae | ||
|
|
87fb35abb7 | ||
|
|
66566f878d | ||
|
|
d3d41324be | ||
|
|
6d0dbeb77f | ||
|
|
5d0ae283a9 | ||
|
|
d2d7e7f5ff | ||
|
|
10f241352d | ||
|
|
846562158a | ||
|
|
00430fdbe1 | ||
|
|
4b2a447003 | ||
|
|
87bc30526b | ||
|
|
9d5b8bd14a | ||
|
|
4257b26abc | ||
|
|
43a8d8763d | ||
|
|
86d6abe9db | ||
|
|
770a5c8412 | ||
|
|
6cf017d680 | ||
|
|
0c51885cf7 | ||
|
|
f86d822a37 | ||
|
|
7b0db3eb54 | ||
|
|
93b08f0e83 | ||
|
|
e959f93489 | ||
|
|
c666cb9f0b | ||
|
|
b1351d0fdb | ||
|
|
3ee6b5393c | ||
|
|
fbd57ad832 | ||
|
|
b021da71a5 | ||
|
|
42f1a95a12 | ||
|
|
f45519c060 | ||
|
|
cfb5de6fa7 | ||
|
|
2f5398796e | ||
|
|
ebef22ccc1 | ||
|
|
42378ea393 | ||
|
|
c063e0e5ec | ||
|
|
419b7ceebb | ||
|
|
1da54837ea | ||
|
|
3dea92081b | ||
|
|
df139f044b | ||
|
|
e8109e4a92 | ||
|
|
acc1fa1655 | ||
|
|
0cca40db3b | ||
|
|
6dc20d1e2e | ||
|
|
e7ebd5d9d1 | ||
|
|
b804e8cffa | ||
|
|
24ba66f106 | ||
|
|
fa2d30ee36 | ||
|
|
94a95efa05 | ||
|
|
79107574a7 | ||
|
|
983d77848b | ||
|
|
af5b94b234 | ||
|
|
949b9163d0 | ||
|
|
6c59db20a3 | ||
|
|
d0593a5a78 | ||
|
|
c1f1345cc0 | ||
|
|
1656a2ff08 | ||
|
|
397648855f | ||
|
|
0067f1a521 | ||
|
|
a590db28b2 | ||
|
|
6b69102990 | ||
|
|
6430d6d638 | ||
|
|
07e160bde1 | ||
|
|
7fa47408a3 | ||
|
|
3a76248071 | ||
|
|
fe501bd7f7 | ||
|
|
27b7ba814a | ||
|
|
9307f57747 | ||
|
|
63bfad0ff4 | ||
|
|
f5ef341c9e | ||
|
|
67da18e374 | ||
|
|
468aabd4ef | ||
|
|
b2ce0844b6 | ||
|
|
b48a22bf50 | ||
|
|
5ff0ae7d48 | ||
|
|
54ec566281 | ||
|
|
17426a60f0 | ||
|
|
dade977307 | ||
|
|
6f09edeb91 | ||
|
|
b2cfcda114 | ||
|
|
b89e6c0fa9 | ||
|
|
1205070687 | ||
|
|
eab561bb87 | ||
|
|
fbbd2e35cb | ||
|
|
1edca1ee2a | ||
|
|
d6928a3c26 | ||
|
|
3c1f393c81 | ||
|
|
65a2b5e219 | ||
|
|
304467feb2 | ||
|
|
186a12ef7f | ||
|
|
b648a85841 | ||
|
|
f21f1d8ab9 | ||
|
|
a7b2327c34 | ||
|
|
befeb17f6f | ||
|
|
5eaa0f24e7 | ||
|
|
aa20faeaa5 | ||
|
|
6617005365 | ||
|
|
b5bed7b0fa | ||
|
|
604811bfc5 | ||
|
|
c12db28251 | ||
|
|
b0c295e545 | ||
|
|
7355bb7f29 | ||
|
|
a226d74133 | ||
|
|
40d2346f29 | ||
|
|
454ecb56e3 | ||
|
|
6f7147376f | ||
|
|
5a460e4ea5 | ||
|
|
d05d8f6558 | ||
|
|
e20feeeee9 | ||
|
|
4793bfcb7c | ||
|
|
d2572f8b33 | ||
|
|
0ede616f31 | ||
|
|
befbea2f00 | ||
|
|
60de1506fe | ||
|
|
a72a66caa8 | ||
|
|
ff88eb588e | ||
|
|
9550ae6984 | ||
|
|
12eddb18fb | ||
|
|
ba8071bbef | ||
|
|
8cd1f9a309 | ||
|
|
646280972b | ||
|
|
fef2cdabfe | ||
|
|
ef69c7969f | ||
|
|
537ff68edd | ||
|
|
f02024615a | ||
|
|
c79094d7a8 | ||
|
|
7a79131bf2 | ||
|
|
3984c14260 | ||
|
|
4168335619 | ||
|
|
8bdc713352 | ||
|
|
84cd4a3854 | ||
|
|
c3c55d82ae | ||
|
|
8aac55cc57 | ||
|
|
3adf082002 | ||
|
|
3d966d8a41 | ||
|
|
83eb7447a1 | ||
|
|
925d2b051c | ||
|
|
3e676bce9e | ||
|
|
ef1340bd32 | ||
|
|
2748f83e12 | ||
|
|
894d9b6587 | ||
|
|
9bdf477f2f | ||
|
|
fb3f423279 | ||
|
|
b1b9c844ac | ||
|
|
3573170dfa | ||
|
|
d86506052c | ||
|
|
45665dd3b4 | ||
|
|
b52fa96238 | ||
|
|
0ea6d131e0 | ||
|
|
6b05d2be28 | ||
|
|
99cbc20778 | ||
|
|
59c855276b | ||
|
|
4655a5f059 | ||
|
|
b3a8754013 | ||
|
|
0511b2a012 | ||
|
|
143f86d60b | ||
|
|
8fa8d0e648 | ||
|
|
f31b9987ba | ||
|
|
5c30a60e30 | ||
|
|
471e89a8b7 | ||
|
|
19e0abcb27 | ||
|
|
5597f4e6f2 | ||
|
|
c3be82fe6e | ||
|
|
a2fb91b8af | ||
| f9637502ee | |||
|
|
58fbf64a27 | ||
|
|
271e104c7e | ||
|
|
f1d1ec3d77 | ||
|
|
33b73d887a | ||
|
|
1e7cc72cd8 | ||
|
|
1a59cae743 | ||
|
|
067b04aaf1 | ||
|
|
0ddfe6fcfb | ||
|
|
62f5bdbbd2 | ||
|
|
dc57652085 | ||
|
|
d0f4554dbe | ||
|
|
785f3c98da | ||
|
|
d3f4af4a3a | ||
|
|
e58ef418c7 | ||
|
|
802b5aca05 | ||
|
|
84b5ad09e6 | ||
|
|
b8f0613b30 | ||
|
|
faf9f06e0a | ||
|
|
bcaf60015a | ||
|
|
0872051bfa | ||
|
|
05eb16d6de | ||
|
|
e43ecad8af | ||
|
|
4094624828 | ||
|
|
70845a2d13 | ||
|
|
fbf050167e | ||
|
|
149155ee20 | ||
|
|
29923cc71a | ||
|
|
64cc4fe915 | ||
|
|
4790a3d94b | ||
|
|
356d9e8e19 | ||
|
|
dc35ce79e4 | ||
|
|
35a18146a2 | ||
|
|
f9b3e3360b | ||
|
|
8cc6fe465c | ||
|
|
af84f215f9 | ||
|
|
2327578adc | ||
|
|
9d1af762d5 | ||
|
|
fd46c597ae | ||
|
|
fdbe9ba149 | ||
|
|
0e82bd024a | ||
|
|
2a92fef879 | ||
|
|
84fd5cd5bb | ||
|
|
0f1acb6cef | ||
|
|
6d4c6924d6 | ||
|
|
4904d7711e | ||
|
|
530145ba3b | ||
|
|
26c2a1ba68 | ||
|
|
cb481f36c5 | ||
|
|
a72ade9475 | ||
| 5ba0687123 | |||
| fef207bf00 | |||
| 5ef3552549 | |||
| 0f6ca4be21 | |||
| 4653348b13 | |||
| 6826284108 | |||
| c93fdca80d | |||
| 432b6d61a6 | |||
| 4c2b7d7573 | |||
| d8e25a6226 | |||
| db6f4eaab1 | |||
| 4555f18c41 | |||
| 788d8a8b98 | |||
| 55f22f74f5 | |||
| de2f7e857d | |||
| 7c869ab033 | |||
| f9c680ddc0 | |||
| 8efe191897 | |||
| 8d6f1a6128 | |||
| 81bae35d2f | |||
| fc5744c7f0 | |||
| 7aea82d526 | |||
| cb29054e66 | |||
| 0416648b39 | |||
| 01fea69352 | |||
| c7a2133639 | |||
| a162f188c2 | |||
| 2b54804c7b | |||
| a8fef30871 | |||
| 9dc4d903c7 | |||
| b8b18995c5 | |||
| 971b397133 | |||
| aee7dc94bc | |||
| feb8db1212 | |||
| f9f7f005f2 | |||
| 2321a886ae | |||
| 72858c6746 | |||
| 79ca5a3026 | |||
| 3d37998174 | |||
| ce29e40b57 | |||
| ef26d6afdc | |||
| dc84bc9391 | |||
| 321eb18cd7 | |||
| 6936b8c4f3 | |||
| 26f43ee9b8 | |||
| e19d318af9 | |||
| dfc7f764de | |||
| 331b4cc42c | |||
| 674d537f91 | |||
| a442a019d9 | |||
| 774a554405 | |||
| 90f56e07ff | |||
| 4b428ffb8a | |||
| bcd0caecd1 | |||
| 78c32afa4e | |||
| f3302fe1b9 | |||
| 7eba06c43d | |||
| 713f8e2c6a | |||
| ea0100310b | |||
| 4332bfe537 | |||
| 25ce2bdd92 | |||
| dc17ef4f7c | |||
| 8097508909 | |||
| 8addc33734 | |||
| 990136a337 | |||
| d14b204aae | |||
| 4067829d2c | |||
| 8bc4c8c485 | |||
| bf8aec2a14 | |||
| ace2787868 | |||
| 08dde1da13 | |||
| 4cde7a4b06 | |||
| 42ce8a82af | |||
| 6d6e446f6f | |||
| 26bf667fec | |||
| 18b9c9b0b1 | |||
| f78ca8833b | |||
| 19337de8f0 | |||
| c2a4fbc98c | |||
| 87c0e13efd | |||
| 3442097b31 | |||
| c7764ed1d0 | |||
| 6e39022af9 | |||
| d88716feba | |||
| 678347d836 | |||
| 890ccea846 | |||
| 405525357d | |||
| 3eee2a3311 | |||
| 55d1f0081d | |||
| ea73d9bf86 | |||
| 3eab15180c | |||
| 2210be45fe | |||
| 5bdc3dfad8 | |||
| c22440fe30 | |||
| b41844290b | |||
| 32a3440156 | |||
| 630eb3c143 | |||
| 534b628ad2 | |||
| 8a463524b4 | |||
| b50eefbd5b | |||
| 3a2ebeca11 | |||
| 95f7da61a9 | |||
| 0d04beb777 | |||
| 7ab26ff7af | |||
| 6800fc6103 | |||
| 9077c1f24f | |||
| 2327f2af6f | |||
| 41fff9c930 | |||
| cfcef40c65 | |||
| 29d158a3bc | |||
| 411cf324dd | |||
| 52230a803f | |||
| ddf6f275db | |||
| 8c65ee54d0 | |||
| d07d44fcc7 | |||
| 772d59f0ab | |||
| f7da3f88f9 | |||
| e4f6cf9993 | |||
| dd34c93656 | |||
| 320ffa2308 | |||
| b5e7136f68 | |||
| e2b7664451 | |||
| 725ad07e6f | |||
| 75cbd69d85 | |||
| a9a71ef011 | |||
| 362ba36695 | |||
| 38d687ede2 | |||
| 78cd1cf494 | |||
| 0b990d42cd | |||
| 74571de5b6 | |||
| 01ce61f6e2 | |||
| 09c9aa078d | |||
| 73441d690e | |||
| afdc21ee04 | |||
| fc317b7f28 | |||
| b3f2b7faf4 | |||
| 7ea70dcb53 | |||
| d0b90fdef7 | |||
| 3c05d31d2e | |||
| 11f5eb21af | |||
| c90665645e | |||
| fb3c71820b | |||
| e533774ac0 | |||
| 647f8de9bb | |||
| 599bf57cd8 | |||
| 50c506ea2d | |||
| 4cc7990b1a | |||
| 4ef5fdefb2 | |||
| a018837214 | |||
| e74f0e1558 | |||
| fd882b5167 | |||
| 15bda62b89 | |||
| 5e4ce96266 | |||
| dbd2f0d06f | |||
| c87e657412 | |||
| 6275e3f08f | |||
| bc2e4a2452 | |||
| ba7d9fb724 | |||
| c50ab96abb | |||
| fa68c6a0fa | |||
| d1b60fec48 | |||
| 99a839605c | |||
| 08f5b3e920 | |||
| 87e0a26d24 | |||
| 91c07e9f99 | |||
| 9b2b75e4b4 | |||
| 77c913c70a | |||
| 1a1bea527c | |||
| 46f8f6d90d | |||
| dbad3b6489 | |||
| 1821cedbc4 | |||
| 1448eafd64 | |||
| 8f4047b36a | |||
| 2683fde42a | |||
| 02522d877d | |||
| 769ffa2982 | |||
| 33eed14141 | |||
| a0bd47a012 | |||
| 8c14ef97bf | |||
| 5bdfbe8250 | |||
| f2319c9689 | |||
| c3138c6497 | |||
| 56e8308621 | |||
| cb6a8756b6 | |||
| e7242143a0 | |||
| c12898b63a | |||
| 9453f29deb | |||
| 9093816113 | |||
| 3471c1b87e | |||
| 30f0de9427 | |||
| 5278e94566 | |||
| 08b1e9d764 | |||
| 30427e0626 | |||
| 752a5b9bc3 | |||
| a5390d5461 | |||
| a02fa19d5a | |||
| f88bdcd4ff | |||
| b98f8a570c | |||
| 644070340d | |||
| 93fecfe7e9 | |||
| 53bb3ac361 | |||
| 137df8c6d3 | |||
| 9863285bf0 | |||
| a392b4a14f | |||
| d03569e908 | |||
| b1097e9c61 | |||
| 5bda6bf48b | |||
| a03cdacd9e | |||
| c3fe33f5a0 | |||
| 5d823ff1a7 | |||
| 63df9dd1f4 | |||
| 0c80c9fead | |||
| b8d42a7cc6 | |||
| 4e7dc30fea | |||
| 99c68b1091 | |||
| d48979091e | |||
| 785caa5b6c | |||
| 261d7331f4 | |||
| 28bd8409df | |||
| 47008a157c | |||
| fc1e8681ef | |||
| 17085b4379 | |||
| dd6eefcd9c | |||
| ae2b0e63d6 | |||
| bcbae097de | |||
| b59dca4eeb | |||
| 8098798fa9 | |||
| d8d0e2c99f | |||
| 214233f82f | |||
| eebe82c990 | |||
| 5b73071d64 | |||
| cd04de7f72 | |||
| cf4b1317e1 | |||
| 10e353b090 | |||
| 81bd756ec6 | |||
| 9527d8aafd | |||
| e35bc58e0e | |||
| bd0f9fd913 | |||
| 44957f7806 | |||
| 7ff26eb95d | |||
| 1f2471fa67 | |||
| 7a5588a408 | |||
| ac03ae737f | |||
| f9db95f555 | |||
| 2bc045a997 | |||
| 531b0fa529 | |||
| 6b1ed4fb9b | |||
| 645a6a9f54 | |||
| 88cd291b0f | |||
| 76e4aaf429 | |||
| 365f8ad981 | |||
| 0af08f9469 | |||
| 23ce658af7 | |||
| 0a54474f98 | |||
| 93ca9ed3a8 | |||
| d110fdccc2 | |||
| 4197d983bf | |||
| d23883b799 | |||
| 675d2ac374 | |||
| 5c86735ab7 | |||
| 566274dcac | |||
| de2814545b | |||
| 4ea26f22c4 | |||
| 458bc7f921 | |||
| 3839698e4a | |||
| b403863e62 | |||
| 246b73f922 | |||
| 6da7f462a9 | |||
| 90874b8b00 | |||
| 7e874a33fb | |||
| bbe357e5c0 | |||
| 428cdae3cf | |||
| 1c689a6b24 | |||
| 55972ef2c1 | |||
| 966687d1ab | |||
| 6a86144adf | |||
| 57765e88c0 | |||
| 60cddad047 | |||
| a77a33dc50 | |||
| 405a07e638 | |||
| 75f9ce9d77 | |||
| 259588e747 | |||
| 0e8b746fb0 | |||
| 753917c10c | |||
| 39f7364f25 | |||
| 8d7de5fcb6 | |||
| 01398f762b | |||
| e12d2efe81 | |||
| 5c7055d840 | |||
| 562c7aa126 | |||
| 5994088e50 | |||
| 9edbe22e19 | |||
| 7fabfff397 | |||
| 356a2fe0e8 | |||
| 54193ebb15 | |||
| 2b4bb9cddd | |||
| 2758907517 | |||
| a7f641eee2 | |||
| 9799ceff80 | |||
| 26e86c2171 | |||
| f6c293fb4d | |||
| 5abc5cf9f8 | |||
| 41a820fdf0 | |||
| 2c8b09da21 | |||
| a7ff526360 | |||
| 1a8148be97 | |||
| 199dd85140 | |||
| f6c44fdb03 | |||
| 1aade72cb1 | |||
| 121c9d308b | |||
| d60a47ab5b | |||
| 8af9b8796f | |||
| 7dd7673fb3 | |||
| aeaf0902e1 | |||
| 498842475c | |||
| 755177508e | |||
| 5b49fd93e2 | |||
| 968ea35b03 | |||
| 97ed90b82a | |||
| ba34aa535a | |||
| e56041da3b | |||
| b19fbc39af | |||
| 1036d419fa | |||
| 0011789443 | |||
| ff7d71fb87 |
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"phabricator.uri": "https://secure.phabricator.com/",
|
||||
"phabricator.uri": "https://developer.blender.org/",
|
||||
"load": ["src/"],
|
||||
"history.immutable": false
|
||||
}
|
||||
|
||||
4
.arclint
@@ -64,13 +64,13 @@
|
||||
"text": {
|
||||
"type": "text",
|
||||
"exclude": [
|
||||
"(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json))"
|
||||
"(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect))"
|
||||
]
|
||||
},
|
||||
"text-without-length": {
|
||||
"type": "text",
|
||||
"include": [
|
||||
"(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json))"
|
||||
"(^src/(.*/)?__tests__/[^/]+/.*\\.(txt|json|expect))"
|
||||
],
|
||||
"severity": {
|
||||
"3": "disabled"
|
||||
|
||||
3
.gitignore
vendored
@@ -40,3 +40,6 @@
|
||||
# Places for users to add custom resources.
|
||||
/resources/cows/custom/*
|
||||
/resources/figlet/custom/*
|
||||
|
||||
# blender migration files
|
||||
migration/dump/
|
||||
|
||||
769
externals/cldr/cldr_windows_timezones.xml
vendored
Normal file
@@ -0,0 +1,769 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE supplementalData SYSTEM "../../common/dtd/ldmlSupplemental.dtd">
|
||||
<!--
|
||||
Copyright © 1991-2013 Unicode, Inc.
|
||||
CLDR data files are interpreted according to the LDML specification (http://unicode.org/reports/tr35/)
|
||||
For terms of use, see http://www.unicode.org/copyright.html
|
||||
-->
|
||||
|
||||
<supplementalData>
|
||||
<version number="$Revision$"/>
|
||||
<windowsZones>
|
||||
<mapTimezones otherVersion="7e00402" typeVersion="2016i">
|
||||
|
||||
<!-- (UTC-12:00) International Date Line West -->
|
||||
<mapZone other="Dateline Standard Time" territory="001" type="Etc/GMT+12"/>
|
||||
<mapZone other="Dateline Standard Time" territory="ZZ" type="Etc/GMT+12"/>
|
||||
|
||||
<!-- (UTC-11:00) Coordinated Universal Time-11 -->
|
||||
<mapZone other="UTC-11" territory="001" type="Etc/GMT+11"/>
|
||||
<mapZone other="UTC-11" territory="AS" type="Pacific/Pago_Pago"/>
|
||||
<mapZone other="UTC-11" territory="NU" type="Pacific/Niue"/>
|
||||
<mapZone other="UTC-11" territory="UM" type="Pacific/Midway"/>
|
||||
<mapZone other="UTC-11" territory="ZZ" type="Etc/GMT+11"/>
|
||||
|
||||
<!-- (UTC-10:00) Aleutian Islands -->
|
||||
<mapZone other="Aleutian Standard Time" territory="001" type="America/Adak"/>
|
||||
<mapZone other="Aleutian Standard Time" territory="US" type="America/Adak"/>
|
||||
|
||||
<!-- (UTC-10:00) Hawaii -->
|
||||
<mapZone other="Hawaiian Standard Time" territory="001" type="Pacific/Honolulu"/>
|
||||
<mapZone other="Hawaiian Standard Time" territory="CK" type="Pacific/Rarotonga"/>
|
||||
<mapZone other="Hawaiian Standard Time" territory="PF" type="Pacific/Tahiti"/>
|
||||
<mapZone other="Hawaiian Standard Time" territory="UM" type="Pacific/Johnston"/>
|
||||
<mapZone other="Hawaiian Standard Time" territory="US" type="Pacific/Honolulu"/>
|
||||
<mapZone other="Hawaiian Standard Time" territory="ZZ" type="Etc/GMT+10"/>
|
||||
|
||||
<!-- (UTC-09:30) Marquesas Islands -->
|
||||
<mapZone other="Marquesas Standard Time" territory="001" type="Pacific/Marquesas"/>
|
||||
<mapZone other="Marquesas Standard Time" territory="PF" type="Pacific/Marquesas"/>
|
||||
|
||||
<!-- (UTC-09:00) Alaska -->
|
||||
<mapZone other="Alaskan Standard Time" territory="001" type="America/Anchorage"/>
|
||||
<mapZone other="Alaskan Standard Time" territory="US" type="America/Anchorage America/Juneau America/Metlakatla America/Nome America/Sitka America/Yakutat"/>
|
||||
|
||||
<!-- (UTC-09:00) Coordinated Universal Time-09 -->
|
||||
<mapZone other="UTC-09" territory="001" type="Etc/GMT+9"/>
|
||||
<mapZone other="UTC-09" territory="PF" type="Pacific/Gambier"/>
|
||||
<mapZone other="UTC-09" territory="ZZ" type="Etc/GMT+9"/>
|
||||
|
||||
<!-- (UTC-08:00) Baja California -->
|
||||
<mapZone other="Pacific Standard Time (Mexico)" territory="001" type="America/Tijuana"/>
|
||||
<mapZone other="Pacific Standard Time (Mexico)" territory="MX" type="America/Tijuana America/Santa_Isabel"/>
|
||||
|
||||
<!-- (UTC-08:00) Coordinated Universal Time-08 -->
|
||||
<mapZone other="UTC-08" territory="001" type="Etc/GMT+8"/>
|
||||
<mapZone other="UTC-08" territory="PN" type="Pacific/Pitcairn"/>
|
||||
<mapZone other="UTC-08" territory="ZZ" type="Etc/GMT+8"/>
|
||||
|
||||
<!-- (UTC-08:00) Pacific Time (US & Canada) -->
|
||||
<mapZone other="Pacific Standard Time" territory="001" type="America/Los_Angeles"/>
|
||||
<mapZone other="Pacific Standard Time" territory="CA" type="America/Vancouver America/Dawson America/Whitehorse"/>
|
||||
<mapZone other="Pacific Standard Time" territory="US" type="America/Los_Angeles"/>
|
||||
<mapZone other="Pacific Standard Time" territory="ZZ" type="PST8PDT"/>
|
||||
|
||||
<!-- (UTC-07:00) Arizona -->
|
||||
<mapZone other="US Mountain Standard Time" territory="001" type="America/Phoenix"/>
|
||||
<mapZone other="US Mountain Standard Time" territory="CA" type="America/Dawson_Creek America/Creston America/Fort_Nelson"/>
|
||||
<mapZone other="US Mountain Standard Time" territory="MX" type="America/Hermosillo"/>
|
||||
<mapZone other="US Mountain Standard Time" territory="US" type="America/Phoenix"/>
|
||||
<mapZone other="US Mountain Standard Time" territory="ZZ" type="Etc/GMT+7"/>
|
||||
|
||||
<!-- (UTC-07:00) Chihuahua, La Paz, Mazatlan -->
|
||||
<mapZone other="Mountain Standard Time (Mexico)" territory="001" type="America/Chihuahua"/>
|
||||
<mapZone other="Mountain Standard Time (Mexico)" territory="MX" type="America/Chihuahua America/Mazatlan"/>
|
||||
|
||||
<!-- (UTC-07:00) Mountain Time (US & Canada) -->
|
||||
<mapZone other="Mountain Standard Time" territory="001" type="America/Denver"/>
|
||||
<mapZone other="Mountain Standard Time" territory="CA" type="America/Edmonton America/Cambridge_Bay America/Inuvik America/Yellowknife"/>
|
||||
<mapZone other="Mountain Standard Time" territory="MX" type="America/Ojinaga"/>
|
||||
<mapZone other="Mountain Standard Time" territory="US" type="America/Denver America/Boise"/>
|
||||
<mapZone other="Mountain Standard Time" territory="ZZ" type="MST7MDT"/>
|
||||
|
||||
<!-- (UTC-06:00) Central America -->
|
||||
<mapZone other="Central America Standard Time" territory="001" type="America/Guatemala"/>
|
||||
<mapZone other="Central America Standard Time" territory="BZ" type="America/Belize"/>
|
||||
<mapZone other="Central America Standard Time" territory="CR" type="America/Costa_Rica"/>
|
||||
<mapZone other="Central America Standard Time" territory="EC" type="Pacific/Galapagos"/>
|
||||
<mapZone other="Central America Standard Time" territory="GT" type="America/Guatemala"/>
|
||||
<mapZone other="Central America Standard Time" territory="HN" type="America/Tegucigalpa"/>
|
||||
<mapZone other="Central America Standard Time" territory="NI" type="America/Managua"/>
|
||||
<mapZone other="Central America Standard Time" territory="SV" type="America/El_Salvador"/>
|
||||
<mapZone other="Central America Standard Time" territory="ZZ" type="Etc/GMT+6"/>
|
||||
|
||||
<!-- (UTC-06:00) Central Time (US & Canada) -->
|
||||
<mapZone other="Central Standard Time" territory="001" type="America/Chicago"/>
|
||||
<mapZone other="Central Standard Time" territory="CA" type="America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute"/>
|
||||
<mapZone other="Central Standard Time" territory="MX" type="America/Matamoros"/>
|
||||
<mapZone other="Central Standard Time" territory="US" type="America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee America/North_Dakota/Beulah America/North_Dakota/Center America/North_Dakota/New_Salem"/>
|
||||
<mapZone other="Central Standard Time" territory="ZZ" type="CST6CDT"/>
|
||||
|
||||
<!-- (UTC-06:00) Easter Island -->
|
||||
<mapZone other="Easter Island Standard Time" territory="001" type="Pacific/Easter"/>
|
||||
<mapZone other="Easter Island Standard Time" territory="CL" type="Pacific/Easter"/>
|
||||
|
||||
<!-- (UTC-06:00) Guadalajara, Mexico City, Monterrey -->
|
||||
<mapZone other="Central Standard Time (Mexico)" territory="001" type="America/Mexico_City"/>
|
||||
<mapZone other="Central Standard Time (Mexico)" territory="MX" type="America/Mexico_City America/Bahia_Banderas America/Merida America/Monterrey"/>
|
||||
|
||||
<!-- (UTC-06:00) Saskatchewan -->
|
||||
<mapZone other="Canada Central Standard Time" territory="001" type="America/Regina"/>
|
||||
<mapZone other="Canada Central Standard Time" territory="CA" type="America/Regina America/Swift_Current"/>
|
||||
|
||||
<!-- (UTC-05:00) Bogota, Lima, Quito, Rio Branco -->
|
||||
<mapZone other="SA Pacific Standard Time" territory="001" type="America/Bogota"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="BR" type="America/Rio_Branco America/Eirunepe"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="CA" type="America/Coral_Harbour"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="CO" type="America/Bogota"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="EC" type="America/Guayaquil"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="JM" type="America/Jamaica"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="KY" type="America/Cayman"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="PA" type="America/Panama"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="PE" type="America/Lima"/>
|
||||
<mapZone other="SA Pacific Standard Time" territory="ZZ" type="Etc/GMT+5"/>
|
||||
|
||||
<!-- (UTC-05:00) Chetumal -->
|
||||
<mapZone other="Eastern Standard Time (Mexico)" territory="001" type="America/Cancun"/>
|
||||
<mapZone other="Eastern Standard Time (Mexico)" territory="MX" type="America/Cancun"/>
|
||||
|
||||
<!-- (UTC-05:00) Eastern Time (US & Canada) -->
|
||||
<mapZone other="Eastern Standard Time" territory="001" type="America/New_York"/>
|
||||
<mapZone other="Eastern Standard Time" territory="BS" type="America/Nassau"/>
|
||||
<mapZone other="Eastern Standard Time" territory="CA" type="America/Toronto America/Iqaluit America/Montreal America/Nipigon America/Pangnirtung America/Thunder_Bay"/>
|
||||
<mapZone other="Eastern Standard Time" territory="US" type="America/New_York America/Detroit America/Indiana/Petersburg America/Indiana/Vincennes America/Indiana/Winamac America/Kentucky/Monticello America/Louisville"/>
|
||||
<mapZone other="Eastern Standard Time" territory="ZZ" type="EST5EDT"/>
|
||||
|
||||
<!-- (UTC-05:00) Haiti -->
|
||||
<mapZone other="Haiti Standard Time" territory="001" type="America/Port-au-Prince"/>
|
||||
<mapZone other="Haiti Standard Time" territory="HT" type="America/Port-au-Prince"/>
|
||||
|
||||
<!-- (UTC-05:00) Havana -->
|
||||
<mapZone other="Cuba Standard Time" territory="001" type="America/Havana"/>
|
||||
<mapZone other="Cuba Standard Time" territory="CU" type="America/Havana"/>
|
||||
|
||||
<!-- (UTC-05:00) Indiana (East) -->
|
||||
<mapZone other="US Eastern Standard Time" territory="001" type="America/Indianapolis"/>
|
||||
<mapZone other="US Eastern Standard Time" territory="US" type="America/Indianapolis America/Indiana/Marengo America/Indiana/Vevay"/>
|
||||
|
||||
<!-- (UTC-04:00) Asuncion -->
|
||||
<mapZone other="Paraguay Standard Time" territory="001" type="America/Asuncion"/>
|
||||
<mapZone other="Paraguay Standard Time" territory="PY" type="America/Asuncion"/>
|
||||
|
||||
<!-- (UTC-04:00) Atlantic Time (Canada) -->
|
||||
<mapZone other="Atlantic Standard Time" territory="001" type="America/Halifax"/>
|
||||
<mapZone other="Atlantic Standard Time" territory="BM" type="Atlantic/Bermuda"/>
|
||||
<mapZone other="Atlantic Standard Time" territory="CA" type="America/Halifax America/Glace_Bay America/Goose_Bay America/Moncton"/>
|
||||
<mapZone other="Atlantic Standard Time" territory="GL" type="America/Thule"/>
|
||||
|
||||
<!-- (UTC-04:00) Caracas -->
|
||||
<mapZone other="Venezuela Standard Time" territory="001" type="America/Caracas"/>
|
||||
<mapZone other="Venezuela Standard Time" territory="VE" type="America/Caracas"/>
|
||||
|
||||
<!-- (UTC-04:00) Cuiaba -->
|
||||
<mapZone other="Central Brazilian Standard Time" territory="001" type="America/Cuiaba"/>
|
||||
<mapZone other="Central Brazilian Standard Time" territory="BR" type="America/Cuiaba America/Campo_Grande"/>
|
||||
|
||||
<!-- (UTC-04:00) Georgetown, La Paz, Manaus, San Juan -->
|
||||
<mapZone other="SA Western Standard Time" territory="001" type="America/La_Paz"/>
|
||||
<mapZone other="SA Western Standard Time" territory="AG" type="America/Antigua"/>
|
||||
<mapZone other="SA Western Standard Time" territory="AI" type="America/Anguilla"/>
|
||||
<mapZone other="SA Western Standard Time" territory="AW" type="America/Aruba"/>
|
||||
<mapZone other="SA Western Standard Time" territory="BB" type="America/Barbados"/>
|
||||
<mapZone other="SA Western Standard Time" territory="BL" type="America/St_Barthelemy"/>
|
||||
<mapZone other="SA Western Standard Time" territory="BO" type="America/La_Paz"/>
|
||||
<mapZone other="SA Western Standard Time" territory="BQ" type="America/Kralendijk"/>
|
||||
<mapZone other="SA Western Standard Time" territory="BR" type="America/Manaus America/Boa_Vista America/Porto_Velho"/>
|
||||
<mapZone other="SA Western Standard Time" territory="CA" type="America/Blanc-Sablon"/>
|
||||
<mapZone other="SA Western Standard Time" territory="CW" type="America/Curacao"/>
|
||||
<mapZone other="SA Western Standard Time" territory="DM" type="America/Dominica"/>
|
||||
<mapZone other="SA Western Standard Time" territory="DO" type="America/Santo_Domingo"/>
|
||||
<mapZone other="SA Western Standard Time" territory="GD" type="America/Grenada"/>
|
||||
<mapZone other="SA Western Standard Time" territory="GP" type="America/Guadeloupe"/>
|
||||
<mapZone other="SA Western Standard Time" territory="GY" type="America/Guyana"/>
|
||||
<mapZone other="SA Western Standard Time" territory="KN" type="America/St_Kitts"/>
|
||||
<mapZone other="SA Western Standard Time" territory="LC" type="America/St_Lucia"/>
|
||||
<mapZone other="SA Western Standard Time" territory="MF" type="America/Marigot"/>
|
||||
<mapZone other="SA Western Standard Time" territory="MQ" type="America/Martinique"/>
|
||||
<mapZone other="SA Western Standard Time" territory="MS" type="America/Montserrat"/>
|
||||
<mapZone other="SA Western Standard Time" territory="PR" type="America/Puerto_Rico"/>
|
||||
<mapZone other="SA Western Standard Time" territory="SX" type="America/Lower_Princes"/>
|
||||
<mapZone other="SA Western Standard Time" territory="TT" type="America/Port_of_Spain"/>
|
||||
<mapZone other="SA Western Standard Time" territory="VC" type="America/St_Vincent"/>
|
||||
<mapZone other="SA Western Standard Time" territory="VG" type="America/Tortola"/>
|
||||
<mapZone other="SA Western Standard Time" territory="VI" type="America/St_Thomas"/>
|
||||
<mapZone other="SA Western Standard Time" territory="ZZ" type="Etc/GMT+4"/>
|
||||
|
||||
<!-- (UTC-04:00) Santiago -->
|
||||
<mapZone other="Pacific SA Standard Time" territory="001" type="America/Santiago"/>
|
||||
<mapZone other="Pacific SA Standard Time" territory="AQ" type="Antarctica/Palmer"/>
|
||||
<mapZone other="Pacific SA Standard Time" territory="CL" type="America/Santiago"/>
|
||||
|
||||
<!-- (UTC-04:00) Turks and Caicos -->
|
||||
<mapZone other="Turks And Caicos Standard Time" territory="001" type="America/Grand_Turk"/>
|
||||
<mapZone other="Turks And Caicos Standard Time" territory="TC" type="America/Grand_Turk"/>
|
||||
|
||||
<!-- (UTC-03:30) Newfoundland -->
|
||||
<mapZone other="Newfoundland Standard Time" territory="001" type="America/St_Johns"/>
|
||||
<mapZone other="Newfoundland Standard Time" territory="CA" type="America/St_Johns"/>
|
||||
|
||||
<!-- (UTC-03:00) Araguaina -->
|
||||
<mapZone other="Tocantins Standard Time" territory="001" type="America/Araguaina"/>
|
||||
<mapZone other="Tocantins Standard Time" territory="BR" type="America/Araguaina"/>
|
||||
|
||||
<!-- (UTC-03:00) Brasilia -->
|
||||
<mapZone other="E. South America Standard Time" territory="001" type="America/Sao_Paulo"/>
|
||||
<mapZone other="E. South America Standard Time" territory="BR" type="America/Sao_Paulo"/>
|
||||
|
||||
<!-- (UTC-03:00) Cayenne, Fortaleza -->
|
||||
<mapZone other="SA Eastern Standard Time" territory="001" type="America/Cayenne"/>
|
||||
<mapZone other="SA Eastern Standard Time" territory="AQ" type="Antarctica/Rothera"/>
|
||||
<mapZone other="SA Eastern Standard Time" territory="BR" type="America/Fortaleza America/Belem America/Maceio America/Recife America/Santarem"/>
|
||||
<mapZone other="SA Eastern Standard Time" territory="FK" type="Atlantic/Stanley"/>
|
||||
<mapZone other="SA Eastern Standard Time" territory="GF" type="America/Cayenne"/>
|
||||
<mapZone other="SA Eastern Standard Time" territory="SR" type="America/Paramaribo"/>
|
||||
<mapZone other="SA Eastern Standard Time" territory="ZZ" type="Etc/GMT+3"/>
|
||||
|
||||
<!-- (UTC-03:00) City of Buenos Aires -->
|
||||
<mapZone other="Argentina Standard Time" territory="001" type="America/Buenos_Aires"/>
|
||||
<mapZone other="Argentina Standard Time" territory="AR" type="America/Buenos_Aires America/Argentina/La_Rioja America/Argentina/Rio_Gallegos America/Argentina/Salta America/Argentina/San_Juan America/Argentina/San_Luis America/Argentina/Tucuman America/Argentina/Ushuaia America/Catamarca America/Cordoba America/Jujuy America/Mendoza"/>
|
||||
|
||||
<!-- (UTC-03:00) Greenland -->
|
||||
<mapZone other="Greenland Standard Time" territory="001" type="America/Godthab"/>
|
||||
<mapZone other="Greenland Standard Time" territory="GL" type="America/Godthab"/>
|
||||
|
||||
<!-- (UTC-03:00) Montevideo -->
|
||||
<mapZone other="Montevideo Standard Time" territory="001" type="America/Montevideo"/>
|
||||
<mapZone other="Montevideo Standard Time" territory="UY" type="America/Montevideo"/>
|
||||
|
||||
<!-- (UTC-03:00) Saint Pierre and Miquelon -->
|
||||
<mapZone other="Saint Pierre Standard Time" territory="001" type="America/Miquelon"/>
|
||||
<mapZone other="Saint Pierre Standard Time" territory="PM" type="America/Miquelon"/>
|
||||
|
||||
<!-- (UTC-03:00) Salvador -->
|
||||
<mapZone other="Bahia Standard Time" territory="001" type="America/Bahia"/>
|
||||
<mapZone other="Bahia Standard Time" territory="BR" type="America/Bahia"/>
|
||||
|
||||
<!-- (UTC-02:00) Coordinated Universal Time-02 -->
|
||||
<mapZone other="UTC-02" territory="001" type="Etc/GMT+2"/>
|
||||
<mapZone other="UTC-02" territory="BR" type="America/Noronha"/>
|
||||
<mapZone other="UTC-02" territory="GS" type="Atlantic/South_Georgia"/>
|
||||
<mapZone other="UTC-02" territory="ZZ" type="Etc/GMT+2"/>
|
||||
|
||||
<!-- (UTC-01:00) Azores -->
|
||||
<mapZone other="Azores Standard Time" territory="001" type="Atlantic/Azores"/>
|
||||
<mapZone other="Azores Standard Time" territory="GL" type="America/Scoresbysund"/>
|
||||
<mapZone other="Azores Standard Time" territory="PT" type="Atlantic/Azores"/>
|
||||
|
||||
<!-- (UTC-01:00) Cabo Verde Is. -->
|
||||
<mapZone other="Cape Verde Standard Time" territory="001" type="Atlantic/Cape_Verde"/>
|
||||
<mapZone other="Cape Verde Standard Time" territory="CV" type="Atlantic/Cape_Verde"/>
|
||||
<mapZone other="Cape Verde Standard Time" territory="ZZ" type="Etc/GMT+1"/>
|
||||
|
||||
<!-- (UTC) Coordinated Universal Time -->
|
||||
<mapZone other="UTC" territory="001" type="Etc/GMT"/>
|
||||
<mapZone other="UTC" territory="GL" type="America/Danmarkshavn"/>
|
||||
<mapZone other="UTC" territory="ZZ" type="Etc/GMT"/>
|
||||
|
||||
<!-- (UTC+00:00) Casablanca -->
|
||||
<mapZone other="Morocco Standard Time" territory="001" type="Africa/Casablanca"/>
|
||||
<mapZone other="Morocco Standard Time" territory="EH" type="Africa/El_Aaiun"/>
|
||||
<mapZone other="Morocco Standard Time" territory="MA" type="Africa/Casablanca"/>
|
||||
|
||||
<!-- (UTC+00:00) Dublin, Edinburgh, Lisbon, London -->
|
||||
<mapZone other="GMT Standard Time" territory="001" type="Europe/London"/>
|
||||
<mapZone other="GMT Standard Time" territory="ES" type="Atlantic/Canary"/>
|
||||
<mapZone other="GMT Standard Time" territory="FO" type="Atlantic/Faeroe"/>
|
||||
<mapZone other="GMT Standard Time" territory="GB" type="Europe/London"/>
|
||||
<mapZone other="GMT Standard Time" territory="GG" type="Europe/Guernsey"/>
|
||||
<mapZone other="GMT Standard Time" territory="IE" type="Europe/Dublin"/>
|
||||
<mapZone other="GMT Standard Time" territory="IM" type="Europe/Isle_of_Man"/>
|
||||
<mapZone other="GMT Standard Time" territory="JE" type="Europe/Jersey"/>
|
||||
<mapZone other="GMT Standard Time" territory="PT" type="Europe/Lisbon Atlantic/Madeira"/>
|
||||
|
||||
<!-- (UTC+00:00) Monrovia, Reykjavik -->
|
||||
<mapZone other="Greenwich Standard Time" territory="001" type="Atlantic/Reykjavik"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="BF" type="Africa/Ouagadougou"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="CI" type="Africa/Abidjan"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="GH" type="Africa/Accra"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="GM" type="Africa/Banjul"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="GN" type="Africa/Conakry"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="GW" type="Africa/Bissau"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="IS" type="Atlantic/Reykjavik"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="LR" type="Africa/Monrovia"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="ML" type="Africa/Bamako"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="MR" type="Africa/Nouakchott"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="SH" type="Atlantic/St_Helena"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="SL" type="Africa/Freetown"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="SN" type="Africa/Dakar"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="ST" type="Africa/Sao_Tome"/>
|
||||
<mapZone other="Greenwich Standard Time" territory="TG" type="Africa/Lome"/>
|
||||
|
||||
<!-- (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna -->
|
||||
<mapZone other="W. Europe Standard Time" territory="001" type="Europe/Berlin"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="AD" type="Europe/Andorra"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="AT" type="Europe/Vienna"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="CH" type="Europe/Zurich"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="DE" type="Europe/Berlin Europe/Busingen"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="GI" type="Europe/Gibraltar"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="IT" type="Europe/Rome"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="LI" type="Europe/Vaduz"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="LU" type="Europe/Luxembourg"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="MC" type="Europe/Monaco"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="MT" type="Europe/Malta"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="NL" type="Europe/Amsterdam"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="NO" type="Europe/Oslo"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="SE" type="Europe/Stockholm"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="SJ" type="Arctic/Longyearbyen"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="SM" type="Europe/San_Marino"/>
|
||||
<mapZone other="W. Europe Standard Time" territory="VA" type="Europe/Vatican"/>
|
||||
|
||||
<!-- (UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague -->
|
||||
<mapZone other="Central Europe Standard Time" territory="001" type="Europe/Budapest"/>
|
||||
<mapZone other="Central Europe Standard Time" territory="AL" type="Europe/Tirane"/>
|
||||
<mapZone other="Central Europe Standard Time" territory="CZ" type="Europe/Prague"/>
|
||||
<mapZone other="Central Europe Standard Time" territory="HU" type="Europe/Budapest"/>
|
||||
<mapZone other="Central Europe Standard Time" territory="ME" type="Europe/Podgorica"/>
|
||||
<mapZone other="Central Europe Standard Time" territory="RS" type="Europe/Belgrade"/>
|
||||
<mapZone other="Central Europe Standard Time" territory="SI" type="Europe/Ljubljana"/>
|
||||
<mapZone other="Central Europe Standard Time" territory="SK" type="Europe/Bratislava"/>
|
||||
|
||||
<!-- (UTC+01:00) Brussels, Copenhagen, Madrid, Paris -->
|
||||
<mapZone other="Romance Standard Time" territory="001" type="Europe/Paris"/>
|
||||
<mapZone other="Romance Standard Time" territory="BE" type="Europe/Brussels"/>
|
||||
<mapZone other="Romance Standard Time" territory="DK" type="Europe/Copenhagen"/>
|
||||
<mapZone other="Romance Standard Time" territory="ES" type="Europe/Madrid Africa/Ceuta"/>
|
||||
<mapZone other="Romance Standard Time" territory="FR" type="Europe/Paris"/>
|
||||
|
||||
<!-- (UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb -->
|
||||
<mapZone other="Central European Standard Time" territory="001" type="Europe/Warsaw"/>
|
||||
<mapZone other="Central European Standard Time" territory="BA" type="Europe/Sarajevo"/>
|
||||
<mapZone other="Central European Standard Time" territory="HR" type="Europe/Zagreb"/>
|
||||
<mapZone other="Central European Standard Time" territory="MK" type="Europe/Skopje"/>
|
||||
<mapZone other="Central European Standard Time" territory="PL" type="Europe/Warsaw"/>
|
||||
|
||||
<!-- (UTC+01:00) West Central Africa -->
|
||||
<mapZone other="W. Central Africa Standard Time" territory="001" type="Africa/Lagos"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="AO" type="Africa/Luanda"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="BJ" type="Africa/Porto-Novo"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="CD" type="Africa/Kinshasa"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="CF" type="Africa/Bangui"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="CG" type="Africa/Brazzaville"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="CM" type="Africa/Douala"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="DZ" type="Africa/Algiers"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="GA" type="Africa/Libreville"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="GQ" type="Africa/Malabo"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="NE" type="Africa/Niamey"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="NG" type="Africa/Lagos"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="TD" type="Africa/Ndjamena"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="TN" type="Africa/Tunis"/>
|
||||
<mapZone other="W. Central Africa Standard Time" territory="ZZ" type="Etc/GMT-1"/>
|
||||
|
||||
<!-- (UTC+01:00) Windhoek -->
|
||||
<mapZone other="Namibia Standard Time" territory="001" type="Africa/Windhoek"/>
|
||||
<mapZone other="Namibia Standard Time" territory="NA" type="Africa/Windhoek"/>
|
||||
|
||||
<!-- (UTC+02:00) Amman -->
|
||||
<mapZone other="Jordan Standard Time" territory="001" type="Asia/Amman"/>
|
||||
<mapZone other="Jordan Standard Time" territory="JO" type="Asia/Amman"/>
|
||||
|
||||
<!-- (UTC+02:00) Athens, Bucharest -->
|
||||
<mapZone other="GTB Standard Time" territory="001" type="Europe/Bucharest"/>
|
||||
<mapZone other="GTB Standard Time" territory="CY" type="Asia/Nicosia"/>
|
||||
<mapZone other="GTB Standard Time" territory="GR" type="Europe/Athens"/>
|
||||
<mapZone other="GTB Standard Time" territory="RO" type="Europe/Bucharest"/>
|
||||
|
||||
<!-- (UTC+02:00) Beirut -->
|
||||
<mapZone other="Middle East Standard Time" territory="001" type="Asia/Beirut"/>
|
||||
<mapZone other="Middle East Standard Time" territory="LB" type="Asia/Beirut"/>
|
||||
|
||||
<!-- (UTC+02:00) Cairo -->
|
||||
<mapZone other="Egypt Standard Time" territory="001" type="Africa/Cairo"/>
|
||||
<mapZone other="Egypt Standard Time" territory="EG" type="Africa/Cairo"/>
|
||||
|
||||
<!-- (UTC+02:00) Chisinau -->
|
||||
<mapZone other="E. Europe Standard Time" territory="001" type="Europe/Chisinau"/>
|
||||
<mapZone other="E. Europe Standard Time" territory="MD" type="Europe/Chisinau"/>
|
||||
|
||||
<!-- (UTC+02:00) Damascus -->
|
||||
<mapZone other="Syria Standard Time" territory="001" type="Asia/Damascus"/>
|
||||
<mapZone other="Syria Standard Time" territory="SY" type="Asia/Damascus"/>
|
||||
|
||||
<!-- (UTC+02:00) Gaza, Hebron -->
|
||||
<mapZone other="West Bank Standard Time" territory="001" type="Asia/Hebron"/>
|
||||
<mapZone other="West Bank Standard Time" territory="PS" type="Asia/Hebron Asia/Gaza"/>
|
||||
|
||||
<!-- (UTC+02:00) Harare, Pretoria -->
|
||||
<mapZone other="South Africa Standard Time" territory="001" type="Africa/Johannesburg"/>
|
||||
<mapZone other="South Africa Standard Time" territory="BI" type="Africa/Bujumbura"/>
|
||||
<mapZone other="South Africa Standard Time" territory="BW" type="Africa/Gaborone"/>
|
||||
<mapZone other="South Africa Standard Time" territory="CD" type="Africa/Lubumbashi"/>
|
||||
<mapZone other="South Africa Standard Time" territory="LS" type="Africa/Maseru"/>
|
||||
<mapZone other="South Africa Standard Time" territory="MW" type="Africa/Blantyre"/>
|
||||
<mapZone other="South Africa Standard Time" territory="MZ" type="Africa/Maputo"/>
|
||||
<mapZone other="South Africa Standard Time" territory="RW" type="Africa/Kigali"/>
|
||||
<mapZone other="South Africa Standard Time" territory="SZ" type="Africa/Mbabane"/>
|
||||
<mapZone other="South Africa Standard Time" territory="ZA" type="Africa/Johannesburg"/>
|
||||
<mapZone other="South Africa Standard Time" territory="ZM" type="Africa/Lusaka"/>
|
||||
<mapZone other="South Africa Standard Time" territory="ZW" type="Africa/Harare"/>
|
||||
<mapZone other="South Africa Standard Time" territory="ZZ" type="Etc/GMT-2"/>
|
||||
|
||||
<!-- (UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius -->
|
||||
<mapZone other="FLE Standard Time" territory="001" type="Europe/Kiev"/>
|
||||
<mapZone other="FLE Standard Time" territory="AX" type="Europe/Mariehamn"/>
|
||||
<mapZone other="FLE Standard Time" territory="BG" type="Europe/Sofia"/>
|
||||
<mapZone other="FLE Standard Time" territory="EE" type="Europe/Tallinn"/>
|
||||
<mapZone other="FLE Standard Time" territory="FI" type="Europe/Helsinki"/>
|
||||
<mapZone other="FLE Standard Time" territory="LT" type="Europe/Vilnius"/>
|
||||
<mapZone other="FLE Standard Time" territory="LV" type="Europe/Riga"/>
|
||||
<mapZone other="FLE Standard Time" territory="UA" type="Europe/Kiev Europe/Uzhgorod Europe/Zaporozhye"/>
|
||||
|
||||
<!-- (UTC+02:00) Istanbul -->
|
||||
<mapZone other="Turkey Standard Time" territory="001" type="Europe/Istanbul"/>
|
||||
<mapZone other="Turkey Standard Time" territory="TR" type="Europe/Istanbul"/>
|
||||
|
||||
<!-- (UTC+02:00) Jerusalem -->
|
||||
<mapZone other="Israel Standard Time" territory="001" type="Asia/Jerusalem"/>
|
||||
<mapZone other="Israel Standard Time" territory="IL" type="Asia/Jerusalem"/>
|
||||
|
||||
<!-- (UTC+02:00) Kaliningrad -->
|
||||
<mapZone other="Kaliningrad Standard Time" territory="001" type="Europe/Kaliningrad"/>
|
||||
<mapZone other="Kaliningrad Standard Time" territory="RU" type="Europe/Kaliningrad"/>
|
||||
|
||||
<!-- (UTC+02:00) Tripoli -->
|
||||
<mapZone other="Libya Standard Time" territory="001" type="Africa/Tripoli"/>
|
||||
<mapZone other="Libya Standard Time" territory="LY" type="Africa/Tripoli"/>
|
||||
|
||||
<!-- (UTC+03:00) Baghdad -->
|
||||
<mapZone other="Arabic Standard Time" territory="001" type="Asia/Baghdad"/>
|
||||
<mapZone other="Arabic Standard Time" territory="IQ" type="Asia/Baghdad"/>
|
||||
|
||||
<!-- (UTC+03:00) Kuwait, Riyadh -->
|
||||
<mapZone other="Arab Standard Time" territory="001" type="Asia/Riyadh"/>
|
||||
<mapZone other="Arab Standard Time" territory="BH" type="Asia/Bahrain"/>
|
||||
<mapZone other="Arab Standard Time" territory="KW" type="Asia/Kuwait"/>
|
||||
<mapZone other="Arab Standard Time" territory="QA" type="Asia/Qatar"/>
|
||||
<mapZone other="Arab Standard Time" territory="SA" type="Asia/Riyadh"/>
|
||||
<mapZone other="Arab Standard Time" territory="YE" type="Asia/Aden"/>
|
||||
|
||||
<!-- (UTC+03:00) Minsk -->
|
||||
<mapZone other="Belarus Standard Time" territory="001" type="Europe/Minsk"/>
|
||||
<mapZone other="Belarus Standard Time" territory="BY" type="Europe/Minsk"/>
|
||||
|
||||
<!-- (UTC+03:00) Moscow, St. Petersburg, Volgograd -->
|
||||
<mapZone other="Russian Standard Time" territory="001" type="Europe/Moscow"/>
|
||||
<mapZone other="Russian Standard Time" territory="RU" type="Europe/Moscow Europe/Kirov Europe/Volgograd"/>
|
||||
<mapZone other="Russian Standard Time" territory="UA" type="Europe/Simferopol"/>
|
||||
|
||||
<!-- (UTC+03:00) Nairobi -->
|
||||
<mapZone other="E. Africa Standard Time" territory="001" type="Africa/Nairobi"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="AQ" type="Antarctica/Syowa"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="DJ" type="Africa/Djibouti"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="ER" type="Africa/Asmera"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="ET" type="Africa/Addis_Ababa"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="KE" type="Africa/Nairobi"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="KM" type="Indian/Comoro"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="MG" type="Indian/Antananarivo"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="SD" type="Africa/Khartoum"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="SO" type="Africa/Mogadishu"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="SS" type="Africa/Juba"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="TZ" type="Africa/Dar_es_Salaam"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="UG" type="Africa/Kampala"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="YT" type="Indian/Mayotte"/>
|
||||
<mapZone other="E. Africa Standard Time" territory="ZZ" type="Etc/GMT-3"/>
|
||||
|
||||
<!-- (UTC+03:30) Tehran -->
|
||||
<mapZone other="Iran Standard Time" territory="001" type="Asia/Tehran"/>
|
||||
<mapZone other="Iran Standard Time" territory="IR" type="Asia/Tehran"/>
|
||||
|
||||
<!-- (UTC+04:00) Abu Dhabi, Muscat -->
|
||||
<mapZone other="Arabian Standard Time" territory="001" type="Asia/Dubai"/>
|
||||
<mapZone other="Arabian Standard Time" territory="AE" type="Asia/Dubai"/>
|
||||
<mapZone other="Arabian Standard Time" territory="OM" type="Asia/Muscat"/>
|
||||
<mapZone other="Arabian Standard Time" territory="ZZ" type="Etc/GMT-4"/>
|
||||
|
||||
<!-- (UTC+04:00) Astrakhan, Ulyanovsk -->
|
||||
<mapZone other="Astrakhan Standard Time" territory="001" type="Europe/Astrakhan"/>
|
||||
<mapZone other="Astrakhan Standard Time" territory="RU" type="Europe/Astrakhan Europe/Ulyanovsk"/>
|
||||
|
||||
<!-- (UTC+04:00) Baku -->
|
||||
<mapZone other="Azerbaijan Standard Time" territory="001" type="Asia/Baku"/>
|
||||
<mapZone other="Azerbaijan Standard Time" territory="AZ" type="Asia/Baku"/>
|
||||
|
||||
<!-- (UTC+04:00) Izhevsk, Samara -->
|
||||
<mapZone other="Russia Time Zone 3" territory="001" type="Europe/Samara"/>
|
||||
<mapZone other="Russia Time Zone 3" territory="RU" type="Europe/Samara"/>
|
||||
|
||||
<!-- (UTC+04:00) Port Louis -->
|
||||
<mapZone other="Mauritius Standard Time" territory="001" type="Indian/Mauritius"/>
|
||||
<mapZone other="Mauritius Standard Time" territory="MU" type="Indian/Mauritius"/>
|
||||
<mapZone other="Mauritius Standard Time" territory="RE" type="Indian/Reunion"/>
|
||||
<mapZone other="Mauritius Standard Time" territory="SC" type="Indian/Mahe"/>
|
||||
|
||||
<!-- (UTC+04:00) Tbilisi -->
|
||||
<mapZone other="Georgian Standard Time" territory="001" type="Asia/Tbilisi"/>
|
||||
<mapZone other="Georgian Standard Time" territory="GE" type="Asia/Tbilisi"/>
|
||||
|
||||
<!-- (UTC+04:00) Yerevan -->
|
||||
<mapZone other="Caucasus Standard Time" territory="001" type="Asia/Yerevan"/>
|
||||
<mapZone other="Caucasus Standard Time" territory="AM" type="Asia/Yerevan"/>
|
||||
|
||||
<!-- (UTC+04:30) Kabul -->
|
||||
<mapZone other="Afghanistan Standard Time" territory="001" type="Asia/Kabul"/>
|
||||
<mapZone other="Afghanistan Standard Time" territory="AF" type="Asia/Kabul"/>
|
||||
|
||||
<!-- (UTC+05:00) Ashgabat, Tashkent -->
|
||||
<mapZone other="West Asia Standard Time" territory="001" type="Asia/Tashkent"/>
|
||||
<mapZone other="West Asia Standard Time" territory="AQ" type="Antarctica/Mawson"/>
|
||||
<mapZone other="West Asia Standard Time" territory="KZ" type="Asia/Oral Asia/Aqtau Asia/Aqtobe"/>
|
||||
<mapZone other="West Asia Standard Time" territory="MV" type="Indian/Maldives"/>
|
||||
<mapZone other="West Asia Standard Time" territory="TF" type="Indian/Kerguelen"/>
|
||||
<mapZone other="West Asia Standard Time" territory="TJ" type="Asia/Dushanbe"/>
|
||||
<mapZone other="West Asia Standard Time" territory="TM" type="Asia/Ashgabat"/>
|
||||
<mapZone other="West Asia Standard Time" territory="UZ" type="Asia/Tashkent Asia/Samarkand"/>
|
||||
<mapZone other="West Asia Standard Time" territory="ZZ" type="Etc/GMT-5"/>
|
||||
|
||||
<!-- (UTC+05:00) Ekaterinburg -->
|
||||
<mapZone other="Ekaterinburg Standard Time" territory="001" type="Asia/Yekaterinburg"/>
|
||||
<mapZone other="Ekaterinburg Standard Time" territory="RU" type="Asia/Yekaterinburg"/>
|
||||
|
||||
<!-- (UTC+05:00) Islamabad, Karachi -->
|
||||
<mapZone other="Pakistan Standard Time" territory="001" type="Asia/Karachi"/>
|
||||
<mapZone other="Pakistan Standard Time" territory="PK" type="Asia/Karachi"/>
|
||||
|
||||
<!-- (UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi -->
|
||||
<mapZone other="India Standard Time" territory="001" type="Asia/Calcutta"/>
|
||||
<mapZone other="India Standard Time" territory="IN" type="Asia/Calcutta"/>
|
||||
|
||||
<!-- (UTC+05:30) Sri Jayawardenepura -->
|
||||
<mapZone other="Sri Lanka Standard Time" territory="001" type="Asia/Colombo"/>
|
||||
<mapZone other="Sri Lanka Standard Time" territory="LK" type="Asia/Colombo"/>
|
||||
|
||||
<!-- (UTC+05:45) Kathmandu -->
|
||||
<mapZone other="Nepal Standard Time" territory="001" type="Asia/Katmandu"/>
|
||||
<mapZone other="Nepal Standard Time" territory="NP" type="Asia/Katmandu"/>
|
||||
|
||||
<!-- (UTC+06:00) Astana -->
|
||||
<mapZone other="Central Asia Standard Time" territory="001" type="Asia/Almaty"/>
|
||||
<mapZone other="Central Asia Standard Time" territory="AQ" type="Antarctica/Vostok"/>
|
||||
<mapZone other="Central Asia Standard Time" territory="CN" type="Asia/Urumqi"/>
|
||||
<mapZone other="Central Asia Standard Time" territory="IO" type="Indian/Chagos"/>
|
||||
<mapZone other="Central Asia Standard Time" territory="KG" type="Asia/Bishkek"/>
|
||||
<mapZone other="Central Asia Standard Time" territory="KZ" type="Asia/Almaty Asia/Qyzylorda"/>
|
||||
<mapZone other="Central Asia Standard Time" territory="ZZ" type="Etc/GMT-6"/>
|
||||
|
||||
<!-- (UTC+06:00) Dhaka -->
|
||||
<mapZone other="Bangladesh Standard Time" territory="001" type="Asia/Dhaka"/>
|
||||
<mapZone other="Bangladesh Standard Time" territory="BD" type="Asia/Dhaka"/>
|
||||
<mapZone other="Bangladesh Standard Time" territory="BT" type="Asia/Thimphu"/>
|
||||
|
||||
<!-- (UTC+06:00) Omsk -->
|
||||
<mapZone other="Omsk Standard Time" territory="001" type="Asia/Omsk"/>
|
||||
<mapZone other="Omsk Standard Time" territory="RU" type="Asia/Omsk"/>
|
||||
|
||||
<!-- (UTC+06:30) Yangon (Rangoon) -->
|
||||
<mapZone other="Myanmar Standard Time" territory="001" type="Asia/Rangoon"/>
|
||||
<mapZone other="Myanmar Standard Time" territory="CC" type="Indian/Cocos"/>
|
||||
<mapZone other="Myanmar Standard Time" territory="MM" type="Asia/Rangoon"/>
|
||||
|
||||
<!-- (UTC+07:00) Bangkok, Hanoi, Jakarta -->
|
||||
<mapZone other="SE Asia Standard Time" territory="001" type="Asia/Bangkok"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="AQ" type="Antarctica/Davis"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="CX" type="Indian/Christmas"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="ID" type="Asia/Jakarta Asia/Pontianak"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="KH" type="Asia/Phnom_Penh"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="LA" type="Asia/Vientiane"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="TH" type="Asia/Bangkok"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="VN" type="Asia/Saigon"/>
|
||||
<mapZone other="SE Asia Standard Time" territory="ZZ" type="Etc/GMT-7"/>
|
||||
|
||||
<!-- (UTC+07:00) Barnaul, Gorno-Altaysk -->
|
||||
<mapZone other="Altai Standard Time" territory="001" type="Asia/Barnaul"/>
|
||||
<mapZone other="Altai Standard Time" territory="RU" type="Asia/Barnaul"/>
|
||||
|
||||
<!-- (UTC+07:00) Hovd -->
|
||||
<mapZone other="W. Mongolia Standard Time" territory="001" type="Asia/Hovd"/>
|
||||
<mapZone other="W. Mongolia Standard Time" territory="MN" type="Asia/Hovd"/>
|
||||
|
||||
<!-- (UTC+07:00) Krasnoyarsk -->
|
||||
<mapZone other="North Asia Standard Time" territory="001" type="Asia/Krasnoyarsk"/>
|
||||
<mapZone other="North Asia Standard Time" territory="RU" type="Asia/Krasnoyarsk Asia/Novokuznetsk"/>
|
||||
|
||||
<!-- (UTC+07:00) Novosibirsk -->
|
||||
<mapZone other="N. Central Asia Standard Time" territory="001" type="Asia/Novosibirsk"/>
|
||||
<mapZone other="N. Central Asia Standard Time" territory="RU" type="Asia/Novosibirsk"/>
|
||||
|
||||
<!-- (UTC+07:00) Tomsk -->
|
||||
<mapZone other="Tomsk Standard Time" territory="001" type="Asia/Tomsk"/>
|
||||
<mapZone other="Tomsk Standard Time" territory="RU" type="Asia/Tomsk"/>
|
||||
|
||||
<!-- (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi -->
|
||||
<mapZone other="China Standard Time" territory="001" type="Asia/Shanghai"/>
|
||||
<mapZone other="China Standard Time" territory="CN" type="Asia/Shanghai"/>
|
||||
<mapZone other="China Standard Time" territory="HK" type="Asia/Hong_Kong"/>
|
||||
<mapZone other="China Standard Time" territory="MO" type="Asia/Macau"/>
|
||||
|
||||
<!-- (UTC+08:00) Irkutsk -->
|
||||
<mapZone other="North Asia East Standard Time" territory="001" type="Asia/Irkutsk"/>
|
||||
<mapZone other="North Asia East Standard Time" territory="RU" type="Asia/Irkutsk"/>
|
||||
|
||||
<!-- (UTC+08:00) Kuala Lumpur, Singapore -->
|
||||
<mapZone other="Singapore Standard Time" territory="001" type="Asia/Singapore"/>
|
||||
<mapZone other="Singapore Standard Time" territory="BN" type="Asia/Brunei"/>
|
||||
<mapZone other="Singapore Standard Time" territory="ID" type="Asia/Makassar"/>
|
||||
<mapZone other="Singapore Standard Time" territory="MY" type="Asia/Kuala_Lumpur Asia/Kuching"/>
|
||||
<mapZone other="Singapore Standard Time" territory="PH" type="Asia/Manila"/>
|
||||
<mapZone other="Singapore Standard Time" territory="SG" type="Asia/Singapore"/>
|
||||
<mapZone other="Singapore Standard Time" territory="ZZ" type="Etc/GMT-8"/>
|
||||
|
||||
<!-- (UTC+08:00) Perth -->
|
||||
<mapZone other="W. Australia Standard Time" territory="001" type="Australia/Perth"/>
|
||||
<mapZone other="W. Australia Standard Time" territory="AU" type="Australia/Perth"/>
|
||||
|
||||
<!-- (UTC+08:00) Taipei -->
|
||||
<mapZone other="Taipei Standard Time" territory="001" type="Asia/Taipei"/>
|
||||
<mapZone other="Taipei Standard Time" territory="TW" type="Asia/Taipei"/>
|
||||
|
||||
<!-- (UTC+08:00) Ulaanbaatar -->
|
||||
<mapZone other="Ulaanbaatar Standard Time" territory="001" type="Asia/Ulaanbaatar"/>
|
||||
<mapZone other="Ulaanbaatar Standard Time" territory="MN" type="Asia/Ulaanbaatar Asia/Choibalsan"/>
|
||||
|
||||
<!-- (UTC+08:30) Pyongyang -->
|
||||
<mapZone other="North Korea Standard Time" territory="001" type="Asia/Pyongyang"/>
|
||||
<mapZone other="North Korea Standard Time" territory="KP" type="Asia/Pyongyang"/>
|
||||
|
||||
<!-- (UTC+08:45) Eucla -->
|
||||
<mapZone other="Aus Central W. Standard Time" territory="001" type="Australia/Eucla"/>
|
||||
<mapZone other="Aus Central W. Standard Time" territory="AU" type="Australia/Eucla"/>
|
||||
|
||||
<!-- (UTC+09:00) Chita -->
|
||||
<mapZone other="Transbaikal Standard Time" territory="001" type="Asia/Chita"/>
|
||||
<mapZone other="Transbaikal Standard Time" territory="RU" type="Asia/Chita"/>
|
||||
|
||||
<!-- (UTC+09:00) Osaka, Sapporo, Tokyo -->
|
||||
<mapZone other="Tokyo Standard Time" territory="001" type="Asia/Tokyo"/>
|
||||
<mapZone other="Tokyo Standard Time" territory="ID" type="Asia/Jayapura"/>
|
||||
<mapZone other="Tokyo Standard Time" territory="JP" type="Asia/Tokyo"/>
|
||||
<mapZone other="Tokyo Standard Time" territory="PW" type="Pacific/Palau"/>
|
||||
<mapZone other="Tokyo Standard Time" territory="TL" type="Asia/Dili"/>
|
||||
<mapZone other="Tokyo Standard Time" territory="ZZ" type="Etc/GMT-9"/>
|
||||
|
||||
<!-- (UTC+09:00) Seoul -->
|
||||
<mapZone other="Korea Standard Time" territory="001" type="Asia/Seoul"/>
|
||||
<mapZone other="Korea Standard Time" territory="KR" type="Asia/Seoul"/>
|
||||
|
||||
<!-- (UTC+09:00) Yakutsk -->
|
||||
<mapZone other="Yakutsk Standard Time" territory="001" type="Asia/Yakutsk"/>
|
||||
<mapZone other="Yakutsk Standard Time" territory="RU" type="Asia/Yakutsk Asia/Khandyga"/>
|
||||
|
||||
<!-- (UTC+09:30) Adelaide -->
|
||||
<mapZone other="Cen. Australia Standard Time" territory="001" type="Australia/Adelaide"/>
|
||||
<mapZone other="Cen. Australia Standard Time" territory="AU" type="Australia/Adelaide Australia/Broken_Hill"/>
|
||||
|
||||
<!-- (UTC+09:30) Darwin -->
|
||||
<mapZone other="AUS Central Standard Time" territory="001" type="Australia/Darwin"/>
|
||||
<mapZone other="AUS Central Standard Time" territory="AU" type="Australia/Darwin"/>
|
||||
|
||||
<!-- (UTC+10:00) Brisbane -->
|
||||
<mapZone other="E. Australia Standard Time" territory="001" type="Australia/Brisbane"/>
|
||||
<mapZone other="E. Australia Standard Time" territory="AU" type="Australia/Brisbane Australia/Lindeman"/>
|
||||
|
||||
<!-- (UTC+10:00) Canberra, Melbourne, Sydney -->
|
||||
<mapZone other="AUS Eastern Standard Time" territory="001" type="Australia/Sydney"/>
|
||||
<mapZone other="AUS Eastern Standard Time" territory="AU" type="Australia/Sydney Australia/Melbourne"/>
|
||||
|
||||
<!-- (UTC+10:00) Guam, Port Moresby -->
|
||||
<mapZone other="West Pacific Standard Time" territory="001" type="Pacific/Port_Moresby"/>
|
||||
<mapZone other="West Pacific Standard Time" territory="AQ" type="Antarctica/DumontDUrville"/>
|
||||
<mapZone other="West Pacific Standard Time" territory="FM" type="Pacific/Truk"/>
|
||||
<mapZone other="West Pacific Standard Time" territory="GU" type="Pacific/Guam"/>
|
||||
<mapZone other="West Pacific Standard Time" territory="MP" type="Pacific/Saipan"/>
|
||||
<mapZone other="West Pacific Standard Time" territory="PG" type="Pacific/Port_Moresby"/>
|
||||
<mapZone other="West Pacific Standard Time" territory="ZZ" type="Etc/GMT-10"/>
|
||||
|
||||
<!-- (UTC+10:00) Hobart -->
|
||||
<mapZone other="Tasmania Standard Time" territory="001" type="Australia/Hobart"/>
|
||||
<mapZone other="Tasmania Standard Time" territory="AU" type="Australia/Hobart Australia/Currie"/>
|
||||
|
||||
<!-- (UTC+10:00) Vladivostok -->
|
||||
<mapZone other="Vladivostok Standard Time" territory="001" type="Asia/Vladivostok"/>
|
||||
<mapZone other="Vladivostok Standard Time" territory="RU" type="Asia/Vladivostok Asia/Ust-Nera"/>
|
||||
|
||||
<!-- (UTC+10:30) Lord Howe Island -->
|
||||
<mapZone other="Lord Howe Standard Time" territory="001" type="Australia/Lord_Howe"/>
|
||||
<mapZone other="Lord Howe Standard Time" territory="AU" type="Australia/Lord_Howe"/>
|
||||
|
||||
<!-- (UTC+11:00) Bougainville Island -->
|
||||
<mapZone other="Bougainville Standard Time" territory="001" type="Pacific/Bougainville"/>
|
||||
<mapZone other="Bougainville Standard Time" territory="PG" type="Pacific/Bougainville"/>
|
||||
|
||||
<!-- (UTC+11:00) Chokurdakh -->
|
||||
<mapZone other="Russia Time Zone 10" territory="001" type="Asia/Srednekolymsk"/>
|
||||
<mapZone other="Russia Time Zone 10" territory="RU" type="Asia/Srednekolymsk"/>
|
||||
|
||||
<!-- (UTC+11:00) Magadan -->
|
||||
<mapZone other="Magadan Standard Time" territory="001" type="Asia/Magadan"/>
|
||||
<mapZone other="Magadan Standard Time" territory="RU" type="Asia/Magadan"/>
|
||||
|
||||
<!-- (UTC+11:00) Norfolk Island -->
|
||||
<mapZone other="Norfolk Standard Time" territory="001" type="Pacific/Norfolk"/>
|
||||
<mapZone other="Norfolk Standard Time" territory="NF" type="Pacific/Norfolk"/>
|
||||
|
||||
<!-- (UTC+11:00) Sakhalin -->
|
||||
<mapZone other="Sakhalin Standard Time" territory="001" type="Asia/Sakhalin"/>
|
||||
<mapZone other="Sakhalin Standard Time" territory="RU" type="Asia/Sakhalin"/>
|
||||
|
||||
<!-- (UTC+11:00) Solomon Is., New Caledonia -->
|
||||
<mapZone other="Central Pacific Standard Time" territory="001" type="Pacific/Guadalcanal"/>
|
||||
<mapZone other="Central Pacific Standard Time" territory="AQ" type="Antarctica/Casey"/>
|
||||
<mapZone other="Central Pacific Standard Time" territory="AU" type="Antarctica/Macquarie"/>
|
||||
<mapZone other="Central Pacific Standard Time" territory="FM" type="Pacific/Ponape Pacific/Kosrae"/>
|
||||
<mapZone other="Central Pacific Standard Time" territory="NC" type="Pacific/Noumea"/>
|
||||
<mapZone other="Central Pacific Standard Time" territory="SB" type="Pacific/Guadalcanal"/>
|
||||
<mapZone other="Central Pacific Standard Time" territory="VU" type="Pacific/Efate"/>
|
||||
<mapZone other="Central Pacific Standard Time" territory="ZZ" type="Etc/GMT-11"/>
|
||||
|
||||
<!-- (UTC+12:00) Anadyr, Petropavlovsk-Kamchatsky -->
|
||||
<mapZone other="Russia Time Zone 11" territory="001" type="Asia/Kamchatka"/>
|
||||
<mapZone other="Russia Time Zone 11" territory="RU" type="Asia/Kamchatka Asia/Anadyr"/>
|
||||
|
||||
<!-- (UTC+12:00) Auckland, Wellington -->
|
||||
<mapZone other="New Zealand Standard Time" territory="001" type="Pacific/Auckland"/>
|
||||
<mapZone other="New Zealand Standard Time" territory="AQ" type="Antarctica/McMurdo"/>
|
||||
<mapZone other="New Zealand Standard Time" territory="NZ" type="Pacific/Auckland"/>
|
||||
|
||||
<!-- (UTC+12:00) Coordinated Universal Time+12 -->
|
||||
<mapZone other="UTC+12" territory="001" type="Etc/GMT-12"/>
|
||||
<mapZone other="UTC+12" territory="KI" type="Pacific/Tarawa"/>
|
||||
<mapZone other="UTC+12" territory="MH" type="Pacific/Majuro Pacific/Kwajalein"/>
|
||||
<mapZone other="UTC+12" territory="NR" type="Pacific/Nauru"/>
|
||||
<mapZone other="UTC+12" territory="TV" type="Pacific/Funafuti"/>
|
||||
<mapZone other="UTC+12" territory="UM" type="Pacific/Wake"/>
|
||||
<mapZone other="UTC+12" territory="WF" type="Pacific/Wallis"/>
|
||||
<mapZone other="UTC+12" territory="ZZ" type="Etc/GMT-12"/>
|
||||
|
||||
<!-- (UTC+12:00) Fiji -->
|
||||
<mapZone other="Fiji Standard Time" territory="001" type="Pacific/Fiji"/>
|
||||
<mapZone other="Fiji Standard Time" territory="FJ" type="Pacific/Fiji"/>
|
||||
|
||||
<!-- (UTC+12:45) Chatham Islands -->
|
||||
<mapZone other="Chatham Islands Standard Time" territory="001" type="Pacific/Chatham"/>
|
||||
<mapZone other="Chatham Islands Standard Time" territory="NZ" type="Pacific/Chatham"/>
|
||||
|
||||
<!-- (UTC+13:00) Nuku'alofa -->
|
||||
<mapZone other="Tonga Standard Time" territory="001" type="Pacific/Tongatapu"/>
|
||||
<mapZone other="Tonga Standard Time" territory="KI" type="Pacific/Enderbury"/>
|
||||
<mapZone other="Tonga Standard Time" territory="TK" type="Pacific/Fakaofo"/>
|
||||
<mapZone other="Tonga Standard Time" territory="TO" type="Pacific/Tongatapu"/>
|
||||
<mapZone other="Tonga Standard Time" territory="ZZ" type="Etc/GMT-13"/>
|
||||
|
||||
<!-- (UTC+13:00) Samoa -->
|
||||
<mapZone other="Samoa Standard Time" territory="001" type="Pacific/Apia"/>
|
||||
<mapZone other="Samoa Standard Time" territory="WS" type="Pacific/Apia"/>
|
||||
|
||||
<!-- (UTC+14:00) Kiritimati Island -->
|
||||
<mapZone other="Line Islands Standard Time" territory="001" type="Pacific/Kiritimati"/>
|
||||
<mapZone other="Line Islands Standard Time" territory="KI" type="Pacific/Kiritimati"/>
|
||||
<mapZone other="Line Islands Standard Time" territory="ZZ" type="Etc/GMT-14"/>
|
||||
</mapTimezones>
|
||||
</windowsZones>
|
||||
</supplementalData>
|
||||
2
externals/phpmailer/class.phpmailer.php
vendored
@@ -1110,8 +1110,6 @@ class PHPMailer {
|
||||
|
||||
if($this->MessageID != '') {
|
||||
$result .= $this->HeaderLine('Message-ID',$this->MessageID);
|
||||
} else {
|
||||
$result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
|
||||
}
|
||||
$result .= $this->HeaderLine('X-Priority', $this->Priority);
|
||||
$result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (phpmailer.sourceforge.net)');
|
||||
|
||||
610
migration/dedup.php
Normal file
@@ -0,0 +1,610 @@
|
||||
<?php
|
||||
|
||||
$migrate_dedup_users = array();
|
||||
|
||||
$migrate_dedup_users["midiclub"] = "midclub";
|
||||
$migrate_dedup_users["trip"] = "car";
|
||||
$migrate_dedup_users["thunderbolt"] = "thunderbolt16";
|
||||
$migrate_dedup_users["avirnig"] = "beav";
|
||||
$migrate_dedup_users["jeaninmontreal"] = "jeanm";
|
||||
$migrate_dedup_users["nneo"] = "nneonneo";
|
||||
$migrate_dedup_users["ebonyj"] = "jim";
|
||||
$migrate_dedup_users["tnr"] = "ichem";
|
||||
$migrate_dedup_users["archus"] = "rstehwien";
|
||||
$migrate_dedup_users["kalysto"] = "kalar";
|
||||
$migrate_dedup_users["eloe"] = "mouvanteloe";
|
||||
$migrate_dedup_users["erdling"] = "eitj";
|
||||
$migrate_dedup_users["cwinebrinner"] = "chuck_1027";
|
||||
$migrate_dedup_users["foo"] = "mfranz";
|
||||
$migrate_dedup_users["f00fbug"] = "viviowns";
|
||||
$migrate_dedup_users["olavbalm"] = "olav";
|
||||
$migrate_dedup_users["kapong"] = "el_kapong";
|
||||
$migrate_dedup_users["thorax"] = "rofthorax";
|
||||
$migrate_dedup_users["kramer3d"] = "asdfghytrewq";
|
||||
$migrate_dedup_users["reevee"] = "vee";
|
||||
$migrate_dedup_users["matzeb"] = "matzebraun";
|
||||
$migrate_dedup_users["jmsoler"] = "jms";
|
||||
$migrate_dedup_users["aqa"] = "angelito";
|
||||
$migrate_dedup_users["blendorphin"] = "blenergetic";
|
||||
$migrate_dedup_users["paolo"] = "jody";
|
||||
$migrate_dedup_users["blendedidea"] = "chubango";
|
||||
$migrate_dedup_users["ruiramos"] = "p3ctu5";
|
||||
$migrate_dedup_users["head_chees"] = "vassilizaitsaf";
|
||||
$migrate_dedup_users["kiernan"] = "rofthorax";
|
||||
$migrate_dedup_users["olaf_arnold"] = "olafarnold";
|
||||
$migrate_dedup_users["joseyanesaltos"] = "joseyanes";
|
||||
$migrate_dedup_users["nicholasfrancis"] = "nicholas";
|
||||
$migrate_dedup_users["briancary"] = "brinux";
|
||||
$migrate_dedup_users["piotrek"] = "ccpiotr";
|
||||
$migrate_dedup_users["slashdev"] = "colonel_panic";
|
||||
$migrate_dedup_users["rj2004"] = "rjblender";
|
||||
$migrate_dedup_users["jeffreymcgrew"] = "toast";
|
||||
$migrate_dedup_users["hendersj"] = "jhenderson";
|
||||
$migrate_dedup_users["pierpy"] = "pier";
|
||||
$migrate_dedup_users["buschhardt"] = "ishtar";
|
||||
$migrate_dedup_users["timlesher"] = "tim";
|
||||
$migrate_dedup_users["tizmo"] = "timlucas";
|
||||
$migrate_dedup_users["pprandin"] = "pashaweb";
|
||||
$migrate_dedup_users["servivo"] = "taz";
|
||||
$migrate_dedup_users["stabby"] = "xingo";
|
||||
$migrate_dedup_users["jimmydietulpe"] = "jimmadietulpe";
|
||||
$migrate_dedup_users["palmnet"] = "palmer";
|
||||
$migrate_dedup_users["graphique-chti"] = "gcprod";
|
||||
$migrate_dedup_users["dreamkatana1"] = "dreamkatana";
|
||||
$migrate_dedup_users["wolverine"] = "shane";
|
||||
$migrate_dedup_users["schwarz"] = "wene";
|
||||
$migrate_dedup_users["justtesting"] = "levon";
|
||||
$migrate_dedup_users["erwin_xnan"] = "erwin";
|
||||
$migrate_dedup_users["zack"] = "krystof";
|
||||
$migrate_dedup_users["fabinator31"] = "fab31";
|
||||
$migrate_dedup_users["themilkman"] = "cliftonium";
|
||||
$migrate_dedup_users["etiennel"] = "choupi";
|
||||
$migrate_dedup_users["m_i_c_h_e_l"] = "michaels";
|
||||
$migrate_dedup_users["techrolla"] = "muffinpeddler";
|
||||
$migrate_dedup_users["fireflymantis"] = "twilight";
|
||||
$migrate_dedup_users["pinucset0"] = "pinucset";
|
||||
$migrate_dedup_users["franzrogar"] = "blender-i18n-po";
|
||||
$migrate_dedup_users["pinucset1"] = "pinucset";
|
||||
$migrate_dedup_users["pinucset3"] = "pinucset";
|
||||
$migrate_dedup_users["threeddream"] = "x-axis";
|
||||
$migrate_dedup_users["mudbot"] = "laurence";
|
||||
$migrate_dedup_users["ligeyx"] = "ligey";
|
||||
$migrate_dedup_users["dreas"] = "dre";
|
||||
$migrate_dedup_users["joorvapl"] = "joorva";
|
||||
$migrate_dedup_users["voyage"] = "xenithi";
|
||||
$migrate_dedup_users["azter"] = "azterix";
|
||||
$migrate_dedup_users["lapinbleu"] = "simeon";
|
||||
$migrate_dedup_users["emmanuel_t"] = "emmanuel";
|
||||
$migrate_dedup_users["cricket"] = "gku";
|
||||
$migrate_dedup_users["justanumber"] = "mad4linux";
|
||||
$migrate_dedup_users["johnnyen"] = "johnny";
|
||||
$migrate_dedup_users["leiota"] = "marcopolo";
|
||||
$migrate_dedup_users["blackstorm"] = "ikbendirk";
|
||||
$migrate_dedup_users["richie"] = "ligey";
|
||||
$migrate_dedup_users["mrcarnivore2"] = "mrcarnivore";
|
||||
$migrate_dedup_users["muddym1nd"] = "muddymind";
|
||||
$migrate_dedup_users["eumesmo"] = "vasco_da_gama";
|
||||
$migrate_dedup_users["ph-kby"] = "olav";
|
||||
$migrate_dedup_users["piotrek_"] = "ccpiotr";
|
||||
$migrate_dedup_users["joaquin"] = "prospero";
|
||||
$migrate_dedup_users["konrad_haenel"] = "konrad8ha";
|
||||
$migrate_dedup_users["benstabler"] = "lightning";
|
||||
$migrate_dedup_users["gustav"] = "draknoid";
|
||||
$migrate_dedup_users["slikdigit"] = "bassamk";
|
||||
$migrate_dedup_users["karlerlandsen"] = "lethalsidep";
|
||||
$migrate_dedup_users["djwillmsoh"] = "djw1";
|
||||
$migrate_dedup_users["aschmitz"] = "root_42";
|
||||
$migrate_dedup_users["malfunc"] = "mcq";
|
||||
$migrate_dedup_users["m_jack"] = "jack";
|
||||
$migrate_dedup_users["davey"] = "madcow";
|
||||
$migrate_dedup_users["iraytrace"] = "butler";
|
||||
$migrate_dedup_users["duser"] = "mslechols";
|
||||
$migrate_dedup_users["akito"] = "ton";
|
||||
$migrate_dedup_users["jochenschmitt"] = "s4504kr";
|
||||
$migrate_dedup_users["digikiller"] = "ace1";
|
||||
$migrate_dedup_users["shzhc"] = "zzzz";
|
||||
$migrate_dedup_users["cyrilbrulebois"] = "kibi";
|
||||
$migrate_dedup_users["themushroom"] = "draknoid";
|
||||
$migrate_dedup_users["zinkmaster"] = "mariolink";
|
||||
$migrate_dedup_users["ashsid"] = "ash";
|
||||
$migrate_dedup_users["novato"] = "jimenez";
|
||||
$migrate_dedup_users["jadie_p"] = "jadie";
|
||||
$migrate_dedup_users["neshshah007"] = "neshrai";
|
||||
$migrate_dedup_users["ryanshow"] = "tankcoder";
|
||||
$migrate_dedup_users["squarelinesq"] = "squareline";
|
||||
$migrate_dedup_users["virginijus"] = "ernestas1994";
|
||||
$migrate_dedup_users["renderdemon"] = "pnio";
|
||||
$migrate_dedup_users["kwab"] = "kobi";
|
||||
$migrate_dedup_users["peterjonckheere"] = "jonckheerep";
|
||||
$migrate_dedup_users["vidar"] = "vidarino";
|
||||
$migrate_dedup_users["sapjohannes"] = "johannesje";
|
||||
$migrate_dedup_users["youri"] = "ayers";
|
||||
$migrate_dedup_users["theamiman"] = "amiman";
|
||||
$migrate_dedup_users["chrisg_ksi"] = "red_planet";
|
||||
$migrate_dedup_users["blenderorgfan"] = "franciscosilva";
|
||||
$migrate_dedup_users["ericd"] = "ericdrayer";
|
||||
$migrate_dedup_users["asdfghjkl2"] = "asdfghjkl";
|
||||
$migrate_dedup_users["quorn"] = "alienit";
|
||||
$migrate_dedup_users["daan221"] = "phoenix221";
|
||||
$migrate_dedup_users["user"] = "mslechols";
|
||||
$migrate_dedup_users["pyb"] = "lomperillo";
|
||||
$migrate_dedup_users["g56"] = "gwald";
|
||||
$migrate_dedup_users["ausland"] = "vots";
|
||||
$migrate_dedup_users["quillinan"] = "orinoco";
|
||||
$migrate_dedup_users["t3tsuj1n"] = "bootsheoz";
|
||||
$migrate_dedup_users["molflesh"] = "melflash";
|
||||
$migrate_dedup_users["rickta59"] = "aerobicsboy";
|
||||
$migrate_dedup_users["nolopoly"] = "lopoly";
|
||||
$migrate_dedup_users["jeel"] = "jl57";
|
||||
$migrate_dedup_users["brianmccumber2"] = "brianmccumber";
|
||||
$migrate_dedup_users["mouette"] = "moutte";
|
||||
$migrate_dedup_users["wout"] = "wonderingwout";
|
||||
$migrate_dedup_users["fatfinger"] = "mattyc";
|
||||
$migrate_dedup_users["nathangull"] = "nateg";
|
||||
$migrate_dedup_users["tampadave"] = "dkmweeks";
|
||||
$migrate_dedup_users["sausages"] = "lethargic";
|
||||
$migrate_dedup_users["chris3d"] = "chrisbd";
|
||||
$migrate_dedup_users["kaito"] = "ton";
|
||||
$migrate_dedup_users["akirasan"] = "akira_b";
|
||||
$migrate_dedup_users["fiddle"] = "rayf";
|
||||
$migrate_dedup_users["bald"] = "manu";
|
||||
$migrate_dedup_users["mistermelquin"] = "melquin";
|
||||
$migrate_dedup_users["kofish"] = "kingdomoffish";
|
||||
$migrate_dedup_users["onanj"] = "orangee";
|
||||
$migrate_dedup_users["jasoncarrier"] = "jason";
|
||||
$migrate_dedup_users["joelgodin"] = "jenniferblender";
|
||||
$migrate_dedup_users["oranj"] = "orangee";
|
||||
$migrate_dedup_users["schdeb"] = "schmidtcristian";
|
||||
$migrate_dedup_users["bastian"] = "angerb";
|
||||
$migrate_dedup_users["patko"] = "patco";
|
||||
$migrate_dedup_users["arakyd666"] = "arakyd";
|
||||
$migrate_dedup_users["karimf"] = "rim-k";
|
||||
$migrate_dedup_users["nletwory"] = "jestertestest";
|
||||
$migrate_dedup_users["mansoorhyder"] = "mansoor";
|
||||
$migrate_dedup_users["rocketmagnet"] = "steventr";
|
||||
$migrate_dedup_users["thekernal"] = "kernal";
|
||||
$migrate_dedup_users["satom"] = "satriatomat";
|
||||
$migrate_dedup_users["a624"] = "a623";
|
||||
$migrate_dedup_users["jldavilacasares"] = "muki";
|
||||
$migrate_dedup_users["segersj"] = "segers";
|
||||
$migrate_dedup_users["hoisan49"] = "hoisan";
|
||||
$migrate_dedup_users["j_bessette"] = "linuxpimp20";
|
||||
$migrate_dedup_users["andreas999"] = "andreas";
|
||||
$migrate_dedup_users["dusan"] = "dsc512";
|
||||
$migrate_dedup_users["dx-mon"] = "mantr100";
|
||||
$migrate_dedup_users["ilislab"] = "ids";
|
||||
$migrate_dedup_users["rben"] = "raybenjamin";
|
||||
$migrate_dedup_users["sphere"] = "dysonsphere";
|
||||
$migrate_dedup_users["highlife22"] = "highlife";
|
||||
$migrate_dedup_users["yonarw"] = "yona";
|
||||
$migrate_dedup_users["kryptic89"] = "kryptic";
|
||||
$migrate_dedup_users["axelp"] = "axel";
|
||||
$migrate_dedup_users["perebalsach"] = "fog22";
|
||||
$migrate_dedup_users["alogerson"] = "gerson";
|
||||
$migrate_dedup_users["cotejrp"] = "cotejrp1";
|
||||
$migrate_dedup_users["tak"] = "carlosjamesr";
|
||||
$migrate_dedup_users["ziddy"] = "anishchandran";
|
||||
$migrate_dedup_users["asdgz"] = "blenderiseur";
|
||||
$migrate_dedup_users["cdated"] = "cdated257";
|
||||
$migrate_dedup_users["jayrkalugin"] = "jayr";
|
||||
$migrate_dedup_users["zeemzoet"] = "johannesje";
|
||||
$migrate_dedup_users["duo"] = "ambyra";
|
||||
$migrate_dedup_users["philb"] = "chewbacca";
|
||||
$migrate_dedup_users["tzi"] = "izt";
|
||||
$migrate_dedup_users["squirrelthetire"] = "squirrel-tire";
|
||||
$migrate_dedup_users["anwyn"] = "sugarshark";
|
||||
$migrate_dedup_users["a2z"] = "a2zaa";
|
||||
$migrate_dedup_users["fxrex"] = "femi";
|
||||
$migrate_dedup_users["alethewiz"] = "mfaso68";
|
||||
$migrate_dedup_users["noseferrit"] = "billybong";
|
||||
$migrate_dedup_users["fcali"] = "fabz";
|
||||
$migrate_dedup_users["bbirchler"] = "bblender";
|
||||
$migrate_dedup_users["oslosewers"] = "oslo";
|
||||
$migrate_dedup_users["wtrsltnk"] = "wtr";
|
||||
$migrate_dedup_users["cspohst"] = "spohst";
|
||||
$migrate_dedup_users["warhawk08"] = "warhawk1990";
|
||||
$migrate_dedup_users["magick_crow"] = "magickcrow";
|
||||
$migrate_dedup_users["guillaumem"] = "guillaume";
|
||||
$migrate_dedup_users["jwitthuhn"] = "rahu";
|
||||
$migrate_dedup_users["fmehigan"] = "frank_me";
|
||||
$migrate_dedup_users["ilissys"] = "ids";
|
||||
$migrate_dedup_users["supermoaaa"] = "moaaa";
|
||||
$migrate_dedup_users["nwmatt"] = "mhenley";
|
||||
$migrate_dedup_users["bezel"] = "xshell";
|
||||
$migrate_dedup_users["rebuss"] = "studioa";
|
||||
$migrate_dedup_users["geonom"] = "geoadel";
|
||||
$migrate_dedup_users["seldan"] = "farakon";
|
||||
$migrate_dedup_users["kuru76"] = "kcorbin";
|
||||
$migrate_dedup_users["kapil"] = "kapilbedarkar";
|
||||
$migrate_dedup_users["henryiii"] = "henryschreiner";
|
||||
$migrate_dedup_users["pateamcarl"] = "carlhuth";
|
||||
$migrate_dedup_users["kamen"] = "bigbob1993";
|
||||
$migrate_dedup_users["olddemon"] = "old_demon";
|
||||
$migrate_dedup_users["draklaw2"] = "draklaw";
|
||||
$migrate_dedup_users["ksdlee"] = "kdlee";
|
||||
$migrate_dedup_users["xource"] = "admix";
|
||||
$migrate_dedup_users["invertednormal"] = "smokebox46and2";
|
||||
$migrate_dedup_users["feelgoodcomics"] = "onlygoodwin";
|
||||
$migrate_dedup_users["glorund"] = "undolaure";
|
||||
$migrate_dedup_users["soulofsound"] = "johnnym";
|
||||
$migrate_dedup_users["ghigi123"] = "ghigi";
|
||||
$migrate_dedup_users["stefanvoigthpi"] = "derstefan";
|
||||
$migrate_dedup_users["dblenderv"] = "default";
|
||||
$migrate_dedup_users["ophiocus"] = "oneliner";
|
||||
$migrate_dedup_users["colleywrks"] = "colley";
|
||||
$migrate_dedup_users["fogy"] = "fog22";
|
||||
$migrate_dedup_users["vidarn"] = "bida70";
|
||||
$migrate_dedup_users["kevin"] = "goblender2541";
|
||||
$migrate_dedup_users["tisachris"] = "warflight";
|
||||
$migrate_dedup_users["personalex2"] = "personalex";
|
||||
$migrate_dedup_users["polypa"] = "lile";
|
||||
$migrate_dedup_users["i4dnf"] = "emilian";
|
||||
$migrate_dedup_users["nitalleb"] = "singleman";
|
||||
$migrate_dedup_users["tcgodoy"] = "godoy";
|
||||
$migrate_dedup_users["joorva_pl"] = "joorva";
|
||||
$migrate_dedup_users["sex"] = "xest";
|
||||
$migrate_dedup_users["chipmunk"] = "ignatz";
|
||||
$migrate_dedup_users["schalmagne"] = "chalmagne";
|
||||
$migrate_dedup_users["michalziulek"] = "eneida";
|
||||
$migrate_dedup_users["jeeps"] = "jeepster";
|
||||
$migrate_dedup_users["yain"] = "chaos";
|
||||
$migrate_dedup_users["amadio"] = "marble";
|
||||
$migrate_dedup_users["javiere"] = "javierchavez";
|
||||
$migrate_dedup_users["drmzperx"] = "mzperx";
|
||||
$migrate_dedup_users["sebastianreaser"] = "sebastian0";
|
||||
$migrate_dedup_users["idolon"] = "spadija";
|
||||
$migrate_dedup_users["alanhzhcn"] = "alanhzh";
|
||||
$migrate_dedup_users["jeanc"] = "jean";
|
||||
$migrate_dedup_users["transblue2"] = "transblue";
|
||||
$migrate_dedup_users["cesarwilfredo"] = "cesar";
|
||||
$migrate_dedup_users["nspyr"] = "spiderfire";
|
||||
$migrate_dedup_users["supermegamoaaa"] = "moaaa";
|
||||
$migrate_dedup_users["firetiger"] = "opensolution";
|
||||
$migrate_dedup_users["skarg"] = "cados";
|
||||
$migrate_dedup_users["realheadcrusher"] = "danigr";
|
||||
$migrate_dedup_users["kpg"] = "nihylius";
|
||||
$migrate_dedup_users["tft"] = "tft67";
|
||||
$migrate_dedup_users["storabbarn"] = "morre";
|
||||
$migrate_dedup_users["bacurau"] = "roger_roo";
|
||||
$migrate_dedup_users["alisari"] = "parasoley";
|
||||
$migrate_dedup_users["skiski"] = "superrom";
|
||||
$migrate_dedup_users["halfninja"] = "nickh";
|
||||
$migrate_dedup_users["drell_develop"] = "drellex";
|
||||
$migrate_dedup_users["highlif3"] = "highlife";
|
||||
$migrate_dedup_users["broggsim1"] = "broggsim";
|
||||
$migrate_dedup_users["blendermanuci"] = "yunior88";
|
||||
$migrate_dedup_users["jpt9"] = "jtuttle";
|
||||
$migrate_dedup_users["farrer"] = "farpro";
|
||||
$migrate_dedup_users["badcheez"] = "randall";
|
||||
$migrate_dedup_users["leewj_"] = "lohns";
|
||||
$migrate_dedup_users["martin107"] = "martinfrances";
|
||||
$migrate_dedup_users["dedpan"] = "tberghuis";
|
||||
$migrate_dedup_users["whiterabbit"] = "dreamscapearts";
|
||||
$migrate_dedup_users["shuvro"] = "shuvro05";
|
||||
$migrate_dedup_users["anichandru"] = "anishchandran";
|
||||
$migrate_dedup_users["ncaralph"] = "ralphdoctorow";
|
||||
$migrate_dedup_users["nlongchamps"] = "nlong";
|
||||
$migrate_dedup_users["mawi37"] = "mawi";
|
||||
$migrate_dedup_users["rizla"] = "jay";
|
||||
$migrate_dedup_users["jeh"] = "mirkril";
|
||||
$migrate_dedup_users["b-fighter"] = "fanatic";
|
||||
$migrate_dedup_users["wasamonkey"] = "wasa";
|
||||
$migrate_dedup_users["nicola"] = "martin45";
|
||||
$migrate_dedup_users["method-es"] = "method";
|
||||
$migrate_dedup_users["pablow"] = "warhole";
|
||||
$migrate_dedup_users["alanishzh"] = "alanhzh";
|
||||
$migrate_dedup_users["thunder947"] = "thunder";
|
||||
$migrate_dedup_users["yijimi"] = "roler";
|
||||
$migrate_dedup_users["jaydenb"] = "logidude";
|
||||
$migrate_dedup_users["leandropolus"] = "leandrosz";
|
||||
$migrate_dedup_users["ibi002"] = "ibi001";
|
||||
$migrate_dedup_users["hakanortasoz"] = "tayfax";
|
||||
$migrate_dedup_users["enur"] = "rune";
|
||||
$migrate_dedup_users["dsuesse"] = "qiip";
|
||||
$migrate_dedup_users["bipedlaboratory"] = "redmetal";
|
||||
$migrate_dedup_users["codeyhanson"] = "codey";
|
||||
$migrate_dedup_users["alphonso_b"] = "alfonso_b";
|
||||
$migrate_dedup_users["surreal6"] = "carlospadial";
|
||||
$migrate_dedup_users["kralizek"] = "kral";
|
||||
$migrate_dedup_users["kfrechet"] = "keithfr";
|
||||
$migrate_dedup_users["jwedlake"] = "joshwedlake";
|
||||
$migrate_dedup_users["westie630"] = "bully";
|
||||
$migrate_dedup_users["fictional"] = "icefire";
|
||||
$migrate_dedup_users["zelozelos"] = "zelozelos1";
|
||||
$migrate_dedup_users["dragonlord"] = "acuena";
|
||||
$migrate_dedup_users["mrcheese"] = "jpeg";
|
||||
$migrate_dedup_users["willemverwey"] = "dandandan";
|
||||
$migrate_dedup_users["jhed"] = "anton_foy";
|
||||
$migrate_dedup_users["treacy1077"] = "briant";
|
||||
$migrate_dedup_users["xest"] = "xembie";
|
||||
$migrate_dedup_users["cyphl25"] = "jmsfreezer";
|
||||
$migrate_dedup_users["wynk"] = "wynn";
|
||||
$migrate_dedup_users["trock2957"] = "trock";
|
||||
$migrate_dedup_users["mr_bomb"] = "carter24";
|
||||
$migrate_dedup_users["nikolaus"] = "tortellini";
|
||||
$migrate_dedup_users["pegasus_001"] = "pegasus001";
|
||||
$migrate_dedup_users["fayte"] = "fayte220";
|
||||
$migrate_dedup_users["jagang_8"] = "jagang";
|
||||
$migrate_dedup_users["thetwom"] = "moe";
|
||||
$migrate_dedup_users["kevlareditor"] = "klthomas";
|
||||
$migrate_dedup_users["damien_deom"] = "dams";
|
||||
$migrate_dedup_users["reynantem"] = "reynante";
|
||||
$migrate_dedup_users["hiralm01"] = "hiralm";
|
||||
$migrate_dedup_users["radix7"] = "wyldethang";
|
||||
$migrate_dedup_users["puppetm"] = "puppetmaster";
|
||||
$migrate_dedup_users["vimax"] = "vimaxus";
|
||||
$migrate_dedup_users["mozzy69"] = "lyndon";
|
||||
$migrate_dedup_users["vitranaccad"] = "thestorm74";
|
||||
$migrate_dedup_users["kj12345"] = "kevinjames";
|
||||
$migrate_dedup_users["foinix"] = "mrnoodle";
|
||||
$migrate_dedup_users["shizu"] = "sntulix";
|
||||
$migrate_dedup_users["kukulcangod23"] = "kukulcangod";
|
||||
$migrate_dedup_users["piliq"] = "qpblendpolis";
|
||||
$migrate_dedup_users["benvad"] = "vbenny";
|
||||
$migrate_dedup_users["fgribben"] = "sharkey";
|
||||
$migrate_dedup_users["makospince"] = "mako_spince";
|
||||
$migrate_dedup_users["ablenderuser"] = "pancakeface";
|
||||
$migrate_dedup_users["axelphi"] = "axel";
|
||||
$migrate_dedup_users["josiasbh"] = "josias";
|
||||
$migrate_dedup_users["mattsix"] = "majawe";
|
||||
$migrate_dedup_users["duarte_ramos"] = "dphantom";
|
||||
$migrate_dedup_users["killogge"] = "muraj";
|
||||
$migrate_dedup_users["luka"] = "omgwtfbbq";
|
||||
$migrate_dedup_users["chromemonkey"] = "brian651msp";
|
||||
$migrate_dedup_users["e_d_i"] = "ide";
|
||||
$migrate_dedup_users["mrhaynesy"] = "haynesy";
|
||||
$migrate_dedup_users["imagineering"] = "imagineer";
|
||||
$migrate_dedup_users["virgiliovasconc"] = "virgilio";
|
||||
$migrate_dedup_users["blenderlb57"] = "louigi";
|
||||
$migrate_dedup_users["nick65"] = "dgnicola";
|
||||
$migrate_dedup_users["mmatthews"] = "mamatthews";
|
||||
$migrate_dedup_users["gerwood"] = "arilian";
|
||||
$migrate_dedup_users["xsidmax"] = "xsi";
|
||||
$migrate_dedup_users["mix-yag"] = "aynahsim";
|
||||
$migrate_dedup_users["wpthomas"] = "tallguy";
|
||||
$migrate_dedup_users["bp007"] = "bender007";
|
||||
$migrate_dedup_users["emach"] = "eon4blender";
|
||||
$migrate_dedup_users["alfclement"] = "alfc";
|
||||
$migrate_dedup_users["blenderwell"] = "goplexian";
|
||||
$migrate_dedup_users["asebastianr"] = "sebastian0";
|
||||
$migrate_dedup_users["joepal1976"] = "joepal";
|
||||
$migrate_dedup_users["chertov"] = "lestat";
|
||||
$migrate_dedup_users["djela63"] = "jerominovich";
|
||||
$migrate_dedup_users["lppinto"] = "lpciper";
|
||||
$migrate_dedup_users["prana"] = "nomath";
|
||||
$migrate_dedup_users["sarubadoru"] = "salvador";
|
||||
$migrate_dedup_users["rarebit"] = "rawstar7";
|
||||
$migrate_dedup_users["hikikamori"] = "hikkikamori";
|
||||
$migrate_dedup_users["mrduke"] = "drop";
|
||||
$migrate_dedup_users["deetee"] = "dertee";
|
||||
$migrate_dedup_users["woooooah"] = "noxwell";
|
||||
$migrate_dedup_users["macoss"] = "ossmac";
|
||||
$migrate_dedup_users["bunnyboy212"] = "blender_buddie";
|
||||
$migrate_dedup_users["maxgrip"] = "czarek";
|
||||
$migrate_dedup_users["tentonman"] = "titandtat";
|
||||
$migrate_dedup_users["jabozzo"] = "bozzo";
|
||||
$migrate_dedup_users["reinways"] = "reinw";
|
||||
$migrate_dedup_users["petergk"] = "nihylius";
|
||||
$migrate_dedup_users["zphr3000"] = "zphr";
|
||||
$migrate_dedup_users["ruivo"] = "andreh";
|
||||
$migrate_dedup_users["kosta"] = "kgd";
|
||||
$migrate_dedup_users["delter"] = "dertee";
|
||||
$migrate_dedup_users["jmiller"] = "lethargic";
|
||||
$migrate_dedup_users["dealga"] = "zeffii";
|
||||
$migrate_dedup_users["bogey"] = "daveh";
|
||||
$migrate_dedup_users["silencebe"] = "silence";
|
||||
$migrate_dedup_users["temozarela"] = "gorn";
|
||||
$migrate_dedup_users["tischite"] = "greenbutton";
|
||||
$migrate_dedup_users["buisson"] = "dinodino";
|
||||
$migrate_dedup_users["cfox"] = "colinfox";
|
||||
$migrate_dedup_users["hunkadoodle"] = "hunkadoodledoo";
|
||||
$migrate_dedup_users["jlwitthuhn"] = "rahu";
|
||||
$migrate_dedup_users["hvfrancesco"] = "hva";
|
||||
$migrate_dedup_users["hazim-jamal"] = "hazim1";
|
||||
$migrate_dedup_users["aurosutru"] = "tlm";
|
||||
$migrate_dedup_users["pierrea"] = "pier2";
|
||||
$migrate_dedup_users["zoon"] = "zoonpolygonikon";
|
||||
$migrate_dedup_users["gruntbatch"] = "carmichael";
|
||||
$migrate_dedup_users["petru"] = "virusanti";
|
||||
$migrate_dedup_users["mikeh74"] = "mikeh";
|
||||
$migrate_dedup_users["sugoi"] = "juntunen";
|
||||
$migrate_dedup_users["bartje"] = "bartart3d";
|
||||
$migrate_dedup_users["yaoyansi"] = "yaoyansi2";
|
||||
$migrate_dedup_users["rafek"] = "rafek_finearts";
|
||||
$migrate_dedup_users["caspern"] = "caspernilsson";
|
||||
$migrate_dedup_users["lee"] = "s_random";
|
||||
$migrate_dedup_users["sparky"] = "mmikkelsen";
|
||||
$migrate_dedup_users["wigglyframes"] = "rene";
|
||||
$migrate_dedup_users["kroni"] = "kronos";
|
||||
$migrate_dedup_users["xgl_asyliax"] = "xglasyliax";
|
||||
$migrate_dedup_users["blendeador"] = "luisperosio";
|
||||
$migrate_dedup_users["kaos1986"] = "kaos86";
|
||||
$migrate_dedup_users["adamdoyle"] = "advs89";
|
||||
$migrate_dedup_users["kahenraz"] = "mistrel";
|
||||
$migrate_dedup_users["ccliffe"] = "cjcliffe";
|
||||
$migrate_dedup_users["nullfied"] = "xercesblue";
|
||||
$migrate_dedup_users["dustyghost"] = "dustbin1_uk";
|
||||
$migrate_dedup_users["claaskuhnen"] = "cekuhnendev";
|
||||
$migrate_dedup_users["vercingetorix"] = "diamond_rust";
|
||||
$migrate_dedup_users["plugboy"] = "centerlaw";
|
||||
$migrate_dedup_users["rben13"] = "raybenjamin";
|
||||
$migrate_dedup_users["deangiberson"] = "voidptr";
|
||||
$migrate_dedup_users["makeitwork"] = "bboybram";
|
||||
$migrate_dedup_users["iljosli"] = "jos";
|
||||
$migrate_dedup_users["slowan"] = "slovan";
|
||||
$migrate_dedup_users["mooonwalkercz"] = "mooonwalker";
|
||||
$migrate_dedup_users["tapplek"] = "tapple";
|
||||
$migrate_dedup_users["blendmond"] = "cornix";
|
||||
$migrate_dedup_users["giorgiomartini"] = "tweakingknobs";
|
||||
$migrate_dedup_users["davidray"] = "deadman";
|
||||
$migrate_dedup_users["justthisguy"] = "nyctef";
|
||||
$migrate_dedup_users["logobar"] = "freyer";
|
||||
$migrate_dedup_users["zooo"] = "leon_cheung";
|
||||
$migrate_dedup_users["josiasalexandre"] = "josias";
|
||||
$migrate_dedup_users["tsukiko_chan"] = "tsukikochan";
|
||||
$migrate_dedup_users["akira_san"] = "akira_b";
|
||||
$migrate_dedup_users["walberti"] = "walbertievarist";
|
||||
$migrate_dedup_users["astro"] = "tnboma";
|
||||
$migrate_dedup_users["mccx"] = "mcq";
|
||||
$migrate_dedup_users["daa84"] = "daa";
|
||||
$migrate_dedup_users["sivert3"] = "cent";
|
||||
$migrate_dedup_users["twentyone"] = "glade";
|
||||
$migrate_dedup_users["endi2"] = "endi";
|
||||
$migrate_dedup_users["jamesr"] = "james_r";
|
||||
$migrate_dedup_users["reece"] = "reecerobinson";
|
||||
$migrate_dedup_users["dustractor"] = "bpygrams";
|
||||
$migrate_dedup_users["pencilhead"] = "pencil-head";
|
||||
$migrate_dedup_users["toml"] = "tomol";
|
||||
$migrate_dedup_users["colinm"] = "tablaman";
|
||||
$migrate_dedup_users["blendphys2"] = "blendphys";
|
||||
$migrate_dedup_users["xgoff"] = "zzyxz";
|
||||
$migrate_dedup_users["coleingraham"] = "coledingraham";
|
||||
$migrate_dedup_users["danielvmacedo"] = "skul3r";
|
||||
$migrate_dedup_users["burster"] = "przemaz";
|
||||
$migrate_dedup_users["tung"] = "tungster";
|
||||
$migrate_dedup_users["chessie"] = "blackcatt";
|
||||
$migrate_dedup_users["foxdog"] = "rubbernuke";
|
||||
$migrate_dedup_users["mordachai"] = "gus";
|
||||
$migrate_dedup_users["chilamlai"] = "cllai";
|
||||
$migrate_dedup_users["sliders34"] = "sliders";
|
||||
$migrate_dedup_users["benji852"] = "benjamin852";
|
||||
$migrate_dedup_users["bebinalpha"] = "bebin";
|
||||
$migrate_dedup_users["mr78"] = "alexandr";
|
||||
$migrate_dedup_users["avirillion"] = "tarion";
|
||||
$migrate_dedup_users["matthiasro"] = "matthias_r";
|
||||
$migrate_dedup_users["debearseax"] = "seogeniuss";
|
||||
$migrate_dedup_users["karja"] = "trockenfrosch";
|
||||
$migrate_dedup_users["rojuinex"] = "ifrit";
|
||||
$migrate_dedup_users["bernardo"] = "dados";
|
||||
$migrate_dedup_users["ddeclara"] = "decden";
|
||||
$migrate_dedup_users["zm_sansan"] = "sansan";
|
||||
$migrate_dedup_users["useless"] = "cortot";
|
||||
$migrate_dedup_users["tymnclono"] = "sooccatly";
|
||||
$migrate_dedup_users["rodrigo_b"] = "rodrigob";
|
||||
$migrate_dedup_users["shnurui"] = "spinster";
|
||||
$migrate_dedup_users["michalisz"] = "michaliszissiou";
|
||||
$migrate_dedup_users["fbbdev"] = "babboide";
|
||||
$migrate_dedup_users["tjackson"] = "tjonline";
|
||||
$migrate_dedup_users["ramaswamy"] = "ramaswamysriram";
|
||||
$migrate_dedup_users["allrod5"] = "rodblender";
|
||||
$migrate_dedup_users["qcp"] = "qpblendpolis";
|
||||
$migrate_dedup_users["ftsf"] = "thesleepless";
|
||||
$migrate_dedup_users["umagoo2012"] = "umagoo";
|
||||
$migrate_dedup_users["raven"] = "rune";
|
||||
$migrate_dedup_users["hsaito"] = "integer";
|
||||
$migrate_dedup_users["paulthegreat"] = "digitalpyro";
|
||||
$migrate_dedup_users["capheen"] = "dval";
|
||||
$migrate_dedup_users["rskinner"] = "rws";
|
||||
$migrate_dedup_users["gregstein"] = "gregorein";
|
||||
$migrate_dedup_users["matty686"] = "matty";
|
||||
$migrate_dedup_users["selby_rowley"] = "selby";
|
||||
$migrate_dedup_users["shembolstudio"] = "natadams8";
|
||||
$migrate_dedup_users["grenzfrequence"] = "goatrance";
|
||||
$migrate_dedup_users["stephan"] = "schdeffan";
|
||||
$migrate_dedup_users["axis33"] = "dsc512";
|
||||
$migrate_dedup_users["redandfish"] = "red-fish";
|
||||
$migrate_dedup_users["artsapcemedia"] = "arzpace";
|
||||
$migrate_dedup_users["artspacemedia"] = "arzpace";
|
||||
$migrate_dedup_users["mccmcc"] = "mcq";
|
||||
$migrate_dedup_users["seocitterx"] = "mediabuy";
|
||||
$migrate_dedup_users["lightning_limn"] = "lightning4";
|
||||
$migrate_dedup_users["omarlakhdar"] = "archimage";
|
||||
$migrate_dedup_users["regeleionescu"] = "regele";
|
||||
$migrate_dedup_users["mitchell_decker"] = "michealikruhara";
|
||||
$migrate_dedup_users["joselebon"] = "jl57";
|
||||
$migrate_dedup_users["simonbroggi"] = "broggsim";
|
||||
$migrate_dedup_users["inwadnepe"] = "ceapbatatry";
|
||||
$migrate_dedup_users["ehobjman"] = "resbsp";
|
||||
$migrate_dedup_users["davelassanske"] = "dolby411";
|
||||
$migrate_dedup_users["jsu"] = "jansub";
|
||||
$migrate_dedup_users["agricola"] = "agricola1";
|
||||
$migrate_dedup_users["bartoszek"] = "bartus";
|
||||
$migrate_dedup_users["captainoblivion"] = "cptoblivion";
|
||||
$migrate_dedup_users["alexmcourt"] = "personalex";
|
||||
$migrate_dedup_users["jmsprss"] = "xonar";
|
||||
$migrate_dedup_users["awarnock"] = "salsa";
|
||||
$migrate_dedup_users["mcc2"] = "mcq";
|
||||
$migrate_dedup_users["psyborg042"] = "psyborg";
|
||||
$migrate_dedup_users["ushiproject"] = "ushi";
|
||||
$migrate_dedup_users["mrjimmy"] = "mrjimmyos";
|
||||
$migrate_dedup_users["thefinalcut"] = "tlousky";
|
||||
$migrate_dedup_users["startheshadow"] = "star";
|
||||
$migrate_dedup_users["axredneck"] = "redneck";
|
||||
$migrate_dedup_users["phimestudio"] = "phime";
|
||||
$migrate_dedup_users["dwatts1"] = "dlax";
|
||||
$migrate_dedup_users["rertjoi"] = "rertjwi";
|
||||
$migrate_dedup_users["erdjkgh"] = "rertjwi";
|
||||
$migrate_dedup_users["libertainsrg"] = "fcougar";
|
||||
$migrate_dedup_users["godling72"] = "dmelchio";
|
||||
$migrate_dedup_users["myclay"] = "thenewone";
|
||||
$migrate_dedup_users["ecaspersen"] = "ecasper";
|
||||
$migrate_dedup_users["driewiel"] = "driesiedriewiel";
|
||||
$migrate_dedup_users["bhupen"] = "bhupendra";
|
||||
$migrate_dedup_users["caosdoar"] = "mailoyo";
|
||||
$migrate_dedup_users["polyspin"] = "butler";
|
||||
$migrate_dedup_users["qalb_al_aqrab"] = "efimpetelin";
|
||||
$migrate_dedup_users["fdfdfdfffd"] = "fcougar";
|
||||
$migrate_dedup_users["brianlockett"] = "macrow";
|
||||
$migrate_dedup_users["claude"] = "coco";
|
||||
$migrate_dedup_users["mattostgard"] = "drflail";
|
||||
$migrate_dedup_users["cekuhnen_new"] = "cekuhnendev";
|
||||
$migrate_dedup_users["kirill_lukyanov"] = "kirill";
|
||||
$migrate_dedup_users["jan-eric"] = "janeric96";
|
||||
$migrate_dedup_users["daniel_h"] = "dhoughto";
|
||||
$migrate_dedup_users["raphaelbarros"] = "thebigheadone";
|
||||
$migrate_dedup_users["salas"] = "tychota";
|
||||
$migrate_dedup_users["danieljsamson"] = "techfix";
|
||||
$migrate_dedup_users["vinagrito"] = "aechemendia";
|
||||
$migrate_dedup_users["lin_165"] = "b1657022405";
|
||||
$migrate_dedup_users["cwebber"] = "paroneayea";
|
||||
$migrate_dedup_users["harolddadomo"] = "harold";
|
||||
$migrate_dedup_users["rabidsquirrel"] = "genericusername";
|
||||
$migrate_dedup_users["larry3"] = "lehibou";
|
||||
$migrate_dedup_users["predoe"] = "petronius3d";
|
||||
$migrate_dedup_users["skoo"] = "stefano";
|
||||
$migrate_dedup_users["cabergolinety"] = "azathioprinewww";
|
||||
$migrate_dedup_users["prestijkorsan07"] = "prestij07";
|
||||
$migrate_dedup_users["scottpetrovic"] = "slpetrov";
|
||||
$migrate_dedup_users["zooly76"] = "zooly";
|
||||
$migrate_dedup_users["theoryanimation"] = "davidandrade";
|
||||
$migrate_dedup_users["daninsky"] = "danishit";
|
||||
$migrate_dedup_users["eyesee2013"] = "eyesee";
|
||||
$migrate_dedup_users["megacal"] = "cmcgaugh";
|
||||
$migrate_dedup_users["const"] = "kostas100";
|
||||
$migrate_dedup_users["ngaudenzi"] = "puppetmaster";
|
||||
$migrate_dedup_users["mroguski"] = "kaelthas";
|
||||
$migrate_dedup_users["brdf"] = "origin";
|
||||
$migrate_dedup_users["davis3d"] = "davis";
|
||||
$migrate_dedup_users["rldigital"] = "locatelli";
|
||||
$migrate_dedup_users["tomforsythe"] = "gallifrey77203";
|
||||
$migrate_dedup_users["gbrnk"] = "benoe";
|
||||
$migrate_dedup_users["arekkasprzyk"] = "kasperski";
|
||||
$migrate_dedup_users["imbusy1"] = "imbusy";
|
||||
$migrate_dedup_users["mfoxdoggg"] = "mfoxdogg";
|
||||
|
||||
$migrate_dedup_users["knusk"] = "kanutus";
|
||||
$migrate_dedup_users["tomekk"] = "anders211";
|
||||
$migrate_dedup_users["kitsueb"] = "kitsu_eb";
|
||||
$migrate_dedup_users["slugzzz"] = "tsquar3d";
|
||||
$migrate_dedup_users["moore500"] = "mmoore500";
|
||||
$migrate_dedup_users["verumbra"] = "sebastian0";
|
||||
$migrate_dedup_users["blenderbug"] = "nikola";
|
||||
|
||||
$migrate_dedup_users["adailtoncomp"] = "adailton";
|
||||
$migrate_dedup_users["mchs3d"] = "abtrumpet";
|
||||
|
||||
// disabled users who have tasks
|
||||
$migrate_dedup_users["sjoerd"] = "sjoerddevries";
|
||||
$migrate_dedup_users["matali"] = "mat_ali";
|
||||
$migrate_dedup_users["voicelesscushio"] = "None";
|
||||
$migrate_dedup_users["bigben0328"] = "None";
|
||||
$migrate_dedup_users["santamouse"] = "None";
|
||||
$migrate_dedup_users["andreanckaert"] = "None";
|
||||
$migrate_dedup_users["yesmydear"] = "None";
|
||||
$migrate_dedup_users["spacetug"] = "None";
|
||||
$migrate_dedup_users["omegafold"] = "None";
|
||||
|
||||
// testing
|
||||
$migrate_dedup_users["blendix_rename_test_a"] = "blendix";
|
||||
$migrate_dedup_users["blendix_rename_test_b"] = "blendix";
|
||||
|
||||
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.4 KiB |
@@ -54,8 +54,6 @@ return array(
|
||||
'javelin-behavior-aphlict-dropdown',
|
||||
'javelin-behavior-history-install',
|
||||
'javelin-behavior-phabricator-gesture',
|
||||
'javelin-behavior-phabricator-active-nav',
|
||||
'javelin-behavior-phabricator-nav',
|
||||
'javelin-behavior-phabricator-remarkup-assist',
|
||||
'phabricator-textareautils',
|
||||
'phabricator-file-upload',
|
||||
@@ -88,6 +86,12 @@ return array(
|
||||
'javelin-behavior-aphlict-status',
|
||||
'javelin-behavior-user-menu',
|
||||
'phabricator-favicon',
|
||||
'javelin-behavior-phui-tab-group',
|
||||
'javelin-behavior-phui-submenu',
|
||||
'phuix-button-view',
|
||||
'javelin-behavior-comment-actions',
|
||||
'phuix-form-control-view',
|
||||
'phuix-autocomplete',
|
||||
),
|
||||
'core.pkg.css' => array(
|
||||
'phabricator-core-css',
|
||||
@@ -158,9 +162,14 @@ return array(
|
||||
'phabricator-feed-css',
|
||||
'phabricator-dashboard-css',
|
||||
'aphront-multi-column-view-css',
|
||||
'phui-curtain-object-ref-view-css',
|
||||
'phui-comment-form-css',
|
||||
'phui-head-thing-view-css',
|
||||
|
||||
'conpherence-durable-column-view',
|
||||
'phui-button-bar-css',
|
||||
),
|
||||
'conpherence.pkg.css' => array(
|
||||
'conpherence-durable-column-view',
|
||||
'conpherence-menu-css',
|
||||
'conpherence-color-css',
|
||||
'conpherence-message-pane-css',
|
||||
@@ -187,7 +196,8 @@ return array(
|
||||
'phabricator-content-source-view-css',
|
||||
'inline-comment-summary-css',
|
||||
'phui-inline-comment-view-css',
|
||||
'phabricator-filetree-view-css',
|
||||
'diff-tree-view-css',
|
||||
'phui-formation-view-css',
|
||||
),
|
||||
'differential.pkg.js' => array(
|
||||
'phabricator-drag-and-drop-file-upload',
|
||||
@@ -204,6 +214,14 @@ return array(
|
||||
'phabricator-diff-inline',
|
||||
'phabricator-diff-changeset',
|
||||
'phabricator-diff-changeset-list',
|
||||
'phabricator-diff-tree-view',
|
||||
'phabricator-diff-path-view',
|
||||
|
||||
'phuix-formation-view',
|
||||
'phuix-formation-column-view',
|
||||
'phuix-formation-flank-view',
|
||||
|
||||
'javelin-external-editor-link-engine',
|
||||
),
|
||||
'diffusion.pkg.css' => array(
|
||||
'diffusion-icons-css',
|
||||
@@ -220,4 +238,9 @@ return array(
|
||||
'javelin-behavior-maniphest-batch-selector',
|
||||
'javelin-behavior-maniphest-list-editor',
|
||||
),
|
||||
'dark-console.pkg.js' => array(
|
||||
'javelin-behavior-dark-console',
|
||||
'phabricator-darklog',
|
||||
'phabricator-darkmessage',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ $status_map = array(
|
||||
3 => 'invalid',
|
||||
4 => 'duplicate',
|
||||
5 => 'spite',
|
||||
123450 => 'archived',
|
||||
);
|
||||
|
||||
$conn_w = id(new ManiphestTask())->establishConnection('w');
|
||||
|
||||
@@ -16,6 +16,9 @@ foreach (new LiskMigrationIterator($table) as $doc) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_view_policy = $default_view_policy;
|
||||
$new_edit_policy = $default_edit_policy;
|
||||
|
||||
// If this was previously a magical project wiki page (under projects/, but
|
||||
// not projects/ itself) we need to apply the project policies. Otherwise,
|
||||
// apply the default policies.
|
||||
@@ -35,26 +38,24 @@ foreach (new LiskMigrationIterator($table) as $doc) {
|
||||
->executeOne();
|
||||
|
||||
if ($project) {
|
||||
|
||||
$view_policy = nonempty($project->getViewPolicy(), $default_view_policy);
|
||||
$edit_policy = nonempty($project->getEditPolicy(), $default_edit_policy);
|
||||
|
||||
$project_name = $project->getName();
|
||||
echo pht(
|
||||
"Migrating document %d to project policy %s...\n",
|
||||
$id,
|
||||
$project_name);
|
||||
$doc->setViewPolicy($view_policy);
|
||||
$doc->setEditPolicy($edit_policy);
|
||||
$doc->save();
|
||||
continue;
|
||||
$new_view_policy = $view_policy;
|
||||
$new_edit_policy = $edit_policy;
|
||||
}
|
||||
}
|
||||
|
||||
echo pht('Migrating document %d to default install policy...', $id)."\n";
|
||||
$doc->setViewPolicy($default_view_policy);
|
||||
$doc->setEditPolicy($default_edit_policy);
|
||||
$doc->save();
|
||||
echo pht('Migrating document %d to new policy...', $id)."\n";
|
||||
|
||||
queryfx(
|
||||
$conn_w,
|
||||
'UPDATE %R SET viewPolicy = %s, editPolicy = %s
|
||||
WHERE id = %d',
|
||||
$table,
|
||||
$new_view_policy,
|
||||
$new_edit_policy,
|
||||
$id);
|
||||
}
|
||||
|
||||
echo pht('Done.')."\n";
|
||||
|
||||
@@ -4,18 +4,8 @@
|
||||
// underlying file data were not written correctly. This restores edges for
|
||||
// any missing pastes.
|
||||
|
||||
$table = new PhabricatorPaste();
|
||||
$edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
|
||||
|
||||
foreach (new LiskMigrationIterator($table) as $paste) {
|
||||
$paste_phid = $paste->getPHID();
|
||||
$file_phid = $paste->getFilePHID();
|
||||
|
||||
if (!$file_phid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
id(new PhabricatorEdgeEditor())
|
||||
->addEdge($paste_phid, $edge_type, $file_phid)
|
||||
->save();
|
||||
}
|
||||
// See T13510. The "pastebin" database was later renamed to "paste", which
|
||||
// broke this migration. The migration was removed in 2020 since it seems
|
||||
// plausible that zero installs are impacted (only installs that ran code
|
||||
// from November 2015 and have not upgraded in five years could possibly be
|
||||
// impacted).
|
||||
|
||||
10
resources/sql/autopatches/20200220.xaccount.01.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
CREATE TABLE {$NAMESPACE}_user.user_externalaccountidentifier (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
externalAccountPHID VARBINARY(64) NOT NULL,
|
||||
providerConfigPHID VARBINARY(64) NOT NULL,
|
||||
identifierHash BINARY(12) NOT NULL,
|
||||
identifierRaw LONGTEXT NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
||||
40
resources/sql/autopatches/20200222.xident.01.migrate.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
$account_table = new PhabricatorExternalAccount();
|
||||
$identifier_table = new PhabricatorExternalAccountIdentifier();
|
||||
|
||||
$conn = $account_table->establishConnection('w');
|
||||
$table_name = $account_table->getTableName();
|
||||
|
||||
$iterator = new LiskRawMigrationIterator($conn, $table_name);
|
||||
foreach ($iterator as $account_row) {
|
||||
// We don't need to migrate "accountID" values for "password" accounts,
|
||||
// since these were dummy values in the first place and are no longer
|
||||
// read or written after D21014. (There would be no harm in writing these
|
||||
// rows, but it's easy to skip them.)
|
||||
|
||||
if ($account_row['accountType'] === 'password') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$account_id = $account_row['accountID'];
|
||||
if (!strlen($account_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
queryfx(
|
||||
$conn,
|
||||
'INSERT IGNORE INTO %R (
|
||||
phid, externalAccountPHID, providerConfigPHID,
|
||||
identifierHash, identifierRaw,
|
||||
dateCreated, dateModified)
|
||||
VALUES (%s, %s, %s, %s, %s, %d, %d)',
|
||||
$identifier_table,
|
||||
$identifier_table->generatePHID(),
|
||||
$account_row['phid'],
|
||||
$account_row['providerConfigPHID'],
|
||||
PhabricatorHash::digestForIndex($account_id),
|
||||
$account_id,
|
||||
$account_row['dateCreated'],
|
||||
$account_row['dateModified']);
|
||||
}
|
||||
21
resources/sql/autopatches/20200222.xident.02.dropkey.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
// See T13493. This table previously had a UNIQUE KEY on "<accountType,
|
||||
// accountDomain, accountID>", which is obsolete. The application now violates
|
||||
// this key, so make sure it gets dropped.
|
||||
|
||||
// There's no "IF EXISTS" modifier for "ALTER TABLE" so run this as a PHP patch
|
||||
// instead of an SQL patch.
|
||||
|
||||
$table = new PhabricatorExternalAccount();
|
||||
$conn = $table->establishConnection('w');
|
||||
|
||||
try {
|
||||
queryfx(
|
||||
$conn,
|
||||
'ALTER TABLE %R DROP KEY %T',
|
||||
$table,
|
||||
'account_details');
|
||||
} catch (AphrontQueryException $ex) {
|
||||
// Ignore.
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE {$NAMESPACE}_paste.paste_paste_fdocument (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
isClosed BOOL NOT NULL,
|
||||
authorPHID VARBINARY(64),
|
||||
ownerPHID VARBINARY(64),
|
||||
epochCreated INT UNSIGNED NOT NULL,
|
||||
epochModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE {$NAMESPACE}_paste.paste_paste_ffield (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
fieldKey VARCHAR(4) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
rawCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
termCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT},
|
||||
normalCorpus LONGTEXT NOT NULL COLLATE {$COLLATE_SORT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1,5 @@
|
||||
CREATE TABLE {$NAMESPACE}_paste.paste_paste_fngrams (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
documentID INT UNSIGNED NOT NULL,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE {$NAMESPACE}_paste.paste_paste_fngrams_common (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
needsCollection BOOL NOT NULL,
|
||||
UNIQUE KEY `key_ngram` (ngram),
|
||||
KEY `key_collect` (needsCollection)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE {$NAMESPACE}_differential.differential_viewstate (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
viewerPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewState LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_viewer` (viewerPHID, objectPHID)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE {$NAMESPACE}_differential.differential_transaction_comment
|
||||
ADD attributes LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE {$NAMESPACE}_audit.audit_transaction_comment
|
||||
ADD attributes LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1,2 @@
|
||||
UPDATE {$NAMESPACE}_differential.differential_transaction_comment
|
||||
SET attributes = '{}' WHERE attributes = '';
|
||||
@@ -0,0 +1,2 @@
|
||||
UPDATE {$NAMESPACE}_audit.audit_transaction_comment
|
||||
SET attributes = '{}' WHERE attributes = '';
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE {$NAMESPACE}_differential.differential_changeset_parse_cache;
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE {$NAMESPACE}_differential.differential_changeset_parse_cache (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
cacheIndex BINARY(12) NOT NULL,
|
||||
cache LONGBLOB NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_cacheIndex` (cacheIndex)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS {$NAMESPACE}_differential.differential_commit;
|
||||
46
resources/timezones/generate-timezone-map.php
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/init/init-script.php';
|
||||
|
||||
$xml = $root.'/externals/cldr/cldr_windows_timezones.xml';
|
||||
$xml = Filesystem::readFile($xml);
|
||||
$xml = new SimpleXMLElement($xml);
|
||||
|
||||
$result_map = array();
|
||||
|
||||
$ignore = array(
|
||||
'UTC',
|
||||
'UTC-11',
|
||||
'UTC-02',
|
||||
'UTC-08',
|
||||
'UTC-09',
|
||||
'UTC+12',
|
||||
);
|
||||
$ignore = array_fuse($ignore);
|
||||
|
||||
$zones = $xml->windowsZones->mapTimezones->mapZone;
|
||||
foreach ($zones as $zone) {
|
||||
$windows_name = (string)$zone['other'];
|
||||
$target_name = (string)$zone['type'];
|
||||
|
||||
// Ignore the offset-based timezones from the CLDR map, since we handle
|
||||
// these later.
|
||||
if (isset($ignore[$windows_name])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We've already seen this timezone so we don't need to add it to the map
|
||||
// again.
|
||||
if (isset($result_map[$windows_name])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result_map[$windows_name] = $target_name;
|
||||
}
|
||||
|
||||
asort($result_map);
|
||||
|
||||
echo id(new PhutilJSON())
|
||||
->encodeFormatted($result_map);
|
||||
126
resources/timezones/windows-timezones.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"Egypt Standard Time": "Africa/Cairo",
|
||||
"Morocco Standard Time": "Africa/Casablanca",
|
||||
"South Africa Standard Time": "Africa/Johannesburg",
|
||||
"W. Central Africa Standard Time": "Africa/Lagos",
|
||||
"E. Africa Standard Time": "Africa/Nairobi",
|
||||
"Libya Standard Time": "Africa/Tripoli",
|
||||
"Namibia Standard Time": "Africa/Windhoek",
|
||||
"Aleutian Standard Time": "America/Adak",
|
||||
"Alaskan Standard Time": "America/Anchorage",
|
||||
"Tocantins Standard Time": "America/Araguaina",
|
||||
"Paraguay Standard Time": "America/Asuncion",
|
||||
"Bahia Standard Time": "America/Bahia",
|
||||
"SA Pacific Standard Time": "America/Bogota",
|
||||
"Argentina Standard Time": "America/Buenos_Aires",
|
||||
"Eastern Standard Time (Mexico)": "America/Cancun",
|
||||
"Venezuela Standard Time": "America/Caracas",
|
||||
"SA Eastern Standard Time": "America/Cayenne",
|
||||
"Central Standard Time": "America/Chicago",
|
||||
"Mountain Standard Time (Mexico)": "America/Chihuahua",
|
||||
"Central Brazilian Standard Time": "America/Cuiaba",
|
||||
"Mountain Standard Time": "America/Denver",
|
||||
"Greenland Standard Time": "America/Godthab",
|
||||
"Turks And Caicos Standard Time": "America/Grand_Turk",
|
||||
"Central America Standard Time": "America/Guatemala",
|
||||
"Atlantic Standard Time": "America/Halifax",
|
||||
"Cuba Standard Time": "America/Havana",
|
||||
"US Eastern Standard Time": "America/Indianapolis",
|
||||
"SA Western Standard Time": "America/La_Paz",
|
||||
"Pacific Standard Time": "America/Los_Angeles",
|
||||
"Central Standard Time (Mexico)": "America/Mexico_City",
|
||||
"Saint Pierre Standard Time": "America/Miquelon",
|
||||
"Montevideo Standard Time": "America/Montevideo",
|
||||
"Eastern Standard Time": "America/New_York",
|
||||
"US Mountain Standard Time": "America/Phoenix",
|
||||
"Haiti Standard Time": "America/Port-au-Prince",
|
||||
"Canada Central Standard Time": "America/Regina",
|
||||
"Pacific SA Standard Time": "America/Santiago",
|
||||
"E. South America Standard Time": "America/Sao_Paulo",
|
||||
"Newfoundland Standard Time": "America/St_Johns",
|
||||
"Pacific Standard Time (Mexico)": "America/Tijuana",
|
||||
"Central Asia Standard Time": "Asia/Almaty",
|
||||
"Jordan Standard Time": "Asia/Amman",
|
||||
"Arabic Standard Time": "Asia/Baghdad",
|
||||
"Azerbaijan Standard Time": "Asia/Baku",
|
||||
"SE Asia Standard Time": "Asia/Bangkok",
|
||||
"Altai Standard Time": "Asia/Barnaul",
|
||||
"Middle East Standard Time": "Asia/Beirut",
|
||||
"India Standard Time": "Asia/Calcutta",
|
||||
"Transbaikal Standard Time": "Asia/Chita",
|
||||
"Sri Lanka Standard Time": "Asia/Colombo",
|
||||
"Syria Standard Time": "Asia/Damascus",
|
||||
"Bangladesh Standard Time": "Asia/Dhaka",
|
||||
"Arabian Standard Time": "Asia/Dubai",
|
||||
"West Bank Standard Time": "Asia/Hebron",
|
||||
"W. Mongolia Standard Time": "Asia/Hovd",
|
||||
"North Asia East Standard Time": "Asia/Irkutsk",
|
||||
"Israel Standard Time": "Asia/Jerusalem",
|
||||
"Afghanistan Standard Time": "Asia/Kabul",
|
||||
"Russia Time Zone 11": "Asia/Kamchatka",
|
||||
"Pakistan Standard Time": "Asia/Karachi",
|
||||
"Nepal Standard Time": "Asia/Katmandu",
|
||||
"North Asia Standard Time": "Asia/Krasnoyarsk",
|
||||
"Magadan Standard Time": "Asia/Magadan",
|
||||
"N. Central Asia Standard Time": "Asia/Novosibirsk",
|
||||
"Omsk Standard Time": "Asia/Omsk",
|
||||
"North Korea Standard Time": "Asia/Pyongyang",
|
||||
"Myanmar Standard Time": "Asia/Rangoon",
|
||||
"Arab Standard Time": "Asia/Riyadh",
|
||||
"Sakhalin Standard Time": "Asia/Sakhalin",
|
||||
"Korea Standard Time": "Asia/Seoul",
|
||||
"China Standard Time": "Asia/Shanghai",
|
||||
"Singapore Standard Time": "Asia/Singapore",
|
||||
"Russia Time Zone 10": "Asia/Srednekolymsk",
|
||||
"Taipei Standard Time": "Asia/Taipei",
|
||||
"West Asia Standard Time": "Asia/Tashkent",
|
||||
"Georgian Standard Time": "Asia/Tbilisi",
|
||||
"Iran Standard Time": "Asia/Tehran",
|
||||
"Tokyo Standard Time": "Asia/Tokyo",
|
||||
"Tomsk Standard Time": "Asia/Tomsk",
|
||||
"Ulaanbaatar Standard Time": "Asia/Ulaanbaatar",
|
||||
"Vladivostok Standard Time": "Asia/Vladivostok",
|
||||
"Yakutsk Standard Time": "Asia/Yakutsk",
|
||||
"Ekaterinburg Standard Time": "Asia/Yekaterinburg",
|
||||
"Caucasus Standard Time": "Asia/Yerevan",
|
||||
"Azores Standard Time": "Atlantic/Azores",
|
||||
"Cape Verde Standard Time": "Atlantic/Cape_Verde",
|
||||
"Greenwich Standard Time": "Atlantic/Reykjavik",
|
||||
"Cen. Australia Standard Time": "Australia/Adelaide",
|
||||
"E. Australia Standard Time": "Australia/Brisbane",
|
||||
"AUS Central Standard Time": "Australia/Darwin",
|
||||
"Aus Central W. Standard Time": "Australia/Eucla",
|
||||
"Tasmania Standard Time": "Australia/Hobart",
|
||||
"Lord Howe Standard Time": "Australia/Lord_Howe",
|
||||
"W. Australia Standard Time": "Australia/Perth",
|
||||
"AUS Eastern Standard Time": "Australia/Sydney",
|
||||
"Dateline Standard Time": "Etc/GMT+12",
|
||||
"Astrakhan Standard Time": "Europe/Astrakhan",
|
||||
"W. Europe Standard Time": "Europe/Berlin",
|
||||
"GTB Standard Time": "Europe/Bucharest",
|
||||
"Central Europe Standard Time": "Europe/Budapest",
|
||||
"E. Europe Standard Time": "Europe/Chisinau",
|
||||
"Turkey Standard Time": "Europe/Istanbul",
|
||||
"Kaliningrad Standard Time": "Europe/Kaliningrad",
|
||||
"FLE Standard Time": "Europe/Kiev",
|
||||
"GMT Standard Time": "Europe/London",
|
||||
"Belarus Standard Time": "Europe/Minsk",
|
||||
"Russian Standard Time": "Europe/Moscow",
|
||||
"Romance Standard Time": "Europe/Paris",
|
||||
"Russia Time Zone 3": "Europe/Samara",
|
||||
"Central European Standard Time": "Europe/Warsaw",
|
||||
"Mauritius Standard Time": "Indian/Mauritius",
|
||||
"Samoa Standard Time": "Pacific/Apia",
|
||||
"New Zealand Standard Time": "Pacific/Auckland",
|
||||
"Bougainville Standard Time": "Pacific/Bougainville",
|
||||
"Chatham Islands Standard Time": "Pacific/Chatham",
|
||||
"Easter Island Standard Time": "Pacific/Easter",
|
||||
"Fiji Standard Time": "Pacific/Fiji",
|
||||
"Central Pacific Standard Time": "Pacific/Guadalcanal",
|
||||
"Hawaiian Standard Time": "Pacific/Honolulu",
|
||||
"Line Islands Standard Time": "Pacific/Kiritimati",
|
||||
"Marquesas Standard Time": "Pacific/Marquesas",
|
||||
"Norfolk Standard Time": "Pacific/Norfolk",
|
||||
"West Pacific Standard Time": "Pacific/Port_Moresby",
|
||||
"Tonga Standard Time": "Pacific/Tongatapu"
|
||||
}
|
||||
172
scripts/auth_provider/auth_provider.php
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2019, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# Contributor(s): Sergey Sharybin.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This scripts implements external AuthBasicProvider which can be used
|
||||
# to authentificate users using Phabricator's database.
|
||||
#
|
||||
# Example configuration:
|
||||
#
|
||||
# .htaccess file:
|
||||
#
|
||||
# AuthType Basic
|
||||
# AuthName "Please Enter Password"
|
||||
# AuthBasicProvider external
|
||||
# AuthExternal phabricator
|
||||
# Require valid-user
|
||||
#
|
||||
# It is also required to have the following provider registered in the
|
||||
# configuration. There are two ways to do it:
|
||||
#
|
||||
# 1. Separate conf file in /etc/apache2/conf-enabled
|
||||
# Create a file (say, authz_external_phabricator.conf) with the following
|
||||
# content:
|
||||
#
|
||||
# DefineExternalAuth phabricator pipe /path/to/auth_provider.php
|
||||
#
|
||||
# This method allows to use provider in any VHOST.
|
||||
#
|
||||
# Downside: from local tests .htaccess file picks the provider nicely,
|
||||
# but attempts to specifu the provider in virtual host configuration
|
||||
# resulted in issues (seems to be different initialization order between
|
||||
# global config in those files and virtual hosts).
|
||||
#
|
||||
# 2. Define provider in the virtual host definition:
|
||||
#
|
||||
# <IfModule mod_authnz_external.c>
|
||||
# AddExternalAuth phabricator /path/to/auth_provider.php
|
||||
# SetExternalAuthMethod phabricator pipe
|
||||
# </IfModule>
|
||||
#
|
||||
# This method allowed to use this auth provider for SVN DAV.
|
||||
|
||||
$IS_DEBUG = false;
|
||||
$PHABRICATOR_ROOT = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $PHABRICATOR_ROOT.'/scripts/__init_script__.php';
|
||||
|
||||
function initLogging() {
|
||||
global $IS_DEBUG;
|
||||
global $argv;
|
||||
for ($i = 1; $i < count($argv); ++$i) {
|
||||
if ($argv[$i] == '--debug') {
|
||||
$IS_DEBUG = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function debugLog(string $text) {
|
||||
global $IS_DEBUG;
|
||||
if (!$IS_DEBUG) {
|
||||
return;
|
||||
}
|
||||
print("${text}\n");
|
||||
}
|
||||
|
||||
function removeSingleTrailingNewline(string $string) {
|
||||
if ($string === '') {
|
||||
return $string;
|
||||
}
|
||||
$length = strlen($string);
|
||||
if ($string[$length - 1] == "\n") {
|
||||
return substr($string, 0, -1);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
class AuthRequest {
|
||||
public $user_name;
|
||||
public $password;
|
||||
|
||||
static function fromStdin() {
|
||||
$auth_request = new AuthRequest();
|
||||
$stdin = fopen('php://stdin', 'r');
|
||||
$auth_request->user_name = removeSingleTrailingNewline(fgets($stdin));
|
||||
$auth_request->password = removeSingleTrailingNewline(fgets($stdin));
|
||||
return $auth_request;
|
||||
}
|
||||
};
|
||||
|
||||
function getUserForAuthRequest(AuthRequest $auth_request) {
|
||||
if ($auth_request->user_name === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$username_or_email = $auth_request->user_name;
|
||||
|
||||
$user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'username = %s',
|
||||
$username_or_email);
|
||||
|
||||
if (!$user) {
|
||||
$user = PhabricatorUser::loadOneWithEmailAddress(
|
||||
$username_or_email);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
function createContentSourceForAuth() {
|
||||
return PhabricatorContentSource::newForSource(
|
||||
PhabricatorUnitTestContentSource::SOURCECONST);
|
||||
}
|
||||
|
||||
function isValidAuth(AuthRequest $auth_request) {
|
||||
debugLog("Begin authentification check for user '$auth_request->user_name'");
|
||||
$user = getUserForAuthRequest($auth_request);
|
||||
if (!$user) {
|
||||
debugLog("No PhabricatorUser() object found for requested user.");
|
||||
return false;
|
||||
}
|
||||
|
||||
$content_source = createContentSourceForAuth();
|
||||
$envelope = new PhutilOpaqueEnvelope($auth_request->password);
|
||||
|
||||
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||
->setViewer($user)
|
||||
->setContentSource($content_source)
|
||||
->setPasswordType(PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT)
|
||||
->setObject($user);
|
||||
|
||||
if (!$engine->isValidPassword($envelope)) {
|
||||
debugLog('Engine reported invalid password.');
|
||||
return false;
|
||||
}
|
||||
|
||||
debugLog('Authentirfication passed.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function main() {
|
||||
initLogging();
|
||||
$auth_request = AuthRequest::fromStdin();
|
||||
if (!isValidAuth($auth_request)) {
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
main();
|
||||
?>
|
||||
131
scripts/daemon/exec/exec_daemon.php
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (function_exists('pcntl_async_signals')) {
|
||||
pcntl_async_signals(true);
|
||||
} else {
|
||||
declare(ticks = 1);
|
||||
}
|
||||
|
||||
require_once dirname(__FILE__).'/../../__init_script__.php';
|
||||
|
||||
if (!posix_isatty(STDOUT)) {
|
||||
$sid = posix_setsid();
|
||||
if ($sid <= 0) {
|
||||
throw new Exception(pht('Failed to create new process session!'));
|
||||
}
|
||||
}
|
||||
|
||||
$args = new PhutilArgumentParser($argv);
|
||||
$args->setTagline(pht('daemon executor'));
|
||||
$args->setSynopsis(<<<EOHELP
|
||||
**exec_daemon.php** [__options__] __daemon__ ...
|
||||
Run an instance of __daemon__.
|
||||
EOHELP
|
||||
);
|
||||
$args->parse(
|
||||
array(
|
||||
array(
|
||||
'name' => 'trace',
|
||||
'help' => pht('Enable debug tracing.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'trace-memory',
|
||||
'help' => pht('Enable debug memory tracing.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'verbose',
|
||||
'help' => pht('Enable verbose activity logging.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'label',
|
||||
'short' => 'l',
|
||||
'param' => 'label',
|
||||
'help' => pht(
|
||||
'Optional process label. Makes "%s" nicer, no behavioral effects.',
|
||||
'ps'),
|
||||
),
|
||||
array(
|
||||
'name' => 'daemon',
|
||||
'wildcard' => true,
|
||||
),
|
||||
));
|
||||
|
||||
$trace_memory = $args->getArg('trace-memory');
|
||||
$trace_mode = $args->getArg('trace') || $trace_memory;
|
||||
$verbose = $args->getArg('verbose');
|
||||
|
||||
if (function_exists('posix_isatty') && posix_isatty(STDIN)) {
|
||||
fprintf(STDERR, pht('Reading daemon configuration from stdin...')."\n");
|
||||
}
|
||||
$config = @file_get_contents('php://stdin');
|
||||
$config = id(new PhutilJSONParser())->parse($config);
|
||||
|
||||
PhutilTypeSpec::checkMap(
|
||||
$config,
|
||||
array(
|
||||
'log' => 'optional string|null',
|
||||
'argv' => 'optional list<wild>',
|
||||
'load' => 'optional list<string>',
|
||||
'down' => 'optional int',
|
||||
));
|
||||
|
||||
$log = idx($config, 'log');
|
||||
|
||||
if ($log) {
|
||||
ini_set('error_log', $log);
|
||||
PhutilErrorHandler::setErrorListener(array('PhutilDaemon', 'errorListener'));
|
||||
}
|
||||
|
||||
$load = idx($config, 'load', array());
|
||||
foreach ($load as $library) {
|
||||
$library = Filesystem::resolvePath($library);
|
||||
phutil_load_library($library);
|
||||
}
|
||||
|
||||
PhutilErrorHandler::initialize();
|
||||
|
||||
$daemon = $args->getArg('daemon');
|
||||
if (!$daemon) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht('Specify which class of daemon to start.'));
|
||||
} else if (count($daemon) > 1) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht('Specify exactly one daemon to start.'));
|
||||
} else {
|
||||
$daemon = head($daemon);
|
||||
if (!class_exists($daemon)) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'No class "%s" exists in any known library.',
|
||||
$daemon));
|
||||
} else if (!is_subclass_of($daemon, 'PhutilDaemon')) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'Class "%s" is not a subclass of "%s".',
|
||||
$daemon,
|
||||
'PhutilDaemon'));
|
||||
}
|
||||
}
|
||||
|
||||
$argv = idx($config, 'argv', array());
|
||||
$daemon = newv($daemon, array($argv));
|
||||
|
||||
if ($trace_mode) {
|
||||
$daemon->setTraceMode();
|
||||
}
|
||||
|
||||
if ($trace_memory) {
|
||||
$daemon->setTraceMemory();
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
$daemon->setVerbose(true);
|
||||
}
|
||||
|
||||
$down_duration = idx($config, 'down');
|
||||
if ($down_duration) {
|
||||
$daemon->setScaledownDuration($down_duration);
|
||||
}
|
||||
|
||||
$daemon->execute();
|
||||
6
scripts/gitadmin/gitx-ssh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/local/bin/bash
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
ssh -i $SSH_KEYFILE $@
|
||||
443
scripts/gitadmin/rebuild_gitadmin.php
Executable file
@@ -0,0 +1,443 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
function escape_name($name) {
|
||||
return preg_replace('/[^A-Za-z0-9\-]/', '_', $name);
|
||||
}
|
||||
|
||||
function startswith($string, $prefix) {
|
||||
return substr($string, 0, strlen($prefix)) == $prefix;
|
||||
}
|
||||
|
||||
function endswith($string, $suffix) {
|
||||
$suffix_length = strlen($suffix);
|
||||
return substr($string, strlen($string) - $suffix_length,
|
||||
$suffix_length) == $suffix;
|
||||
}
|
||||
|
||||
function write_ini_file($array, $file) {
|
||||
$res = array();
|
||||
foreach ($array as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
$res[] = "[$key]";
|
||||
foreach ($val as $skey => $sval) {
|
||||
$res[] = "$skey = $sval";
|
||||
}
|
||||
$res[] = '';
|
||||
} else {
|
||||
$res[] = "$key = $val";
|
||||
}
|
||||
}
|
||||
file_put_contents($file, implode("\n", $res));
|
||||
}
|
||||
|
||||
function getProjectMembersPHIDs($viewer, $project_phid) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($project_phid))
|
||||
->executeOne();
|
||||
|
||||
return $project->getMemberPHIDs();
|
||||
}
|
||||
|
||||
// Get user's heys and put them to the configuration
|
||||
function handleSingleUserPHID(
|
||||
$keydir, $viewer, $userPHID, $system_keys, &$used_keys) {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($userPHID))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($user->getIsDisabled()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$keys = id(new PhabricatorAuthSSHKey())->loadAllWhere(
|
||||
'objectPHID = %s',
|
||||
$user->getPHID());
|
||||
|
||||
$members = array();
|
||||
foreach ($keys as $key) {
|
||||
$full_key_content =
|
||||
$key->getKeyType().' '.
|
||||
$key->getKeyBody().' '.
|
||||
$key->getKeyComment()."\n";
|
||||
|
||||
if (array_key_exists($full_key_content, $system_keys)) {
|
||||
$members[] = $system_keys[$full_key_content];
|
||||
} else {
|
||||
$escaped_key_name = escape_name($key->getName());
|
||||
$member = 'PHAB_'.$user->getUserName().
|
||||
'_'.$escaped_key_name.
|
||||
'_'.$key->getID();
|
||||
$members[] = $member;
|
||||
if (!array_key_exists($member, $used_keys)) {
|
||||
$used_keys[$member] = true;
|
||||
file_put_contents("$keydir/$member.pub", $full_key_content);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleUsersPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$members = array();
|
||||
foreach ($rule['value'] as $userPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $userPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleProjectsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$members = array();
|
||||
foreach ($rule['value'] as $projectPHID) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $projectPHID);
|
||||
foreach ($memberPHIDs as $userPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $userPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleProjectsAllPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$is_first_project = true;
|
||||
$allowed_members_phids = array();
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $project_phid);
|
||||
if ($is_first_project) {
|
||||
$allowed_members_phids = $memberPHIDs;
|
||||
$is_first_project = false;
|
||||
} else {
|
||||
$allowed_members_phids = array_intersect(
|
||||
$allowed_members_phids, $memberPHIDs);
|
||||
}
|
||||
}
|
||||
|
||||
$members = array();
|
||||
foreach ($allowed_members_phids as $userPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $userPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleAdministratorsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$administrators = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withIsAdmin(true)
|
||||
->execute();
|
||||
|
||||
$members = array();
|
||||
foreach ($administrators as $administrator) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $administrator->getPHID(),
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleLegalpadSingleDocument(
|
||||
$keydir, $viewer, $document, $system_keys, &$used_keys) {
|
||||
if ($document->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$members = array();
|
||||
foreach ($document->getSignatures() as $signature) {
|
||||
if ($signature->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
continue;
|
||||
}
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $signature->getSignerPHID(),
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleLegalpadSignaturePolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$documents = id(new LegalpadDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($rule['value'])
|
||||
->needSignatures(true)
|
||||
->execute();
|
||||
|
||||
$members = array();
|
||||
foreach ($documents as $document) {
|
||||
$members = array_merge(
|
||||
$members,
|
||||
handleLegalpadSingleDocument(
|
||||
$keydir, $viewer, $document, $system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleCustomPolicy(
|
||||
$keydir, $viewer, $policy, $system_keys, &$used_keys) {
|
||||
$members = array();
|
||||
$rules = $policy->getRules();
|
||||
foreach ($rules as $rule) {
|
||||
// Everyone is denied by default anyway
|
||||
if ($rule['action'] != 'allow') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$policy_members = array();
|
||||
$rule_type = $rule['rule'];
|
||||
if ($rule_type == 'PhabricatorPolicyRuleUsers') {
|
||||
$policy_members = handleUsersPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorProjectsPolicyRule') {
|
||||
$policy_members = handleProjectsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorProjectsAllPolicyRule') {
|
||||
$policy_members = handleProjectsAllPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorAdministratorsPolicyRule') {
|
||||
$policy_members = handleAdministratorsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorLegalpadSignaturePolicyRule') {
|
||||
$policy_members = handleLegalpadSignaturePolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
}
|
||||
|
||||
$members = array_merge($members, $policy_members);
|
||||
}
|
||||
|
||||
return $members;
|
||||
}
|
||||
|
||||
// Parse repository and put it's members to the config file
|
||||
function handleSingleRepository(
|
||||
$keydir, $viewer, $repository, $all_repositories, $system_keys,
|
||||
&$new_configuration, &$used_keys) {
|
||||
$policies = PhabricatorPolicyQuery::loadPolicies(
|
||||
$viewer,
|
||||
$repository);
|
||||
|
||||
$pushable = $policies[DiffusionPushCapability::CAPABILITY];
|
||||
$type = $pushable->getType();
|
||||
|
||||
$members = array();
|
||||
|
||||
if ($type == PhabricatorPolicyType::TYPE_PROJECT) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($pushable->getPHID()))
|
||||
->executeOne();
|
||||
|
||||
$memberPHIDs = $project->getMemberPHIDs();
|
||||
foreach ($memberPHIDs as $memberPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $memberPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_USER) {
|
||||
$members = handleSingleUserPHID(
|
||||
$keydir, $viewer, $pushable->getPHID(), $system_keys, $used_keys);
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_CUSTOM) {
|
||||
$members = handleCustomPolicy(
|
||||
$keydir, $viewer, $pushable, $system_keys, $used_keys);
|
||||
} else {
|
||||
/* pass */
|
||||
}
|
||||
|
||||
if (count($members)) {
|
||||
$uri = $repository->getRemoteURI();
|
||||
$repository_name = basename($uri, '.git');
|
||||
$escaped_repository_name = escape_name($repository->getName());
|
||||
$group_name = "PHAB_${escaped_repository_name}";
|
||||
$values = array();
|
||||
$values['members'] = join(' ', $members);
|
||||
$values['readonly'] = join(' ', $all_repositories);
|
||||
$values['writable'] = $repository_name;
|
||||
$new_configuration["group $group_name"] = $values;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove groups from previous automated configuration built
|
||||
function getCleanOldConfiguration($old_configuration) {
|
||||
$new_configuration = array();
|
||||
foreach ($old_configuration as $group => $values) {
|
||||
if (!startswith($group, 'group PHAB')) {
|
||||
$new_configuration[$group] = $values;
|
||||
}
|
||||
}
|
||||
return $new_configuration;
|
||||
}
|
||||
|
||||
// Get non-phab keys
|
||||
function getSystemPublicKeys($keydir) {
|
||||
$files = scandir($keydir);
|
||||
$system_keys = array();
|
||||
foreach ($files as $file) {
|
||||
if (!startswith($file, "PHAB") && endswith($file, '.pub')) {
|
||||
$key = file_get_contents("$keydir/$file");
|
||||
$system_keys[$key] = basename($file, '.pub');
|
||||
}
|
||||
}
|
||||
return $system_keys;
|
||||
}
|
||||
|
||||
// Remove unused public keys
|
||||
function removeUnusedPublicKeys($keydir, $used_keys) {
|
||||
$files = scandir($keydir);
|
||||
foreach ($files as $file) {
|
||||
if (startswith($file, "PHAB")) {
|
||||
$member = basename($file, '.pub');
|
||||
if (!array_key_exists($member, $used_keys)) {
|
||||
unlink("$keydir/$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rebuildConfiguration($gitosis_root) {
|
||||
$keydir = "$gitosis_root/keydir";
|
||||
$configuration_file = "$gitosis_root/gitosis.conf";
|
||||
|
||||
if (!file_exists($configuration_file)) {
|
||||
print("Not found: $configuration_file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
$viewer = id(new PhabricatorUser())
|
||||
->loadOneWhere('username = %s', 'sergey');
|
||||
|
||||
$old_configuration = parse_ini_file(
|
||||
$configuration_file, true, INI_SCANNER_RAW);
|
||||
|
||||
$new_configuration = getCleanOldConfiguration(
|
||||
$old_configuration);
|
||||
|
||||
// Get "system" keys to re-use if phab account uses the
|
||||
// same public key
|
||||
$system_keys = getSystemPublicKeys($keydir);
|
||||
|
||||
// Get list of all repos which is awailable for read
|
||||
$all_repositories = array();
|
||||
foreach ($old_configuration as $group => $values) {
|
||||
if (startswith($group, 'repo')) {
|
||||
$repository_name = substr($group, 5, strlen($group) - 5);
|
||||
if ($repository_name == 'gitosis-admin')
|
||||
continue;
|
||||
$all_repositories[] = $repository_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in new configuration and keys
|
||||
$used_keys = array();
|
||||
$repositories = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($viewer)
|
||||
->execute();
|
||||
|
||||
foreach ($repositories as $repository_id => $repository) {
|
||||
$type = $repository->getVersionControlSystem();
|
||||
if ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
|
||||
handleSingleRepository(
|
||||
$keydir, $viewer, $repository, $all_repositories, $system_keys,
|
||||
$new_configuration, $used_keys);
|
||||
}
|
||||
}
|
||||
|
||||
write_ini_file($new_configuration, $configuration_file);
|
||||
removeUnusedPublicKeys($keydir, $used_keys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getGitCommand($repository) {
|
||||
$git_dir = realpath("$repository/.git");
|
||||
$git = "git --git-dir='$git_dir'";
|
||||
$git .= ' --work-tree='.realpath($repository);
|
||||
return $git;
|
||||
}
|
||||
|
||||
function runGitCommand($repository, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$git = getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function runGitSshCommand($repository, $key, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$gitx_ssh = realpath(dirname(__FILE__) . "/gitx-ssh");
|
||||
$abs_key = realpath($key);
|
||||
$git = "SSH_KEYFILE=$abs_key GIT_SSH=$gitx_ssh ";
|
||||
$git .= getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function repositoryPull($repository, $key) {
|
||||
return runGitSshCommand($repository, $key, 'pull');
|
||||
}
|
||||
|
||||
function repositoryCommitAll($repository, $author, $message) {
|
||||
if (!runGitCommand(
|
||||
$repository, 'ls-files --other --exclude-standard', $untracked_files)) {
|
||||
return false;
|
||||
}
|
||||
if (count($untracked_files)) {
|
||||
$flat_files = join(' ', $untracked_files);
|
||||
if (!runGitCommand($repository, "add $flat_files")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
runGitCommand($repository, "update-index -q --refresh", $output);
|
||||
runGitCommand($repository, "diff-index --name-only HEAD --", $output);
|
||||
if (count($output)) {
|
||||
return runGitCommand(
|
||||
$repository, "commit --author='$author' -a -m '$message'", $output);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count($argv) != 3) {
|
||||
print("Usage: {$argv[0]} /path/to/gitosis-admin /path/to/id_rsa.pub\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$gitosis_root = $argv[1];
|
||||
$key = $argv[2];
|
||||
|
||||
if (!repositoryPull($gitosis_root, $key)) {
|
||||
print("Failed to pull changes from server.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!rebuildConfiguration($gitosis_root)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!repositoryCommitAll(
|
||||
$gitosis_root, 'Rebuild Gitadmin <null@git.blender.org>',
|
||||
'Update to correspond changes in Phabricator')) {
|
||||
print("Failed to commit changes.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
runGitSshCommand($gitosis_root, $key, 'push origin master');
|
||||
?>
|
||||
504
scripts/gitolite/rebuild_gitolite.php
Executable file
@@ -0,0 +1,504 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Utilities.
|
||||
//
|
||||
// TODO(sergey): Move somewhere else. Or, evenmore ideally, use Phabricator's
|
||||
// utilities instead.
|
||||
|
||||
function escape_name($name) {
|
||||
return preg_replace('/[^A-Za-z0-9]/', '_', $name);
|
||||
}
|
||||
|
||||
function startswith($string, $prefix) {
|
||||
return substr($string, 0, strlen($prefix)) == $prefix;
|
||||
}
|
||||
|
||||
function endswith($string, $suffix) {
|
||||
$suffix_length = strlen($suffix);
|
||||
return substr($string, strlen($string) - $suffix_length,
|
||||
$suffix_length) == $suffix;
|
||||
}
|
||||
|
||||
function file_put_contents_if_different($file_name, $content) {
|
||||
if (file_exists($file_name)) {
|
||||
$current_content = file_get_contents($file_name);
|
||||
if ($current_content == $content) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($file_name, $content);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Phabricator access list traversal.
|
||||
|
||||
class Configuration {
|
||||
// Phabricator user which is used as a viewer.
|
||||
public $viewer;
|
||||
|
||||
// Directory where public keys are stored.
|
||||
// Full path.
|
||||
protected $keys_directory;
|
||||
|
||||
// Gitolite configuration file (gitolite.conf).
|
||||
// Full path.
|
||||
protected $config_file;
|
||||
|
||||
// Indexed by key content, contains configuration user name.
|
||||
protected $stored_keys;
|
||||
|
||||
// Indexed by config user name.
|
||||
protected $used_keys;
|
||||
|
||||
// Indexed by committers variable name, contains list of users which are
|
||||
// configured by Phabricator to be able to commit to the repository.
|
||||
protected $committers;
|
||||
|
||||
public function __construct($gitolite_root) {
|
||||
$this->viewer = PhabricatorUser::getOmnipotentUser();
|
||||
$this->keys_directory = "$gitolite_root/keydir";
|
||||
$this->config_file = "$gitolite_root/conf/gitolite.conf";
|
||||
|
||||
$this->collectSystemPublicKeys();
|
||||
|
||||
$this->used_keys = array();
|
||||
$this->committers = array();
|
||||
|
||||
if (!file_exists($this->config_file)) {
|
||||
die("Not found: $this->config_file\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Store given key of given user.
|
||||
//
|
||||
// Includes both storing public key in the file, and storing mapping between
|
||||
// user and the key.
|
||||
public function storeUserPublicKey($user, $key) {
|
||||
$full_key_content = $this->getPublicKeyContent($key);
|
||||
|
||||
if (array_key_exists($full_key_content, $this->stored_keys)) {
|
||||
return $this->stored_keys[$full_key_content];
|
||||
}
|
||||
|
||||
$config_user_name = $this->getConfigUserName($user, $key);
|
||||
|
||||
if (!array_key_exists($config_user_name, $this->used_keys)) {
|
||||
$this->used_keys[$config_user_name] = true;
|
||||
file_put_contents_if_different("$this->keys_directory/$config_user_name.pub",
|
||||
$full_key_content);
|
||||
}
|
||||
|
||||
$this->stored_keys[$full_key_content] = $config_user_name;
|
||||
|
||||
return $config_user_name;
|
||||
}
|
||||
|
||||
public function setRepositoryUsers($repository, $config_user_names) {
|
||||
$uri = $repository->getRemoteURI();
|
||||
$repository_name = basename($uri, '.git');
|
||||
|
||||
$variable_name = '@committers_' . escape_name(strtolower($repository_name));
|
||||
|
||||
if (array_key_exists($variable_name, $this->committers)) {
|
||||
die("Duplicate variable mapping for repository $uri\n");
|
||||
}
|
||||
|
||||
$this->committers[$variable_name] = $config_user_names;
|
||||
}
|
||||
|
||||
public function writeNewConfiguration() {
|
||||
$current_config = file_get_contents($this->config_file);
|
||||
$current_config_lines = explode("\n", $current_config);
|
||||
|
||||
$new_config = "";
|
||||
foreach ($current_config_lines as $line) {
|
||||
if (startswith($line, '@committers_')) {
|
||||
$parts = explode('=', $line);
|
||||
$variable_name = trim($parts[0]);
|
||||
if (array_key_exists($variable_name, $this->committers)) {
|
||||
$system_committers = $this->getNonPhabtricatorUsers($parts[1]);
|
||||
$all_committers = array_merge(
|
||||
$system_committers, $this->committers[$variable_name]);
|
||||
$unique_committers = array_unique($all_committers);
|
||||
$committers = implode(' ', $unique_committers);
|
||||
$line = "$variable_name = $committers";
|
||||
}
|
||||
}
|
||||
$new_config .= $line . "\n";
|
||||
}
|
||||
|
||||
file_put_contents_if_different($this->config_file, trim($new_config) . "\n");
|
||||
}
|
||||
|
||||
protected function getNonPhabtricatorUsers($configuration_value) {
|
||||
$system_users = array();
|
||||
$users = explode(' ', $configuration_value);
|
||||
foreach ($users as $user) {
|
||||
$user = trim($user);
|
||||
if (empty($user)) {
|
||||
continue;
|
||||
}
|
||||
if (startswith($user, 'PHAB')) {
|
||||
continue;
|
||||
}
|
||||
$system_users[] = $user;
|
||||
}
|
||||
return $system_users;
|
||||
}
|
||||
|
||||
public function finalize() {
|
||||
$this->removeUnusedPublicKeys();
|
||||
}
|
||||
|
||||
// Get content of a public key to be stored in file.
|
||||
protected function getPublicKeyContent($key) {
|
||||
return $key->getKeyType().' '.
|
||||
$key->getKeyBody().' '.
|
||||
$key->getKeyComment()."\n";
|
||||
}
|
||||
|
||||
// Get user+key name used by the Gitolite configuration.
|
||||
protected function getConfigUserName($user, $key) {
|
||||
$escaped_key_name = escape_name($key->getName());
|
||||
return 'PHAB_'.$user->getUserName().
|
||||
'_'.$escaped_key_name.
|
||||
'_'.$key->getID();
|
||||
}
|
||||
|
||||
// Get keys which are not managed by this Phabricator/Git integration script.
|
||||
//
|
||||
// Returns map from key content to the key file name. This is used to avoid
|
||||
// public key duplication in the case system key is used by phabricator user.
|
||||
protected function collectSystemPublicKeys() {
|
||||
$files = scandir($this->keys_directory);
|
||||
foreach ($files as $file) {
|
||||
if (startswith($file, "PHAB")) {
|
||||
continue;
|
||||
}
|
||||
if (!endswith($file, '.pub')) {
|
||||
continue;
|
||||
}
|
||||
$key = file_get_contents("$this->keys_directory/$file");
|
||||
$file_we = basename($file, '.pub');
|
||||
$this->stored_keys[$key] = $file_we;
|
||||
$this->used_keys[$file_we] = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function removeUnusedPublicKeys() {
|
||||
$files = scandir($this->keys_directory);
|
||||
foreach ($files as $file) {
|
||||
if (!startswith($file, "PHAB")) {
|
||||
continue;
|
||||
}
|
||||
$config_user_name = basename($file, '.pub');
|
||||
if (!array_key_exists($config_user_name, $this->used_keys)) {
|
||||
unlink("$this->keys_directory/$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function getProjectMembersPHIDs($viewer, $project_phid) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($project_phid))
|
||||
->executeOne();
|
||||
|
||||
return $project->getMemberPHIDs();
|
||||
}
|
||||
|
||||
// Get user's heys and put them to the configuration
|
||||
function handleSingleUserPHID($config, $userPHID) {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($config->viewer)
|
||||
->withPHIDs(array($userPHID))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($user->getIsDisabled()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$keys = id(new PhabricatorAuthSSHKey())->loadAllWhere(
|
||||
'objectPHID = %s',
|
||||
$user->getPHID());
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($keys as $key) {
|
||||
$config_user_name = $config->storeUserPublicKey($user, $key);
|
||||
$config_user_names[] = $config_user_name;
|
||||
}
|
||||
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleUsersPolicyRule($config, $rule) {
|
||||
$config_user_names = array();
|
||||
foreach ($rule['value'] as $userPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $userPHID));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleProjectsPolicyRule($config, $rule) {
|
||||
$config_user_names = array();
|
||||
foreach ($rule['value'] as $projectPHID) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($config->viewer, $projectPHID);
|
||||
foreach ($memberPHIDs as $userPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $userPHID));
|
||||
}
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleProjectsAllPolicyRule($config, $rule) {
|
||||
$is_first_project = true;
|
||||
$allowed_members_phids = array();
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($config->viewer, $project_phid);
|
||||
if ($is_first_project) {
|
||||
$allowed_members_phids = $memberPHIDs;
|
||||
$is_first_project = false;
|
||||
} else {
|
||||
$allowed_members_phids = array_intersect(
|
||||
$allowed_members_phids, $memberPHIDs);
|
||||
}
|
||||
}
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($allowed_members_phids as $userPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $userPHID));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleAdministratorsPolicyRule($config, $rule) {
|
||||
$administrators = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($config->viewer)
|
||||
->withIsAdmin(true)
|
||||
->execute();
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($administrators as $administrator) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $administrator->getPHID()));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleLegalpadSingleDocument($config, $document) {
|
||||
if ($document->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($document->getSignatures() as $signature) {
|
||||
if ($signature->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
continue;
|
||||
}
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $signature->getSignerPHID()));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleLegalpadSignaturePolicyRule($config, $rule) {
|
||||
$documents = id(new LegalpadDocumentQuery())
|
||||
->setViewer($config->viewer)
|
||||
->withPHIDs($rule['value'])
|
||||
->needSignatures(true)
|
||||
->execute();
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($documents as $document) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleLegalpadSingleDocument($config, $document));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleCustomPolicy($config, $policy) {
|
||||
$config_user_names = array();
|
||||
$rules = $policy->getRules();
|
||||
foreach ($rules as $rule) {
|
||||
// Everyone is denied by default anyway
|
||||
if ($rule['action'] != 'allow') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$policy_config_user_names = array();
|
||||
$rule_type = $rule['rule'];
|
||||
if ($rule_type == 'PhabricatorPolicyRuleUsers') {
|
||||
$policy_config_user_names =
|
||||
handleUsersPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorProjectsPolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleProjectsPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorProjectsAllPolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleProjectsAllPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorAdministratorsPolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleAdministratorsPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorLegalpadSignaturePolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleLegalpadSignaturePolicyRule($config, $rule);
|
||||
}
|
||||
|
||||
$config_user_names = array_merge(
|
||||
$config_user_names, $policy_config_user_names);
|
||||
}
|
||||
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
// Parse repository and put it's members to the config file
|
||||
function handleSingleRepository($config, $repository) {
|
||||
$policies = PhabricatorPolicyQuery::loadPolicies(
|
||||
$config->viewer,
|
||||
$repository);
|
||||
|
||||
$pushable = $policies[DiffusionPushCapability::CAPABILITY];
|
||||
$type = $pushable->getType();
|
||||
|
||||
$config_user_names = array();
|
||||
|
||||
if ($type == PhabricatorPolicyType::TYPE_PROJECT) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($config->viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($pushable->getPHID()))
|
||||
->executeOne();
|
||||
|
||||
$memberPHIDs = $project->getMemberPHIDs();
|
||||
foreach ($memberPHIDs as $memberPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $memberPHID));
|
||||
}
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_USER) {
|
||||
$config_user_names = handleSingleUserPHID($config, $pushable->getPHID());
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_CUSTOM) {
|
||||
$config_user_names = handleCustomPolicy($config, $pushable);
|
||||
} else {
|
||||
/* pass */
|
||||
}
|
||||
|
||||
$config->setRepositoryUsers($repository, $config_user_names);
|
||||
}
|
||||
|
||||
function rebuildConfiguration($gitolite_root) {
|
||||
$config = new Configuration($gitolite_root);
|
||||
|
||||
// Fill in new configuration and keys
|
||||
$used_keys = array();
|
||||
$repositories = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($config->viewer)
|
||||
->execute();
|
||||
|
||||
foreach ($repositories as $repository_id => $repository) {
|
||||
$type = $repository->getVersionControlSystem();
|
||||
if ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
|
||||
handleSingleRepository($config, $repository);
|
||||
}
|
||||
}
|
||||
|
||||
$config->writeNewConfiguration();
|
||||
|
||||
$config->finalize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Repository manipulation functionality.
|
||||
|
||||
function getGitCommand($repository) {
|
||||
$git_dir = realpath("$repository/.git");
|
||||
$git = "git --git-dir='$git_dir'";
|
||||
$git .= ' --work-tree='.realpath($repository);
|
||||
return $git;
|
||||
}
|
||||
|
||||
function runGitCommand($repository, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$git = getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function runGitSshCommand($repository, $key, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$abs_key = realpath($key);
|
||||
$git = "GIT_SSH_COMMAND=\"ssh -i $key -o IdentitiesOnly=yes\" ";
|
||||
$git .= getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function repositoryPull($repository, $key) {
|
||||
return runGitSshCommand($repository, $key, 'pull --rebase');
|
||||
}
|
||||
|
||||
function repositoryCommitAll($repository, $author, $message) {
|
||||
if (!runGitCommand(
|
||||
$repository, 'ls-files --other --exclude-standard', $untracked_files)) {
|
||||
return false;
|
||||
}
|
||||
if (count($untracked_files)) {
|
||||
$flat_files = join(' ', $untracked_files);
|
||||
if (!runGitCommand($repository, "add $flat_files")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
runGitCommand($repository, "update-index -q --refresh", $output);
|
||||
runGitCommand($repository, "diff-index --name-only HEAD --", $output);
|
||||
if (count($output)) {
|
||||
return runGitCommand(
|
||||
$repository, "commit --author='$author' -a -m '$message'", $output);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count($argv) != 3) {
|
||||
print("Usage: {$argv[0]} /path/to/gitolite-admin /path/to/id_rsa.pub\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$gitolite_root = $argv[1];
|
||||
$key = $argv[2];
|
||||
|
||||
if (!repositoryPull($gitolite_root, $key)) {
|
||||
print("Failed to pull changes from server.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!rebuildConfiguration($gitolite_root)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!repositoryCommitAll(
|
||||
$gitolite_root, 'Rebuild Gitadmin <null@git.blender.org>',
|
||||
'Update to correspond changes in Phabricator')) {
|
||||
print("Failed to commit changes.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
runGitSshCommand($gitolite_root, $key, 'push origin master');
|
||||
?>
|
||||
@@ -8,10 +8,14 @@ function init_phabricator_script(array $options) {
|
||||
ini_set(
|
||||
'include_path',
|
||||
$include_path.PATH_SEPARATOR.dirname(__FILE__).'/../../../');
|
||||
@include_once 'libphutil/scripts/__init_script__.php';
|
||||
if (!@constant('__LIBPHUTIL__')) {
|
||||
echo "ERROR: Unable to load libphutil. Update your PHP 'include_path' to ".
|
||||
"include the parent directory of libphutil/.\n";
|
||||
|
||||
$ok = @include_once 'arcanist/support/init/init-script.php';
|
||||
if (!$ok) {
|
||||
echo
|
||||
'FATAL ERROR: Unable to load the "Arcanist" library. '.
|
||||
'Put "arcanist/" next to "phabricator/" on disk.';
|
||||
echo "\n";
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ failed() {
|
||||
}
|
||||
|
||||
ISSUE=`cat /etc/issue`
|
||||
if [[ $ISSUE != Ubuntu* ]]
|
||||
if [[ ($ISSUE != Ubuntu*) && ($ISSUE != Debian*) ]];
|
||||
then
|
||||
echo "This script is intended for use on Ubuntu, but this system appears";
|
||||
echo "to be something else. Your results may vary.";
|
||||
|
||||
61
scripts/svnauth/archived_repos.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
$ARCHIVED_REPOS = array(
|
||||
'abstractmesh',
|
||||
'beast',
|
||||
# 'bf-blender',
|
||||
'bf-docboard-es',
|
||||
'bf-extensions',
|
||||
'bf-funboard',
|
||||
'bf-scripts',
|
||||
# 'bf-translations',
|
||||
'bfct',
|
||||
'bforge',
|
||||
'blend-doc',
|
||||
'blend2cs',
|
||||
'blendedmidi',
|
||||
'blendercad',
|
||||
'blendxml',
|
||||
'bzoo',
|
||||
'docboard',
|
||||
'drqueue',
|
||||
'ghost',
|
||||
'girona',
|
||||
'guiman',
|
||||
'lsystem',
|
||||
'magic',
|
||||
'makeh',
|
||||
'mechanicblender',
|
||||
'neverblender',
|
||||
'news',
|
||||
'night',
|
||||
'nitrox',
|
||||
'osgexport',
|
||||
'peerrating',
|
||||
'piovra',
|
||||
'pyverse',
|
||||
'qdune',
|
||||
'scolblender',
|
||||
'skined',
|
||||
'smdio',
|
||||
'soapyblender',
|
||||
'soc-2005',
|
||||
'soc-2006',
|
||||
'soc-2007',
|
||||
'soc-2008',
|
||||
'sourceforge',
|
||||
'spe',
|
||||
'stats',
|
||||
'ter2blend',
|
||||
'torqueexporter',
|
||||
'tuhopuu',
|
||||
'tzuray',
|
||||
'vectex',
|
||||
'vectorrender',
|
||||
'verse',
|
||||
'vrmlimportexp',
|
||||
'warblender',
|
||||
'wpyre',
|
||||
'yafray',
|
||||
'yofrankie'
|
||||
);
|
||||
?>
|
||||
292
scripts/svnauth/rebuild_svnauth.php
Executable file
@@ -0,0 +1,292 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
function getSVNRepositoryName($repository) {
|
||||
$uri = $repository->getRemoteURI();
|
||||
return preg_replace(
|
||||
'/https?\:\/\/.*?\/svnroot\/([^\/]+)\/?.*/', '$1', $uri);
|
||||
}
|
||||
|
||||
// Get user's heys and put them to the configuration
|
||||
function handleSingleUserPHID(
|
||||
$viewer, $userPHID, $repository, &$namemap, &$access) {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($userPHID))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($user->getIsDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user_name = $user->getUserName();
|
||||
if (!array_key_exists($user_name, $namemap)) {
|
||||
$namemap[$user_name] = array('email' => $user->loadPrimaryEmailAddress(),
|
||||
'name' => $user->getRealName());
|
||||
}
|
||||
|
||||
$repository_name = getSVNRepositoryName($repository);
|
||||
|
||||
$repository_rootpath = $repository_name . ':/';
|
||||
if (!array_key_exists($repository_rootpath, $access)) {
|
||||
$access[$repository_rootpath]['RW'] = array();
|
||||
$access[$repository_rootpath]['RO'] = array();
|
||||
}
|
||||
$access[$repository_rootpath]['RO'][] = $user_name;
|
||||
|
||||
// Store write access settings to current subath
|
||||
$subpath = $repository->getDetail('svn-subpath');
|
||||
$subpath = rtrim($subpath, '/');
|
||||
$repository_pathname = "$repository_name:/$subpath";
|
||||
if (!array_key_exists($repository_pathname, $access)) {
|
||||
$access[$repository_pathname]['RW'] = array();
|
||||
$access[$repository_pathname]['RO'] = array();
|
||||
}
|
||||
$access[$repository_pathname]['RW'][] = $user_name;
|
||||
|
||||
// Write access to the tags
|
||||
$tags_pathname = "$repository_name:/tags";
|
||||
if (!array_key_exists($tags_pathname, $access)) {
|
||||
$access[$tags_pathname]['RW'] = array();
|
||||
$access[$tags_pathname]['RO'] = array();
|
||||
}
|
||||
$access[$tags_pathname]['RW'][] = $user_name;
|
||||
|
||||
// Write access to the branches.
|
||||
$branches_pathname = "$repository_name:/branches";
|
||||
if (!array_key_exists($branches_pathname, $access)) {
|
||||
$access[$branches_pathname]['RW'] = array();
|
||||
$access[$branches_pathname]['RO'] = array();
|
||||
}
|
||||
$access[$branches_pathname]['RW'][] = $user_name;
|
||||
}
|
||||
|
||||
function getProjectMembersPHIDs($viewer, $project_phid) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($project_phid))
|
||||
->executeOne();
|
||||
|
||||
return $project->getMemberPHIDs();
|
||||
}
|
||||
|
||||
function handleProjectPHID(
|
||||
$viewer, $project_phid, $repository, &$namemap, &$access) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $project_phid);
|
||||
foreach ($memberPHIDs as $memberPHID) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $memberPHID, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleUsersPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
foreach ($rule['value'] as $user_phid) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $user_phid, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleProjectsPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
handleProjectPHID(
|
||||
$viewer, $project_phid, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleProjectsAllPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
$is_first_project = true;
|
||||
$allowed_members_phids = array();
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $project_phid);
|
||||
if ($is_first_project) {
|
||||
$allowed_members_phids = $memberPHIDs;
|
||||
$is_first_project = false;
|
||||
} else {
|
||||
$allowed_members_phids = array_intersect(
|
||||
$allowed_members_phids, $memberPHIDs);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($allowed_members_phids as $user_phid) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $user_phid, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleAdministratorsPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
$administrators = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withIsAdmin(true)
|
||||
->execute();
|
||||
foreach ($administrators as $administrator) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $administrator->getPHID(), $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleLegalpadSingleDocument(
|
||||
$viewer, $document, $repository, &$namemap, &$access) {
|
||||
if ($document->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($document->getSignatures() as $signature) {
|
||||
if ($signature->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
continue;
|
||||
}
|
||||
handleSingleUserPHID(
|
||||
$viewer, $signature->getSignerPHID(), $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleLegalpadSignaturePolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
$documents = id(new LegalpadDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($rule['value'])
|
||||
->needSignatures(true)
|
||||
->execute();
|
||||
|
||||
foreach ($documents as $document) {
|
||||
handleLegalpadSingleDocument(
|
||||
$viewer, $document, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCustomPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
if ($rule['action'] != PhabricatorPolicy::ACTION_ALLOW) {
|
||||
// By default the script decides to DENY unless explicitly allowed.
|
||||
return;
|
||||
}
|
||||
|
||||
$rule_type = $rule['rule'];
|
||||
if ($rule_type == 'PhabricatorUsersPolicyRule') {
|
||||
handleUsersPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorProjectsPolicyRule') {
|
||||
handleProjectsPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorProjectsAllPolicyRule') {
|
||||
handleProjectsAllPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorAdministratorsPolicyRule') {
|
||||
handleAdministratorsPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorLegalpadSignaturePolicyRule') {
|
||||
handleLegalpadSignaturePolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCustomPolicy(
|
||||
$viewer, $policy, $repository, &$namemap, &$access) {
|
||||
foreach ($policy->getRules() as $rule) {
|
||||
handleCustomPolicyRule($viewer, $rule, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse repository and put it's members to the config file
|
||||
function handleSingleRepository(
|
||||
$viewer, $repository, &$namemap, &$access) {
|
||||
$policies = PhabricatorPolicyQuery::loadPolicies(
|
||||
$viewer,
|
||||
$repository);
|
||||
|
||||
$pushable = $policies[DiffusionPushCapability::CAPABILITY];
|
||||
$type = phid_get_type($pushable->getPHID());
|
||||
|
||||
// Make sure repository is always available for read-only access
|
||||
$repository_rootpath = getSVNRepositoryName($repository) . ':/';
|
||||
if (!array_key_exists($repository_rootpath, $access)) {
|
||||
$access[$repository_rootpath]['RW'] = array();
|
||||
$access[$repository_rootpath]['RO'] = array();
|
||||
}
|
||||
|
||||
if ($type == PhabricatorProjectProjectPHIDType::TYPECONST) {
|
||||
handleProjectPHID(
|
||||
$viewer, $pushable->getPHID(), $repository, $namemap, $access);
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_USER) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $pushable->getPHID(), $repository, $namemap, $access);
|
||||
} else if ($type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) {
|
||||
handleCustomPolicy(
|
||||
$viewer, $pushable, $repository, $namemap, $access);
|
||||
/* pass */
|
||||
} else {
|
||||
/* pass */
|
||||
}
|
||||
}
|
||||
|
||||
function rebuildConfiguration($what) {
|
||||
$viewer = id(new PhabricatorUser())
|
||||
->loadOneWhere('username = %s', 'sergey');
|
||||
|
||||
$repositories = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($viewer)
|
||||
->execute();
|
||||
|
||||
$namemap = array();
|
||||
$access = array();
|
||||
|
||||
require_once 'archived_repos.php';
|
||||
foreach ($ARCHIVED_REPOS as $repository) {
|
||||
$repository_pathname = "$repository:/";
|
||||
$access[$repository_pathname]['RW'] = array();
|
||||
$access[$repository_pathname]['RO'] = array();
|
||||
}
|
||||
|
||||
foreach ($repositories as $repository_id => $repository) {
|
||||
$type = $repository->getVersionControlSystem();
|
||||
if ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) {
|
||||
handleSingleRepository(
|
||||
$viewer, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
if ($what == 'ACCESS') {
|
||||
foreach ($access as $repository => $users) {
|
||||
print("[$repository]\n");
|
||||
$rw_users = array();
|
||||
foreach ($users['RW'] as $user) {
|
||||
print("$user = rw\n");
|
||||
$rw_users[$user] = true;
|
||||
}
|
||||
foreach ($users['RO'] as $user) {
|
||||
if (!array_key_exists($user, $rw_users)) {
|
||||
print("$user = r\n");
|
||||
}
|
||||
}
|
||||
print("anonsvn = r\n");
|
||||
print("* = r\n\n");
|
||||
}
|
||||
} else if ($what == 'NAMEMAP') {
|
||||
foreach ($namemap as $user => $data) {
|
||||
print("$user\t${data['email']}\t${data['name']}\n");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count($argv) != 2 ||
|
||||
($argv[1] != 'ACCESS' && $argv[1] != 'NAMEMAP')) {
|
||||
print("Usage: {$argv[0]} ACCESS|NAMEMAP\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rebuildConfiguration($argv[1]);
|
||||
?>
|
||||
@@ -179,6 +179,7 @@ phutil_register_library_map(array(
|
||||
'AphrontAccessDeniedQueryException' => 'infrastructure/storage/exception/AphrontAccessDeniedQueryException.php',
|
||||
'AphrontAjaxResponse' => 'aphront/response/AphrontAjaxResponse.php',
|
||||
'AphrontApplicationConfiguration' => 'aphront/configuration/AphrontApplicationConfiguration.php',
|
||||
'AphrontAutoIDView' => 'view/AphrontAutoIDView.php',
|
||||
'AphrontBarView' => 'view/widget/bars/AphrontBarView.php',
|
||||
'AphrontBaseMySQLDatabaseConnection' => 'infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php',
|
||||
'AphrontBoolHTTPParameterType' => 'aphront/httpparametertype/AphrontBoolHTTPParameterType.php',
|
||||
@@ -224,6 +225,8 @@ phutil_register_library_map(array(
|
||||
'AphrontFormView' => 'view/form/AphrontFormView.php',
|
||||
'AphrontGlyphBarView' => 'view/widget/bars/AphrontGlyphBarView.php',
|
||||
'AphrontHTMLResponse' => 'aphront/response/AphrontHTMLResponse.php',
|
||||
'AphrontHTTPHeaderParser' => 'aphront/headerparser/AphrontHTTPHeaderParser.php',
|
||||
'AphrontHTTPHeaderParserTestCase' => 'aphront/headerparser/__tests__/AphrontHTTPHeaderParserTestCase.php',
|
||||
'AphrontHTTPParameterType' => 'aphront/httpparametertype/AphrontHTTPParameterType.php',
|
||||
'AphrontHTTPProxyResponse' => 'aphront/response/AphrontHTTPProxyResponse.php',
|
||||
'AphrontHTTPSink' => 'aphront/sink/AphrontHTTPSink.php',
|
||||
@@ -242,6 +245,9 @@ phutil_register_library_map(array(
|
||||
'AphrontMalformedRequestException' => 'aphront/exception/AphrontMalformedRequestException.php',
|
||||
'AphrontMoreView' => 'view/layout/AphrontMoreView.php',
|
||||
'AphrontMultiColumnView' => 'view/layout/AphrontMultiColumnView.php',
|
||||
'AphrontMultipartParser' => 'aphront/multipartparser/AphrontMultipartParser.php',
|
||||
'AphrontMultipartParserTestCase' => 'aphront/multipartparser/__tests__/AphrontMultipartParserTestCase.php',
|
||||
'AphrontMultipartPart' => 'aphront/multipartparser/AphrontMultipartPart.php',
|
||||
'AphrontMySQLDatabaseConnection' => 'infrastructure/storage/connection/mysql/AphrontMySQLDatabaseConnection.php',
|
||||
'AphrontMySQLDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontMySQLDatabaseConnectionTestCase.php',
|
||||
'AphrontMySQLiDatabaseConnection' => 'infrastructure/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php',
|
||||
@@ -265,12 +271,15 @@ phutil_register_library_map(array(
|
||||
'AphrontReloadResponse' => 'aphront/response/AphrontReloadResponse.php',
|
||||
'AphrontRequest' => 'aphront/AphrontRequest.php',
|
||||
'AphrontRequestExceptionHandler' => 'aphront/handler/AphrontRequestExceptionHandler.php',
|
||||
'AphrontRequestStream' => 'aphront/requeststream/AphrontRequestStream.php',
|
||||
'AphrontRequestTestCase' => 'aphront/__tests__/AphrontRequestTestCase.php',
|
||||
'AphrontResponse' => 'aphront/response/AphrontResponse.php',
|
||||
'AphrontResponseProducerInterface' => 'aphront/interface/AphrontResponseProducerInterface.php',
|
||||
'AphrontRoutingMap' => 'aphront/site/AphrontRoutingMap.php',
|
||||
'AphrontRoutingMapTestCase' => 'aphront/__tests__/AphrontRoutingMapTestCase.php',
|
||||
'AphrontRoutingResult' => 'aphront/site/AphrontRoutingResult.php',
|
||||
'AphrontSchemaQueryException' => 'infrastructure/storage/exception/AphrontSchemaQueryException.php',
|
||||
'AphrontScopedUnguardedWriteCapability' => 'aphront/writeguard/AphrontScopedUnguardedWriteCapability.php',
|
||||
'AphrontSelectHTTPParameterType' => 'aphront/httpparametertype/AphrontSelectHTTPParameterType.php',
|
||||
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
|
||||
'AphrontSite' => 'aphront/site/AphrontSite.php',
|
||||
@@ -286,6 +295,7 @@ phutil_register_library_map(array(
|
||||
'AphrontUserListHTTPParameterType' => 'aphront/httpparametertype/AphrontUserListHTTPParameterType.php',
|
||||
'AphrontView' => 'view/AphrontView.php',
|
||||
'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.php',
|
||||
'AphrontWriteGuard' => 'aphront/writeguard/AphrontWriteGuard.php',
|
||||
'ArcanistConduitAPIMethod' => 'applications/arcanist/conduit/ArcanistConduitAPIMethod.php',
|
||||
'AuditConduitAPIMethod' => 'applications/audit/conduit/AuditConduitAPIMethod.php',
|
||||
'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php',
|
||||
@@ -456,7 +466,6 @@ phutil_register_library_map(array(
|
||||
'DifferentialChangeset' => 'applications/differential/storage/DifferentialChangeset.php',
|
||||
'DifferentialChangesetDetailView' => 'applications/differential/view/DifferentialChangesetDetailView.php',
|
||||
'DifferentialChangesetEngine' => 'applications/differential/engine/DifferentialChangesetEngine.php',
|
||||
'DifferentialChangesetFileTreeSideNavBuilder' => 'applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php',
|
||||
'DifferentialChangesetHTMLRenderer' => 'applications/differential/render/DifferentialChangesetHTMLRenderer.php',
|
||||
'DifferentialChangesetListController' => 'applications/differential/controller/DifferentialChangesetListController.php',
|
||||
'DifferentialChangesetListView' => 'applications/differential/view/DifferentialChangesetListView.php',
|
||||
@@ -529,6 +538,7 @@ phutil_register_library_map(array(
|
||||
'DifferentialExactUserFunctionDatasource' => 'applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php',
|
||||
'DifferentialFieldParseException' => 'applications/differential/exception/DifferentialFieldParseException.php',
|
||||
'DifferentialFieldValidationException' => 'applications/differential/exception/DifferentialFieldValidationException.php',
|
||||
'DifferentialFileTreeEngine' => 'applications/differential/engine/DifferentialFileTreeEngine.php',
|
||||
'DifferentialGetAllDiffsConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetAllDiffsConduitAPIMethod.php',
|
||||
'DifferentialGetCommitMessageConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetCommitMessageConduitAPIMethod.php',
|
||||
'DifferentialGetCommitPathsConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetCommitPathsConduitAPIMethod.php',
|
||||
@@ -551,7 +561,6 @@ phutil_register_library_map(array(
|
||||
'DifferentialInlineComment' => 'applications/differential/storage/DifferentialInlineComment.php',
|
||||
'DifferentialInlineCommentEditController' => 'applications/differential/controller/DifferentialInlineCommentEditController.php',
|
||||
'DifferentialInlineCommentMailView' => 'applications/differential/mail/DifferentialInlineCommentMailView.php',
|
||||
'DifferentialInlineCommentQuery' => 'applications/differential/query/DifferentialInlineCommentQuery.php',
|
||||
'DifferentialJIRAIssuesCommitMessageField' => 'applications/differential/field/DifferentialJIRAIssuesCommitMessageField.php',
|
||||
'DifferentialJIRAIssuesField' => 'applications/differential/customfield/DifferentialJIRAIssuesField.php',
|
||||
'DifferentialLegacyQuery' => 'applications/differential/constants/DifferentialLegacyQuery.php',
|
||||
@@ -704,6 +713,9 @@ phutil_register_library_map(array(
|
||||
'DifferentialUnitStatus' => 'applications/differential/constants/DifferentialUnitStatus.php',
|
||||
'DifferentialUnitTestResult' => 'applications/differential/constants/DifferentialUnitTestResult.php',
|
||||
'DifferentialUpdateRevisionConduitAPIMethod' => 'applications/differential/conduit/DifferentialUpdateRevisionConduitAPIMethod.php',
|
||||
'DifferentialViewState' => 'applications/differential/storage/DifferentialViewState.php',
|
||||
'DifferentialViewStateGarbageCollector' => 'applications/differential/garbagecollector/DifferentialViewStateGarbageCollector.php',
|
||||
'DifferentialViewStateQuery' => 'applications/differential/query/DifferentialViewStateQuery.php',
|
||||
'DiffusionAuditorDatasource' => 'applications/diffusion/typeahead/DiffusionAuditorDatasource.php',
|
||||
'DiffusionAuditorFunctionDatasource' => 'applications/diffusion/typeahead/DiffusionAuditorFunctionDatasource.php',
|
||||
'DiffusionAuditorsAddAuditorsHeraldAction' => 'applications/diffusion/herald/DiffusionAuditorsAddAuditorsHeraldAction.php',
|
||||
@@ -864,7 +876,6 @@ phutil_register_library_map(array(
|
||||
'DiffusionIdentityUnassignedDatasource' => 'applications/diffusion/typeahead/DiffusionIdentityUnassignedDatasource.php',
|
||||
'DiffusionIdentityViewController' => 'applications/diffusion/controller/DiffusionIdentityViewController.php',
|
||||
'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
|
||||
'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
|
||||
'DiffusionInternalAncestorsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionInternalAncestorsConduitAPIMethod.php',
|
||||
'DiffusionInternalGitRawDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionInternalGitRawDiffQueryConduitAPIMethod.php',
|
||||
'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
|
||||
@@ -1279,6 +1290,8 @@ phutil_register_library_map(array(
|
||||
'FeedPushWorker' => 'applications/feed/worker/FeedPushWorker.php',
|
||||
'FeedQueryConduitAPIMethod' => 'applications/feed/conduit/FeedQueryConduitAPIMethod.php',
|
||||
'FeedStoryNotificationGarbageCollector' => 'applications/notification/garbagecollector/FeedStoryNotificationGarbageCollector.php',
|
||||
'FerretConfigurableSearchFunction' => 'applications/search/ferret/function/FerretConfigurableSearchFunction.php',
|
||||
'FerretSearchFunction' => 'applications/search/ferret/function/FerretSearchFunction.php',
|
||||
'FileAllocateConduitAPIMethod' => 'applications/files/conduit/FileAllocateConduitAPIMethod.php',
|
||||
'FileConduitAPIMethod' => 'applications/files/conduit/FileConduitAPIMethod.php',
|
||||
'FileCreateMailReceiver' => 'applications/files/mail/FileCreateMailReceiver.php',
|
||||
@@ -1760,6 +1773,7 @@ phutil_register_library_map(array(
|
||||
'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php',
|
||||
'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php',
|
||||
'ManiphestSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestSearchConduitAPIMethod.php',
|
||||
'ManiphestSearchController' => 'applications/maniphest/controller/ManiphestSearchController.php',
|
||||
'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php',
|
||||
'ManiphestStatusSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php',
|
||||
'ManiphestStatusesConfigType' => 'applications/maniphest/config/ManiphestStatusesConfigType.php',
|
||||
@@ -1991,6 +2005,8 @@ phutil_register_library_map(array(
|
||||
'PHUICrumbView' => 'view/phui/PHUICrumbView.php',
|
||||
'PHUICrumbsView' => 'view/phui/PHUICrumbsView.php',
|
||||
'PHUICurtainExtension' => 'view/extension/PHUICurtainExtension.php',
|
||||
'PHUICurtainObjectRefListView' => 'view/phui/PHUICurtainObjectRefListView.php',
|
||||
'PHUICurtainObjectRefView' => 'view/phui/PHUICurtainObjectRefView.php',
|
||||
'PHUICurtainPanelView' => 'view/layout/PHUICurtainPanelView.php',
|
||||
'PHUICurtainView' => 'view/layout/PHUICurtainView.php',
|
||||
'PHUIDiffGraphView' => 'infrastructure/diff/view/PHUIDiffGraphView.php',
|
||||
@@ -2020,6 +2036,14 @@ phutil_register_library_map(array(
|
||||
'PHUIFormLayoutView' => 'view/form/PHUIFormLayoutView.php',
|
||||
'PHUIFormNumberControl' => 'view/form/control/PHUIFormNumberControl.php',
|
||||
'PHUIFormTimerControl' => 'view/form/control/PHUIFormTimerControl.php',
|
||||
'PHUIFormationColumnDynamicView' => 'view/formation/PHUIFormationColumnDynamicView.php',
|
||||
'PHUIFormationColumnItem' => 'view/formation/PHUIFormationColumnItem.php',
|
||||
'PHUIFormationColumnView' => 'view/formation/PHUIFormationColumnView.php',
|
||||
'PHUIFormationContentView' => 'view/formation/PHUIFormationContentView.php',
|
||||
'PHUIFormationExpanderView' => 'view/formation/PHUIFormationExpanderView.php',
|
||||
'PHUIFormationFlankView' => 'view/formation/PHUIFormationFlankView.php',
|
||||
'PHUIFormationResizerView' => 'view/formation/PHUIFormationResizerView.php',
|
||||
'PHUIFormationView' => 'view/formation/PHUIFormationView.php',
|
||||
'PHUIHandleListView' => 'applications/phid/view/PHUIHandleListView.php',
|
||||
'PHUIHandleTagListView' => 'applications/phid/view/PHUIHandleTagListView.php',
|
||||
'PHUIHandleView' => 'applications/phid/view/PHUIHandleView.php',
|
||||
@@ -2037,8 +2061,10 @@ phutil_register_library_map(array(
|
||||
'PHUIInfoView' => 'view/phui/PHUIInfoView.php',
|
||||
'PHUIInvisibleCharacterTestCase' => 'view/phui/__tests__/PHUIInvisibleCharacterTestCase.php',
|
||||
'PHUIInvisibleCharacterView' => 'view/phui/PHUIInvisibleCharacterView.php',
|
||||
'PHUILauncherView' => 'view/phui/PHUILauncherView.php',
|
||||
'PHUILeftRightExample' => 'applications/uiexample/examples/PHUILeftRightExample.php',
|
||||
'PHUILeftRightView' => 'view/phui/PHUILeftRightView.php',
|
||||
'PHUILinkView' => 'view/phui/PHUILinkView.php',
|
||||
'PHUIListExample' => 'applications/uiexample/examples/PHUIListExample.php',
|
||||
'PHUIListItemView' => 'view/phui/PHUIListItemView.php',
|
||||
'PHUIListView' => 'view/phui/PHUIListView.php',
|
||||
@@ -2140,6 +2166,7 @@ phutil_register_library_map(array(
|
||||
'PasteSearchConduitAPIMethod' => 'applications/paste/conduit/PasteSearchConduitAPIMethod.php',
|
||||
'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php',
|
||||
'PeopleCreateUsersCapability' => 'applications/people/capability/PeopleCreateUsersCapability.php',
|
||||
'PeopleDisableSpamUsersCapability' => 'applications/people/capability/PeopleDisableSpamUsersCapability.php',
|
||||
'PeopleDisableUsersCapability' => 'applications/people/capability/PeopleDisableUsersCapability.php',
|
||||
'PeopleHovercardEngineExtension' => 'applications/people/engineextension/PeopleHovercardEngineExtension.php',
|
||||
'PeopleMainMenuBarExtension' => 'applications/people/engineextension/PeopleMainMenuBarExtension.php',
|
||||
@@ -2201,6 +2228,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorApplicationSearchResultView' => 'applications/search/view/PhabricatorApplicationSearchResultView.php',
|
||||
'PhabricatorApplicationTestCase' => 'applications/base/__tests__/PhabricatorApplicationTestCase.php',
|
||||
'PhabricatorApplicationTransaction' => 'applications/transactions/storage/PhabricatorApplicationTransaction.php',
|
||||
'PhabricatorApplicationTransactionCannedResponsesController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCannedResponsesController.php',
|
||||
'PhabricatorApplicationTransactionComment' => 'applications/transactions/storage/PhabricatorApplicationTransactionComment.php',
|
||||
'PhabricatorApplicationTransactionCommentEditController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentEditController.php',
|
||||
'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
|
||||
@@ -2720,6 +2748,8 @@ phutil_register_library_map(array(
|
||||
'PhabricatorChangePasswordUserLogType' => 'applications/people/userlog/PhabricatorChangePasswordUserLogType.php',
|
||||
'PhabricatorChangesetCachePurger' => 'applications/cache/purger/PhabricatorChangesetCachePurger.php',
|
||||
'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php',
|
||||
'PhabricatorChangesetViewState' => 'infrastructure/diff/viewstate/PhabricatorChangesetViewState.php',
|
||||
'PhabricatorChangesetViewStateEngine' => 'infrastructure/diff/viewstate/PhabricatorChangesetViewStateEngine.php',
|
||||
'PhabricatorChartAxis' => 'applications/fact/chart/PhabricatorChartAxis.php',
|
||||
'PhabricatorChartDataQuery' => 'applications/fact/chart/PhabricatorChartDataQuery.php',
|
||||
'PhabricatorChartDataset' => 'applications/fact/chart/PhabricatorChartDataset.php',
|
||||
@@ -2798,46 +2828,42 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConduitTokenQuery' => 'applications/conduit/query/PhabricatorConduitTokenQuery.php',
|
||||
'PhabricatorConduitTokenTerminateController' => 'applications/conduit/controller/PhabricatorConduitTokenTerminateController.php',
|
||||
'PhabricatorConduitTokensSettingsPanel' => 'applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php',
|
||||
'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php',
|
||||
'PhabricatorConfigApplication' => 'applications/config/application/PhabricatorConfigApplication.php',
|
||||
'PhabricatorConfigApplicationController' => 'applications/config/controller/PhabricatorConfigApplicationController.php',
|
||||
'PhabricatorConfigCacheController' => 'applications/config/controller/PhabricatorConfigCacheController.php',
|
||||
'PhabricatorConfigClusterDatabasesController' => 'applications/config/controller/PhabricatorConfigClusterDatabasesController.php',
|
||||
'PhabricatorConfigClusterNotificationsController' => 'applications/config/controller/PhabricatorConfigClusterNotificationsController.php',
|
||||
'PhabricatorConfigClusterRepositoriesController' => 'applications/config/controller/PhabricatorConfigClusterRepositoriesController.php',
|
||||
'PhabricatorConfigClusterSearchController' => 'applications/config/controller/PhabricatorConfigClusterSearchController.php',
|
||||
'PhabricatorConfigCacheController' => 'applications/config/controller/services/PhabricatorConfigCacheController.php',
|
||||
'PhabricatorConfigClusterDatabasesController' => 'applications/config/controller/services/PhabricatorConfigClusterDatabasesController.php',
|
||||
'PhabricatorConfigClusterNotificationsController' => 'applications/config/controller/services/PhabricatorConfigClusterNotificationsController.php',
|
||||
'PhabricatorConfigClusterRepositoriesController' => 'applications/config/controller/services/PhabricatorConfigClusterRepositoriesController.php',
|
||||
'PhabricatorConfigClusterSearchController' => 'applications/config/controller/services/PhabricatorConfigClusterSearchController.php',
|
||||
'PhabricatorConfigCollectorsModule' => 'applications/config/module/PhabricatorConfigCollectorsModule.php',
|
||||
'PhabricatorConfigColumnSchema' => 'applications/config/schema/PhabricatorConfigColumnSchema.php',
|
||||
'PhabricatorConfigConfigPHIDType' => 'applications/config/phid/PhabricatorConfigConfigPHIDType.php',
|
||||
'PhabricatorConfigConsoleController' => 'applications/config/controller/PhabricatorConfigConsoleController.php',
|
||||
'PhabricatorConfigConstants' => 'applications/config/constants/PhabricatorConfigConstants.php',
|
||||
'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
|
||||
'PhabricatorConfigCoreSchemaSpec' => 'applications/config/schema/PhabricatorConfigCoreSchemaSpec.php',
|
||||
'PhabricatorConfigDatabaseController' => 'applications/config/controller/PhabricatorConfigDatabaseController.php',
|
||||
'PhabricatorConfigDatabaseIssueController' => 'applications/config/controller/PhabricatorConfigDatabaseIssueController.php',
|
||||
'PhabricatorConfigDatabaseController' => 'applications/config/controller/services/PhabricatorConfigDatabaseController.php',
|
||||
'PhabricatorConfigDatabaseIssueController' => 'applications/config/controller/services/PhabricatorConfigDatabaseIssueController.php',
|
||||
'PhabricatorConfigDatabaseSchema' => 'applications/config/schema/PhabricatorConfigDatabaseSchema.php',
|
||||
'PhabricatorConfigDatabaseSource' => 'infrastructure/env/PhabricatorConfigDatabaseSource.php',
|
||||
'PhabricatorConfigDatabaseStatusController' => 'applications/config/controller/PhabricatorConfigDatabaseStatusController.php',
|
||||
'PhabricatorConfigDatabaseStatusController' => 'applications/config/controller/services/PhabricatorConfigDatabaseStatusController.php',
|
||||
'PhabricatorConfigDefaultSource' => 'infrastructure/env/PhabricatorConfigDefaultSource.php',
|
||||
'PhabricatorConfigDictionarySource' => 'infrastructure/env/PhabricatorConfigDictionarySource.php',
|
||||
'PhabricatorConfigEdgeModule' => 'applications/config/module/PhabricatorConfigEdgeModule.php',
|
||||
'PhabricatorConfigEditController' => 'applications/config/controller/PhabricatorConfigEditController.php',
|
||||
'PhabricatorConfigEditController' => 'applications/config/controller/settings/PhabricatorConfigEditController.php',
|
||||
'PhabricatorConfigEditor' => 'applications/config/editor/PhabricatorConfigEditor.php',
|
||||
'PhabricatorConfigEntry' => 'applications/config/storage/PhabricatorConfigEntry.php',
|
||||
'PhabricatorConfigEntryDAO' => 'applications/config/storage/PhabricatorConfigEntryDAO.php',
|
||||
'PhabricatorConfigEntryQuery' => 'applications/config/query/PhabricatorConfigEntryQuery.php',
|
||||
'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php',
|
||||
'PhabricatorConfigGroupConstants' => 'applications/config/constants/PhabricatorConfigGroupConstants.php',
|
||||
'PhabricatorConfigGroupController' => 'applications/config/controller/PhabricatorConfigGroupController.php',
|
||||
'PhabricatorConfigHTTPParameterTypesModule' => 'applications/config/module/PhabricatorConfigHTTPParameterTypesModule.php',
|
||||
'PhabricatorConfigHistoryController' => 'applications/config/controller/PhabricatorConfigHistoryController.php',
|
||||
'PhabricatorConfigIgnoreController' => 'applications/config/controller/PhabricatorConfigIgnoreController.php',
|
||||
'PhabricatorConfigIssueListController' => 'applications/config/controller/PhabricatorConfigIssueListController.php',
|
||||
'PhabricatorConfigIssuePanelController' => 'applications/config/controller/PhabricatorConfigIssuePanelController.php',
|
||||
'PhabricatorConfigIssueViewController' => 'applications/config/controller/PhabricatorConfigIssueViewController.php',
|
||||
'PhabricatorConfigIgnoreController' => 'applications/config/controller/issue/PhabricatorConfigIgnoreController.php',
|
||||
'PhabricatorConfigIssueListController' => 'applications/config/controller/issue/PhabricatorConfigIssueListController.php',
|
||||
'PhabricatorConfigIssuePanelController' => 'applications/config/controller/issue/PhabricatorConfigIssuePanelController.php',
|
||||
'PhabricatorConfigIssueViewController' => 'applications/config/controller/issue/PhabricatorConfigIssueViewController.php',
|
||||
'PhabricatorConfigJSON' => 'applications/config/json/PhabricatorConfigJSON.php',
|
||||
'PhabricatorConfigJSONOptionType' => 'applications/config/custom/PhabricatorConfigJSONOptionType.php',
|
||||
'PhabricatorConfigKeySchema' => 'applications/config/schema/PhabricatorConfigKeySchema.php',
|
||||
'PhabricatorConfigListController' => 'applications/config/controller/PhabricatorConfigListController.php',
|
||||
'PhabricatorConfigLocalSource' => 'infrastructure/env/PhabricatorConfigLocalSource.php',
|
||||
'PhabricatorConfigManagementDeleteWorkflow' => 'applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php',
|
||||
'PhabricatorConfigManagementDoneWorkflow' => 'applications/config/management/PhabricatorConfigManagementDoneWorkflow.php',
|
||||
@@ -2848,12 +2874,12 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php',
|
||||
'PhabricatorConfigManualActivity' => 'applications/config/storage/PhabricatorConfigManualActivity.php',
|
||||
'PhabricatorConfigModule' => 'applications/config/module/PhabricatorConfigModule.php',
|
||||
'PhabricatorConfigModuleController' => 'applications/config/controller/PhabricatorConfigModuleController.php',
|
||||
'PhabricatorConfigModuleController' => 'applications/config/controller/module/PhabricatorConfigModuleController.php',
|
||||
'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php',
|
||||
'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php',
|
||||
'PhabricatorConfigPHIDModule' => 'applications/config/module/PhabricatorConfigPHIDModule.php',
|
||||
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
|
||||
'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php',
|
||||
'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/services/PhabricatorConfigPurgeCacheController.php',
|
||||
'PhabricatorConfigRegexOptionType' => 'applications/config/custom/PhabricatorConfigRegexOptionType.php',
|
||||
'PhabricatorConfigRemarkupRule' => 'infrastructure/markup/rule/PhabricatorConfigRemarkupRule.php',
|
||||
'PhabricatorConfigRequestExceptionHandlerModule' => 'applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php',
|
||||
@@ -2861,6 +2887,10 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigSchemaQuery' => 'applications/config/schema/PhabricatorConfigSchemaQuery.php',
|
||||
'PhabricatorConfigSchemaSpec' => 'applications/config/schema/PhabricatorConfigSchemaSpec.php',
|
||||
'PhabricatorConfigServerSchema' => 'applications/config/schema/PhabricatorConfigServerSchema.php',
|
||||
'PhabricatorConfigServicesController' => 'applications/config/controller/services/PhabricatorConfigServicesController.php',
|
||||
'PhabricatorConfigSettingsController' => 'applications/config/controller/settings/PhabricatorConfigSettingsController.php',
|
||||
'PhabricatorConfigSettingsHistoryController' => 'applications/config/controller/settings/PhabricatorConfigSettingsHistoryController.php',
|
||||
'PhabricatorConfigSettingsListController' => 'applications/config/controller/settings/PhabricatorConfigSettingsListController.php',
|
||||
'PhabricatorConfigSetupCheckModule' => 'applications/config/module/PhabricatorConfigSetupCheckModule.php',
|
||||
'PhabricatorConfigSiteModule' => 'applications/config/module/PhabricatorConfigSiteModule.php',
|
||||
'PhabricatorConfigSiteSource' => 'infrastructure/env/PhabricatorConfigSiteSource.php',
|
||||
@@ -2872,7 +2902,6 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigTransactionQuery' => 'applications/config/query/PhabricatorConfigTransactionQuery.php',
|
||||
'PhabricatorConfigType' => 'applications/config/type/PhabricatorConfigType.php',
|
||||
'PhabricatorConfigValidationException' => 'applications/config/exception/PhabricatorConfigValidationException.php',
|
||||
'PhabricatorConfigVersionController' => 'applications/config/controller/PhabricatorConfigVersionController.php',
|
||||
'PhabricatorConpherenceApplication' => 'applications/conpherence/application/PhabricatorConpherenceApplication.php',
|
||||
'PhabricatorConpherenceColumnMinimizeSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnMinimizeSetting.php',
|
||||
'PhabricatorConpherenceColumnVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceColumnVisibleSetting.php',
|
||||
@@ -3134,6 +3163,8 @@ phutil_register_library_map(array(
|
||||
'PhabricatorDestructionEngineExtensionModule' => 'applications/system/engine/PhabricatorDestructionEngineExtensionModule.php',
|
||||
'PhabricatorDeveloperConfigOptions' => 'applications/config/option/PhabricatorDeveloperConfigOptions.php',
|
||||
'PhabricatorDeveloperPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorDeveloperPreferencesSettingsPanel.php',
|
||||
'PhabricatorDiffInlineCommentContentState' => 'infrastructure/diff/inline/PhabricatorDiffInlineCommentContentState.php',
|
||||
'PhabricatorDiffInlineCommentContext' => 'infrastructure/diff/inline/PhabricatorDiffInlineCommentContext.php',
|
||||
'PhabricatorDiffInlineCommentQuery' => 'infrastructure/diff/query/PhabricatorDiffInlineCommentQuery.php',
|
||||
'PhabricatorDiffPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorDiffPreferencesSettingsPanel.php',
|
||||
'PhabricatorDiffScopeEngine' => 'infrastructure/diff/PhabricatorDiffScopeEngine.php',
|
||||
@@ -3233,6 +3264,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorEditEngineMFAInterface' => 'applications/transactions/editengine/PhabricatorEditEngineMFAInterface.php',
|
||||
'PhabricatorEditEngineNameTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineNameTransaction.php',
|
||||
'PhabricatorEditEngineOrderTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineOrderTransaction.php',
|
||||
'PhabricatorEditEnginePageState' => 'applications/transactions/editengine/PhabricatorEditEnginePageState.php',
|
||||
'PhabricatorEditEnginePointsCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEnginePointsCommentAction.php',
|
||||
'PhabricatorEditEnginePreambleTransaction' => 'applications/transactions/xaction/PhabricatorEditEnginePreambleTransaction.php',
|
||||
'PhabricatorEditEngineProfileMenuItem' => 'applications/search/menuitem/PhabricatorEditEngineProfileMenuItem.php',
|
||||
@@ -3256,8 +3288,10 @@ phutil_register_library_map(array(
|
||||
'PhabricatorEditorExtension' => 'applications/transactions/engineextension/PhabricatorEditorExtension.php',
|
||||
'PhabricatorEditorExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditorExtensionModule.php',
|
||||
'PhabricatorEditorMailEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditorMailEngineExtension.php',
|
||||
'PhabricatorEditorMultipleSetting' => 'applications/settings/setting/PhabricatorEditorMultipleSetting.php',
|
||||
'PhabricatorEditorSetting' => 'applications/settings/setting/PhabricatorEditorSetting.php',
|
||||
'PhabricatorEditorURIEngine' => 'infrastructure/editor/PhabricatorEditorURIEngine.php',
|
||||
'PhabricatorEditorURIEngineTestCase' => 'infrastructure/editor/__tests__/PhabricatorEditorURIEngineTestCase.php',
|
||||
'PhabricatorEditorURIParserException' => 'infrastructure/editor/PhabricatorEditorURIParserException.php',
|
||||
'PhabricatorElasticFulltextStorageEngine' => 'applications/search/fulltextstorage/PhabricatorElasticFulltextStorageEngine.php',
|
||||
'PhabricatorElasticsearchHost' => 'infrastructure/cluster/search/PhabricatorElasticsearchHost.php',
|
||||
'PhabricatorElasticsearchQueryBuilder' => 'applications/search/fulltextstorage/PhabricatorElasticsearchQueryBuilder.php',
|
||||
@@ -3306,8 +3340,11 @@ phutil_register_library_map(array(
|
||||
'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
|
||||
'PhabricatorExtensionsSetupCheck' => 'applications/config/check/PhabricatorExtensionsSetupCheck.php',
|
||||
'PhabricatorExternalAccount' => 'applications/people/storage/PhabricatorExternalAccount.php',
|
||||
'PhabricatorExternalAccountIdentifier' => 'applications/people/storage/PhabricatorExternalAccountIdentifier.php',
|
||||
'PhabricatorExternalAccountIdentifierQuery' => 'applications/auth/query/PhabricatorExternalAccountIdentifierQuery.php',
|
||||
'PhabricatorExternalAccountQuery' => 'applications/auth/query/PhabricatorExternalAccountQuery.php',
|
||||
'PhabricatorExternalAccountsSettingsPanel' => 'applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php',
|
||||
'PhabricatorExternalEditorSettingsPanel' => 'applications/settings/panel/PhabricatorExternalEditorSettingsPanel.php',
|
||||
'PhabricatorExtraConfigSetupCheck' => 'applications/config/check/PhabricatorExtraConfigSetupCheck.php',
|
||||
'PhabricatorFacebookAuthProvider' => 'applications/auth/provider/PhabricatorFacebookAuthProvider.php',
|
||||
'PhabricatorFact' => 'applications/fact/fact/PhabricatorFact.php',
|
||||
@@ -3337,6 +3374,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorFactRaw' => 'applications/fact/storage/PhabricatorFactRaw.php',
|
||||
'PhabricatorFactUpdateIterator' => 'applications/fact/extract/PhabricatorFactUpdateIterator.php',
|
||||
'PhabricatorFailHisecUserLogType' => 'applications/people/userlog/PhabricatorFailHisecUserLogType.php',
|
||||
'PhabricatorFaviconController' => 'applications/system/controller/PhabricatorFaviconController.php',
|
||||
'PhabricatorFaviconRef' => 'applications/files/favicon/PhabricatorFaviconRef.php',
|
||||
'PhabricatorFaviconRefQuery' => 'applications/files/favicon/PhabricatorFaviconRefQuery.php',
|
||||
'PhabricatorFavoritesApplication' => 'applications/favorites/application/PhabricatorFavoritesApplication.php',
|
||||
@@ -3523,7 +3561,6 @@ phutil_register_library_map(array(
|
||||
'PhabricatorHelpApplication' => 'applications/help/application/PhabricatorHelpApplication.php',
|
||||
'PhabricatorHelpController' => 'applications/help/controller/PhabricatorHelpController.php',
|
||||
'PhabricatorHelpDocumentationController' => 'applications/help/controller/PhabricatorHelpDocumentationController.php',
|
||||
'PhabricatorHelpEditorProtocolController' => 'applications/help/controller/PhabricatorHelpEditorProtocolController.php',
|
||||
'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php',
|
||||
'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php',
|
||||
'PhabricatorHeraldContentSource' => 'applications/herald/contentsource/PhabricatorHeraldContentSource.php',
|
||||
@@ -3558,9 +3595,12 @@ phutil_register_library_map(array(
|
||||
'PhabricatorIndexEngineExtensionModule' => 'applications/search/index/PhabricatorIndexEngineExtensionModule.php',
|
||||
'PhabricatorIndexableInterface' => 'applications/search/interface/PhabricatorIndexableInterface.php',
|
||||
'PhabricatorInfrastructureTestCase' => '__tests__/PhabricatorInfrastructureTestCase.php',
|
||||
'PhabricatorInlineComment' => 'infrastructure/diff/interface/PhabricatorInlineComment.php',
|
||||
'PhabricatorInlineCommentAdjustmentEngine' => 'infrastructure/diff/engine/PhabricatorInlineCommentAdjustmentEngine.php',
|
||||
'PhabricatorInlineCommentContentState' => 'infrastructure/diff/inline/PhabricatorInlineCommentContentState.php',
|
||||
'PhabricatorInlineCommentContext' => 'infrastructure/diff/inline/PhabricatorInlineCommentContext.php',
|
||||
'PhabricatorInlineCommentController' => 'infrastructure/diff/PhabricatorInlineCommentController.php',
|
||||
'PhabricatorInlineCommentInterface' => 'infrastructure/diff/interface/PhabricatorInlineCommentInterface.php',
|
||||
'PhabricatorInlineCommentPreviewController' => 'infrastructure/diff/PhabricatorInlineCommentPreviewController.php',
|
||||
'PhabricatorInlineCommentInterface' => 'applications/transactions/interface/PhabricatorInlineCommentInterface.php',
|
||||
'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php',
|
||||
'PhabricatorInstructionsEditField' => 'applications/transactions/editfield/PhabricatorInstructionsEditField.php',
|
||||
'PhabricatorIntConfigType' => 'applications/config/type/PhabricatorIntConfigType.php',
|
||||
@@ -4056,7 +4096,9 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
|
||||
'PhabricatorPasteEditEngine' => 'applications/paste/editor/PhabricatorPasteEditEngine.php',
|
||||
'PhabricatorPasteEditor' => 'applications/paste/editor/PhabricatorPasteEditor.php',
|
||||
'PhabricatorPasteFerretEngine' => 'applications/paste/engine/PhabricatorPasteFerretEngine.php',
|
||||
'PhabricatorPasteFilenameContextFreeGrammar' => 'applications/paste/lipsum/PhabricatorPasteFilenameContextFreeGrammar.php',
|
||||
'PhabricatorPasteFulltextEngine' => 'applications/paste/engine/PhabricatorPasteFulltextEngine.php',
|
||||
'PhabricatorPasteLanguageTransaction' => 'applications/paste/xaction/PhabricatorPasteLanguageTransaction.php',
|
||||
'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
|
||||
'PhabricatorPastePastePHIDType' => 'applications/paste/phid/PhabricatorPastePastePHIDType.php',
|
||||
@@ -4091,6 +4133,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleDisableController' => 'applications/people/controller/PhabricatorPeopleDisableController.php',
|
||||
'PhabricatorPeopleEmailLoginMailEngine' => 'applications/people/mail/PhabricatorPeopleEmailLoginMailEngine.php',
|
||||
'PhabricatorPeopleEmpowerController' => 'applications/people/controller/PhabricatorPeopleEmpowerController.php',
|
||||
'PhabricatorPeopleExternalIdentifierPHIDType' => 'applications/people/phid/PhabricatorPeopleExternalIdentifierPHIDType.php',
|
||||
'PhabricatorPeopleExternalPHIDType' => 'applications/people/phid/PhabricatorPeopleExternalPHIDType.php',
|
||||
'PhabricatorPeopleIconSet' => 'applications/people/icon/PhabricatorPeopleIconSet.php',
|
||||
'PhabricatorPeopleInviteController' => 'applications/people/controller/PhabricatorPeopleInviteController.php',
|
||||
@@ -4125,6 +4168,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleRenameController' => 'applications/people/controller/PhabricatorPeopleRenameController.php',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleRevisionsProfileMenuItem.php',
|
||||
'PhabricatorPeopleSearchEngine' => 'applications/people/query/PhabricatorPeopleSearchEngine.php',
|
||||
'PhabricatorPeopleSpamController' => 'applications/people/controller/PhabricatorPeopleSpamController.php',
|
||||
'PhabricatorPeopleTasksProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleTasksProfileMenuItem.php',
|
||||
'PhabricatorPeopleTestDataGenerator' => 'applications/people/lipsum/PhabricatorPeopleTestDataGenerator.php',
|
||||
'PhabricatorPeopleTransactionQuery' => 'applications/people/query/PhabricatorPeopleTransactionQuery.php',
|
||||
@@ -4679,6 +4723,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSearchManagementNgramsWorkflow' => 'applications/search/management/PhabricatorSearchManagementNgramsWorkflow.php',
|
||||
'PhabricatorSearchManagementQueryWorkflow' => 'applications/search/management/PhabricatorSearchManagementQueryWorkflow.php',
|
||||
'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
|
||||
'PhabricatorSearchNgramEngine' => 'applications/search/engine/PhabricatorSearchNgramEngine.php',
|
||||
'PhabricatorSearchNgrams' => 'applications/search/ngrams/PhabricatorSearchNgrams.php',
|
||||
'PhabricatorSearchNgramsDestructionEngineExtension' => 'applications/search/engineextension/PhabricatorSearchNgramsDestructionEngineExtension.php',
|
||||
'PhabricatorSearchOrderController' => 'applications/search/controller/PhabricatorSearchOrderController.php',
|
||||
@@ -4722,6 +4767,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
|
||||
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
|
||||
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
|
||||
'PhabricatorSettingsPanelChangeUsername' => 'applications/settings/panel/PhabricatorSettingsPanelChangeUsername.php',
|
||||
'PhabricatorSettingsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsPanelGroup.php',
|
||||
'PhabricatorSettingsTimezoneController' => 'applications/settings/controller/PhabricatorSettingsTimezoneController.php',
|
||||
'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
|
||||
@@ -4732,7 +4778,6 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php',
|
||||
'PhabricatorShiftChartFunction' => 'applications/fact/chart/PhabricatorShiftChartFunction.php',
|
||||
'PhabricatorShortSite' => 'aphront/site/PhabricatorShortSite.php',
|
||||
'PhabricatorShowFiletreeSetting' => 'applications/settings/setting/PhabricatorShowFiletreeSetting.php',
|
||||
'PhabricatorSignDocumentsUserLogType' => 'applications/people/userlog/PhabricatorSignDocumentsUserLogType.php',
|
||||
'PhabricatorSimpleEditType' => 'applications/transactions/edittype/PhabricatorSimpleEditType.php',
|
||||
'PhabricatorSinChartFunction' => 'applications/fact/chart/PhabricatorSinChartFunction.php',
|
||||
@@ -4957,6 +5002,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorTransactionChange' => 'applications/transactions/data/PhabricatorTransactionChange.php',
|
||||
'PhabricatorTransactionFactEngine' => 'applications/fact/engine/PhabricatorTransactionFactEngine.php',
|
||||
'PhabricatorTransactionRemarkupChange' => 'applications/transactions/data/PhabricatorTransactionRemarkupChange.php',
|
||||
'PhabricatorTransactionWarning' => 'applications/transactions/data/PhabricatorTransactionWarning.php',
|
||||
'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
|
||||
'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php',
|
||||
'PhabricatorTransactionsDestructionEngineExtension' => 'applications/transactions/engineextension/PhabricatorTransactionsDestructionEngineExtension.php',
|
||||
@@ -5015,6 +5061,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorUserCustomFieldNumericIndex' => 'applications/people/storage/PhabricatorUserCustomFieldNumericIndex.php',
|
||||
'PhabricatorUserCustomFieldStringIndex' => 'applications/people/storage/PhabricatorUserCustomFieldStringIndex.php',
|
||||
'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
|
||||
'PhabricatorUserDisableSpamTransaction' => 'applications/people/xaction/PhabricatorUserDisableSpamTransaction.php',
|
||||
'PhabricatorUserDisableTransaction' => 'applications/people/xaction/PhabricatorUserDisableTransaction.php',
|
||||
'PhabricatorUserEditEngine' => 'applications/people/editor/PhabricatorUserEditEngine.php',
|
||||
'PhabricatorUserEditor' => 'applications/people/editor/PhabricatorUserEditor.php',
|
||||
@@ -5580,6 +5627,7 @@ phutil_register_library_map(array(
|
||||
'PhrictionTransactionComment' => 'applications/phriction/storage/PhrictionTransactionComment.php',
|
||||
'PhrictionTransactionEditor' => 'applications/phriction/editor/PhrictionTransactionEditor.php',
|
||||
'PhrictionTransactionQuery' => 'applications/phriction/query/PhrictionTransactionQuery.php',
|
||||
'PhutilAPCKeyValueCache' => 'infrastructure/cache/PhutilAPCKeyValueCache.php',
|
||||
'PhutilAmazonAuthAdapter' => 'applications/auth/adapter/PhutilAmazonAuthAdapter.php',
|
||||
'PhutilAsanaAuthAdapter' => 'applications/auth/adapter/PhutilAsanaAuthAdapter.php',
|
||||
'PhutilAuthAdapter' => 'applications/auth/adapter/PhutilAuthAdapter.php',
|
||||
@@ -5609,7 +5657,20 @@ phutil_register_library_map(array(
|
||||
'PhutilCalendarRootNode' => 'applications/calendar/parser/data/PhutilCalendarRootNode.php',
|
||||
'PhutilCalendarUserNode' => 'applications/calendar/parser/data/PhutilCalendarUserNode.php',
|
||||
'PhutilCodeSnippetContextFreeGrammar' => 'infrastructure/lipsum/code/PhutilCodeSnippetContextFreeGrammar.php',
|
||||
'PhutilConsoleSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilConsoleSyntaxHighlighter.php',
|
||||
'PhutilContextFreeGrammar' => 'infrastructure/lipsum/PhutilContextFreeGrammar.php',
|
||||
'PhutilDaemon' => 'infrastructure/daemon/PhutilDaemon.php',
|
||||
'PhutilDaemonHandle' => 'infrastructure/daemon/PhutilDaemonHandle.php',
|
||||
'PhutilDaemonOverseer' => 'infrastructure/daemon/PhutilDaemonOverseer.php',
|
||||
'PhutilDaemonOverseerModule' => 'infrastructure/daemon/PhutilDaemonOverseerModule.php',
|
||||
'PhutilDaemonPool' => 'infrastructure/daemon/PhutilDaemonPool.php',
|
||||
'PhutilDefaultSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilDefaultSyntaxHighlighter.php',
|
||||
'PhutilDefaultSyntaxHighlighterEngine' => 'infrastructure/markup/syntax/engine/PhutilDefaultSyntaxHighlighterEngine.php',
|
||||
'PhutilDefaultSyntaxHighlighterEnginePygmentsFuture' => 'infrastructure/markup/syntax/highlighter/pygments/PhutilDefaultSyntaxHighlighterEnginePygmentsFuture.php',
|
||||
'PhutilDefaultSyntaxHighlighterEngineTestCase' => 'infrastructure/markup/syntax/engine/__tests__/PhutilDefaultSyntaxHighlighterEngineTestCase.php',
|
||||
'PhutilDirectoryKeyValueCache' => 'infrastructure/cache/PhutilDirectoryKeyValueCache.php',
|
||||
'PhutilDisqusAuthAdapter' => 'applications/auth/adapter/PhutilDisqusAuthAdapter.php',
|
||||
'PhutilDivinerSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilDivinerSyntaxHighlighter.php',
|
||||
'PhutilEmptyAuthAdapter' => 'applications/auth/adapter/PhutilEmptyAuthAdapter.php',
|
||||
'PhutilFacebookAuthAdapter' => 'applications/auth/adapter/PhutilFacebookAuthAdapter.php',
|
||||
'PhutilGitHubAuthAdapter' => 'applications/auth/adapter/PhutilGitHubAuthAdapter.php',
|
||||
@@ -5619,19 +5680,38 @@ phutil_register_library_map(array(
|
||||
'PhutilICSParserTestCase' => 'applications/calendar/parser/ics/__tests__/PhutilICSParserTestCase.php',
|
||||
'PhutilICSWriter' => 'applications/calendar/parser/ics/PhutilICSWriter.php',
|
||||
'PhutilICSWriterTestCase' => 'applications/calendar/parser/ics/__tests__/PhutilICSWriterTestCase.php',
|
||||
'PhutilInRequestKeyValueCache' => 'infrastructure/cache/PhutilInRequestKeyValueCache.php',
|
||||
'PhutilInvisibleSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilInvisibleSyntaxHighlighter.php',
|
||||
'PhutilJIRAAuthAdapter' => 'applications/auth/adapter/PhutilJIRAAuthAdapter.php',
|
||||
'PhutilJSONFragmentLexerHighlighterTestCase' => 'infrastructure/markup/syntax/highlighter/__tests__/PhutilJSONFragmentLexerHighlighterTestCase.php',
|
||||
'PhutilJavaCodeSnippetContextFreeGrammar' => 'infrastructure/lipsum/code/PhutilJavaCodeSnippetContextFreeGrammar.php',
|
||||
'PhutilKeyValueCache' => 'infrastructure/cache/PhutilKeyValueCache.php',
|
||||
'PhutilKeyValueCacheNamespace' => 'infrastructure/cache/PhutilKeyValueCacheNamespace.php',
|
||||
'PhutilKeyValueCacheProfiler' => 'infrastructure/cache/PhutilKeyValueCacheProfiler.php',
|
||||
'PhutilKeyValueCacheProxy' => 'infrastructure/cache/PhutilKeyValueCacheProxy.php',
|
||||
'PhutilKeyValueCacheStack' => 'infrastructure/cache/PhutilKeyValueCacheStack.php',
|
||||
'PhutilKeyValueCacheTestCase' => 'infrastructure/cache/__tests__/PhutilKeyValueCacheTestCase.php',
|
||||
'PhutilLDAPAuthAdapter' => 'applications/auth/adapter/PhutilLDAPAuthAdapter.php',
|
||||
'PhutilLexerSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilLexerSyntaxHighlighter.php',
|
||||
'PhutilLipsumContextFreeGrammar' => 'infrastructure/lipsum/PhutilLipsumContextFreeGrammar.php',
|
||||
'PhutilMarkupEngine' => 'infrastructure/markup/PhutilMarkupEngine.php',
|
||||
'PhutilMarkupTestCase' => 'infrastructure/markup/__tests__/PhutilMarkupTestCase.php',
|
||||
'PhutilMemcacheKeyValueCache' => 'infrastructure/cache/PhutilMemcacheKeyValueCache.php',
|
||||
'PhutilOAuth1AuthAdapter' => 'applications/auth/adapter/PhutilOAuth1AuthAdapter.php',
|
||||
'PhutilOAuthAuthAdapter' => 'applications/auth/adapter/PhutilOAuthAuthAdapter.php',
|
||||
'PhutilOnDiskKeyValueCache' => 'infrastructure/cache/PhutilOnDiskKeyValueCache.php',
|
||||
'PhutilPHPCodeSnippetContextFreeGrammar' => 'infrastructure/lipsum/code/PhutilPHPCodeSnippetContextFreeGrammar.php',
|
||||
'PhutilPHPFragmentLexerHighlighterTestCase' => 'infrastructure/markup/syntax/highlighter/__tests__/PhutilPHPFragmentLexerHighlighterTestCase.php',
|
||||
'PhutilPhabricatorAuthAdapter' => 'applications/auth/adapter/PhutilPhabricatorAuthAdapter.php',
|
||||
'PhutilProseDiff' => 'infrastructure/diff/prose/PhutilProseDiff.php',
|
||||
'PhutilProseDiffTestCase' => 'infrastructure/diff/prose/__tests__/PhutilProseDiffTestCase.php',
|
||||
'PhutilProseDifferenceEngine' => 'infrastructure/diff/prose/PhutilProseDifferenceEngine.php',
|
||||
'PhutilPygmentizeParser' => 'infrastructure/parser/PhutilPygmentizeParser.php',
|
||||
'PhutilPygmentizeParserTestCase' => 'infrastructure/parser/__tests__/PhutilPygmentizeParserTestCase.php',
|
||||
'PhutilPygmentsSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilPygmentsSyntaxHighlighter.php',
|
||||
'PhutilQsprintfInterface' => 'infrastructure/storage/xsprintf/PhutilQsprintfInterface.php',
|
||||
'PhutilQueryString' => 'infrastructure/storage/xsprintf/PhutilQueryString.php',
|
||||
'PhutilRainbowSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilRainbowSyntaxHighlighter.php',
|
||||
'PhutilRealNameContextFreeGrammar' => 'infrastructure/lipsum/PhutilRealNameContextFreeGrammar.php',
|
||||
'PhutilRemarkupAnchorRule' => 'infrastructure/markup/markuprule/PhutilRemarkupAnchorRule.php',
|
||||
'PhutilRemarkupBlockInterpreter' => 'infrastructure/markup/blockrule/PhutilRemarkupBlockInterpreter.php',
|
||||
@@ -5667,6 +5747,9 @@ phutil_register_library_map(array(
|
||||
'PhutilRemarkupTableBlockRule' => 'infrastructure/markup/blockrule/PhutilRemarkupTableBlockRule.php',
|
||||
'PhutilRemarkupTestInterpreterRule' => 'infrastructure/markup/blockrule/PhutilRemarkupTestInterpreterRule.php',
|
||||
'PhutilRemarkupUnderlineRule' => 'infrastructure/markup/markuprule/PhutilRemarkupUnderlineRule.php',
|
||||
'PhutilSafeHTML' => 'infrastructure/markup/PhutilSafeHTML.php',
|
||||
'PhutilSafeHTMLProducerInterface' => 'infrastructure/markup/PhutilSafeHTMLProducerInterface.php',
|
||||
'PhutilSafeHTMLTestCase' => 'infrastructure/markup/__tests__/PhutilSafeHTMLTestCase.php',
|
||||
'PhutilSearchQueryCompiler' => 'applications/search/compiler/PhutilSearchQueryCompiler.php',
|
||||
'PhutilSearchQueryCompilerSyntaxException' => 'applications/search/compiler/PhutilSearchQueryCompilerSyntaxException.php',
|
||||
'PhutilSearchQueryCompilerTestCase' => 'applications/search/compiler/__tests__/PhutilSearchQueryCompilerTestCase.php',
|
||||
@@ -5674,9 +5757,18 @@ phutil_register_library_map(array(
|
||||
'PhutilSearchStemmer' => 'applications/search/compiler/PhutilSearchStemmer.php',
|
||||
'PhutilSearchStemmerTestCase' => 'applications/search/compiler/__tests__/PhutilSearchStemmerTestCase.php',
|
||||
'PhutilSlackAuthAdapter' => 'applications/auth/adapter/PhutilSlackAuthAdapter.php',
|
||||
'PhutilSprite' => 'aphront/sprite/PhutilSprite.php',
|
||||
'PhutilSpriteSheet' => 'aphront/sprite/PhutilSpriteSheet.php',
|
||||
'PhutilSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilSyntaxHighlighter.php',
|
||||
'PhutilSyntaxHighlighterEngine' => 'infrastructure/markup/syntax/engine/PhutilSyntaxHighlighterEngine.php',
|
||||
'PhutilSyntaxHighlighterException' => 'infrastructure/markup/syntax/highlighter/PhutilSyntaxHighlighterException.php',
|
||||
'PhutilTranslatedHTMLTestCase' => 'infrastructure/markup/__tests__/PhutilTranslatedHTMLTestCase.php',
|
||||
'PhutilTwitchAuthAdapter' => 'applications/auth/adapter/PhutilTwitchAuthAdapter.php',
|
||||
'PhutilTwitterAuthAdapter' => 'applications/auth/adapter/PhutilTwitterAuthAdapter.php',
|
||||
'PhutilWordPressAuthAdapter' => 'applications/auth/adapter/PhutilWordPressAuthAdapter.php',
|
||||
'PhutilXHPASTSyntaxHighlighter' => 'infrastructure/markup/syntax/highlighter/PhutilXHPASTSyntaxHighlighter.php',
|
||||
'PhutilXHPASTSyntaxHighlighterFuture' => 'infrastructure/markup/syntax/highlighter/xhpast/PhutilXHPASTSyntaxHighlighterFuture.php',
|
||||
'PhutilXHPASTSyntaxHighlighterTestCase' => 'infrastructure/markup/syntax/highlighter/__tests__/PhutilXHPASTSyntaxHighlighterTestCase.php',
|
||||
'PolicyLockOptionType' => 'applications/policy/config/PolicyLockOptionType.php',
|
||||
'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php',
|
||||
'PonderAnswer' => 'applications/ponder/storage/PonderAnswer.php',
|
||||
@@ -5868,6 +5960,7 @@ phutil_register_library_map(array(
|
||||
'function' => array(
|
||||
'celerity_generate_unique_node_id' => 'applications/celerity/api.php',
|
||||
'celerity_get_resource_uri' => 'applications/celerity/api.php',
|
||||
'hsprintf' => 'infrastructure/markup/render.php',
|
||||
'javelin_tag' => 'infrastructure/javelin/markup.php',
|
||||
'phabricator_date' => 'view/viewutils.php',
|
||||
'phabricator_datetime' => 'view/viewutils.php',
|
||||
@@ -5879,6 +5972,12 @@ phutil_register_library_map(array(
|
||||
'phid_get_subtype' => 'applications/phid/utils.php',
|
||||
'phid_get_type' => 'applications/phid/utils.php',
|
||||
'phid_group_by_type' => 'applications/phid/utils.php',
|
||||
'phutil_escape_html' => 'infrastructure/markup/render.php',
|
||||
'phutil_escape_html_newlines' => 'infrastructure/markup/render.php',
|
||||
'phutil_implode_html' => 'infrastructure/markup/render.php',
|
||||
'phutil_safe_html' => 'infrastructure/markup/render.php',
|
||||
'phutil_tag' => 'infrastructure/markup/render.php',
|
||||
'phutil_tag_div' => 'infrastructure/markup/render.php',
|
||||
'qsprintf' => 'infrastructure/storage/xsprintf/qsprintf.php',
|
||||
'qsprintf_check_scalar_type' => 'infrastructure/storage/xsprintf/qsprintf.php',
|
||||
'qsprintf_check_type' => 'infrastructure/storage/xsprintf/qsprintf.php',
|
||||
@@ -6114,6 +6213,7 @@ phutil_register_library_map(array(
|
||||
'AphrontAccessDeniedQueryException' => 'AphrontQueryException',
|
||||
'AphrontAjaxResponse' => 'AphrontResponse',
|
||||
'AphrontApplicationConfiguration' => 'Phobject',
|
||||
'AphrontAutoIDView' => 'AphrontView',
|
||||
'AphrontBarView' => 'AphrontView',
|
||||
'AphrontBaseMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
|
||||
'AphrontBoolHTTPParameterType' => 'AphrontHTTPParameterType',
|
||||
@@ -6167,6 +6267,8 @@ phutil_register_library_map(array(
|
||||
'AphrontFormView' => 'AphrontView',
|
||||
'AphrontGlyphBarView' => 'AphrontBarView',
|
||||
'AphrontHTMLResponse' => 'AphrontResponse',
|
||||
'AphrontHTTPHeaderParser' => 'Phobject',
|
||||
'AphrontHTTPHeaderParserTestCase' => 'PhutilTestCase',
|
||||
'AphrontHTTPParameterType' => 'Phobject',
|
||||
'AphrontHTTPProxyResponse' => 'AphrontResponse',
|
||||
'AphrontHTTPSink' => 'Phobject',
|
||||
@@ -6185,6 +6287,9 @@ phutil_register_library_map(array(
|
||||
'AphrontMalformedRequestException' => 'AphrontException',
|
||||
'AphrontMoreView' => 'AphrontView',
|
||||
'AphrontMultiColumnView' => 'AphrontView',
|
||||
'AphrontMultipartParser' => 'Phobject',
|
||||
'AphrontMultipartParserTestCase' => 'PhutilTestCase',
|
||||
'AphrontMultipartPart' => 'Phobject',
|
||||
'AphrontMySQLDatabaseConnection' => 'AphrontBaseMySQLDatabaseConnection',
|
||||
'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase',
|
||||
'AphrontMySQLiDatabaseConnection' => 'AphrontBaseMySQLDatabaseConnection',
|
||||
@@ -6211,11 +6316,14 @@ phutil_register_library_map(array(
|
||||
'AphrontReloadResponse' => 'AphrontRedirectResponse',
|
||||
'AphrontRequest' => 'Phobject',
|
||||
'AphrontRequestExceptionHandler' => 'Phobject',
|
||||
'AphrontRequestStream' => 'Phobject',
|
||||
'AphrontRequestTestCase' => 'PhabricatorTestCase',
|
||||
'AphrontResponse' => 'Phobject',
|
||||
'AphrontRoutingMap' => 'Phobject',
|
||||
'AphrontRoutingMapTestCase' => 'PhabricatorTestCase',
|
||||
'AphrontRoutingResult' => 'Phobject',
|
||||
'AphrontSchemaQueryException' => 'AphrontQueryException',
|
||||
'AphrontScopedUnguardedWriteCapability' => 'Phobject',
|
||||
'AphrontSelectHTTPParameterType' => 'AphrontHTTPParameterType',
|
||||
'AphrontSideNavFilterView' => 'AphrontView',
|
||||
'AphrontSite' => 'Phobject',
|
||||
@@ -6234,6 +6342,7 @@ phutil_register_library_map(array(
|
||||
'PhutilSafeHTMLProducerInterface',
|
||||
),
|
||||
'AphrontWebpageResponse' => 'AphrontHTMLResponse',
|
||||
'AphrontWriteGuard' => 'Phobject',
|
||||
'ArcanistConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'AuditConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod',
|
||||
@@ -6418,7 +6527,6 @@ phutil_register_library_map(array(
|
||||
),
|
||||
'DifferentialChangesetDetailView' => 'AphrontView',
|
||||
'DifferentialChangesetEngine' => 'Phobject',
|
||||
'DifferentialChangesetFileTreeSideNavBuilder' => 'Phobject',
|
||||
'DifferentialChangesetHTMLRenderer' => 'DifferentialChangesetRenderer',
|
||||
'DifferentialChangesetListController' => 'DifferentialController',
|
||||
'DifferentialChangesetListView' => 'AphrontView',
|
||||
@@ -6501,6 +6609,7 @@ phutil_register_library_map(array(
|
||||
'DifferentialExactUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'DifferentialFieldParseException' => 'Exception',
|
||||
'DifferentialFieldValidationException' => 'Exception',
|
||||
'DifferentialFileTreeEngine' => 'Phobject',
|
||||
'DifferentialGetAllDiffsConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||
'DifferentialGetCommitMessageConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||
'DifferentialGetCommitPathsConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||
@@ -6524,13 +6633,9 @@ phutil_register_library_map(array(
|
||||
'DifferentialHunkParserTestCase' => 'PhabricatorTestCase',
|
||||
'DifferentialHunkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'DifferentialHunkTestCase' => 'PhutilTestCase',
|
||||
'DifferentialInlineComment' => array(
|
||||
'Phobject',
|
||||
'PhabricatorInlineCommentInterface',
|
||||
),
|
||||
'DifferentialInlineComment' => 'PhabricatorInlineComment',
|
||||
'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController',
|
||||
'DifferentialInlineCommentMailView' => 'DifferentialMailView',
|
||||
'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery',
|
||||
'DifferentialJIRAIssuesCommitMessageField' => 'DifferentialCommitMessageCustomField',
|
||||
'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField',
|
||||
'DifferentialLegacyQuery' => 'Phobject',
|
||||
@@ -6694,7 +6799,10 @@ phutil_register_library_map(array(
|
||||
'DifferentialTestPlanField' => 'DifferentialCoreCustomField',
|
||||
'DifferentialTitleCommitMessageField' => 'DifferentialCommitMessageField',
|
||||
'DifferentialTransaction' => 'PhabricatorModularTransaction',
|
||||
'DifferentialTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'DifferentialTransactionComment' => array(
|
||||
'PhabricatorApplicationTransactionComment',
|
||||
'PhabricatorInlineCommentInterface',
|
||||
),
|
||||
'DifferentialTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'DifferentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'DifferentialTransactionView' => 'PhabricatorApplicationTransactionView',
|
||||
@@ -6702,6 +6810,12 @@ phutil_register_library_map(array(
|
||||
'DifferentialUnitStatus' => 'Phobject',
|
||||
'DifferentialUnitTestResult' => 'Phobject',
|
||||
'DifferentialUpdateRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod',
|
||||
'DifferentialViewState' => array(
|
||||
'DifferentialDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
),
|
||||
'DifferentialViewStateGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||
'DifferentialViewStateQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'DiffusionAuditorDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'DiffusionAuditorFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
|
||||
'DiffusionAuditorsAddAuditorsHeraldAction' => 'DiffusionAuditorsHeraldAction',
|
||||
@@ -6865,7 +6979,6 @@ phutil_register_library_map(array(
|
||||
'DiffusionIdentityUnassignedDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'DiffusionIdentityViewController' => 'DiffusionController',
|
||||
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
|
||||
'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
|
||||
'DiffusionInternalAncestorsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||
'DiffusionInternalGitRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||
'DiffusionLastModifiedController' => 'DiffusionController',
|
||||
@@ -7325,6 +7438,8 @@ phutil_register_library_map(array(
|
||||
'FeedPushWorker' => 'PhabricatorWorker',
|
||||
'FeedQueryConduitAPIMethod' => 'FeedConduitAPIMethod',
|
||||
'FeedStoryNotificationGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||
'FerretConfigurableSearchFunction' => 'FerretSearchFunction',
|
||||
'FerretSearchFunction' => 'Phobject',
|
||||
'FileAllocateConduitAPIMethod' => 'FileConduitAPIMethod',
|
||||
'FileConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'FileCreateMailReceiver' => 'PhabricatorApplicationMailReceiver',
|
||||
@@ -7916,6 +8031,7 @@ phutil_register_library_map(array(
|
||||
'ManiphestReportController' => 'ManiphestController',
|
||||
'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'ManiphestSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'ManiphestSearchController' => 'PhabricatorApplicationSearchController',
|
||||
'ManiphestStatusEmailCommand' => 'ManiphestEmailCommand',
|
||||
'ManiphestStatusSearchConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
||||
'ManiphestStatusesConfigType' => 'PhabricatorJSONConfigType',
|
||||
@@ -8189,6 +8305,8 @@ phutil_register_library_map(array(
|
||||
'PHUICrumbView' => 'AphrontView',
|
||||
'PHUICrumbsView' => 'AphrontView',
|
||||
'PHUICurtainExtension' => 'Phobject',
|
||||
'PHUICurtainObjectRefListView' => 'AphrontTagView',
|
||||
'PHUICurtainObjectRefView' => 'AphrontTagView',
|
||||
'PHUICurtainPanelView' => 'AphrontTagView',
|
||||
'PHUICurtainView' => 'AphrontTagView',
|
||||
'PHUIDiffGraphView' => 'Phobject',
|
||||
@@ -8218,6 +8336,14 @@ phutil_register_library_map(array(
|
||||
'PHUIFormLayoutView' => 'AphrontView',
|
||||
'PHUIFormNumberControl' => 'AphrontFormControl',
|
||||
'PHUIFormTimerControl' => 'AphrontFormControl',
|
||||
'PHUIFormationColumnDynamicView' => 'PHUIFormationColumnView',
|
||||
'PHUIFormationColumnItem' => 'Phobject',
|
||||
'PHUIFormationColumnView' => 'AphrontAutoIDView',
|
||||
'PHUIFormationContentView' => 'PHUIFormationColumnView',
|
||||
'PHUIFormationExpanderView' => 'AphrontAutoIDView',
|
||||
'PHUIFormationFlankView' => 'PHUIFormationColumnDynamicView',
|
||||
'PHUIFormationResizerView' => 'PHUIFormationColumnView',
|
||||
'PHUIFormationView' => 'AphrontAutoIDView',
|
||||
'PHUIHandleListView' => 'AphrontTagView',
|
||||
'PHUIHandleTagListView' => 'AphrontTagView',
|
||||
'PHUIHandleView' => 'AphrontView',
|
||||
@@ -8235,8 +8361,10 @@ phutil_register_library_map(array(
|
||||
'PHUIInfoView' => 'AphrontTagView',
|
||||
'PHUIInvisibleCharacterTestCase' => 'PhabricatorTestCase',
|
||||
'PHUIInvisibleCharacterView' => 'AphrontView',
|
||||
'PHUILauncherView' => 'AphrontTagView',
|
||||
'PHUILeftRightExample' => 'PhabricatorUIExample',
|
||||
'PHUILeftRightView' => 'AphrontTagView',
|
||||
'PHUILinkView' => 'AphrontTagView',
|
||||
'PHUIListExample' => 'PhabricatorUIExample',
|
||||
'PHUIListItemView' => 'AphrontTagView',
|
||||
'PHUIListView' => 'AphrontTagView',
|
||||
@@ -8348,6 +8476,7 @@ phutil_register_library_map(array(
|
||||
'PasteSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleDisableSpamUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleDisableUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||
'PeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
@@ -8417,6 +8546,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorApplicationTransactionCannedResponsesController' => 'PhabricatorApplicationTransactionController',
|
||||
'PhabricatorApplicationTransactionComment' => array(
|
||||
'PhabricatorLiskDAO',
|
||||
'PhabricatorMarkupInterface',
|
||||
@@ -8476,10 +8606,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
|
||||
'PhabricatorAuditController' => 'PhabricatorController',
|
||||
'PhabricatorAuditEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorAuditInlineComment' => array(
|
||||
'Phobject',
|
||||
'PhabricatorInlineCommentInterface',
|
||||
),
|
||||
'PhabricatorAuditInlineComment' => 'PhabricatorInlineComment',
|
||||
'PhabricatorAuditListView' => 'AphrontView',
|
||||
'PhabricatorAuditMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'PhabricatorAuditManagementDeleteWorkflow' => 'PhabricatorAuditManagementWorkflow',
|
||||
@@ -8488,7 +8615,10 @@ phutil_register_library_map(array(
|
||||
'PhabricatorAuditStatusConstants' => 'Phobject',
|
||||
'PhabricatorAuditSynchronizeManagementWorkflow' => 'PhabricatorAuditManagementWorkflow',
|
||||
'PhabricatorAuditTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhabricatorAuditTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PhabricatorAuditTransactionComment' => array(
|
||||
'PhabricatorApplicationTransactionComment',
|
||||
'PhabricatorInlineCommentInterface',
|
||||
),
|
||||
'PhabricatorAuditTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorAuditTransactionView' => 'PhabricatorApplicationTransactionView',
|
||||
'PhabricatorAuditUpdateOwnersManagementWorkflow' => 'PhabricatorAuditManagementWorkflow',
|
||||
@@ -8678,6 +8808,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorAuthDAO',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorAuthProviderConfigController' => 'PhabricatorAuthProviderController',
|
||||
'PhabricatorAuthProviderConfigEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
@@ -9042,6 +9173,8 @@ phutil_register_library_map(array(
|
||||
'PhabricatorChangePasswordUserLogType' => 'PhabricatorUserLogType',
|
||||
'PhabricatorChangesetCachePurger' => 'PhabricatorCachePurger',
|
||||
'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
|
||||
'PhabricatorChangesetViewState' => 'Phobject',
|
||||
'PhabricatorChangesetViewStateEngine' => 'Phobject',
|
||||
'PhabricatorChartAxis' => 'Phobject',
|
||||
'PhabricatorChartDataQuery' => 'Phobject',
|
||||
'PhabricatorChartDataset' => 'Phobject',
|
||||
@@ -9131,21 +9264,20 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConduitTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorConduitTokenTerminateController' => 'PhabricatorConduitController',
|
||||
'PhabricatorConduitTokensSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorConfigAllController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorConfigApplicationController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigCacheController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigClusterDatabasesController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigClusterNotificationsController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigClusterRepositoriesController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigClusterSearchController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigCacheController' => 'PhabricatorConfigServicesController',
|
||||
'PhabricatorConfigClusterDatabasesController' => 'PhabricatorConfigServicesController',
|
||||
'PhabricatorConfigClusterNotificationsController' => 'PhabricatorConfigServicesController',
|
||||
'PhabricatorConfigClusterRepositoriesController' => 'PhabricatorConfigServicesController',
|
||||
'PhabricatorConfigClusterSearchController' => 'PhabricatorConfigServicesController',
|
||||
'PhabricatorConfigCollectorsModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorConfigColumnSchema' => 'PhabricatorConfigStorageSchema',
|
||||
'PhabricatorConfigConfigPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorConfigConsoleController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigConstants' => 'Phobject',
|
||||
'PhabricatorConfigController' => 'PhabricatorController',
|
||||
'PhabricatorConfigCoreSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'PhabricatorConfigDatabaseController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigDatabaseController' => 'PhabricatorConfigServicesController',
|
||||
'PhabricatorConfigDatabaseIssueController' => 'PhabricatorConfigDatabaseController',
|
||||
'PhabricatorConfigDatabaseSchema' => 'PhabricatorConfigStorageSchema',
|
||||
'PhabricatorConfigDatabaseSource' => 'PhabricatorConfigProxySource',
|
||||
@@ -9153,7 +9285,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigDefaultSource' => 'PhabricatorConfigProxySource',
|
||||
'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource',
|
||||
'PhabricatorConfigEdgeModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorConfigEditController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigEditController' => 'PhabricatorConfigSettingsController',
|
||||
'PhabricatorConfigEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorConfigEntry' => array(
|
||||
'PhabricatorConfigEntryDAO',
|
||||
@@ -9164,9 +9296,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigEntryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource',
|
||||
'PhabricatorConfigGroupConstants' => 'PhabricatorConfigConstants',
|
||||
'PhabricatorConfigGroupController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigHTTPParameterTypesModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorConfigHistoryController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigIgnoreController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigIssueListController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigIssuePanelController' => 'PhabricatorConfigController',
|
||||
@@ -9174,7 +9304,6 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigJSON' => 'Phobject',
|
||||
'PhabricatorConfigJSONOptionType' => 'PhabricatorConfigOptionType',
|
||||
'PhabricatorConfigKeySchema' => 'PhabricatorConfigStorageSchema',
|
||||
'PhabricatorConfigListController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigLocalSource' => 'PhabricatorConfigProxySource',
|
||||
'PhabricatorConfigManagementDeleteWorkflow' => 'PhabricatorConfigManagementWorkflow',
|
||||
'PhabricatorConfigManagementDoneWorkflow' => 'PhabricatorConfigManagementWorkflow',
|
||||
@@ -9198,6 +9327,10 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigSchemaQuery' => 'Phobject',
|
||||
'PhabricatorConfigSchemaSpec' => 'Phobject',
|
||||
'PhabricatorConfigServerSchema' => 'PhabricatorConfigStorageSchema',
|
||||
'PhabricatorConfigServicesController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigSettingsController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConfigSettingsHistoryController' => 'PhabricatorConfigSettingsController',
|
||||
'PhabricatorConfigSettingsListController' => 'PhabricatorConfigSettingsController',
|
||||
'PhabricatorConfigSetupCheckModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorConfigSiteModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorConfigSiteSource' => 'PhabricatorConfigProxySource',
|
||||
@@ -9209,7 +9342,6 @@ phutil_register_library_map(array(
|
||||
'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorConfigType' => 'Phobject',
|
||||
'PhabricatorConfigValidationException' => 'Exception',
|
||||
'PhabricatorConfigVersionController' => 'PhabricatorConfigController',
|
||||
'PhabricatorConpherenceApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorConpherenceColumnMinimizeSetting' => 'PhabricatorInternalSetting',
|
||||
'PhabricatorConpherenceColumnVisibleSetting' => 'PhabricatorInternalSetting',
|
||||
@@ -9508,6 +9640,8 @@ phutil_register_library_map(array(
|
||||
'PhabricatorDestructionEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorDeveloperConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorDeveloperPreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
|
||||
'PhabricatorDiffInlineCommentContentState' => 'PhabricatorInlineCommentContentState',
|
||||
'PhabricatorDiffInlineCommentContext' => 'PhabricatorInlineCommentContext',
|
||||
'PhabricatorDiffInlineCommentQuery' => 'PhabricatorApplicationTransactionCommentQuery',
|
||||
'PhabricatorDiffPreferencesSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
|
||||
'PhabricatorDiffScopeEngine' => 'Phobject',
|
||||
@@ -9614,6 +9748,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorEditEngineMFAEngine' => 'Phobject',
|
||||
'PhabricatorEditEngineNameTransaction' => 'PhabricatorEditEngineTransactionType',
|
||||
'PhabricatorEditEngineOrderTransaction' => 'PhabricatorEditEngineTransactionType',
|
||||
'PhabricatorEditEnginePageState' => 'Phobject',
|
||||
'PhabricatorEditEnginePointsCommentAction' => 'PhabricatorEditEngineCommentAction',
|
||||
'PhabricatorEditEnginePreambleTransaction' => 'PhabricatorEditEngineTransactionType',
|
||||
'PhabricatorEditEngineProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
@@ -9636,8 +9771,10 @@ phutil_register_library_map(array(
|
||||
'PhabricatorEditorExtension' => 'Phobject',
|
||||
'PhabricatorEditorExtensionModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorEditorMailEngineExtension' => 'PhabricatorMailEngineExtension',
|
||||
'PhabricatorEditorMultipleSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorEditorSetting' => 'PhabricatorStringSetting',
|
||||
'PhabricatorEditorURIEngine' => 'Phobject',
|
||||
'PhabricatorEditorURIEngineTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorEditorURIParserException' => 'Exception',
|
||||
'PhabricatorElasticFulltextStorageEngine' => 'PhabricatorFulltextStorageEngine',
|
||||
'PhabricatorElasticsearchHost' => 'PhabricatorSearchHost',
|
||||
'PhabricatorElasticsearchSetupCheck' => 'PhabricatorSetupCheck',
|
||||
@@ -9686,9 +9823,17 @@ phutil_register_library_map(array(
|
||||
'PhabricatorExternalAccount' => array(
|
||||
'PhabricatorUserDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorExternalAccountIdentifier' => array(
|
||||
'PhabricatorUserDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorExternalAccountIdentifierQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorExternalAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorExternalAccountsSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorExternalEditorSettingsPanel' => 'PhabricatorEditEngineSettingsPanel',
|
||||
'PhabricatorExtraConfigSetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorFacebookAuthProvider' => 'PhabricatorOAuth2AuthProvider',
|
||||
'PhabricatorFact' => 'Phobject',
|
||||
@@ -9721,6 +9866,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorFactRaw' => 'PhabricatorFactDAO',
|
||||
'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator',
|
||||
'PhabricatorFailHisecUserLogType' => 'PhabricatorUserLogType',
|
||||
'PhabricatorFaviconController' => 'PhabricatorController',
|
||||
'PhabricatorFaviconRef' => 'Phobject',
|
||||
'PhabricatorFaviconRefQuery' => 'Phobject',
|
||||
'PhabricatorFavoritesApplication' => 'PhabricatorApplication',
|
||||
@@ -9949,7 +10095,6 @@ phutil_register_library_map(array(
|
||||
'PhabricatorHelpApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorHelpController' => 'PhabricatorController',
|
||||
'PhabricatorHelpDocumentationController' => 'PhabricatorHelpController',
|
||||
'PhabricatorHelpEditorProtocolController' => 'PhabricatorHelpController',
|
||||
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
|
||||
'PhabricatorHeraldApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorHeraldContentSource' => 'PhabricatorContentSource',
|
||||
@@ -9983,9 +10128,14 @@ phutil_register_library_map(array(
|
||||
'PhabricatorIndexEngineExtension' => 'Phobject',
|
||||
'PhabricatorIndexEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorInfrastructureTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorInlineComment' => array(
|
||||
'Phobject',
|
||||
'PhabricatorMarkupInterface',
|
||||
),
|
||||
'PhabricatorInlineCommentAdjustmentEngine' => 'Phobject',
|
||||
'PhabricatorInlineCommentContentState' => 'Phobject',
|
||||
'PhabricatorInlineCommentContext' => 'Phobject',
|
||||
'PhabricatorInlineCommentController' => 'PhabricatorController',
|
||||
'PhabricatorInlineCommentInterface' => 'PhabricatorMarkupInterface',
|
||||
'PhabricatorInlineCommentPreviewController' => 'PhabricatorController',
|
||||
'PhabricatorInlineSummaryView' => 'AphrontView',
|
||||
'PhabricatorInstructionsEditField' => 'PhabricatorEditField',
|
||||
'PhabricatorIntConfigType' => 'PhabricatorTextConfigType',
|
||||
@@ -10560,6 +10710,8 @@ phutil_register_library_map(array(
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorSpacesInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
'PhabricatorFerretInterface',
|
||||
'PhabricatorFulltextInterface',
|
||||
),
|
||||
'PhabricatorPasteApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorPasteArchiveController' => 'PhabricatorPasteController',
|
||||
@@ -10570,7 +10722,9 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPasteEditController' => 'PhabricatorPasteController',
|
||||
'PhabricatorPasteEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorPasteEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorPasteFerretEngine' => 'PhabricatorFerretEngine',
|
||||
'PhabricatorPasteFilenameContextFreeGrammar' => 'PhutilContextFreeGrammar',
|
||||
'PhabricatorPasteFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'PhabricatorPasteLanguageTransaction' => 'PhabricatorPasteTransactionType',
|
||||
'PhabricatorPasteListController' => 'PhabricatorPasteController',
|
||||
'PhabricatorPastePastePHIDType' => 'PhabricatorPHIDType',
|
||||
@@ -10605,6 +10759,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleEmailLoginMailEngine' => 'PhabricatorPeopleMailEngine',
|
||||
'PhabricatorPeopleEmpowerController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleExternalIdentifierPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorPeopleExternalPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorPeopleIconSet' => 'PhabricatorIconSet',
|
||||
'PhabricatorPeopleInviteController' => 'PhabricatorPeopleController',
|
||||
@@ -10639,6 +10794,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleRenameController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorPeopleSpamController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleTasksProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleTestDataGenerator' => 'PhabricatorTestDataGenerator',
|
||||
'PhabricatorPeopleTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
@@ -11329,6 +11485,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSearchManagementNgramsWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
'PhabricatorSearchManagementQueryWorkflow' => 'PhabricatorSearchManagementWorkflow',
|
||||
'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
'PhabricatorSearchNgramEngine' => 'Phobject',
|
||||
'PhabricatorSearchNgrams' => 'PhabricatorSearchDAO',
|
||||
'PhabricatorSearchNgramsDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
||||
'PhabricatorSearchOrderController' => 'PhabricatorSearchBaseController',
|
||||
@@ -11372,6 +11529,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsMainController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsPanel' => 'Phobject',
|
||||
'PhabricatorSettingsPanelChangeUsername' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorSettingsPanelGroup' => 'Phobject',
|
||||
'PhabricatorSettingsTimezoneController' => 'PhabricatorController',
|
||||
'PhabricatorSetupCheck' => 'Phobject',
|
||||
@@ -11382,7 +11540,6 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSetupIssueView' => 'AphrontView',
|
||||
'PhabricatorShiftChartFunction' => 'PhabricatorPureChartFunction',
|
||||
'PhabricatorShortSite' => 'PhabricatorSite',
|
||||
'PhabricatorShowFiletreeSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorSignDocumentsUserLogType' => 'PhabricatorUserLogType',
|
||||
'PhabricatorSimpleEditType' => 'PhabricatorEditType',
|
||||
'PhabricatorSinChartFunction' => 'PhabricatorPureChartFunction',
|
||||
@@ -11634,6 +11791,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorTransactionChange' => 'Phobject',
|
||||
'PhabricatorTransactionFactEngine' => 'PhabricatorFactEngine',
|
||||
'PhabricatorTransactionRemarkupChange' => 'PhabricatorTransactionChange',
|
||||
'PhabricatorTransactionWarning' => 'Phobject',
|
||||
'PhabricatorTransactions' => 'Phobject',
|
||||
'PhabricatorTransactionsApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorTransactionsDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
||||
@@ -11707,6 +11865,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorUserCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
|
||||
'PhabricatorUserCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
|
||||
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorUserDisableSpamTransaction' => 'PhabricatorUserTransactionType',
|
||||
'PhabricatorUserDisableTransaction' => 'PhabricatorUserTransactionType',
|
||||
'PhabricatorUserEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorUserEditor' => 'PhabricatorEditor',
|
||||
@@ -12421,6 +12580,7 @@ phutil_register_library_map(array(
|
||||
'PhrictionTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PhrictionTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhrictionTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhutilAPCKeyValueCache' => 'PhutilKeyValueCache',
|
||||
'PhutilAmazonAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilAsanaAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilAuthAdapter' => 'Phobject',
|
||||
@@ -12450,7 +12610,20 @@ phutil_register_library_map(array(
|
||||
'PhutilCalendarRootNode' => 'PhutilCalendarContainerNode',
|
||||
'PhutilCalendarUserNode' => 'PhutilCalendarNode',
|
||||
'PhutilCodeSnippetContextFreeGrammar' => 'PhutilContextFreeGrammar',
|
||||
'PhutilConsoleSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilContextFreeGrammar' => 'Phobject',
|
||||
'PhutilDaemon' => 'Phobject',
|
||||
'PhutilDaemonHandle' => 'Phobject',
|
||||
'PhutilDaemonOverseer' => 'Phobject',
|
||||
'PhutilDaemonOverseerModule' => 'Phobject',
|
||||
'PhutilDaemonPool' => 'Phobject',
|
||||
'PhutilDefaultSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilDefaultSyntaxHighlighterEngine' => 'PhutilSyntaxHighlighterEngine',
|
||||
'PhutilDefaultSyntaxHighlighterEnginePygmentsFuture' => 'FutureProxy',
|
||||
'PhutilDefaultSyntaxHighlighterEngineTestCase' => 'PhutilTestCase',
|
||||
'PhutilDirectoryKeyValueCache' => 'PhutilKeyValueCache',
|
||||
'PhutilDisqusAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilDivinerSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilEmptyAuthAdapter' => 'PhutilAuthAdapter',
|
||||
'PhutilFacebookAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilGitHubAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
@@ -12460,18 +12633,37 @@ phutil_register_library_map(array(
|
||||
'PhutilICSParserTestCase' => 'PhutilTestCase',
|
||||
'PhutilICSWriter' => 'Phobject',
|
||||
'PhutilICSWriterTestCase' => 'PhutilTestCase',
|
||||
'PhutilInRequestKeyValueCache' => 'PhutilKeyValueCache',
|
||||
'PhutilInvisibleSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilJIRAAuthAdapter' => 'PhutilOAuth1AuthAdapter',
|
||||
'PhutilJSONFragmentLexerHighlighterTestCase' => 'PhutilTestCase',
|
||||
'PhutilJavaCodeSnippetContextFreeGrammar' => 'PhutilCLikeCodeSnippetContextFreeGrammar',
|
||||
'PhutilKeyValueCache' => 'Phobject',
|
||||
'PhutilKeyValueCacheNamespace' => 'PhutilKeyValueCacheProxy',
|
||||
'PhutilKeyValueCacheProfiler' => 'PhutilKeyValueCacheProxy',
|
||||
'PhutilKeyValueCacheProxy' => 'PhutilKeyValueCache',
|
||||
'PhutilKeyValueCacheStack' => 'PhutilKeyValueCache',
|
||||
'PhutilKeyValueCacheTestCase' => 'PhutilTestCase',
|
||||
'PhutilLDAPAuthAdapter' => 'PhutilAuthAdapter',
|
||||
'PhutilLexerSyntaxHighlighter' => 'PhutilSyntaxHighlighter',
|
||||
'PhutilLipsumContextFreeGrammar' => 'PhutilContextFreeGrammar',
|
||||
'PhutilMarkupEngine' => 'Phobject',
|
||||
'PhutilMarkupTestCase' => 'PhutilTestCase',
|
||||
'PhutilMemcacheKeyValueCache' => 'PhutilKeyValueCache',
|
||||
'PhutilOAuth1AuthAdapter' => 'PhutilAuthAdapter',
|
||||
'PhutilOAuthAuthAdapter' => 'PhutilAuthAdapter',
|
||||
'PhutilOnDiskKeyValueCache' => 'PhutilKeyValueCache',
|
||||
'PhutilPHPCodeSnippetContextFreeGrammar' => 'PhutilCLikeCodeSnippetContextFreeGrammar',
|
||||
'PhutilPHPFragmentLexerHighlighterTestCase' => 'PhutilTestCase',
|
||||
'PhutilPhabricatorAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilProseDiff' => 'Phobject',
|
||||
'PhutilProseDiffTestCase' => 'PhabricatorTestCase',
|
||||
'PhutilProseDifferenceEngine' => 'Phobject',
|
||||
'PhutilPygmentizeParser' => 'Phobject',
|
||||
'PhutilPygmentizeParserTestCase' => 'PhutilTestCase',
|
||||
'PhutilPygmentsSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilQueryString' => 'Phobject',
|
||||
'PhutilRainbowSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilRealNameContextFreeGrammar' => 'PhutilContextFreeGrammar',
|
||||
'PhutilRemarkupAnchorRule' => 'PhutilRemarkupRule',
|
||||
'PhutilRemarkupBlockInterpreter' => 'Phobject',
|
||||
@@ -12507,6 +12699,8 @@ phutil_register_library_map(array(
|
||||
'PhutilRemarkupTableBlockRule' => 'PhutilRemarkupBlockRule',
|
||||
'PhutilRemarkupTestInterpreterRule' => 'PhutilRemarkupBlockInterpreter',
|
||||
'PhutilRemarkupUnderlineRule' => 'PhutilRemarkupRule',
|
||||
'PhutilSafeHTML' => 'Phobject',
|
||||
'PhutilSafeHTMLTestCase' => 'PhutilTestCase',
|
||||
'PhutilSearchQueryCompiler' => 'Phobject',
|
||||
'PhutilSearchQueryCompilerSyntaxException' => 'Exception',
|
||||
'PhutilSearchQueryCompilerTestCase' => 'PhutilTestCase',
|
||||
@@ -12514,9 +12708,18 @@ phutil_register_library_map(array(
|
||||
'PhutilSearchStemmer' => 'Phobject',
|
||||
'PhutilSearchStemmerTestCase' => 'PhutilTestCase',
|
||||
'PhutilSlackAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilSprite' => 'Phobject',
|
||||
'PhutilSpriteSheet' => 'Phobject',
|
||||
'PhutilSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilSyntaxHighlighterEngine' => 'Phobject',
|
||||
'PhutilSyntaxHighlighterException' => 'Exception',
|
||||
'PhutilTranslatedHTMLTestCase' => 'PhutilTestCase',
|
||||
'PhutilTwitchAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilTwitterAuthAdapter' => 'PhutilOAuth1AuthAdapter',
|
||||
'PhutilWordPressAuthAdapter' => 'PhutilOAuthAuthAdapter',
|
||||
'PhutilXHPASTSyntaxHighlighter' => 'Phobject',
|
||||
'PhutilXHPASTSyntaxHighlighterFuture' => 'FutureProxy',
|
||||
'PhutilXHPASTSyntaxHighlighterTestCase' => 'PhutilTestCase',
|
||||
'PolicyLockOptionType' => 'PhabricatorConfigJSONOptionType',
|
||||
'PonderAddAnswerView' => 'AphrontView',
|
||||
'PonderAnswer' => array(
|
||||
|
||||
@@ -30,6 +30,7 @@ final class AphrontRequest extends Phobject {
|
||||
private $controller;
|
||||
private $uriData = array();
|
||||
private $cookiePrefix;
|
||||
private $submitKey;
|
||||
|
||||
public function __construct($host, $path) {
|
||||
$this->host = $host;
|
||||
@@ -914,5 +915,19 @@ final class AphrontRequest extends Phobject {
|
||||
return $future;
|
||||
}
|
||||
|
||||
public function updateEphemeralCookies() {
|
||||
$submit_cookie = PhabricatorCookies::COOKIE_SUBMIT;
|
||||
|
||||
$submit_key = $this->getCookie($submit_cookie);
|
||||
if (strlen($submit_key)) {
|
||||
$this->clearCookie($submit_cookie);
|
||||
$this->submitKey = $submit_key;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getSubmitKey() {
|
||||
return $this->submitKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
85
src/aphront/__tests__/AphrontRoutingMapTestCase.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
final class AphrontRoutingMapTestCase
|
||||
extends PhabricatorTestCase {
|
||||
|
||||
public function testRoutingMaps() {
|
||||
$count = 0;
|
||||
|
||||
$sites = AphrontSite::getAllSites();
|
||||
foreach ($sites as $site) {
|
||||
$maps = $site->getRoutingMaps();
|
||||
foreach ($maps as $map) {
|
||||
foreach ($map->getRoutes() as $rule => $value) {
|
||||
$this->assertRoutable($site, $map, array(), $rule, $value);
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$count) {
|
||||
$this->assertSkipped(
|
||||
pht('No sites define any routing rules.'));
|
||||
}
|
||||
}
|
||||
|
||||
private function assertRoutable(
|
||||
AphrontSite $site,
|
||||
AphrontRoutingMap $map,
|
||||
array $path,
|
||||
$rule,
|
||||
$value) {
|
||||
|
||||
$path[] = $rule;
|
||||
|
||||
$site_description = $site->getDescription();
|
||||
$rule_path = implode(' > ', $path);
|
||||
|
||||
$pattern = implode('', $path);
|
||||
$pattern = '('.$pattern.')';
|
||||
$ok = @preg_match($pattern, '');
|
||||
|
||||
$this->assertTrue(
|
||||
($ok !== false),
|
||||
pht(
|
||||
'Routing rule ("%s", for site "%s") does not compile into a '.
|
||||
'valid regular expression.',
|
||||
$rule_path,
|
||||
$site_description));
|
||||
|
||||
if (is_array($value)) {
|
||||
$this->assertTrue(
|
||||
(count($value) > 0),
|
||||
pht(
|
||||
'Routing rule ("%s", for site "%s") does not have any targets.',
|
||||
$rule_path,
|
||||
$site_description));
|
||||
|
||||
foreach ($value as $sub_rule => $sub_value) {
|
||||
$this->assertRoutable($site, $map, $path, $sub_rule, $sub_value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_string($value)) {
|
||||
$this->assertTrue(
|
||||
class_exists($value),
|
||||
pht(
|
||||
'Routing rule ("%s", for site "%s") points at controller ("%s") '.
|
||||
'which does not exist.',
|
||||
$rule_path,
|
||||
$site_description,
|
||||
$value));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertFailure(
|
||||
pht(
|
||||
'Routing rule ("%s", for site "%s") points at unknown value '.
|
||||
'(of type "%s"), expected a controller class name string.',
|
||||
$rule_path,
|
||||
$site_description,
|
||||
phutil_describe_type($value)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,8 @@ final class AphrontApplicationConfiguration
|
||||
$request->setApplicationConfiguration($this);
|
||||
$request->setCookiePrefix($cookie_prefix);
|
||||
|
||||
$request->updateEphemeralCookies();
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
@@ -771,12 +773,21 @@ final class AphrontApplicationConfiguration
|
||||
);
|
||||
}
|
||||
|
||||
$raw_input = @file_get_contents('php://input');
|
||||
if ($raw_input !== false) {
|
||||
$base64_input = base64_encode($raw_input);
|
||||
} else {
|
||||
$base64_input = null;
|
||||
}
|
||||
|
||||
$result = array(
|
||||
'path' => $path,
|
||||
'params' => $params,
|
||||
'user' => idx($_SERVER, 'PHP_AUTH_USER'),
|
||||
'pass' => idx($_SERVER, 'PHP_AUTH_PW'),
|
||||
|
||||
'raw.base64' => $base64_input,
|
||||
|
||||
// This just makes sure that the response compresses well, so reasonable
|
||||
// algorithms should want to gzip or deflate it.
|
||||
'filler' => str_repeat('Q', 1024 * 16),
|
||||
@@ -801,27 +812,22 @@ final class AphrontApplicationConfiguration
|
||||
// if we can. Among other things, this corrects variable names with
|
||||
// the "." character in them, which PHP normally converts into "_".
|
||||
|
||||
// There are two major considerations here: whether the
|
||||
// `enable_post_data_reading` option is set, and whether the content
|
||||
// type is "multipart/form-data" or not.
|
||||
|
||||
// If `enable_post_data_reading` is off, we're free to read the entire
|
||||
// raw request body and parse it -- and we must, because $_POST and
|
||||
// $_FILES are not built for us. If `enable_post_data_reading` is on,
|
||||
// which is the default, we may not be able to read the body (the
|
||||
// documentation says we can't, but empirically we can at least some
|
||||
// of the time).
|
||||
// If "enable_post_data_reading" is on, the documentation suggests we
|
||||
// can not read the body. In practice, we seem to be able to. This may
|
||||
// need to be resolved at some point, likely by instructing installs
|
||||
// to disable this option.
|
||||
|
||||
// If the content type is "multipart/form-data", we need to build both
|
||||
// $_POST and $_FILES, which is involved. The body itself is also more
|
||||
// difficult to parse than other requests.
|
||||
|
||||
$raw_input = PhabricatorStartup::getRawInput();
|
||||
$parser = new PhutilQueryStringParser();
|
||||
|
||||
if (strlen($raw_input)) {
|
||||
$content_type = idx($_SERVER, 'CONTENT_TYPE');
|
||||
$is_multipart = preg_match('@^multipart/form-data@i', $content_type);
|
||||
if ($is_multipart && !ini_get('enable_post_data_reading')) {
|
||||
if ($is_multipart) {
|
||||
$multipart_parser = id(new AphrontMultipartParser())
|
||||
->setContentType($content_type);
|
||||
|
||||
|
||||
150
src/aphront/headerparser/AphrontHTTPHeaderParser.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
final class AphrontHTTPHeaderParser extends Phobject {
|
||||
|
||||
private $name;
|
||||
private $content;
|
||||
private $pairs;
|
||||
|
||||
public function parseRawHeader($raw_header) {
|
||||
$this->name = null;
|
||||
$this->content = null;
|
||||
|
||||
$parts = explode(':', $raw_header, 2);
|
||||
$this->name = trim($parts[0]);
|
||||
if (count($parts) > 1) {
|
||||
$this->content = trim($parts[1]);
|
||||
}
|
||||
|
||||
$this->pairs = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHeaderName() {
|
||||
$this->requireParse();
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getHeaderContent() {
|
||||
$this->requireParse();
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getHeaderContentAsPairs() {
|
||||
$content = $this->getHeaderContent();
|
||||
|
||||
|
||||
$state = 'prekey';
|
||||
$length = strlen($content);
|
||||
|
||||
$pair_name = null;
|
||||
$pair_value = null;
|
||||
|
||||
$pairs = array();
|
||||
$ii = 0;
|
||||
while ($ii < $length) {
|
||||
$c = $content[$ii];
|
||||
|
||||
switch ($state) {
|
||||
case 'prekey';
|
||||
// We're eating space in front of a key.
|
||||
if ($c == ' ') {
|
||||
$ii++;
|
||||
break;
|
||||
}
|
||||
$pair_name = '';
|
||||
$state = 'key';
|
||||
break;
|
||||
case 'key';
|
||||
// We're parsing a key name until we find "=" or ";".
|
||||
if ($c == ';') {
|
||||
$state = 'done';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($c == '=') {
|
||||
$ii++;
|
||||
$state = 'value';
|
||||
break;
|
||||
}
|
||||
|
||||
$ii++;
|
||||
$pair_name .= $c;
|
||||
break;
|
||||
case 'value':
|
||||
// We found an "=", so now figure out if the value is quoted
|
||||
// or not.
|
||||
if ($c == '"') {
|
||||
$ii++;
|
||||
$state = 'quoted';
|
||||
break;
|
||||
}
|
||||
$state = 'unquoted';
|
||||
break;
|
||||
case 'quoted':
|
||||
// We're in a quoted string, parse until we find the closing quote.
|
||||
if ($c == '"') {
|
||||
$ii++;
|
||||
$state = 'done';
|
||||
break;
|
||||
}
|
||||
|
||||
$ii++;
|
||||
$pair_value .= $c;
|
||||
break;
|
||||
case 'unquoted':
|
||||
// We're in an unquoted string, parse until we find a space or a
|
||||
// semicolon.
|
||||
if ($c == ' ' || $c == ';') {
|
||||
$state = 'done';
|
||||
break;
|
||||
}
|
||||
$ii++;
|
||||
$pair_value .= $c;
|
||||
break;
|
||||
case 'done':
|
||||
// We parsed something, so eat any trailing whitespace and semicolons
|
||||
// and look for a new value.
|
||||
if ($c == ' ' || $c == ';') {
|
||||
$ii++;
|
||||
break;
|
||||
}
|
||||
|
||||
$pairs[] = array(
|
||||
$pair_name,
|
||||
$pair_value,
|
||||
);
|
||||
|
||||
$pair_name = null;
|
||||
$pair_value = null;
|
||||
|
||||
$state = 'prekey';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($state == 'quoted') {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Header has unterminated double quote for key "%s".',
|
||||
$pair_name));
|
||||
}
|
||||
|
||||
if ($pair_name !== null) {
|
||||
$pairs[] = array(
|
||||
$pair_name,
|
||||
$pair_value,
|
||||
);
|
||||
}
|
||||
|
||||
return $pairs;
|
||||
}
|
||||
|
||||
private function requireParse() {
|
||||
if ($this->name === null) {
|
||||
throw new PhutilInvalidStateException('parseRawHeader');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
final class AphrontHTTPHeaderParserTestCase extends PhutilTestCase {
|
||||
|
||||
public function testHeaderParser() {
|
||||
$cases = array(
|
||||
array(
|
||||
'Key: x; y; z',
|
||||
'Key',
|
||||
'x; y; z',
|
||||
array(
|
||||
array('x', null),
|
||||
array('y', null),
|
||||
array('z', null),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'Content-Disposition: form-data; name="label"',
|
||||
'Content-Disposition',
|
||||
'form-data; name="label"',
|
||||
array(
|
||||
array('form-data', null),
|
||||
array('name', 'label'),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'Content-Type: multipart/form-data; charset=utf-8',
|
||||
'Content-Type',
|
||||
'multipart/form-data; charset=utf-8',
|
||||
array(
|
||||
array('multipart/form-data', null),
|
||||
array('charset', 'utf-8'),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'Content-Type: application/octet-stream; charset="ut',
|
||||
'Content-Type',
|
||||
'application/octet-stream; charset="ut',
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'Content-Type: multipart/form-data; boundary=ABCDEFG',
|
||||
'Content-Type',
|
||||
'multipart/form-data; boundary=ABCDEFG',
|
||||
array(
|
||||
array('multipart/form-data', null),
|
||||
array('boundary', 'ABCDEFG'),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'Content-Type: multipart/form-data; boundary="ABCDEFG"',
|
||||
'Content-Type',
|
||||
'multipart/form-data; boundary="ABCDEFG"',
|
||||
array(
|
||||
array('multipart/form-data', null),
|
||||
array('boundary', 'ABCDEFG'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($cases as $case) {
|
||||
$input = $case[0];
|
||||
$expect_name = $case[1];
|
||||
$expect_content = $case[2];
|
||||
|
||||
$parser = id(new AphrontHTTPHeaderParser())
|
||||
->parseRawHeader($input);
|
||||
|
||||
$actual_name = $parser->getHeaderName();
|
||||
$actual_content = $parser->getHeaderContent();
|
||||
|
||||
$this->assertEqual(
|
||||
$expect_name,
|
||||
$actual_name,
|
||||
pht('Header name for: %s', $input));
|
||||
|
||||
$this->assertEqual(
|
||||
$expect_content,
|
||||
$actual_content,
|
||||
pht('Header content for: %s', $input));
|
||||
|
||||
if (isset($case[3])) {
|
||||
$expect_pairs = $case[3];
|
||||
|
||||
$caught = null;
|
||||
try {
|
||||
$actual_pairs = $parser->getHeaderContentAsPairs();
|
||||
} catch (Exception $ex) {
|
||||
$caught = $ex;
|
||||
}
|
||||
|
||||
if ($expect_pairs === false) {
|
||||
$this->assertEqual(
|
||||
true,
|
||||
($caught instanceof Exception),
|
||||
pht('Expect exception for header pairs of: %s', $input));
|
||||
} else {
|
||||
$this->assertEqual(
|
||||
$expect_pairs,
|
||||
$actual_pairs,
|
||||
pht('Header pairs for: %s', $input));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
249
src/aphront/multipartparser/AphrontMultipartParser.php
Normal file
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
|
||||
final class AphrontMultipartParser extends Phobject {
|
||||
|
||||
private $contentType;
|
||||
private $boundary;
|
||||
|
||||
private $buffer;
|
||||
private $body;
|
||||
private $state;
|
||||
|
||||
private $part;
|
||||
private $parts;
|
||||
|
||||
public function setContentType($content_type) {
|
||||
$this->contentType = $content_type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContentType() {
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
public function beginParse() {
|
||||
$content_type = $this->getContentType();
|
||||
if ($content_type === null) {
|
||||
throw new PhutilInvalidStateException('setContentType');
|
||||
}
|
||||
|
||||
if (!preg_match('(^multipart/form-data)', $content_type)) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Expected "multipart/form-data" content type when executing a '.
|
||||
'multipart body read.'));
|
||||
}
|
||||
|
||||
$type_parts = preg_split('(\s*;\s*)', $content_type);
|
||||
$boundary = null;
|
||||
foreach ($type_parts as $type_part) {
|
||||
$matches = null;
|
||||
if (preg_match('(^boundary=(.*))', $type_part, $matches)) {
|
||||
$boundary = $matches[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($boundary === null) {
|
||||
throw new Exception(
|
||||
pht('Received "multipart/form-data" request with no "boundary".'));
|
||||
}
|
||||
|
||||
$this->parts = array();
|
||||
$this->part = null;
|
||||
|
||||
$this->buffer = '';
|
||||
$this->boundary = $boundary;
|
||||
|
||||
// We're looking for a (usually empty) body before the first boundary.
|
||||
$this->state = 'bodynewline';
|
||||
}
|
||||
|
||||
public function continueParse($bytes) {
|
||||
$this->buffer .= $bytes;
|
||||
|
||||
$continue = true;
|
||||
while ($continue) {
|
||||
switch ($this->state) {
|
||||
case 'endboundary':
|
||||
// We've just parsed a boundary. Next, we expect either "--" (which
|
||||
// indicates we've reached the end of the parts) or "\r\n" (which
|
||||
// indicates we should read the headers for the next part).
|
||||
|
||||
if (strlen($this->buffer) < 2) {
|
||||
// We don't have enough bytes yet, so wait for more.
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strncmp($this->buffer, '--', 2)) {
|
||||
// This is "--" after a boundary, so we're done. We'll read the
|
||||
// rest of the body (the "epilogue") and discard it.
|
||||
$this->buffer = substr($this->buffer, 2);
|
||||
$this->state = 'epilogue';
|
||||
|
||||
$this->part = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strncmp($this->buffer, "\r\n", 2)) {
|
||||
// This is "\r\n" after a boundary, so we're going to going to
|
||||
// read the headers for a part.
|
||||
$this->buffer = substr($this->buffer, 2);
|
||||
$this->state = 'header';
|
||||
|
||||
// Create the object to hold the part we're about to read.
|
||||
$part = new AphrontMultipartPart();
|
||||
$this->parts[] = $part;
|
||||
$this->part = $part;
|
||||
break;
|
||||
}
|
||||
|
||||
throw new Exception(
|
||||
pht('Expected "\r\n" or "--" after multipart data boundary.'));
|
||||
case 'header':
|
||||
// We've just parsed a boundary, followed by "\r\n". We are going
|
||||
// to read the headers for this part. They are in the form of HTTP
|
||||
// headers and terminated by "\r\n". The section is terminated by
|
||||
// a line with no header on it.
|
||||
|
||||
if (strlen($this->buffer) < 2) {
|
||||
// We don't have enough data to find a "\r\n", so wait for more.
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strncmp("\r\n", $this->buffer, 2)) {
|
||||
// This line immediately began "\r\n", so we're done with parsing
|
||||
// headers. Start parsing the body.
|
||||
$this->buffer = substr($this->buffer, 2);
|
||||
$this->state = 'body';
|
||||
break;
|
||||
}
|
||||
|
||||
// This is an actual header, so look for the end of it.
|
||||
$header_len = strpos($this->buffer, "\r\n");
|
||||
if ($header_len === false) {
|
||||
// We don't have a full header yet, so wait for more data.
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
$header_buf = substr($this->buffer, 0, $header_len);
|
||||
$this->part->appendRawHeader($header_buf);
|
||||
|
||||
$this->buffer = substr($this->buffer, $header_len + 2);
|
||||
break;
|
||||
case 'body':
|
||||
// We've parsed a boundary and headers, and are parsing the data for
|
||||
// this part. The data is terminated by "\r\n--", then the boundary.
|
||||
|
||||
// We'll look for "\r\n", then switch to the "bodynewline" state if
|
||||
// we find it.
|
||||
|
||||
$marker = "\r";
|
||||
$marker_pos = strpos($this->buffer, $marker);
|
||||
|
||||
if ($marker_pos === false) {
|
||||
// There's no "\r" anywhere in the buffer, so we can just read it
|
||||
// as provided. Then, since we read all the data, we're done until
|
||||
// we get more.
|
||||
|
||||
// Note that if we're in the preamble, we won't have a "part"
|
||||
// object and will just discard the data.
|
||||
if ($this->part) {
|
||||
$this->part->appendData($this->buffer);
|
||||
}
|
||||
$this->buffer = '';
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($marker_pos > 0) {
|
||||
// If there are bytes before the "\r",
|
||||
if ($this->part) {
|
||||
$this->part->appendData(substr($this->buffer, 0, $marker_pos));
|
||||
}
|
||||
$this->buffer = substr($this->buffer, $marker_pos);
|
||||
}
|
||||
|
||||
$expect = "\r\n";
|
||||
$expect_len = strlen($expect);
|
||||
if (strlen($this->buffer) < $expect_len) {
|
||||
// We don't have enough bytes yet to know if this is "\r\n"
|
||||
// or not.
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp($this->buffer, $expect, $expect_len)) {
|
||||
// The next two bytes aren't "\r\n", so eat them and go looking
|
||||
// for more newlines.
|
||||
if ($this->part) {
|
||||
$this->part->appendData(substr($this->buffer, 0, $expect_len));
|
||||
}
|
||||
$this->buffer = substr($this->buffer, $expect_len);
|
||||
break;
|
||||
}
|
||||
|
||||
// Eat the "\r\n".
|
||||
$this->buffer = substr($this->buffer, $expect_len);
|
||||
$this->state = 'bodynewline';
|
||||
break;
|
||||
case 'bodynewline':
|
||||
// We've parsed a newline in a body, or we just started parsing the
|
||||
// request. In either case, we're looking for "--", then the boundary.
|
||||
// If we find it, this section is done. If we don't, we consume the
|
||||
// bytes and move on.
|
||||
|
||||
$expect = '--'.$this->boundary;
|
||||
$expect_len = strlen($expect);
|
||||
|
||||
if (strlen($this->buffer) < $expect_len) {
|
||||
// We don't have enough bytes yet, so wait for more.
|
||||
$continue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp($this->buffer, $expect, $expect_len)) {
|
||||
// This wasn't the boundary, so return to the "body" state and
|
||||
// consume it. (But first, we need to append the "\r\n" which we
|
||||
// ate earlier.)
|
||||
if ($this->part) {
|
||||
$this->part->appendData("\r\n");
|
||||
}
|
||||
$this->state = 'body';
|
||||
break;
|
||||
}
|
||||
|
||||
// This is the boundary, so toss it and move on.
|
||||
$this->buffer = substr($this->buffer, $expect_len);
|
||||
$this->state = 'endboundary';
|
||||
break;
|
||||
case 'epilogue':
|
||||
// We just discard any epilogue.
|
||||
$this->buffer = '';
|
||||
$continue = false;
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unknown parser state "%s".\n',
|
||||
$this->state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function endParse() {
|
||||
if ($this->state !== 'epilogue') {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Expected "multipart/form-data" parse to end '.
|
||||
'in state "epilogue".'));
|
||||
}
|
||||
|
||||
return $this->parts;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
96
src/aphront/multipartparser/AphrontMultipartPart.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
final class AphrontMultipartPart extends Phobject {
|
||||
|
||||
private $headers = array();
|
||||
private $value = '';
|
||||
|
||||
private $name;
|
||||
private $filename;
|
||||
private $tempFile;
|
||||
private $byteSize = 0;
|
||||
|
||||
public function appendRawHeader($bytes) {
|
||||
$parser = id(new AphrontHTTPHeaderParser())
|
||||
->parseRawHeader($bytes);
|
||||
|
||||
$header_name = $parser->getHeaderName();
|
||||
|
||||
$this->headers[] = array(
|
||||
$header_name,
|
||||
$parser->getHeaderContent(),
|
||||
);
|
||||
|
||||
if (strtolower($header_name) === 'content-disposition') {
|
||||
$pairs = $parser->getHeaderContentAsPairs();
|
||||
foreach ($pairs as $pair) {
|
||||
list($key, $value) = $pair;
|
||||
switch ($key) {
|
||||
case 'filename':
|
||||
$this->filename = $value;
|
||||
break;
|
||||
case 'name':
|
||||
$this->name = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function appendData($bytes) {
|
||||
$this->byteSize += strlen($bytes);
|
||||
|
||||
if ($this->isVariable()) {
|
||||
$this->value .= $bytes;
|
||||
} else {
|
||||
if (!$this->tempFile) {
|
||||
$this->tempFile = new TempFile(getmypid().'.upload');
|
||||
}
|
||||
Filesystem::appendFile($this->tempFile, $bytes);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isVariable() {
|
||||
return ($this->filename === null);
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getVariableValue() {
|
||||
if (!$this->isVariable()) {
|
||||
throw new Exception(pht('This part is not a variable!'));
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function getPHPFileDictionary() {
|
||||
if (!$this->tempFile) {
|
||||
$this->appendData('');
|
||||
}
|
||||
|
||||
$mime_type = 'application/octet-stream';
|
||||
foreach ($this->headers as $header) {
|
||||
list($name, $value) = $header;
|
||||
if (strtolower($name) == 'content-type') {
|
||||
$mime_type = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => $this->filename,
|
||||
'type' => $mime_type,
|
||||
'tmp_name' => (string)$this->tempFile,
|
||||
'error' => 0,
|
||||
'size' => $this->byteSize,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
final class AphrontMultipartParserTestCase extends PhutilTestCase {
|
||||
|
||||
public function testParser() {
|
||||
$map = array(
|
||||
array(
|
||||
'data' => 'simple.txt',
|
||||
'variables' => array(
|
||||
array('a', 'b'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$data_dir = dirname(__FILE__).'/data/';
|
||||
foreach ($map as $test_case) {
|
||||
$data = Filesystem::readFile($data_dir.$test_case['data']);
|
||||
$data = str_replace("\n", "\r\n", $data);
|
||||
|
||||
$parser = id(new AphrontMultipartParser())
|
||||
->setContentType('multipart/form-data; boundary=ABCDEFG');
|
||||
$parser->beginParse();
|
||||
$parser->continueParse($data);
|
||||
$parts = $parser->endParse();
|
||||
|
||||
$variables = array();
|
||||
foreach ($parts as $part) {
|
||||
if (!$part->isVariable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$variables[] = array(
|
||||
$part->getName(),
|
||||
$part->getVariableValue(),
|
||||
);
|
||||
}
|
||||
|
||||
$expect_variables = idx($test_case, 'variables', array());
|
||||
$this->assertEqual($expect_variables, $variables);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
5
src/aphront/multipartparser/__tests__/data/simple.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
--ABCDEFG
|
||||
Content-Disposition: form-data; name="a"
|
||||
|
||||
b
|
||||
--ABCDEFG--
|
||||
113
src/aphront/requeststream/AphrontRequestStream.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
final class AphrontRequestStream extends Phobject {
|
||||
|
||||
private $encoding;
|
||||
private $stream;
|
||||
private $closed;
|
||||
private $iterator;
|
||||
|
||||
public function setEncoding($encoding) {
|
||||
$this->encoding = $encoding;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEncoding() {
|
||||
return $this->encoding;
|
||||
}
|
||||
|
||||
public function getIterator() {
|
||||
if (!$this->iterator) {
|
||||
$this->iterator = new PhutilStreamIterator($this->getStream());
|
||||
}
|
||||
return $this->iterator;
|
||||
}
|
||||
|
||||
public function readData() {
|
||||
if (!$this->iterator) {
|
||||
$iterator = $this->getIterator();
|
||||
$iterator->rewind();
|
||||
} else {
|
||||
$iterator = $this->getIterator();
|
||||
}
|
||||
|
||||
if (!$iterator->valid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $iterator->current();
|
||||
$iterator->next();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function getStream() {
|
||||
if (!$this->stream) {
|
||||
$this->stream = $this->newStream();
|
||||
}
|
||||
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
private function newStream() {
|
||||
$stream = fopen('php://input', 'rb');
|
||||
if (!$stream) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Failed to open stream "%s" for reading.',
|
||||
'php://input'));
|
||||
}
|
||||
|
||||
$encoding = $this->getEncoding();
|
||||
if ($encoding === 'gzip') {
|
||||
// This parameter is magic. Values 0-15 express a time/memory tradeoff,
|
||||
// but the largest value (15) corresponds to only 32KB of memory and
|
||||
// data encoded with a smaller window size than the one we pass can not
|
||||
// be decompressed. Always pass the maximum window size.
|
||||
|
||||
// Additionally, you can add 16 (to enable gzip) or 32 (to enable both
|
||||
// gzip and zlib). Add 32 to support both.
|
||||
$zlib_window = 15 + 32;
|
||||
|
||||
$ok = stream_filter_append(
|
||||
$stream,
|
||||
'zlib.inflate',
|
||||
STREAM_FILTER_READ,
|
||||
array(
|
||||
'window' => $zlib_window,
|
||||
));
|
||||
if (!$ok) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Failed to append filter "%s" to input stream while processing '.
|
||||
'a request with "%s" encoding.',
|
||||
'zlib.inflate',
|
||||
$encoding));
|
||||
}
|
||||
}
|
||||
|
||||
return $stream;
|
||||
}
|
||||
|
||||
public static function supportsGzip() {
|
||||
if (!function_exists('gzencode') || !function_exists('gzdecode')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$has_zlib = false;
|
||||
|
||||
// NOTE: At least locally, this returns "zlib.*", which is not terribly
|
||||
// reassuring. We care about "zlib.inflate".
|
||||
|
||||
$filters = stream_get_filters();
|
||||
foreach ($filters as $filter) {
|
||||
if (!strncasecmp($filter, 'zlib.', strlen('zlib.'))) {
|
||||
$has_zlib = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $has_zlib;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,11 +61,17 @@ final class AphrontHTTPProxyResponse extends AphrontResponse {
|
||||
// Strip "Transfer-Encoding" headers. Particularly, the server we proxied
|
||||
// may have chunked the response, but cURL will already have un-chunked it.
|
||||
// If we emit the header and unchunked data, the response becomes invalid.
|
||||
|
||||
// See T13517. Strip "Content-Encoding" and "Content-Length" headers, since
|
||||
// they may reflect compressed content.
|
||||
|
||||
foreach ($headers as $key => $header) {
|
||||
list($header_head, $header_body) = $header;
|
||||
$header_head = phutil_utf8_strtolower($header_head);
|
||||
switch ($header_head) {
|
||||
case 'transfer-encoding':
|
||||
case 'content-encoding':
|
||||
case 'content-length':
|
||||
unset($headers[$key]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -31,10 +31,10 @@ final class AphrontJSONResponse extends AphrontResponse {
|
||||
}
|
||||
|
||||
public function getHeaders() {
|
||||
$headers = array(
|
||||
array('Content-Type', 'application/json'),
|
||||
);
|
||||
$headers = array_merge(parent::getHeaders(), $headers);
|
||||
$headers = parent::getHeaders();
|
||||
|
||||
$headers[] = array('Content-Type', 'application/json');
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ abstract class AphrontResponse extends Phobject {
|
||||
private $contentSecurityPolicyURIs;
|
||||
private $disableContentSecurityPolicy;
|
||||
protected $frameable;
|
||||
|
||||
private $headers = array();
|
||||
|
||||
public function setRequest($request) {
|
||||
$this->request = $request;
|
||||
@@ -49,6 +49,11 @@ abstract class AphrontResponse extends Phobject {
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function addHeader($key, $value) {
|
||||
$this->headers[] = array($key, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/* -( Content )------------------------------------------------------------ */
|
||||
|
||||
@@ -105,6 +110,10 @@ abstract class AphrontResponse extends Phobject {
|
||||
|
||||
$headers[] = array('Referrer-Policy', 'no-referrer');
|
||||
|
||||
foreach ($this->headers as $header) {
|
||||
$headers[] = $header;
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
@@ -417,13 +426,19 @@ abstract class AphrontResponse extends Phobject {
|
||||
}
|
||||
|
||||
public function willBeginWrite() {
|
||||
if ($this->shouldCompressResponse()) {
|
||||
// Enable automatic compression here. Webservers sometimes do this for
|
||||
// us, but we now detect the absence of compression and warn users about
|
||||
// it so try to cover our bases more thoroughly.
|
||||
ini_set('zlib.output_compression', 1);
|
||||
} else {
|
||||
ini_set('zlib.output_compression', 0);
|
||||
// If we've already sent headers, these "ini_set()" calls will warn that
|
||||
// they have no effect. Today, this always happens because we're inside
|
||||
// a unit test, so just skip adjusting the setting.
|
||||
|
||||
if (!headers_sent()) {
|
||||
if ($this->shouldCompressResponse()) {
|
||||
// Enable automatic compression here. Webservers sometimes do this for
|
||||
// us, but we now detect the absence of compression and warn users about
|
||||
// it so try to cover our bases more thoroughly.
|
||||
ini_set('zlib.output_compression', 1);
|
||||
} else {
|
||||
ini_set('zlib.output_compression', 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
76
src/aphront/sprite/PhutilSprite.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NOTE: This is very new and unstable.
|
||||
*/
|
||||
final class PhutilSprite extends Phobject {
|
||||
|
||||
private $sourceFiles = array();
|
||||
private $sourceX;
|
||||
private $sourceY;
|
||||
private $sourceW;
|
||||
private $sourceH;
|
||||
private $targetCSS;
|
||||
private $spriteSheet;
|
||||
private $name;
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setTargetCSS($target_css) {
|
||||
$this->targetCSS = $target_css;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTargetCSS() {
|
||||
return $this->targetCSS;
|
||||
}
|
||||
|
||||
public function setSourcePosition($x, $y) {
|
||||
$this->sourceX = $x;
|
||||
$this->sourceY = $y;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSourceSize($w, $h) {
|
||||
$this->sourceW = $w;
|
||||
$this->sourceH = $h;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSourceH() {
|
||||
return $this->sourceH;
|
||||
}
|
||||
|
||||
public function getSourceW() {
|
||||
return $this->sourceW;
|
||||
}
|
||||
|
||||
public function getSourceY() {
|
||||
return $this->sourceY;
|
||||
}
|
||||
|
||||
public function getSourceX() {
|
||||
return $this->sourceX;
|
||||
}
|
||||
|
||||
public function setSourceFile($source_file, $scale = 1) {
|
||||
$this->sourceFiles[$scale] = $source_file;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSourceFile($scale) {
|
||||
if (empty($this->sourceFiles[$scale])) {
|
||||
throw new Exception(pht("No source file for scale '%s'!", $scale));
|
||||
}
|
||||
|
||||
return $this->sourceFiles[$scale];
|
||||
}
|
||||
|
||||
}
|
||||
385
src/aphront/sprite/PhutilSpriteSheet.php
Normal file
@@ -0,0 +1,385 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NOTE: This is very new and unstable.
|
||||
*/
|
||||
final class PhutilSpriteSheet extends Phobject {
|
||||
|
||||
const MANIFEST_VERSION = 1;
|
||||
|
||||
const TYPE_STANDARD = 'standard';
|
||||
const TYPE_REPEAT_X = 'repeat-x';
|
||||
const TYPE_REPEAT_Y = 'repeat-y';
|
||||
|
||||
private $sprites = array();
|
||||
private $sources = array();
|
||||
private $hashes = array();
|
||||
private $cssHeader;
|
||||
private $generated;
|
||||
private $scales = array(1);
|
||||
private $type = self::TYPE_STANDARD;
|
||||
private $basePath;
|
||||
|
||||
private $css;
|
||||
private $images;
|
||||
|
||||
public function addSprite(PhutilSprite $sprite) {
|
||||
$this->generated = false;
|
||||
$this->sprites[] = $sprite;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCSSHeader($header) {
|
||||
$this->generated = false;
|
||||
$this->cssHeader = $header;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setScales(array $scales) {
|
||||
$this->scales = array_values($scales);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getScales() {
|
||||
return $this->scales;
|
||||
}
|
||||
|
||||
public function setSheetType($type) {
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setBasePath($base_path) {
|
||||
$this->basePath = $base_path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function generate() {
|
||||
if ($this->generated) {
|
||||
return;
|
||||
}
|
||||
|
||||
$multi_row = true;
|
||||
$multi_col = true;
|
||||
$margin_w = 1;
|
||||
$margin_h = 1;
|
||||
|
||||
$type = $this->type;
|
||||
switch ($type) {
|
||||
case self::TYPE_STANDARD:
|
||||
break;
|
||||
case self::TYPE_REPEAT_X:
|
||||
$multi_col = false;
|
||||
$margin_w = 0;
|
||||
|
||||
$width = null;
|
||||
foreach ($this->sprites as $sprite) {
|
||||
if ($width === null) {
|
||||
$width = $sprite->getSourceW();
|
||||
} else if ($width !== $sprite->getSourceW()) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"All sprites in a '%s' sheet must have the same width.",
|
||||
'repeat-x'));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case self::TYPE_REPEAT_Y:
|
||||
$multi_row = false;
|
||||
$margin_h = 0;
|
||||
|
||||
$height = null;
|
||||
foreach ($this->sprites as $sprite) {
|
||||
if ($height === null) {
|
||||
$height = $sprite->getSourceH();
|
||||
} else if ($height !== $sprite->getSourceH()) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"All sprites in a '%s' sheet must have the same height.",
|
||||
'repeat-y'));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception(pht("Unknown sprite sheet type '%s'!", $type));
|
||||
}
|
||||
|
||||
|
||||
$css = array();
|
||||
if ($this->cssHeader) {
|
||||
$css[] = $this->cssHeader;
|
||||
}
|
||||
|
||||
$out_w = 0;
|
||||
$out_h = 0;
|
||||
|
||||
// Lay out the sprite sheet. We attempt to build a roughly square sheet
|
||||
// so it's easier to manage, since 2000x20 is more cumbersome for humans
|
||||
// to deal with than 200x200.
|
||||
//
|
||||
// To do this, we use a simple greedy algorithm, adding sprites one at a
|
||||
// time. For each sprite, if the sheet is at least as wide as it is tall
|
||||
// we create a new row. Otherwise, we try to add it to an existing row.
|
||||
//
|
||||
// This isn't optimal, but does a reasonable job in most cases and isn't
|
||||
// too messy.
|
||||
|
||||
// Group the sprites by their sizes. We lay them out in the sheet as
|
||||
// boxes, but then put them into the boxes in the order they were added
|
||||
// so similar sprites end up nearby on the final sheet.
|
||||
$boxes = array();
|
||||
foreach (array_reverse($this->sprites) as $sprite) {
|
||||
$s_w = $sprite->getSourceW() + $margin_w;
|
||||
$s_h = $sprite->getSourceH() + $margin_h;
|
||||
$boxes[$s_w][$s_h][] = $sprite;
|
||||
}
|
||||
|
||||
$rows = array();
|
||||
foreach ($this->sprites as $sprite) {
|
||||
$s_w = $sprite->getSourceW() + $margin_w;
|
||||
$s_h = $sprite->getSourceH() + $margin_h;
|
||||
|
||||
// Choose a row for this sprite.
|
||||
$maybe = array();
|
||||
foreach ($rows as $key => $row) {
|
||||
if ($row['h'] < $s_h) {
|
||||
// We can only add it to a row if the row is at least as tall as the
|
||||
// sprite.
|
||||
continue;
|
||||
}
|
||||
// We prefer rows which have the same height as the sprite, and then
|
||||
// rows which aren't yet very wide.
|
||||
$wasted_v = ($row['h'] - $s_h);
|
||||
$wasted_h = ($row['w'] / $out_w);
|
||||
$maybe[$key] = $wasted_v + $wasted_h;
|
||||
}
|
||||
|
||||
$row_key = null;
|
||||
if ($maybe && $multi_col) {
|
||||
// If there were any candidate rows, pick the best one.
|
||||
asort($maybe);
|
||||
$row_key = head_key($maybe);
|
||||
}
|
||||
|
||||
if ($row_key !== null && $multi_row) {
|
||||
// If there's a candidate row, but adding the sprite to it would make
|
||||
// the sprite wider than it is tall, create a new row instead. This
|
||||
// generally keeps the sprite square-ish.
|
||||
if ($rows[$row_key]['w'] + $s_w > $out_h) {
|
||||
$row_key = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($row_key === null) {
|
||||
// Add a new row.
|
||||
$rows[] = array(
|
||||
'w' => 0,
|
||||
'h' => $s_h,
|
||||
'boxes' => array(),
|
||||
);
|
||||
$row_key = last_key($rows);
|
||||
$out_h += $s_h;
|
||||
}
|
||||
|
||||
// Add the sprite box to the row.
|
||||
$row = $rows[$row_key];
|
||||
$row['w'] += $s_w;
|
||||
$row['boxes'][] = array($s_w, $s_h);
|
||||
$rows[$row_key] = $row;
|
||||
|
||||
$out_w = max($row['w'], $out_w);
|
||||
}
|
||||
|
||||
$images = array();
|
||||
foreach ($this->scales as $scale) {
|
||||
$img = imagecreatetruecolor($out_w * $scale, $out_h * $scale);
|
||||
imagesavealpha($img, true);
|
||||
imagefill($img, 0, 0, imagecolorallocatealpha($img, 0, 0, 0, 127));
|
||||
|
||||
$images[$scale] = $img;
|
||||
}
|
||||
|
||||
|
||||
// Put the shorter rows first. At the same height, put the wider rows first.
|
||||
// This makes the resulting sheet more human-readable.
|
||||
foreach ($rows as $key => $row) {
|
||||
$rows[$key]['sort'] = $row['h'] + (1 - ($row['w'] / $out_w));
|
||||
}
|
||||
$rows = isort($rows, 'sort');
|
||||
|
||||
$pos_x = 0;
|
||||
$pos_y = 0;
|
||||
$rules = array();
|
||||
foreach ($rows as $row) {
|
||||
$max_h = 0;
|
||||
foreach ($row['boxes'] as $box) {
|
||||
$sprite = array_pop($boxes[$box[0]][$box[1]]);
|
||||
|
||||
foreach ($images as $scale => $img) {
|
||||
$src = $this->loadSource($sprite, $scale);
|
||||
imagecopy(
|
||||
$img,
|
||||
$src,
|
||||
$scale * $pos_x, $scale * $pos_y,
|
||||
$scale * $sprite->getSourceX(), $scale * $sprite->getSourceY(),
|
||||
$scale * $sprite->getSourceW(), $scale * $sprite->getSourceH());
|
||||
}
|
||||
|
||||
$rule = $sprite->getTargetCSS();
|
||||
$cssx = (-$pos_x).'px';
|
||||
$cssy = (-$pos_y).'px';
|
||||
|
||||
$rules[$sprite->getName()] = "{$rule} {\n".
|
||||
" background-position: {$cssx} {$cssy};\n}";
|
||||
|
||||
$pos_x += $sprite->getSourceW() + $margin_w;
|
||||
$max_h = max($max_h, $sprite->getSourceH());
|
||||
}
|
||||
$pos_x = 0;
|
||||
$pos_y += $max_h + $margin_h;
|
||||
}
|
||||
|
||||
// Generate CSS rules in input order.
|
||||
foreach ($this->sprites as $sprite) {
|
||||
$css[] = $rules[$sprite->getName()];
|
||||
}
|
||||
|
||||
$this->images = $images;
|
||||
$this->css = implode("\n\n", $css)."\n";
|
||||
$this->generated = true;
|
||||
}
|
||||
|
||||
public function generateImage($path, $scale = 1) {
|
||||
$this->generate();
|
||||
$this->log(pht("Writing sprite '%s'...", $path));
|
||||
imagepng($this->images[$scale], $path);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function generateCSS($path) {
|
||||
$this->generate();
|
||||
$this->log(pht("Writing CSS '%s'...", $path));
|
||||
|
||||
$out = $this->css;
|
||||
$out = str_replace('{X}', imagesx($this->images[1]), $out);
|
||||
$out = str_replace('{Y}', imagesy($this->images[1]), $out);
|
||||
|
||||
Filesystem::writeFile($path, $out);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function needsRegeneration(array $manifest) {
|
||||
return ($this->buildManifest() !== $manifest);
|
||||
}
|
||||
|
||||
private function buildManifest() {
|
||||
$output = array();
|
||||
foreach ($this->sprites as $sprite) {
|
||||
$output[$sprite->getName()] = array(
|
||||
'name' => $sprite->getName(),
|
||||
'rule' => $sprite->getTargetCSS(),
|
||||
'hash' => $this->loadSourceHash($sprite),
|
||||
);
|
||||
}
|
||||
|
||||
ksort($output);
|
||||
|
||||
$data = array(
|
||||
'version' => self::MANIFEST_VERSION,
|
||||
'sprites' => $output,
|
||||
'scales' => $this->scales,
|
||||
'header' => $this->cssHeader,
|
||||
'type' => $this->type,
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function generateManifest($path) {
|
||||
$data = $this->buildManifest();
|
||||
|
||||
$json = new PhutilJSON();
|
||||
$data = $json->encodeFormatted($data);
|
||||
Filesystem::writeFile($path, $data);
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function log($message) {
|
||||
echo $message."\n";
|
||||
}
|
||||
|
||||
private function loadSourceHash(PhutilSprite $sprite) {
|
||||
$inputs = array();
|
||||
|
||||
foreach ($this->scales as $scale) {
|
||||
$file = $sprite->getSourceFile($scale);
|
||||
|
||||
// If two users have a project in different places, like:
|
||||
//
|
||||
// /home/alincoln/project
|
||||
// /home/htaft/project
|
||||
//
|
||||
// ...we want to ignore the `/home/alincoln` part when hashing the sheet,
|
||||
// since the sprites don't change when the project directory moves. If
|
||||
// the base path is set, build the hashes using paths relative to the
|
||||
// base path.
|
||||
|
||||
$file_key = $file;
|
||||
if ($this->basePath) {
|
||||
$file_key = Filesystem::readablePath($file, $this->basePath);
|
||||
}
|
||||
|
||||
if (empty($this->hashes[$file_key])) {
|
||||
$this->hashes[$file_key] = md5(Filesystem::readFile($file));
|
||||
}
|
||||
|
||||
$inputs[] = $file_key;
|
||||
$inputs[] = $this->hashes[$file_key];
|
||||
}
|
||||
|
||||
$inputs[] = $sprite->getSourceX();
|
||||
$inputs[] = $sprite->getSourceY();
|
||||
$inputs[] = $sprite->getSourceW();
|
||||
$inputs[] = $sprite->getSourceH();
|
||||
|
||||
return md5(implode(':', $inputs));
|
||||
}
|
||||
|
||||
private function loadSource(PhutilSprite $sprite, $scale) {
|
||||
$file = $sprite->getSourceFile($scale);
|
||||
if (empty($this->sources[$file])) {
|
||||
$data = Filesystem::readFile($file);
|
||||
$image = imagecreatefromstring($data);
|
||||
$this->sources[$file] = array(
|
||||
'image' => $image,
|
||||
'x' => imagesx($image),
|
||||
'y' => imagesy($image),
|
||||
);
|
||||
}
|
||||
|
||||
$s_w = $sprite->getSourceW() * $scale;
|
||||
$i_w = $this->sources[$file]['x'];
|
||||
if ($s_w > $i_w) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"Sprite source for '%s' is too small (expected width %d, found %d).",
|
||||
$file,
|
||||
$s_w,
|
||||
$i_w));
|
||||
}
|
||||
|
||||
$s_h = $sprite->getSourceH() * $scale;
|
||||
$i_h = $this->sources[$file]['y'];
|
||||
if ($s_h > $i_h) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"Sprite source for '%s' is too small (expected height %d, found %d).",
|
||||
$file,
|
||||
$s_h,
|
||||
$i_h));
|
||||
}
|
||||
|
||||
return $this->sources[$file]['image'];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
final class AphrontScopedUnguardedWriteCapability extends Phobject {
|
||||
|
||||
public function __destruct() {
|
||||
AphrontWriteGuard::endUnguardedWrites();
|
||||
}
|
||||
|
||||
}
|
||||
267
src/aphront/writeguard/AphrontWriteGuard.php
Normal file
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Guard writes against CSRF. The Aphront structure takes care of most of this
|
||||
* for you, you just need to call:
|
||||
*
|
||||
* AphrontWriteGuard::willWrite();
|
||||
*
|
||||
* ...before executing a write against any new kind of storage engine. MySQL
|
||||
* databases and the default file storage engines are already covered, but if
|
||||
* you introduce new types of datastores make sure their writes are guarded. If
|
||||
* you don't guard writes and make a mistake doing CSRF checks in a controller,
|
||||
* a CSRF vulnerability can escape undetected.
|
||||
*
|
||||
* If you need to execute writes on a page which doesn't have CSRF tokens (for
|
||||
* example, because you need to do logging), you can temporarily disable the
|
||||
* write guard by calling:
|
||||
*
|
||||
* AphrontWriteGuard::beginUnguardedWrites();
|
||||
* do_logging_write();
|
||||
* AphrontWriteGuard::endUnguardedWrites();
|
||||
*
|
||||
* This is dangerous, because it disables the backup layer of CSRF protection
|
||||
* this class provides. You should need this only very, very rarely.
|
||||
*
|
||||
* @task protect Protecting Writes
|
||||
* @task disable Disabling Protection
|
||||
* @task manage Managing Write Guards
|
||||
* @task internal Internals
|
||||
*/
|
||||
final class AphrontWriteGuard extends Phobject {
|
||||
|
||||
private static $instance;
|
||||
private static $allowUnguardedWrites = false;
|
||||
|
||||
private $callback;
|
||||
private $allowDepth = 0;
|
||||
|
||||
|
||||
/* -( Managing Write Guards )---------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new write guard for a request. Only one write guard may be
|
||||
* active at a time. You must explicitly call @{method:dispose} when you are
|
||||
* done with a write guard:
|
||||
*
|
||||
* $guard = new AphrontWriteGuard($callback);
|
||||
* // ...
|
||||
* $guard->dispose();
|
||||
*
|
||||
* Normally, you do not need to manage guards yourself -- the Aphront stack
|
||||
* handles it for you.
|
||||
*
|
||||
* This class accepts a callback, which will be invoked when a write is
|
||||
* attempted. The callback should validate the presence of a CSRF token in
|
||||
* the request, or abort the request (e.g., by throwing an exception) if a
|
||||
* valid token isn't present.
|
||||
*
|
||||
* @param callable CSRF callback.
|
||||
* @return this
|
||||
* @task manage
|
||||
*/
|
||||
public function __construct($callback) {
|
||||
if (self::$instance) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'An %s already exists. Dispose of the previous guard '.
|
||||
'before creating a new one.',
|
||||
__CLASS__));
|
||||
}
|
||||
if (self::$allowUnguardedWrites) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'An %s is being created in a context which permits '.
|
||||
'unguarded writes unconditionally. This is not allowed and '.
|
||||
'indicates a serious error.',
|
||||
__CLASS__));
|
||||
}
|
||||
$this->callback = $callback;
|
||||
self::$instance = $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dispose of the active write guard. You must call this method when you are
|
||||
* done with a write guard. You do not normally need to call this yourself.
|
||||
*
|
||||
* @return void
|
||||
* @task manage
|
||||
*/
|
||||
public function dispose() {
|
||||
if (!self::$instance) {
|
||||
throw new Exception(pht(
|
||||
'Attempting to dispose of write guard, but no write guard is active!'));
|
||||
}
|
||||
|
||||
if ($this->allowDepth > 0) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Imbalanced %s: more %s calls than %s calls.',
|
||||
__CLASS__,
|
||||
'beginUnguardedWrites()',
|
||||
'endUnguardedWrites()'));
|
||||
}
|
||||
self::$instance = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if there is an active write guard.
|
||||
*
|
||||
* @return bool
|
||||
* @task manage
|
||||
*/
|
||||
public static function isGuardActive() {
|
||||
return (bool)self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return on instance of AphrontWriteGuard if it's active, or null
|
||||
*
|
||||
* @return AphrontWriteGuard|null
|
||||
*/
|
||||
public static function getInstance() {
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/* -( Protecting Writes )-------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Declare intention to perform a write, validating that writes are allowed.
|
||||
* You should call this method before executing a write whenever you implement
|
||||
* a new storage engine where information can be permanently kept.
|
||||
*
|
||||
* Writes are permitted if:
|
||||
*
|
||||
* - The request has valid CSRF tokens.
|
||||
* - Unguarded writes have been temporarily enabled by a call to
|
||||
* @{method:beginUnguardedWrites}.
|
||||
* - All write guarding has been disabled with
|
||||
* @{method:allowDangerousUnguardedWrites}.
|
||||
*
|
||||
* If none of these conditions are true, this method will throw and prevent
|
||||
* the write.
|
||||
*
|
||||
* @return void
|
||||
* @task protect
|
||||
*/
|
||||
public static function willWrite() {
|
||||
if (!self::$instance) {
|
||||
if (!self::$allowUnguardedWrites) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unguarded write! There must be an active %s to perform writes.',
|
||||
__CLASS__));
|
||||
} else {
|
||||
// Unguarded writes are being allowed unconditionally.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$instance = self::$instance;
|
||||
if ($instance->allowDepth == 0) {
|
||||
call_user_func($instance->callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -( Disabling Write Protection )----------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Enter a scope which permits unguarded writes. This works like
|
||||
* @{method:beginUnguardedWrites} but returns an object which will end
|
||||
* the unguarded write scope when its __destruct() method is called. This
|
||||
* is useful to more easily handle exceptions correctly in unguarded write
|
||||
* blocks:
|
||||
*
|
||||
* // Restores the guard even if do_logging() throws.
|
||||
* function unguarded_scope() {
|
||||
* $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
* do_logging();
|
||||
* }
|
||||
*
|
||||
* @return AphrontScopedUnguardedWriteCapability Object which ends unguarded
|
||||
* writes when it leaves scope.
|
||||
* @task disable
|
||||
*/
|
||||
public static function beginScopedUnguardedWrites() {
|
||||
self::beginUnguardedWrites();
|
||||
return new AphrontScopedUnguardedWriteCapability();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Begin a block which permits unguarded writes. You should use this very
|
||||
* sparingly, and only for things like logging where CSRF is not a concern.
|
||||
*
|
||||
* You must pair every call to @{method:beginUnguardedWrites} with a call to
|
||||
* @{method:endUnguardedWrites}:
|
||||
*
|
||||
* AphrontWriteGuard::beginUnguardedWrites();
|
||||
* do_logging();
|
||||
* AphrontWriteGuard::endUnguardedWrites();
|
||||
*
|
||||
* @return void
|
||||
* @task disable
|
||||
*/
|
||||
public static function beginUnguardedWrites() {
|
||||
if (!self::$instance) {
|
||||
return;
|
||||
}
|
||||
self::$instance->allowDepth++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare that you have finished performing unguarded writes. You must
|
||||
* call this exactly once for each call to @{method:beginUnguardedWrites}.
|
||||
*
|
||||
* @return void
|
||||
* @task disable
|
||||
*/
|
||||
public static function endUnguardedWrites() {
|
||||
if (!self::$instance) {
|
||||
return;
|
||||
}
|
||||
if (self::$instance->allowDepth <= 0) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Imbalanced %s: more %s calls than %s calls.',
|
||||
__CLASS__,
|
||||
'endUnguardedWrites()',
|
||||
'beginUnguardedWrites()'));
|
||||
}
|
||||
self::$instance->allowDepth--;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allow execution of unguarded writes. This is ONLY appropriate for use in
|
||||
* script contexts or other contexts where you are guaranteed to never be
|
||||
* vulnerable to CSRF concerns. Calling this method is EXTREMELY DANGEROUS
|
||||
* if you do not understand the consequences.
|
||||
*
|
||||
* If you need to perform unguarded writes on an otherwise guarded workflow
|
||||
* which is vulnerable to CSRF, use @{method:beginUnguardedWrites}.
|
||||
*
|
||||
* @return void
|
||||
* @task disable
|
||||
*/
|
||||
public static function allowDangerousUnguardedWrites($allow) {
|
||||
if (self::$instance) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'You can not unconditionally disable %s by calling %s while a write '.
|
||||
'guard is active. Use %s to temporarily allow unguarded writes.',
|
||||
__CLASS__,
|
||||
__FUNCTION__.'()',
|
||||
'beginUnguardedWrites()'));
|
||||
}
|
||||
self::$allowUnguardedWrites = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,13 +10,15 @@ final class AlmanacConsoleController extends AlmanacController {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
->setViewer($viewer)
|
||||
->setBig(true);
|
||||
|
||||
$menu->addItem(
|
||||
id(new PHUIObjectItemView())
|
||||
->setHeader(pht('Devices'))
|
||||
->setHref($this->getApplicationURI('device/'))
|
||||
->setImageIcon('fa-server')
|
||||
->setClickable(true)
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Create an inventory of physical and virtual hosts and '.
|
||||
@@ -27,6 +29,7 @@ final class AlmanacConsoleController extends AlmanacController {
|
||||
->setHeader(pht('Services'))
|
||||
->setHref($this->getApplicationURI('service/'))
|
||||
->setImageIcon('fa-plug')
|
||||
->setClickable(true)
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Create and update services, and map them to interfaces on '.
|
||||
@@ -37,6 +40,7 @@ final class AlmanacConsoleController extends AlmanacController {
|
||||
->setHeader(pht('Networks'))
|
||||
->setHref($this->getApplicationURI('network/'))
|
||||
->setImageIcon('fa-globe')
|
||||
->setClickable(true)
|
||||
->addAttribute(
|
||||
pht(
|
||||
'Manage public and private networks.')));
|
||||
@@ -46,6 +50,7 @@ final class AlmanacConsoleController extends AlmanacController {
|
||||
->setHeader(pht('Namespaces'))
|
||||
->setHref($this->getApplicationURI('namespace/'))
|
||||
->setImageIcon('fa-asterisk')
|
||||
->setClickable(true)
|
||||
->addAttribute(
|
||||
pht('Control who can create new named services and devices.')));
|
||||
|
||||
@@ -57,6 +62,7 @@ final class AlmanacConsoleController extends AlmanacController {
|
||||
->setHeader(pht('Documentation'))
|
||||
->setHref($docs_uri)
|
||||
->setImageIcon('fa-book')
|
||||
->setClickable(true)
|
||||
->addAttribute(pht('Browse documentation for Almanac.')));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
@@ -64,23 +70,20 @@ final class AlmanacConsoleController extends AlmanacController {
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Almanac Console'))
|
||||
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||
->setObjectList($menu);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Almanac Console'))
|
||||
->setHeaderIcon('fa-server');
|
||||
$launcher_view = id(new PHUILauncherView())
|
||||
->appendChild($box);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$box,
|
||||
));
|
||||
->setFooter($launcher_view);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle(pht('Almanac Console'))
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,15 +57,6 @@ final class AlmanacKeys extends Phobject {
|
||||
}
|
||||
|
||||
public static function getClusterSSHUser() {
|
||||
// NOTE: When instancing, we currently use the SSH username to figure out
|
||||
// which instance you are connecting to. We can't use the host name because
|
||||
// we have no way to tell which host you think you're reaching: the SSH
|
||||
// protocol does not have a mechanism like a "Host" header.
|
||||
$username = PhabricatorEnv::getEnvConfig('cluster.instance');
|
||||
if (strlen($username)) {
|
||||
return $username;
|
||||
}
|
||||
|
||||
$username = PhabricatorEnv::getEnvConfig('diffusion.ssh-user');
|
||||
if (strlen($username)) {
|
||||
return $username;
|
||||
|
||||
@@ -550,11 +550,18 @@ abstract class PhabricatorAphlictManagementWorkflow
|
||||
}
|
||||
|
||||
private function getStartCommand(array $server_argv) {
|
||||
$launch_argv = array();
|
||||
|
||||
if ($this->debug) {
|
||||
$launch_argv[] = '--debug=1';
|
||||
}
|
||||
|
||||
return csprintf(
|
||||
'%R %Ls -- %s %Ls',
|
||||
'%R %Ls -- %s %Ls %Ls',
|
||||
$this->getNodeBinary(),
|
||||
$this->getNodeArgv(),
|
||||
$this->getAphlictScriptPath(),
|
||||
$launch_argv,
|
||||
$server_argv);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,14 @@ final class PhabricatorAuditEditor
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorAuditActionConstants::INLINE:
|
||||
$comment = $xaction->getComment();
|
||||
|
||||
$comment->setAttribute('editing', false);
|
||||
|
||||
PhabricatorVersionedDraft::purgeDrafts(
|
||||
$comment->getPHID(),
|
||||
$this->getActingAsPHID());
|
||||
return;
|
||||
case PhabricatorAuditTransaction::TYPE_COMMIT:
|
||||
return;
|
||||
}
|
||||
@@ -232,14 +240,22 @@ final class PhabricatorAuditEditor
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
$auditors_type = DiffusionCommitAuditorsTransaction::TRANSACTIONTYPE;
|
||||
|
||||
$xactions = parent::expandTransaction($object, $xaction);
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorAuditTransaction::TYPE_COMMIT:
|
||||
$request = $this->createAuditRequestTransactionFromCommitMessage(
|
||||
$phids = $this->getAuditRequestTransactionPHIDsFromCommitMessage(
|
||||
$object);
|
||||
if ($request) {
|
||||
$xactions[] = $request;
|
||||
$this->addUnmentionablePHIDs($request->getNewValue());
|
||||
if ($phids) {
|
||||
$xactions[] = $object->getApplicationTransactionTemplate()
|
||||
->setTransactionType($auditors_type)
|
||||
->setNewValue(
|
||||
array(
|
||||
'+' => array_fuse($phids),
|
||||
));
|
||||
$this->addUnmentionablePHIDs($phids);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -268,7 +284,7 @@ final class PhabricatorAuditEditor
|
||||
return $xactions;
|
||||
}
|
||||
|
||||
private function createAuditRequestTransactionFromCommitMessage(
|
||||
private function getAuditRequestTransactionPHIDsFromCommitMessage(
|
||||
PhabricatorRepositoryCommit $commit) {
|
||||
|
||||
$actor = $this->getActor();
|
||||
@@ -297,12 +313,7 @@ final class PhabricatorAuditEditor
|
||||
return array();
|
||||
}
|
||||
|
||||
return $commit->getApplicationTransactionTemplate()
|
||||
->setTransactionType(DiffusionCommitAuditorsTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(
|
||||
array(
|
||||
'+' => array_fuse($phids),
|
||||
));
|
||||
return $phids;
|
||||
}
|
||||
|
||||
protected function sortTransactions(array $xactions) {
|
||||
@@ -405,6 +416,31 @@ final class PhabricatorAuditEditor
|
||||
$phid_map[] = $reverted_phids;
|
||||
}
|
||||
|
||||
// See T13463. Copy "related task" edges from the associated revision, if
|
||||
// one exists.
|
||||
|
||||
$revision = DiffusionCommitRevisionQuery::loadRevisionForCommit(
|
||||
$actor,
|
||||
$object);
|
||||
if ($revision) {
|
||||
$task_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
|
||||
$revision->getPHID(),
|
||||
DifferentialRevisionHasTaskEdgeType::EDGECONST);
|
||||
$task_phids = array_fuse($task_phids);
|
||||
|
||||
if ($task_phids) {
|
||||
$related_edge = DiffusionCommitHasTaskEdgeType::EDGECONST;
|
||||
$result[] = id(new PhabricatorAuditTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $related_edge)
|
||||
->setNewValue(array('+' => $task_phids));
|
||||
}
|
||||
|
||||
// Mark these objects as unmentionable, since the explicit relationship
|
||||
// is stronger and any mentions are redundant.
|
||||
$phid_map[] = $task_phids;
|
||||
}
|
||||
|
||||
$phid_map = array_mergev($phid_map);
|
||||
$this->addUnmentionablePHIDs($phid_map);
|
||||
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorAuditInlineComment
|
||||
extends Phobject
|
||||
implements PhabricatorInlineCommentInterface {
|
||||
extends PhabricatorInlineComment {
|
||||
|
||||
private $proxy;
|
||||
private $syntheticAuthor;
|
||||
private $isGhost;
|
||||
|
||||
public function __construct() {
|
||||
$this->proxy = new PhabricatorAuditTransactionComment();
|
||||
protected function newStorageObject() {
|
||||
return new PhabricatorAuditTransactionComment();
|
||||
}
|
||||
|
||||
public function __clone() {
|
||||
$this->proxy = clone $this->proxy;
|
||||
}
|
||||
|
||||
public function getTransactionPHID() {
|
||||
return $this->proxy->getTransactionPHID();
|
||||
}
|
||||
|
||||
public function getTransactionComment() {
|
||||
return $this->proxy;
|
||||
public function getControllerURI() {
|
||||
return urisprintf(
|
||||
'/diffusion/inline/edit/%s/',
|
||||
$this->getCommitPHID());
|
||||
}
|
||||
|
||||
public function supportsHiding() {
|
||||
@@ -36,246 +25,40 @@ final class PhabricatorAuditInlineComment
|
||||
$content_source = PhabricatorContentSource::newForSource(
|
||||
PhabricatorOldWorldContentSource::SOURCECONST);
|
||||
|
||||
$this->proxy
|
||||
$this->getStorageObject()
|
||||
->setViewPolicy('public')
|
||||
->setEditPolicy($this->getAuthorPHID())
|
||||
->setContentSource($content_source)
|
||||
->setCommentVersion(1);
|
||||
|
||||
return $this->proxy;
|
||||
}
|
||||
|
||||
public static function loadID($id) {
|
||||
$inlines = id(new PhabricatorAuditTransactionComment())->loadAllWhere(
|
||||
'id = %d',
|
||||
$id);
|
||||
if (!$inlines) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return head(self::buildProxies($inlines));
|
||||
}
|
||||
|
||||
public static function loadPHID($phid) {
|
||||
$inlines = id(new PhabricatorAuditTransactionComment())->loadAllWhere(
|
||||
'phid = %s',
|
||||
$phid);
|
||||
if (!$inlines) {
|
||||
return null;
|
||||
}
|
||||
return head(self::buildProxies($inlines));
|
||||
}
|
||||
|
||||
public static function loadDraftComments(
|
||||
PhabricatorUser $viewer,
|
||||
$commit_phid,
|
||||
$raw = false) {
|
||||
|
||||
$inlines = id(new DiffusionDiffInlineCommentQuery())
|
||||
->setViewer($viewer)
|
||||
->withAuthorPHIDs(array($viewer->getPHID()))
|
||||
->withCommitPHIDs(array($commit_phid))
|
||||
->withHasTransaction(false)
|
||||
->withHasPath(true)
|
||||
->withIsDeleted(false)
|
||||
->needReplyToComments(true)
|
||||
->execute();
|
||||
|
||||
if ($raw) {
|
||||
return $inlines;
|
||||
}
|
||||
|
||||
return self::buildProxies($inlines);
|
||||
}
|
||||
|
||||
public static function loadPublishedComments(
|
||||
PhabricatorUser $viewer,
|
||||
$commit_phid) {
|
||||
|
||||
$inlines = id(new DiffusionDiffInlineCommentQuery())
|
||||
->setViewer($viewer)
|
||||
->withCommitPHIDs(array($commit_phid))
|
||||
->withHasTransaction(true)
|
||||
->withHasPath(true)
|
||||
->execute();
|
||||
|
||||
return self::buildProxies($inlines);
|
||||
}
|
||||
|
||||
public static function loadDraftAndPublishedComments(
|
||||
PhabricatorUser $viewer,
|
||||
$commit_phid,
|
||||
$path_id = null) {
|
||||
|
||||
if ($path_id === null) {
|
||||
$inlines = id(new PhabricatorAuditTransactionComment())->loadAllWhere(
|
||||
'commitPHID = %s AND (transactionPHID IS NOT NULL OR authorPHID = %s)
|
||||
AND pathID IS NOT NULL',
|
||||
$commit_phid,
|
||||
$viewer->getPHID());
|
||||
} else {
|
||||
$inlines = id(new PhabricatorAuditTransactionComment())->loadAllWhere(
|
||||
'commitPHID = %s AND pathID = %d AND
|
||||
((authorPHID = %s AND isDeleted = 0) OR transactionPHID IS NOT NULL)',
|
||||
$commit_phid,
|
||||
$path_id,
|
||||
$viewer->getPHID());
|
||||
}
|
||||
|
||||
return self::buildProxies($inlines);
|
||||
}
|
||||
|
||||
private static function buildProxies(array $inlines) {
|
||||
$results = array();
|
||||
foreach ($inlines as $key => $inline) {
|
||||
$results[$key] = self::newFromModernComment(
|
||||
$inline);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function setSyntheticAuthor($synthetic_author) {
|
||||
$this->syntheticAuthor = $synthetic_author;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSyntheticAuthor() {
|
||||
return $this->syntheticAuthor;
|
||||
}
|
||||
|
||||
public function openTransaction() {
|
||||
$this->proxy->openTransaction();
|
||||
}
|
||||
|
||||
public function saveTransaction() {
|
||||
$this->proxy->saveTransaction();
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$this->getTransactionCommentForSave()->save();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
$this->proxy->delete();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getID() {
|
||||
return $this->proxy->getID();
|
||||
}
|
||||
|
||||
public function getPHID() {
|
||||
return $this->proxy->getPHID();
|
||||
return $this->getStorageObject();
|
||||
}
|
||||
|
||||
public static function newFromModernComment(
|
||||
PhabricatorAuditTransactionComment $comment) {
|
||||
|
||||
$obj = new PhabricatorAuditInlineComment();
|
||||
$obj->proxy = $comment;
|
||||
$obj->setStorageObject($comment);
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
public function isCompatible(PhabricatorInlineCommentInterface $comment) {
|
||||
return
|
||||
($this->getAuthorPHID() === $comment->getAuthorPHID()) &&
|
||||
($this->getSyntheticAuthor() === $comment->getSyntheticAuthor()) &&
|
||||
($this->getContent() === $comment->getContent());
|
||||
}
|
||||
|
||||
public function setContent($content) {
|
||||
$this->proxy->setContent($content);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContent() {
|
||||
return $this->proxy->getContent();
|
||||
}
|
||||
|
||||
public function isDraft() {
|
||||
return !$this->proxy->getTransactionPHID();
|
||||
}
|
||||
|
||||
public function setPathID($id) {
|
||||
$this->proxy->setPathID($id);
|
||||
$this->getStorageObject()->setPathID($id);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPathID() {
|
||||
return $this->proxy->getPathID();
|
||||
}
|
||||
|
||||
public function setIsNewFile($is_new) {
|
||||
$this->proxy->setIsNewFile($is_new);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsNewFile() {
|
||||
return $this->proxy->getIsNewFile();
|
||||
}
|
||||
|
||||
public function setLineNumber($number) {
|
||||
$this->proxy->setLineNumber($number);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLineNumber() {
|
||||
return $this->proxy->getLineNumber();
|
||||
}
|
||||
|
||||
public function setLineLength($length) {
|
||||
$this->proxy->setLineLength($length);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLineLength() {
|
||||
return $this->proxy->getLineLength();
|
||||
}
|
||||
|
||||
public function setCache($cache) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setAuthorPHID($phid) {
|
||||
$this->proxy->setAuthorPHID($phid);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAuthorPHID() {
|
||||
return $this->proxy->getAuthorPHID();
|
||||
return $this->getStorageObject()->getPathID();
|
||||
}
|
||||
|
||||
public function setCommitPHID($commit_phid) {
|
||||
$this->proxy->setCommitPHID($commit_phid);
|
||||
$this->getStorageObject()->setCommitPHID($commit_phid);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCommitPHID() {
|
||||
return $this->proxy->getCommitPHID();
|
||||
}
|
||||
|
||||
// When setting a comment ID, we also generate a phantom transaction PHID for
|
||||
// the future transaction.
|
||||
|
||||
public function setAuditCommentID($id) {
|
||||
$this->proxy->setLegacyCommentID($id);
|
||||
$this->proxy->setTransactionPHID(
|
||||
PhabricatorPHID::generateNewPHID(
|
||||
PhabricatorApplicationTransactionTransactionPHIDType::TYPECONST,
|
||||
PhabricatorRepositoryCommitPHIDType::TYPECONST));
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAuditCommentID() {
|
||||
return $this->proxy->getLegacyCommentID();
|
||||
return $this->getStorageObject()->getCommitPHID();
|
||||
}
|
||||
|
||||
public function setChangesetID($id) {
|
||||
@@ -286,82 +69,4 @@ final class PhabricatorAuditInlineComment
|
||||
return $this->getPathID();
|
||||
}
|
||||
|
||||
public function setReplyToCommentPHID($phid) {
|
||||
$this->proxy->setReplyToCommentPHID($phid);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReplyToCommentPHID() {
|
||||
return $this->proxy->getReplyToCommentPHID();
|
||||
}
|
||||
|
||||
public function setHasReplies($has_replies) {
|
||||
$this->proxy->setHasReplies($has_replies);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHasReplies() {
|
||||
return $this->proxy->getHasReplies();
|
||||
}
|
||||
|
||||
public function setIsDeleted($is_deleted) {
|
||||
$this->proxy->setIsDeleted($is_deleted);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsDeleted() {
|
||||
return $this->proxy->getIsDeleted();
|
||||
}
|
||||
|
||||
public function setFixedState($state) {
|
||||
$this->proxy->setFixedState($state);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFixedState() {
|
||||
return $this->proxy->getFixedState();
|
||||
}
|
||||
|
||||
public function setIsGhost($is_ghost) {
|
||||
$this->isGhost = $is_ghost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsGhost() {
|
||||
return $this->isGhost;
|
||||
}
|
||||
|
||||
public function getDateModified() {
|
||||
return $this->proxy->getDateModified();
|
||||
}
|
||||
|
||||
public function getDateCreated() {
|
||||
return $this->proxy->getDateCreated();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */
|
||||
|
||||
|
||||
public function getMarkupFieldKey($field) {
|
||||
return 'AI:'.$this->getID();
|
||||
}
|
||||
|
||||
public function newMarkupEngine($field) {
|
||||
return PhabricatorMarkupEngine::newDifferentialMarkupEngine();
|
||||
}
|
||||
|
||||
public function getMarkupText($field) {
|
||||
return $this->getContent();
|
||||
}
|
||||
|
||||
public function didMarkupText($field, $output, PhutilMarkupEngine $engine) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function shouldUseMarkupCache($field) {
|
||||
// Only cache submitted comments.
|
||||
return ($this->getID() && $this->getAuditCommentID());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorAuditTransactionComment
|
||||
extends PhabricatorApplicationTransactionComment {
|
||||
extends PhabricatorApplicationTransactionComment
|
||||
implements
|
||||
PhabricatorInlineCommentInterface {
|
||||
|
||||
protected $commitPHID;
|
||||
protected $pathID;
|
||||
@@ -12,8 +14,10 @@ final class PhabricatorAuditTransactionComment
|
||||
protected $hasReplies = 0;
|
||||
protected $replyToCommentPHID;
|
||||
protected $legacyCommentID;
|
||||
protected $attributes = array();
|
||||
|
||||
private $replyToComment = self::ATTACHABLE;
|
||||
private $inlineContext = self::ATTACHABLE;
|
||||
|
||||
public function getApplicationTransactionObject() {
|
||||
return new PhabricatorAuditTransaction();
|
||||
@@ -54,6 +58,10 @@ final class PhabricatorAuditTransactionComment
|
||||
),
|
||||
) + $config[self::CONFIG_KEY_SCHEMA];
|
||||
|
||||
$config[self::CONFIG_SERIALIZATION] = array(
|
||||
'attributes' => self::SERIALIZATION_JSON,
|
||||
) + idx($config, self::CONFIG_SERIALIZATION, array());
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
@@ -67,4 +75,27 @@ final class PhabricatorAuditTransactionComment
|
||||
return $this->assertAttached($this->replyToComment);
|
||||
}
|
||||
|
||||
public function getAttribute($key, $default = null) {
|
||||
return idx($this->attributes, $key, $default);
|
||||
}
|
||||
|
||||
public function setAttribute($key, $value) {
|
||||
$this->attributes[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newInlineCommentObject() {
|
||||
return PhabricatorAuditInlineComment::newFromModernComment($this);
|
||||
}
|
||||
|
||||
public function getInlineContext() {
|
||||
return $this->assertAttached($this->inlineContext);
|
||||
}
|
||||
|
||||
public function attachInlineContext(
|
||||
PhabricatorInlineCommentContext $context = null) {
|
||||
$this->inlineContext = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* Abstract interface to an identity provider or authentication source, like
|
||||
* Twitter, Facebook or Google.
|
||||
* Twitter, Facebook, or Google.
|
||||
*
|
||||
* Generally, adapters are handed some set of credentials particular to the
|
||||
* provider they adapt, and they turn those credentials into standard
|
||||
@@ -17,13 +17,37 @@
|
||||
*/
|
||||
abstract class PhutilAuthAdapter extends Phobject {
|
||||
|
||||
final public function getAccountIdentifiers() {
|
||||
$result = $this->newAccountIdentifiers();
|
||||
assert_instances_of($result, 'PhabricatorExternalAccountIdentifier');
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function newAccountIdentifiers() {
|
||||
$identifiers = array();
|
||||
|
||||
$raw_identifier = $this->getAccountID();
|
||||
if ($raw_identifier !== null) {
|
||||
$identifiers[] = $this->newAccountIdentifier($raw_identifier);
|
||||
}
|
||||
|
||||
return $identifiers;
|
||||
}
|
||||
|
||||
final protected function newAccountIdentifier($raw_identifier) {
|
||||
return id(new PhabricatorExternalAccountIdentifier())
|
||||
->setIdentifierRaw($raw_identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a unique identifier associated with the identity. For most providers,
|
||||
* this is an account ID.
|
||||
* Get a unique identifier associated with the account.
|
||||
*
|
||||
* The account ID needs to be unique within this adapter's configuration, such
|
||||
* that `<adapterKey, accountID>` is globally unique and always identifies the
|
||||
* same identity.
|
||||
* This identifier should be permanent, immutable, and uniquely identify
|
||||
* the account. If possible, it should be nonsensitive. For providers that
|
||||
* have a GUID or PHID value for accounts, these are the best values to use.
|
||||
*
|
||||
* You can implement @{method:newAccountIdentifiers} instead if a provider
|
||||
* is unable to emit identifiers with all of these properties.
|
||||
*
|
||||
* If the adapter was unable to authenticate an identity, it should return
|
||||
* `null`.
|
||||
@@ -31,7 +55,9 @@ abstract class PhutilAuthAdapter extends Phobject {
|
||||
* @return string|null Unique account identifier, or `null` if authentication
|
||||
* failed.
|
||||
*/
|
||||
abstract public function getAccountID();
|
||||
public function getAccountID() {
|
||||
throw new PhutilMethodNotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,13 +51,17 @@ final class PhutilGitHubAuthAdapter extends PhutilOAuthAuthAdapter {
|
||||
|
||||
protected function loadOAuthAccountData() {
|
||||
$uri = new PhutilURI('https://api.github.com/user');
|
||||
$uri->replaceQueryParam('access_token', $this->getAccessToken());
|
||||
|
||||
$future = new HTTPSFuture($uri);
|
||||
|
||||
// NOTE: GitHub requires a User-Agent string.
|
||||
$future->addHeader('User-Agent', __CLASS__);
|
||||
|
||||
// See T13485. Circa early 2020, GitHub has deprecated use of the
|
||||
// "access_token" URI parameter.
|
||||
$token_header = sprintf('token %s', $this->getAccessToken());
|
||||
$future->addHeader('Authorization', $token_header);
|
||||
|
||||
list($body) = $future->resolvex();
|
||||
|
||||
try {
|
||||
|
||||
@@ -13,8 +13,23 @@ final class PhutilGoogleAuthAdapter extends PhutilOAuthAuthAdapter {
|
||||
return 'google.com';
|
||||
}
|
||||
|
||||
public function getAccountID() {
|
||||
return $this->getAccountEmail();
|
||||
protected function newAccountIdentifiers() {
|
||||
$identifiers = array();
|
||||
|
||||
$account_id = $this->getOAuthAccountData('id');
|
||||
if ($account_id !== null) {
|
||||
$account_id = sprintf(
|
||||
'id(%s)',
|
||||
$account_id);
|
||||
$identifiers[] = $this->newAccountIdentifier($account_id);
|
||||
}
|
||||
|
||||
$email = $this->getAccountEmail();
|
||||
if ($email !== null) {
|
||||
$identifiers[] = $this->newAccountIdentifier($email);
|
||||
}
|
||||
|
||||
return $identifiers;
|
||||
}
|
||||
|
||||
public function getAccountEmail() {
|
||||
|
||||
@@ -10,7 +10,6 @@ final class PhutilJIRAAuthAdapter extends PhutilOAuth1AuthAdapter {
|
||||
|
||||
private $jiraBaseURI;
|
||||
private $adapterDomain;
|
||||
private $currentSession;
|
||||
private $userInfo;
|
||||
|
||||
public function setJIRABaseURI($jira_base_uri) {
|
||||
@@ -22,12 +21,33 @@ final class PhutilJIRAAuthAdapter extends PhutilOAuth1AuthAdapter {
|
||||
return $this->jiraBaseURI;
|
||||
}
|
||||
|
||||
public function getAccountID() {
|
||||
protected function newAccountIdentifiers() {
|
||||
// Make sure the handshake is finished; this method is used for its
|
||||
// side effect by Auth providers.
|
||||
$this->getHandshakeData();
|
||||
|
||||
return idx($this->getUserInfo(), 'key');
|
||||
$info = $this->getUserInfo();
|
||||
|
||||
// See T13493. Older versions of JIRA provide a "key" with a username or
|
||||
// email address. Newer versions of JIRA provide a GUID "accountId".
|
||||
// Intermediate versions of JIRA provide both.
|
||||
|
||||
$identifiers = array();
|
||||
|
||||
$account_key = idx($info, 'key');
|
||||
if ($account_key !== null) {
|
||||
$identifiers[] = $this->newAccountIdentifier($account_key);
|
||||
}
|
||||
|
||||
$account_id = idx($info, 'accountId');
|
||||
if ($account_id !== null) {
|
||||
$identifiers[] = $this->newAccountIdentifier(
|
||||
sprintf(
|
||||
'accountId(%s)',
|
||||
$account_id));
|
||||
}
|
||||
|
||||
return $identifiers;
|
||||
}
|
||||
|
||||
public function getAccountName() {
|
||||
@@ -85,23 +105,36 @@ final class PhutilJIRAAuthAdapter extends PhutilOAuth1AuthAdapter {
|
||||
|
||||
private function getUserInfo() {
|
||||
if ($this->userInfo === null) {
|
||||
$this->currentSession = $this->newJIRAFuture('rest/auth/1/session', 'GET')
|
||||
->resolveJSON();
|
||||
|
||||
// The session call gives us the username, but not the user key or other
|
||||
// information. Make a second call to get additional information.
|
||||
|
||||
$params = array(
|
||||
'username' => $this->currentSession['name'],
|
||||
);
|
||||
|
||||
$this->userInfo = $this->newJIRAFuture('rest/api/2/user', 'GET', $params)
|
||||
->resolveJSON();
|
||||
$this->userInfo = $this->newUserInfo();
|
||||
}
|
||||
|
||||
return $this->userInfo;
|
||||
}
|
||||
|
||||
private function newUserInfo() {
|
||||
// See T13493. Try a relatively modern (circa early 2020) API call first.
|
||||
try {
|
||||
return $this->newJIRAFuture('rest/api/3/myself', 'GET')
|
||||
->resolveJSON();
|
||||
} catch (Exception $ex) {
|
||||
// If we failed the v3 call, assume the server version is too old
|
||||
// to support this API and fall back to trying the older method.
|
||||
}
|
||||
|
||||
$session = $this->newJIRAFuture('rest/auth/1/session', 'GET')
|
||||
->resolveJSON();
|
||||
|
||||
// The session call gives us the username, but not the user key or other
|
||||
// information. Make a second call to get additional information.
|
||||
|
||||
$params = array(
|
||||
'username' => $session['name'],
|
||||
);
|
||||
|
||||
return $this->newJIRAFuture('rest/api/2/user', 'GET', $params)
|
||||
->resolveJSON();
|
||||
}
|
||||
|
||||
public static function newJIRAKeypair() {
|
||||
$config = array(
|
||||
'digest_alg' => 'sha512',
|
||||
|
||||
@@ -156,7 +156,7 @@ abstract class PhutilOAuth1AuthAdapter extends PhutilAuthAdapter {
|
||||
$authorize_token_uri = new PhutilURI($this->getAuthorizeTokenURI());
|
||||
$authorize_token_uri->replaceQueryParam('oauth_token', $this->getToken());
|
||||
|
||||
return (string)$authorize_token_uri;
|
||||
return phutil_string_cast($authorize_token_uri);
|
||||
}
|
||||
|
||||
protected function finishOAuthHandshake() {
|
||||
|
||||
@@ -73,7 +73,7 @@ final class PhabricatorAuthApplication extends PhabricatorApplication {
|
||||
'session/downgrade/'
|
||||
=> 'PhabricatorAuthDowngradeSessionController',
|
||||
'enroll/' => array(
|
||||
'(?:(?P<pageKey>[^/]+)/)?(?:(?P<formSaved>saved)/)?'
|
||||
'(?:(?P<pageKey>[^/]+)/)?'
|
||||
=> 'PhabricatorAuthNeedsMultiFactorController',
|
||||
),
|
||||
'sshkey/' => array(
|
||||
|
||||
@@ -63,6 +63,13 @@ final class PhabricatorCookies extends Phobject {
|
||||
const COOKIE_INVITE = 'invite';
|
||||
|
||||
|
||||
/**
|
||||
* Stores a workflow completion across a redirect-after-POST following a
|
||||
* form submission. This can be used to show "Changes Saved" messages.
|
||||
*/
|
||||
const COOKIE_SUBMIT = 'phfrm';
|
||||
|
||||
|
||||
/* -( Client ID Cookie )--------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
@@ -197,22 +197,6 @@ abstract class PhabricatorAuthController extends PhabricatorController {
|
||||
return array($account, $provider, $response);
|
||||
}
|
||||
|
||||
$other_account = id(new PhabricatorExternalAccount())->loadAllWhere(
|
||||
'accountType = %s AND accountDomain = %s AND accountID = %s
|
||||
AND id != %d',
|
||||
$account->getAccountType(),
|
||||
$account->getAccountDomain(),
|
||||
$account->getAccountID(),
|
||||
$account->getID());
|
||||
|
||||
if ($other_account) {
|
||||
$response = $this->renderError(
|
||||
pht(
|
||||
'The account you are attempting to register with already belongs '.
|
||||
'to another user.'));
|
||||
return array($account, $provider, $response);
|
||||
}
|
||||
|
||||
$config = $account->getProviderConfig();
|
||||
if (!$config->getIsEnabled()) {
|
||||
$response = $this->renderError(
|
||||
|
||||
@@ -116,14 +116,21 @@ final class PhabricatorAuthLoginController
|
||||
}
|
||||
} else {
|
||||
|
||||
// If the user already has a linked account of this type, prevent them
|
||||
// from linking a second account. This can happen if they swap logins
|
||||
// and then refresh the account link. See T6707. We will eventually
|
||||
// allow this after T2549.
|
||||
// If the user already has a linked account on this provider, prevent
|
||||
// them from linking a second account. This can happen if they swap
|
||||
// logins and then refresh the account link.
|
||||
|
||||
// There's no technical reason we can't allow you to link multiple
|
||||
// accounts from a single provider; disallowing this is currently a
|
||||
// product deciison. See T2549.
|
||||
|
||||
$existing_accounts = id(new PhabricatorExternalAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withUserPHIDs(array($viewer->getPHID()))
|
||||
->withAccountTypes(array($account->getAccountType()))
|
||||
->withProviderConfigPHIDs(
|
||||
array(
|
||||
$provider->getProviderConfigPHID(),
|
||||
))
|
||||
->execute();
|
||||
if ($existing_accounts) {
|
||||
return $this->renderError(
|
||||
|
||||
@@ -346,6 +346,14 @@ final class PhabricatorAuthRegisterController
|
||||
}
|
||||
}
|
||||
|
||||
// blender hack
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require $root.'/migration/dedup.php';
|
||||
if (array_key_exists($request->getStr('username'), $migrate_dedup_users)) {
|
||||
$e_username = pht('Duplicate');
|
||||
$errors[] = pht('Username is already reserved.');
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
if (!$is_setup) {
|
||||
$image = $this->loadProfilePicture($account);
|
||||
@@ -457,7 +465,6 @@ final class PhabricatorAuthRegisterController
|
||||
|
||||
if (!$is_setup) {
|
||||
$account->setUserPHID($user->getPHID());
|
||||
$provider->willRegisterAccount($account);
|
||||
$account->save();
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ final class PhabricatorAuthUnlinkController
|
||||
->setWorkflowKey($workflow_key)
|
||||
->requireHighSecurityToken($viewer, $request, $done_uri);
|
||||
|
||||
$account->delete();
|
||||
$account->unlinkAccount();
|
||||
|
||||
id(new PhabricatorAuthSessionEngine())->terminateLoginSessions(
|
||||
$viewer,
|
||||
|
||||
@@ -56,9 +56,12 @@ final class PhabricatorAuthManagementLDAPWorkflow
|
||||
$console->writeOut("\n");
|
||||
$console->writeOut("%s\n", pht('Connecting to LDAP...'));
|
||||
|
||||
$account_id = $adapter->getAccountID();
|
||||
if ($account_id) {
|
||||
$console->writeOut("%s\n", pht('Found LDAP Account: %s', $account_id));
|
||||
$account_ids = $adapter->getAccountIdentifiers();
|
||||
if ($account_ids) {
|
||||
$value_list = mpull($account_ids, 'getIdentifierRaw');
|
||||
$value_list = implode(', ', $value_list);
|
||||
|
||||
$console->writeOut("%s\n", pht('Found LDAP Account: %s', $value_list));
|
||||
} else {
|
||||
$console->writeOut("%s\n", pht('Unable to find LDAP account!'));
|
||||
}
|
||||
|
||||
@@ -18,16 +18,6 @@ final class PhabricatorAuthManagementRefreshWorkflow
|
||||
'param' => 'user',
|
||||
'help' => pht('Refresh tokens for a given user.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'type',
|
||||
'param' => 'provider',
|
||||
'help' => pht('Refresh tokens for a given provider type.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'domain',
|
||||
'param' => 'domain',
|
||||
'help' => pht('Refresh tokens for a given domain.'),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -57,17 +47,6 @@ final class PhabricatorAuthManagementRefreshWorkflow
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$type = $args->getArg('type');
|
||||
if (strlen($type)) {
|
||||
$query->withAccountTypes(array($type));
|
||||
}
|
||||
|
||||
$domain = $args->getArg('domain');
|
||||
if (strlen($domain)) {
|
||||
$query->withAccountDomains(array($domain));
|
||||
}
|
||||
|
||||
$accounts = $query->execute();
|
||||
|
||||
if (!$accounts) {
|
||||
@@ -82,25 +61,24 @@ final class PhabricatorAuthManagementRefreshWorkflow
|
||||
}
|
||||
|
||||
$providers = PhabricatorAuthProvider::getAllEnabledProviders();
|
||||
$providers = mpull($providers, null, 'getProviderConfigPHID');
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$console->writeOut(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Refreshing account #%d (%s/%s).',
|
||||
$account->getID(),
|
||||
$account->getAccountType(),
|
||||
$account->getAccountDomain()));
|
||||
'Refreshing account #%d.',
|
||||
$account->getID()));
|
||||
|
||||
$key = $account->getProviderKey();
|
||||
if (empty($providers[$key])) {
|
||||
$config_phid = $account->getProviderConfigPHID();
|
||||
if (empty($providers[$config_phid])) {
|
||||
$console->writeOut(
|
||||
"> %s\n",
|
||||
pht('Skipping, provider is not enabled or does not exist.'));
|
||||
continue;
|
||||
}
|
||||
|
||||
$provider = $providers[$key];
|
||||
$provider = $providers[$config_phid];
|
||||
if (!($provider instanceof PhabricatorOAuth2AuthProvider)) {
|
||||
$console->writeOut(
|
||||
"> %s\n",
|
||||
|
||||
@@ -20,6 +20,10 @@ abstract class PhabricatorAuthProvider extends Phobject {
|
||||
return $this->providerConfig;
|
||||
}
|
||||
|
||||
public function getProviderConfigPHID() {
|
||||
return $this->getProviderConfig()->getPHID();
|
||||
}
|
||||
|
||||
public function getConfigurationHelp() {
|
||||
return null;
|
||||
}
|
||||
@@ -186,44 +190,86 @@ abstract class PhabricatorAuthProvider extends Phobject {
|
||||
return;
|
||||
}
|
||||
|
||||
public function willRegisterAccount(PhabricatorExternalAccount $account) {
|
||||
return;
|
||||
final protected function newExternalAccountForIdentifiers(
|
||||
array $identifiers) {
|
||||
|
||||
assert_instances_of($identifiers, 'PhabricatorExternalAccountIdentifier');
|
||||
|
||||
if (!$identifiers) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Authentication provider (of class "%s") is attempting to '.
|
||||
'load or create an external account, but provided no account '.
|
||||
'identifiers.',
|
||||
get_class($this)));
|
||||
}
|
||||
|
||||
$config = $this->getProviderConfig();
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
$raw_identifiers = mpull($identifiers, 'getIdentifierRaw');
|
||||
|
||||
$accounts = id(new PhabricatorExternalAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withProviderConfigPHIDs(array($config->getPHID()))
|
||||
->withRawAccountIdentifiers($raw_identifiers)
|
||||
->needAccountIdentifiers(true)
|
||||
->execute();
|
||||
if (!$accounts) {
|
||||
$account = $this->newExternalAccount();
|
||||
} else if (count($accounts) === 1) {
|
||||
$account = head($accounts);
|
||||
} else {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Authentication provider (of class "%s") is attempting to load '.
|
||||
'or create an external account, but provided a list of '.
|
||||
'account identifiers which map to more than one account: %s.',
|
||||
get_class($this),
|
||||
implode(', ', $raw_identifiers)));
|
||||
}
|
||||
|
||||
// See T13493. Add all the identifiers to the account. In the case where
|
||||
// an account initially has a lower-quality identifier (like an email
|
||||
// address) and later adds a higher-quality identifier (like a GUID), this
|
||||
// allows us to automatically upgrade toward the higher-quality identifier
|
||||
// and survive API changes which remove the lower-quality identifier more
|
||||
// gracefully.
|
||||
|
||||
foreach ($identifiers as $identifier) {
|
||||
$account->appendIdentifier($identifier);
|
||||
}
|
||||
|
||||
return $this->didUpdateAccount($account);
|
||||
}
|
||||
|
||||
protected function loadOrCreateAccount($account_id) {
|
||||
if (!strlen($account_id)) {
|
||||
throw new Exception(pht('Empty account ID!'));
|
||||
}
|
||||
final protected function newExternalAccountForUser(PhabricatorUser $user) {
|
||||
$config = $this->getProviderConfig();
|
||||
|
||||
$adapter = $this->getAdapter();
|
||||
$adapter_class = get_class($adapter);
|
||||
// When a user logs in with a provider like username/password, they
|
||||
// always already have a Phabricator account (since there's no way they
|
||||
// could have a username otherwise).
|
||||
|
||||
if (!strlen($adapter->getAdapterType())) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"AuthAdapter (of class '%s') has an invalid implementation: ".
|
||||
"no adapter type.",
|
||||
$adapter_class));
|
||||
}
|
||||
// These users should never go to registration, so we're building a
|
||||
// dummy "external account" which just links directly back to their
|
||||
// internal account.
|
||||
|
||||
if (!strlen($adapter->getAdapterDomain())) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"AuthAdapter (of class '%s') has an invalid implementation: ".
|
||||
"no adapter domain.",
|
||||
$adapter_class));
|
||||
}
|
||||
|
||||
$account = id(new PhabricatorExternalAccount())->loadOneWhere(
|
||||
'accountType = %s AND accountDomain = %s AND accountID = %s',
|
||||
$adapter->getAdapterType(),
|
||||
$adapter->getAdapterDomain(),
|
||||
$account_id);
|
||||
$account = id(new PhabricatorExternalAccountQuery())
|
||||
->setViewer($user)
|
||||
->withProviderConfigPHIDs(array($config->getPHID()))
|
||||
->withUserPHIDs(array($user->getPHID()))
|
||||
->executeOne();
|
||||
if (!$account) {
|
||||
$account = $this->newExternalAccount()
|
||||
->setAccountID($account_id);
|
||||
->setUserPHID($user->getPHID());
|
||||
}
|
||||
|
||||
return $this->didUpdateAccount($account);
|
||||
}
|
||||
|
||||
private function didUpdateAccount(PhabricatorExternalAccount $account) {
|
||||
$adapter = $this->getAdapter();
|
||||
|
||||
$account->setUsername($adapter->getAccountName());
|
||||
$account->setRealName($adapter->getAccountRealName());
|
||||
$account->setEmail($adapter->getAccountEmail());
|
||||
@@ -240,6 +286,7 @@ abstract class PhabricatorAuthProvider extends Phobject {
|
||||
// file entry for it, but there's no convenient way to do this with
|
||||
// PhabricatorFile right now. The storage will get shared, so the impact
|
||||
// here is negligible.
|
||||
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
$image_file = PhabricatorFile::newFromFileDownload(
|
||||
$image_uri,
|
||||
@@ -305,10 +352,23 @@ abstract class PhabricatorAuthProvider extends Phobject {
|
||||
$config = $this->getProviderConfig();
|
||||
$adapter = $this->getAdapter();
|
||||
|
||||
return id(new PhabricatorExternalAccount())
|
||||
$account = id(new PhabricatorExternalAccount())
|
||||
->setProviderConfigPHID($config->getPHID())
|
||||
->attachAccountIdentifiers(array());
|
||||
|
||||
// TODO: Remove this when these columns are removed. They no longer have
|
||||
// readers or writers (other than this callsite).
|
||||
|
||||
$account
|
||||
->setAccountType($adapter->getAdapterType())
|
||||
->setAccountDomain($adapter->getAdapterDomain())
|
||||
->setProviderConfigPHID($config->getPHID());
|
||||
->setAccountDomain($adapter->getAdapterDomain());
|
||||
|
||||
// TODO: Remove this when "accountID" is removed; the column is not
|
||||
// nullable.
|
||||
|
||||
$account->setAccountID('');
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
public function getLoginOrder() {
|
||||
|
||||
@@ -335,7 +335,7 @@ final class PhabricatorJIRAAuthProvider
|
||||
public function getDoorkeeperURIRef(PhutilURI $uri) {
|
||||
$uri_string = phutil_string_cast($uri);
|
||||
|
||||
$pattern = '((https?://\S+?)/browse/([A-Z]+-[1-9]\d*))';
|
||||
$pattern = '((https?://\S+?)/browse/([A-Z][A-Z0-9]*-[1-9]\d*))';
|
||||
$matches = null;
|
||||
if (!preg_match($pattern, $uri_string, $matches)) {
|
||||
return null;
|
||||
|
||||
@@ -164,7 +164,7 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider {
|
||||
// See T3351.
|
||||
|
||||
DarkConsoleErrorLogPluginAPI::enableDiscardMode();
|
||||
$account_id = $adapter->getAccountID();
|
||||
$identifiers = $adapter->getAccountIdentifiers();
|
||||
DarkConsoleErrorLogPluginAPI::disableDiscardMode();
|
||||
} else {
|
||||
throw new Exception(pht('Username and password are required!'));
|
||||
@@ -180,7 +180,9 @@ final class PhabricatorLDAPAuthProvider extends PhabricatorAuthProvider {
|
||||
}
|
||||
}
|
||||
|
||||
return array($this->loadOrCreateAccount($account_id), $response);
|
||||
$account = $this->newExternalAccountForIdentifiers($identifiers);
|
||||
|
||||
return array($account, $response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -100,13 +100,13 @@ abstract class PhabricatorOAuth1AuthProvider
|
||||
// an access token.
|
||||
|
||||
try {
|
||||
$account_id = $adapter->getAccountID();
|
||||
$identifiers = $adapter->getAccountIdentifiers();
|
||||
} catch (Exception $ex) {
|
||||
// TODO: Handle this in a more user-friendly way.
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
if (!strlen($account_id)) {
|
||||
if (!$identifiers) {
|
||||
$response = $controller->buildProviderErrorResponse(
|
||||
$this,
|
||||
pht(
|
||||
@@ -115,7 +115,9 @@ abstract class PhabricatorOAuth1AuthProvider
|
||||
return array($account, $response);
|
||||
}
|
||||
|
||||
return array($this->loadOrCreateAccount($account_id), $response);
|
||||
$account = $this->newExternalAccountForIdentifiers($identifiers);
|
||||
|
||||
return array($account, $response);
|
||||
}
|
||||
|
||||
public function processEditForm(
|
||||
|
||||
@@ -80,13 +80,13 @@ abstract class PhabricatorOAuth2AuthProvider
|
||||
// an access token.
|
||||
|
||||
try {
|
||||
$account_id = $adapter->getAccountID();
|
||||
$identifiers = $adapter->getAccountIdentifiers();
|
||||
} catch (Exception $ex) {
|
||||
// TODO: Handle this in a more user-friendly way.
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
if (!strlen($account_id)) {
|
||||
if (!$identifiers) {
|
||||
$response = $controller->buildProviderErrorResponse(
|
||||
$this,
|
||||
pht(
|
||||
@@ -95,7 +95,9 @@ abstract class PhabricatorOAuth2AuthProvider
|
||||
return array($account, $response);
|
||||
}
|
||||
|
||||
return array($this->loadOrCreateAccount($account_id), $response);
|
||||
$account = $this->newExternalAccountForIdentifiers($identifiers);
|
||||
|
||||
return array($account, $response);
|
||||
}
|
||||
|
||||
public function processEditForm(
|
||||
@@ -197,7 +199,7 @@ abstract class PhabricatorOAuth2AuthProvider
|
||||
PhabricatorExternalAccount $account,
|
||||
$force_refresh = false) {
|
||||
|
||||
if ($account->getProviderKey() !== $this->getProviderKey()) {
|
||||
if ($account->getProviderConfigPHID() !== $this->getProviderConfigPHID()) {
|
||||
throw new Exception(pht('Account does not match provider!'));
|
||||
}
|
||||
|
||||
|
||||
@@ -173,8 +173,8 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setSubmitURI($this->getLoginURI())
|
||||
->setUser($viewer)
|
||||
->setTitle(pht('Log In'))
|
||||
->addSubmitButton(pht('Log In'));
|
||||
->setTitle(pht('Login to developer.blender.org'))
|
||||
->addSubmitButton(pht('Login'));
|
||||
|
||||
if ($this->shouldAllowRegistration()) {
|
||||
$dialog->addCancelButton(
|
||||
@@ -182,6 +182,11 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
pht('Register New Account'));
|
||||
}
|
||||
|
||||
$webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/';
|
||||
$dialog->addFooter(
|
||||
phutil_safe_html(
|
||||
FileSystem::readFile($webroot .'rsrc/custom/static/login.html')));
|
||||
|
||||
$dialog->addFooter(
|
||||
phutil_tag(
|
||||
'a',
|
||||
@@ -217,6 +222,28 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
$errors[] = pht('Username or password are incorrect.');
|
||||
}
|
||||
|
||||
if (true) {
|
||||
// blender hack
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require $root.'/migration/dedup.php';
|
||||
|
||||
$missing_username = $request->getStr('username');
|
||||
|
||||
$find_user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'username = %s',
|
||||
$missing_username);
|
||||
|
||||
if (!$find_user && array_key_exists($missing_username, $migrate_dedup_users)) {
|
||||
$errors = array();
|
||||
$errors[] = pht('This account was merged into account "' .
|
||||
$migrate_dedup_users[$missing_username] .
|
||||
'", because Phabricator does not support multiple accounts with the same email address. ' .
|
||||
'Please login with that account instead ' .
|
||||
'(optionally recovering your password if you forgot it). ' .
|
||||
'After logging in you will be able to change your username in the User Settings.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
$errors = id(new PHUIInfoView())->setErrors($errors);
|
||||
}
|
||||
@@ -305,7 +332,7 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
->setObject($user);
|
||||
|
||||
if ($engine->isValidPassword($envelope)) {
|
||||
$account = $this->loadOrCreateAccount($user->getPHID());
|
||||
$account = $this->newExternalAccountForUser($user);
|
||||
$log_user = $user;
|
||||
}
|
||||
}
|
||||
@@ -339,16 +366,6 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function willSaveAccount(PhabricatorExternalAccount $account) {
|
||||
parent::willSaveAccount($account);
|
||||
$account->setUserPHID($account->getAccountID());
|
||||
}
|
||||
|
||||
public function willRegisterAccount(PhabricatorExternalAccount $account) {
|
||||
parent::willRegisterAccount($account);
|
||||
$account->setAccountID($account->getUserPHID());
|
||||
}
|
||||
|
||||
public static function getPasswordProvider() {
|
||||
$providers = self::getAllEnabledProviders();
|
||||
|
||||
@@ -375,4 +392,5 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
public function shouldAllowEmailTrustConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorExternalAccountIdentifierQuery
|
||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
private $ids;
|
||||
private $phids;
|
||||
private $providerConfigPHIDs;
|
||||
private $externalAccountPHIDs;
|
||||
private $rawIdentifiers;
|
||||
|
||||
public function withIDs($ids) {
|
||||
$this->ids = $ids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withPHIDs(array $phids) {
|
||||
$this->phids = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withProviderConfigPHIDs(array $phids) {
|
||||
$this->providerConfigPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withExternalAccountPHIDs(array $phids) {
|
||||
$this->externalAccountPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withRawIdentifiers(array $identifiers) {
|
||||
$this->rawIdentifiers = $identifiers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new PhabricatorExternalAccountIdentifier();
|
||||
}
|
||||
|
||||
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->providerConfigPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'providerConfigPHID IN (%Ls)',
|
||||
$this->providerConfigPHIDs);
|
||||
}
|
||||
|
||||
if ($this->externalAccountPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'externalAccountPHID IN (%Ls)',
|
||||
$this->externalAccountPHIDs);
|
||||
}
|
||||
|
||||
if ($this->rawIdentifiers !== null) {
|
||||
$hashes = array();
|
||||
foreach ($this->rawIdentifiers as $raw_identifier) {
|
||||
$hashes[] = PhabricatorHash::digestForIndex($raw_identifier);
|
||||
}
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'identifierHash IN (%Ls)',
|
||||
$hashes);
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
public function getQueryApplicationClass() {
|
||||
return 'PhabricatorPeopleApplication';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,34 +15,18 @@ final class PhabricatorExternalAccountQuery
|
||||
|
||||
private $ids;
|
||||
private $phids;
|
||||
private $accountTypes;
|
||||
private $accountDomains;
|
||||
private $accountIDs;
|
||||
private $userPHIDs;
|
||||
private $needImages;
|
||||
private $accountSecrets;
|
||||
private $providerConfigPHIDs;
|
||||
private $needAccountIdentifiers;
|
||||
private $rawAccountIdentifiers;
|
||||
|
||||
public function withUserPHIDs(array $user_phids) {
|
||||
$this->userPHIDs = $user_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withAccountIDs(array $account_ids) {
|
||||
$this->accountIDs = $account_ids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withAccountDomains(array $account_domains) {
|
||||
$this->accountDomains = $account_domains;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withAccountTypes(array $account_types) {
|
||||
$this->accountTypes = $account_types;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withPHIDs(array $phids) {
|
||||
$this->phids = $phids;
|
||||
return $this;
|
||||
@@ -63,11 +47,21 @@ final class PhabricatorExternalAccountQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function needAccountIdentifiers($need) {
|
||||
$this->needAccountIdentifiers = $need;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withProviderConfigPHIDs(array $phids) {
|
||||
$this->providerConfigPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withRawAccountIdentifiers(array $identifiers) {
|
||||
$this->rawAccountIdentifiers = $identifiers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new PhabricatorExternalAccount();
|
||||
}
|
||||
@@ -132,6 +126,23 @@ final class PhabricatorExternalAccountQuery
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->needAccountIdentifiers) {
|
||||
$account_phids = mpull($accounts, 'getPHID');
|
||||
|
||||
$identifiers = id(new PhabricatorExternalAccountIdentifierQuery())
|
||||
->setViewer($viewer)
|
||||
->setParentQuery($this)
|
||||
->withExternalAccountPHIDs($account_phids)
|
||||
->execute();
|
||||
|
||||
$identifiers = mgroup($identifiers, 'getExternalAccountPHID');
|
||||
foreach ($accounts as $account) {
|
||||
$account_phid = $account->getPHID();
|
||||
$account_identifiers = idx($identifiers, $account_phid, array());
|
||||
$account->attachAccountIdentifiers($account_identifiers);
|
||||
}
|
||||
}
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
@@ -141,62 +152,98 @@ final class PhabricatorExternalAccountQuery
|
||||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'id IN (%Ld)',
|
||||
'account.id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'phid IN (%Ls)',
|
||||
'account.phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->accountTypes !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'accountType IN (%Ls)',
|
||||
$this->accountTypes);
|
||||
}
|
||||
|
||||
if ($this->accountDomains !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'accountDomain IN (%Ls)',
|
||||
$this->accountDomains);
|
||||
}
|
||||
|
||||
if ($this->accountIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'accountID IN (%Ls)',
|
||||
$this->accountIDs);
|
||||
}
|
||||
|
||||
if ($this->userPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'userPHID IN (%Ls)',
|
||||
'account.userPHID IN (%Ls)',
|
||||
$this->userPHIDs);
|
||||
}
|
||||
|
||||
if ($this->accountSecrets !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'accountSecret IN (%Ls)',
|
||||
'account.accountSecret IN (%Ls)',
|
||||
$this->accountSecrets);
|
||||
}
|
||||
|
||||
if ($this->providerConfigPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'providerConfigPHID IN (%Ls)',
|
||||
'account.providerConfigPHID IN (%Ls)',
|
||||
$this->providerConfigPHIDs);
|
||||
|
||||
// If we have a list of ProviderConfig PHIDs and are joining the
|
||||
// identifiers table, also include the list as an additional constraint
|
||||
// on the identifiers table.
|
||||
|
||||
// This does not change the query results (an Account and its
|
||||
// Identifiers always have the same ProviderConfig PHID) but it allows
|
||||
// us to use keys on the Identifier table more efficiently.
|
||||
|
||||
if ($this->shouldJoinIdentifiersTable()) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'identifier.providerConfigPHID IN (%Ls)',
|
||||
$this->providerConfigPHIDs);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->rawAccountIdentifiers !== null) {
|
||||
$hashes = array();
|
||||
|
||||
foreach ($this->rawAccountIdentifiers as $raw_identifier) {
|
||||
$hashes[] = PhabricatorHash::digestForIndex($raw_identifier);
|
||||
}
|
||||
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'identifier.identifierHash IN (%Ls)',
|
||||
$hashes);
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$joins = parent::buildJoinClauseParts($conn);
|
||||
|
||||
if ($this->shouldJoinIdentifiersTable()) {
|
||||
$joins[] = qsprintf(
|
||||
$conn,
|
||||
'JOIN %R identifier ON account.phid = identifier.externalAccountPHID',
|
||||
new PhabricatorExternalAccountIdentifier());
|
||||
}
|
||||
|
||||
return $joins;
|
||||
}
|
||||
|
||||
protected function shouldJoinIdentifiersTable() {
|
||||
return ($this->rawAccountIdentifiers !== null);
|
||||
}
|
||||
|
||||
protected function shouldGroupQueryResultRows() {
|
||||
if ($this->shouldJoinIdentifiersTable()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::shouldGroupQueryResultRows();
|
||||
}
|
||||
|
||||
protected function getPrimaryTableAlias() {
|
||||
return 'account';
|
||||
}
|
||||
|
||||
public function getQueryApplicationClass() {
|
||||
return 'PhabricatorPeopleApplication';
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ final class PhabricatorAuthSSHPrivateKey extends Phobject {
|
||||
if (!$err) {
|
||||
if ($passphrase) {
|
||||
execx(
|
||||
'ssh-keygen -y -P %P -N %s -f %R',
|
||||
'ssh-keygen -p -P %P -N %s -f %R',
|
||||
$passphrase,
|
||||
'',
|
||||
$tmp);
|
||||
|
||||
@@ -125,7 +125,13 @@ final class PhabricatorAuthPassword
|
||||
$hash = $hasher->getPasswordHashForStorage($digest);
|
||||
$raw_hash = $hash->openEnvelope();
|
||||
|
||||
return $this->setPasswordHash($raw_hash);
|
||||
$result = $this->setPasswordHash($raw_hash);
|
||||
if ($result) {
|
||||
if ($object instanceof PhabricatorUser) {
|
||||
$object->updateHtaccessPassword($password);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function comparePassword(
|
||||
|
||||
@@ -4,7 +4,8 @@ final class PhabricatorAuthProviderConfig
|
||||
extends PhabricatorAuthDAO
|
||||
implements
|
||||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorPolicyInterface {
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $providerClass;
|
||||
protected $providerType;
|
||||
@@ -140,4 +141,33 @@ final class PhabricatorAuthProviderConfig
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
|
||||
$viewer = $engine->getViewer();
|
||||
$config_phid = $this->getPHID();
|
||||
|
||||
$accounts = id(new PhabricatorExternalAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withProviderConfigPHIDs(array($config_phid))
|
||||
->newIterator();
|
||||
foreach ($accounts as $account) {
|
||||
$engine->destroyObject($account);
|
||||
}
|
||||
|
||||
$identifiers = id(new PhabricatorExternalAccountIdentifierQuery())
|
||||
->setViewer($viewer)
|
||||
->withProviderConfigPHIDs(array($config_phid))
|
||||
->newIterator();
|
||||
foreach ($identifiers as $identifier) {
|
||||
$engine->destroyObject($identifier);
|
||||
}
|
||||
|
||||
$this->delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +37,6 @@ final class PhabricatorAuthAccountView extends AphrontView {
|
||||
$use_name = $username;
|
||||
} else if (strlen($realname)) {
|
||||
$use_name = $realname;
|
||||
} else {
|
||||
$use_name = $account->getAccountID();
|
||||
}
|
||||
|
||||
$content[] = phutil_tag(
|
||||
@@ -61,8 +59,6 @@ final class PhabricatorAuthAccountView extends AphrontView {
|
||||
),
|
||||
array(
|
||||
$prov_name,
|
||||
" \xC2\xB7 ",
|
||||
$account->getAccountID(),
|
||||
));
|
||||
|
||||
$account_uri = $account->getAccountURI();
|
||||
|
||||
@@ -849,8 +849,8 @@ final class PhutilICSParser extends Phobject {
|
||||
);
|
||||
|
||||
// Load the map of Windows timezones.
|
||||
$root_path = dirname(phutil_get_library_root('phutil'));
|
||||
$windows_path = $root_path.'/resources/timezones/windows_timezones.json';
|
||||
$root_path = dirname(phutil_get_library_root('phabricator'));
|
||||
$windows_path = $root_path.'/resources/timezones/windows-timezones.json';
|
||||
$windows_data = Filesystem::readFile($windows_path);
|
||||
$windows_zones = phutil_json_decode($windows_data);
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ final class CelerityDefaultPostprocessor
|
||||
'alphablack' => '0,0,0',
|
||||
|
||||
// Base Greys
|
||||
'thingreyborder' => '#dadee8',
|
||||
'lightgreyborder' => '#C7CCD9',
|
||||
'greyborder' => '#A1A6B0',
|
||||
'darkgreyborder' => '#676A70',
|
||||
@@ -207,6 +208,9 @@ final class CelerityDefaultPostprocessor
|
||||
// Usually light yellow
|
||||
'gentle.highlight' => '#fdf3da',
|
||||
'gentle.highlight.border' => '#c9b8a8',
|
||||
'gentle.highlight.background' => '#fffdf6',
|
||||
|
||||
'highlight.bright' => '#fdf320',
|
||||
|
||||
'paste.content' => '#fffef5',
|
||||
'paste.border' => '#e9dbcd',
|
||||
@@ -240,6 +244,9 @@ final class CelerityDefaultPostprocessor
|
||||
|
||||
'document.border' => '#dedee1',
|
||||
|
||||
'delete-color' => '#c0392b',
|
||||
'create-color' => '#139543',
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ final class CelerityRedGreenPostprocessor
|
||||
'new-bright' => 'rgba(152, 207, 235, .35)',
|
||||
'old-background' => 'rgba(250, 212, 175, .3)',
|
||||
'old-bright' => 'rgba(250, 212, 175, .55)',
|
||||
|
||||
'delete-color' => '#e67e22',
|
||||
'create-color' => '#2980b9',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -134,9 +134,17 @@ final class PhabricatorConduitAPIController
|
||||
$method_implementation);
|
||||
case 'json':
|
||||
default:
|
||||
return id(new AphrontJSONResponse())
|
||||
$response = id(new AphrontJSONResponse())
|
||||
->setAddJSONShield(false)
|
||||
->setContent($response->toDictionary());
|
||||
|
||||
$capabilities = $this->getConduitCapabilities();
|
||||
if ($capabilities) {
|
||||
$capabilities = implode(' ', $capabilities);
|
||||
$response->addHeader('X-Conduit-Capabilities', $capabilities);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,5 +724,14 @@ final class PhabricatorConduitAPIController
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getConduitCapabilities() {
|
||||
$capabilities = array();
|
||||
|
||||
if (AphrontRequestStream::supportsGzip()) {
|
||||
$capabilities[] = 'gzip';
|
||||
}
|
||||
|
||||
return $capabilities;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,12 @@ final class PhabricatorConduitCallManagementWorkflow
|
||||
'File to read parameters from, or "-" to read from '.
|
||||
'stdin.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'local',
|
||||
'help' => pht(
|
||||
'Force the request to execute in this process, rather than '.
|
||||
'proxying to another host in the cluster.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'as',
|
||||
'param' => 'username',
|
||||
@@ -75,9 +81,17 @@ final class PhabricatorConduitCallManagementWorkflow
|
||||
|
||||
$params = phutil_json_decode($input_json);
|
||||
|
||||
$result = id(new ConduitCall($method, $params))
|
||||
->setUser($actor)
|
||||
->execute();
|
||||
$call = id(new ConduitCall($method, $params))
|
||||
->setUser($actor);
|
||||
|
||||
$api_request = $call->getAPIRequest();
|
||||
|
||||
$is_local = $args->getArg('local');
|
||||
if ($is_local) {
|
||||
$api_request->setIsClusterRequest(true);
|
||||
}
|
||||
|
||||
$result = $call->execute();
|
||||
|
||||
$output = array(
|
||||
'result' => $result,
|
||||
|
||||
@@ -129,8 +129,9 @@ abstract class ConduitParameterType extends Phobject {
|
||||
'true' => true,
|
||||
);
|
||||
|
||||
if (!$strict && is_string($value) && isset($bool_strings[$value])) {
|
||||
$value = $bool_strings[$value];
|
||||
$normal_value = phutil_utf8_strtolower($value);
|
||||
if (!$strict && is_string($value) && isset($bool_strings[$normal_value])) {
|
||||
$value = $bool_strings[$normal_value];
|
||||
} else if (!is_bool($value)) {
|
||||
$this->raiseValidationException(
|
||||
$request,
|
||||
|
||||
@@ -37,13 +37,8 @@ final class PhabricatorConfigApplication extends PhabricatorApplication {
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/config/' => array(
|
||||
'' => 'PhabricatorConfigListController',
|
||||
'application/' => 'PhabricatorConfigApplicationController',
|
||||
'all/' => 'PhabricatorConfigAllController',
|
||||
'history/' => 'PhabricatorConfigHistoryController',
|
||||
'' => 'PhabricatorConfigConsoleController',
|
||||
'edit/(?P<key>[\w\.\-]+)/' => 'PhabricatorConfigEditController',
|
||||
'group/(?P<key>[^/]+)/' => 'PhabricatorConfigGroupController',
|
||||
'version/' => 'PhabricatorConfigVersionController',
|
||||
'database/'.
|
||||
'(?:(?P<ref>[^/]+)/'.
|
||||
'(?:(?P<database>[^/]+)/'.
|
||||
@@ -63,7 +58,7 @@ final class PhabricatorConfigApplication extends PhabricatorApplication {
|
||||
'purge/' => 'PhabricatorConfigPurgeCacheController',
|
||||
),
|
||||
'module/' => array(
|
||||
'(?P<module>[^/]+)/' => 'PhabricatorConfigModuleController',
|
||||
'(?:(?P<module>[^/]+)/)?' => 'PhabricatorConfigModuleController',
|
||||
),
|
||||
'cluster/' => array(
|
||||
'databases/' => 'PhabricatorConfigClusterDatabasesController',
|
||||
@@ -71,6 +66,12 @@ final class PhabricatorConfigApplication extends PhabricatorApplication {
|
||||
'repositories/' => 'PhabricatorConfigClusterRepositoriesController',
|
||||
'search/' => 'PhabricatorConfigClusterSearchController',
|
||||
),
|
||||
'settings/' => array(
|
||||
'' => 'PhabricatorConfigSettingsListController',
|
||||
'(?P<filter>advanced|all)/'
|
||||
=> 'PhabricatorConfigSettingsListController',
|
||||
'history/' => 'PhabricatorConfigSettingsHistoryController',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,20 +53,23 @@ final class PhabricatorAuthSetupCheck extends PhabricatorSetupCheck {
|
||||
"\n\n".
|
||||
'Leaving your authentication provider configuration unlocked '.
|
||||
'increases the damage that a compromised administrator account can '.
|
||||
'do to your install, by, for example, changing the authentication '.
|
||||
'provider to a server they control and intercepting usernames and '.
|
||||
'do to your install. For example, an attacker who compromises an '.
|
||||
'administrator account can change authentication providers to point '.
|
||||
'at a server they control and attempt to intercept usernames and '.
|
||||
'passwords.'.
|
||||
"\n\n".
|
||||
'To prevent this attack, you should configure your authentication '.
|
||||
'providers, and then lock the configuration by doing `%s` '.
|
||||
'from the command line. This will prevent changing the '.
|
||||
'authentication provider config without first doing `%s`.',
|
||||
'bin/auth lock',
|
||||
'bin/auth unlock');
|
||||
'To prevent this attack, you should configure authentication, and '.
|
||||
'then lock the configuration by running "bin/auth lock" from the '.
|
||||
'command line. This will prevent changing the authentication config '.
|
||||
'without first running "bin/auth unlock".');
|
||||
$this
|
||||
->newIssue('auth.config-unlocked')
|
||||
->setShortName(pht('Auth Config Unlocked'))
|
||||
->setName(pht('Authenticaton Provider Configuration Unlocked'))
|
||||
->setName(pht('Authenticaton Configuration Unlocked'))
|
||||
->setSummary(
|
||||
pht(
|
||||
'Authentication configuration is currently unlocked. Once you '.
|
||||
'finish configuring authentication, you should lock it.'))
|
||||
->setMessage($message)
|
||||
->addRelatedPhabricatorConfig('auth.lock-config')
|
||||
->addCommand(
|
||||
|
||||
@@ -48,10 +48,17 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck {
|
||||
|
||||
$expect_user = PhabricatorEnv::getEnvConfig('phd.user');
|
||||
if (strlen($expect_user)) {
|
||||
$all_daemons = id(new PhabricatorDaemonLogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||
->execute();
|
||||
|
||||
try {
|
||||
$all_daemons = id(new PhabricatorDaemonLogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||
->execute();
|
||||
} catch (Exception $ex) {
|
||||
// If this query fails for some reason, just skip this check.
|
||||
$all_daemons = array();
|
||||
}
|
||||
|
||||
foreach ($all_daemons as $daemon) {
|
||||
$actual_user = $daemon->getRunningAsUser();
|
||||
if ($actual_user == $expect_user) {
|
||||
|
||||
@@ -58,8 +58,7 @@ final class PhabricatorSecuritySetupCheck extends PhabricatorSetupCheck {
|
||||
->setName(pht('Alternate File Domain Not Configured'))
|
||||
->setSummary(
|
||||
pht(
|
||||
'Increase security (and improve performance) by configuring '.
|
||||
'a CDN or alternate file domain.'))
|
||||
'Improve security by configuring an alternate file domain.'))
|
||||
->setMessage(
|
||||
pht(
|
||||
'Phabricator is currently configured to serve user uploads '.
|
||||
|
||||