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