Show More
@@ -61,23 +61,6 b' self: super: {' | |||
|
61 | 61 | ]; |
|
62 | 62 | }); |
|
63 | 63 | |
|
64 | celery = super.celery.override (attrs: { | |
|
65 | # The current version of kombu needs some patching to work with the | |
|
66 | # other libs. Should be removed once we update celery and kombu. | |
|
67 | patches = [ | |
|
68 | ./patch-celery-dateutil.diff | |
|
69 | ]; | |
|
70 | }); | |
|
71 | ||
|
72 | kombu = super.kombu.override (attrs: { | |
|
73 | # The current version of kombu needs some patching to work with the | |
|
74 | # other libs. Should be removed once we update celery and kombu. | |
|
75 | patches = [ | |
|
76 | ./patch-kombu-py-2-7-11.diff | |
|
77 | ./patch-kombu-msgpack.diff | |
|
78 | ]; | |
|
79 | }); | |
|
80 | ||
|
81 | 64 | lxml = super.lxml.override (attrs: { |
|
82 | 65 | # johbo: On 16.09 we need this to compile on darwin, otherwise compilation |
|
83 | 66 | # fails on Darwin. |
@@ -133,10 +116,6 b' self: super: {' | |||
|
133 | 116 | }; |
|
134 | 117 | }); |
|
135 | 118 | |
|
136 | Pylons = super.Pylons.override (attrs: { | |
|
137 | name = "Pylons-1.0.2.rhodecode-patch1"; | |
|
138 | }); | |
|
139 | ||
|
140 | 119 | pyramid = super.pyramid.override (attrs: { |
|
141 | 120 | postFixup = '' |
|
142 | 121 | wrapPythonPrograms |
@@ -184,30 +184,17 b'' | |||
|
184 | 184 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
185 | 185 | }; |
|
186 | 186 | }; |
|
187 |
|
|
|
188 |
name = " |
|
|
187 | Routes = super.buildPythonPackage { | |
|
188 | name = "Routes-2.4.1"; | |
|
189 | 189 | buildInputs = with self; []; |
|
190 | 190 | doCheck = false; |
|
191 | propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; | |
|
191 | propagatedBuildInputs = with self; [six repoze.lru]; | |
|
192 | 192 | src = fetchurl { |
|
193 | url = "https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f"; | |
|
194 | md5 = "f26633726fa2cd3a340316ee6a5d218f"; | |
|
193 | url = "https://pypi.python.org/packages/33/38/ea827837e68d9c7dde4cff7ec122a93c319f0effc08ce92a17095576603f/Routes-2.4.1.tar.gz"; | |
|
194 | md5 = "c058dff6832941dec47e0d0052548ad8"; | |
|
195 | 195 | }; |
|
196 | 196 | meta = { |
|
197 |
license = [ pkgs.lib.licenses. |
|
|
198 | }; | |
|
199 | }; | |
|
200 | Routes = super.buildPythonPackage { | |
|
201 | name = "Routes-1.13"; | |
|
202 | buildInputs = with self; []; | |
|
203 | doCheck = false; | |
|
204 | propagatedBuildInputs = with self; [repoze.lru]; | |
|
205 | src = fetchurl { | |
|
206 | url = "https://pypi.python.org/packages/88/d3/259c3b3cde8837eb9441ab5f574a660e8a4acea8f54a078441d4d2acac1c/Routes-1.13.tar.gz"; | |
|
207 | md5 = "d527b0ab7dd9172b1275a41f97448783"; | |
|
208 | }; | |
|
209 | meta = { | |
|
210 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
|
197 | license = [ pkgs.lib.licenses.mit ]; | |
|
211 | 198 | }; |
|
212 | 199 | }; |
|
213 | 200 | SQLAlchemy = super.buildPythonPackage { |
@@ -340,6 +327,19 b'' | |||
|
340 | 327 | license = [ pkgs.lib.licenses.mit ]; |
|
341 | 328 | }; |
|
342 | 329 | }; |
|
330 | amqp = super.buildPythonPackage { | |
|
331 | name = "amqp-2.2.2"; | |
|
332 | buildInputs = with self; []; | |
|
333 | doCheck = false; | |
|
334 | propagatedBuildInputs = with self; [vine]; | |
|
335 | src = fetchurl { | |
|
336 | url = "https://pypi.python.org/packages/e0/70/9ab9ccd8247fb7d2adb717e9f6a0ed358c9e1ab2c349048b0352f9e80ee2/amqp-2.2.2.tar.gz"; | |
|
337 | md5 = "0971a3fd2d635ded45c349cfc17106bd"; | |
|
338 | }; | |
|
339 | meta = { | |
|
340 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
|
341 | }; | |
|
342 | }; | |
|
343 | 343 | amqplib = super.buildPythonPackage { |
|
344 | 344 | name = "amqplib-1.0.2"; |
|
345 | 345 | buildInputs = with self; []; |
@@ -353,19 +353,6 b'' | |||
|
353 | 353 | license = [ { fullName = "LGPL"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ]; |
|
354 | 354 | }; |
|
355 | 355 | }; |
|
356 | anyjson = super.buildPythonPackage { | |
|
357 | name = "anyjson-0.3.3"; | |
|
358 | buildInputs = with self; []; | |
|
359 | doCheck = false; | |
|
360 | propagatedBuildInputs = with self; []; | |
|
361 | src = fetchurl { | |
|
362 | url = "https://pypi.python.org/packages/c3/4d/d4089e1a3dd25b46bebdb55a992b0797cff657b4477bc32ce28038fdecbc/anyjson-0.3.3.tar.gz"; | |
|
363 | md5 = "2ea28d6ec311aeeebaf993cb3008b27c"; | |
|
364 | }; | |
|
365 | meta = { | |
|
366 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
|
367 | }; | |
|
368 | }; | |
|
369 | 356 | appenlight-client = super.buildPythonPackage { |
|
370 | 357 | name = "appenlight-client-0.6.22"; |
|
371 | 358 | buildInputs = with self; []; |
@@ -418,6 +405,19 b'' | |||
|
418 | 405 | license = [ pkgs.lib.licenses.mit ]; |
|
419 | 406 | }; |
|
420 | 407 | }; |
|
408 | billiard = super.buildPythonPackage { | |
|
409 | name = "billiard-3.5.0.3"; | |
|
410 | buildInputs = with self; []; | |
|
411 | doCheck = false; | |
|
412 | propagatedBuildInputs = with self; []; | |
|
413 | src = fetchurl { | |
|
414 | url = "https://pypi.python.org/packages/39/ac/f5571210cca2e4f4532e38aaff242f26c8654c5e2436bee966c230647ccc/billiard-3.5.0.3.tar.gz"; | |
|
415 | md5 = "113ba481e48400adbf6fbbf59a2f8554"; | |
|
416 | }; | |
|
417 | meta = { | |
|
418 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
|
419 | }; | |
|
420 | }; | |
|
421 | 421 | bleach = super.buildPythonPackage { |
|
422 | 422 | name = "bleach-1.5.0"; |
|
423 | 423 | buildInputs = with self; []; |
@@ -458,13 +458,13 b'' | |||
|
458 | 458 | }; |
|
459 | 459 | }; |
|
460 | 460 | celery = super.buildPythonPackage { |
|
461 |
name = "celery- |
|
|
461 | name = "celery-4.1.0"; | |
|
462 | 462 | buildInputs = with self; []; |
|
463 | 463 | doCheck = false; |
|
464 |
propagatedBuildInputs = with self; [pyt |
|
|
464 | propagatedBuildInputs = with self; [pytz billiard kombu]; | |
|
465 | 465 | src = fetchurl { |
|
466 |
url = "https://pypi.python.org/packages/ |
|
|
467 | md5 = "898bc87e54f278055b561316ba73e222"; | |
|
466 | url = "https://pypi.python.org/packages/07/65/88a2a45fc80f487872c93121a701a53bbbc3d3d832016876fac84fc8d46a/celery-4.1.0.tar.gz"; | |
|
467 | md5 = "db91e1d26936381127f01e150fe3054a"; | |
|
468 | 468 | }; |
|
469 | 469 | meta = { |
|
470 | 470 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1004,13 +1004,13 b'' | |||
|
1004 | 1004 | }; |
|
1005 | 1005 | }; |
|
1006 | 1006 | kombu = super.buildPythonPackage { |
|
1007 |
name = "kombu-1. |
|
|
1007 | name = "kombu-4.1.0"; | |
|
1008 | 1008 | buildInputs = with self; []; |
|
1009 | 1009 | doCheck = false; |
|
1010 |
propagatedBuildInputs = with self; [ |
|
|
1010 | propagatedBuildInputs = with self; [amqp]; | |
|
1011 | 1011 | src = fetchurl { |
|
1012 |
url = "https://pypi.python.org/packages/ |
|
|
1013 | md5 = "50662f3c7e9395b3d0721fb75d100b63"; | |
|
1012 | url = "https://pypi.python.org/packages/03/5e/1a47d1e543d4943d65330af4e4406049f443878818fb65bfdc651bb93a96/kombu-4.1.0.tar.gz"; | |
|
1013 | md5 = "2fb2be9fec0e6514231bba23a3779439"; | |
|
1014 | 1014 | }; |
|
1015 | 1015 | meta = { |
|
1016 | 1016 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1094,19 +1094,6 b'' | |||
|
1094 | 1094 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1095 | 1095 | }; |
|
1096 | 1096 | }; |
|
1097 | nose = super.buildPythonPackage { | |
|
1098 | name = "nose-1.3.6"; | |
|
1099 | buildInputs = with self; []; | |
|
1100 | doCheck = false; | |
|
1101 | propagatedBuildInputs = with self; []; | |
|
1102 | src = fetchurl { | |
|
1103 | url = "https://pypi.python.org/packages/70/c7/469e68148d17a0d3db5ed49150242fd70a74a8147b8f3f8b87776e028d99/nose-1.3.6.tar.gz"; | |
|
1104 | md5 = "0ca546d81ca8309080fc80cb389e7a16"; | |
|
1105 | }; | |
|
1106 | meta = { | |
|
1107 | license = [ { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "GNU LGPL"; } ]; | |
|
1108 | }; | |
|
1109 | }; | |
|
1110 | 1097 | objgraph = super.buildPythonPackage { |
|
1111 | 1098 | name = "objgraph-3.1.1"; |
|
1112 | 1099 | buildInputs = with self; []; |
@@ -1173,13 +1160,13 b'' | |||
|
1173 | 1160 | }; |
|
1174 | 1161 | }; |
|
1175 | 1162 | pexpect = super.buildPythonPackage { |
|
1176 |
name = "pexpect-4. |
|
|
1163 | name = "pexpect-4.3.0"; | |
|
1177 | 1164 | buildInputs = with self; []; |
|
1178 | 1165 | doCheck = false; |
|
1179 | 1166 | propagatedBuildInputs = with self; [ptyprocess]; |
|
1180 | 1167 | src = fetchurl { |
|
1181 | url = "https://pypi.python.org/packages/e8/13/d0b0599099d6cd23663043a2a0bb7c61e58c6ba359b2656e6fb000ef5b98/pexpect-4.2.1.tar.gz"; | |
|
1182 | md5 = "3694410001a99dff83f0b500a1ca1c95"; | |
|
1168 | url = "https://pypi.python.org/packages/f8/44/5466c30e49762bb92e442bbdf4472d6904608d211258eb3198a11f0309a4/pexpect-4.3.0.tar.gz"; | |
|
1169 | md5 = "047a486dcd26134b74f2e67046bb61a0"; | |
|
1183 | 1170 | }; |
|
1184 | 1171 | meta = { |
|
1185 | 1172 | license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ]; |
@@ -1550,16 +1537,16 b'' | |||
|
1550 | 1537 | }; |
|
1551 | 1538 | }; |
|
1552 | 1539 | python-dateutil = super.buildPythonPackage { |
|
1553 | name = "python-dateutil-2.1"; | |
|
1540 | name = "python-dateutil-2.6.1"; | |
|
1554 | 1541 | buildInputs = with self; []; |
|
1555 | 1542 | doCheck = false; |
|
1556 | 1543 | propagatedBuildInputs = with self; [six]; |
|
1557 | 1544 | src = fetchurl { |
|
1558 |
url = "https://pypi.python.org/packages/65 |
|
|
1559 | md5 = "1534bb15cf311f07afaa3aacba1c028b"; | |
|
1545 | url = "https://pypi.python.org/packages/54/bb/f1db86504f7a49e1d9b9301531181b00a1c7325dc85a29160ee3eaa73a54/python-dateutil-2.6.1.tar.gz"; | |
|
1546 | md5 = "db38f6b4511cefd76014745bb0cc45a4"; | |
|
1560 | 1547 | }; |
|
1561 | 1548 | meta = { |
|
1562 | license = [ { fullName = "Simplified BSD"; } ]; | |
|
1549 | license = [ pkgs.lib.licenses.bsdOriginal { fullName = "Simplified BSD"; } ]; | |
|
1563 | 1550 | }; |
|
1564 | 1551 | }; |
|
1565 | 1552 | python-editor = super.buildPythonPackage { |
@@ -1615,13 +1602,13 b'' | |||
|
1615 | 1602 | }; |
|
1616 | 1603 | }; |
|
1617 | 1604 | pytz = super.buildPythonPackage { |
|
1618 |
name = "pytz-201 |
|
|
1605 | name = "pytz-2017.3"; | |
|
1619 | 1606 | buildInputs = with self; []; |
|
1620 | 1607 | doCheck = false; |
|
1621 | 1608 | propagatedBuildInputs = with self; []; |
|
1622 | 1609 | src = fetchurl { |
|
1623 |
url = "https://pypi.python.org/packages/ |
|
|
1624 | md5 = "233f2a2b370d03f9b5911700cc9ebf3c"; | |
|
1610 | url = "https://pypi.python.org/packages/60/88/d3152c234da4b2a1f7a989f89609ea488225eaea015bc16fbde2b3fdfefa/pytz-2017.3.zip"; | |
|
1611 | md5 = "7006b56c0d68a162d9fe57d4249c3171"; | |
|
1625 | 1612 | }; |
|
1626 | 1613 | meta = { |
|
1627 | 1614 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1696,7 +1683,7 b'' | |||
|
1696 | 1683 | name = "rhodecode-enterprise-ce-4.11.0"; |
|
1697 | 1684 | buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj]; |
|
1698 | 1685 | doCheck = true; |
|
1699 | propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic cssselect celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu lxml msgpack-python nbconvert packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client redis repoze.lru requests simplejson sshpubkeys subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt]; | |
|
1686 | propagatedBuildInputs = with self; [setuptools-scm amqplib amqp authomatic Babel Beaker celery Chameleon channelstream click colander configobj cssselect decorator deform docutils dogpile.cache dogpile.core ecdsa FormEncode future futures gnureadline infrae.cache iso8601 itsdangerous Jinja2 billiard kombu lxml Mako Markdown MarkupSafe msgpack-python MySQL-python objgraph packaging Paste PasteDeploy PasteScript pathlib2 peppercorn psutil psycopg2 py-bcrypt pycrypto pycurl pyflakes pygments-markdown-lexer Pygments pyparsing pyramid-beaker pyramid-debugtoolbar pyramid-jinja2 pyramid-mako pyramid pysqlite python-dateutil python-ldap python-memcached python-pam pytz pyzmq py-gfm recaptcha-client redis repoze.lru requests Routes setproctitle simplejson six SQLAlchemy sshpubkeys subprocess32 Tempita translationstring trollius urllib3 URLObject venusian WebError WebHelpers2 WebHelpers WebOb Whoosh wsgiref zope.cachedescriptors zope.deprecation zope.event zope.interface nbconvert bleach nbformat jupyter-client alembic invoke bumpversion transifex-client gevent greenlet gunicorn waitress uWSGI ipdb ipython CProfileV bottle rhodecode-tools appenlight-client pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage]; | |
|
1700 | 1687 | src = ./.; |
|
1701 | 1688 | meta = { |
|
1702 | 1689 | license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ]; |
@@ -1755,13 +1742,13 b'' | |||
|
1755 | 1742 | }; |
|
1756 | 1743 | }; |
|
1757 | 1744 | setuptools-scm = super.buildPythonPackage { |
|
1758 |
name = "setuptools-scm-1.15. |
|
|
1745 | name = "setuptools-scm-1.15.6"; | |
|
1759 | 1746 | buildInputs = with self; []; |
|
1760 | 1747 | doCheck = false; |
|
1761 | 1748 | propagatedBuildInputs = with self; []; |
|
1762 | 1749 | src = fetchurl { |
|
1763 |
url = "https://pypi.python.org/packages/8 |
|
|
1764 | md5 = "b6916c78ed6253d6602444fad4279c5b"; | |
|
1750 | url = "https://pypi.python.org/packages/03/6d/aafdd01edd227ee879b691455bf19895091872af7e48192bea1758c82032/setuptools_scm-1.15.6.tar.gz"; | |
|
1751 | md5 = "f17493d53f0d842bb0152f214775640b"; | |
|
1765 | 1752 | }; |
|
1766 | 1753 | meta = { |
|
1767 | 1754 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1949,6 +1936,19 b'' | |||
|
1949 | 1936 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
1950 | 1937 | }; |
|
1951 | 1938 | }; |
|
1939 | vine = super.buildPythonPackage { | |
|
1940 | name = "vine-1.1.4"; | |
|
1941 | buildInputs = with self; []; | |
|
1942 | doCheck = false; | |
|
1943 | propagatedBuildInputs = with self; []; | |
|
1944 | src = fetchurl { | |
|
1945 | url = "https://pypi.python.org/packages/32/23/36284986e011f3c130d802c3c66abd8f1aef371eae110ddf80c5ae22e1ff/vine-1.1.4.tar.gz"; | |
|
1946 | md5 = "9fdb971e7fd15b181b84f3bfcf20d11c"; | |
|
1947 | }; | |
|
1948 | meta = { | |
|
1949 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
|
1950 | }; | |
|
1951 | }; | |
|
1952 | 1952 | waitress = super.buildPythonPackage { |
|
1953 | 1953 | name = "waitress-1.1.0"; |
|
1954 | 1954 | buildInputs = with self; []; |
@@ -1,13 +1,13 b'' | |||
|
1 | 1 | ## core |
|
2 | 2 | setuptools==30.1.0 |
|
3 |
setuptools-scm==1.15. |
|
|
3 | setuptools-scm==1.15.6 | |
|
4 | 4 | |
|
5 | 5 | amqplib==1.0.2 |
|
6 | anyjson==0.3.3 | |
|
6 | amqp==2.2.2 | |
|
7 | 7 | authomatic==0.1.0.post1 |
|
8 | 8 | Babel==1.3 |
|
9 | 9 | Beaker==1.9.0 |
|
10 |
celery== |
|
|
10 | celery==4.1.0 | |
|
11 | 11 | Chameleon==2.24 |
|
12 | 12 | channelstream==0.5.2 |
|
13 | 13 | click==6.6 |
@@ -28,7 +28,8 b' infrae.cache==1.0.1' | |||
|
28 | 28 | iso8601==0.1.12 |
|
29 | 29 | itsdangerous==0.24 |
|
30 | 30 | Jinja2==2.9.6 |
|
31 | kombu==1.5.1 | |
|
31 | billiard==3.5.0.3 | |
|
32 | kombu==4.1.0 | |
|
32 | 33 | lxml==3.7.3 |
|
33 | 34 | Mako==1.0.7 |
|
34 | 35 | Markdown==2.6.9 |
@@ -57,18 +58,18 b' pyramid-jinja2==2.7' | |||
|
57 | 58 | pyramid-mako==1.0.2 |
|
58 | 59 | pyramid==1.9.1 |
|
59 | 60 | pysqlite==2.8.3 |
|
60 |
python-dateutil |
|
|
61 | python-dateutil | |
|
61 | 62 | python-ldap==2.4.45 |
|
62 | 63 | python-memcached==1.58 |
|
63 | 64 | python-pam==1.8.2 |
|
64 |
pytz==201 |
|
|
65 | pytz==2017.3 | |
|
65 | 66 | pyzmq==14.6.0 |
|
66 | 67 | py-gfm==0.1.3 |
|
67 | 68 | recaptcha-client==1.0.6 |
|
68 | 69 | redis==2.10.6 |
|
69 | 70 | repoze.lru==0.7 |
|
70 | 71 | requests==2.9.1 |
|
71 |
Routes== |
|
|
72 | Routes==2.4.1 | |
|
72 | 73 | setproctitle==1.1.10 |
|
73 | 74 | simplejson==3.11.1 |
|
74 | 75 | six==1.11.0 |
@@ -92,10 +93,6 b' zope.deprecation==4.1.2' | |||
|
92 | 93 | zope.event==4.0.3 |
|
93 | 94 | zope.interface==4.1.3 |
|
94 | 95 | |
|
95 | ## customized/patched libs | |
|
96 | # our patched version of Pylons==1.0.2 | |
|
97 | https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f#egg=Pylons==1.0.2.rhodecode-patch-1 | |
|
98 | ||
|
99 | 96 | |
|
100 | 97 | # IPYTHON RENDERING |
|
101 | 98 | # entrypoints backport, pypi version doesn't support egg installs |
@@ -27,7 +27,7 b' from rhodecode.tests import TEST_USER_AD' | |||
|
27 | 27 | |
|
28 | 28 | |
|
29 | 29 | @pytest.fixture(scope="class") |
|
30 |
def testuser_api(request, |
|
|
30 | def testuser_api(request, baseapp): | |
|
31 | 31 | cls = request.cls |
|
32 | 32 | |
|
33 | 33 | # ADMIN USER |
@@ -159,32 +159,14 b' class BaseAppView(object):' | |||
|
159 | 159 | |
|
160 | 160 | return c |
|
161 | 161 | |
|
162 |
def _ |
|
|
163 | """ | |
|
164 | Registers attributes to pylons global `c` | |
|
165 | """ | |
|
166 | ||
|
167 | # TODO(marcink): remove once pyramid migration is finished | |
|
168 | from pylons import tmpl_context as c | |
|
169 | try: | |
|
170 | for k, v in tmpl_args.items(): | |
|
171 | setattr(c, k, v) | |
|
172 | except TypeError: | |
|
173 | log.exception('Failed to register pylons C') | |
|
174 | pass | |
|
175 | ||
|
176 | def _get_template_context(self, tmpl_args): | |
|
177 | self._register_global_c(tmpl_args) | |
|
162 | def _get_template_context(self, tmpl_args, **kwargs): | |
|
178 | 163 | |
|
179 | 164 | local_tmpl_args = { |
|
180 | 165 | 'defaults': {}, |
|
181 | 166 | 'errors': {}, |
|
182 | # register a fake 'c' to be used in templates instead of global | |
|
183 | # pylons c, after migration to pyramid we should rename it to 'c' | |
|
184 | # make sure we replace usage of _c in templates too | |
|
185 | '_c': tmpl_args | |
|
167 | 'c': tmpl_args | |
|
186 | 168 | } |
|
187 |
local_tmpl_args.update( |
|
|
169 | local_tmpl_args.update(kwargs) | |
|
188 | 170 | return local_tmpl_args |
|
189 | 171 | |
|
190 | 172 | def load_default_context(self): |
@@ -194,7 +176,7 b' class BaseAppView(object):' | |||
|
194 | 176 | def load_default_context(self): |
|
195 | 177 | c = self._get_local_tmpl_context() |
|
196 | 178 | c.custom_var = 'foobar' |
|
197 | self._register_global_c(c) | |
|
179 | ||
|
198 | 180 | return c |
|
199 | 181 | """ |
|
200 | 182 | raise NotImplementedError('Needs implementation in view class') |
@@ -213,7 +195,7 b' class RepoAppView(BaseAppView):' | |||
|
213 | 195 | 'Requirements are missing for repository %s: %s', |
|
214 | 196 | self.db_repo_name, error.message) |
|
215 | 197 | |
|
216 |
def _get_local_tmpl_context(self, include_app_defaults= |
|
|
198 | def _get_local_tmpl_context(self, include_app_defaults=True): | |
|
217 | 199 | _ = self.request.translate |
|
218 | 200 | c = super(RepoAppView, self)._get_local_tmpl_context( |
|
219 | 201 | include_app_defaults=include_app_defaults) |
@@ -336,7 +318,7 b' class BaseReferencesView(RepoAppView):' | |||
|
336 | 318 | def load_default_context(self): |
|
337 | 319 | c = self._get_local_tmpl_context() |
|
338 | 320 | |
|
339 | self._register_global_c(c) | |
|
321 | ||
|
340 | 322 | return c |
|
341 | 323 | |
|
342 | 324 | def load_refs_context(self, ref_items, partials_template): |
@@ -25,7 +25,6 b' import collections' | |||
|
25 | 25 | from zope.interface import implementer |
|
26 | 26 | |
|
27 | 27 | from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry |
|
28 | from rhodecode.lib.utils import get_registry | |
|
29 | 28 | from rhodecode.lib.utils2 import str2bool |
|
30 | 29 | from rhodecode.translation import _ |
|
31 | 30 | |
@@ -116,7 +115,7 b' def navigation_registry(request, registr' | |||
|
116 | 115 | """ |
|
117 | 116 | Helper that returns the admin navigation registry. |
|
118 | 117 | """ |
|
119 |
pyramid_registry = registry or |
|
|
118 | pyramid_registry = registry or request.registry | |
|
120 | 119 | nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry) |
|
121 | 120 | return nav_registry |
|
122 | 121 |
@@ -46,10 +46,11 b' def route_path(name, params=None, **kwar' | |||
|
46 | 46 | return base_url |
|
47 | 47 | |
|
48 | 48 | |
|
49 | class TestAdminController(TestController): | |
|
49 | @pytest.mark.usefixtures('app') | |
|
50 | class TestAdminController(object): | |
|
50 | 51 | |
|
51 | 52 | @pytest.fixture(scope='class', autouse=True) |
|
52 |
def prepare(self, request, |
|
|
53 | def prepare(self, request, baseapp): | |
|
53 | 54 | UserLog.query().delete() |
|
54 | 55 | Session().commit() |
|
55 | 56 | |
@@ -84,104 +85,87 b' class TestAdminController(TestController' | |||
|
84 | 85 | UserLog.query().delete() |
|
85 | 86 | Session().commit() |
|
86 | 87 | |
|
87 | def test_index(self): | |
|
88 | self.log_user() | |
|
88 | def test_index(self, autologin_user): | |
|
89 | 89 | response = self.app.get(route_path('admin_audit_logs')) |
|
90 | 90 | response.mustcontain('Admin audit logs') |
|
91 | 91 | |
|
92 | def test_filter_all_entries(self): | |
|
93 | self.log_user() | |
|
92 | def test_filter_all_entries(self, autologin_user): | |
|
94 | 93 | response = self.app.get(route_path('admin_audit_logs')) |
|
95 | 94 | all_count = UserLog.query().count() |
|
96 | 95 | response.mustcontain('%s entries' % all_count) |
|
97 | 96 | |
|
98 | def test_filter_journal_filter_exact_match_on_repository(self): | |
|
99 | self.log_user() | |
|
97 | def test_filter_journal_filter_exact_match_on_repository(self, autologin_user): | |
|
100 | 98 | response = self.app.get(route_path('admin_audit_logs', |
|
101 | 99 | params=dict(filter='repository:rhodecode'))) |
|
102 | 100 | response.mustcontain('3 entries') |
|
103 | 101 | |
|
104 | def test_filter_journal_filter_exact_match_on_repository_CamelCase(self): | |
|
105 | self.log_user() | |
|
102 | def test_filter_journal_filter_exact_match_on_repository_CamelCase(self, autologin_user): | |
|
106 | 103 | response = self.app.get(route_path('admin_audit_logs', |
|
107 | 104 | params=dict(filter='repository:RhodeCode'))) |
|
108 | 105 | response.mustcontain('3 entries') |
|
109 | 106 | |
|
110 | def test_filter_journal_filter_wildcard_on_repository(self): | |
|
111 | self.log_user() | |
|
107 | def test_filter_journal_filter_wildcard_on_repository(self, autologin_user): | |
|
112 | 108 | response = self.app.get(route_path('admin_audit_logs', |
|
113 | 109 | params=dict(filter='repository:*test*'))) |
|
114 | 110 | response.mustcontain('862 entries') |
|
115 | 111 | |
|
116 | def test_filter_journal_filter_prefix_on_repository(self): | |
|
117 | self.log_user() | |
|
112 | def test_filter_journal_filter_prefix_on_repository(self, autologin_user): | |
|
118 | 113 | response = self.app.get(route_path('admin_audit_logs', |
|
119 | 114 | params=dict(filter='repository:test*'))) |
|
120 | 115 | response.mustcontain('257 entries') |
|
121 | 116 | |
|
122 | def test_filter_journal_filter_prefix_on_repository_CamelCase(self): | |
|
123 | self.log_user() | |
|
117 | def test_filter_journal_filter_prefix_on_repository_CamelCase(self, autologin_user): | |
|
124 | 118 | response = self.app.get(route_path('admin_audit_logs', |
|
125 | 119 | params=dict(filter='repository:Test*'))) |
|
126 | 120 | response.mustcontain('257 entries') |
|
127 | 121 | |
|
128 | def test_filter_journal_filter_prefix_on_repository_and_user(self): | |
|
129 | self.log_user() | |
|
122 | def test_filter_journal_filter_prefix_on_repository_and_user(self, autologin_user): | |
|
130 | 123 | response = self.app.get(route_path('admin_audit_logs', |
|
131 | 124 | params=dict(filter='repository:test* AND username:demo'))) |
|
132 | 125 | response.mustcontain('130 entries') |
|
133 | 126 | |
|
134 | def test_filter_journal_filter_prefix_on_repository_or_target_repo(self): | |
|
135 | self.log_user() | |
|
127 | def test_filter_journal_filter_prefix_on_repository_or_target_repo(self, autologin_user): | |
|
136 | 128 | response = self.app.get(route_path('admin_audit_logs', |
|
137 | 129 | params=dict(filter='repository:test* OR repository:rhodecode'))) |
|
138 | 130 | response.mustcontain('260 entries') # 257 + 3 |
|
139 | 131 | |
|
140 | def test_filter_journal_filter_exact_match_on_username(self): | |
|
141 | self.log_user() | |
|
132 | def test_filter_journal_filter_exact_match_on_username(self, autologin_user): | |
|
142 | 133 | response = self.app.get(route_path('admin_audit_logs', |
|
143 | 134 | params=dict(filter='username:demo'))) |
|
144 | 135 | response.mustcontain('1087 entries') |
|
145 | 136 | |
|
146 | def test_filter_journal_filter_exact_match_on_username_camelCase(self): | |
|
147 | self.log_user() | |
|
137 | def test_filter_journal_filter_exact_match_on_username_camelCase(self, autologin_user): | |
|
148 | 138 | response = self.app.get(route_path('admin_audit_logs', |
|
149 | 139 | params=dict(filter='username:DemO'))) |
|
150 | 140 | response.mustcontain('1087 entries') |
|
151 | 141 | |
|
152 | def test_filter_journal_filter_wildcard_on_username(self): | |
|
153 | self.log_user() | |
|
142 | def test_filter_journal_filter_wildcard_on_username(self, autologin_user): | |
|
154 | 143 | response = self.app.get(route_path('admin_audit_logs', |
|
155 | 144 | params=dict(filter='username:*test*'))) |
|
156 | 145 | entries_count = UserLog.query().filter(UserLog.username.ilike('%test%')).count() |
|
157 | 146 | response.mustcontain('{} entries'.format(entries_count)) |
|
158 | 147 | |
|
159 | def test_filter_journal_filter_prefix_on_username(self): | |
|
160 | self.log_user() | |
|
148 | def test_filter_journal_filter_prefix_on_username(self, autologin_user): | |
|
161 | 149 | response = self.app.get(route_path('admin_audit_logs', |
|
162 | 150 | params=dict(filter='username:demo*'))) |
|
163 | 151 | response.mustcontain('1101 entries') |
|
164 | 152 | |
|
165 | def test_filter_journal_filter_prefix_on_user_or_other_user(self): | |
|
166 | self.log_user() | |
|
153 | def test_filter_journal_filter_prefix_on_user_or_other_user(self, autologin_user): | |
|
167 | 154 | response = self.app.get(route_path('admin_audit_logs', |
|
168 | 155 | params=dict(filter='username:demo OR username:volcan'))) |
|
169 | 156 | response.mustcontain('1095 entries') # 1087 + 8 |
|
170 | 157 | |
|
171 | def test_filter_journal_filter_wildcard_on_action(self): | |
|
172 | self.log_user() | |
|
158 | def test_filter_journal_filter_wildcard_on_action(self, autologin_user): | |
|
173 | 159 | response = self.app.get(route_path('admin_audit_logs', |
|
174 | 160 | params=dict(filter='action:*pull_request*'))) |
|
175 | 161 | response.mustcontain('187 entries') |
|
176 | 162 | |
|
177 | def test_filter_journal_filter_on_date(self): | |
|
178 | self.log_user() | |
|
163 | def test_filter_journal_filter_on_date(self, autologin_user): | |
|
179 | 164 | response = self.app.get(route_path('admin_audit_logs', |
|
180 | 165 | params=dict(filter='date:20121010'))) |
|
181 | 166 | response.mustcontain('47 entries') |
|
182 | 167 | |
|
183 | def test_filter_journal_filter_on_date_2(self): | |
|
184 | self.log_user() | |
|
168 | def test_filter_journal_filter_on_date_2(self, autologin_user): | |
|
185 | 169 | response = self.app.get(route_path('admin_audit_logs', |
|
186 | 170 | params=dict(filter='date:20121020'))) |
|
187 | 171 | response.mustcontain('17 entries') |
@@ -429,7 +429,7 b' class TestAdminSettingsVcs(object):' | |||
|
429 | 429 | # TODO: johbo: What we really want is to checkpoint before a test run and |
|
430 | 430 | # reset the session afterwards. |
|
431 | 431 | @pytest.fixture(scope='class', autouse=True) |
|
432 |
def cleanup_settings(self, request, |
|
|
432 | def cleanup_settings(self, request, baseapp): | |
|
433 | 433 | ui_id = RhodeCodeUi.ui_id |
|
434 | 434 | original_ids = list( |
|
435 | 435 | r.ui_id for r in RhodeCodeUi.query().values(ui_id)) |
@@ -23,7 +23,6 b' from sqlalchemy.orm.exc import NoResultF' | |||
|
23 | 23 | |
|
24 | 24 | from rhodecode.lib import auth |
|
25 | 25 | from rhodecode.lib import helpers as h |
|
26 | from rhodecode.model import validators | |
|
27 | 26 | from rhodecode.model.db import User, UserApiKeys, UserEmailMap, Repository |
|
28 | 27 | from rhodecode.model.meta import Session |
|
29 | 28 | from rhodecode.model.user import UserModel |
@@ -386,8 +385,7 b' class TestAdminUsersView(TestController)' | |||
|
386 | 385 | 'csrf_token': self.csrf_token, |
|
387 | 386 | }) |
|
388 | 387 | |
|
389 | msg = validators.ValidUsername( | |
|
390 | False, {})._messages['system_invalid_username'] | |
|
388 | msg = '???' | |
|
391 | 389 | msg = h.html_escape(msg % {'username': 'new_user'}) |
|
392 | 390 | response.mustcontain('<span class="error-message">%s</span>' % msg) |
|
393 | 391 | response.mustcontain( |
@@ -36,7 +36,6 b' log = logging.getLogger(__name__)' | |||
|
36 | 36 | class AdminAuditLogsView(BaseAppView): |
|
37 | 37 | def load_default_context(self): |
|
38 | 38 | c = self._get_local_tmpl_context() |
|
39 | self._register_global_c(c) | |
|
40 | 39 | return c |
|
41 | 40 | |
|
42 | 41 | @LoginRequired() |
@@ -44,7 +44,7 b' class AdminDefaultSettingsView(BaseAppVi' | |||
|
44 | 44 | def load_default_context(self): |
|
45 | 45 | c = self._get_local_tmpl_context() |
|
46 | 46 | |
|
47 | self._register_global_c(c) | |
|
47 | ||
|
48 | 48 | return c |
|
49 | 49 | |
|
50 | 50 | @LoginRequired() |
@@ -79,7 +79,7 b' class AdminDefaultSettingsView(BaseAppVi' | |||
|
79 | 79 | _ = self.request.translate |
|
80 | 80 | c = self.load_default_context() |
|
81 | 81 | c.active = 'repositories' |
|
82 | form = DefaultsForm()() | |
|
82 | form = DefaultsForm(self.request.translate)() | |
|
83 | 83 | |
|
84 | 84 | try: |
|
85 | 85 | form_result = form.to_python(dict(self.request.POST)) |
@@ -35,7 +35,7 b' class OpenSourceLicensesAdminSettingsVie' | |||
|
35 | 35 | |
|
36 | 36 | def load_default_context(self): |
|
37 | 37 | c = self._get_local_tmpl_context() |
|
38 | self._register_global_c(c) | |
|
38 | ||
|
39 | 39 | return c |
|
40 | 40 | |
|
41 | 41 | @LoginRequired() |
@@ -54,7 +54,7 b' class AdminPermissionsView(BaseAppView, ' | |||
|
54 | 54 | def load_default_context(self): |
|
55 | 55 | c = self._get_local_tmpl_context() |
|
56 | 56 | |
|
57 | self._register_global_c(c) | |
|
57 | ||
|
58 | 58 | PermissionModel().set_global_permission_choices( |
|
59 | 59 | c, gettext_translator=self.request.translate) |
|
60 | 60 | return c |
@@ -100,6 +100,7 b' class AdminPermissionsView(BaseAppView, ' | |||
|
100 | 100 | c.active = 'application' |
|
101 | 101 | |
|
102 | 102 | _form = ApplicationPermissionsForm( |
|
103 | self.request.translate, | |
|
103 | 104 | [x[0] for x in c.register_choices], |
|
104 | 105 | [x[0] for x in c.password_reset_choices], |
|
105 | 106 | [x[0] for x in c.extern_activate_choices])() |
@@ -180,6 +181,7 b' class AdminPermissionsView(BaseAppView, ' | |||
|
180 | 181 | c.active = 'objects' |
|
181 | 182 | |
|
182 | 183 | _form = ObjectPermissionsForm( |
|
184 | self.request.translate, | |
|
183 | 185 | [x[0] for x in c.repo_perms_choices], |
|
184 | 186 | [x[0] for x in c.group_perms_choices], |
|
185 | 187 | [x[0] for x in c.user_group_perms_choices])() |
@@ -251,6 +253,7 b' class AdminPermissionsView(BaseAppView, ' | |||
|
251 | 253 | c.active = 'global' |
|
252 | 254 | |
|
253 | 255 | _form = UserPermissionsForm( |
|
256 | self.request.translate, | |
|
254 | 257 | [x[0] for x in c.repo_create_choices], |
|
255 | 258 | [x[0] for x in c.repo_create_on_write_choices], |
|
256 | 259 | [x[0] for x in c.repo_group_create_choices], |
@@ -395,6 +398,7 b' class AdminPermissionsView(BaseAppView, ' | |||
|
395 | 398 | renderer='json_ext', xhr=True) |
|
396 | 399 | def ssh_keys_data(self): |
|
397 | 400 | _ = self.request.translate |
|
401 | self.load_default_context() | |
|
398 | 402 | column_map = { |
|
399 | 403 | 'fingerprint': 'ssh_key_fingerprint', |
|
400 | 404 | 'username': User.username |
@@ -35,7 +35,7 b' log = logging.getLogger(__name__)' | |||
|
35 | 35 | class AdminProcessManagementView(BaseAppView): |
|
36 | 36 | def load_default_context(self): |
|
37 | 37 | c = self._get_local_tmpl_context() |
|
38 | self._register_global_c(c) | |
|
38 | ||
|
39 | 39 | return c |
|
40 | 40 | |
|
41 | 41 | @LoginRequired() |
@@ -47,7 +47,7 b' class AdminRepoGroupsView(BaseAppView, D' | |||
|
47 | 47 | |
|
48 | 48 | def load_default_context(self): |
|
49 | 49 | c = self._get_local_tmpl_context() |
|
50 | self._register_global_c(c) | |
|
50 | ||
|
51 | 51 | return c |
|
52 | 52 | |
|
53 | 53 | def _load_form_data(self, c): |
@@ -150,8 +150,9 b' class AdminRepoGroupsView(BaseAppView, D' | |||
|
150 | 150 | # permissions for can create group based on parent_id are checked |
|
151 | 151 | # here in the Form |
|
152 | 152 | available_groups = map(lambda k: safe_unicode(k[0]), c.repo_groups) |
|
153 |
repo_group_form = RepoGroupForm( |
|
|
154 | can_create_in_root=can_create)() | |
|
153 | repo_group_form = RepoGroupForm( | |
|
154 | self.request.translate, available_groups=available_groups, | |
|
155 | can_create_in_root=can_create)() | |
|
155 | 156 | |
|
156 | 157 | repo_group_name = self.request.POST.get('group_name') |
|
157 | 158 | try: |
@@ -49,7 +49,7 b' class AdminReposView(BaseAppView, DataGr' | |||
|
49 | 49 | |
|
50 | 50 | def load_default_context(self): |
|
51 | 51 | c = self._get_local_tmpl_context() |
|
52 | self._register_global_c(c) | |
|
52 | ||
|
53 | 53 | return c |
|
54 | 54 | |
|
55 | 55 | def _load_form_data(self, c): |
@@ -148,9 +148,10 b' class AdminReposView(BaseAppView, DataGr' | |||
|
148 | 148 | |
|
149 | 149 | try: |
|
150 | 150 | # CanWriteToGroup validators checks permissions of this POST |
|
151 | form_result = RepoForm(repo_groups=c.repo_groups_choices, | |
|
152 | landing_revs=c.landing_revs_choices)()\ | |
|
153 | .to_python(dict(self.request.POST)) | |
|
151 | form = RepoForm( | |
|
152 | self.request.translate, repo_groups=c.repo_groups_choices, | |
|
153 | landing_revs=c.landing_revs_choices)() | |
|
154 | form_results = form.to_python(dict(self.request.POST)) | |
|
154 | 155 | |
|
155 | 156 | # create is done sometimes async on celery, db transaction |
|
156 | 157 | # management is handled there. |
@@ -39,7 +39,7 b' class AdminSessionSettingsView(BaseAppVi' | |||
|
39 | 39 | def load_default_context(self): |
|
40 | 40 | c = self._get_local_tmpl_context() |
|
41 | 41 | |
|
42 | self._register_global_c(c) | |
|
42 | ||
|
43 | 43 | return c |
|
44 | 44 | |
|
45 | 45 | @LoginRequired() |
@@ -67,7 +67,7 b' class AdminSettingsView(BaseAppView):' | |||
|
67 | 67 | c.labs_active = str2bool( |
|
68 | 68 | rhodecode.CONFIG.get('labs_settings_active', 'true')) |
|
69 | 69 | c.navlist = navigation_list(self.request) |
|
70 | self._register_global_c(c) | |
|
70 | ||
|
71 | 71 | return c |
|
72 | 72 | |
|
73 | 73 | @classmethod |
@@ -153,7 +153,7 b' class AdminSettingsView(BaseAppView):' | |||
|
153 | 153 | settings = self.request.registry.settings |
|
154 | 154 | c.svn_proxy_generate_config = settings[generate_config] |
|
155 | 155 | |
|
156 | application_form = ApplicationUiSettingsForm()() | |
|
156 | application_form = ApplicationUiSettingsForm(self.request.translate)() | |
|
157 | 157 | |
|
158 | 158 | try: |
|
159 | 159 | form_result = application_form.to_python(dict(self.request.POST)) |
@@ -310,7 +310,7 b' class AdminSettingsView(BaseAppView):' | |||
|
310 | 310 | c.active = 'global' |
|
311 | 311 | c.personal_repo_group_default_pattern = RepoGroupModel()\ |
|
312 | 312 | .get_personal_group_name_pattern() |
|
313 | application_form = ApplicationSettingsForm()() | |
|
313 | application_form = ApplicationSettingsForm(self.request.translate)() | |
|
314 | 314 | try: |
|
315 | 315 | form_result = application_form.to_python(dict(self.request.POST)) |
|
316 | 316 | except formencode.Invalid as errors: |
@@ -382,7 +382,7 b' class AdminSettingsView(BaseAppView):' | |||
|
382 | 382 | _ = self.request.translate |
|
383 | 383 | c = self.load_default_context() |
|
384 | 384 | c.active = 'visual' |
|
385 | application_form = ApplicationVisualisationForm()() | |
|
385 | application_form = ApplicationVisualisationForm(self.request.translate)() | |
|
386 | 386 | try: |
|
387 | 387 | form_result = application_form.to_python(dict(self.request.POST)) |
|
388 | 388 | except formencode.Invalid as errors: |
@@ -482,7 +482,7 b' class AdminSettingsView(BaseAppView):' | |||
|
482 | 482 | settings_model = IssueTrackerSettingsModel() |
|
483 | 483 | |
|
484 | 484 | try: |
|
485 | form = IssueTrackerPatternsForm()().to_python(self.request.POST) | |
|
485 | form = IssueTrackerPatternsForm(self.request.translate)().to_python(self.request.POST) | |
|
486 | 486 | except formencode.Invalid as errors: |
|
487 | 487 | log.exception('Failed to add new pattern') |
|
488 | 488 | error = errors |
@@ -698,7 +698,7 b' class AdminSettingsView(BaseAppView):' | |||
|
698 | 698 | c = self.load_default_context() |
|
699 | 699 | c.active = 'labs' |
|
700 | 700 | |
|
701 | application_form = LabsSettingsForm()() | |
|
701 | application_form = LabsSettingsForm(self.request.translate)() | |
|
702 | 702 | try: |
|
703 | 703 | form_result = application_form.to_python(dict(self.request.POST)) |
|
704 | 704 | except formencode.Invalid as errors: |
@@ -40,7 +40,7 b' log = logging.getLogger(__name__)' | |||
|
40 | 40 | class AdminSystemInfoSettingsView(BaseAppView): |
|
41 | 41 | def load_default_context(self): |
|
42 | 42 | c = self._get_local_tmpl_context() |
|
43 | self._register_global_c(c) | |
|
43 | ||
|
44 | 44 | return c |
|
45 | 45 | |
|
46 | 46 | @staticmethod |
@@ -53,7 +53,7 b' class AdminUserGroupsView(BaseAppView, D' | |||
|
53 | 53 | PermissionModel().set_global_permission_choices( |
|
54 | 54 | c, gettext_translator=self.request.translate) |
|
55 | 55 | |
|
56 | self._register_global_c(c) | |
|
56 | ||
|
57 | 57 | return c |
|
58 | 58 | |
|
59 | 59 | # permission check in data loading of |
@@ -196,7 +196,7 b' class AdminUserGroupsView(BaseAppView, D' | |||
|
196 | 196 | def user_groups_create(self): |
|
197 | 197 | _ = self.request.translate |
|
198 | 198 | c = self.load_default_context() |
|
199 | users_group_form = UserGroupForm()() | |
|
199 | users_group_form = UserGroupForm(self.request.translate)() | |
|
200 | 200 | |
|
201 | 201 | user_group_name = self.request.POST.get('users_group_name') |
|
202 | 202 | try: |
@@ -44,7 +44,8 b' from rhodecode.lib import helpers as h' | |||
|
44 | 44 | from rhodecode.lib.utils2 import safe_int, safe_unicode, AttributeDict |
|
45 | 45 | from rhodecode.model.auth_token import AuthTokenModel |
|
46 | 46 | from rhodecode.model.forms import ( |
|
47 |
UserForm, UserIndividualPermissionsForm, UserPermissionsForm |
|
|
47 | UserForm, UserIndividualPermissionsForm, UserPermissionsForm, | |
|
48 | UserExtraEmailForm, UserExtraIpForm) | |
|
48 | 49 | from rhodecode.model.permission import PermissionModel |
|
49 | 50 | from rhodecode.model.repo_group import RepoGroupModel |
|
50 | 51 | from rhodecode.model.ssh_key import SshKeyModel |
@@ -62,7 +63,6 b' class AdminUsersView(BaseAppView, DataGr' | |||
|
62 | 63 | |
|
63 | 64 | def load_default_context(self): |
|
64 | 65 | c = self._get_local_tmpl_context() |
|
65 | self._register_global_c(c) | |
|
66 | 66 | return c |
|
67 | 67 | |
|
68 | 68 | @LoginRequired() |
@@ -191,7 +191,7 b' class AdminUsersView(BaseAppView, DataGr' | |||
|
191 | 191 | c = self.load_default_context() |
|
192 | 192 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name |
|
193 | 193 | user_model = UserModel() |
|
194 | user_form = UserForm()() | |
|
194 | user_form = UserForm(self.request.translate)() | |
|
195 | 195 | try: |
|
196 | 196 | form_result = user_form.to_python(dict(self.request.POST)) |
|
197 | 197 | user = user_model.create(form_result) |
@@ -259,7 +259,7 b' class UsersView(UserAppView):' | |||
|
259 | 259 | PermissionModel().set_global_permission_choices( |
|
260 | 260 | c, gettext_translator=req.translate) |
|
261 | 261 | |
|
262 | self._register_global_c(c) | |
|
262 | ||
|
263 | 263 | return c |
|
264 | 264 | |
|
265 | 265 | @LoginRequired() |
@@ -280,7 +280,8 b' class UsersView(UserAppView):' | |||
|
280 | 280 | c.extern_name = c.user.extern_name |
|
281 | 281 | c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) |
|
282 | 282 | available_languages = [x[0] for x in c.allowed_languages] |
|
283 | _form = UserForm(edit=True, available_languages=available_languages, | |
|
283 | _form = UserForm(self.request.translate, edit=True, | |
|
284 | available_languages=available_languages, | |
|
284 | 285 | old_data={'user_id': user_id, |
|
285 | 286 | 'email': c.user.email})() |
|
286 | 287 | form_result = {} |
@@ -538,7 +539,7 b' class UsersView(UserAppView):' | |||
|
538 | 539 | c.active = 'global_perms' |
|
539 | 540 | try: |
|
540 | 541 | # first stage that verifies the checkbox |
|
541 | _form = UserIndividualPermissionsForm() | |
|
542 | _form = UserIndividualPermissionsForm(self.request.translate) | |
|
542 | 543 | form_result = _form.to_python(dict(self.request.POST)) |
|
543 | 544 | inherit_perms = form_result['inherit_default_permissions'] |
|
544 | 545 | c.user.inherit_default_permissions = inherit_perms |
@@ -547,6 +548,7 b' class UsersView(UserAppView):' | |||
|
547 | 548 | if not inherit_perms: |
|
548 | 549 | # only update the individual ones if we un check the flag |
|
549 | 550 | _form = UserPermissionsForm( |
|
551 | self.request.translate, | |
|
550 | 552 | [x[0] for x in c.repo_create_choices], |
|
551 | 553 | [x[0] for x in c.repo_create_on_write_choices], |
|
552 | 554 | [x[0] for x in c.repo_group_create_choices], |
@@ -914,6 +916,11 b' class UsersView(UserAppView):' | |||
|
914 | 916 | email = self.request.POST.get('new_email') |
|
915 | 917 | user_data = c.user.get_api_data() |
|
916 | 918 | try: |
|
919 | ||
|
920 | form = UserExtraEmailForm(self.request.translate)() | |
|
921 | data = form.to_python({'email': email}) | |
|
922 | email = data['email'] | |
|
923 | ||
|
917 | 924 | UserModel().add_extra_email(c.user.user_id, email) |
|
918 | 925 | audit_logger.store_web( |
|
919 | 926 | 'user.edit.email.add', |
@@ -1009,6 +1016,10 b' class UsersView(UserAppView):' | |||
|
1009 | 1016 | user_data = c.user.get_api_data() |
|
1010 | 1017 | for ip in ip_list: |
|
1011 | 1018 | try: |
|
1019 | form = UserExtraIpForm(self.request.translate)() | |
|
1020 | data = form.to_python({'ip': ip}) | |
|
1021 | ip = data['ip'] | |
|
1022 | ||
|
1012 | 1023 | user_model.add_extra_ip(c.user.user_id, ip, desc) |
|
1013 | 1024 | audit_logger.store_web( |
|
1014 | 1025 | 'user.edit.ip.add', |
@@ -24,6 +24,7 b' import uuid' | |||
|
24 | 24 | from pyramid.view import view_config |
|
25 | 25 | from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPBadGateway |
|
26 | 26 | |
|
27 | from rhodecode.apps._base import BaseAppView | |
|
27 | 28 | from rhodecode.lib.channelstream import ( |
|
28 | 29 | channelstream_request, |
|
29 | 30 | ChannelstreamConnectionException, |
@@ -34,28 +35,28 b' from rhodecode.lib.channelstream import ' | |||
|
34 | 35 | parse_channels_info, |
|
35 | 36 | update_history_from_logs, |
|
36 | 37 | STATE_PUBLIC_KEYS) |
|
38 | ||
|
37 | 39 | from rhodecode.lib.auth import NotAnonymous |
|
38 | 40 | |
|
39 | 41 | log = logging.getLogger(__name__) |
|
40 | 42 | |
|
41 | 43 | |
|
42 |
class ChannelstreamView( |
|
|
43 | def __init__(self, context, request): | |
|
44 | self.context = context | |
|
45 | self.request = request | |
|
44 | class ChannelstreamView(BaseAppView): | |
|
46 | 45 | |
|
47 | # Some of the decorators rely on this attribute to be present | |
|
48 | # on the class of the decorated method. | |
|
49 | self._rhodecode_user = request.user | |
|
50 | registry = request.registry | |
|
51 | self.channelstream_config = registry.rhodecode_plugins['channelstream'] | |
|
46 | def load_default_context(self): | |
|
47 | c = self._get_local_tmpl_context() | |
|
48 | self.channelstream_config = \ | |
|
49 | self.request.registry.rhodecode_plugins['channelstream'] | |
|
52 | 50 | if not self.channelstream_config.get('enabled'): |
|
53 | 51 | log.error('Channelstream plugin is disabled') |
|
54 | 52 | raise HTTPBadRequest() |
|
55 | 53 | |
|
54 | return c | |
|
55 | ||
|
56 | 56 | @NotAnonymous() |
|
57 | @view_config(route_name='channelstream_connect', renderer='json') | |
|
57 | @view_config(route_name='channelstream_connect', renderer='json_ext') | |
|
58 | 58 | def connect(self): |
|
59 | self.load_default_context() | |
|
59 | 60 | """ handle authorization of users trying to connect """ |
|
60 | 61 | try: |
|
61 | 62 | json_body = self.request.json_body |
@@ -122,9 +123,10 b' class ChannelstreamView(object):' | |||
|
122 | 123 | return connect_result |
|
123 | 124 | |
|
124 | 125 | @NotAnonymous() |
|
125 | @view_config(route_name='channelstream_subscribe', renderer='json') | |
|
126 | @view_config(route_name='channelstream_subscribe', renderer='json_ext') | |
|
126 | 127 | def subscribe(self): |
|
127 | 128 | """ can be used to subscribe specific connection to other channels """ |
|
129 | self.load_default_context() | |
|
128 | 130 | try: |
|
129 | 131 | json_body = self.request.json_body |
|
130 | 132 | except Exception: |
@@ -31,7 +31,7 b' log = logging.getLogger(__name__)' | |||
|
31 | 31 | class DebugStyleView(BaseAppView): |
|
32 | 32 | def load_default_context(self): |
|
33 | 33 | c = self._get_local_tmpl_context() |
|
34 | self._register_global_c(c) | |
|
34 | ||
|
35 | 35 | return c |
|
36 | 36 | |
|
37 | 37 | @view_config( |
@@ -67,7 +67,7 b' class GistView(BaseAppView):' | |||
|
67 | 67 | (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users")) |
|
68 | 68 | ] |
|
69 | 69 | |
|
70 | self._register_global_c(c) | |
|
70 | ||
|
71 | 71 | return c |
|
72 | 72 | |
|
73 | 73 | @LoginRequired() |
@@ -66,7 +66,7 b' class TestGotoSwitcherData(TestControlle' | |||
|
66 | 66 | ] |
|
67 | 67 | |
|
68 | 68 | @pytest.fixture(autouse=True, scope='class') |
|
69 |
def prepare(self, request, |
|
|
69 | def prepare(self, request, baseapp): | |
|
70 | 70 | for repo_and_group in self.required_repos_with_groups: |
|
71 | 71 | # create structure of groups and return the last group |
|
72 | 72 |
@@ -46,7 +46,7 b' class HomeView(BaseAppView):' | |||
|
46 | 46 | def load_default_context(self): |
|
47 | 47 | c = self._get_local_tmpl_context() |
|
48 | 48 | c.user = c.auth_user.get_instance() |
|
49 | self._register_global_c(c) | |
|
49 | ||
|
50 | 50 | return c |
|
51 | 51 | |
|
52 | 52 | @LoginRequired() |
@@ -47,7 +47,7 b' class JournalView(BaseAppView):' | |||
|
47 | 47 | |
|
48 | 48 | def load_default_context(self): |
|
49 | 49 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
50 | self._register_global_c(c) | |
|
50 | ||
|
51 | 51 | self._load_defaults(c.rhodecode_name) |
|
52 | 52 | |
|
53 | 53 | # TODO(marcink): what is this, why we need a global register ? |
@@ -146,7 +146,8 b' class JournalView(BaseAppView):' | |||
|
146 | 146 | user = AttributeDict({'short_contact': entry.username, |
|
147 | 147 | 'email': '', |
|
148 | 148 | 'full_contact': ''}) |
|
149 |
action, action_extra, ico = h.action_parser( |
|
|
149 | action, action_extra, ico = h.action_parser( | |
|
150 | self.request, entry, feed=True) | |
|
150 | 151 | title = "%s - %s %s" % (user.short_contact, action(), |
|
151 | 152 | entry.repository.repo_name) |
|
152 | 153 | desc = action_extra() |
@@ -191,7 +192,8 b' class JournalView(BaseAppView):' | |||
|
191 | 192 | user = AttributeDict({'short_contact': entry.username, |
|
192 | 193 | 'email': '', |
|
193 | 194 | 'full_contact': ''}) |
|
194 |
action, action_extra, ico = h.action_parser( |
|
|
195 | action, action_extra, ico = h.action_parser( | |
|
196 | self.request, entry, feed=True) | |
|
195 | 197 | title = "%s - %s %s" % (user.short_contact, action(), |
|
196 | 198 | entry.repository.repo_name) |
|
197 | 199 | desc = action_extra() |
@@ -30,7 +30,6 b' from rhodecode.tests.fixture import Fixt' | |||
|
30 | 30 | from rhodecode.lib.auth import check_password |
|
31 | 31 | from rhodecode.lib import helpers as h |
|
32 | 32 | from rhodecode.model.auth_token import AuthTokenModel |
|
33 | from rhodecode.model import validators | |
|
34 | 33 | from rhodecode.model.db import User, Notification, UserApiKeys |
|
35 | 34 | from rhodecode.model.meta import Session |
|
36 | 35 | |
@@ -234,7 +233,7 b' class TestLoginController(object):' | |||
|
234 | 233 | ) |
|
235 | 234 | |
|
236 | 235 | assertr = response.assert_response() |
|
237 | msg = validators.ValidUsername()._messages['username_exists'] | |
|
236 | msg = '???' | |
|
238 | 237 | msg = msg % {'username': uname} |
|
239 | 238 | assertr.element_contains('#username+.error-message', msg) |
|
240 | 239 | |
@@ -252,7 +251,7 b' class TestLoginController(object):' | |||
|
252 | 251 | ) |
|
253 | 252 | |
|
254 | 253 | assertr = response.assert_response() |
|
255 | msg = validators.UniqSystemEmail()()._messages['email_taken'] | |
|
254 | msg = '???' | |
|
256 | 255 | assertr.element_contains('#email+.error-message', msg) |
|
257 | 256 | |
|
258 | 257 | def test_register_err_same_email_case_sensitive(self): |
@@ -268,7 +267,7 b' class TestLoginController(object):' | |||
|
268 | 267 | } |
|
269 | 268 | ) |
|
270 | 269 | assertr = response.assert_response() |
|
271 | msg = validators.UniqSystemEmail()()._messages['email_taken'] | |
|
270 | msg = '???' | |
|
272 | 271 | assertr.element_contains('#email+.error-message', msg) |
|
273 | 272 | |
|
274 | 273 | def test_register_err_wrong_data(self): |
@@ -322,7 +321,7 b' class TestLoginController(object):' | |||
|
322 | 321 | ) |
|
323 | 322 | |
|
324 | 323 | assertr = response.assert_response() |
|
325 | msg = validators.ValidUsername()._messages['username_exists'] | |
|
324 | msg = '???' | |
|
326 | 325 | msg = msg % {'username': usr} |
|
327 | 326 | assertr.element_contains('#username+.error-message', msg) |
|
328 | 327 | |
@@ -339,7 +338,7 b' class TestLoginController(object):' | |||
|
339 | 338 | } |
|
340 | 339 | ) |
|
341 | 340 | |
|
342 | msg = validators.ValidPassword()._messages['invalid_password'] | |
|
341 | msg = '???' | |
|
343 | 342 | response.mustcontain(msg) |
|
344 | 343 | |
|
345 | 344 | def test_register_password_mismatch(self): |
@@ -354,7 +353,7 b' class TestLoginController(object):' | |||
|
354 | 353 | 'lastname': 'test' |
|
355 | 354 | } |
|
356 | 355 | ) |
|
357 | msg = validators.ValidPasswordsMatch()._messages['password_mismatch'] | |
|
356 | msg = '???' | |
|
358 | 357 | response.mustcontain(msg) |
|
359 | 358 | |
|
360 | 359 | def test_register_ok(self): |
@@ -113,7 +113,7 b' class LoginView(BaseAppView):' | |||
|
113 | 113 | def load_default_context(self): |
|
114 | 114 | c = self._get_local_tmpl_context() |
|
115 | 115 | c.came_from = get_came_from(self.request) |
|
116 | self._register_global_c(c) | |
|
116 | ||
|
117 | 117 | return c |
|
118 | 118 | |
|
119 | 119 | def _get_captcha_data(self): |
@@ -157,7 +157,7 b' class LoginView(BaseAppView):' | |||
|
157 | 157 | def login_post(self): |
|
158 | 158 | c = self.load_default_context() |
|
159 | 159 | |
|
160 | login_form = LoginForm()() | |
|
160 | login_form = LoginForm(self.request.translate)() | |
|
161 | 161 | |
|
162 | 162 | try: |
|
163 | 163 | self.session.invalidate() |
@@ -182,11 +182,10 b' class LoginView(BaseAppView):' | |||
|
182 | 182 | defaults = errors.value |
|
183 | 183 | # remove password from filling in form again |
|
184 | 184 | defaults.pop('password', None) |
|
185 |
render_ctx = |
|
|
186 | render_ctx.update({ | |
|
185 | render_ctx = { | |
|
187 | 186 | 'errors': errors.error_dict, |
|
188 | 187 | 'defaults': defaults, |
|
189 |
} |
|
|
188 | } | |
|
190 | 189 | |
|
191 | 190 | audit_user = audit_logger.UserWrap( |
|
192 | 191 | username=self.request.POST.get('username'), |
@@ -195,7 +194,7 b' class LoginView(BaseAppView):' | |||
|
195 | 194 | audit_logger.store_web( |
|
196 | 195 | 'user.login.failure', action_data=action_data, |
|
197 | 196 | user=audit_user, commit=True) |
|
198 | return render_ctx | |
|
197 | return self._get_template_context(c, **render_ctx) | |
|
199 | 198 | |
|
200 | 199 | except UserCreationError as e: |
|
201 | 200 | # headers auth or other auth functions that create users on |
@@ -255,7 +254,7 b' class LoginView(BaseAppView):' | |||
|
255 | 254 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ |
|
256 | 255 | .AuthUser().permissions['global'] |
|
257 | 256 | |
|
258 | register_form = RegisterForm()() | |
|
257 | register_form = RegisterForm(self.request.translate)() | |
|
259 | 258 | try: |
|
260 | 259 | |
|
261 | 260 | form_result = register_form.to_python(self.request.POST) |
@@ -324,7 +323,7 b' class LoginView(BaseAppView):' | |||
|
324 | 323 | queue='error') |
|
325 | 324 | return HTTPFound(self.request.route_path('reset_password')) |
|
326 | 325 | |
|
327 | password_reset_form = PasswordResetForm()() | |
|
326 | password_reset_form = PasswordResetForm(self.request.translate)() | |
|
328 | 327 | try: |
|
329 | 328 | form_result = password_reset_form.to_python( |
|
330 | 329 | self.request.POST) |
@@ -198,8 +198,6 b' class TestMyAccountEdit(TestController):' | |||
|
198 | 198 | params=params) |
|
199 | 199 | |
|
200 | 200 | response.mustcontain('An email address must contain a single @') |
|
201 | from rhodecode.model import validators | |
|
202 | msg = validators.ValidUsername( | |
|
203 | edit=False, old_data={})._messages['username_exists'] | |
|
201 | msg = '???' | |
|
204 | 202 | msg = h.html_escape(msg % {'username': 'test_admin'}) |
|
205 | 203 | response.mustcontain(u"%s" % msg) |
@@ -42,7 +42,7 b' from rhodecode.model.comment import Comm' | |||
|
42 | 42 | from rhodecode.model.db import ( |
|
43 | 43 | Repository, UserEmailMap, UserApiKeys, UserFollowing, joinedload, |
|
44 | 44 | PullRequest) |
|
45 | from rhodecode.model.forms import UserForm | |
|
45 | from rhodecode.model.forms import UserForm, UserExtraEmailForm | |
|
46 | 46 | from rhodecode.model.meta import Session |
|
47 | 47 | from rhodecode.model.pull_request import PullRequestModel |
|
48 | 48 | from rhodecode.model.scm import RepoList |
@@ -64,7 +64,7 b' class MyAccountView(BaseAppView, DataGri' | |||
|
64 | 64 | c = self._get_local_tmpl_context() |
|
65 | 65 | c.user = c.auth_user.get_instance() |
|
66 | 66 | c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS |
|
67 | self._register_global_c(c) | |
|
67 | ||
|
68 | 68 | return c |
|
69 | 69 | |
|
70 | 70 | @LoginRequired() |
@@ -245,6 +245,10 b' class MyAccountView(BaseAppView, DataGri' | |||
|
245 | 245 | email = self.request.POST.get('new_email') |
|
246 | 246 | |
|
247 | 247 | try: |
|
248 | form = UserExtraEmailForm(self.request.translate)() | |
|
249 | data = form.to_python({'email': email}) | |
|
250 | email = data['email'] | |
|
251 | ||
|
248 | 252 | UserModel().add_extra_email(c.user.user_id, email) |
|
249 | 253 | audit_logger.store_web( |
|
250 | 254 | 'user.edit.email.add', action_data={ |
@@ -442,7 +446,7 b' class MyAccountView(BaseAppView, DataGri' | |||
|
442 | 446 | c.extern_type = c.user.extern_type |
|
443 | 447 | c.extern_name = c.user.extern_name |
|
444 | 448 | |
|
445 | _form = UserForm(edit=True, | |
|
449 | _form = UserForm(self.request.translate, edit=True, | |
|
446 | 450 | old_data={'user_id': self._rhodecode_user.user_id, |
|
447 | 451 | 'email': self._rhodecode_user.email})() |
|
448 | 452 | form_result = {} |
@@ -43,7 +43,7 b' class MyAccountNotificationsView(BaseApp' | |||
|
43 | 43 | def load_default_context(self): |
|
44 | 44 | c = self._get_local_tmpl_context() |
|
45 | 45 | c.user = c.auth_user.get_instance() |
|
46 | self._register_global_c(c) | |
|
46 | ||
|
47 | 47 | return c |
|
48 | 48 | |
|
49 | 49 | def _has_permissions(self, notification): |
@@ -44,7 +44,7 b' class MyAccountSshKeysView(BaseAppView, ' | |||
|
44 | 44 | |
|
45 | 45 | c.ssh_enabled = self.request.registry.settings.get( |
|
46 | 46 | 'ssh.generate_authorized_keyfile') |
|
47 | self._register_global_c(c) | |
|
47 | ||
|
48 | 48 | return c |
|
49 | 49 | |
|
50 | 50 | @LoginRequired() |
@@ -36,7 +36,7 b' def admin_routes(config):' | |||
|
36 | 36 | def includeme(config): |
|
37 | 37 | |
|
38 | 38 | config.include(admin_routes, route_prefix=ADMIN_PREFIX + '/ops') |
|
39 |
# make OLD entries from |
|
|
39 | # make OLD entries from <4.10.0 work | |
|
40 | 40 | config.add_route( |
|
41 | 41 | name='ops_ping_legacy', pattern=ADMIN_PREFIX + '/ping') |
|
42 | 42 | config.add_route( |
@@ -35,7 +35,7 b' class OpsView(BaseAppView):' | |||
|
35 | 35 | def load_default_context(self): |
|
36 | 36 | c = self._get_local_tmpl_context() |
|
37 | 37 | c.user = c.auth_user.get_instance() |
|
38 | self._register_global_c(c) | |
|
38 | ||
|
39 | 39 | return c |
|
40 | 40 | |
|
41 | 41 | @view_config( |
@@ -37,7 +37,7 b' log = logging.getLogger(__name__)' | |||
|
37 | 37 | class RepoGroupSettingsView(RepoGroupAppView): |
|
38 | 38 | def load_default_context(self): |
|
39 | 39 | c = self._get_local_tmpl_context() |
|
40 | self._register_global_c(c) | |
|
40 | ||
|
41 | 41 | return c |
|
42 | 42 | |
|
43 | 43 | @LoginRequired() |
@@ -38,7 +38,7 b' log = logging.getLogger(__name__)' | |||
|
38 | 38 | class RepoGroupPermissionsView(RepoGroupAppView): |
|
39 | 39 | def load_default_context(self): |
|
40 | 40 | c = self._get_local_tmpl_context() |
|
41 | self._register_global_c(c) | |
|
41 | ||
|
42 | 42 | return c |
|
43 | 43 | |
|
44 | 44 | @LoginRequired() |
@@ -65,7 +65,7 b' class RepoGroupPermissionsView(RepoGroup' | |||
|
65 | 65 | c.repo_group = self.db_repo_group |
|
66 | 66 | |
|
67 | 67 | valid_recursive_choices = ['none', 'repos', 'groups', 'all'] |
|
68 | form = RepoGroupPermsForm(valid_recursive_choices)()\ | |
|
68 | form = RepoGroupPermsForm(self.request.translate, valid_recursive_choices)()\ | |
|
69 | 69 | .to_python(self.request.POST) |
|
70 | 70 | |
|
71 | 71 | if not c.rhodecode_user.is_admin: |
@@ -73,7 +73,7 b' class RepoGroupSettingsView(RepoGroupApp' | |||
|
73 | 73 | c.repo_groups_choices.append(parent_group.group_id) |
|
74 | 74 | c.repo_groups.append(RepoGroup._generate_choice(parent_group)) |
|
75 | 75 | |
|
76 | self._register_global_c(c) | |
|
76 | ||
|
77 | 77 | return c |
|
78 | 78 | |
|
79 | 79 | def _can_create_repo_group(self, parent_group_id=None): |
@@ -47,7 +47,7 b' def route_path(name, params=None, **kwar' | |||
|
47 | 47 | class TestRepoCommitCommentsView(TestController): |
|
48 | 48 | |
|
49 | 49 | @pytest.fixture(autouse=True) |
|
50 |
def prepare(self, request, |
|
|
50 | def prepare(self, request, baseapp): | |
|
51 | 51 | for x in ChangesetComment.query().all(): |
|
52 | 52 | Session().delete(x) |
|
53 | 53 | Session().commit() |
@@ -34,7 +34,7 b' class AuditLogsView(RepoAppView):' | |||
|
34 | 34 | def load_default_context(self): |
|
35 | 35 | c = self._get_local_tmpl_context() |
|
36 | 36 | |
|
37 | self._register_global_c(c) | |
|
37 | ||
|
38 | 38 | return c |
|
39 | 39 | |
|
40 | 40 | @LoginRequired() |
@@ -37,7 +37,7 b' class RepoCachesView(RepoAppView):' | |||
|
37 | 37 | def load_default_context(self): |
|
38 | 38 | c = self._get_local_tmpl_context() |
|
39 | 39 | |
|
40 | self._register_global_c(c) | |
|
40 | ||
|
41 | 41 | return c |
|
42 | 42 | |
|
43 | 43 | @LoginRequired() |
@@ -159,7 +159,7 b' class RepoChangelogView(RepoAppView):' | |||
|
159 | 159 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
160 | 160 | |
|
161 | 161 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
162 | self._register_global_c(c) | |
|
162 | ||
|
163 | 163 | return c |
|
164 | 164 | |
|
165 | 165 | def _get_preload_attrs(self): |
@@ -34,7 +34,7 b' log = logging.getLogger(__name__)' | |||
|
34 | 34 | class RepoChecksView(BaseAppView): |
|
35 | 35 | def load_default_context(self): |
|
36 | 36 | c = self._get_local_tmpl_context() |
|
37 | self._register_global_c(c) | |
|
37 | ||
|
38 | 38 | return c |
|
39 | 39 | |
|
40 | 40 | @NotAnonymous() |
@@ -150,7 +150,6 b' class RepoCommitsView(RepoAppView):' | |||
|
150 | 150 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
151 | 151 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
152 | 152 | |
|
153 | self._register_global_c(c) | |
|
154 | 153 | return c |
|
155 | 154 | |
|
156 | 155 | def _commit(self, commit_id_range, method): |
@@ -47,7 +47,7 b' class RepoCompareView(RepoAppView):' | |||
|
47 | 47 | |
|
48 | 48 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
49 | 49 | |
|
50 | self._register_global_c(c) | |
|
50 | ||
|
51 | 51 | return c |
|
52 | 52 | |
|
53 | 53 | def _get_commit_or_redirect( |
@@ -42,7 +42,7 b' class RepoFeedView(RepoAppView):' | |||
|
42 | 42 | def load_default_context(self): |
|
43 | 43 | c = self._get_local_tmpl_context() |
|
44 | 44 | |
|
45 | self._register_global_c(c) | |
|
45 | ||
|
46 | 46 | self._load_defaults() |
|
47 | 47 | return c |
|
48 | 48 |
@@ -83,7 +83,7 b' class RepoFilesView(RepoAppView):' | |||
|
83 | 83 | |
|
84 | 84 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
85 | 85 | |
|
86 | self._register_global_c(c) | |
|
86 | ||
|
87 | 87 | return c |
|
88 | 88 | |
|
89 | 89 | def _ensure_not_locked(self): |
@@ -57,7 +57,7 b' class RepoForksView(RepoAppView, DataGri' | |||
|
57 | 57 | c.landing_revs_choices = choices |
|
58 | 58 | c.personal_repo_group = c.rhodecode_user.personal_repo_group |
|
59 | 59 | |
|
60 | self._register_global_c(c) | |
|
60 | ||
|
61 | 61 | return c |
|
62 | 62 | |
|
63 | 63 | @LoginRequired() |
@@ -209,7 +209,7 b' class RepoForksView(RepoAppView, DataGri' | |||
|
209 | 209 | _ = self.request.translate |
|
210 | 210 | c = self.load_default_context() |
|
211 | 211 | |
|
212 | _form = RepoForkForm(old_data={'repo_type': self.db_repo.repo_type}, | |
|
212 | _form = RepoForkForm(self.request.translate, old_data={'repo_type': self.db_repo.repo_type}, | |
|
213 | 213 | repo_groups=c.repo_groups_choices, |
|
214 | 214 | landing_revs=c.landing_revs_choices)() |
|
215 | 215 | post_data = dict(self.request.POST) |
@@ -33,7 +33,7 b' class RepoMaintenanceView(RepoAppView):' | |||
|
33 | 33 | def load_default_context(self): |
|
34 | 34 | c = self._get_local_tmpl_context() |
|
35 | 35 | |
|
36 | self._register_global_c(c) | |
|
36 | ||
|
37 | 37 | return c |
|
38 | 38 | |
|
39 | 39 | @LoginRequired() |
@@ -40,7 +40,7 b' class RepoSettingsPermissionsView(RepoAp' | |||
|
40 | 40 | def load_default_context(self): |
|
41 | 41 | c = self._get_local_tmpl_context() |
|
42 | 42 | |
|
43 | self._register_global_c(c) | |
|
43 | ||
|
44 | 44 | return c |
|
45 | 45 | |
|
46 | 46 | @LoginRequired() |
@@ -68,7 +68,7 b' class RepoSettingsPermissionsView(RepoAp' | |||
|
68 | 68 | # default user permissions, prevents submission of FAKE post data |
|
69 | 69 | # into the form for private repos |
|
70 | 70 | data['repo_private'] = self.db_repo.private |
|
71 | form = RepoPermsForm()().to_python(data) | |
|
71 | form = RepoPermsForm(self.request.translate)().to_python(data) | |
|
72 | 72 | changes = RepoModel().update_permissions( |
|
73 | 73 | self.db_repo_name, form['perm_additions'], form['perm_updates'], |
|
74 | 74 | form['perm_deletions']) |
@@ -60,7 +60,7 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
60 | 60 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
61 | 61 | c.REVIEW_STATUS_APPROVED = ChangesetStatus.STATUS_APPROVED |
|
62 | 62 | c.REVIEW_STATUS_REJECTED = ChangesetStatus.STATUS_REJECTED |
|
63 | self._register_global_c(c) | |
|
63 | ||
|
64 | 64 | return c |
|
65 | 65 | |
|
66 | 66 | def _get_pull_requests_list( |
@@ -749,7 +749,9 b' class RepoPullRequestsView(RepoAppView, ' | |||
|
749 | 749 | controls = peppercorn.parse(self.request.POST.items()) |
|
750 | 750 | |
|
751 | 751 | try: |
|
752 |
|
|
|
752 | form = PullRequestForm( | |
|
753 | self.request.translate, self.db_repo.repo_id)() | |
|
754 | _form = form.to_python(controls) | |
|
753 | 755 | except formencode.Invalid as errors: |
|
754 | 756 | if errors.error_dict.get('revisions'): |
|
755 | 757 | msg = 'Revisions: %s' % errors.error_dict['revisions'] |
@@ -32,8 +32,6 b' log = logging.getLogger(__name__)' | |||
|
32 | 32 | class RepoReviewRulesView(RepoAppView): |
|
33 | 33 | def load_default_context(self): |
|
34 | 34 | c = self._get_local_tmpl_context() |
|
35 | ||
|
36 | self._register_global_c(c) | |
|
37 | 35 | return c |
|
38 | 36 | |
|
39 | 37 | @LoginRequired() |
@@ -54,6 +52,7 b' class RepoReviewRulesView(RepoAppView):' | |||
|
54 | 52 | route_name='repo_default_reviewers_data', request_method='GET', |
|
55 | 53 | renderer='json_ext') |
|
56 | 54 | def repo_default_reviewers_data(self): |
|
55 | self.load_default_context() | |
|
57 | 56 | review_data = get_default_reviewers_data( |
|
58 | 57 | self.db_repo.user, None, None, None, None) |
|
59 | 58 | return review_data |
@@ -71,7 +71,7 b' class RepoSettingsView(RepoAppView):' | |||
|
71 | 71 | c.repo_fields = RepositoryField.query()\ |
|
72 | 72 | .filter(RepositoryField.repository == self.db_repo).all() |
|
73 | 73 | |
|
74 | self._register_global_c(c) | |
|
74 | ||
|
75 | 75 | return c |
|
76 | 76 | |
|
77 | 77 | def _get_schema(self, c, old_values=None): |
@@ -44,7 +44,7 b' class RepoSettingsView(RepoAppView):' | |||
|
44 | 44 | def load_default_context(self): |
|
45 | 45 | c = self._get_local_tmpl_context() |
|
46 | 46 | |
|
47 | self._register_global_c(c) | |
|
47 | ||
|
48 | 48 | return c |
|
49 | 49 | |
|
50 | 50 | @LoginRequired() |
@@ -43,7 +43,7 b' class RepoSettingsFieldsView(RepoAppView' | |||
|
43 | 43 | def load_default_context(self): |
|
44 | 44 | c = self._get_local_tmpl_context() |
|
45 | 45 | |
|
46 | self._register_global_c(c) | |
|
46 | ||
|
47 | 47 | return c |
|
48 | 48 | |
|
49 | 49 | @LoginRequired() |
@@ -70,7 +70,8 b' class RepoSettingsFieldsView(RepoAppView' | |||
|
70 | 70 | _ = self.request.translate |
|
71 | 71 | |
|
72 | 72 | try: |
|
73 |
form |
|
|
73 | form = RepoFieldForm(self.request.translate)() | |
|
74 | form_result = form.to_python(dict(self.request.POST)) | |
|
74 | 75 | RepoModel().add_repo_field( |
|
75 | 76 | self.db_repo_name, |
|
76 | 77 | form_result['new_field_key'], |
@@ -40,7 +40,7 b' class RepoSettingsIssueTrackersView(Repo' | |||
|
40 | 40 | def load_default_context(self): |
|
41 | 41 | c = self._get_local_tmpl_context() |
|
42 | 42 | |
|
43 | self._register_global_c(c) | |
|
43 | ||
|
44 | 44 | return c |
|
45 | 45 | |
|
46 | 46 | @LoginRequired() |
@@ -118,7 +118,7 b' class RepoSettingsIssueTrackersView(Repo' | |||
|
118 | 118 | Session().commit() |
|
119 | 119 | |
|
120 | 120 | try: |
|
121 | form = IssueTrackerPatternsForm()().to_python(self.request.POST) | |
|
121 | form = IssueTrackerPatternsForm(self.request.translate)().to_python(self.request.POST) | |
|
122 | 122 | except formencode.Invalid as errors: |
|
123 | 123 | log.exception('Failed to add new pattern') |
|
124 | 124 | error = errors |
@@ -36,7 +36,7 b' class RepoSettingsRemoteView(RepoAppView' | |||
|
36 | 36 | def load_default_context(self): |
|
37 | 37 | c = self._get_local_tmpl_context() |
|
38 | 38 | |
|
39 | self._register_global_c(c) | |
|
39 | ||
|
40 | 40 | return c |
|
41 | 41 | |
|
42 | 42 | @LoginRequired() |
@@ -43,7 +43,7 b' class RepoSettingsVcsView(RepoAppView):' | |||
|
43 | 43 | def load_default_context(self): |
|
44 | 44 | c = self._get_local_tmpl_context() |
|
45 | 45 | |
|
46 | self._register_global_c(c) | |
|
46 | ||
|
47 | 47 | return c |
|
48 | 48 | |
|
49 | 49 | def _vcs_form_defaults(self, repo_name): |
@@ -117,7 +117,7 b' class RepoSettingsVcsView(RepoAppView):' | |||
|
117 | 117 | defaults = self._vcs_form_defaults(self.db_repo_name) |
|
118 | 118 | c.inherit_global_settings = defaults['inherit_global_settings'] |
|
119 | 119 | |
|
120 | application_form = RepoVcsSettingsForm(self.db_repo_name)() | |
|
120 | application_form = RepoVcsSettingsForm(self.request.translate, self.db_repo_name)() | |
|
121 | 121 | try: |
|
122 | 122 | form_result = application_form.to_python(dict(self.request.POST)) |
|
123 | 123 | except formencode.Invalid as errors: |
@@ -35,7 +35,7 b' class StripView(RepoAppView):' | |||
|
35 | 35 | def load_default_context(self): |
|
36 | 36 | c = self._get_local_tmpl_context() |
|
37 | 37 | |
|
38 | self._register_global_c(c) | |
|
38 | ||
|
39 | 39 | return c |
|
40 | 40 | |
|
41 | 41 | @LoginRequired() |
@@ -53,7 +53,7 b' class RepoSummaryView(RepoAppView):' | |||
|
53 | 53 | if not c.repository_requirements_missing: |
|
54 | 54 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
55 | 55 | |
|
56 | self._register_global_c(c) | |
|
56 | ||
|
57 | 57 | return c |
|
58 | 58 | |
|
59 | 59 | def _get_readme_data(self, db_repo, default_renderer): |
@@ -103,7 +103,7 b' def search(request, tmpl_context, repo_n' | |||
|
103 | 103 | class SearchView(BaseAppView): |
|
104 | 104 | def load_default_context(self): |
|
105 | 105 | c = self._get_local_tmpl_context() |
|
106 | self._register_global_c(c) | |
|
106 | ||
|
107 | 107 | return c |
|
108 | 108 | |
|
109 | 109 | @LoginRequired() |
@@ -119,7 +119,7 b' class SearchView(BaseAppView):' | |||
|
119 | 119 | class SearchRepoView(RepoAppView): |
|
120 | 120 | def load_default_context(self): |
|
121 | 121 | c = self._get_local_tmpl_context() |
|
122 | self._register_global_c(c) | |
|
122 | ||
|
123 | 123 | return c |
|
124 | 124 | |
|
125 | 125 | @LoginRequired() |
@@ -56,7 +56,7 b' class UserGroupsView(UserGroupAppView):' | |||
|
56 | 56 | PermissionModel().set_global_permission_choices( |
|
57 | 57 | c, gettext_translator=self.request.translate) |
|
58 | 58 | |
|
59 | self._register_global_c(c) | |
|
59 | ||
|
60 | 60 | return c |
|
61 | 61 | |
|
62 | 62 | def _get_perms_summary(self, user_group_id): |
@@ -94,6 +94,7 b' class UserGroupsView(UserGroupAppView):' | |||
|
94 | 94 | """ |
|
95 | 95 | Return members of given user group |
|
96 | 96 | """ |
|
97 | self.load_default_context() | |
|
97 | 98 | user_group = self.db_user_group |
|
98 | 99 | group_members_obj = sorted((x.user for x in user_group.members), |
|
99 | 100 | key=lambda u: u.username.lower()) |
@@ -173,7 +174,8 b' class UserGroupsView(UserGroupAppView):' | |||
|
173 | 174 | c.active = 'settings' |
|
174 | 175 | |
|
175 | 176 | users_group_form = UserGroupForm( |
|
176 | edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)() | |
|
177 | self.request.translate, edit=True, | |
|
178 | old_data=c.user_group.get_dict(), allow_disabled=True)() | |
|
177 | 179 | |
|
178 | 180 | old_values = c.user_group.get_api_data() |
|
179 | 181 | user_group_name = self.request.POST.get('users_group_name') |
@@ -346,7 +348,7 b' class UserGroupsView(UserGroupAppView):' | |||
|
346 | 348 | user_group_id = user_group.users_group_id |
|
347 | 349 | c = self.load_default_context() |
|
348 | 350 | c.user_group = user_group |
|
349 | form = UserGroupPermsForm()().to_python(self.request.POST) | |
|
351 | form = UserGroupPermsForm(self.request.translate)().to_python(self.request.POST) | |
|
350 | 352 | |
|
351 | 353 | if not self._rhodecode_user.is_admin: |
|
352 | 354 | if self._revoke_perms_on_yourself(form): |
@@ -435,6 +437,7 b' class UserGroupsView(UserGroupAppView):' | |||
|
435 | 437 | if not inherit_perms: |
|
436 | 438 | # only update the individual ones if we un check the flag |
|
437 | 439 | _form = UserPermissionsForm( |
|
440 | self.request.translate, | |
|
438 | 441 | [x[0] for x in c.repo_create_choices], |
|
439 | 442 | [x[0] for x in c.repo_create_on_write_choices], |
|
440 | 443 | [x[0] for x in c.repo_group_create_choices], |
@@ -252,29 +252,6 b' class RhodeCodeAuthPluginBase(object):' | |||
|
252 | 252 | del settings_copy[k] |
|
253 | 253 | return settings_copy |
|
254 | 254 | |
|
255 | @property | |
|
256 | def validators(self): | |
|
257 | """ | |
|
258 | Exposes RhodeCode validators modules | |
|
259 | """ | |
|
260 | # this is a hack to overcome issues with pylons threadlocals and | |
|
261 | # translator object _() not being registered properly. | |
|
262 | class LazyCaller(object): | |
|
263 | def __init__(self, name): | |
|
264 | self.validator_name = name | |
|
265 | ||
|
266 | def __call__(self, *args, **kwargs): | |
|
267 | from rhodecode.model import validators as v | |
|
268 | obj = getattr(v, self.validator_name) | |
|
269 | # log.debug('Initializing lazy formencode object: %s', obj) | |
|
270 | return LazyFormencode(obj, *args, **kwargs) | |
|
271 | ||
|
272 | class ProxyGet(object): | |
|
273 | def __getattribute__(self, name): | |
|
274 | return LazyCaller(name) | |
|
275 | ||
|
276 | return ProxyGet() | |
|
277 | ||
|
278 | 255 | @hybrid_property |
|
279 | 256 | def name(self): |
|
280 | 257 | """ |
@@ -26,25 +26,24 b' from pyramid.httpexceptions import HTTPF' | |||
|
26 | 26 | from pyramid.renderers import render |
|
27 | 27 | from pyramid.response import Response |
|
28 | 28 | |
|
29 | from rhodecode.apps._base import BaseAppView | |
|
29 | 30 | from rhodecode.authentication.base import ( |
|
30 | 31 | get_auth_cache_manager, get_perms_cache_manager, get_authn_registry) |
|
31 |
from rhodecode.lib import |
|
|
32 |
|
|
|
32 | from rhodecode.lib.auth import ( | |
|
33 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |
|
33 | 34 | from rhodecode.model.forms import AuthSettingsForm |
|
34 | 35 | from rhodecode.model.meta import Session |
|
35 | 36 | from rhodecode.model.settings import SettingsModel |
|
36 | from rhodecode.translation import _ | |
|
37 | 37 | |
|
38 | 38 | log = logging.getLogger(__name__) |
|
39 | 39 | |
|
40 | 40 | |
|
41 |
class AuthnPluginViewBase( |
|
|
41 | class AuthnPluginViewBase(BaseAppView): | |
|
42 | 42 | |
|
43 | def __init__(self, context, request): | |
|
44 | self.request = request | |
|
45 | self.context = context | |
|
46 | self.plugin = context.plugin | |
|
47 | self._rhodecode_user = request.user | |
|
43 | def load_default_context(self): | |
|
44 | c = self._get_local_tmpl_context() | |
|
45 | self.plugin = self.context.plugin | |
|
46 | return c | |
|
48 | 47 | |
|
49 | 48 | @LoginRequired() |
|
50 | 49 | @HasPermissionAllDecorator('hg.admin') |
@@ -52,6 +51,7 b' class AuthnPluginViewBase(object):' | |||
|
52 | 51 | """ |
|
53 | 52 | View that displays the plugin settings as a form. |
|
54 | 53 | """ |
|
54 | c = self.load_default_context() | |
|
55 | 55 | defaults = defaults or {} |
|
56 | 56 | errors = errors or {} |
|
57 | 57 | schema = self.plugin.get_settings_schema() |
@@ -70,15 +70,17 b' class AuthnPluginViewBase(object):' | |||
|
70 | 70 | 'resource': self.context, |
|
71 | 71 | } |
|
72 | 72 | |
|
73 | return template_context | |
|
73 | return self._get_template_context(c, **template_context) | |
|
74 | 74 | |
|
75 | 75 | @LoginRequired() |
|
76 | 76 | @HasPermissionAllDecorator('hg.admin') |
|
77 |
@ |
|
|
77 | @CSRFRequired() | |
|
78 | 78 | def settings_post(self): |
|
79 | 79 | """ |
|
80 | 80 | View that validates and stores the plugin settings. |
|
81 | 81 | """ |
|
82 | _ = self.request.translate | |
|
83 | self.load_default_context() | |
|
82 | 84 | schema = self.plugin.get_settings_schema() |
|
83 | 85 | data = self.request.params |
|
84 | 86 | |
@@ -107,23 +109,16 b' class AuthnPluginViewBase(object):' | |||
|
107 | 109 | return HTTPFound(redirect_to) |
|
108 | 110 | |
|
109 | 111 | |
|
110 | # TODO: Ongoing migration in these views. | |
|
111 | # - Maybe we should also use a colander schema for these views. | |
|
112 | class AuthSettingsView(object): | |
|
113 | def __init__(self, context, request): | |
|
114 | self.context = context | |
|
115 | self.request = request | |
|
116 | ||
|
117 | # TODO: Move this into a utility function. It is needed in all view | |
|
118 | # classes during migration. Maybe a mixin? | |
|
119 | ||
|
120 | # Some of the decorators rely on this attribute to be present on the | |
|
121 | # class of the decorated method. | |
|
122 | self._rhodecode_user = request.user | |
|
112 | class AuthSettingsView(BaseAppView): | |
|
113 | def load_default_context(self): | |
|
114 | c = self._get_local_tmpl_context() | |
|
115 | return c | |
|
123 | 116 | |
|
124 | 117 | @LoginRequired() |
|
125 | 118 | @HasPermissionAllDecorator('hg.admin') |
|
126 | 119 | def index(self, defaults=None, errors=None, prefix_error=False): |
|
120 | c = self.load_default_context() | |
|
121 | ||
|
127 | 122 | defaults = defaults or {} |
|
128 | 123 | authn_registry = get_authn_registry(self.request.registry) |
|
129 | 124 | enabled_plugins = SettingsModel().get_auth_plugins() |
@@ -135,8 +130,8 b' class AuthSettingsView(object):' | |||
|
135 | 130 | 'enabled_plugins': enabled_plugins, |
|
136 | 131 | } |
|
137 | 132 | html = render('rhodecode:templates/admin/auth/auth_settings.mako', |
|
138 | template_context, | |
|
139 |
|
|
|
133 | self._get_template_context(c, **template_context), | |
|
134 | self.request) | |
|
140 | 135 | |
|
141 | 136 | # Create form default values and fill the form. |
|
142 | 137 | form_defaults = { |
@@ -155,11 +150,12 b' class AuthSettingsView(object):' | |||
|
155 | 150 | |
|
156 | 151 | @LoginRequired() |
|
157 | 152 | @HasPermissionAllDecorator('hg.admin') |
|
158 |
@ |
|
|
153 | @CSRFRequired() | |
|
159 | 154 | def auth_settings(self): |
|
155 | _ = self.request.translate | |
|
160 | 156 | try: |
|
161 | form = AuthSettingsForm()() | |
|
162 |
form_result = form.to_python(self.request. |
|
|
157 | form = AuthSettingsForm(self.request.translate)() | |
|
158 | form_result = form.to_python(self.request.POST) | |
|
163 | 159 | plugins = ','.join(form_result['auth_plugins']) |
|
164 | 160 | setting = SettingsModel().create_or_update_setting( |
|
165 | 161 | 'auth_plugins', plugins) |
@@ -18,127 +18,49 b'' | |||
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | """ | |
|
22 | Pylons environment configuration | |
|
23 | """ | |
|
24 | 21 | |
|
25 | 22 | import os |
|
26 | 23 | import logging |
|
27 | 24 | import rhodecode |
|
28 | 25 | |
|
29 | from mako.lookup import TemplateLookup | |
|
30 | from pyramid.settings import asbool | |
|
31 | ||
|
32 | 26 | # ------------------------------------------------------------------------------ |
|
33 | 27 | # CELERY magic until refactor - issue #4163 - import order matters here: |
|
34 | from rhodecode.lib import celerypylons # this must be first, celerypylons | |
|
28 | #from rhodecode.lib import celerypylons # this must be first, celerypylons | |
|
35 | 29 | # sets config settings upon import |
|
36 | 30 | |
|
37 | 31 | import rhodecode.integrations # any modules using celery task |
|
38 | 32 | # decorators should be added afterwards: |
|
39 | 33 | # ------------------------------------------------------------------------------ |
|
40 | 34 | |
|
41 | from rhodecode.lib import app_globals | |
|
42 | 35 | from rhodecode.config import utils |
|
43 | from rhodecode.config.routing import make_map | |
|
44 | 36 | |
|
45 |
from rhodecode.lib import |
|
|
46 |
from rhodecode.lib.utils import |
|
|
47 | make_db_config, set_rhodecode_config, load_rcextensions) | |
|
48 | from rhodecode.lib.utils2 import str2bool, aslist | |
|
37 | from rhodecode.lib.utils import load_rcextensions | |
|
38 | from rhodecode.lib.utils2 import str2bool | |
|
49 | 39 | from rhodecode.lib.vcs import connect_vcs, start_vcs_server |
|
50 | 40 | |
|
51 | 41 | log = logging.getLogger(__name__) |
|
52 | 42 | |
|
53 | 43 | |
|
54 | def load_environment(global_conf, app_conf, initial=False, | |
|
55 | test_env=None, test_index=None): | |
|
56 | """ | |
|
57 | Configure the Pylons environment via the ``pylons.config`` | |
|
58 | object | |
|
59 | """ | |
|
60 | from pylons.configuration import PylonsConfig | |
|
61 | from pylons.error import handle_mako_error | |
|
62 | ||
|
63 | config = PylonsConfig() | |
|
64 | ||
|
65 | ||
|
66 | # Pylons paths | |
|
67 | root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
|
68 | paths = { | |
|
69 | 'root': root, | |
|
70 | 'controllers': os.path.join(root, 'controllers'), | |
|
71 | 'static_files': os.path.join(root, 'public'), | |
|
72 | 'templates': [os.path.join(root, 'templates')], | |
|
73 | } | |
|
74 | ||
|
75 | # Initialize config with the basic options | |
|
76 | config.init_app(global_conf, app_conf, package='rhodecode', paths=paths) | |
|
77 | ||
|
78 | # store some globals into rhodecode | |
|
79 | rhodecode.CELERY_ENABLED = str2bool(config['app_conf'].get('use_celery')) | |
|
80 | rhodecode.CELERY_EAGER = str2bool( | |
|
81 | config['app_conf'].get('celery.always.eager')) | |
|
82 | ||
|
83 | config['routes.map'] = make_map(config) | |
|
84 | ||
|
85 | config['pylons.app_globals'] = app_globals.Globals(config) | |
|
86 | config['pylons.h'] = helpers | |
|
87 | rhodecode.CONFIG = config | |
|
88 | ||
|
89 | load_rcextensions(root_path=config['here']) | |
|
90 | ||
|
91 | # Setup cache object as early as possible | |
|
92 | import pylons | |
|
93 | pylons.cache._push_object(config['pylons.app_globals'].cache) | |
|
94 | ||
|
95 | # Create the Mako TemplateLookup, with the default auto-escaping | |
|
96 | config['pylons.app_globals'].mako_lookup = TemplateLookup( | |
|
97 | directories=paths['templates'], | |
|
98 | error_handler=handle_mako_error, | |
|
99 | module_directory=os.path.join(app_conf['cache_dir'], 'templates'), | |
|
100 | input_encoding='utf-8', default_filters=['escape'], | |
|
101 | imports=['from webhelpers.html import escape']) | |
|
102 | ||
|
103 | # sets the c attribute access when don't existing attribute are accessed | |
|
104 | config['pylons.strict_tmpl_context'] = True | |
|
105 | ||
|
106 | # configure channelstream | |
|
107 | config['channelstream_config'] = { | |
|
108 | 'enabled': asbool(config.get('channelstream.enabled', False)), | |
|
109 | 'server': config.get('channelstream.server'), | |
|
110 | 'secret': config.get('channelstream.secret') | |
|
111 | } | |
|
112 | ||
|
113 | db_cfg = make_db_config(clear_session=True) | |
|
114 | ||
|
115 | repos_path = list(db_cfg.items('paths'))[0][1] | |
|
116 | config['base_path'] = repos_path | |
|
117 | ||
|
118 | # store db config also in main global CONFIG | |
|
119 | set_rhodecode_config(config) | |
|
120 | ||
|
121 | # configure instance id | |
|
122 | utils.set_instance_id(config) | |
|
123 | ||
|
124 | # CONFIGURATION OPTIONS HERE (note: all config options will override | |
|
125 | # any Pylons config options) | |
|
126 | ||
|
127 | # store config reference into our module to skip import magic of pylons | |
|
128 | rhodecode.CONFIG.update(config) | |
|
129 | ||
|
130 | return config | |
|
131 | ||
|
132 | ||
|
133 | 44 | def load_pyramid_environment(global_config, settings): |
|
134 | 45 | # Some parts of the code expect a merge of global and app settings. |
|
135 | 46 | settings_merged = global_config.copy() |
|
136 | 47 | settings_merged.update(settings) |
|
137 | 48 | |
|
138 | # Store the settings to make them available to other modules. | |
|
139 | rhodecode.PYRAMID_SETTINGS = settings_merged | |
|
140 | # NOTE(marcink): needs to be enabled after full port to pyramid | |
|
141 | # rhodecode.CONFIG = config | |
|
49 | # TODO(marcink): probably not required anymore | |
|
50 | # configure channelstream, | |
|
51 | settings_merged['channelstream_config'] = { | |
|
52 | 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)), | |
|
53 | 'server': settings_merged.get('channelstream.server'), | |
|
54 | 'secret': settings_merged.get('channelstream.secret') | |
|
55 | } | |
|
56 | ||
|
57 | ||
|
58 | # TODO(marcink): celery | |
|
59 | # # store some globals into rhodecode | |
|
60 | # rhodecode.CELERY_ENABLED = str2bool(config['app_conf'].get('use_celery')) | |
|
61 | # rhodecode.CELERY_EAGER = str2bool( | |
|
62 | # config['app_conf'].get('celery.always.eager')) | |
|
63 | ||
|
142 | 64 | |
|
143 | 65 | # If this is a test run we prepare the test environment like |
|
144 | 66 | # creating a test database, test search index and test repositories. |
@@ -152,6 +74,11 b' def load_pyramid_environment(global_conf' | |||
|
152 | 74 | # Initialize the database connection. |
|
153 | 75 | utils.initialize_database(settings_merged) |
|
154 | 76 | |
|
77 | # TODO(marcink): base_path handling ? | |
|
78 | # repos_path = list(db_cfg.items('paths'))[0][1] | |
|
79 | ||
|
80 | load_rcextensions(root_path=settings_merged['here']) | |
|
81 | ||
|
155 | 82 | # Limit backends to `vcs.backends` from configuration |
|
156 | 83 | for alias in rhodecode.BACKENDS.keys(): |
|
157 | 84 | if alias not in settings['vcs.backends']: |
@@ -173,5 +100,10 b' def load_pyramid_environment(global_conf' | |||
|
173 | 100 | |
|
174 | 101 | utils.configure_vcs(settings) |
|
175 | 102 | |
|
103 | # Store the settings to make them available to other modules. | |
|
104 | ||
|
105 | rhodecode.PYRAMID_SETTINGS = settings_merged | |
|
106 | rhodecode.CONFIG = settings_merged | |
|
107 | ||
|
176 | 108 | if vcs_server_enabled: |
|
177 | 109 | connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings)) |
@@ -43,10 +43,7 b'' | |||
|
43 | 43 | }, |
|
44 | 44 | "python2.7-Pygments-2.2.0": { |
|
45 | 45 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
46 |
}, |
|
|
47 | "python2.7-Pylons-1.0.2.rhodecode-patch1": { | |
|
48 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" | |
|
49 | }, | |
|
46 | }, | |
|
50 | 47 | "python2.7-Routes-1.13": { |
|
51 | 48 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
52 | 49 | }, |
@@ -80,10 +77,7 b'' | |||
|
80 | 77 | }, |
|
81 | 78 | "python2.7-amqplib-1.0.2": { |
|
82 | 79 | "GNU Lesser General Public License v3.0 only": "http://spdx.org/licenses/LGPL-3.0" |
|
83 |
}, |
|
|
84 | "python2.7-anyjson-0.3.3": { | |
|
85 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" | |
|
86 | }, | |
|
80 | }, | |
|
87 | 81 | "python2.7-appenlight-client-0.6.14": { |
|
88 | 82 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
89 | 83 | }, |
@@ -327,7 +321,7 b'' | |||
|
327 | 321 | "Python Software Foundation License version 2": "http://spdx.org/licenses/Python-2.0", |
|
328 | 322 | "Zope Public License 2.0": "http://spdx.org/licenses/ZPL-2.0" |
|
329 | 323 | }, |
|
330 |
"python2.7-setuptools-scm-1.15. |
|
|
324 | "python2.7-setuptools-scm-1.15.6": { | |
|
331 | 325 | "MIT License": "http://spdx.org/licenses/MIT" |
|
332 | 326 | }, |
|
333 | 327 | "python2.7-simplegeneric-0.8.1": { |
@@ -22,33 +22,26 b' import logging' | |||
|
22 | 22 | import traceback |
|
23 | 23 | import collections |
|
24 | 24 | |
|
25 | from paste.registry import RegistryManager | |
|
26 | 25 | from paste.gzipper import make_gzip_middleware |
|
26 | from pyramid.wsgi import wsgiapp | |
|
27 | 27 | from pyramid.authorization import ACLAuthorizationPolicy |
|
28 | 28 | from pyramid.config import Configurator |
|
29 | 29 | from pyramid.settings import asbool, aslist |
|
30 | from pyramid.wsgi import wsgiapp | |
|
31 | 30 | from pyramid.httpexceptions import ( |
|
32 | HTTPException, HTTPError, HTTPInternalServerError, HTTPFound) | |
|
31 | HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound) | |
|
33 | 32 | from pyramid.events import ApplicationCreated |
|
34 | 33 | from pyramid.renderers import render_to_response |
|
35 | from routes.middleware import RoutesMiddleware | |
|
36 | import rhodecode | |
|
37 | 34 | |
|
38 | 35 | from rhodecode.model import meta |
|
39 | 36 | from rhodecode.config import patches |
|
40 | 37 | from rhodecode.config import utils as config_utils |
|
41 | from rhodecode.config.routing import STATIC_FILE_PREFIX | |
|
42 | from rhodecode.config.environment import ( | |
|
43 | load_environment, load_pyramid_environment) | |
|
38 | from rhodecode.config.environment import load_pyramid_environment | |
|
44 | 39 | |
|
40 | from rhodecode.lib.middleware.vcs import VCSMiddleware | |
|
45 | 41 | from rhodecode.lib.vcs import VCSCommunicationError |
|
46 | 42 | from rhodecode.lib.exceptions import VCSServerUnavailable |
|
47 | 43 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled |
|
48 | from rhodecode.lib.middleware.error_handling import ( | |
|
49 | PylonsErrorHandlingMiddleware) | |
|
50 | 44 | from rhodecode.lib.middleware.https_fixup import HttpsFixup |
|
51 | from rhodecode.lib.middleware.vcs import VCSMiddleware | |
|
52 | 45 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin |
|
53 | 46 | from rhodecode.lib.utils2 import aslist as rhodecode_aslist, AttributeDict |
|
54 | 47 | from rhodecode.subscribers import ( |
@@ -59,76 +52,17 b' from rhodecode.subscribers import (' | |||
|
59 | 52 | log = logging.getLogger(__name__) |
|
60 | 53 | |
|
61 | 54 | |
|
62 | # this is used to avoid avoid the route lookup overhead in routesmiddleware | |
|
63 | # for certain routes which won't go to pylons to - eg. static files, debugger | |
|
64 | # it is only needed for the pylons migration and can be removed once complete | |
|
65 | class SkippableRoutesMiddleware(RoutesMiddleware): | |
|
66 | """ Routes middleware that allows you to skip prefixes """ | |
|
67 | ||
|
68 | def __init__(self, *args, **kw): | |
|
69 | self.skip_prefixes = kw.pop('skip_prefixes', []) | |
|
70 | super(SkippableRoutesMiddleware, self).__init__(*args, **kw) | |
|
71 | ||
|
72 | def __call__(self, environ, start_response): | |
|
73 | for prefix in self.skip_prefixes: | |
|
74 | if environ['PATH_INFO'].startswith(prefix): | |
|
75 | # added to avoid the case when a missing /_static route falls | |
|
76 | # through to pylons and causes an exception as pylons is | |
|
77 | # expecting wsgiorg.routingargs to be set in the environ | |
|
78 | # by RoutesMiddleware. | |
|
79 | if 'wsgiorg.routing_args' not in environ: | |
|
80 | environ['wsgiorg.routing_args'] = (None, {}) | |
|
81 | return self.app(environ, start_response) | |
|
82 | ||
|
83 | return super(SkippableRoutesMiddleware, self).__call__( | |
|
84 | environ, start_response) | |
|
85 | ||
|
86 | ||
|
87 | def make_app(global_conf, static_files=True, **app_conf): | |
|
88 | """Create a Pylons WSGI application and return it | |
|
89 | ||
|
90 | ``global_conf`` | |
|
91 | The inherited configuration for this application. Normally from | |
|
92 | the [DEFAULT] section of the Paste ini file. | |
|
93 | ||
|
94 | ``app_conf`` | |
|
95 | The application's local configuration. Normally specified in | |
|
96 | the [app:<name>] section of the Paste ini file (where <name> | |
|
97 | defaults to main). | |
|
98 | ||
|
99 | """ | |
|
100 | from pylons.wsgiapp import PylonsApp | |
|
101 | ||
|
102 | # Apply compatibility patches | |
|
103 | patches.kombu_1_5_1_python_2_7_11() | |
|
104 | patches.inspect_getargspec() | |
|
105 | ||
|
106 | # Configure the Pylons environment | |
|
107 | config = load_environment(global_conf, app_conf) | |
|
108 | ||
|
109 | # The Pylons WSGI app | |
|
110 | app = PylonsApp(config=config) | |
|
111 | ||
|
112 | # Establish the Registry for this application | |
|
113 | app = RegistryManager(app) | |
|
114 | ||
|
115 | app.config = config | |
|
116 | ||
|
117 | return app | |
|
55 | def is_http_error(response): | |
|
56 | # error which should have traceback | |
|
57 | return response.status_code > 499 | |
|
118 | 58 | |
|
119 | 59 | |
|
120 | 60 | def make_pyramid_app(global_config, **settings): |
|
121 | 61 | """ |
|
122 |
Constructs the WSGI application based on Pyramid |
|
|
123 | application. | |
|
62 | Constructs the WSGI application based on Pyramid. | |
|
124 | 63 | |
|
125 | 64 | Specials: |
|
126 | 65 | |
|
127 | * We migrate from Pylons to Pyramid. While doing this, we keep both | |
|
128 | frameworks functional. This involves moving some WSGI middlewares around | |
|
129 | and providing access to some data internals, so that the old code is | |
|
130 | still functional. | |
|
131 | ||
|
132 | 66 | * The application can also be integrated like a plugin via the call to |
|
133 | 67 | `includeme`. This is accompanied with the other utility functions which |
|
134 | 68 | are called. Changing this should be done with great care to not break |
@@ -138,9 +72,11 b' def make_pyramid_app(global_config, **se' | |||
|
138 | 72 | sanitize_settings_and_apply_defaults(settings) |
|
139 | 73 | |
|
140 | 74 | config = Configurator(settings=settings) |
|
141 | load_pyramid_environment(global_config, settings) | |
|
142 | 75 | |
|
143 | add_pylons_compat_data(config.registry, global_config, settings.copy()) | |
|
76 | # Apply compatibility patches | |
|
77 | patches.inspect_getargspec() | |
|
78 | ||
|
79 | load_pyramid_environment(global_config, settings) | |
|
144 | 80 | |
|
145 | 81 | # Static file view comes first |
|
146 | 82 | includeme_first(config) |
@@ -157,54 +93,24 b' def make_pyramid_app(global_config, **se' | |||
|
157 | 93 | return pyramid_app |
|
158 | 94 | |
|
159 | 95 | |
|
160 |
def |
|
|
96 | def not_found_view(request): | |
|
161 | 97 | """ |
|
162 | 98 | This creates the view which should be registered as not-found-view to |
|
163 | pyramid. Basically it contains of the old pylons app, converted to a view. | |
|
164 | Additionally it is wrapped by some other middlewares. | |
|
99 | pyramid. | |
|
165 | 100 | """ |
|
166 | settings = config.registry.settings | |
|
167 | vcs_server_enabled = settings['vcs.server.enable'] | |
|
168 | 101 | |
|
169 | # Make pylons app from unprepared settings. | |
|
170 | pylons_app = make_app( | |
|
171 | config.registry._pylons_compat_global_config, | |
|
172 | **config.registry._pylons_compat_settings) | |
|
173 | config.registry._pylons_compat_config = pylons_app.config | |
|
174 | ||
|
175 | # Appenlight monitoring. | |
|
176 | pylons_app, appenlight_client = wrap_in_appenlight_if_enabled( | |
|
177 | pylons_app, settings) | |
|
102 | if not getattr(request, 'vcs_call', None): | |
|
103 | # handle like regular case with our error_handler | |
|
104 | return error_handler(HTTPNotFound(), request) | |
|
178 | 105 | |
|
179 | # The pylons app is executed inside of the pyramid 404 exception handler. | |
|
180 | # Exceptions which are raised inside of it are not handled by pyramid | |
|
181 | # again. Therefore we add a middleware that invokes the error handler in | |
|
182 | # case of an exception or error response. This way we return proper error | |
|
183 | # HTML pages in case of an error. | |
|
184 | reraise = (settings.get('debugtoolbar.enabled', False) or | |
|
185 | rhodecode.disable_error_handler) | |
|
186 | pylons_app = PylonsErrorHandlingMiddleware( | |
|
187 | pylons_app, error_handler, reraise) | |
|
106 | # handle not found view as a vcs call | |
|
107 | settings = request.registry.settings | |
|
108 | ae_client = getattr(request, 'ae_client', None) | |
|
109 | vcs_app = VCSMiddleware( | |
|
110 | HTTPNotFound(), request.registry, settings, | |
|
111 | appenlight_client=ae_client) | |
|
188 | 112 | |
|
189 | # The VCSMiddleware shall operate like a fallback if pyramid doesn't find a | |
|
190 | # view to handle the request. Therefore it is wrapped around the pylons | |
|
191 | # app. It has to be outside of the error handling otherwise error responses | |
|
192 | # from the vcsserver are converted to HTML error pages. This confuses the | |
|
193 | # command line tools and the user won't get a meaningful error message. | |
|
194 | if vcs_server_enabled: | |
|
195 | pylons_app = VCSMiddleware( | |
|
196 | pylons_app, settings, appenlight_client, registry=config.registry) | |
|
197 | ||
|
198 | # Convert WSGI app to pyramid view and return it. | |
|
199 | return wsgiapp(pylons_app) | |
|
200 | ||
|
201 | ||
|
202 | def add_pylons_compat_data(registry, global_config, settings): | |
|
203 | """ | |
|
204 | Attach data to the registry to support the Pylons integration. | |
|
205 | """ | |
|
206 | registry._pylons_compat_global_config = global_config | |
|
207 | registry._pylons_compat_settings = settings | |
|
113 | return wsgiapp(vcs_app)(None, request) | |
|
208 | 114 | |
|
209 | 115 | |
|
210 | 116 | def error_handler(exception, request): |
@@ -220,10 +126,6 b' def error_handler(exception, request):' | |||
|
220 | 126 | elif isinstance(exception, VCSCommunicationError): |
|
221 | 127 | base_response = VCSServerUnavailable() |
|
222 | 128 | |
|
223 | def is_http_error(response): | |
|
224 | # error which should have traceback | |
|
225 | return response.status_code > 499 | |
|
226 | ||
|
227 | 129 | if is_http_error(base_response): |
|
228 | 130 | log.exception( |
|
229 | 131 | 'error occurred handling this request for path: %s', request.path) |
@@ -366,43 +268,29 b' def includeme(config):' | |||
|
366 | 268 | for inc in includes: |
|
367 | 269 | config.include(inc) |
|
368 | 270 | |
|
369 | # This is the glue which allows us to migrate in chunks. By registering the | |
|
370 | # pylons based application as the "Not Found" view in Pyramid, we will | |
|
371 | # fallback to the old application each time the new one does not yet know | |
|
372 | # how to handle a request. | |
|
373 | config.add_notfound_view(make_not_found_view(config)) | |
|
374 | ||
|
271 | # custom not found view, if our pyramid app doesn't know how to handle | |
|
272 | # the request pass it to potential VCS handling ap | |
|
273 | config.add_notfound_view(not_found_view) | |
|
375 | 274 | if not settings.get('debugtoolbar.enabled', False): |
|
376 | 275 | # disabled debugtoolbar handle all exceptions via the error_handlers |
|
377 | 276 | config.add_view(error_handler, context=Exception) |
|
378 | 277 | |
|
278 | # all errors including 403/404/50X | |
|
379 | 279 | config.add_view(error_handler, context=HTTPError) |
|
380 | 280 | |
|
381 | 281 | |
|
382 | 282 | def wrap_app_in_wsgi_middlewares(pyramid_app, config): |
|
383 | 283 | """ |
|
384 | 284 | Apply outer WSGI middlewares around the application. |
|
385 | ||
|
386 | Part of this has been moved up from the Pylons layer, so that the | |
|
387 | data is also available if old Pylons code is hit through an already ported | |
|
388 | view. | |
|
389 | 285 | """ |
|
390 | 286 | settings = config.registry.settings |
|
391 | 287 | |
|
392 | 288 | # enable https redirects based on HTTP_X_URL_SCHEME set by proxy |
|
393 | 289 | pyramid_app = HttpsFixup(pyramid_app, settings) |
|
394 | 290 | |
|
395 | # Add RoutesMiddleware to support the pylons compatibility tween during | |
|
396 | # migration to pyramid. | |
|
397 | ||
|
398 | # TODO(marcink): remove after migration to pyramid | |
|
399 | if hasattr(config.registry, '_pylons_compat_config'): | |
|
400 | routes_map = config.registry._pylons_compat_config['routes.map'] | |
|
401 | pyramid_app = SkippableRoutesMiddleware( | |
|
402 | pyramid_app, routes_map, | |
|
403 | skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar')) | |
|
404 | ||
|
405 | pyramid_app, _ = wrap_in_appenlight_if_enabled(pyramid_app, settings) | |
|
291 | pyramid_app, _ae_client = wrap_in_appenlight_if_enabled( | |
|
292 | pyramid_app, settings) | |
|
293 | config.registry.ae_client = _ae_client | |
|
406 | 294 | |
|
407 | 295 | if settings['gzip_responses']: |
|
408 | 296 | pyramid_app = make_gzip_middleware( |
@@ -518,10 +406,10 b' def _int_setting(settings, name, default' | |||
|
518 | 406 | |
|
519 | 407 | |
|
520 | 408 | def _bool_setting(settings, name, default): |
|
521 | input = settings.get(name, default) | |
|
522 | if isinstance(input, unicode): | |
|
523 | input = input.encode('utf8') | |
|
524 | settings[name] = asbool(input) | |
|
409 | input_val = settings.get(name, default) | |
|
410 | if isinstance(input_val, unicode): | |
|
411 | input_val = input_val.encode('utf8') | |
|
412 | settings[name] = asbool(input_val) | |
|
525 | 413 | |
|
526 | 414 | |
|
527 | 415 | def _list_setting(settings, name, default): |
@@ -32,26 +32,10 b' Please keep the following principles in ' | |||
|
32 | 32 | """ |
|
33 | 33 | |
|
34 | 34 | |
|
35 | def kombu_1_5_1_python_2_7_11(): | |
|
36 | """ | |
|
37 | Kombu 1.5.1 relies on a private method which got removed in Python 2.7.11. | |
|
38 | ||
|
39 | This patch adds the symbol to the module :mod:`uuid` and assigns the value | |
|
40 | ``None`` to it. This causes kombu to fall back to the public API of | |
|
41 | :mod:`uuid`. | |
|
42 | ||
|
43 | This patch can most probably be removed once celery and kombu are updated | |
|
44 | to more recent versions. | |
|
45 | """ | |
|
46 | import uuid | |
|
47 | ||
|
48 | if not hasattr(uuid, '_uuid_generate_random'): | |
|
49 | uuid._uuid_generate_random = None | |
|
50 | ||
|
51 | 35 | |
|
52 | 36 | def inspect_getargspec(): |
|
53 | 37 | """ |
|
54 |
Pyramid |
|
|
38 | Pyramid rely on inspect.getargspec to lookup the signature of | |
|
55 | 39 | view functions. This is not compatible with cython, therefore we replace |
|
56 | 40 | getargspec with a custom version. |
|
57 | 41 | Code is inspired by the inspect module from Python-3.4 |
@@ -110,7 +110,7 b' class IntegrationSettingsViewBase(BaseAp' | |||
|
110 | 110 | |
|
111 | 111 | return False |
|
112 | 112 | |
|
113 |
def _get_local_tmpl_context(self, include_app_defaults= |
|
|
113 | def _get_local_tmpl_context(self, include_app_defaults=True): | |
|
114 | 114 | _ = self.request.translate |
|
115 | 115 | c = super(IntegrationSettingsViewBase, self)._get_local_tmpl_context( |
|
116 | 116 | include_app_defaults=include_app_defaults) |
@@ -366,7 +366,7 b' class GlobalIntegrationsView(Integration' | |||
|
366 | 366 | c.repo = self.repo |
|
367 | 367 | c.repo_group = self.repo_group |
|
368 | 368 | c.navlist = navigation_list(self.request) |
|
369 | self._register_global_c(c) | |
|
369 | ||
|
370 | 370 | return c |
|
371 | 371 | |
|
372 | 372 | @LoginRequired() |
@@ -403,7 +403,7 b' class RepoIntegrationsView(IntegrationSe' | |||
|
403 | 403 | c.repo_name = self.db_repo.repo_name |
|
404 | 404 | c.repository_pull_requests = ScmModel().get_pull_requests(self.repo) |
|
405 | 405 | |
|
406 | self._register_global_c(c) | |
|
406 | ||
|
407 | 407 | return c |
|
408 | 408 | |
|
409 | 409 | @LoginRequired() |
@@ -434,7 +434,7 b' class RepoGroupIntegrationsView(Integrat' | |||
|
434 | 434 | c.repo = self.repo |
|
435 | 435 | c.repo_group = self.repo_group |
|
436 | 436 | c.navlist = navigation_list(self.request) |
|
437 | self._register_global_c(c) | |
|
437 | ||
|
438 | 438 | return c |
|
439 | 439 | |
|
440 | 440 | @LoginRequired() |
@@ -20,7 +20,6 b'' | |||
|
20 | 20 | |
|
21 | 21 | import logging |
|
22 | 22 | |
|
23 | from pylons.i18n.translation import _ | |
|
24 | 23 | from webhelpers.html.builder import literal |
|
25 | 24 | from webhelpers.html.tags import link_to |
|
26 | 25 | |
@@ -32,7 +31,7 b' from rhodecode.lib.vcs.exceptions import' | |||
|
32 | 31 | log = logging.getLogger(__name__) |
|
33 | 32 | |
|
34 | 33 | |
|
35 | def action_parser(user_log, feed=False, parse_cs=False): | |
|
34 | def action_parser(request, user_log, feed=False, parse_cs=False): | |
|
36 | 35 | """ |
|
37 | 36 | This helper will action_map the specified string action into translated |
|
38 | 37 | fancy names with icons and links |
@@ -42,11 +41,11 b' def action_parser(user_log, feed=False, ' | |||
|
42 | 41 | :param parse_cs: parse Changesets into VCS instances |
|
43 | 42 | """ |
|
44 | 43 | if user_log.version == 'v2': |
|
45 | ap = AuditLogParser(user_log) | |
|
44 | ap = AuditLogParser(request, user_log) | |
|
46 | 45 | return ap.callbacks() |
|
47 | 46 | else: |
|
48 | 47 | # old style |
|
49 | ap = ActionParser(user_log, feed=False, parse_commits=False) | |
|
48 | ap = ActionParser(request, user_log, feed=False, parse_commits=False) | |
|
50 | 49 | return ap.callbacks() |
|
51 | 50 | |
|
52 | 51 | |
@@ -55,10 +54,11 b' class ActionParser(object):' | |||
|
55 | 54 | commits_limit = 3 # display this amount always |
|
56 | 55 | commits_top_limit = 50 # show up to this amount of commits hidden |
|
57 | 56 | |
|
58 | def __init__(self, user_log, feed=False, parse_commits=False): | |
|
57 | def __init__(self, request, user_log, feed=False, parse_commits=False): | |
|
59 | 58 | self.user_log = user_log |
|
60 | 59 | self.feed = feed |
|
61 | 60 | self.parse_commits = parse_commits |
|
61 | self.request = request | |
|
62 | 62 | |
|
63 | 63 | self.action = user_log.action |
|
64 | 64 | self.action_params = ' ' |
@@ -86,7 +86,7 b' class ActionParser(object):' | |||
|
86 | 86 | |
|
87 | 87 | @property |
|
88 | 88 | def action_map(self): |
|
89 | ||
|
89 | _ = self.request.translate | |
|
90 | 90 | # action : translated str, callback(extractor), icon |
|
91 | 91 | action_map = { |
|
92 | 92 | 'user_deleted_repo': ( |
@@ -166,6 +166,7 b' class ActionParser(object):' | |||
|
166 | 166 | |
|
167 | 167 | def get_fork_name(self): |
|
168 | 168 | from rhodecode.lib import helpers as h |
|
169 | _ = self.request.translate | |
|
169 | 170 | repo_name = self.action_params |
|
170 | 171 | _url = h.route_path('repo_summary', repo_name=repo_name) |
|
171 | 172 | return _('fork name %s') % link_to(self.action_params, _url) |
@@ -180,6 +181,7 b' class ActionParser(object):' | |||
|
180 | 181 | |
|
181 | 182 | def get_pull_request(self): |
|
182 | 183 | from rhodecode.lib import helpers as h |
|
184 | _ = self.request.translate | |
|
183 | 185 | pull_request_id = self.action_params |
|
184 | 186 | if self.is_deleted(): |
|
185 | 187 | repo_name = self.user_log.repository_name |
@@ -201,6 +203,7 b' class ActionParser(object):' | |||
|
201 | 203 | |
|
202 | 204 | def get_cs_links(self): |
|
203 | 205 | from rhodecode.lib import helpers as h |
|
206 | _ = self.request.translate | |
|
204 | 207 | if self.is_deleted(): |
|
205 | 208 | return self.action_params |
|
206 | 209 | |
@@ -277,7 +280,9 b' class ActionParser(object):' | |||
|
277 | 280 | def lnk(self, commit_or_id, repo_name): |
|
278 | 281 | from rhodecode.lib.helpers import tooltip |
|
279 | 282 | from rhodecode.lib import helpers as h |
|
280 | ||
|
283 | _ = self.request.translate | |
|
284 | title = '' | |
|
285 | lazy_cs = True | |
|
281 | 286 | if isinstance(commit_or_id, (BaseCommit, AttributeDict)): |
|
282 | 287 | lazy_cs = True |
|
283 | 288 | if (getattr(commit_or_id, 'op', None) and |
@@ -312,8 +317,9 b' class ActionParser(object):' | |||
|
312 | 317 | |
|
313 | 318 | |
|
314 | 319 | class AuditLogParser(object): |
|
315 | def __init__(self, audit_log_entry): | |
|
320 | def __init__(self, request, audit_log_entry): | |
|
316 | 321 | self.audit_log_entry = audit_log_entry |
|
322 | self.request = request | |
|
317 | 323 | |
|
318 | 324 | def get_icon(self, action): |
|
319 | 325 | return 'icon-rhodecode' |
@@ -34,7 +34,7 b' import traceback' | |||
|
34 | 34 | from functools import wraps |
|
35 | 35 | |
|
36 | 36 | import ipaddress |
|
37 | from beaker.cache import cache_region | |
|
37 | ||
|
38 | 38 | from pyramid.httpexceptions import HTTPForbidden, HTTPFound, HTTPNotFound |
|
39 | 39 | from sqlalchemy.orm.exc import ObjectDeletedError |
|
40 | 40 | from sqlalchemy.orm import joinedload |
@@ -52,42 +52,9 b' from rhodecode.model.notification import' | |||
|
52 | 52 | from rhodecode.model.scm import ScmModel |
|
53 | 53 | from rhodecode.model.settings import VcsSettingsModel, SettingsModel |
|
54 | 54 | |
|
55 | # NOTE(marcink): remove after base controller is no longer required | |
|
56 | from pylons.controllers import WSGIController | |
|
57 | from pylons.i18n import translation | |
|
58 | ||
|
59 | 55 | log = logging.getLogger(__name__) |
|
60 | 56 | |
|
61 | 57 | |
|
62 | # hack to make the migration to pyramid easier | |
|
63 | def render(template_name, extra_vars=None, cache_key=None, | |
|
64 | cache_type=None, cache_expire=None): | |
|
65 | """Render a template with Mako | |
|
66 | ||
|
67 | Accepts the cache options ``cache_key``, ``cache_type``, and | |
|
68 | ``cache_expire``. | |
|
69 | ||
|
70 | """ | |
|
71 | from pylons.templating import literal | |
|
72 | from pylons.templating import cached_template, pylons_globals | |
|
73 | ||
|
74 | # Create a render callable for the cache function | |
|
75 | def render_template(): | |
|
76 | # Pull in extra vars if needed | |
|
77 | globs = extra_vars or {} | |
|
78 | ||
|
79 | # Second, get the globals | |
|
80 | globs.update(pylons_globals()) | |
|
81 | ||
|
82 | globs['_ungettext'] = globs['ungettext'] | |
|
83 | # Grab a template reference | |
|
84 | template = globs['app_globals'].mako_lookup.get_template(template_name) | |
|
85 | ||
|
86 | return literal(template.render_unicode(**globs)) | |
|
87 | ||
|
88 | return cached_template(template_name, render_template, cache_key=cache_key, | |
|
89 | cache_type=cache_type, cache_expire=cache_expire) | |
|
90 | ||
|
91 | 58 | def _filter_proxy(ip): |
|
92 | 59 | """ |
|
93 | 60 | Passed in IP addresses in HEADERS can be in a special format of multiple |
@@ -310,14 +277,10 b' def get_current_lang(request):' | |||
|
310 | 277 | |
|
311 | 278 | def attach_context_attributes(context, request, user_id): |
|
312 | 279 | """ |
|
313 |
Attach variables into template context called `c` |
|
|
314 | request could be pylons or pyramid request in here. | |
|
280 | Attach variables into template context called `c`. | |
|
315 | 281 | """ |
|
316 | # NOTE(marcink): remove check after pyramid migration | |
|
317 | if hasattr(request, 'registry'): | |
|
318 | config = request.registry.settings | |
|
319 | else: | |
|
320 | from pylons import config | |
|
282 | config = request.registry.settings | |
|
283 | ||
|
321 | 284 | |
|
322 | 285 | rc_config = SettingsModel().get_all_settings(cache=True) |
|
323 | 286 | |
@@ -418,10 +381,6 b' def attach_context_attributes(context, r' | |||
|
418 | 381 | } |
|
419 | 382 | # END CONFIG VARS |
|
420 | 383 | |
|
421 | # TODO: This dosn't work when called from pylons compatibility tween. | |
|
422 | # Fix this and remove it from base controller. | |
|
423 | # context.repo_name = get_repo_slug(request) # can be empty | |
|
424 | ||
|
425 | 384 | diffmode = 'sideside' |
|
426 | 385 | if request.GET.get('diffmode'): |
|
427 | 386 | if request.GET['diffmode'] == 'unified': |
@@ -439,20 +398,15 b' def attach_context_attributes(context, r' | |||
|
439 | 398 | context.backends.sort() |
|
440 | 399 | context.unread_notifications = NotificationModel().get_unread_cnt_for_user(user_id) |
|
441 | 400 | |
|
442 | # NOTE(marcink): when migrated to pyramid we don't need to set this anymore, | |
|
443 | # given request will ALWAYS be pyramid one | |
|
444 | pyramid_request = pyramid.threadlocal.get_current_request() | |
|
445 | context.pyramid_request = pyramid_request | |
|
446 | ||
|
447 | 401 | # web case |
|
448 |
if hasattr( |
|
|
449 |
context.auth_user = |
|
|
450 |
context.rhodecode_user = |
|
|
402 | if hasattr(request, 'user'): | |
|
403 | context.auth_user = request.user | |
|
404 | context.rhodecode_user = request.user | |
|
451 | 405 | |
|
452 | 406 | # api case |
|
453 |
if hasattr( |
|
|
454 |
context.auth_user = |
|
|
455 |
context.rhodecode_user = |
|
|
407 | if hasattr(request, 'rpc_user'): | |
|
408 | context.auth_user = request.rpc_user | |
|
409 | context.rhodecode_user = request.rpc_user | |
|
456 | 410 | |
|
457 | 411 | # attach the whole call context to the request |
|
458 | 412 | request.call_context = context |
@@ -500,82 +454,6 b' def get_auth_user(request):' | |||
|
500 | 454 | return auth_user |
|
501 | 455 | |
|
502 | 456 | |
|
503 | class BaseController(WSGIController): | |
|
504 | ||
|
505 | def __before__(self): | |
|
506 | """ | |
|
507 | __before__ is called before controller methods and after __call__ | |
|
508 | """ | |
|
509 | # on each call propagate settings calls into global settings. | |
|
510 | from pylons import config | |
|
511 | from pylons import tmpl_context as c, request, url | |
|
512 | set_rhodecode_config(config) | |
|
513 | attach_context_attributes(c, request, self._rhodecode_user.user_id) | |
|
514 | ||
|
515 | # TODO: Remove this when fixed in attach_context_attributes() | |
|
516 | c.repo_name = get_repo_slug(request) # can be empty | |
|
517 | ||
|
518 | self.cut_off_limit_diff = safe_int(config.get('cut_off_limit_diff')) | |
|
519 | self.cut_off_limit_file = safe_int(config.get('cut_off_limit_file')) | |
|
520 | self.sa = meta.Session | |
|
521 | self.scm_model = ScmModel(self.sa) | |
|
522 | ||
|
523 | # set user language | |
|
524 | user_lang = getattr(c.pyramid_request, '_LOCALE_', None) | |
|
525 | if user_lang: | |
|
526 | translation.set_lang(user_lang) | |
|
527 | log.debug('set language to %s for user %s', | |
|
528 | user_lang, self._rhodecode_user) | |
|
529 | ||
|
530 | def _dispatch_redirect(self, with_url, environ, start_response): | |
|
531 | from webob.exc import HTTPFound | |
|
532 | resp = HTTPFound(with_url) | |
|
533 | environ['SCRIPT_NAME'] = '' # handle prefix middleware | |
|
534 | environ['PATH_INFO'] = with_url | |
|
535 | return resp(environ, start_response) | |
|
536 | ||
|
537 | def __call__(self, environ, start_response): | |
|
538 | """Invoke the Controller""" | |
|
539 | # WSGIController.__call__ dispatches to the Controller method | |
|
540 | # the request is routed to. This routing information is | |
|
541 | # available in environ['pylons.routes_dict'] | |
|
542 | from rhodecode.lib import helpers as h | |
|
543 | from pylons import tmpl_context as c, request, url | |
|
544 | ||
|
545 | # Provide the Pylons context to Pyramid's debugtoolbar if it asks | |
|
546 | if environ.get('debugtoolbar.wants_pylons_context', False): | |
|
547 | environ['debugtoolbar.pylons_context'] = c._current_obj() | |
|
548 | ||
|
549 | _route_name = '.'.join([environ['pylons.routes_dict']['controller'], | |
|
550 | environ['pylons.routes_dict']['action']]) | |
|
551 | ||
|
552 | self.rc_config = SettingsModel().get_all_settings(cache=True) | |
|
553 | self.ip_addr = get_ip_addr(environ) | |
|
554 | ||
|
555 | # The rhodecode auth user is looked up and passed through the | |
|
556 | # environ by the pylons compatibility tween in pyramid. | |
|
557 | # So we can just grab it from there. | |
|
558 | auth_user = environ['rc_auth_user'] | |
|
559 | ||
|
560 | # set globals for auth user | |
|
561 | request.user = auth_user | |
|
562 | self._rhodecode_user = auth_user | |
|
563 | ||
|
564 | log.info('IP: %s User: %s accessed %s [%s]' % ( | |
|
565 | self.ip_addr, auth_user, safe_unicode(get_access_path(environ)), | |
|
566 | _route_name) | |
|
567 | ) | |
|
568 | ||
|
569 | user_obj = auth_user.get_instance() | |
|
570 | if user_obj and user_obj.user_data.get('force_password_change'): | |
|
571 | h.flash('You are required to change your password', 'warning', | |
|
572 | ignore_duplicate=True) | |
|
573 | return self._dispatch_redirect( | |
|
574 | url('my_account_password'), environ, start_response) | |
|
575 | ||
|
576 | return WSGIController.__call__(self, environ, start_response) | |
|
577 | ||
|
578 | ||
|
579 | 457 | def h_filter(s): |
|
580 | 458 | """ |
|
581 | 459 | Custom filter for Mako templates. Mako by standard uses `markupsafe.escape` |
@@ -623,6 +501,7 b' def bootstrap_config(request):' | |||
|
623 | 501 | |
|
624 | 502 | # allow pyramid lookup in testing |
|
625 | 503 | config.include('pyramid_mako') |
|
504 | config.include('pyramid_beaker') | |
|
626 | 505 | |
|
627 | 506 | add_events_routes(config) |
|
628 | 507 |
@@ -28,7 +28,6 b' import os' | |||
|
28 | 28 | import logging |
|
29 | 29 | |
|
30 | 30 | from celery.task import task |
|
31 | from pylons import config | |
|
32 | 31 | |
|
33 | 32 | import rhodecode |
|
34 | 33 | from rhodecode.lib import audit_logger |
@@ -42,9 +41,6 b' from rhodecode.lib.utils2 import safe_in' | |||
|
42 | 41 | from rhodecode.model.db import Repository, User |
|
43 | 42 | |
|
44 | 43 | |
|
45 | add_cache(config) # pragma: no cover | |
|
46 | ||
|
47 | ||
|
48 | 44 | def get_logger(cls): |
|
49 | 45 | if rhodecode.CELERY_ENABLED: |
|
50 | 46 | try: |
@@ -36,7 +36,7 b' class PylonsSettingsProxy(object):' | |||
|
36 | 36 | """ |
|
37 | 37 | def __getattr__(self, key): |
|
38 | 38 | pylons_key = to_pylons(key) |
|
39 |
proxy_config = rhodecode.PYRAMID_SETTINGS |
|
|
39 | proxy_config = rhodecode.PYRAMID_SETTINGS | |
|
40 | 40 | try: |
|
41 | 41 | value = proxy_config[pylons_key] |
|
42 | 42 | if key in LIST_PARAMS: |
@@ -59,7 +59,7 b' class PylonsSettingsProxy(object):' | |||
|
59 | 59 | |
|
60 | 60 | def __setattr__(self, key, value): |
|
61 | 61 | pylons_key = to_pylons(key) |
|
62 |
proxy_config = rhodecode.PYRAMID_SETTINGS |
|
|
62 | proxy_config = rhodecode.PYRAMID_SETTINGS | |
|
63 | 63 | proxy_config[pylons_key] = value |
|
64 | 64 | |
|
65 | 65 | def __setitem__(self, key, value): |
@@ -30,7 +30,7 b' import logging' | |||
|
30 | 30 | |
|
31 | 31 | from itertools import tee, imap |
|
32 | 32 | |
|
33 | from pylons.i18n.translation import _ | |
|
33 | from rhodecode.translation import temp_translation_factory as _ | |
|
34 | 34 | |
|
35 | 35 | from rhodecode.lib.vcs.exceptions import VCSError |
|
36 | 36 | from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode |
@@ -7,9 +7,9 b' import simplejson as json' | |||
|
7 | 7 | from rhodecode.lib.datelib import is_aware |
|
8 | 8 | |
|
9 | 9 | try: |
|
10 | import pylons | |
|
10 | import rhodecode.translation | |
|
11 | 11 | except ImportError: |
|
12 |
|
|
|
12 | rhodecode = None | |
|
13 | 13 | |
|
14 | 14 | __all__ = ['json'] |
|
15 | 15 | |
@@ -51,7 +51,7 b' def _obj_dump(obj):' | |||
|
51 | 51 | return str(obj) |
|
52 | 52 | elif isinstance(obj, complex): |
|
53 | 53 | return [obj.real, obj.imag] |
|
54 |
elif |
|
|
54 | elif rhodecode and isinstance(obj, rhodecode.translation.LazyString): | |
|
55 | 55 | return obj.eval() |
|
56 | 56 | else: |
|
57 | 57 | raise TypeError(repr(obj) + " is not JSON serializable") |
@@ -91,11 +91,6 b' DEFAULT_USER = User.DEFAULT_USER' | |||
|
91 | 91 | DEFAULT_USER_EMAIL = User.DEFAULT_USER_EMAIL |
|
92 | 92 | |
|
93 | 93 | |
|
94 | def url(*args, **kw): | |
|
95 | from pylons import url as pylons_url | |
|
96 | return pylons_url(*args, **kw) | |
|
97 | ||
|
98 | ||
|
99 | 94 | def asset(path, ver=None, **kwargs): |
|
100 | 95 | """ |
|
101 | 96 | Helper to generate a static asset file path for rhodecode assets |
@@ -1287,15 +1282,8 b' def initials_gravatar(email_address, fir' | |||
|
1287 | 1282 | |
|
1288 | 1283 | def gravatar_url(email_address, size=30, request=None): |
|
1289 | 1284 | request = get_current_request() |
|
1290 | if request and hasattr(request, 'call_context'): | |
|
1291 |
|
|
|
1292 | _gravatar_url = request.call_context.visual.gravatar_url | |
|
1293 | else: | |
|
1294 | # doh, we need to re-import those to mock it later | |
|
1295 | from pylons import tmpl_context as c | |
|
1296 | ||
|
1297 | _use_gravatar = c.visual.use_gravatar | |
|
1298 | _gravatar_url = c.visual.gravatar_url | |
|
1285 | _use_gravatar = request.call_context.visual.use_gravatar | |
|
1286 | _gravatar_url = request.call_context.visual.gravatar_url | |
|
1299 | 1287 | |
|
1300 | 1288 | _gravatar_url = _gravatar_url or User.DEFAULT_GRAVATAR_URL |
|
1301 | 1289 | |
@@ -1745,8 +1733,6 b' def urlify_commit_message(commit_text, r' | |||
|
1745 | 1733 | :param commit_text: |
|
1746 | 1734 | :param repository: |
|
1747 | 1735 | """ |
|
1748 | from pylons import url # doh, we need to re-import url to mock it later | |
|
1749 | ||
|
1750 | 1736 | def escaper(string): |
|
1751 | 1737 | return string.replace('<', '<').replace('>', '>') |
|
1752 | 1738 | |
@@ -2006,8 +1992,6 b' def get_last_path_part(file_node):' | |||
|
2006 | 1992 | def route_url(*args, **kwargs): |
|
2007 | 1993 | """ |
|
2008 | 1994 | Wrapper around pyramids `route_url` (fully qualified url) function. |
|
2009 | It is used to generate URLs from within pylons views or templates. | |
|
2010 | This will be removed when pyramid migration if finished. | |
|
2011 | 1995 | """ |
|
2012 | 1996 | req = get_current_request() |
|
2013 | 1997 | return req.route_url(*args, **kwargs) |
@@ -2015,9 +1999,7 b' def route_url(*args, **kwargs):' | |||
|
2015 | 1999 | |
|
2016 | 2000 | def route_path(*args, **kwargs): |
|
2017 | 2001 | """ |
|
2018 |
Wrapper around pyramids `route_path` function. |
|
|
2019 | URLs from within pylons views or templates. This will be removed when | |
|
2020 | pyramid migration if finished. | |
|
2002 | Wrapper around pyramids `route_path` function. | |
|
2021 | 2003 | """ |
|
2022 | 2004 | req = get_current_request() |
|
2023 | 2005 | return req.route_path(*args, **kwargs) |
@@ -2036,26 +2018,6 b' def current_route_path(request, **kw):' | |||
|
2036 | 2018 | return request.current_route_path(_query=new_args) |
|
2037 | 2019 | |
|
2038 | 2020 | |
|
2039 | def static_url(*args, **kwds): | |
|
2040 | """ | |
|
2041 | Wrapper around pyramids `route_path` function. It is used to generate | |
|
2042 | URLs from within pylons views or templates. This will be removed when | |
|
2043 | pyramid migration if finished. | |
|
2044 | """ | |
|
2045 | req = get_current_request() | |
|
2046 | return req.static_url(*args, **kwds) | |
|
2047 | ||
|
2048 | ||
|
2049 | def resource_path(*args, **kwds): | |
|
2050 | """ | |
|
2051 | Wrapper around pyramids `route_path` function. It is used to generate | |
|
2052 | URLs from within pylons views or templates. This will be removed when | |
|
2053 | pyramid migration if finished. | |
|
2054 | """ | |
|
2055 | req = get_current_request() | |
|
2056 | return req.resource_path(*args, **kwds) | |
|
2057 | ||
|
2058 | ||
|
2059 | 2021 | def api_call_example(method, args): |
|
2060 | 2022 | """ |
|
2061 | 2023 | Generates an API call example via CURL |
@@ -18,8 +18,8 b'' | |||
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | import pylons | |
|
22 | 21 | import webob |
|
22 | from pyramid.threadlocal import get_current_request | |
|
23 | 23 | |
|
24 | 24 | from rhodecode import events |
|
25 | 25 | from rhodecode.lib import hooks_base |
@@ -31,12 +31,15 b' def _get_rc_scm_extras(username, repo_na' | |||
|
31 | 31 | from rhodecode.lib.base import vcs_operation_context |
|
32 | 32 | check_locking = action in ('pull', 'push') |
|
33 | 33 | |
|
34 | request = get_current_request() | |
|
35 | ||
|
36 | # default | |
|
37 | dummy_environ = webob.Request.blank('').environ | |
|
34 | 38 | try: |
|
35 |
environ = |
|
|
39 | environ = request.environ or dummy_environ | |
|
36 | 40 | except TypeError: |
|
37 |
# we might use this outside of request context |
|
|
38 |
|
|
|
39 | environ = webob.Request.blank('').environ | |
|
41 | # we might use this outside of request context | |
|
42 | environ = dummy_environ | |
|
40 | 43 | |
|
41 | 44 | extras = vcs_operation_context( |
|
42 | 45 | environ, repo_name, username, action, repo_alias, check_locking) |
@@ -27,7 +27,7 b' import logging' | |||
|
27 | 27 | import os |
|
28 | 28 | import re |
|
29 | 29 | |
|
30 | from pylons.i18n.translation import _ | |
|
30 | from rhodecode.translation import temp_translation_factory as _ | |
|
31 | 31 | |
|
32 | 32 | from whoosh import query as query_lib, sorting |
|
33 | 33 | from whoosh.highlight import HtmlFormatter, ContextFragmenter |
@@ -23,7 +23,7 b' import time' | |||
|
23 | 23 | import logging |
|
24 | 24 | |
|
25 | 25 | |
|
26 | from rhodecode.lib.base import get_ip_addr, get_access_path | |
|
26 | from rhodecode.lib.base import get_ip_addr, get_access_path, get_user_agent | |
|
27 | 27 | from rhodecode.lib.utils2 import safe_str |
|
28 | 28 | |
|
29 | 29 | |
@@ -43,10 +43,11 b' class RequestWrapperTween(object):' | |||
|
43 | 43 | response = self.handler(request) |
|
44 | 44 | finally: |
|
45 | 45 | end = time.time() |
|
46 | ||
|
47 | log.info('IP: %s Request to %s time: %.3fs' % ( | |
|
46 | total = end - start | |
|
47 | log.info('IP: %s Request to %s time: %.3fs [%s]' % ( | |
|
48 | 48 | get_ip_addr(request.environ), |
|
49 |
safe_str(get_access_path(request.environ)), |
|
|
49 | safe_str(get_access_path(request.environ)), total, | |
|
50 | get_user_agent(request. environ),) | |
|
50 | 51 | ) |
|
51 | 52 | |
|
52 | 53 | return response |
@@ -134,11 +134,11 b' class SimpleSvn(simplevcs.SimpleVCS):' | |||
|
134 | 134 | # SVN includes the whole path in it's requests, including |
|
135 | 135 | # subdirectories inside the repo. Therefore we have to search for |
|
136 | 136 | # the repo root directory. |
|
137 | if not is_valid_repo(repo_name, self.basepath, self.SCM): | |
|
137 | if not is_valid_repo(repo_name, self.base_path, self.SCM): | |
|
138 | 138 | current_path = '' |
|
139 | 139 | for component in repo_name.split('/'): |
|
140 | 140 | current_path += component |
|
141 | if is_valid_repo(current_path, self.basepath, self.SCM): | |
|
141 | if is_valid_repo(current_path, self.base_path, self.SCM): | |
|
142 | 142 | return current_path |
|
143 | 143 | current_path += '/' |
|
144 | 144 |
@@ -31,7 +31,8 b' from functools import wraps' | |||
|
31 | 31 | |
|
32 | 32 | import time |
|
33 | 33 | from paste.httpheaders import REMOTE_USER, AUTH_TYPE |
|
34 | from webob.exc import ( | |
|
34 | # TODO(marcink): check if we should use webob.exc here ? | |
|
35 | from pyramid.httpexceptions import ( | |
|
35 | 36 | HTTPNotFound, HTTPForbidden, HTTPNotAcceptable, HTTPInternalServerError) |
|
36 | 37 | |
|
37 | 38 | import rhodecode |
@@ -55,7 +56,7 b' from rhodecode.model import meta' | |||
|
55 | 56 | from rhodecode.model.db import User, Repository, PullRequest |
|
56 | 57 | from rhodecode.model.scm import ScmModel |
|
57 | 58 | from rhodecode.model.pull_request import PullRequestModel |
|
58 | from rhodecode.model.settings import SettingsModel | |
|
59 | from rhodecode.model.settings import SettingsModel, VcsSettingsModel | |
|
59 | 60 | |
|
60 | 61 | log = logging.getLogger(__name__) |
|
61 | 62 | |
@@ -103,14 +104,13 b' class SimpleVCS(object):' | |||
|
103 | 104 | 'repository$' # shadow repo |
|
104 | 105 | .format(slug_pat=SLUG_RE.pattern)) |
|
105 | 106 | |
|
106 |
def __init__(self, |
|
|
107 | def __init__(self, config, registry): | |
|
107 | 108 | self.registry = registry |
|
108 | self.application = application | |
|
109 | 109 | self.config = config |
|
110 | 110 | # re-populated by specialized middleware |
|
111 | 111 | self.repo_vcs_config = base.Config() |
|
112 | 112 | self.rhodecode_settings = SettingsModel().get_all_settings(cache=True) |
|
113 | self.basepath = rhodecode.CONFIG['base_path'] | |
|
113 | ||
|
114 | 114 | registry.rhodecode_settings = self.rhodecode_settings |
|
115 | 115 | # authenticate this VCS request using authfunc |
|
116 | 116 | auth_ret_code_detection = \ |
@@ -120,6 +120,10 b' class SimpleVCS(object):' | |||
|
120 | 120 | auth_ret_code_detection) |
|
121 | 121 | self.ip_addr = '0.0.0.0' |
|
122 | 122 | |
|
123 | @property | |
|
124 | def base_path(self): | |
|
125 | return self.repo_vcs_config.get(*VcsSettingsModel.PATH_SETTING) | |
|
126 | ||
|
123 | 127 | def set_repo_names(self, environ): |
|
124 | 128 | """ |
|
125 | 129 | This will populate the attributes acl_repo_name, url_repo_name, |
@@ -381,6 +385,8 b' class SimpleVCS(object):' | |||
|
381 | 385 | # Check if the shadow repo actually exists, in case someone refers |
|
382 | 386 | # to it, and it has been deleted because of successful merge. |
|
383 | 387 | if self.is_shadow_repo and not self.is_shadow_repo_dir: |
|
388 | log.debug('Shadow repo detected, and shadow repo dir `%s` is missing', | |
|
389 | self.is_shadow_repo_dir) | |
|
384 | 390 | return HTTPNotFound()(environ, start_response) |
|
385 | 391 | |
|
386 | 392 | # ====================================================================== |
@@ -493,7 +499,7 b' class SimpleVCS(object):' | |||
|
493 | 499 | # REQUEST HANDLING |
|
494 | 500 | # ====================================================================== |
|
495 | 501 | repo_path = os.path.join( |
|
496 | safe_str(self.basepath), safe_str(self.vcs_repo_name)) | |
|
502 | safe_str(self.base_path), safe_str(self.vcs_repo_name)) | |
|
497 | 503 | log.debug('Repository path is %s', repo_path) |
|
498 | 504 | |
|
499 | 505 | fix_PATH() |
@@ -168,11 +168,11 b' def detect_vcs_request(environ, backends' | |||
|
168 | 168 | |
|
169 | 169 | class VCSMiddleware(object): |
|
170 | 170 | |
|
171 |
def __init__(self, app, config, appenlight_client |
|
|
171 | def __init__(self, app, registry, config, appenlight_client): | |
|
172 | 172 | self.application = app |
|
173 | self.registry = registry | |
|
173 | 174 | self.config = config |
|
174 | 175 | self.appenlight_client = appenlight_client |
|
175 | self.registry = registry | |
|
176 | 176 | self.use_gzip = True |
|
177 | 177 | # order in which we check the middlewares, based on vcs.backends config |
|
178 | 178 | self.check_middlewares = config['vcs.backends'] |
@@ -193,7 +193,7 b' class VCSMiddleware(object):' | |||
|
193 | 193 | log.debug('VCSMiddleware: detecting vcs type.') |
|
194 | 194 | handler = detect_vcs_request(environ, self.check_middlewares) |
|
195 | 195 | if handler: |
|
196 |
app = handler(self. |
|
|
196 | app = handler(self.config, self.registry) | |
|
197 | 197 | |
|
198 | 198 | return app |
|
199 | 199 | |
@@ -212,7 +212,7 b' class VCSMiddleware(object):' | |||
|
212 | 212 | # check for type, presence in database and on filesystem |
|
213 | 213 | if not vcs_handler.is_valid_and_existing_repo( |
|
214 | 214 | vcs_handler.acl_repo_name, |
|
215 | vcs_handler.basepath, | |
|
215 | vcs_handler.base_path, | |
|
216 | 216 | vcs_handler.SCM): |
|
217 | 217 | return HTTPNotFound()(environ, start_response) |
|
218 | 218 |
@@ -578,9 +578,6 b' def rhodecode_config():' | |||
|
578 | 578 | blacklist = [ |
|
579 | 579 | 'rhodecode_license_key', |
|
580 | 580 | 'routes.map', |
|
581 | 'pylons.h', | |
|
582 | 'pylons.app_globals', | |
|
583 | 'pylons.environ_config', | |
|
584 | 581 | 'sqlalchemy.db1.url', |
|
585 | 582 | 'channelstream.secret', |
|
586 | 583 | 'beaker.session.secret', |
@@ -97,18 +97,14 b' def repo_name_slug(value):' | |||
|
97 | 97 | #============================================================================== |
|
98 | 98 | def get_repo_slug(request): |
|
99 | 99 | _repo = '' |
|
100 | if isinstance(request, Request): | |
|
101 | if hasattr(request, 'db_repo'): | |
|
102 | # if our requests has set db reference use it for name, this | |
|
103 | # translates the example.com/_<id> into proper repo names | |
|
104 | _repo = request.db_repo.repo_name | |
|
105 | elif getattr(request, 'matchdict', None): | |
|
106 | # pyramid | |
|
107 | _repo = request.matchdict.get('repo_name') | |
|
108 | 100 | |
|
109 | # TODO(marcink): remove after pylons migration... | |
|
110 | if not _repo: | |
|
111 | _repo = request.environ['pylons.routes_dict'].get('repo_name') | |
|
101 | if hasattr(request, 'db_repo'): | |
|
102 | # if our requests has set db reference use it for name, this | |
|
103 | # translates the example.com/_<id> into proper repo names | |
|
104 | _repo = request.db_repo.repo_name | |
|
105 | elif getattr(request, 'matchdict', None): | |
|
106 | # pyramid | |
|
107 | _repo = request.matchdict.get('repo_name') | |
|
112 | 108 | |
|
113 | 109 | if _repo: |
|
114 | 110 | _repo = _repo.rstrip('/') |
@@ -117,18 +113,14 b' def get_repo_slug(request):' | |||
|
117 | 113 | |
|
118 | 114 | def get_repo_group_slug(request): |
|
119 | 115 | _group = '' |
|
120 | if isinstance(request, Request): | |
|
121 | if hasattr(request, 'db_repo_group'): | |
|
122 | # if our requests has set db reference use it for name, this | |
|
123 | # translates the example.com/_<id> into proper repo group names | |
|
124 | _group = request.db_repo_group.group_name | |
|
125 | elif getattr(request, 'matchdict', None): | |
|
126 | # pyramid | |
|
127 | _group = request.matchdict.get('repo_group_name') | |
|
116 | if hasattr(request, 'db_repo_group'): | |
|
117 | # if our requests has set db reference use it for name, this | |
|
118 | # translates the example.com/_<id> into proper repo group names | |
|
119 | _group = request.db_repo_group.group_name | |
|
120 | elif getattr(request, 'matchdict', None): | |
|
121 | # pyramid | |
|
122 | _group = request.matchdict.get('repo_group_name') | |
|
128 | 123 | |
|
129 | # TODO(marcink): remove after pylons migration... | |
|
130 | if not _group: | |
|
131 | _group = request.environ['pylons.routes_dict'].get('group_name') | |
|
132 | 124 | |
|
133 | 125 | if _group: |
|
134 | 126 | _group = _group.rstrip('/') |
@@ -137,26 +129,21 b' def get_repo_group_slug(request):' | |||
|
137 | 129 | |
|
138 | 130 | def get_user_group_slug(request): |
|
139 | 131 | _user_group = '' |
|
140 | if isinstance(request, Request): | |
|
141 | 132 | |
|
142 |
|
|
|
143 |
|
|
|
144 |
|
|
|
145 |
|
|
|
146 |
|
|
|
133 | if hasattr(request, 'db_user_group'): | |
|
134 | _user_group = request.db_user_group.users_group_name | |
|
135 | elif getattr(request, 'matchdict', None): | |
|
136 | # pyramid | |
|
137 | _user_group = request.matchdict.get('user_group_id') | |
|
147 | 138 | |
|
148 |
|
|
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
|
152 |
|
|
|
153 |
|
|
|
154 |
|
|
|
155 |
|
|
|
156 | ||
|
157 | # TODO(marcink): remove after pylons migration... | |
|
158 | if not _user_group: | |
|
159 | _user_group = request.environ['pylons.routes_dict'].get('user_group_id') | |
|
139 | try: | |
|
140 | _user_group = UserGroup.get(_user_group) | |
|
141 | if _user_group: | |
|
142 | _user_group = _user_group.users_group_name | |
|
143 | except Exception: | |
|
144 | log.exception('Failed to get user group by id') | |
|
145 | # catch all failures here | |
|
146 | return None | |
|
160 | 147 | |
|
161 | 148 | return _user_group |
|
162 | 149 | |
@@ -438,7 +425,7 b' def get_enabled_hook_classes(ui_settings' | |||
|
438 | 425 | |
|
439 | 426 | def set_rhodecode_config(config): |
|
440 | 427 | """ |
|
441 |
Updates py |
|
|
428 | Updates pyramid config with new settings from database | |
|
442 | 429 | |
|
443 | 430 | :param config: |
|
444 | 431 | """ |
@@ -881,19 +868,6 b' def read_opensource_licenses():' | |||
|
881 | 868 | return _license_cache |
|
882 | 869 | |
|
883 | 870 | |
|
884 | def get_registry(request): | |
|
885 | """ | |
|
886 | Utility to get the pyramid registry from a request. During migration to | |
|
887 | pyramid we sometimes want to use the pyramid registry from pylons context. | |
|
888 | Therefore this utility returns `request.registry` for pyramid requests and | |
|
889 | uses `get_current_registry()` for pylons requests. | |
|
890 | """ | |
|
891 | try: | |
|
892 | return request.registry | |
|
893 | except AttributeError: | |
|
894 | return get_current_registry() | |
|
895 | ||
|
896 | ||
|
897 | 871 | def generate_platform_uuid(): |
|
898 | 872 | """ |
|
899 | 873 | Generates platform UUID based on it's name |
@@ -18,27 +18,6 b'' | |||
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | """ | |
|
22 | The application's model objects | |
|
23 | ||
|
24 | :example: | |
|
25 | ||
|
26 | .. code-block:: python | |
|
27 | ||
|
28 | from paste.deploy import appconfig | |
|
29 | from pylons import config | |
|
30 | from sqlalchemy import engine_from_config | |
|
31 | from rhodecode.config.environment import load_environment | |
|
32 | ||
|
33 | conf = appconfig('config:development.ini', relative_to = './../../') | |
|
34 | load_environment(conf.global_conf, conf.local_conf) | |
|
35 | ||
|
36 | engine = engine_from_config(config, 'sqlalchemy.') | |
|
37 | init_model(engine) | |
|
38 | # RUN YOUR CODE HERE | |
|
39 | ||
|
40 | """ | |
|
41 | ||
|
42 | 21 | |
|
43 | 22 | import logging |
|
44 | 23 |
@@ -26,7 +26,6 b' import logging' | |||
|
26 | 26 | import traceback |
|
27 | 27 | import collections |
|
28 | 28 | |
|
29 | from pylons.i18n.translation import _ | |
|
30 | 29 | from pyramid.threadlocal import get_current_registry, get_current_request |
|
31 | 30 | from sqlalchemy.sql.expression import null |
|
32 | 31 | from sqlalchemy.sql.functions import coalesce |
@@ -68,8 +67,8 b' class CommentsModel(BaseModel):' | |||
|
68 | 67 | user_objects.append(user_obj) |
|
69 | 68 | return user_objects |
|
70 | 69 | |
|
71 | def _get_renderer(self, global_renderer='rst'): | |
|
72 | request = get_current_request() | |
|
70 | def _get_renderer(self, global_renderer='rst', request=None): | |
|
71 | request = request or get_current_request() | |
|
73 | 72 | |
|
74 | 73 | try: |
|
75 | 74 | global_renderer = request.call_context.visual.default_renderer |
@@ -194,9 +193,11 b' class CommentsModel(BaseModel):' | |||
|
194 | 193 | if not text: |
|
195 | 194 | log.warning('Missing text for comment, skipping...') |
|
196 | 195 | return |
|
196 | request = get_current_request() | |
|
197 | _ = request.translate | |
|
197 | 198 | |
|
198 | 199 | if not renderer: |
|
199 | renderer = self._get_renderer() | |
|
200 | renderer = self._get_renderer(request=request) | |
|
200 | 201 | |
|
201 | 202 | repo = self._get_repo(repo) |
|
202 | 203 | user = self._get_user(user) |
@@ -268,7 +269,7 b' class CommentsModel(BaseModel):' | |||
|
268 | 269 | cs_author = repo.user |
|
269 | 270 | recipients += [cs_author] |
|
270 | 271 | |
|
271 | commit_comment_url = self.get_url(comment) | |
|
272 | commit_comment_url = self.get_url(comment, request=request) | |
|
272 | 273 | |
|
273 | 274 | target_repo_url = h.link_to( |
|
274 | 275 | repo.repo_name, |
@@ -48,7 +48,7 b' import formencode' | |||
|
48 | 48 | from pkg_resources import resource_filename |
|
49 | 49 | from formencode import All, Pipe |
|
50 | 50 | |
|
51 | from pylons.i18n.translation import _ | |
|
51 | from rhodecode.translation import temp_translation_factory as _ | |
|
52 | 52 | from pyramid.threadlocal import get_current_request |
|
53 | 53 | |
|
54 | 54 | from rhodecode import BACKENDS |
@@ -75,7 +75,9 b' form_renderer = RhodecodeFormZPTRenderer' | |||
|
75 | 75 | deform.Form.set_default_renderer(form_renderer) |
|
76 | 76 | |
|
77 | 77 | |
|
78 | def LoginForm(): | |
|
78 | def LoginForm(localizer): | |
|
79 | _ = localizer | |
|
80 | ||
|
79 | 81 | class _LoginForm(formencode.Schema): |
|
80 | 82 | allow_extra_fields = True |
|
81 | 83 | filter_extra_fields = True |
@@ -101,33 +103,37 b' def LoginForm():' | |||
|
101 | 103 | |
|
102 | 104 | remember = v.StringBoolean(if_missing=False) |
|
103 | 105 | |
|
104 | chained_validators = [v.ValidAuth()] | |
|
106 | chained_validators = [v.ValidAuth(localizer)] | |
|
105 | 107 | return _LoginForm |
|
106 | 108 | |
|
107 | 109 | |
|
108 |
def UserForm(edit=False, available_languages= |
|
|
110 | def UserForm(localizer, edit=False, available_languages=None, old_data=None): | |
|
111 | old_data = old_data or {} | |
|
112 | available_languages = available_languages or [] | |
|
113 | _ = localizer | |
|
114 | ||
|
109 | 115 | class _UserForm(formencode.Schema): |
|
110 | 116 | allow_extra_fields = True |
|
111 | 117 | filter_extra_fields = True |
|
112 | 118 | username = All(v.UnicodeString(strip=True, min=1, not_empty=True), |
|
113 | v.ValidUsername(edit, old_data)) | |
|
119 | v.ValidUsername(localizer, edit, old_data)) | |
|
114 | 120 | if edit: |
|
115 | 121 | new_password = All( |
|
116 | v.ValidPassword(), | |
|
122 | v.ValidPassword(localizer), | |
|
117 | 123 | v.UnicodeString(strip=False, min=6, max=72, not_empty=False) |
|
118 | 124 | ) |
|
119 | 125 | password_confirmation = All( |
|
120 | v.ValidPassword(), | |
|
126 | v.ValidPassword(localizer), | |
|
121 | 127 | v.UnicodeString(strip=False, min=6, max=72, not_empty=False), |
|
122 | 128 | ) |
|
123 | 129 | admin = v.StringBoolean(if_missing=False) |
|
124 | 130 | else: |
|
125 | 131 | password = All( |
|
126 | v.ValidPassword(), | |
|
132 | v.ValidPassword(localizer), | |
|
127 | 133 | v.UnicodeString(strip=False, min=6, max=72, not_empty=True) |
|
128 | 134 | ) |
|
129 | 135 | password_confirmation = All( |
|
130 | v.ValidPassword(), | |
|
136 | v.ValidPassword(localizer), | |
|
131 | 137 | v.UnicodeString(strip=False, min=6, max=72, not_empty=False) |
|
132 | 138 | ) |
|
133 | 139 | |
@@ -137,17 +143,18 b' def UserForm(edit=False, available_langu' | |||
|
137 | 143 | active = v.StringBoolean(if_missing=False) |
|
138 | 144 | firstname = v.UnicodeString(strip=True, min=1, not_empty=False) |
|
139 | 145 | lastname = v.UnicodeString(strip=True, min=1, not_empty=False) |
|
140 | email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data)) | |
|
146 | email = All(v.Email(not_empty=True), v.UniqSystemEmail(localizer, old_data)) | |
|
141 | 147 | extern_name = v.UnicodeString(strip=True) |
|
142 | 148 | extern_type = v.UnicodeString(strip=True) |
|
143 | 149 | language = v.OneOf(available_languages, hideList=False, |
|
144 | 150 | testValueList=True, if_missing=None) |
|
145 | chained_validators = [v.ValidPasswordsMatch()] | |
|
151 | chained_validators = [v.ValidPasswordsMatch(localizer)] | |
|
146 | 152 | return _UserForm |
|
147 | 153 | |
|
148 | 154 | |
|
149 | def UserGroupForm(edit=False, old_data=None, allow_disabled=False): | |
|
155 | def UserGroupForm(localizer, edit=False, old_data=None, allow_disabled=False): | |
|
150 | 156 | old_data = old_data or {} |
|
157 | _ = localizer | |
|
151 | 158 | |
|
152 | 159 | class _UserGroupForm(formencode.Schema): |
|
153 | 160 | allow_extra_fields = True |
@@ -155,7 +162,7 b' def UserGroupForm(edit=False, old_data=N' | |||
|
155 | 162 | |
|
156 | 163 | users_group_name = All( |
|
157 | 164 | v.UnicodeString(strip=True, min=1, not_empty=True), |
|
158 | v.ValidUserGroup(edit, old_data) | |
|
165 | v.ValidUserGroup(localizer, edit, old_data) | |
|
159 | 166 | ) |
|
160 | 167 | user_group_description = v.UnicodeString(strip=True, min=1, |
|
161 | 168 | not_empty=False) |
@@ -166,12 +173,13 b' def UserGroupForm(edit=False, old_data=N' | |||
|
166 | 173 | # this is user group owner |
|
167 | 174 | user = All( |
|
168 | 175 | v.UnicodeString(not_empty=True), |
|
169 | v.ValidRepoUser(allow_disabled)) | |
|
176 | v.ValidRepoUser(localizer, allow_disabled)) | |
|
170 | 177 | return _UserGroupForm |
|
171 | 178 | |
|
172 | 179 | |
|
173 | def RepoGroupForm(edit=False, old_data=None, available_groups=None, | |
|
174 |
|
|
|
180 | def RepoGroupForm(localizer, edit=False, old_data=None, available_groups=None, | |
|
181 | can_create_in_root=False, allow_disabled=False): | |
|
182 | _ = localizer | |
|
175 | 183 | old_data = old_data or {} |
|
176 | 184 | available_groups = available_groups or [] |
|
177 | 185 | |
@@ -180,7 +188,7 b' def RepoGroupForm(edit=False, old_data=N' | |||
|
180 | 188 | filter_extra_fields = False |
|
181 | 189 | |
|
182 | 190 | group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), |
|
183 | v.SlugifyName(),) | |
|
191 | v.SlugifyName(localizer),) | |
|
184 | 192 | group_description = v.UnicodeString(strip=True, min=1, |
|
185 | 193 | not_empty=False) |
|
186 | 194 | group_copy_permissions = v.StringBoolean(if_missing=False) |
@@ -189,53 +197,57 b' def RepoGroupForm(edit=False, old_data=N' | |||
|
189 | 197 | testValueList=True, not_empty=True) |
|
190 | 198 | enable_locking = v.StringBoolean(if_missing=False) |
|
191 | 199 | chained_validators = [ |
|
192 | v.ValidRepoGroup(edit, old_data, can_create_in_root)] | |
|
200 | v.ValidRepoGroup(localizer, edit, old_data, can_create_in_root)] | |
|
193 | 201 | |
|
194 | 202 | if edit: |
|
195 | 203 | # this is repo group owner |
|
196 | 204 | user = All( |
|
197 | 205 | v.UnicodeString(not_empty=True), |
|
198 | v.ValidRepoUser(allow_disabled)) | |
|
199 | ||
|
206 | v.ValidRepoUser(localizer, allow_disabled)) | |
|
200 | 207 | return _RepoGroupForm |
|
201 | 208 | |
|
202 | 209 | |
|
203 |
def RegisterForm(edit=False, old_data= |
|
|
210 | def RegisterForm(localizer, edit=False, old_data=None): | |
|
211 | _ = localizer | |
|
212 | old_data = old_data or {} | |
|
213 | ||
|
204 | 214 | class _RegisterForm(formencode.Schema): |
|
205 | 215 | allow_extra_fields = True |
|
206 | 216 | filter_extra_fields = True |
|
207 | 217 | username = All( |
|
208 | v.ValidUsername(edit, old_data), | |
|
218 | v.ValidUsername(localizer, edit, old_data), | |
|
209 | 219 | v.UnicodeString(strip=True, min=1, not_empty=True) |
|
210 | 220 | ) |
|
211 | 221 | password = All( |
|
212 | v.ValidPassword(), | |
|
222 | v.ValidPassword(localizer), | |
|
213 | 223 | v.UnicodeString(strip=False, min=6, max=72, not_empty=True) |
|
214 | 224 | ) |
|
215 | 225 | password_confirmation = All( |
|
216 | v.ValidPassword(), | |
|
226 | v.ValidPassword(localizer), | |
|
217 | 227 | v.UnicodeString(strip=False, min=6, max=72, not_empty=True) |
|
218 | 228 | ) |
|
219 | 229 | active = v.StringBoolean(if_missing=False) |
|
220 | 230 | firstname = v.UnicodeString(strip=True, min=1, not_empty=False) |
|
221 | 231 | lastname = v.UnicodeString(strip=True, min=1, not_empty=False) |
|
222 | email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data)) | |
|
232 | email = All(v.Email(not_empty=True), v.UniqSystemEmail(localizer, old_data)) | |
|
223 | 233 | |
|
224 | chained_validators = [v.ValidPasswordsMatch()] | |
|
225 | ||
|
234 | chained_validators = [v.ValidPasswordsMatch(localizer)] | |
|
226 | 235 | return _RegisterForm |
|
227 | 236 | |
|
228 | 237 | |
|
229 | def PasswordResetForm(): | |
|
238 | def PasswordResetForm(localizer): | |
|
239 | _ = localizer | |
|
240 | ||
|
230 | 241 | class _PasswordResetForm(formencode.Schema): |
|
231 | 242 | allow_extra_fields = True |
|
232 | 243 | filter_extra_fields = True |
|
233 | email = All(v.ValidSystemEmail(), v.Email(not_empty=True)) | |
|
244 | email = All(v.ValidSystemEmail(localizer), v.Email(not_empty=True)) | |
|
234 | 245 | return _PasswordResetForm |
|
235 | 246 | |
|
236 | 247 | |
|
237 |
def RepoForm(edit=False, old_data=None, repo_groups=None, |
|
|
238 | allow_disabled=False): | |
|
248 | def RepoForm(localizer, edit=False, old_data=None, repo_groups=None, | |
|
249 | landing_revs=None, allow_disabled=False): | |
|
250 | _ = localizer | |
|
239 | 251 | old_data = old_data or {} |
|
240 | 252 | repo_groups = repo_groups or [] |
|
241 | 253 | landing_revs = landing_revs or [] |
@@ -245,8 +257,8 b' def RepoForm(edit=False, old_data=None, ' | |||
|
245 | 257 | allow_extra_fields = True |
|
246 | 258 | filter_extra_fields = False |
|
247 | 259 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), |
|
248 | v.SlugifyName(), v.CannotHaveGitSuffix()) | |
|
249 | repo_group = All(v.CanWriteGroup(old_data), | |
|
260 | v.SlugifyName(localizer), v.CannotHaveGitSuffix(localizer)) | |
|
261 | repo_group = All(v.CanWriteGroup(localizer, old_data), | |
|
250 | 262 | v.OneOf(repo_groups, hideList=True)) |
|
251 | 263 | repo_type = v.OneOf(supported_backends, required=False, |
|
252 | 264 | if_missing=old_data.get('repo_type')) |
@@ -264,77 +276,91 b' def RepoForm(edit=False, old_data=None, ' | |||
|
264 | 276 | # this is repo owner |
|
265 | 277 | user = All( |
|
266 | 278 | v.UnicodeString(not_empty=True), |
|
267 | v.ValidRepoUser(allow_disabled)) | |
|
279 | v.ValidRepoUser(localizer, allow_disabled)) | |
|
268 | 280 | clone_uri_change = v.UnicodeString( |
|
269 | 281 | not_empty=False, if_missing=v.Missing) |
|
270 | 282 | |
|
271 | chained_validators = [v.ValidCloneUri(), | |
|
272 | v.ValidRepoName(edit, old_data)] | |
|
283 | chained_validators = [v.ValidCloneUri(localizer), | |
|
284 | v.ValidRepoName(localizer, edit, old_data)] | |
|
273 | 285 | return _RepoForm |
|
274 | 286 | |
|
275 | 287 | |
|
276 | def RepoPermsForm(): | |
|
288 | def RepoPermsForm(localizer): | |
|
289 | _ = localizer | |
|
290 | ||
|
277 | 291 | class _RepoPermsForm(formencode.Schema): |
|
278 | 292 | allow_extra_fields = True |
|
279 | 293 | filter_extra_fields = False |
|
280 | chained_validators = [v.ValidPerms(type_='repo')] | |
|
294 | chained_validators = [v.ValidPerms(localizer, type_='repo')] | |
|
281 | 295 | return _RepoPermsForm |
|
282 | 296 | |
|
283 | 297 | |
|
284 | def RepoGroupPermsForm(valid_recursive_choices): | |
|
298 | def RepoGroupPermsForm(localizer, valid_recursive_choices): | |
|
299 | _ = localizer | |
|
300 | ||
|
285 | 301 | class _RepoGroupPermsForm(formencode.Schema): |
|
286 | 302 | allow_extra_fields = True |
|
287 | 303 | filter_extra_fields = False |
|
288 | 304 | recursive = v.OneOf(valid_recursive_choices) |
|
289 | chained_validators = [v.ValidPerms(type_='repo_group')] | |
|
305 | chained_validators = [v.ValidPerms(localizer, type_='repo_group')] | |
|
290 | 306 | return _RepoGroupPermsForm |
|
291 | 307 | |
|
292 | 308 | |
|
293 | def UserGroupPermsForm(): | |
|
309 | def UserGroupPermsForm(localizer): | |
|
310 | _ = localizer | |
|
311 | ||
|
294 | 312 | class _UserPermsForm(formencode.Schema): |
|
295 | 313 | allow_extra_fields = True |
|
296 | 314 | filter_extra_fields = False |
|
297 | chained_validators = [v.ValidPerms(type_='user_group')] | |
|
315 | chained_validators = [v.ValidPerms(localizer, type_='user_group')] | |
|
298 | 316 | return _UserPermsForm |
|
299 | 317 | |
|
300 | 318 | |
|
301 | def RepoFieldForm(): | |
|
319 | def RepoFieldForm(localizer): | |
|
320 | _ = localizer | |
|
321 | ||
|
302 | 322 | class _RepoFieldForm(formencode.Schema): |
|
303 | 323 | filter_extra_fields = True |
|
304 | 324 | allow_extra_fields = True |
|
305 | 325 | |
|
306 | new_field_key = All(v.FieldKey(), | |
|
326 | new_field_key = All(v.FieldKey(localizer), | |
|
307 | 327 | v.UnicodeString(strip=True, min=3, not_empty=True)) |
|
308 | 328 | new_field_value = v.UnicodeString(not_empty=False, if_missing=u'') |
|
309 | 329 | new_field_type = v.OneOf(['str', 'unicode', 'list', 'tuple'], |
|
310 | 330 | if_missing='str') |
|
311 | 331 | new_field_label = v.UnicodeString(not_empty=False) |
|
312 | 332 | new_field_desc = v.UnicodeString(not_empty=False) |
|
313 | ||
|
314 | 333 | return _RepoFieldForm |
|
315 | 334 | |
|
316 | 335 | |
|
317 | def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(), | |
|
318 | repo_groups=[], landing_revs=[]): | |
|
336 | def RepoForkForm(localizer, edit=False, old_data=None, | |
|
337 | supported_backends=BACKENDS.keys(), repo_groups=None, | |
|
338 | landing_revs=None): | |
|
339 | _ = localizer | |
|
340 | old_data = old_data or {} | |
|
341 | repo_groups = repo_groups or [] | |
|
342 | landing_revs = landing_revs or [] | |
|
343 | ||
|
319 | 344 | class _RepoForkForm(formencode.Schema): |
|
320 | 345 | allow_extra_fields = True |
|
321 | 346 | filter_extra_fields = False |
|
322 | 347 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), |
|
323 | v.SlugifyName()) | |
|
324 | repo_group = All(v.CanWriteGroup(), | |
|
348 | v.SlugifyName(localizer)) | |
|
349 | repo_group = All(v.CanWriteGroup(localizer, ), | |
|
325 | 350 | v.OneOf(repo_groups, hideList=True)) |
|
326 | repo_type = All(v.ValidForkType(old_data), v.OneOf(supported_backends)) | |
|
351 | repo_type = All(v.ValidForkType(localizer, old_data), v.OneOf(supported_backends)) | |
|
327 | 352 | description = v.UnicodeString(strip=True, min=1, not_empty=True) |
|
328 | 353 | private = v.StringBoolean(if_missing=False) |
|
329 | 354 | copy_permissions = v.StringBoolean(if_missing=False) |
|
330 | 355 | fork_parent_id = v.UnicodeString() |
|
331 | chained_validators = [v.ValidForkName(edit, old_data)] | |
|
356 | chained_validators = [v.ValidForkName(localizer, edit, old_data)] | |
|
332 | 357 | landing_rev = v.OneOf(landing_revs, hideList=True) |
|
333 | ||
|
334 | 358 | return _RepoForkForm |
|
335 | 359 | |
|
336 | 360 | |
|
337 | def ApplicationSettingsForm(): | |
|
361 | def ApplicationSettingsForm(localizer): | |
|
362 | _ = localizer | |
|
363 | ||
|
338 | 364 | class _ApplicationSettingsForm(formencode.Schema): |
|
339 | 365 | allow_extra_fields = True |
|
340 | 366 | filter_extra_fields = False |
@@ -346,11 +372,12 b' def ApplicationSettingsForm():' | |||
|
346 | 372 | rhodecode_captcha_private_key = v.UnicodeString(strip=True, min=1, not_empty=False) |
|
347 | 373 | rhodecode_create_personal_repo_group = v.StringBoolean(if_missing=False) |
|
348 | 374 | rhodecode_personal_repo_group_pattern = v.UnicodeString(strip=True, min=1, not_empty=False) |
|
349 | ||
|
350 | 375 | return _ApplicationSettingsForm |
|
351 | 376 | |
|
352 | 377 | |
|
353 | def ApplicationVisualisationForm(): | |
|
378 | def ApplicationVisualisationForm(localizer): | |
|
379 | _ = localizer | |
|
380 | ||
|
354 | 381 | class _ApplicationVisualisationForm(formencode.Schema): |
|
355 | 382 | allow_extra_fields = True |
|
356 | 383 | filter_extra_fields = False |
@@ -370,11 +397,11 b' def ApplicationVisualisationForm():' | |||
|
370 | 397 | rhodecode_support_url = v.UnicodeString() |
|
371 | 398 | rhodecode_show_revision_number = v.StringBoolean(if_missing=False) |
|
372 | 399 | rhodecode_show_sha_length = v.Int(min=4, not_empty=True) |
|
373 | ||
|
374 | 400 | return _ApplicationVisualisationForm |
|
375 | 401 | |
|
376 | 402 | |
|
377 | 403 | class _BaseVcsSettingsForm(formencode.Schema): |
|
404 | ||
|
378 | 405 | allow_extra_fields = True |
|
379 | 406 | filter_extra_fields = False |
|
380 | 407 | hooks_changegroup_repo_size = v.StringBoolean(if_missing=False) |
@@ -403,48 +430,54 b' class _BaseVcsSettingsForm(formencode.Sc' | |||
|
403 | 430 | vcs_svn_proxy_http_server_url = v.UnicodeString(strip=True, if_missing=None) |
|
404 | 431 | |
|
405 | 432 | |
|
406 | def ApplicationUiSettingsForm(): | |
|
433 | def ApplicationUiSettingsForm(localizer): | |
|
434 | _ = localizer | |
|
435 | ||
|
407 | 436 | class _ApplicationUiSettingsForm(_BaseVcsSettingsForm): |
|
408 | 437 | web_push_ssl = v.StringBoolean(if_missing=False) |
|
409 | 438 | paths_root_path = All( |
|
410 | v.ValidPath(), | |
|
439 | v.ValidPath(localizer), | |
|
411 | 440 | v.UnicodeString(strip=True, min=1, not_empty=True) |
|
412 | 441 | ) |
|
413 | 442 | largefiles_usercache = All( |
|
414 | v.ValidPath(), | |
|
443 | v.ValidPath(localizer), | |
|
415 | 444 | v.UnicodeString(strip=True, min=2, not_empty=True)) |
|
416 | 445 | vcs_git_lfs_store_location = All( |
|
417 | v.ValidPath(), | |
|
446 | v.ValidPath(localizer), | |
|
418 | 447 | v.UnicodeString(strip=True, min=2, not_empty=True)) |
|
419 | 448 | extensions_hgsubversion = v.StringBoolean(if_missing=False) |
|
420 | 449 | extensions_hggit = v.StringBoolean(if_missing=False) |
|
421 | new_svn_branch = v.ValidSvnPattern(section='vcs_svn_branch') | |
|
422 | new_svn_tag = v.ValidSvnPattern(section='vcs_svn_tag') | |
|
423 | ||
|
450 | new_svn_branch = v.ValidSvnPattern(localizer, section='vcs_svn_branch') | |
|
451 | new_svn_tag = v.ValidSvnPattern(localizer, section='vcs_svn_tag') | |
|
424 | 452 | return _ApplicationUiSettingsForm |
|
425 | 453 | |
|
426 | 454 | |
|
427 | def RepoVcsSettingsForm(repo_name): | |
|
455 | def RepoVcsSettingsForm(localizer, repo_name): | |
|
456 | _ = localizer | |
|
457 | ||
|
428 | 458 | class _RepoVcsSettingsForm(_BaseVcsSettingsForm): |
|
429 | 459 | inherit_global_settings = v.StringBoolean(if_missing=False) |
|
430 | new_svn_branch = v.ValidSvnPattern( | |
|
460 | new_svn_branch = v.ValidSvnPattern(localizer, | |
|
431 | 461 | section='vcs_svn_branch', repo_name=repo_name) |
|
432 | new_svn_tag = v.ValidSvnPattern( | |
|
462 | new_svn_tag = v.ValidSvnPattern(localizer, | |
|
433 | 463 | section='vcs_svn_tag', repo_name=repo_name) |
|
434 | ||
|
435 | 464 | return _RepoVcsSettingsForm |
|
436 | 465 | |
|
437 | 466 | |
|
438 | def LabsSettingsForm(): | |
|
467 | def LabsSettingsForm(localizer): | |
|
468 | _ = localizer | |
|
469 | ||
|
439 | 470 | class _LabSettingsForm(formencode.Schema): |
|
440 | 471 | allow_extra_fields = True |
|
441 | 472 | filter_extra_fields = False |
|
442 | ||
|
443 | 473 | return _LabSettingsForm |
|
444 | 474 | |
|
445 | 475 | |
|
446 | 476 | def ApplicationPermissionsForm( |
|
447 |
register_choices, password_reset_choices, |
|
|
477 | localizer, register_choices, password_reset_choices, | |
|
478 | extern_activate_choices): | |
|
479 | _ = localizer | |
|
480 | ||
|
448 | 481 | class _DefaultPermissionsForm(formencode.Schema): |
|
449 | 482 | allow_extra_fields = True |
|
450 | 483 | filter_extra_fields = True |
@@ -454,12 +487,13 b' def ApplicationPermissionsForm(' | |||
|
454 | 487 | default_register_message = v.UnicodeString() |
|
455 | 488 | default_password_reset = v.OneOf(password_reset_choices) |
|
456 | 489 | default_extern_activate = v.OneOf(extern_activate_choices) |
|
457 | ||
|
458 | 490 | return _DefaultPermissionsForm |
|
459 | 491 | |
|
460 | 492 | |
|
461 | def ObjectPermissionsForm(repo_perms_choices, group_perms_choices, | |
|
493 | def ObjectPermissionsForm(localizer, repo_perms_choices, group_perms_choices, | |
|
462 | 494 | user_group_perms_choices): |
|
495 | _ = localizer | |
|
496 | ||
|
463 | 497 | class _ObjectPermissionsForm(formencode.Schema): |
|
464 | 498 | allow_extra_fields = True |
|
465 | 499 | filter_extra_fields = True |
@@ -469,13 +503,14 b' def ObjectPermissionsForm(repo_perms_cho' | |||
|
469 | 503 | default_repo_perm = v.OneOf(repo_perms_choices) |
|
470 | 504 | default_group_perm = v.OneOf(group_perms_choices) |
|
471 | 505 | default_user_group_perm = v.OneOf(user_group_perms_choices) |
|
472 | ||
|
473 | 506 | return _ObjectPermissionsForm |
|
474 | 507 | |
|
475 | 508 | |
|
476 | def UserPermissionsForm(create_choices, create_on_write_choices, | |
|
509 | def UserPermissionsForm(localizer, create_choices, create_on_write_choices, | |
|
477 | 510 | repo_group_create_choices, user_group_create_choices, |
|
478 | 511 | fork_choices, inherit_default_permissions_choices): |
|
512 | _ = localizer | |
|
513 | ||
|
479 | 514 | class _DefaultPermissionsForm(formencode.Schema): |
|
480 | 515 | allow_extra_fields = True |
|
481 | 516 | filter_extra_fields = True |
@@ -488,21 +523,24 b' def UserPermissionsForm(create_choices, ' | |||
|
488 | 523 | default_repo_group_create = v.OneOf(repo_group_create_choices) |
|
489 | 524 | default_fork_create = v.OneOf(fork_choices) |
|
490 | 525 | default_inherit_default_permissions = v.OneOf(inherit_default_permissions_choices) |
|
491 | ||
|
492 | 526 | return _DefaultPermissionsForm |
|
493 | 527 | |
|
494 | 528 | |
|
495 | def UserIndividualPermissionsForm(): | |
|
529 | def UserIndividualPermissionsForm(localizer): | |
|
530 | _ = localizer | |
|
531 | ||
|
496 | 532 | class _DefaultPermissionsForm(formencode.Schema): |
|
497 | 533 | allow_extra_fields = True |
|
498 | 534 | filter_extra_fields = True |
|
499 | 535 | |
|
500 | 536 | inherit_default_permissions = v.StringBoolean(if_missing=False) |
|
501 | ||
|
502 | 537 | return _DefaultPermissionsForm |
|
503 | 538 | |
|
504 | 539 | |
|
505 |
def DefaultsForm(edit=False, old_data= |
|
|
540 | def DefaultsForm(localizer, edit=False, old_data=None, supported_backends=BACKENDS.keys()): | |
|
541 | _ = localizer | |
|
542 | old_data = old_data or {} | |
|
543 | ||
|
506 | 544 | class _DefaultsForm(formencode.Schema): |
|
507 | 545 | allow_extra_fields = True |
|
508 | 546 | filter_extra_fields = True |
@@ -511,34 +549,39 b' def DefaultsForm(edit=False, old_data={}' | |||
|
511 | 549 | default_repo_enable_statistics = v.StringBoolean(if_missing=False) |
|
512 | 550 | default_repo_enable_downloads = v.StringBoolean(if_missing=False) |
|
513 | 551 | default_repo_enable_locking = v.StringBoolean(if_missing=False) |
|
514 | ||
|
515 | 552 | return _DefaultsForm |
|
516 | 553 | |
|
517 | 554 | |
|
518 | def AuthSettingsForm(): | |
|
555 | def AuthSettingsForm(localizer): | |
|
556 | _ = localizer | |
|
557 | ||
|
519 | 558 | class _AuthSettingsForm(formencode.Schema): |
|
520 | 559 | allow_extra_fields = True |
|
521 | 560 | filter_extra_fields = True |
|
522 | auth_plugins = All(v.ValidAuthPlugins(), | |
|
523 | v.UniqueListFromString()(not_empty=True)) | |
|
524 | ||
|
561 | auth_plugins = All(v.ValidAuthPlugins(localizer), | |
|
562 | v.UniqueListFromString(localizer)(not_empty=True)) | |
|
525 | 563 | return _AuthSettingsForm |
|
526 | 564 | |
|
527 | 565 | |
|
528 | def UserExtraEmailForm(): | |
|
566 | def UserExtraEmailForm(localizer): | |
|
567 | _ = localizer | |
|
568 | ||
|
529 | 569 | class _UserExtraEmailForm(formencode.Schema): |
|
530 | email = All(v.UniqSystemEmail(), v.Email(not_empty=True)) | |
|
570 | email = All(v.UniqSystemEmail(localizer), v.Email(not_empty=True)) | |
|
531 | 571 | return _UserExtraEmailForm |
|
532 | 572 | |
|
533 | 573 | |
|
534 | def UserExtraIpForm(): | |
|
574 | def UserExtraIpForm(localizer): | |
|
575 | _ = localizer | |
|
576 | ||
|
535 | 577 | class _UserExtraIpForm(formencode.Schema): |
|
536 | ip = v.ValidIp()(not_empty=True) | |
|
578 | ip = v.ValidIp(localizer)(not_empty=True) | |
|
537 | 579 | return _UserExtraIpForm |
|
538 | 580 | |
|
539 | 581 | |
|
582 | def PullRequestForm(localizer, repo_id): | |
|
583 | _ = localizer | |
|
540 | 584 | |
|
541 | def PullRequestForm(repo_id): | |
|
542 | 585 | class ReviewerForm(formencode.Schema): |
|
543 | 586 | user_id = v.Int(not_empty=True) |
|
544 | 587 | reasons = All() |
@@ -553,8 +596,8 b' def PullRequestForm(repo_id):' | |||
|
553 | 596 | source_ref = v.UnicodeString(strip=True, required=True) |
|
554 | 597 | target_repo = v.UnicodeString(strip=True, required=True) |
|
555 | 598 | target_ref = v.UnicodeString(strip=True, required=True) |
|
556 | revisions = All(#v.NotReviewedRevisions(repo_id)(), | |
|
557 | v.UniqueList()(not_empty=True)) | |
|
599 | revisions = All(#v.NotReviewedRevisions(localizer, repo_id)(), | |
|
600 | v.UniqueList(localizer)(not_empty=True)) | |
|
558 | 601 | review_members = formencode.ForEach(ReviewerForm()) |
|
559 | 602 | pullrequest_title = v.UnicodeString(strip=True, required=True) |
|
560 | 603 | pullrequest_desc = v.UnicodeString(strip=True, required=False) |
@@ -562,9 +605,11 b' def PullRequestForm(repo_id):' | |||
|
562 | 605 | return _PullRequestForm |
|
563 | 606 | |
|
564 | 607 | |
|
565 | def IssueTrackerPatternsForm(): | |
|
608 | def IssueTrackerPatternsForm(localizer): | |
|
609 | _ = localizer | |
|
610 | ||
|
566 | 611 | class _IssueTrackerPatternsForm(formencode.Schema): |
|
567 | 612 | allow_extra_fields = True |
|
568 | 613 | filter_extra_fields = False |
|
569 | chained_validators = [v.ValidPattern()] | |
|
614 | chained_validators = [v.ValidPattern(localizer)] | |
|
570 | 615 | return _IssueTrackerPatternsForm |
@@ -30,7 +30,7 b' import logging' | |||
|
30 | 30 | import cStringIO |
|
31 | 31 | import pkg_resources |
|
32 | 32 | |
|
33 | from pylons.i18n.translation import _ | |
|
33 | from rhodecode.translation import temp_translation_factory as _ | |
|
34 | 34 | from sqlalchemy import func |
|
35 | 35 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
36 | 36 |
@@ -26,7 +26,7 b' import logging' | |||
|
26 | 26 | import traceback |
|
27 | 27 | |
|
28 | 28 | import datetime |
|
29 | from pylons.i18n.translation import _ | |
|
29 | from rhodecode.translation import temp_translation_factory as _ | |
|
30 | 30 | |
|
31 | 31 | import ipaddress |
|
32 | 32 | from sqlalchemy.exc import DatabaseError |
@@ -754,14 +754,12 b' class UserModel(BaseModel):' | |||
|
754 | 754 | :param user: |
|
755 | 755 | :param email: |
|
756 | 756 | """ |
|
757 | from rhodecode.model import forms | |
|
758 | form = forms.UserExtraEmailForm()() | |
|
759 | data = form.to_python({'email': email}) | |
|
757 | ||
|
760 | 758 | user = self._get_user(user) |
|
761 | 759 | |
|
762 | 760 | obj = UserEmailMap() |
|
763 | 761 | obj.user = user |
|
764 |
obj.email = |
|
|
762 | obj.email = email | |
|
765 | 763 | self.sa.add(obj) |
|
766 | 764 | return obj |
|
767 | 765 | |
@@ -811,14 +809,11 b' class UserModel(BaseModel):' | |||
|
811 | 809 | :param user: |
|
812 | 810 | :param ip: |
|
813 | 811 | """ |
|
814 | from rhodecode.model import forms | |
|
815 | form = forms.UserExtraIpForm()() | |
|
816 | data = form.to_python({'ip': ip}) | |
|
812 | ||
|
817 | 813 | user = self._get_user(user) |
|
818 | ||
|
819 | 814 | obj = UserIpMap() |
|
820 | 815 | obj.user = user |
|
821 |
obj.ip_addr = |
|
|
816 | obj.ip_addr = ip | |
|
822 | 817 | obj.description = description |
|
823 | 818 | self.sa.add(obj) |
|
824 | 819 | return obj |
@@ -22,10 +22,11 b'' | |||
|
22 | 22 | Set of generic validators |
|
23 | 23 | """ |
|
24 | 24 | |
|
25 | import logging | |
|
25 | ||
|
26 | 26 | import os |
|
27 | 27 | import re |
|
28 | from collections import defaultdict | |
|
28 | import logging | |
|
29 | import collections | |
|
29 | 30 | |
|
30 | 31 | import formencode |
|
31 | 32 | import ipaddress |
@@ -33,7 +34,7 b' from formencode.validators import (' | |||
|
33 | 34 | UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, |
|
34 | 35 | NotEmpty, IPAddress, CIDR, String, FancyValidator |
|
35 | 36 | ) |
|
36 | from pylons.i18n.translation import _ | |
|
37 | ||
|
37 | 38 | from sqlalchemy.sql.expression import true |
|
38 | 39 | from sqlalchemy.util import OrderedSet |
|
39 | 40 | from webhelpers.pylonslib.secure_form import authentication_token |
@@ -62,17 +63,11 b' log = logging.getLogger(__name__)' | |||
|
62 | 63 | class _Missing(object): |
|
63 | 64 | pass |
|
64 | 65 | |
|
66 | ||
|
65 | 67 | Missing = _Missing() |
|
66 | 68 | |
|
67 | 69 | |
|
68 | class StateObj(object): | |
|
69 | """ | |
|
70 | this is needed to translate the messages using _() in validators | |
|
71 | """ | |
|
72 | _ = staticmethod(_) | |
|
73 | ||
|
74 | ||
|
75 | def M(self, key, state=None, **kwargs): | |
|
70 | def M(self, key, state, **kwargs): | |
|
76 | 71 | """ |
|
77 | 72 | returns string from self.message based on given key, |
|
78 | 73 | passed kw params are used to substitute %(named)s params inside |
@@ -81,16 +76,16 b' def M(self, key, state=None, **kwargs):' | |||
|
81 | 76 | :param msg: |
|
82 | 77 | :param state: |
|
83 | 78 | """ |
|
84 | if state is None: | |
|
85 | state = StateObj() | |
|
86 | else: | |
|
87 | state._ = staticmethod(_) | |
|
79 | ||
|
80 | #state._ = staticmethod(_) | |
|
88 | 81 | # inject validator into state object |
|
89 | 82 | return self.message(key, state, **kwargs) |
|
90 | 83 | |
|
91 | 84 | |
|
92 | def UniqueList(convert=None): | |
|
93 | class _UniqueList(formencode.FancyValidator): | |
|
85 | def UniqueList(localizer, convert=None): | |
|
86 | _ = localizer | |
|
87 | ||
|
88 | class _validator(formencode.FancyValidator): | |
|
94 | 89 | """ |
|
95 | 90 | Unique List ! |
|
96 | 91 | """ |
@@ -123,20 +118,23 b' def UniqueList(convert=None):' | |||
|
123 | 118 | |
|
124 | 119 | def empty_value(self, value): |
|
125 | 120 | return [] |
|
126 | ||
|
127 | return _UniqueList | |
|
121 | return _validator | |
|
128 | 122 | |
|
129 | 123 | |
|
130 | def UniqueListFromString(): | |
|
131 | class _UniqueListFromString(UniqueList()): | |
|
124 | def UniqueListFromString(localizer): | |
|
125 | _ = localizer | |
|
126 | ||
|
127 | class _validator(UniqueList(localizer)): | |
|
132 | 128 | def _to_python(self, value, state): |
|
133 | 129 | if isinstance(value, basestring): |
|
134 | 130 | value = aslist(value, ',') |
|
135 |
return super(_ |
|
|
136 | return _UniqueListFromString | |
|
131 | return super(_validator, self)._to_python(value, state) | |
|
132 | return _validator | |
|
137 | 133 | |
|
138 | 134 | |
|
139 | def ValidSvnPattern(section, repo_name=None): | |
|
135 | def ValidSvnPattern(localizer, section, repo_name=None): | |
|
136 | _ = localizer | |
|
137 | ||
|
140 | 138 | class _validator(formencode.validators.FancyValidator): |
|
141 | 139 | messages = { |
|
142 | 140 | 'pattern_exists': _(u'Pattern already exists'), |
@@ -154,7 +152,10 b' def ValidSvnPattern(section, repo_name=N' | |||
|
154 | 152 | return _validator |
|
155 | 153 | |
|
156 | 154 | |
|
157 |
def ValidUsername(edit=False, old_data= |
|
|
155 | def ValidUsername(localizer, edit=False, old_data=None): | |
|
156 | _ = localizer | |
|
157 | old_data = old_data or {} | |
|
158 | ||
|
158 | 159 | class _validator(formencode.validators.FancyValidator): |
|
159 | 160 | messages = { |
|
160 | 161 | 'username_exists': _(u'Username "%(username)s" already exists'), |
@@ -187,13 +188,9 b' def ValidUsername(edit=False, old_data={' | |||
|
187 | 188 | return _validator |
|
188 | 189 | |
|
189 | 190 | |
|
190 | def ValidRegex(msg=None): | |
|
191 | class _validator(formencode.validators.Regex): | |
|
192 | messages = {'invalid': msg or _(u'The input is not valid')} | |
|
193 | return _validator | |
|
191 | def ValidRepoUser(localizer, allow_disabled=False): | |
|
192 | _ = localizer | |
|
194 | 193 | |
|
195 | ||
|
196 | def ValidRepoUser(allow_disabled=False): | |
|
197 | 194 | class _validator(formencode.validators.FancyValidator): |
|
198 | 195 | messages = { |
|
199 | 196 | 'invalid_username': _(u'Username %(username)s is not valid'), |
@@ -213,11 +210,13 b' def ValidRepoUser(allow_disabled=False):' | |||
|
213 | 210 | raise formencode.Invalid( |
|
214 | 211 | msg, value, state, error_dict={'username': msg} |
|
215 | 212 | ) |
|
216 | ||
|
217 | 213 | return _validator |
|
218 | 214 | |
|
219 | 215 | |
|
220 |
def ValidUserGroup(edit=False, old_data= |
|
|
216 | def ValidUserGroup(localizer, edit=False, old_data=None): | |
|
217 | _ = localizer | |
|
218 | old_data = old_data or {} | |
|
219 | ||
|
221 | 220 | class _validator(formencode.validators.FancyValidator): |
|
222 | 221 | messages = { |
|
223 | 222 | 'invalid_group': _(u'Invalid user group name'), |
@@ -254,11 +253,13 b' def ValidUserGroup(edit=False, old_data=' | |||
|
254 | 253 | raise formencode.Invalid( |
|
255 | 254 | msg, value, state, error_dict={'users_group_name': msg} |
|
256 | 255 | ) |
|
257 | ||
|
258 | 256 | return _validator |
|
259 | 257 | |
|
260 | 258 | |
|
261 |
def ValidRepoGroup(edit=False, old_data= |
|
|
259 | def ValidRepoGroup(localizer, edit=False, old_data=None, can_create_in_root=False): | |
|
260 | _ = localizer | |
|
261 | old_data = old_data or {} | |
|
262 | ||
|
262 | 263 | class _validator(formencode.validators.FancyValidator): |
|
263 | 264 | messages = { |
|
264 | 265 | 'group_parent_id': _(u'Cannot assign this group as parent'), |
@@ -375,11 +376,12 b' def ValidRepoGroup(edit=False, old_data=' | |||
|
375 | 376 | msg = M(self, 'repo_exists', state, group_name=group_name) |
|
376 | 377 | raise formencode.Invalid( |
|
377 | 378 | msg, value, state, error_dict={'group_name': msg}) |
|
378 | ||
|
379 | 379 | return _validator |
|
380 | 380 | |
|
381 | 381 | |
|
382 | def ValidPassword(): | |
|
382 | def ValidPassword(localizer): | |
|
383 | _ = localizer | |
|
384 | ||
|
383 | 385 | class _validator(formencode.validators.FancyValidator): |
|
384 | 386 | messages = { |
|
385 | 387 | 'invalid_password': |
@@ -395,24 +397,11 b' def ValidPassword():' | |||
|
395 | 397 | return _validator |
|
396 | 398 | |
|
397 | 399 | |
|
398 |
def Valid |
|
|
399 | class _validator(formencode.validators.FancyValidator): | |
|
400 | messages = { | |
|
401 | 'invalid_password': _(u'Invalid old password') | |
|
402 | } | |
|
400 | def ValidPasswordsMatch( | |
|
401 | localizer, passwd='new_password', | |
|
402 | passwd_confirmation='password_confirmation'): | |
|
403 | _ = localizer | |
|
403 | 404 | |
|
404 | def validate_python(self, value, state): | |
|
405 | from rhodecode.authentication.base import authenticate, HTTP_TYPE | |
|
406 | if not authenticate(username, value, '', HTTP_TYPE): | |
|
407 | msg = M(self, 'invalid_password', state) | |
|
408 | raise formencode.Invalid( | |
|
409 | msg, value, state, error_dict={'current_password': msg} | |
|
410 | ) | |
|
411 | return _validator | |
|
412 | ||
|
413 | ||
|
414 | def ValidPasswordsMatch( | |
|
415 | passwd='new_password', passwd_confirmation='password_confirmation'): | |
|
416 | 405 | class _validator(formencode.validators.FancyValidator): |
|
417 | 406 | messages = { |
|
418 | 407 | 'password_mismatch': _(u'Passwords do not match'), |
@@ -430,7 +419,9 b' def ValidPasswordsMatch(' | |||
|
430 | 419 | return _validator |
|
431 | 420 | |
|
432 | 421 | |
|
433 | def ValidAuth(): | |
|
422 | def ValidAuth(localizer): | |
|
423 | _ = localizer | |
|
424 | ||
|
434 | 425 | class _validator(formencode.validators.FancyValidator): |
|
435 | 426 | messages = { |
|
436 | 427 | 'invalid_password': _(u'invalid password'), |
@@ -464,7 +455,9 b' def ValidAuth():' | |||
|
464 | 455 | return _validator |
|
465 | 456 | |
|
466 | 457 | |
|
467 | def ValidAuthToken(): | |
|
458 | def ValidAuthToken(localizer): | |
|
459 | _ = localizer | |
|
460 | ||
|
468 | 461 | class _validator(formencode.validators.FancyValidator): |
|
469 | 462 | messages = { |
|
470 | 463 | 'invalid_token': _(u'Token mismatch') |
@@ -477,7 +470,10 b' def ValidAuthToken():' | |||
|
477 | 470 | return _validator |
|
478 | 471 | |
|
479 | 472 | |
|
480 |
def ValidRepoName(edit=False, old_data= |
|
|
473 | def ValidRepoName(localizer, edit=False, old_data=None): | |
|
474 | old_data = old_data or {} | |
|
475 | _ = localizer | |
|
476 | ||
|
481 | 477 | class _validator(formencode.validators.FancyValidator): |
|
482 | 478 | messages = { |
|
483 | 479 | 'invalid_repo_name': |
@@ -558,11 +554,15 b' def ValidRepoName(edit=False, old_data={' | |||
|
558 | 554 | return _validator |
|
559 | 555 | |
|
560 | 556 | |
|
561 | def ValidForkName(*args, **kwargs): | |
|
562 | return ValidRepoName(*args, **kwargs) | |
|
557 | def ValidForkName(localizer, *args, **kwargs): | |
|
558 | _ = localizer | |
|
559 | ||
|
560 | return ValidRepoName(localizer, *args, **kwargs) | |
|
563 | 561 | |
|
564 | 562 | |
|
565 | def SlugifyName(): | |
|
563 | def SlugifyName(localizer): | |
|
564 | _ = localizer | |
|
565 | ||
|
566 | 566 | class _validator(formencode.validators.FancyValidator): |
|
567 | 567 | |
|
568 | 568 | def _to_python(self, value, state): |
@@ -570,11 +570,12 b' def SlugifyName():' | |||
|
570 | 570 | |
|
571 | 571 | def validate_python(self, value, state): |
|
572 | 572 | pass |
|
573 | ||
|
574 | 573 | return _validator |
|
575 | 574 | |
|
576 | 575 | |
|
577 | def CannotHaveGitSuffix(): | |
|
576 | def CannotHaveGitSuffix(localizer): | |
|
577 | _ = localizer | |
|
578 | ||
|
578 | 579 | class _validator(formencode.validators.FancyValidator): |
|
579 | 580 | messages = { |
|
580 | 581 | 'has_git_suffix': |
@@ -590,11 +591,12 b' def CannotHaveGitSuffix():' | |||
|
590 | 591 | self, 'has_git_suffix', state) |
|
591 | 592 | raise formencode.Invalid( |
|
592 | 593 | msg, value, state, error_dict={'repo_name': msg}) |
|
593 | ||
|
594 | 594 | return _validator |
|
595 | 595 | |
|
596 | 596 | |
|
597 | def ValidCloneUri(): | |
|
597 | def ValidCloneUri(localizer): | |
|
598 | _ = localizer | |
|
599 | ||
|
598 | 600 | class InvalidCloneUrl(Exception): |
|
599 | 601 | allowed_prefixes = () |
|
600 | 602 | |
@@ -652,19 +654,22 b' def ValidCloneUri():' | |||
|
652 | 654 | url_handler(repo_type, url) |
|
653 | 655 | except InvalidCloneUrl as e: |
|
654 | 656 | log.warning(e) |
|
655 | msg = M(self, 'invalid_clone_uri', rtype=repo_type, | |
|
657 | msg = M(self, 'invalid_clone_uri', state, rtype=repo_type, | |
|
656 | 658 | allowed_prefixes=','.join(e.allowed_prefixes)) |
|
657 | 659 | raise formencode.Invalid(msg, value, state, |
|
658 | 660 | error_dict={'clone_uri': msg}) |
|
659 | 661 | except Exception: |
|
660 | 662 | log.exception('Url validation failed') |
|
661 | msg = M(self, 'clone_uri', rtype=repo_type) | |
|
663 | msg = M(self, 'clone_uri', state, rtype=repo_type) | |
|
662 | 664 | raise formencode.Invalid(msg, value, state, |
|
663 | 665 | error_dict={'clone_uri': msg}) |
|
664 | 666 | return _validator |
|
665 | 667 | |
|
666 | 668 | |
|
667 |
def ValidForkType(old_data= |
|
|
669 | def ValidForkType(localizer, old_data=None): | |
|
670 | _ = localizer | |
|
671 | old_data = old_data or {} | |
|
672 | ||
|
668 | 673 | class _validator(formencode.validators.FancyValidator): |
|
669 | 674 | messages = { |
|
670 | 675 | 'invalid_fork_type': _(u'Fork have to be the same type as parent') |
@@ -679,7 +684,9 b' def ValidForkType(old_data={}):' | |||
|
679 | 684 | return _validator |
|
680 | 685 | |
|
681 | 686 | |
|
682 | def CanWriteGroup(old_data=None): | |
|
687 | def CanWriteGroup(localizer, old_data=None): | |
|
688 | _ = localizer | |
|
689 | ||
|
683 | 690 | class _validator(formencode.validators.FancyValidator): |
|
684 | 691 | messages = { |
|
685 | 692 | 'permission_denied': _( |
@@ -730,11 +737,11 b' def CanWriteGroup(old_data=None):' | |||
|
730 | 737 | raise formencode.Invalid( |
|
731 | 738 | msg, value, state, error_dict={'repo_type': msg} |
|
732 | 739 | ) |
|
733 | ||
|
734 | 740 | return _validator |
|
735 | 741 | |
|
736 | 742 | |
|
737 | def ValidPerms(type_='repo'): | |
|
743 | def ValidPerms(localizer, type_='repo'): | |
|
744 | _ = localizer | |
|
738 | 745 | if type_ == 'repo_group': |
|
739 | 746 | EMPTY_PERM = 'group.none' |
|
740 | 747 | elif type_ == 'repo': |
@@ -756,8 +763,8 b" def ValidPerms(type_='repo'):" | |||
|
756 | 763 | |
|
757 | 764 | # Read the perm_new_member/perm_del_member attributes and group |
|
758 | 765 | # them by they IDs |
|
759 | new_perms_group = defaultdict(dict) | |
|
760 | del_perms_group = defaultdict(dict) | |
|
766 | new_perms_group = collections.defaultdict(dict) | |
|
767 | del_perms_group = collections.defaultdict(dict) | |
|
761 | 768 | for k, v in value.copy().iteritems(): |
|
762 | 769 | if k.startswith('perm_del_member'): |
|
763 | 770 | # delete from org storage so we don't process that later |
@@ -851,29 +858,9 b" def ValidPerms(type_='repo'):" | |||
|
851 | 858 | return _validator |
|
852 | 859 | |
|
853 | 860 | |
|
854 | def ValidSettings(): | |
|
855 | class _validator(formencode.validators.FancyValidator): | |
|
856 | def _to_python(self, value, state): | |
|
857 | # settings form for users that are not admin | |
|
858 | # can't edit certain parameters, it's extra backup if they mangle | |
|
859 | # with forms | |
|
860 | ||
|
861 | forbidden_params = [ | |
|
862 | 'user', 'repo_type', 'repo_enable_locking', | |
|
863 | 'repo_enable_downloads', 'repo_enable_statistics' | |
|
864 | ] | |
|
861 | def ValidPath(localizer): | |
|
862 | _ = localizer | |
|
865 | 863 | |
|
866 | for param in forbidden_params: | |
|
867 | if param in value: | |
|
868 | del value[param] | |
|
869 | return value | |
|
870 | ||
|
871 | def validate_python(self, value, state): | |
|
872 | pass | |
|
873 | return _validator | |
|
874 | ||
|
875 | ||
|
876 | def ValidPath(): | |
|
877 | 864 | class _validator(formencode.validators.FancyValidator): |
|
878 | 865 | messages = { |
|
879 | 866 | 'invalid_path': _(u'This is not a valid path') |
@@ -888,7 +875,10 b' def ValidPath():' | |||
|
888 | 875 | return _validator |
|
889 | 876 | |
|
890 | 877 | |
|
891 |
def UniqSystemEmail(old_data= |
|
|
878 | def UniqSystemEmail(localizer, old_data=None): | |
|
879 | _ = localizer | |
|
880 | old_data = old_data or {} | |
|
881 | ||
|
892 | 882 | class _validator(formencode.validators.FancyValidator): |
|
893 | 883 | messages = { |
|
894 | 884 | 'email_taken': _(u'This e-mail address is already taken') |
@@ -908,7 +898,9 b' def UniqSystemEmail(old_data={}):' | |||
|
908 | 898 | return _validator |
|
909 | 899 | |
|
910 | 900 | |
|
911 | def ValidSystemEmail(): | |
|
901 | def ValidSystemEmail(localizer): | |
|
902 | _ = localizer | |
|
903 | ||
|
912 | 904 | class _validator(formencode.validators.FancyValidator): |
|
913 | 905 | messages = { |
|
914 | 906 | 'non_existing_email': _(u'e-mail "%(email)s" does not exist.') |
@@ -924,11 +916,11 b' def ValidSystemEmail():' | |||
|
924 | 916 | raise formencode.Invalid( |
|
925 | 917 | msg, value, state, error_dict={'email': msg} |
|
926 | 918 | ) |
|
927 | ||
|
928 | 919 | return _validator |
|
929 | 920 | |
|
930 | 921 | |
|
931 | def NotReviewedRevisions(repo_id): | |
|
922 | def NotReviewedRevisions(localizer, repo_id): | |
|
923 | _ = localizer | |
|
932 | 924 | class _validator(formencode.validators.FancyValidator): |
|
933 | 925 | messages = { |
|
934 | 926 | 'rev_already_reviewed': |
@@ -960,7 +952,9 b' def NotReviewedRevisions(repo_id):' | |||
|
960 | 952 | return _validator |
|
961 | 953 | |
|
962 | 954 | |
|
963 | def ValidIp(): | |
|
955 | def ValidIp(localizer): | |
|
956 | _ = localizer | |
|
957 | ||
|
964 | 958 | class _validator(CIDR): |
|
965 | 959 | messages = { |
|
966 | 960 | 'badFormat': _(u'Please enter a valid IPv4 or IpV6 address'), |
@@ -984,11 +978,12 b' def ValidIp():' | |||
|
984 | 978 | except ValueError: |
|
985 | 979 | raise formencode.Invalid(self.message('badFormat', state), |
|
986 | 980 | value, state) |
|
987 | ||
|
988 | 981 | return _validator |
|
989 | 982 | |
|
990 | 983 | |
|
991 | def FieldKey(): | |
|
984 | def FieldKey(localizer): | |
|
985 | _ = localizer | |
|
986 | ||
|
992 | 987 | class _validator(formencode.validators.FancyValidator): |
|
993 | 988 | messages = { |
|
994 | 989 | 'badFormat': _( |
@@ -1003,7 +998,9 b' def FieldKey():' | |||
|
1003 | 998 | return _validator |
|
1004 | 999 | |
|
1005 | 1000 | |
|
1006 | def ValidAuthPlugins(): | |
|
1001 | def ValidAuthPlugins(localizer): | |
|
1002 | _ = localizer | |
|
1003 | ||
|
1007 | 1004 | class _validator(formencode.validators.FancyValidator): |
|
1008 | 1005 | messages = { |
|
1009 | 1006 | 'import_duplicate': _( |
@@ -1033,11 +1030,11 b' def ValidAuthPlugins():' | |||
|
1033 | 1030 | log.exception( |
|
1034 | 1031 | 'Exception during import of auth legacy plugin "{}"' |
|
1035 | 1032 | .format(plugin_id)) |
|
1036 | msg = M(self, 'import_error', plugin_id=plugin_id) | |
|
1033 | msg = M(self, 'import_error', state, plugin_id=plugin_id) | |
|
1037 | 1034 | raise formencode.Invalid(msg, value, state) |
|
1038 | 1035 | |
|
1039 | 1036 | if not hasattr(plugin, 'includeme'): |
|
1040 | msg = M(self, 'missing_includeme', plugin_id=plugin_id) | |
|
1037 | msg = M(self, 'missing_includeme', state, plugin_id=plugin_id) | |
|
1041 | 1038 | raise formencode.Invalid(msg, value, state) |
|
1042 | 1039 | |
|
1043 | 1040 | return plugin |
@@ -1051,7 +1048,7 b' def ValidAuthPlugins():' | |||
|
1051 | 1048 | plugin = loadplugin(plugin_id) |
|
1052 | 1049 | |
|
1053 | 1050 | if plugin is None: |
|
1054 | msg = M(self, 'no_plugin', plugin_id=plugin_id) | |
|
1051 | msg = M(self, 'no_plugin', state, plugin_id=plugin_id) | |
|
1055 | 1052 | raise formencode.Invalid(msg, value, state) |
|
1056 | 1053 | |
|
1057 | 1054 | return plugin |
@@ -1074,13 +1071,13 b' def ValidAuthPlugins():' | |||
|
1074 | 1071 | next_to_load=plugin) |
|
1075 | 1072 | raise formencode.Invalid(msg, value, state) |
|
1076 | 1073 | unique_names[plugin.name] = plugin |
|
1077 | ||
|
1078 | 1074 | return _validator |
|
1079 | 1075 | |
|
1080 | 1076 | |
|
1081 | def ValidPattern(): | |
|
1077 | def ValidPattern(localizer): | |
|
1078 | _ = localizer | |
|
1082 | 1079 | |
|
1083 |
class _ |
|
|
1080 | class _validator(formencode.validators.FancyValidator): | |
|
1084 | 1081 | messages = { |
|
1085 | 1082 | 'bad_format': _(u'Url must start with http or /'), |
|
1086 | 1083 | } |
@@ -1129,4 +1126,4 b' def ValidPattern():' | |||
|
1129 | 1126 | delete_patterns = [delete_patterns] |
|
1130 | 1127 | value['delete_patterns'] = delete_patterns |
|
1131 | 1128 | return value |
|
1132 |
return _ |
|
|
1129 | return _validator |
@@ -21,7 +21,6 b' import io' | |||
|
21 | 21 | import re |
|
22 | 22 | import datetime |
|
23 | 23 | import logging |
|
24 | import pylons | |
|
25 | 24 | import Queue |
|
26 | 25 | import subprocess32 |
|
27 | 26 | import os |
@@ -36,14 +35,11 b' from threading import Thread' | |||
|
36 | 35 | from rhodecode.translation import _ as tsf |
|
37 | 36 | from rhodecode.config.jsroutes import generate_jsroutes_content |
|
38 | 37 | from rhodecode.lib import auth |
|
38 | from rhodecode.lib.base import get_auth_user | |
|
39 | ||
|
39 | 40 | |
|
40 | 41 | import rhodecode |
|
41 | 42 | |
|
42 | from pylons.i18n.translation import _get_translator | |
|
43 | from pylons.util import ContextObj | |
|
44 | from routes.util import URLGenerator | |
|
45 | ||
|
46 | from rhodecode.lib.base import attach_context_attributes, get_auth_user | |
|
47 | 43 | |
|
48 | 44 | log = logging.getLogger(__name__) |
|
49 | 45 | |
@@ -51,11 +47,6 b' log = logging.getLogger(__name__)' | |||
|
51 | 47 | def add_renderer_globals(event): |
|
52 | 48 | from rhodecode.lib import helpers |
|
53 | 49 | |
|
54 | # NOTE(marcink): | |
|
55 | # Put pylons stuff into the context. This will be removed as soon as | |
|
56 | # migration to pyramid is finished. | |
|
57 | event['c'] = pylons.tmpl_context | |
|
58 | ||
|
59 | 50 | # TODO: When executed in pyramid view context the request is not available |
|
60 | 51 | # in the event. Find a better solution to get the request. |
|
61 | 52 | request = event['request'] or get_current_request() |
@@ -68,12 +59,11 b' def add_renderer_globals(event):' | |||
|
68 | 59 | |
|
69 | 60 | def add_localizer(event): |
|
70 | 61 | request = event.request |
|
71 |
localizer = |
|
|
62 | localizer = request.localizer | |
|
72 | 63 | |
|
73 | 64 | def auto_translate(*args, **kwargs): |
|
74 | 65 | return localizer.translate(tsf(*args, **kwargs)) |
|
75 | 66 | |
|
76 | request.localizer = localizer | |
|
77 | 67 | request.translate = auto_translate |
|
78 | 68 | request.plularize = localizer.pluralize |
|
79 | 69 | |
@@ -108,39 +98,6 b' def add_request_user_context(event):' | |||
|
108 | 98 | request.environ['rc_auth_user'] = auth_user |
|
109 | 99 | |
|
110 | 100 | |
|
111 | def add_pylons_context(event): | |
|
112 | request = event.request | |
|
113 | ||
|
114 | config = rhodecode.CONFIG | |
|
115 | environ = request.environ | |
|
116 | session = request.session | |
|
117 | ||
|
118 | if hasattr(request, 'vcs_call'): | |
|
119 | # skip vcs calls | |
|
120 | return | |
|
121 | ||
|
122 | # Setup pylons globals. | |
|
123 | pylons.config._push_object(config) | |
|
124 | pylons.request._push_object(request) | |
|
125 | pylons.session._push_object(session) | |
|
126 | pylons.translator._push_object(_get_translator(config.get('lang'))) | |
|
127 | ||
|
128 | pylons.url._push_object(URLGenerator(config['routes.map'], environ)) | |
|
129 | session_key = ( | |
|
130 | config['pylons.environ_config'].get('session', 'beaker.session')) | |
|
131 | environ[session_key] = session | |
|
132 | ||
|
133 | if hasattr(request, 'rpc_method'): | |
|
134 | # skip api calls | |
|
135 | return | |
|
136 | ||
|
137 | # Setup the pylons context object ('c') | |
|
138 | context = ContextObj() | |
|
139 | context.rhodecode_user = request.user | |
|
140 | attach_context_attributes(context, request, request.user.user_id) | |
|
141 | pylons.tmpl_context._push_object(context) | |
|
142 | ||
|
143 | ||
|
144 | 101 | def inject_app_settings(event): |
|
145 | 102 | settings = event.app.registry.settings |
|
146 | 103 | # inject info about available permissions |
@@ -61,14 +61,14 b'' | |||
|
61 | 61 | </td> |
|
62 | 62 | <td> |
|
63 | 63 | % if c.audit_log_entry.version == c.audit_log_entry.VERSION_1: |
|
64 | ${h.action_parser(l)[0]()} | |
|
64 | ${h.action_parser(request, l)[0]()} | |
|
65 | 65 | % else: |
|
66 | 66 | ${h.literal(c.audit_log_entry.action)} |
|
67 | 67 | % endif |
|
68 | 68 | |
|
69 | 69 | <div class="journal_action_params"> |
|
70 | 70 | % if c.audit_log_entry.version == c.audit_log_entry.VERSION_1: |
|
71 | ${h.literal(h.action_parser(l)[1]())} | |
|
71 | ${h.literal(h.action_parser(request, l)[1]())} | |
|
72 | 72 | % endif |
|
73 | 73 | </div> |
|
74 | 74 | </td> |
@@ -14,7 +14,7 b'' | |||
|
14 | 14 | <input type='submit' value="${_('filter')}" class="btn" /> |
|
15 | 15 | ${_('Audit logs')} - ${_ungettext('%s entry', '%s entries', c.audit_logs.item_count) % (c.audit_logs.item_count)} |
|
16 | 16 | ${h.end_form()} |
|
17 |
<p class="tooltip filterexample" title="${h.tooltip(h.journal_filter_help( |
|
|
17 | <p class="tooltip filterexample" title="${h.tooltip(h.journal_filter_help(request))}">${_('Example Queries')}</p> | |
|
18 | 18 | </%def> |
|
19 | 19 | |
|
20 | 20 | <%def name="menu_bar_nav()"> |
@@ -26,14 +26,14 b'' | |||
|
26 | 26 | </td> |
|
27 | 27 | <td class="td-journalaction"> |
|
28 | 28 | % if l.version == l.VERSION_1: |
|
29 | ${h.action_parser(l)[0]()} | |
|
29 | ${h.action_parser(request, l)[0]()} | |
|
30 | 30 | % else: |
|
31 | 31 | ${h.literal(l.action)} |
|
32 | 32 | % endif |
|
33 | 33 | |
|
34 | 34 | <div class="journal_action_params"> |
|
35 | 35 | % if l.version == l.VERSION_1: |
|
36 | ${h.literal(h.action_parser(l)[1]())} | |
|
36 | ${h.literal(h.action_parser(request, l)[1]())} | |
|
37 | 37 | % endif |
|
38 | 38 | </div> |
|
39 | 39 | </td> |
@@ -14,7 +14,7 b'' | |||
|
14 | 14 | <input class="q_filter_box ${'' if c.filter_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.filter_term or ''}" placeholder="${_('audit filter...')}"/> |
|
15 | 15 | <input type='submit' value="${_('filter')}" class="btn" /> |
|
16 | 16 | ${h.end_form()} |
|
17 |
<p class="tooltip filterexample" style="position: inherit" title="${h.tooltip(h.journal_filter_help( |
|
|
17 | <p class="tooltip filterexample" style="position: inherit" title="${h.tooltip(h.journal_filter_help(request))}">${_('Example Queries')}</p> | |
|
18 | 18 | |
|
19 | 19 | <%include file="/admin/admin_log_base.mako" /> |
|
20 | 20 |
@@ -14,7 +14,7 b'' | |||
|
14 | 14 | <input class="q_filter_box ${'' if c.filter_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.filter_term or ''}" placeholder="${_('audit filter...')}"/> |
|
15 | 15 | <input type='submit' value="${_('filter')}" class="btn" /> |
|
16 | 16 | ${h.end_form()} |
|
17 |
<p class="tooltip filterexample" style="position: inherit" title="${h.tooltip(h.journal_filter_help( |
|
|
17 | <p class="tooltip filterexample" style="position: inherit" title="${h.tooltip(h.journal_filter_help(request))}">${_('Example Queries')}</p> | |
|
18 | 18 | |
|
19 | 19 | <%include file="/admin/admin_log_base.mako" /> |
|
20 | 20 |
@@ -1,11 +1,8 b'' | |||
|
1 | <% | |
|
2 | from pyramid.renderers import render as pyramid_render | |
|
3 | from pyramid.threadlocal import get_current_registry, get_current_request | |
|
4 | pyramid_registry = get_current_registry() | |
|
5 | %> | |
|
6 | % for plugin, config in getattr(pyramid_registry, 'rhodecode_plugins', {}).items(): | |
|
7 | % if config['template_hooks'].get('plugin_init_template'): | |
|
8 | ${pyramid_render(config['template_hooks'].get('plugin_init_template'), | |
|
9 | {'config':config}, request=get_current_request(), package='rc_ae')|n} | |
|
10 | % endif | |
|
1 | ||
|
2 | % for plugin, config in getattr(request.registry, 'rhodecode_plugins', {}).items(): | |
|
3 | <% tmpl = config['template_hooks'].get('plugin_init_template') %> | |
|
4 | ||
|
5 | % if tmpl: | |
|
6 | <%include file="${tmpl}" args="config=config"/> | |
|
7 | % endif | |
|
11 | 8 | % endfor |
@@ -1,3 +1,5 b'' | |||
|
1 | <%page args="config"/> | |
|
2 | ||
|
1 | 3 | <script> |
|
2 | 4 | var CHANNELSTREAM_URLS = ${config['url_gen'](request)|n}; |
|
3 | 5 | %if request.registry.rhodecode_plugins['channelstream']['enabled'] and c.rhodecode_user.username != h.DEFAULT_USER: |
@@ -15,7 +15,7 b'' | |||
|
15 | 15 | ${_('Journal')} - ${_ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)} |
|
16 | 16 | ${h.end_form()} |
|
17 | 17 | </h1> |
|
18 |
<p class="tooltip filterexample" title="${h.tooltip(h.journal_filter_help( |
|
|
18 | <p class="tooltip filterexample" title="${h.tooltip(h.journal_filter_help(request))}">${_('Example Queries')}</p> | |
|
19 | 19 | </%def> |
|
20 | 20 | <%def name="menu_bar_nav()"> |
|
21 | 21 | ${self.menu_items(active='journal')} |
@@ -14,8 +14,8 b'' | |||
|
14 | 14 | %endif |
|
15 | 15 | <div class="journal_action_container"> |
|
16 | 16 | % for entry in entries: |
|
17 | <div class="journal_icon"> ${h.action_parser(entry)[2]()}</div> | |
|
18 | <div class="journal_action">${h.action_parser(entry)[0]()}</div> | |
|
17 | <div class="journal_icon"> ${h.action_parser(request, entry)[2]()}</div> | |
|
18 | <div class="journal_action">${h.action_parser(request, entry)[0]()}</div> | |
|
19 | 19 | <div class="journal_repo"> |
|
20 | 20 | <span class="journal_repo_name"> |
|
21 | 21 | %if entry.repository is not None: |
@@ -26,7 +26,7 b'' | |||
|
26 | 26 | %endif |
|
27 | 27 | </span> |
|
28 | 28 | </div> |
|
29 | <div class="journal_action_params">${h.literal(h.action_parser(entry)[1]())}</div> | |
|
29 | <div class="journal_action_params">${h.literal(h.action_parser(request, entry)[1]())}</div> | |
|
30 | 30 | <div class="date"> |
|
31 | 31 | ${h.age_component(entry.action_date, time_is_local=True)} |
|
32 | 32 | </div> |
@@ -38,7 +38,7 b'' | |||
|
38 | 38 | %endif |
|
39 | 39 | </div> |
|
40 | 40 | <div class="inner form"> |
|
41 | ${h.form(request.route_path('login', _query={'came_from': came_from}), needs_csrf_token=False)} | |
|
41 | ${h.form(request.route_path('login', _query={'came_from': c.came_from}), needs_csrf_token=False)} | |
|
42 | 42 | |
|
43 | 43 | <label for="username">${_('Username')}:</label> |
|
44 | 44 | ${h.text('username', class_='focus', value=defaults.get('username'))} |
@@ -74,7 +74,7 b'' | |||
|
74 | 74 | % endfor |
|
75 | 75 | <div class="field"> |
|
76 | 76 | <p class="filterexample" style="position: inherit" onclick="$('#search-help').toggle()">${_('Example Queries')}</p> |
|
77 |
<pre id="search-help" style="display: none">${h.tooltip(h.search_filter_help(c.searcher, |
|
|
77 | <pre id="search-help" style="display: none">${h.tooltip(h.search_filter_help(c.searcher, request))}</pre> | |
|
78 | 78 | </div> |
|
79 | 79 | |
|
80 | 80 | <div class="field">${c.runtime}</div> |
@@ -28,8 +28,6 b' from os.path import join as jn' | |||
|
28 | 28 | |
|
29 | 29 | from tempfile import _RandomNameSequence |
|
30 | 30 | |
|
31 | from pylons import url | |
|
32 | ||
|
33 | 31 | import pytest |
|
34 | 32 | |
|
35 | 33 | from rhodecode.model.db import User |
@@ -43,7 +41,7 b' log = logging.getLogger(__name__)' | |||
|
43 | 41 | |
|
44 | 42 | __all__ = [ |
|
45 | 43 | 'get_new_dir', 'TestController', |
|
46 |
|
|
|
44 | 'link_to', 'ldap_lib_installed', 'clear_all_caches', | |
|
47 | 45 | 'assert_session_flash', 'login_user', 'no_newline_id_generator', |
|
48 | 46 | 'TESTS_TMP_PATH', 'HG_REPO', 'GIT_REPO', 'SVN_REPO', |
|
49 | 47 | 'NEW_HG_REPO', 'NEW_GIT_REPO', |
@@ -55,8 +53,6 b' log = logging.getLogger(__name__)' | |||
|
55 | 53 | 'TEST_GIT_REPO_CLONE', 'TEST_GIT_REPO_PULL', 'SCM_TESTS', |
|
56 | 54 | ] |
|
57 | 55 | |
|
58 | # Invoke websetup with the current config file | |
|
59 | # SetupCommand('setup-app').run([config_file]) | |
|
60 | 56 | |
|
61 | 57 | # SOME GLOBALS FOR TESTS |
|
62 | 58 | TEST_DIR = tempfile.gettempdir() |
@@ -61,7 +61,7 b' def pytest_collection_modifyitems(sessio' | |||
|
61 | 61 | |
|
62 | 62 | @pytest.fixture |
|
63 | 63 | def db_backend( |
|
64 |
request, db_backend_name, |
|
|
64 | request, db_backend_name, ini_config, tmpdir_factory): | |
|
65 | 65 | basetemp = tmpdir_factory.getbasetemp().strpath |
|
66 | 66 | klass = _get_backend(db_backend_name) |
|
67 | 67 | |
@@ -69,7 +69,7 b' def db_backend(' | |||
|
69 | 69 | connection_string = request.config.getoption(option_name) or None |
|
70 | 70 | |
|
71 | 71 | return klass( |
|
72 |
config_file= |
|
|
72 | config_file=ini_config, basetemp=basetemp, | |
|
73 | 73 | connection_string=connection_string) |
|
74 | 74 | |
|
75 | 75 |
@@ -95,7 +95,7 b' def test_webook_parse_url_for_pull_reque' | |||
|
95 | 95 | 'http://server.com/dev/dev-yyy']), |
|
96 | 96 | ]) |
|
97 | 97 | def test_webook_parse_url_for_push_event( |
|
98 |
|
|
|
98 | baseapp, repo_push_event, base_data, template, expected_urls): | |
|
99 | 99 | base_data['push'] = { |
|
100 | 100 | 'branches': [{'name': 'stable'}, {'name': 'dev'}], |
|
101 | 101 | 'commits': [{'branch': 'stable', 'raw_id': 'stable-xxx'}, |
@@ -73,7 +73,7 b' def get_environ(url, request_method):' | |||
|
73 | 73 | ('/info/lfs/info/lfs/objects/batch', 'pull', 'POST'), |
|
74 | 74 | |
|
75 | 75 | ]) |
|
76 |
def test_get_action(url, expected_action, request_method, |
|
|
76 | def test_get_action(url, expected_action, request_method, baseapp, request_stub): | |
|
77 | 77 | app = simplegit.SimpleGit(application=None, |
|
78 | 78 | config={'auth_ret_code': '', 'base_path': ''}, |
|
79 | 79 | registry=request_stub.registry) |
@@ -102,7 +102,7 b' def test_get_action(url, expected_action' | |||
|
102 | 102 | ('/info/lfs/info/lfs/objects/batch', 'info/lfs', 'POST'), |
|
103 | 103 | |
|
104 | 104 | ]) |
|
105 |
def test_get_repository_name(url, expected_repo_name, request_method, |
|
|
105 | def test_get_repository_name(url, expected_repo_name, request_method, baseapp, request_stub): | |
|
106 | 106 | app = simplegit.SimpleGit(application=None, |
|
107 | 107 | config={'auth_ret_code': '', 'base_path': ''}, |
|
108 | 108 | registry=request_stub.registry) |
@@ -110,7 +110,7 b' def test_get_repository_name(url, expect' | |||
|
110 | 110 | get_environ(url, request_method)) |
|
111 | 111 | |
|
112 | 112 | |
|
113 |
def test_get_config(user_util, |
|
|
113 | def test_get_config(user_util, baseapp, request_stub): | |
|
114 | 114 | repo = user_util.create_repo(repo_type='git') |
|
115 | 115 | app = simplegit.SimpleGit(application=None, |
|
116 | 116 | config={'auth_ret_code': '', 'base_path': ''}, |
@@ -130,7 +130,7 b' def test_get_config(user_util, pylonsapp' | |||
|
130 | 130 | assert git_config == expected_config |
|
131 | 131 | |
|
132 | 132 | |
|
133 |
def test_create_wsgi_app_uses_scm_app_from_simplevcs( |
|
|
133 | def test_create_wsgi_app_uses_scm_app_from_simplevcs(baseapp, request_stub): | |
|
134 | 134 | config = { |
|
135 | 135 | 'auth_ret_code': '', |
|
136 | 136 | 'base_path': '', |
@@ -78,7 +78,7 b' def test_get_repository_name(url, expect' | |||
|
78 | 78 | assert expected_repo_name == app._get_repository_name(get_environ(url)) |
|
79 | 79 | |
|
80 | 80 | |
|
81 |
def test_get_config(user_util, |
|
|
81 | def test_get_config(user_util, baseapp, request_stub): | |
|
82 | 82 | repo = user_util.create_repo(repo_type='git') |
|
83 | 83 | app = simplehg.SimpleHg(application=None, |
|
84 | 84 | config={'auth_ret_code': '', 'base_path': ''}, |
@@ -29,7 +29,7 b' from rhodecode.lib.middleware.simplesvn ' | |||
|
29 | 29 | |
|
30 | 30 | class TestSimpleSvn(object): |
|
31 | 31 | @pytest.fixture(autouse=True) |
|
32 |
def simple_svn(self, |
|
|
32 | def simple_svn(self, baseapp, request_stub): | |
|
33 | 33 | self.app = SimpleSvn( |
|
34 | 34 | application='None', |
|
35 | 35 | config={'auth_ret_code': '', |
@@ -74,13 +74,13 b' class StubVCSController(simplevcs.Simple' | |||
|
74 | 74 | |
|
75 | 75 | |
|
76 | 76 | @pytest.fixture |
|
77 |
def vcscontroller( |
|
|
77 | def vcscontroller(baseapp, config_stub, request_stub): | |
|
78 | 78 | config_stub.testing_securitypolicy() |
|
79 | 79 | config_stub.include('rhodecode.authentication') |
|
80 | 80 | |
|
81 | 81 | controller = StubVCSController( |
|
82 |
|
|
|
83 |
app = HttpsFixup(controller, |
|
|
82 | baseapp, baseapp.config, request_stub.registry) | |
|
83 | app = HttpsFixup(controller, baseapp.config) | |
|
84 | 84 | app = CustomTestApp(app) |
|
85 | 85 | |
|
86 | 86 | _remove_default_user_from_query_cache() |
@@ -134,10 +134,10 b' class StubFailVCSController(simplevcs.Si' | |||
|
134 | 134 | |
|
135 | 135 | |
|
136 | 136 | @pytest.fixture(scope='module') |
|
137 |
def fail_controller( |
|
|
137 | def fail_controller(baseapp): | |
|
138 | 138 | controller = StubFailVCSController( |
|
139 |
|
|
|
140 |
controller = HttpsFixup(controller, |
|
|
139 | baseapp, baseapp.config, baseapp.config) | |
|
140 | controller = HttpsFixup(controller, baseapp.config) | |
|
141 | 141 | controller = CustomTestApp(controller) |
|
142 | 142 | return controller |
|
143 | 143 | |
@@ -152,18 +152,18 b' def test_provides_traceback_for_appenlig' | |||
|
152 | 152 | assert 'appenlight.__traceback' in response.request.environ |
|
153 | 153 | |
|
154 | 154 | |
|
155 |
def test_provides_utils_scm_app_as_scm_app_by_default( |
|
|
155 | def test_provides_utils_scm_app_as_scm_app_by_default(baseapp, request_stub): | |
|
156 | 156 | controller = StubVCSController( |
|
157 |
|
|
|
157 | baseapp, baseapp.config, request_stub.registry) | |
|
158 | 158 | assert controller.scm_app is scm_app_http |
|
159 | 159 | |
|
160 | 160 | |
|
161 |
def test_allows_to_override_scm_app_via_config( |
|
|
162 |
config = |
|
|
161 | def test_allows_to_override_scm_app_via_config(baseapp, request_stub): | |
|
162 | config = baseapp.config.copy() | |
|
163 | 163 | config['vcs.scm_app_implementation'] = ( |
|
164 | 164 | 'rhodecode.tests.lib.middleware.mock_scm_app') |
|
165 | 165 | controller = StubVCSController( |
|
166 |
|
|
|
166 | baseapp, config, request_stub.registry) | |
|
167 | 167 | assert controller.scm_app is mock_scm_app |
|
168 | 168 | |
|
169 | 169 | |
@@ -219,13 +219,13 b' class TestShadowRepoRegularExpression(ob' | |||
|
219 | 219 | class TestShadowRepoExposure(object): |
|
220 | 220 | |
|
221 | 221 | def test_pull_on_shadow_repo_propagates_to_wsgi_app( |
|
222 |
self, |
|
|
222 | self, baseapp, request_stub): | |
|
223 | 223 | """ |
|
224 | 224 | Check that a pull action to a shadow repo is propagated to the |
|
225 | 225 | underlying wsgi app. |
|
226 | 226 | """ |
|
227 | 227 | controller = StubVCSController( |
|
228 |
|
|
|
228 | baseapp, baseapp.config, request_stub.registry) | |
|
229 | 229 | controller._check_ssl = mock.Mock() |
|
230 | 230 | controller.is_shadow_repo = True |
|
231 | 231 | controller._action = 'pull' |
@@ -244,13 +244,13 b' class TestShadowRepoExposure(object):' | |||
|
244 | 244 | # Assert that we got the response from the wsgi app. |
|
245 | 245 | assert response_body == controller.stub_response_body |
|
246 | 246 | |
|
247 |
def test_pull_on_shadow_repo_that_is_missing(self, |
|
|
247 | def test_pull_on_shadow_repo_that_is_missing(self, baseapp, request_stub): | |
|
248 | 248 | """ |
|
249 | 249 | Check that a pull action to a shadow repo is propagated to the |
|
250 | 250 | underlying wsgi app. |
|
251 | 251 | """ |
|
252 | 252 | controller = StubVCSController( |
|
253 |
|
|
|
253 | baseapp, baseapp.config, request_stub.registry) | |
|
254 | 254 | controller._check_ssl = mock.Mock() |
|
255 | 255 | controller.is_shadow_repo = True |
|
256 | 256 | controller._action = 'pull' |
@@ -269,12 +269,12 b' class TestShadowRepoExposure(object):' | |||
|
269 | 269 | # Assert that we got the response from the wsgi app. |
|
270 | 270 | assert '404 Not Found' in response_body |
|
271 | 271 | |
|
272 |
def test_push_on_shadow_repo_raises(self, |
|
|
272 | def test_push_on_shadow_repo_raises(self, baseapp, request_stub): | |
|
273 | 273 | """ |
|
274 | 274 | Check that a push action to a shadow repo is aborted. |
|
275 | 275 | """ |
|
276 | 276 | controller = StubVCSController( |
|
277 |
|
|
|
277 | baseapp, baseapp.config, request_stub.registry) | |
|
278 | 278 | controller._check_ssl = mock.Mock() |
|
279 | 279 | controller.is_shadow_repo = True |
|
280 | 280 | controller._action = 'push' |
@@ -293,14 +293,14 b' class TestShadowRepoExposure(object):' | |||
|
293 | 293 | # Assert that a 406 error is returned. |
|
294 | 294 | assert '406 Not Acceptable' in response_body |
|
295 | 295 | |
|
296 |
def test_set_repo_names_no_shadow(self, |
|
|
296 | def test_set_repo_names_no_shadow(self, baseapp, request_stub): | |
|
297 | 297 | """ |
|
298 | 298 | Check that the set_repo_names method sets all names to the one returned |
|
299 | 299 | by the _get_repository_name method on a request to a non shadow repo. |
|
300 | 300 | """ |
|
301 | 301 | environ_stub = {} |
|
302 | 302 | controller = StubVCSController( |
|
303 |
|
|
|
303 | baseapp, baseapp.config, request_stub.registry) | |
|
304 | 304 | controller._name = 'RepoGroup/MyRepo' |
|
305 | 305 | controller.set_repo_names(environ_stub) |
|
306 | 306 | assert not controller.is_shadow_repo |
@@ -310,7 +310,7 b' class TestShadowRepoExposure(object):' | |||
|
310 | 310 | controller._get_repository_name(environ_stub)) |
|
311 | 311 | |
|
312 | 312 | def test_set_repo_names_with_shadow( |
|
313 |
self, |
|
|
313 | self, baseapp, pr_util, config_stub, request_stub): | |
|
314 | 314 | """ |
|
315 | 315 | Check that the set_repo_names method sets correct names on a request |
|
316 | 316 | to a shadow repo. |
@@ -324,7 +324,7 b' class TestShadowRepoExposure(object):' | |||
|
324 | 324 | pr_segment=TestShadowRepoRegularExpression.pr_segment, |
|
325 | 325 | shadow_segment=TestShadowRepoRegularExpression.shadow_segment) |
|
326 | 326 | controller = StubVCSController( |
|
327 |
|
|
|
327 | baseapp, baseapp.config, request_stub.registry) | |
|
328 | 328 | controller._name = shadow_url |
|
329 | 329 | controller.set_repo_names({}) |
|
330 | 330 | |
@@ -340,7 +340,7 b' class TestShadowRepoExposure(object):' | |||
|
340 | 340 | assert controller.is_shadow_repo |
|
341 | 341 | |
|
342 | 342 | def test_set_repo_names_with_shadow_but_missing_pr( |
|
343 |
self, |
|
|
343 | self, baseapp, pr_util, config_stub, request_stub): | |
|
344 | 344 | """ |
|
345 | 345 | Checks that the set_repo_names method enforces matching target repos |
|
346 | 346 | and pull request IDs. |
@@ -352,7 +352,7 b' class TestShadowRepoExposure(object):' | |||
|
352 | 352 | pr_segment=TestShadowRepoRegularExpression.pr_segment, |
|
353 | 353 | shadow_segment=TestShadowRepoRegularExpression.shadow_segment) |
|
354 | 354 | controller = StubVCSController( |
|
355 |
|
|
|
355 | baseapp, baseapp.config, request_stub.registry) | |
|
356 | 356 | controller._name = shadow_url |
|
357 | 357 | controller.set_repo_names({}) |
|
358 | 358 |
@@ -108,8 +108,7 b' class TestVCSMiddleware(object):' | |||
|
108 | 108 | config = {'appenlight': False, 'vcs.backends': ['svn']} |
|
109 | 109 | registry = Mock() |
|
110 | 110 | middleware = vcs.VCSMiddleware( |
|
111 |
application, |
|
|
112 | appenlight_client=None, registry=registry) | |
|
111 | application, registry, config, appenlight_client=None) | |
|
113 | 112 | middleware.use_gzip = False |
|
114 | 113 | |
|
115 | 114 | with patch.object(SimpleSvn, '_is_svn_enabled') as mock_method: |
@@ -128,8 +127,7 b' class TestVCSMiddleware(object):' | |||
|
128 | 127 | config = {'appenlight': False, 'vcs.backends': ['svn']} |
|
129 | 128 | registry = Mock() |
|
130 | 129 | middleware = vcs.VCSMiddleware( |
|
131 |
application, |
|
|
132 | appenlight_client=None, registry=registry) | |
|
130 | application, registry, config, appenlight_client=None) | |
|
133 | 131 | middleware.use_gzip = False |
|
134 | 132 | |
|
135 | 133 | with patch.object(SimpleSvn, '_is_svn_enabled') as mock_method: |
@@ -31,19 +31,13 b' def test_vcs_available_returns_summary_p' | |||
|
31 | 31 | |
|
32 | 32 | |
|
33 | 33 | @pytest.mark.usefixtures('autologin_user', 'app') |
|
34 |
def test_vcs_unavailable_returns_vcs_error_page(app, backend |
|
|
34 | def test_vcs_unavailable_returns_vcs_error_page(app, backend): | |
|
35 | 35 | from rhodecode.lib.vcs.exceptions import VCSCommunicationError |
|
36 | from rhodecode.lib.middleware.error_handling import ( | |
|
37 | PylonsErrorHandlingMiddleware) | |
|
38 | 36 | |
|
39 | 37 | # Depending on the used VCSServer protocol we have to patch a different |
|
40 | 38 | # RemoteRepo class to raise an exception. For the test it doesn't matter |
|
41 | 39 | # if http is used, it just requires the exception to be raised. |
|
42 | vcs_protocol = app_settings['vcs.server.protocol'] | |
|
43 | if vcs_protocol == 'http': | |
|
44 | from rhodecode.lib.vcs.client_http import RemoteRepo | |
|
45 | else: | |
|
46 | pytest.fail('Unknown VCS server protocol: "{}"'.format(vcs_protocol)) | |
|
40 | from rhodecode.lib.vcs.client_http import RemoteRepo | |
|
47 | 41 | |
|
48 | 42 | url = '/{repo_name}'.format(repo_name=backend.repo.repo_name) |
|
49 | 43 |
@@ -29,6 +29,6 b' from rhodecode.model.db import UserLog' | |||
|
29 | 29 | 'user_closed_pull_request', |
|
30 | 30 | 'user_merged_pull_request' |
|
31 | 31 | ]) |
|
32 |
def test_action_map_pr_values( |
|
|
32 | def test_action_map_pr_values(baseapp, pr_key): | |
|
33 | 33 | parser = ActionParser(UserLog(action="test:test")) |
|
34 | 34 | assert pr_key in parser.action_map |
@@ -26,7 +26,7 b' from rhodecode.model import db' | |||
|
26 | 26 | |
|
27 | 27 | |
|
28 | 28 | @pytest.fixture |
|
29 |
def db_manage( |
|
|
29 | def db_manage(baseapp): | |
|
30 | 30 | db_manage = DbManage( |
|
31 | 31 | log_sql=True, dbconf='fake', root='fake', tests=False, |
|
32 | 32 | cli_args={}, SESSION=db.Session()) |
@@ -34,7 +34,7 b' def db_manage(pylonsapp):' | |||
|
34 | 34 | |
|
35 | 35 | |
|
36 | 36 | @pytest.fixture(autouse=True) |
|
37 |
def session_rollback( |
|
|
37 | def session_rollback(baseapp, request): | |
|
38 | 38 | """ |
|
39 | 39 | Rollback the database session after the test run. |
|
40 | 40 |
@@ -27,7 +27,7 b' import pytest' | |||
|
27 | 27 | |
|
28 | 28 | from rhodecode.lib.ext_json import json |
|
29 | 29 | from rhodecode.lib.ext_json import formatted_json |
|
30 |
from |
|
|
30 | from rhodecode.translation import _, _pluralize | |
|
31 | 31 | |
|
32 | 32 | |
|
33 | 33 | class Timezone(datetime.tzinfo): |
@@ -158,9 +158,9 b' def test_formatted_json():' | |||
|
158 | 158 | assert formatted_json(data) == expected_data |
|
159 | 159 | |
|
160 | 160 | |
|
161 |
def test_pylons_lazy_translation_string( |
|
|
161 | def test_pylons_lazy_translation_string(baseapp): | |
|
162 | 162 | data = {'label': _('hello')} |
|
163 |
data2 = {'label2': |
|
|
163 | data2 = {'label2': _pluralize('singular', 'plural', 1)} | |
|
164 | 164 | |
|
165 | 165 | assert json.dumps(data) == '{"label": "hello"}' |
|
166 | 166 | assert json.dumps(data2) == '{"label2": "singular"}' |
@@ -22,8 +22,6 b' import copy' | |||
|
22 | 22 | import mock |
|
23 | 23 | import pytest |
|
24 | 24 | |
|
25 | from pylons.util import ContextObj | |
|
26 | ||
|
27 | 25 | from rhodecode.lib import helpers |
|
28 | 26 | from rhodecode.lib.utils2 import AttributeDict |
|
29 | 27 | from rhodecode.model.settings import IssueTrackerSettingsModel |
@@ -188,8 +186,9 b' def test_process_patterns_non_existent_r' | |||
|
188 | 186 | assert processed_text == expected_text |
|
189 | 187 | |
|
190 | 188 | |
|
191 |
def test_get_visual_attr( |
|
|
192 | c = ContextObj() | |
|
189 | def test_get_visual_attr(baseapp): | |
|
190 | from rhodecode.apps._base import TemplateArgs | |
|
191 | c = TemplateArgs() | |
|
193 | 192 | assert None is helpers.get_visual_attr(c, 'fakse') |
|
194 | 193 | |
|
195 | 194 | # emulate the c.visual behaviour |
@@ -142,7 +142,7 b' def test_mention_extractor(text, expecte' | |||
|
142 | 142 | ({'months': -1, 'days': -2}, u'1m, 2d ago', {'short_format': True}), |
|
143 | 143 | ({'years': -1, 'months': -1}, u'1y, 1m ago', {'short_format': True}), |
|
144 | 144 | ]) |
|
145 |
def test_age(age_args, expected, kw, |
|
|
145 | def test_age(age_args, expected, kw, baseapp): | |
|
146 | 146 | from rhodecode.lib.utils2 import age |
|
147 | 147 | from dateutil import relativedelta |
|
148 | 148 | n = datetime.datetime(year=2012, month=5, day=17) |
@@ -174,7 +174,7 b' def test_age(age_args, expected, kw, pyl' | |||
|
174 | 174 | ({'months': 1, 'days': 1}, u'in 1m, 1d', {'short_format': True}), |
|
175 | 175 | ({'years': 1, 'months': 1}, u'in 1y, 1m', {'short_format': True}), |
|
176 | 176 | ]) |
|
177 |
def test_age_in_future(age_args, expected, kw, |
|
|
177 | def test_age_in_future(age_args, expected, kw, baseapp): | |
|
178 | 178 | from rhodecode.lib.utils2 import age |
|
179 | 179 | from dateutil import relativedelta |
|
180 | 180 | n = datetime.datetime(year=2012, month=5, day=17) |
@@ -551,7 +551,7 b' def test_get_repo_by_id(test, expected):' | |||
|
551 | 551 | ("test_non_asci_ąćę", None), |
|
552 | 552 | (u"test_non_asci_unicode_ąćę", None), |
|
553 | 553 | ]) |
|
554 |
def test_invalidation_context( |
|
|
554 | def test_invalidation_context(baseapp, test_repo_name, repo_type): | |
|
555 | 555 | from beaker.cache import cache_region |
|
556 | 556 | from rhodecode.lib import caches |
|
557 | 557 | from rhodecode.model.db import CacheKey |
@@ -581,7 +581,7 b' def test_invalidation_context(pylonsapp,' | |||
|
581 | 581 | assert isinstance(context, caches.ActiveRegionCache) |
|
582 | 582 | |
|
583 | 583 | |
|
584 |
def test_invalidation_context_exception_in_compute( |
|
|
584 | def test_invalidation_context_exception_in_compute(baseapp): | |
|
585 | 585 | from rhodecode.model.db import CacheKey |
|
586 | 586 | from beaker.cache import cache_region |
|
587 | 587 | |
@@ -600,7 +600,7 b' def test_invalidation_context_exception_' | |||
|
600 | 600 | |
|
601 | 601 | |
|
602 | 602 | @pytest.mark.parametrize('execution_number', range(5)) |
|
603 |
def test_cache_invalidation_race_condition(execution_number, |
|
|
603 | def test_cache_invalidation_race_condition(execution_number, baseapp): | |
|
604 | 604 | import time |
|
605 | 605 | from beaker.cache import cache_region |
|
606 | 606 | from rhodecode.model.db import CacheKey |
@@ -104,7 +104,7 b' HG_HOOKS = frozenset(' | |||
|
104 | 104 | ([HOOK_PULL], [HOOK_PRE_PUSH, HOOK_PRETX_PUSH, HOOK_PUSH, HOOK_REPO_SIZE, |
|
105 | 105 | HOOK_PUSH_KEY]), |
|
106 | 106 | ]) |
|
107 |
def test_make_db_config_hg_hooks( |
|
|
107 | def test_make_db_config_hg_hooks(baseapp, request, disabled_hooks, | |
|
108 | 108 | expected_hooks): |
|
109 | 109 | disable_hooks(request, disabled_hooks) |
|
110 | 110 | |
@@ -130,25 +130,25 b' def test_get_enabled_hook_classes(disabl' | |||
|
130 | 130 | assert sorted(result) == expected_hooks |
|
131 | 131 | |
|
132 | 132 | |
|
133 |
def test_get_filesystem_repos_finds_repos(tmpdir, |
|
|
133 | def test_get_filesystem_repos_finds_repos(tmpdir, baseapp): | |
|
134 | 134 | _stub_git_repo(tmpdir.ensure('repo', dir=True)) |
|
135 | 135 | repos = list(utils.get_filesystem_repos(str(tmpdir))) |
|
136 | 136 | assert repos == [('repo', ('git', tmpdir.join('repo')))] |
|
137 | 137 | |
|
138 | 138 | |
|
139 |
def test_get_filesystem_repos_skips_directories(tmpdir, |
|
|
139 | def test_get_filesystem_repos_skips_directories(tmpdir, baseapp): | |
|
140 | 140 | tmpdir.ensure('not-a-repo', dir=True) |
|
141 | 141 | repos = list(utils.get_filesystem_repos(str(tmpdir))) |
|
142 | 142 | assert repos == [] |
|
143 | 143 | |
|
144 | 144 | |
|
145 |
def test_get_filesystem_repos_skips_directories_with_repos(tmpdir, |
|
|
145 | def test_get_filesystem_repos_skips_directories_with_repos(tmpdir, baseapp): | |
|
146 | 146 | _stub_git_repo(tmpdir.ensure('subdir/repo', dir=True)) |
|
147 | 147 | repos = list(utils.get_filesystem_repos(str(tmpdir))) |
|
148 | 148 | assert repos == [] |
|
149 | 149 | |
|
150 | 150 | |
|
151 |
def test_get_filesystem_repos_finds_repos_in_subdirectories(tmpdir, |
|
|
151 | def test_get_filesystem_repos_finds_repos_in_subdirectories(tmpdir, baseapp): | |
|
152 | 152 | _stub_git_repo(tmpdir.ensure('subdir/repo', dir=True)) |
|
153 | 153 | repos = list(utils.get_filesystem_repos(str(tmpdir), recursive=True)) |
|
154 | 154 | assert repos == [('subdir/repo', ('git', tmpdir.join('subdir', 'repo')))] |
@@ -34,7 +34,7 b' def test_obfuscate_url_pw():' | |||
|
34 | 34 | 'www.test.com', 'test.com', 'test.co.uk', '192.168.1.3']) |
|
35 | 35 | @pytest.mark.parametrize('port', [None, '80', '443', '999']) |
|
36 | 36 | @pytest.mark.parametrize('script_path', [None, '/', '/prefix', '/prefix/more']) |
|
37 |
def test_routes_generator( |
|
|
37 | def test_routes_generator(baseapp, scheme, domain, port, script_path): | |
|
38 | 38 | server_url = '%s://%s' % (scheme, domain) |
|
39 | 39 | if port is not None: |
|
40 | 40 | server_url += ':' + port |
@@ -44,7 +44,7 b' def repo_name(backend_hg):' | |||
|
44 | 44 | class TestPermissions(object): |
|
45 | 45 | |
|
46 | 46 | @pytest.fixture(scope='class', autouse=True) |
|
47 |
def default_permissions(self, request, |
|
|
47 | def default_permissions(self, request, baseapp): | |
|
48 | 48 | # recreate default user to get a clean start |
|
49 | 49 | PermissionModel().create_default_user_permissions( |
|
50 | 50 | user=User.DEFAULT_USER, force=True) |
@@ -475,7 +475,7 b' def merge_extras(user_regular):' | |||
|
475 | 475 | class TestUpdateCommentHandling(object): |
|
476 | 476 | |
|
477 | 477 | @pytest.fixture(autouse=True, scope='class') |
|
478 |
def enable_outdated_comments(self, request, |
|
|
478 | def enable_outdated_comments(self, request, baseapp): | |
|
479 | 479 | config_patch = mock.patch.dict( |
|
480 | 480 | 'rhodecode.CONFIG', {'rhodecode_use_outdated_comments': True}) |
|
481 | 481 | config_patch.start() |
@@ -64,7 +64,7 b" def permissions_setup_func(group_name='g" | |||
|
64 | 64 | |
|
65 | 65 | |
|
66 | 66 | @pytest.fixture(scope='module', autouse=True) |
|
67 |
def prepare(request, |
|
|
67 | def prepare(request, baseapp): | |
|
68 | 68 | global test_u1_id, _get_repo_perms, _get_group_perms |
|
69 | 69 | test_u1 = _create_project_tree() |
|
70 | 70 | Session().commit() |
@@ -115,7 +115,7 b' class TestGetUsers(object):' | |||
|
115 | 115 | |
|
116 | 116 | |
|
117 | 117 | @pytest.fixture |
|
118 |
def test_user(request, |
|
|
118 | def test_user(request, baseapp): | |
|
119 | 119 | usr = UserModel().create_or_update( |
|
120 | 120 | username=u'test_user', |
|
121 | 121 | password=u'qweqwe', |
@@ -38,11 +38,18 b' from rhodecode.tests.fixture import Fixt' | |||
|
38 | 38 | |
|
39 | 39 | fixture = Fixture() |
|
40 | 40 | |
|
41 |
pytestmark = pytest.mark.usefixtures(' |
|
|
41 | pytestmark = pytest.mark.usefixtures('baseapp') | |
|
42 | 42 | |
|
43 | 43 | |
|
44 | def test_Message_extractor(): | |
|
45 | validator = v.ValidUsername() | |
|
44 | @pytest.fixture | |
|
45 | def localizer(): | |
|
46 | def func(msg): | |
|
47 | return msg | |
|
48 | return func | |
|
49 | ||
|
50 | ||
|
51 | def test_Message_extractor(localizer): | |
|
52 | validator = v.ValidUsername(localizer) | |
|
46 | 53 | pytest.raises(formencode.Invalid, validator.to_python, 'default') |
|
47 | 54 | |
|
48 | 55 | class StateObj(object): |
@@ -52,8 +59,8 b' def test_Message_extractor():' | |||
|
52 | 59 | formencode.Invalid, validator.to_python, 'default', StateObj) |
|
53 | 60 | |
|
54 | 61 | |
|
55 | def test_ValidUsername(): | |
|
56 | validator = v.ValidUsername() | |
|
62 | def test_ValidUsername(localizer): | |
|
63 | validator = v.ValidUsername(localizer) | |
|
57 | 64 | |
|
58 | 65 | pytest.raises(formencode.Invalid, validator.to_python, 'default') |
|
59 | 66 | pytest.raises(formencode.Invalid, validator.to_python, 'new_user') |
@@ -62,18 +69,18 b' def test_ValidUsername():' | |||
|
62 | 69 | formencode.Invalid, validator.to_python, TEST_USER_ADMIN_LOGIN) |
|
63 | 70 | assert 'test' == validator.to_python('test') |
|
64 | 71 | |
|
65 | validator = v.ValidUsername(edit=True, old_data={'user_id': 1}) | |
|
72 | validator = v.ValidUsername(localizer, edit=True, old_data={'user_id': 1}) | |
|
66 | 73 | |
|
67 | 74 | |
|
68 | def test_ValidRepoUser(): | |
|
69 | validator = v.ValidRepoUser() | |
|
75 | def test_ValidRepoUser(localizer): | |
|
76 | validator = v.ValidRepoUser(localizer) | |
|
70 | 77 | pytest.raises(formencode.Invalid, validator.to_python, 'nouser') |
|
71 | 78 | assert TEST_USER_ADMIN_LOGIN == \ |
|
72 | 79 | validator.to_python(TEST_USER_ADMIN_LOGIN) |
|
73 | 80 | |
|
74 | 81 | |
|
75 | def test_ValidUserGroup(): | |
|
76 | validator = v.ValidUserGroup() | |
|
82 | def test_ValidUserGroup(localizer): | |
|
83 | validator = v.ValidUserGroup(localizer) | |
|
77 | 84 | pytest.raises(formencode.Invalid, validator.to_python, 'default') |
|
78 | 85 | pytest.raises(formencode.Invalid, validator.to_python, '.,') |
|
79 | 86 | |
@@ -82,7 +89,7 b' def test_ValidUserGroup():' | |||
|
82 | 89 | Session().commit() |
|
83 | 90 | pytest.raises(formencode.Invalid, validator.to_python, 'test') |
|
84 | 91 | assert gr.users_group_id is not None |
|
85 | validator = v.ValidUserGroup( | |
|
92 | validator = v.ValidUserGroup(localizer, | |
|
86 | 93 | edit=True, |
|
87 | 94 | old_data={'users_group_id': gr2.users_group_id}) |
|
88 | 95 | |
@@ -109,24 +116,24 b' def repo_group(request):' | |||
|
109 | 116 | return gr |
|
110 | 117 | |
|
111 | 118 | |
|
112 | def test_ValidRepoGroup_same_name_as_repo(): | |
|
113 | validator = v.ValidRepoGroup() | |
|
119 | def test_ValidRepoGroup_same_name_as_repo(localizer): | |
|
120 | validator = v.ValidRepoGroup(localizer) | |
|
114 | 121 | with pytest.raises(formencode.Invalid) as excinfo: |
|
115 | 122 | validator.to_python({'group_name': HG_REPO}) |
|
116 | 123 | expected_msg = 'Repository with name "vcs_test_hg" already exists' |
|
117 | 124 | assert expected_msg in str(excinfo.value) |
|
118 | 125 | |
|
119 | 126 | |
|
120 | def test_ValidRepoGroup_group_exists(repo_group): | |
|
121 | validator = v.ValidRepoGroup() | |
|
127 | def test_ValidRepoGroup_group_exists(localizer, repo_group): | |
|
128 | validator = v.ValidRepoGroup(localizer) | |
|
122 | 129 | with pytest.raises(formencode.Invalid) as excinfo: |
|
123 | 130 | validator.to_python({'group_name': repo_group.group_name}) |
|
124 | 131 | expected_msg = 'Group "test_gr" already exists' |
|
125 | 132 | assert expected_msg in str(excinfo.value) |
|
126 | 133 | |
|
127 | 134 | |
|
128 | def test_ValidRepoGroup_invalid_parent(repo_group): | |
|
129 | validator = v.ValidRepoGroup(edit=True, | |
|
135 | def test_ValidRepoGroup_invalid_parent(localizer, repo_group): | |
|
136 | validator = v.ValidRepoGroup(localizer, edit=True, | |
|
130 | 137 | old_data={'group_id': repo_group.group_id}) |
|
131 | 138 | with pytest.raises(formencode.Invalid) as excinfo: |
|
132 | 139 | validator.to_python({ |
@@ -137,8 +144,8 b' def test_ValidRepoGroup_invalid_parent(r' | |||
|
137 | 144 | assert expected_msg in str(excinfo.value) |
|
138 | 145 | |
|
139 | 146 | |
|
140 | def test_ValidRepoGroup_edit_group_no_root_permission(repo_group): | |
|
141 | validator = v.ValidRepoGroup( | |
|
147 | def test_ValidRepoGroup_edit_group_no_root_permission(localizer, repo_group): | |
|
148 | validator = v.ValidRepoGroup(localizer, | |
|
142 | 149 | edit=True, old_data={'group_id': repo_group.group_id}, |
|
143 | 150 | can_create_in_root=False) |
|
144 | 151 | |
@@ -156,15 +163,15 b' def test_ValidRepoGroup_edit_group_no_ro' | |||
|
156 | 163 | validator.to_python({'enable_locking': 'true', 'group_parent_id': '-1'}) |
|
157 | 164 | |
|
158 | 165 | |
|
159 | def test_ValidPassword(): | |
|
160 | validator = v.ValidPassword() | |
|
166 | def test_ValidPassword(localizer): | |
|
167 | validator = v.ValidPassword(localizer) | |
|
161 | 168 | assert 'lol' == validator.to_python('lol') |
|
162 | 169 | assert None == validator.to_python(None) |
|
163 | 170 | pytest.raises(formencode.Invalid, validator.to_python, 'ąćżź') |
|
164 | 171 | |
|
165 | 172 | |
|
166 | def test_ValidPasswordsMatch(): | |
|
167 | validator = v.ValidPasswordsMatch() | |
|
173 | def test_ValidPasswordsMatch(localizer): | |
|
174 | validator = v.ValidPasswordsMatch(localizer) | |
|
168 | 175 | pytest.raises( |
|
169 | 176 | formencode.Invalid, |
|
170 | 177 | validator.to_python, {'password': 'pass', |
@@ -184,11 +191,11 b' def test_ValidPasswordsMatch():' | |||
|
184 | 191 | 'password_confirmation': 'pass'}) |
|
185 | 192 | |
|
186 | 193 | |
|
187 | def test_ValidAuth(config_stub): | |
|
194 | def test_ValidAuth(localizer, config_stub): | |
|
188 | 195 | config_stub.testing_securitypolicy() |
|
189 | 196 | config_stub.include('rhodecode.authentication') |
|
190 | 197 | |
|
191 | validator = v.ValidAuth() | |
|
198 | validator = v.ValidAuth(localizer) | |
|
192 | 199 | valid_creds = { |
|
193 | 200 | 'username': TEST_USER_REGULAR2_LOGIN, |
|
194 | 201 | 'password': TEST_USER_REGULAR2_PASS, |
@@ -202,17 +209,14 b' def test_ValidAuth(config_stub):' | |||
|
202 | 209 | formencode.Invalid, validator.to_python, invalid_creds) |
|
203 | 210 | |
|
204 | 211 | |
|
205 | # TODO: johbo: Fix or wipe this test | |
|
206 | def test_ValidAuthToken(): | |
|
207 | validator = v.ValidAuthToken() | |
|
208 | # this is untestable without a threadlocal | |
|
209 | # pytest.raises(formencode.Invalid, | |
|
210 | # validator.to_python, 'BadToken') | |
|
212 | def test_ValidAuthToken(localizer): | |
|
213 | validator = v.ValidAuthToken(localizer) | |
|
214 | pytest.raises(formencode.Invalid, validator.to_python, 'BadToken') | |
|
211 | 215 | validator |
|
212 | 216 | |
|
213 | 217 | |
|
214 | def test_ValidRepoName(): | |
|
215 | validator = v.ValidRepoName() | |
|
218 | def test_ValidRepoName(localizer): | |
|
219 | validator = v.ValidRepoName(localizer) | |
|
216 | 220 | |
|
217 | 221 | pytest.raises( |
|
218 | 222 | formencode.Invalid, validator.to_python, {'repo_name': ''}) |
@@ -232,7 +236,7 b' def test_ValidRepoName():' | |||
|
232 | 236 | # 'repo_group': gr.group_id}) |
|
233 | 237 | |
|
234 | 238 | |
|
235 | def test_ValidForkName(): | |
|
239 | def test_ValidForkName(localizer): | |
|
236 | 240 | # this uses ValidRepoName validator |
|
237 | 241 | assert True |
|
238 | 242 | |
@@ -241,37 +245,26 b' def test_ValidForkName():' | |||
|
241 | 245 | ('ala ma kota', 'ala-ma-kota'), ('@nooo', 'nooo'), |
|
242 | 246 | ('$!haha lolz !', 'haha-lolz'), ('$$$$$', ''), ('{}OK!', 'OK'), |
|
243 | 247 | ('/]re po', 're-po')]) |
|
244 | def test_SlugifyName(name, expected): | |
|
245 | validator = v.SlugifyName() | |
|
248 | def test_SlugifyName(name, expected, localizer): | |
|
249 | validator = v.SlugifyName(localizer) | |
|
246 | 250 | assert expected == validator.to_python(name) |
|
247 | 251 | |
|
248 | 252 | |
|
249 | def test_ValidForkType(): | |
|
250 | validator = v.ValidForkType(old_data={'repo_type': 'hg'}) | |
|
253 | def test_ValidForkType(localizer): | |
|
254 | validator = v.ValidForkType(localizer, old_data={'repo_type': 'hg'}) | |
|
251 | 255 | assert 'hg' == validator.to_python('hg') |
|
252 | 256 | pytest.raises(formencode.Invalid, validator.to_python, 'git') |
|
253 | 257 | |
|
254 | 258 | |
|
255 |
def test_Valid |
|
|
256 |
validator = v.Valid |
|
|
257 | assert {'pass': 'pass'} == \ | |
|
258 | validator.to_python(value={'user': 'test', | |
|
259 | 'pass': 'pass'}) | |
|
260 | ||
|
261 | assert {'user2': 'test', 'pass': 'pass'} == \ | |
|
262 | validator.to_python(value={'user2': 'test', | |
|
263 | 'pass': 'pass'}) | |
|
264 | ||
|
265 | ||
|
266 | def test_ValidPath(): | |
|
267 | validator = v.ValidPath() | |
|
259 | def test_ValidPath(localizer): | |
|
260 | validator = v.ValidPath(localizer) | |
|
268 | 261 | assert TESTS_TMP_PATH == validator.to_python(TESTS_TMP_PATH) |
|
269 | 262 | pytest.raises( |
|
270 | 263 | formencode.Invalid, validator.to_python, '/no_such_dir') |
|
271 | 264 | |
|
272 | 265 | |
|
273 | def test_UniqSystemEmail(): | |
|
274 | validator = v.UniqSystemEmail(old_data={}) | |
|
266 | def test_UniqSystemEmail(localizer): | |
|
267 | validator = v.UniqSystemEmail(localizer, old_data={}) | |
|
275 | 268 | |
|
276 | 269 | assert 'mail@python.org' == validator.to_python('MaiL@Python.org') |
|
277 | 270 | |
@@ -279,17 +272,17 b' def test_UniqSystemEmail():' | |||
|
279 | 272 | pytest.raises(formencode.Invalid, validator.to_python, email) |
|
280 | 273 | |
|
281 | 274 | |
|
282 | def test_ValidSystemEmail(): | |
|
283 | validator = v.ValidSystemEmail() | |
|
275 | def test_ValidSystemEmail(localizer): | |
|
276 | validator = v.ValidSystemEmail(localizer) | |
|
284 | 277 | email = TEST_USER_REGULAR2_EMAIL |
|
285 | 278 | |
|
286 | 279 | assert email == validator.to_python(email) |
|
287 | 280 | pytest.raises(formencode.Invalid, validator.to_python, 'err') |
|
288 | 281 | |
|
289 | 282 | |
|
290 | def test_NotReviewedRevisions(): | |
|
283 | def test_NotReviewedRevisions(localizer): | |
|
291 | 284 | repo_id = Repository.get_by_repo_name(HG_REPO).repo_id |
|
292 | validator = v.NotReviewedRevisions(repo_id) | |
|
285 | validator = v.NotReviewedRevisions(localizer, repo_id) | |
|
293 | 286 | rev = '0' * 40 |
|
294 | 287 | # add status for a rev, that should throw an error because it is already |
|
295 | 288 | # reviewed |
@@ -88,7 +88,7 b' class RcWebServer(object):' | |||
|
88 | 88 | |
|
89 | 89 | |
|
90 | 90 | @pytest.fixture(scope="module") |
|
91 |
def rcextensions(request, |
|
|
91 | def rcextensions(request, baseapp, tmpdir_factory): | |
|
92 | 92 | """ |
|
93 | 93 | Installs a testing rcextensions pack to ensure they work as expected. |
|
94 | 94 | """ |
@@ -114,7 +114,7 b' def rcextensions(request, pylonsapp, tmp' | |||
|
114 | 114 | |
|
115 | 115 | |
|
116 | 116 | @pytest.fixture(scope="module") |
|
117 |
def repos(request, |
|
|
117 | def repos(request, baseapp): | |
|
118 | 118 | """Create a copy of each test repo in a repo group.""" |
|
119 | 119 | fixture = Fixture() |
|
120 | 120 | repo_group = fixture.create_repo_group(REPO_GROUP) |
@@ -146,7 +146,7 b' def rc_web_server_config(testini_factory' | |||
|
146 | 146 | |
|
147 | 147 | @pytest.fixture(scope="module") |
|
148 | 148 | def rc_web_server( |
|
149 |
request, |
|
|
149 | request, baseapp, rc_web_server_config, repos, rcextensions): | |
|
150 | 150 | """ |
|
151 | 151 | Run the web server as a subprocess. |
|
152 | 152 | |
@@ -188,7 +188,7 b' def rc_web_server(' | |||
|
188 | 188 | |
|
189 | 189 | |
|
190 | 190 | @pytest.fixture |
|
191 |
def disable_locking( |
|
|
191 | def disable_locking(baseapp): | |
|
192 | 192 | r = Repository.get_by_repo_name(GIT_REPO) |
|
193 | 193 | Repository.unlock(r) |
|
194 | 194 | r.enable_locking = False |
@@ -203,7 +203,7 b' def disable_locking(pylonsapp):' | |||
|
203 | 203 | |
|
204 | 204 | |
|
205 | 205 | @pytest.fixture |
|
206 |
def enable_auth_plugins(request, |
|
|
206 | def enable_auth_plugins(request, baseapp, csrf_token): | |
|
207 | 207 | """ |
|
208 | 208 | Return a factory object that when called, allows to control which |
|
209 | 209 | authentication plugins are enabled. |
@@ -110,7 +110,6 b' def pytest_addoption(parser):' | |||
|
110 | 110 | def pytest_configure(config): |
|
111 | 111 | # Appy the kombu patch early on, needed for test discovery on Python 2.7.11 |
|
112 | 112 | from rhodecode.config import patches |
|
113 | patches.kombu_1_5_1_python_2_7_11() | |
|
114 | 113 | |
|
115 | 114 | |
|
116 | 115 | def pytest_collection_modifyitems(session, config, items): |
@@ -221,9 +220,9 b' def http_environ(http_host_stub):' | |||
|
221 | 220 | |
|
222 | 221 | |
|
223 | 222 | @pytest.fixture(scope='function') |
|
224 |
def app(request, config_stub, |
|
|
223 | def app(request, config_stub, baseapp, http_environ): | |
|
225 | 224 | app = CustomTestApp( |
|
226 |
|
|
|
225 | baseapp, | |
|
227 | 226 | extra_environ=http_environ) |
|
228 | 227 | if request.cls: |
|
229 | 228 | request.cls.app = app |
@@ -231,31 +230,14 b' def app(request, config_stub, pylonsapp,' | |||
|
231 | 230 | |
|
232 | 231 | |
|
233 | 232 | @pytest.fixture(scope='session') |
|
234 |
def app_settings( |
|
|
233 | def app_settings(baseapp, ini_config): | |
|
235 | 234 | """ |
|
236 | 235 | Settings dictionary used to create the app. |
|
237 | 236 | |
|
238 | 237 | Parses the ini file and passes the result through the sanitize and apply |
|
239 | 238 | defaults mechanism in `rhodecode.config.middleware`. |
|
240 | 239 | """ |
|
241 | from paste.deploy.loadwsgi import loadcontext, APP | |
|
242 | from rhodecode.config.middleware import ( | |
|
243 | sanitize_settings_and_apply_defaults) | |
|
244 | context = loadcontext(APP, 'config:' + pylons_config) | |
|
245 | settings = sanitize_settings_and_apply_defaults(context.config()) | |
|
246 | return settings | |
|
247 | ||
|
248 | ||
|
249 | @pytest.fixture(scope='session') | |
|
250 | def db(app_settings): | |
|
251 | """ | |
|
252 | Initializes the database connection. | |
|
253 | ||
|
254 | It uses the same settings which are used to create the ``pylonsapp`` or | |
|
255 | ``app`` fixtures. | |
|
256 | """ | |
|
257 | from rhodecode.config.utils import initialize_database | |
|
258 | initialize_database(app_settings) | |
|
240 | return baseapp.config.get_settings() | |
|
259 | 241 | |
|
260 | 242 | |
|
261 | 243 | LoginData = collections.namedtuple('LoginData', ('csrf_token', 'user')) |
@@ -306,8 +288,8 b' def real_crypto_backend(monkeypatch):' | |||
|
306 | 288 | |
|
307 | 289 | |
|
308 | 290 | @pytest.fixture(scope='class') |
|
309 |
def index_location(request, |
|
|
310 |
index_location = |
|
|
291 | def index_location(request, baseapp): | |
|
292 | index_location = baseapp.config.get_settings()['search.location'] | |
|
311 | 293 | if request.cls: |
|
312 | 294 | request.cls.index_location = index_location |
|
313 | 295 | return index_location |
@@ -421,7 +403,7 b' class TestRepoContainer(object):' | |||
|
421 | 403 | |
|
422 | 404 | |
|
423 | 405 | @pytest.fixture |
|
424 |
def backend(request, backend_alias, |
|
|
406 | def backend(request, backend_alias, baseapp, test_repo): | |
|
425 | 407 | """ |
|
426 | 408 | Parametrized fixture which represents a single backend implementation. |
|
427 | 409 | |
@@ -449,18 +431,18 b' def backend(request, backend_alias, pylo' | |||
|
449 | 431 | |
|
450 | 432 | |
|
451 | 433 | @pytest.fixture |
|
452 |
def backend_git(request, |
|
|
453 |
return backend(request, 'git', |
|
|
434 | def backend_git(request, baseapp, test_repo): | |
|
435 | return backend(request, 'git', baseapp, test_repo) | |
|
454 | 436 | |
|
455 | 437 | |
|
456 | 438 | @pytest.fixture |
|
457 |
def backend_hg(request, |
|
|
458 |
return backend(request, 'hg', |
|
|
439 | def backend_hg(request, baseapp, test_repo): | |
|
440 | return backend(request, 'hg', baseapp, test_repo) | |
|
459 | 441 | |
|
460 | 442 | |
|
461 | 443 | @pytest.fixture |
|
462 |
def backend_svn(request, |
|
|
463 |
return backend(request, 'svn', |
|
|
444 | def backend_svn(request, baseapp, test_repo): | |
|
445 | return backend(request, 'svn', baseapp, test_repo) | |
|
464 | 446 | |
|
465 | 447 | |
|
466 | 448 | @pytest.fixture |
@@ -672,7 +654,7 b' class Backend(object):' | |||
|
672 | 654 | |
|
673 | 655 | |
|
674 | 656 | @pytest.fixture |
|
675 |
def vcsbackend(request, backend_alias, tests_tmp_path, |
|
|
657 | def vcsbackend(request, backend_alias, tests_tmp_path, baseapp, test_repo): | |
|
676 | 658 | """ |
|
677 | 659 | Parametrized fixture which represents a single vcs backend implementation. |
|
678 | 660 | |
@@ -700,18 +682,18 b' def vcsbackend(request, backend_alias, t' | |||
|
700 | 682 | |
|
701 | 683 | |
|
702 | 684 | @pytest.fixture |
|
703 |
def vcsbackend_git(request, tests_tmp_path, |
|
|
704 |
return vcsbackend(request, 'git', tests_tmp_path, |
|
|
685 | def vcsbackend_git(request, tests_tmp_path, baseapp, test_repo): | |
|
686 | return vcsbackend(request, 'git', tests_tmp_path, baseapp, test_repo) | |
|
705 | 687 | |
|
706 | 688 | |
|
707 | 689 | @pytest.fixture |
|
708 |
def vcsbackend_hg(request, tests_tmp_path, |
|
|
709 |
return vcsbackend(request, 'hg', tests_tmp_path, |
|
|
690 | def vcsbackend_hg(request, tests_tmp_path, baseapp, test_repo): | |
|
691 | return vcsbackend(request, 'hg', tests_tmp_path, baseapp, test_repo) | |
|
710 | 692 | |
|
711 | 693 | |
|
712 | 694 | @pytest.fixture |
|
713 |
def vcsbackend_svn(request, tests_tmp_path, |
|
|
714 |
return vcsbackend(request, 'svn', tests_tmp_path, |
|
|
695 | def vcsbackend_svn(request, tests_tmp_path, baseapp, test_repo): | |
|
696 | return vcsbackend(request, 'svn', tests_tmp_path, baseapp, test_repo) | |
|
715 | 697 | |
|
716 | 698 | |
|
717 | 699 | @pytest.fixture |
@@ -1093,7 +1075,7 b' class PRTestUtility(object):' | |||
|
1093 | 1075 | |
|
1094 | 1076 | |
|
1095 | 1077 | @pytest.fixture |
|
1096 |
def user_admin( |
|
|
1078 | def user_admin(baseapp): | |
|
1097 | 1079 | """ |
|
1098 | 1080 | Provides the default admin test user as an instance of `db.User`. |
|
1099 | 1081 | """ |
@@ -1102,7 +1084,7 b' def user_admin(pylonsapp):' | |||
|
1102 | 1084 | |
|
1103 | 1085 | |
|
1104 | 1086 | @pytest.fixture |
|
1105 |
def user_regular( |
|
|
1087 | def user_regular(baseapp): | |
|
1106 | 1088 | """ |
|
1107 | 1089 | Provides the default regular test user as an instance of `db.User`. |
|
1108 | 1090 | """ |
@@ -1111,7 +1093,7 b' def user_regular(pylonsapp):' | |||
|
1111 | 1093 | |
|
1112 | 1094 | |
|
1113 | 1095 | @pytest.fixture |
|
1114 |
def user_util(request, |
|
|
1096 | def user_util(request, baseapp): | |
|
1115 | 1097 | """ |
|
1116 | 1098 | Provides a wired instance of `UserUtility` with integrated cleanup. |
|
1117 | 1099 | """ |
@@ -1386,10 +1368,10 b' def collect_appenlight_stats(request, te' | |||
|
1386 | 1368 | if not request.config.getoption('--appenlight'): |
|
1387 | 1369 | return |
|
1388 | 1370 | else: |
|
1389 |
# Only request the |
|
|
1371 | # Only request the baseapp fixture if appenlight tracking is | |
|
1390 | 1372 | # enabled. This will speed up a test run of unit tests by 2 to 3 |
|
1391 | 1373 | # seconds if appenlight is not enabled. |
|
1392 |
|
|
|
1374 | baseapp = request.getfuncargvalue("baseapp") | |
|
1393 | 1375 | url = '{}/api/logs'.format(request.config.getoption('--appenlight-url')) |
|
1394 | 1376 | client = AppenlightClient( |
|
1395 | 1377 | url=url, |
@@ -1402,8 +1384,8 b' def collect_appenlight_stats(request, te' | |||
|
1402 | 1384 | 'message': "Starting", |
|
1403 | 1385 | }) |
|
1404 | 1386 | |
|
1405 |
server_and_port = |
|
|
1406 |
protocol = |
|
|
1387 | server_and_port = baseapp.config.get_settings()['vcs.server'] | |
|
1388 | protocol = baseapp.config.get_settings()['vcs.server.protocol'] | |
|
1407 | 1389 | server = create_vcsserver_proxy(server_and_port, protocol) |
|
1408 | 1390 | with server: |
|
1409 | 1391 | vcs_pid = server.get_pid() |
@@ -1509,13 +1491,13 b' class AppenlightClient():' | |||
|
1509 | 1491 | |
|
1510 | 1492 | if not response.status_code == 200: |
|
1511 | 1493 | pprint.pprint(self.stats) |
|
1512 |
print |
|
|
1513 |
print |
|
|
1494 | print(response.headers) | |
|
1495 | print(response.text) | |
|
1514 | 1496 | raise Exception('Sending to appenlight failed') |
|
1515 | 1497 | |
|
1516 | 1498 | |
|
1517 | 1499 | @pytest.fixture |
|
1518 |
def gist_util(request, |
|
|
1500 | def gist_util(request, baseapp): | |
|
1519 | 1501 | """ |
|
1520 | 1502 | Provides a wired instance of `GistUtility` with integrated cleanup. |
|
1521 | 1503 | """ |
@@ -1821,7 +1803,7 b' def local_dt_to_utc():' | |||
|
1821 | 1803 | |
|
1822 | 1804 | |
|
1823 | 1805 | @pytest.fixture |
|
1824 |
def disable_anonymous_user(request, |
|
|
1806 | def disable_anonymous_user(request, baseapp): | |
|
1825 | 1807 | set_anonymous_access(False) |
|
1826 | 1808 | |
|
1827 | 1809 | @request.addfinalizer |
@@ -18,9 +18,8 b'' | |||
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | import os | |
|
21 | 22 | import json |
|
22 | import logging.config | |
|
23 | import os | |
|
24 | 23 | import platform |
|
25 | 24 | import socket |
|
26 | 25 | import subprocess32 |
@@ -28,16 +27,9 b' import time' | |||
|
28 | 27 | from urllib2 import urlopen, URLError |
|
29 | 28 | |
|
30 | 29 | import configobj |
|
31 | import pylons | |
|
32 | 30 | import pytest |
|
33 | import webob | |
|
34 | from beaker.session import SessionObject | |
|
35 | from paste.deploy import loadapp | |
|
36 | from pylons.i18n.translation import _get_translator | |
|
37 | from pylons.util import ContextObj | |
|
38 | from routes.util import URLGenerator | |
|
39 | 31 | |
|
40 | from rhodecode.lib import vcs | |
|
32 | import pyramid.paster | |
|
41 | 33 | from rhodecode.tests.fixture import TestINI |
|
42 | 34 | import rhodecode |
|
43 | 35 | |
@@ -246,7 +238,7 b' class HttpVCSServer(VCSServer):' | |||
|
246 | 238 | |
|
247 | 239 | |
|
248 | 240 | @pytest.fixture(scope='session') |
|
249 |
def |
|
|
241 | def ini_config(request, tmpdir_factory, rcserver_port, vcsserver_port): | |
|
250 | 242 | option_name = 'pylons_config' |
|
251 | 243 | log_level = _use_log_level(request.config) |
|
252 | 244 | |
@@ -333,23 +325,28 b' def available_port(available_port_factor' | |||
|
333 | 325 | |
|
334 | 326 | |
|
335 | 327 | @pytest.fixture(scope='session') |
|
336 |
def |
|
|
337 | print("Using the RhodeCode configuration:{}".format(pylons_config)) | |
|
338 | logging.config.fileConfig( | |
|
339 | pylons_config, disable_existing_loggers=False) | |
|
340 | app = _setup_pylons_environment(pylons_config, http_environ_session) | |
|
328 | def baseapp(ini_config, vcsserver, http_environ_session): | |
|
329 | from rhodecode.lib.pyramid_utils import get_app_config | |
|
330 | from rhodecode.config.middleware import make_pyramid_app | |
|
331 | ||
|
332 | print("Using the RhodeCode configuration:{}".format(ini_config)) | |
|
333 | pyramid.paster.setup_logging(ini_config) | |
|
334 | ||
|
335 | settings = get_app_config(ini_config) | |
|
336 | app = make_pyramid_app({}, **settings) | |
|
337 | ||
|
341 | 338 | return app |
|
342 | 339 | |
|
343 | 340 | |
|
344 | 341 | @pytest.fixture(scope='session') |
|
345 |
def testini_factory(tmpdir_factory, |
|
|
342 | def testini_factory(tmpdir_factory, ini_config): | |
|
346 | 343 | """ |
|
347 | 344 | Factory to create an INI file based on TestINI. |
|
348 | 345 | |
|
349 | 346 | It will make sure to place the INI file in the correct directory. |
|
350 | 347 | """ |
|
351 | 348 | basetemp = tmpdir_factory.getbasetemp().strpath |
|
352 |
return TestIniFactory(basetemp, |
|
|
349 | return TestIniFactory(basetemp, ini_config) | |
|
353 | 350 | |
|
354 | 351 | |
|
355 | 352 | class TestIniFactory(object): |
@@ -387,36 +384,3 b' def get_config(' | |||
|
387 | 384 | dir=basetemp) |
|
388 | 385 | |
|
389 | 386 | return temp_ini_file.create() |
|
390 | ||
|
391 | ||
|
392 | def _setup_pylons_environment(pylons_config, http_environ): | |
|
393 | current_path = os.getcwd() | |
|
394 | pylonsapp = loadapp( | |
|
395 | 'config:' + pylons_config, relative_to=current_path) | |
|
396 | ||
|
397 | # Using rhodecode.CONFIG which is assigned during "load_environment". | |
|
398 | # The indirect approach is used, because "pylonsapp" may actually be | |
|
399 | # the Pyramid application. | |
|
400 | pylonsapp_config = rhodecode.CONFIG | |
|
401 | _init_stack(pylonsapp_config, environ=http_environ) | |
|
402 | ||
|
403 | # For compatibility add the attribute "config" which would be | |
|
404 | # present on the Pylons application. | |
|
405 | pylonsapp.config = pylonsapp_config | |
|
406 | return pylonsapp | |
|
407 | ||
|
408 | ||
|
409 | def _init_stack(config=None, environ=None): | |
|
410 | if not config: | |
|
411 | config = pylons.test.pylonsapp.config | |
|
412 | if not environ: | |
|
413 | environ = {} | |
|
414 | pylons.url._push_object(URLGenerator(config['routes.map'], environ or {})) | |
|
415 | pylons.app_globals._push_object(config['pylons.app_globals']) | |
|
416 | pylons.config._push_object(config) | |
|
417 | pylons.tmpl_context._push_object(ContextObj()) | |
|
418 | # Initialize a translator for tests that utilize i18n | |
|
419 | translator = _get_translator(pylons.config.get('lang')) | |
|
420 | pylons.translator._push_object(translator) | |
|
421 | pylons.session._push_object(SessionObject(environ or {})) | |
|
422 | pylons.request._push_object(webob.Request.blank('', environ=environ)) |
@@ -390,7 +390,7 b' beaker.cache.sql_cache_short.key_length ' | |||
|
390 | 390 | |
|
391 | 391 | ## default is memory cache, configure only if required |
|
392 | 392 | ## using multi-node or multi-worker setup |
|
393 |
|
|
|
393 | beaker.cache.auth_plugins.type = memory | |
|
394 | 394 | #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock |
|
395 | 395 | #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode |
|
396 | 396 | #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode |
@@ -31,9 +31,7 b' from os.path import dirname as dn' | |||
|
31 | 31 | |
|
32 | 32 | from tempfile import _RandomNameSequence |
|
33 | 33 | from subprocess32 import Popen, PIPE |
|
34 | from paste.deploy import appconfig | |
|
35 | 34 | |
|
36 | from rhodecode.lib.utils import add_cache | |
|
37 | 35 | from rhodecode.lib.utils2 import engine_from_config |
|
38 | 36 | from rhodecode.lib.auth import get_crypt_password |
|
39 | 37 | from rhodecode.model import init_model |
@@ -41,13 +39,9 b' from rhodecode.model import meta' | |||
|
41 | 39 | from rhodecode.model.db import User, Repository |
|
42 | 40 | |
|
43 | 41 | from rhodecode.tests import TESTS_TMP_PATH, HG_REPO |
|
44 | from rhodecode.config.environment import load_environment | |
|
45 | 42 | |
|
46 | 43 | rel_path = dn(dn(dn(dn(os.path.abspath(__file__))))) |
|
47 | conf = appconfig('config:rc.ini', relative_to=rel_path) | |
|
48 | load_environment(conf.global_conf, conf.local_conf) | |
|
49 | 44 | |
|
50 | add_cache(conf) | |
|
51 | 45 | |
|
52 | 46 | USER = 'test_admin' |
|
53 | 47 | PASS = 'test12' |
@@ -69,15 +63,16 b' class Command(object):' | |||
|
69 | 63 | command = cmd + ' ' + ' '.join(args) |
|
70 | 64 | log.debug('Executing %s' % command) |
|
71 | 65 | if DEBUG: |
|
72 |
print |
|
|
66 | print(command) | |
|
73 | 67 | p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd) |
|
74 | 68 | stdout, stderr = p.communicate() |
|
75 | 69 | if DEBUG: |
|
76 | print stdout, stderr | |
|
70 | print('{} {}'.format(stdout, stderr)) | |
|
77 | 71 | return stdout, stderr |
|
78 | 72 | |
|
79 | 73 | |
|
80 | 74 | def get_session(): |
|
75 | conf = {} | |
|
81 | 76 | engine = engine_from_config(conf, 'sqlalchemy.db1.') |
|
82 | 77 | init_model(engine) |
|
83 | 78 | sa = meta.Session |
@@ -85,20 +80,20 b' def get_session():' | |||
|
85 | 80 | |
|
86 | 81 | |
|
87 | 82 | def create_test_user(force=True): |
|
88 |
print |
|
|
83 | print('creating test user') | |
|
89 | 84 | sa = get_session() |
|
90 | 85 | |
|
91 | 86 | user = sa.query(User).filter(User.username == USER).scalar() |
|
92 | 87 | |
|
93 | 88 | if force and user is not None: |
|
94 |
print |
|
|
89 | print('removing current user') | |
|
95 | 90 | for repo in sa.query(Repository).filter(Repository.user == user).all(): |
|
96 | 91 | sa.delete(repo) |
|
97 | 92 | sa.delete(user) |
|
98 | 93 | sa.commit() |
|
99 | 94 | |
|
100 | 95 | if user is None or force: |
|
101 |
print |
|
|
96 | print('creating new one') | |
|
102 | 97 | new_usr = User() |
|
103 | 98 | new_usr.username = USER |
|
104 | 99 | new_usr.password = get_crypt_password(PASS) |
@@ -110,11 +105,11 b' def create_test_user(force=True):' | |||
|
110 | 105 | sa.add(new_usr) |
|
111 | 106 | sa.commit() |
|
112 | 107 | |
|
113 |
print |
|
|
108 | print('done') | |
|
114 | 109 | |
|
115 | 110 | |
|
116 | 111 | def create_test_repo(force=True): |
|
117 |
print |
|
|
112 | print('creating test repo') | |
|
118 | 113 | from rhodecode.model.repo import RepoModel |
|
119 | 114 | sa = get_session() |
|
120 | 115 | |
@@ -125,7 +120,7 b' def create_test_repo(force=True):' | |||
|
125 | 120 | repo = sa.query(Repository).filter(Repository.repo_name == HG_REPO).scalar() |
|
126 | 121 | |
|
127 | 122 | if repo is None: |
|
128 |
print |
|
|
123 | print('repo not found creating') | |
|
129 | 124 | |
|
130 | 125 | form_data = {'repo_name': HG_REPO, |
|
131 | 126 | 'repo_type': 'hg', |
@@ -135,7 +130,7 b' def create_test_repo(force=True):' | |||
|
135 | 130 | rm.base_path = '/home/hg' |
|
136 | 131 | rm.create(form_data, user) |
|
137 | 132 | |
|
138 |
print |
|
|
133 | print('done') | |
|
139 | 134 | |
|
140 | 135 | |
|
141 | 136 | def get_anonymous_access(): |
@@ -177,6 +172,7 b' def test_clone_with_credentials(repo=HG_' | |||
|
177 | 172 | elif backend == 'git': |
|
178 | 173 | assert """Cloning into""" in stdout, 'no messages about cloning' |
|
179 | 174 | |
|
175 | ||
|
180 | 176 | if __name__ == '__main__': |
|
181 | 177 | try: |
|
182 | 178 | create_test_user(force=False) |
@@ -199,9 +195,9 b" if __name__ == '__main__':" | |||
|
199 | 195 | seq=seq, backend=backend) |
|
200 | 196 | s = time.time() |
|
201 | 197 | for i in range(1, int(sys.argv[2]) + 1): |
|
202 |
print |
|
|
198 | print('take {}'.format(i)) | |
|
203 | 199 | test_clone_with_credentials(repo=sys.argv[1], method=METHOD, |
|
204 | 200 | seq=seq, backend=backend) |
|
205 |
print |
|
|
201 | print('time taken %.3f' % (time.time() - s)) | |
|
206 | 202 | except Exception as e: |
|
207 | 203 | sys.exit('stop on %s' % e) |
@@ -97,11 +97,13 b' class CustomTestResponse(TestResponse):' | |||
|
97 | 97 | |
|
98 | 98 | def get_session_from_response(self): |
|
99 | 99 | """ |
|
100 |
This returns the session from a response object. |
|
|
101 | to make the session available as `response.session`. But pyramid | |
|
102 | doesn't expose it. | |
|
100 | This returns the session from a response object. | |
|
103 | 101 | """ |
|
104 | return self.request.environ['beaker.session'] | |
|
102 | ||
|
103 | from pyramid_beaker import session_factory_from_settings | |
|
104 | session = session_factory_from_settings( | |
|
105 | self.test_app.app.config.get_settings()) | |
|
106 | return session(self.request) | |
|
105 | 107 | |
|
106 | 108 | |
|
107 | 109 | class TestRequest(webob.BaseRequest): |
@@ -110,6 +112,9 b' class TestRequest(webob.BaseRequest):' | |||
|
110 | 112 | disabled = True |
|
111 | 113 | ResponseClass = CustomTestResponse |
|
112 | 114 | |
|
115 | def add_response_callback(self, callback): | |
|
116 | pass | |
|
117 | ||
|
113 | 118 | |
|
114 | 119 | class CustomTestApp(TestApp): |
|
115 | 120 | """ |
@@ -34,7 +34,7 b' from rhodecode.tests.vcs.base import Bac' | |||
|
34 | 34 | |
|
35 | 35 | @pytest.fixture() |
|
36 | 36 | def vcs_repository_support( |
|
37 |
request, backend_alias, |
|
|
37 | request, backend_alias, baseapp, _vcs_repo_container): | |
|
38 | 38 | """ |
|
39 | 39 | Provide a test repository for the test run. |
|
40 | 40 |
@@ -65,7 +65,7 b' class TestGitRepository:' | |||
|
65 | 65 | % TEST_GIT_REPO_CLONE) |
|
66 | 66 | |
|
67 | 67 | @pytest.fixture(autouse=True) |
|
68 |
def prepare(self, request, |
|
|
68 | def prepare(self, request, baseapp): | |
|
69 | 69 | self.repo = GitRepository(TEST_GIT_REPO, bare=True) |
|
70 | 70 | |
|
71 | 71 | def get_clone_repo(self): |
@@ -1153,7 +1153,7 b' class TestGitRegression(BackendTestMixin' | |||
|
1153 | 1153 | |
|
1154 | 1154 | class TestDiscoverGitVersion: |
|
1155 | 1155 | |
|
1156 |
def test_returns_git_version(self, |
|
|
1156 | def test_returns_git_version(self, baseapp): | |
|
1157 | 1157 | version = discover_git_version() |
|
1158 | 1158 | assert version |
|
1159 | 1159 |
@@ -51,7 +51,7 b' REPO_PATH_GENERATOR = repo_path_generato' | |||
|
51 | 51 | |
|
52 | 52 | |
|
53 | 53 | @pytest.fixture(scope='class', autouse=True) |
|
54 |
def repo(request, |
|
|
54 | def repo(request, baseapp): | |
|
55 | 55 | repo = MercurialRepository(TEST_HG_REPO) |
|
56 | 56 | if request.cls: |
|
57 | 57 | request.cls.repo = repo |
@@ -49,7 +49,7 b" TEST_GIT_REPO = os.environ.get('TEST_GIT" | |||
|
49 | 49 | |
|
50 | 50 | |
|
51 | 51 | @pytest.fixture(params=('hg', 'git')) |
|
52 |
def repo(request, |
|
|
52 | def repo(request, baseapp): | |
|
53 | 53 | repos = { |
|
54 | 54 | 'hg': TEST_HG_REPO, |
|
55 | 55 | 'git': TEST_GIT_REPO, |
@@ -59,12 +59,12 b' def repo(request, pylonsapp):' | |||
|
59 | 59 | |
|
60 | 60 | |
|
61 | 61 | @pytest.fixture |
|
62 |
def server( |
|
|
62 | def server(baseapp): | |
|
63 | 63 | """ |
|
64 | 64 | Returns a proxy of the server object. |
|
65 | 65 | """ |
|
66 |
server_and_port = |
|
|
67 |
protocol = |
|
|
66 | server_and_port = baseapp.config.get_settings()['vcs.server'] | |
|
67 | protocol = baseapp.config.get_settings()['vcs.server.protocol'] | |
|
68 | 68 | server = create_vcsserver_proxy(server_and_port, protocol) |
|
69 | 69 | return server |
|
70 | 70 |
@@ -31,12 +31,12 b' from rhodecode.lib.vcs.exceptions import' | |||
|
31 | 31 | |
|
32 | 32 | pytestmark = [ |
|
33 | 33 | pytest.mark.backends("svn"), |
|
34 |
pytest.mark.usefixtures(" |
|
|
34 | pytest.mark.usefixtures("baseapp"), | |
|
35 | 35 | ] |
|
36 | 36 | |
|
37 | 37 | |
|
38 | 38 | @pytest.fixture |
|
39 |
def repo( |
|
|
39 | def repo(baseapp): | |
|
40 | 40 | repo = SubversionRepository(os.path.join(TESTS_TMP_PATH, SVN_REPO)) |
|
41 | 41 | return repo |
|
42 | 42 |
@@ -32,7 +32,7 b' from rhodecode.lib.vcs.utils.helpers imp' | |||
|
32 | 32 | from rhodecode.lib.vcs.utils.paths import get_dirs_for_path |
|
33 | 33 | |
|
34 | 34 | |
|
35 |
@pytest.mark.usefixtures(" |
|
|
35 | @pytest.mark.usefixtures("baseapp") | |
|
36 | 36 | class TestPaths: |
|
37 | 37 | |
|
38 | 38 | def _test_get_dirs_for_path(self, path, expected): |
@@ -34,7 +34,7 b' from rhodecode.lib.vcs.backends.hg impor' | |||
|
34 | 34 | from rhodecode.tests import TEST_HG_REPO, TEST_GIT_REPO |
|
35 | 35 | |
|
36 | 36 | |
|
37 |
pytestmark = pytest.mark.usefixtures(" |
|
|
37 | pytestmark = pytest.mark.usefixtures("baseapp") | |
|
38 | 38 | |
|
39 | 39 | |
|
40 | 40 | def test_get_backend(): |
@@ -19,16 +19,24 b'' | |||
|
19 | 19 | from pyramid.i18n import TranslationStringFactory, TranslationString |
|
20 | 20 | |
|
21 | 21 | # Create a translation string factory for the 'rhodecode' domain. |
|
22 | from pyramid.threadlocal import get_current_request | |
|
23 | ||
|
22 | 24 | _ = TranslationStringFactory('rhodecode') |
|
23 | 25 | |
|
26 | temp_translation_factory = _ | |
|
24 | 27 | |
|
25 | class LazyString(object): | |
|
28 | ||
|
29 | class _LazyString(object): | |
|
26 | 30 | def __init__(self, *args, **kw): |
|
27 | 31 | self.args = args |
|
28 | 32 | self.kw = kw |
|
29 | 33 | |
|
30 | 34 | def eval(self): |
|
31 | return _(*self.args, **self.kw) | |
|
35 | req = get_current_request() | |
|
36 | translator = _ | |
|
37 | if req: | |
|
38 | translator = req.translator | |
|
39 | return translator(*self.args, **self.kw) | |
|
32 | 40 | |
|
33 | 41 | def __unicode__(self): |
|
34 | 42 | return unicode(self.eval()) |
@@ -36,6 +44,9 b' class LazyString(object):' | |||
|
36 | 44 | def __str__(self): |
|
37 | 45 | return self.eval() |
|
38 | 46 | |
|
47 | def __repr__(self): | |
|
48 | return self.__str__() | |
|
49 | ||
|
39 | 50 | def __mod__(self, other): |
|
40 | 51 | return self.eval() % other |
|
41 | 52 | |
@@ -45,7 +56,7 b' class LazyString(object):' | |||
|
45 | 56 | |
|
46 | 57 | def lazy_ugettext(*args, **kw): |
|
47 | 58 | """ Lazily evaluated version of _() """ |
|
48 | return LazyString(*args, **kw) | |
|
59 | return _LazyString(*args, **kw) | |
|
49 | 60 | |
|
50 | 61 | |
|
51 | 62 | def _pluralize(msgid1, msgid2, n, mapping=None): |
@@ -35,19 +35,22 b' def vcs_detection_tween_factory(handler,' | |||
|
35 | 35 | Do detection of vcs type, and save results for other layers to re-use |
|
36 | 36 | this information |
|
37 | 37 | """ |
|
38 | ||
|
39 | vcs_handler = detect_vcs_request( | |
|
38 | vcs_server_enabled = request.registry.settings.get('vcs.server.enable') | |
|
39 | vcs_handler = vcs_server_enabled and detect_vcs_request( | |
|
40 | 40 | request.environ, request.registry.settings.get('vcs.backends')) |
|
41 | 41 | |
|
42 | 42 | if vcs_handler: |
|
43 | 43 | # save detected VCS type for later re-use |
|
44 | 44 | request.environ[VCS_TYPE_KEY] = vcs_handler.SCM |
|
45 | 45 | request.vcs_call = vcs_handler.SCM |
|
46 | ||
|
47 | log.debug('Processing request with `%s` handler', handler) | |
|
46 | 48 | return handler(request) |
|
47 | 49 | |
|
48 | 50 | # mark that we didn't detect an VCS, and we can skip detection later on |
|
49 | 51 | request.environ[VCS_TYPE_KEY] = VCS_TYPE_SKIP |
|
50 | 52 | |
|
53 | log.debug('Processing request with `%s` handler', handler) | |
|
51 | 54 | return handler(request) |
|
52 | 55 | |
|
53 | 56 | return vcs_detection_tween |
@@ -62,7 +65,5 b' def includeme(config):' | |||
|
62 | 65 | 'pyramid.events.NewRequest') |
|
63 | 66 | config.add_subscriber('rhodecode.subscribers.add_request_user_context', |
|
64 | 67 | 'pyramid.events.ContextFound') |
|
65 | config.add_subscriber('rhodecode.subscribers.add_pylons_context', | |
|
66 | 'pyramid.events.ContextFound') | |
|
67 | 68 | |
|
68 | 69 | config.add_tween('rhodecode.tweens.vcs_detection_tween_factory') |
@@ -66,85 +66,10 b' def _get_requirements(req_filename, excl' | |||
|
66 | 66 | # requirements extract |
|
67 | 67 | setup_requirements = ['PasteScript', 'pytest-runner'] |
|
68 | 68 | install_requirements = _get_requirements( |
|
69 | 'requirements.txt', exclude=['setuptools']) | |
|
69 | 'requirements.txt', exclude=['setuptools', 'entrypoints']) | |
|
70 | 70 | test_requirements = _get_requirements( |
|
71 | 71 | 'requirements_test.txt', extras=['configobj']) |
|
72 | 72 | |
|
73 | install_requirements = [ | |
|
74 | 'Babel', | |
|
75 | 'Beaker', | |
|
76 | 'FormEncode', | |
|
77 | 'Mako', | |
|
78 | 'Markdown', | |
|
79 | 'MarkupSafe', | |
|
80 | 'MySQL-python', | |
|
81 | 'Paste', | |
|
82 | 'PasteDeploy', | |
|
83 | 'PasteScript', | |
|
84 | 'Pygments', | |
|
85 | 'pygments-markdown-lexer', | |
|
86 | 'Pylons', | |
|
87 | 'Routes', | |
|
88 | 'SQLAlchemy', | |
|
89 | 'Tempita', | |
|
90 | 'URLObject', | |
|
91 | 'WebError', | |
|
92 | 'WebHelpers', | |
|
93 | 'WebHelpers2', | |
|
94 | 'WebOb', | |
|
95 | 'WebTest', | |
|
96 | 'Whoosh', | |
|
97 | 'alembic', | |
|
98 | 'amqplib', | |
|
99 | 'anyjson', | |
|
100 | 'appenlight-client', | |
|
101 | 'authomatic', | |
|
102 | 'cssselect', | |
|
103 | 'celery', | |
|
104 | 'channelstream', | |
|
105 | 'colander', | |
|
106 | 'decorator', | |
|
107 | 'deform', | |
|
108 | 'docutils', | |
|
109 | 'gevent', | |
|
110 | 'gunicorn', | |
|
111 | 'infrae.cache', | |
|
112 | 'ipython', | |
|
113 | 'iso8601', | |
|
114 | 'kombu', | |
|
115 | 'lxml', | |
|
116 | 'msgpack-python', | |
|
117 | 'nbconvert', | |
|
118 | 'packaging', | |
|
119 | 'psycopg2', | |
|
120 | 'py-gfm', | |
|
121 | 'pycrypto', | |
|
122 | 'pycurl', | |
|
123 | 'pyparsing', | |
|
124 | 'pyramid', | |
|
125 | 'pyramid-debugtoolbar', | |
|
126 | 'pyramid-mako', | |
|
127 | 'pyramid-beaker', | |
|
128 | 'pysqlite', | |
|
129 | 'python-dateutil', | |
|
130 | 'python-ldap', | |
|
131 | 'python-memcached', | |
|
132 | 'python-pam', | |
|
133 | 'recaptcha-client', | |
|
134 | 'redis', | |
|
135 | 'repoze.lru', | |
|
136 | 'requests', | |
|
137 | 'simplejson', | |
|
138 | 'sshpubkeys', | |
|
139 | 'subprocess32', | |
|
140 | 'waitress', | |
|
141 | 'zope.cachedescriptors', | |
|
142 | 'dogpile.cache', | |
|
143 | 'dogpile.core', | |
|
144 | 'psutil', | |
|
145 | 'py-bcrypt', | |
|
146 | ] | |
|
147 | ||
|
148 | 73 | |
|
149 | 74 | def get_version(): |
|
150 | 75 | version = pkgutil.get_data('rhodecode', 'VERSION') |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now