Show More
@@ -0,0 +1,105 b'' | |||
|
1 | .. _config-saml-duosecurity-ref: | |
|
2 | ||
|
3 | ||
|
4 | SAML 2.0 with Duo Security | |
|
5 | -------------------------- | |
|
6 | ||
|
7 | **This plugin is available only in EE Edition.** | |
|
8 | ||
|
9 | |RCE| supports SAML 2.0 Authentication with Duo Security provider. This allows | |
|
10 | users to log-in to RhodeCode via SSO mechanism of external identity provider | |
|
11 | such as Duo. The login can be triggered either by the external IDP, or internally | |
|
12 | by clicking specific authentication button on the log-in page. | |
|
13 | ||
|
14 | ||
|
15 | Configuration steps | |
|
16 | ^^^^^^^^^^^^^^^^^^^ | |
|
17 | ||
|
18 | To configure Duo Security SAML authentication, use the following steps: | |
|
19 | ||
|
20 | 1. From the |RCE| interface, select | |
|
21 | :menuselection:`Admin --> Authentication` | |
|
22 | 2. Activate the `Duo Security` plugin and select :guilabel:`Save` | |
|
23 | 3. Go to newly available menu option called `Duo Security` on the left side. | |
|
24 | 4. Check the `enabled` check box in the plugin configuration section, | |
|
25 | and fill in the required SAML information and :guilabel:`Save`, for more details, | |
|
26 | see :ref:`config-saml-duosecurity` | |
|
27 | ||
|
28 | ||
|
29 | .. _config-saml-duosecurity: | |
|
30 | ||
|
31 | ||
|
32 | Example SAML Duo Security configuration | |
|
33 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
|
34 | ||
|
35 | Example configuration for SAML 2.0 with Duo Security provider:: | |
|
36 | ||
|
37 | *option*: `enabled` => `True` | |
|
38 | # Enable or disable this authentication plugin. | |
|
39 | ||
|
40 | *option*: `cache_ttl` => `0` | |
|
41 | # Amount of seconds to cache the authentication and permissions check response call for this plugin. | |
|
42 | # Useful for expensive calls like LDAP to improve the performance of the system (0 means disabled). | |
|
43 | ||
|
44 | *option*: `debug` => `True` | |
|
45 | # Enable or disable debug mode that shows SAML errors in the RhodeCode logs. | |
|
46 | ||
|
47 | *option*: `entity_id` => `http://rc-app.com/dag/saml2/idp/metadata.php` | |
|
48 | # Identity Provider entity/metadata URI. | |
|
49 | # E.g. https://duo-gateway.com/dag/saml2/idp/metadata.php | |
|
50 | ||
|
51 | *option*: `sso_service_url` => `http://rc-app.com/dag/saml2/idp/SSOService.php?spentityid=http://rc.local.pl/_admin/auth/duosecurity/saml-metadata` | |
|
52 | # SSO (SingleSignOn) endpoint URL of the IdP. This can be used to initialize login | |
|
53 | # E.g. https://duo-gateway.com/dag/saml2/idp/SSOService.php?spentityid=<metadata_entity_id> | |
|
54 | ||
|
55 | *option*: `slo_service_url` => `http://rc-app.com/dag/saml2/idp/SingleLogoutService.php?ReturnTo=http://rc-app.com/dag/module.php/duosecurity/logout.php` | |
|
56 | # SLO (SingleLogout) endpoint URL of the IdP. | |
|
57 | # E.g. https://duo-gateway.com/dag/saml2/idp/SingleLogoutService.php?ReturnTo=http://duo-gateway.com/_admin/saml/sign-out-endpoint | |
|
58 | ||
|
59 | *option*: `x509cert` => `<CERTIFICATE_STRING>` | |
|
60 | # Identity provider public x509 certificate. It will be converted to single-line format without headers | |
|
61 | ||
|
62 | *option*: `name_id_format` => `sha-1` | |
|
63 | # The format that specifies how the NameID is sent to the service provider. | |
|
64 | ||
|
65 | *option*: `signature_algo` => `sha-256` | |
|
66 | # Type of Algorithm to use for verification of SAML signature on Identity provider side | |
|
67 | ||
|
68 | *option*: `digest_algo` => `sha-256` | |
|
69 | # Type of Algorithm to use for verification of SAML digest on Identity provider side | |
|
70 | ||
|
71 | *option*: `cert_dir` => `/etc/saml/` | |
|
72 | # Optional directory to store service provider certificate and private keys. | |
|
73 | # Expected certs for the SP should be stored in this folder as: | |
|
74 | # * sp.key Private Key | |
|
75 | # * sp.crt Public cert | |
|
76 | # * sp_new.crt Future Public cert | |
|
77 | # | |
|
78 | # Also you can use other cert to sign the metadata of the SP using the: | |
|
79 | # * metadata.key | |
|
80 | # * metadata.crt | |
|
81 | ||
|
82 | *option*: `user_id_attribute` => `PersonImmutableID` | |
|
83 | # User ID Attribute name. This defines which attribute in SAML response will be used to link accounts via unique id. | |
|
84 | # Ensure this is returned from DuoSecurity for example via duo_username | |
|
85 | ||
|
86 | *option*: `username_attribute` => `User.username` | |
|
87 | # Username Attribute name. This defines which attribute in SAML response will map to an username. | |
|
88 | ||
|
89 | *option*: `email_attribute` => `User.email` | |
|
90 | # Email Attribute name. This defines which attribute in SAML response will map to an email address. | |
|
91 | ||
|
92 | ||
|
93 | Below is example setup from DUO Administration page that can be used with above config. | |
|
94 | ||
|
95 | .. image:: ../images/saml-duosecurity-service-provider-example.png | |
|
96 | :alt: DUO Security SAML setup example | |
|
97 | :scale: 50 % | |
|
98 | ||
|
99 | ||
|
100 | Below is an example attribute mapping set for IDP provider required by the above config. | |
|
101 | ||
|
102 | ||
|
103 | .. image:: ../images/saml-duosecurity-attributes-example.png | |
|
104 | :alt: DUO Security SAML setup example | |
|
105 | :scale: 50 % No newline at end of file |
@@ -0,0 +1,18 b'' | |||
|
1 | .. _config-saml-generic-ref: | |
|
2 | ||
|
3 | ||
|
4 | SAML 2.0 Authentication | |
|
5 | ----------------------- | |
|
6 | ||
|
7 | ||
|
8 | **This plugin is available only in EE Edition.** | |
|
9 | ||
|
10 | RhodeCode Supports standard SAML 2.0 SSO for the web-application part. | |
|
11 | ||
|
12 | Please check for reference two example providers: | |
|
13 | ||
|
14 | .. toctree:: | |
|
15 | ||
|
16 | auth-saml-duosecurity | |
|
17 | auth-saml-onelogin | |
|
18 |
@@ -0,0 +1,106 b'' | |||
|
1 | .. _config-saml-onelogin-ref: | |
|
2 | ||
|
3 | ||
|
4 | SAML 2.0 with One Login | |
|
5 | ----------------------- | |
|
6 | ||
|
7 | **This plugin is available only in EE Edition.** | |
|
8 | ||
|
9 | |RCE| supports SAML 2.0 Authentication with OneLogin provider. This allows | |
|
10 | users to log-in to RhodeCode via SSO mechanism of external identity provider | |
|
11 | such as OneLogin. The login can be triggered either by the external IDP, or internally | |
|
12 | by clicking specific authentication button on the log-in page. | |
|
13 | ||
|
14 | ||
|
15 | Configuration steps | |
|
16 | ^^^^^^^^^^^^^^^^^^^ | |
|
17 | ||
|
18 | To configure OneLogin SAML authentication, use the following steps: | |
|
19 | ||
|
20 | 1. From the |RCE| interface, select | |
|
21 | :menuselection:`Admin --> Authentication` | |
|
22 | 2. Activate the `OneLogin` plugin and select :guilabel:`Save` | |
|
23 | 3. Go to newly available menu option called `OneLogin` on the left side. | |
|
24 | 4. Check the `enabled` check box in the plugin configuration section, | |
|
25 | and fill in the required SAML information and :guilabel:`Save`, for more details, | |
|
26 | see :ref:`config-saml-onelogin` | |
|
27 | ||
|
28 | ||
|
29 | .. _config-saml-onelogin: | |
|
30 | ||
|
31 | ||
|
32 | Example SAML OneLogin configuration | |
|
33 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
|
34 | ||
|
35 | Example configuration for SAML 2.0 with OneLogin provider:: | |
|
36 | ||
|
37 | *option*: `enabled` => `True` | |
|
38 | # Enable or disable this authentication plugin. | |
|
39 | ||
|
40 | *option*: `cache_ttl` => `0` | |
|
41 | # Amount of seconds to cache the authentication and permissions check response call for this plugin. | |
|
42 | # Useful for expensive calls like LDAP to improve the performance of the system (0 means disabled). | |
|
43 | ||
|
44 | *option*: `debug` => `True` | |
|
45 | # Enable or disable debug mode that shows SAML errors in the RhodeCode logs. | |
|
46 | ||
|
47 | *option*: `entity_id` => `https://app.onelogin.com/saml/metadata/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` | |
|
48 | # Identity Provider entity/metadata URI. | |
|
49 | # E.g. https://app.onelogin.com/saml/metadata/<onelogin_connector_id> | |
|
50 | ||
|
51 | *option*: `sso_service_url` => `https://customer-domain.onelogin.com/trust/saml2/http-post/sso/xxxxxx` | |
|
52 | # SSO (SingleSignOn) endpoint URL of the IdP. This can be used to initialize login | |
|
53 | # E.g. https://app.onelogin.com/trust/saml2/http-post/sso/<onelogin_connector_id> | |
|
54 | ||
|
55 | *option*: `slo_service_url` => `https://customer-domain.onelogin.com/trust/saml2/http-redirect/slo/xxxxxx` | |
|
56 | # SLO (SingleLogout) endpoint URL of the IdP. | |
|
57 | # E.g. https://app.onelogin.com/trust/saml2/http-redirect/slo/<onelogin_connector_id> | |
|
58 | ||
|
59 | *option*: `x509cert` => `<CERTIFICATE_STRING>` | |
|
60 | # Identity provider public x509 certificate. It will be converted to single-line format without headers | |
|
61 | ||
|
62 | *option*: `name_id_format` => `sha-1` | |
|
63 | # The format that specifies how the NameID is sent to the service provider. | |
|
64 | ||
|
65 | *option*: `signature_algo` => `sha-256` | |
|
66 | # Type of Algorithm to use for verification of SAML signature on Identity provider side | |
|
67 | ||
|
68 | *option*: `digest_algo` => `sha-256` | |
|
69 | # Type of Algorithm to use for verification of SAML digest on Identity provider side | |
|
70 | ||
|
71 | *option*: `cert_dir` => `/etc/saml/` | |
|
72 | # Optional directory to store service provider certificate and private keys. | |
|
73 | # Expected certs for the SP should be stored in this folder as: | |
|
74 | # * sp.key Private Key | |
|
75 | # * sp.crt Public cert | |
|
76 | # * sp_new.crt Future Public cert | |
|
77 | # | |
|
78 | # Also you can use other cert to sign the metadata of the SP using the: | |
|
79 | # * metadata.key | |
|
80 | # * metadata.crt | |
|
81 | ||
|
82 | *option*: `user_id_attribute` => `PersonImmutableID` | |
|
83 | # User ID Attribute name. This defines which attribute in SAML response will be used to link accounts via unique id. | |
|
84 | # Ensure this is returned from OneLogin for example via Internal ID | |
|
85 | ||
|
86 | *option*: `username_attribute` => `User.username` | |
|
87 | # Username Attribute name. This defines which attribute in SAML response will map to an username. | |
|
88 | ||
|
89 | *option*: `email_attribute` => `User.email` | |
|
90 | # Email Attribute name. This defines which attribute in SAML response will map to an email address. | |
|
91 | ||
|
92 | ||
|
93 | ||
|
94 | Below is example setup that can be used with OneLogin SAML authentication that can be used with above config.. | |
|
95 | ||
|
96 | .. image:: ../images/saml-onelogin-config-example.png | |
|
97 | :alt: OneLogin SAML setup example | |
|
98 | :scale: 50 % | |
|
99 | ||
|
100 | ||
|
101 | Below is an example attribute mapping set for IDP provider required by the above config. | |
|
102 | ||
|
103 | ||
|
104 | .. image:: ../images/saml-onelogin-attributes-example.png | |
|
105 | :alt: OneLogin SAML setup example | |
|
106 | :scale: 50 % No newline at end of file |
|
1 | NO CONTENT: new file 100644, binary diff hidden |
|
1 | NO CONTENT: new file 100644, binary diff hidden |
|
1 | NO CONTENT: new file 100644, binary diff hidden |
|
1 | NO CONTENT: new file 100644, binary diff hidden |
@@ -0,0 +1,81 b'' | |||
|
1 | |RCE| 4.15.0 |RNS| | |
|
2 | ------------------ | |
|
3 | ||
|
4 | Release Date | |
|
5 | ^^^^^^^^^^^^ | |
|
6 | ||
|
7 | - 2018-12-10 | |
|
8 | ||
|
9 | ||
|
10 | New Features | |
|
11 | ^^^^^^^^^^^^ | |
|
12 | ||
|
13 | - Authentication: Added SAML 2.0 Authentication, with support of OneLogin and DUO Security. | |
|
14 | - Core: add debug mode that switches logging to debug. | |
|
15 | It's no longer required to reconfigure all logging. A `debug=true` set in .ini file | |
|
16 | does it automatically. | |
|
17 | ||
|
18 | ||
|
19 | General | |
|
20 | ^^^^^^^ | |
|
21 | ||
|
22 | - Authentication: rename oauth to external identity as it would now be serving both | |
|
23 | oAuth and SAML. | |
|
24 | - Authentication: allow setting extern type with registration. | |
|
25 | This will allow external identity plugins to define proper externs instead of always | |
|
26 | using "rhodecode" one. | |
|
27 | - Authentication: show if plugin is activated and enabled in the list. | |
|
28 | - Authentication: add better logging for ldap related attributes to help track | |
|
29 | LDAP connection problems more easily. | |
|
30 | - Visual: add change logo header template | |
|
31 | - UI: updated error pages style to be consistent with other pages. | |
|
32 | - Utils: updated request generation so ishell can run some automation scripts. | |
|
33 | - Docs: updated documentation for SVN 1.10 Wandisco repositories. | |
|
34 | - System info: expose base_url set in .ini file. | |
|
35 | - Style: update pygments template styling. | |
|
36 | - Style: updated li style and markdown style. | |
|
37 | - Dependencies: added python-saml library. | |
|
38 | - Dependencies: bumped hgsubversion to 1.9.3 release. | |
|
39 | - Dependencies: bumped gevent to 1.3.7 release. | |
|
40 | - Dependencies: bumped lxml to 4.2.5 release. | |
|
41 | - Dependencies: bumped gevent to 1.3.7 release. | |
|
42 | - Dependencies: bumped alembic to 1.0.5 release. | |
|
43 | - Dependencies: bumped peppercorn to 0.6 release. | |
|
44 | - Dependencies: bumped pyotp to 2.2.7 release. | |
|
45 | - Dependencies: bumped deform to 2.0.7 release | |
|
46 | - Dependencies: bumped py-gfm to 0.1.4 release. | |
|
47 | - Dependencies: bumped colander to 1.5.1 release | |
|
48 | - Dependencies: bumped appenlight-client to 0.6.26 release. | |
|
49 | - Dependencies: bumped bleach to 3.0.2 release. | |
|
50 | - Dependencies: bumped pygments to 2.3.0 | |
|
51 | ||
|
52 | ||
|
53 | Security | |
|
54 | ^^^^^^^^ | |
|
55 | ||
|
56 | - Mercurial: support evolve sub-commands when checking for permissions. | |
|
57 | Those defaulted to write, while only read is required for evolve. | |
|
58 | - auth/security: enforce that external users cannot reset their password. | |
|
59 | External users don't use RhodeCode passwords, so resetting them shouldn't be allowed. | |
|
60 | ||
|
61 | ||
|
62 | Performance | |
|
63 | ^^^^^^^^^^^ | |
|
64 | ||
|
65 | - Markdown: use lazy loaded markdown initialization to speed up app startup. | |
|
66 | - Gevent: changed DNS resolver to ares for better stability on long running processes. | |
|
67 | ||
|
68 | ||
|
69 | Fixes | |
|
70 | ^^^^^ | |
|
71 | ||
|
72 | - Default Reviewers: use target repo owner as default reviewer in case of CE edition. | |
|
73 | - LDAP: ensure the proper cert files and dirs are set. | |
|
74 | It's also now possible to specify custom paths for those. | |
|
75 | - Markdown: fixed auto checkbox generation from markdown code | |
|
76 | ||
|
77 | ||
|
78 | Upgrade notes | |
|
79 | ^^^^^^^^^^^^^ | |
|
80 | ||
|
81 | - LDAP cert dirs No newline at end of file |
@@ -0,0 +1,175 b'' | |||
|
1 | # This code allows override the integrations templates. Put this into the __init__.py | |
|
2 | # file of rcextensions | |
|
3 | ||
|
4 | ||
|
5 | ||
|
6 | from rhodecode.integrations import email | |
|
7 | email.REPO_PUSH_TEMPLATE_HTML = email.Template(''' | |
|
8 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
|
9 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
|
10 | <head> | |
|
11 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
|
12 | <meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
|
13 | <title>${subject}</title> | |
|
14 | <style type="text/css"> | |
|
15 | /* Based on The MailChimp Reset INLINE: Yes. */ | |
|
16 | #outlook a {padding:0;} /* Force Outlook to provide a "view in browser" menu link. */ | |
|
17 | body{width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0;} | |
|
18 | /* Prevent Webkit and Windows Mobile platforms from changing default font sizes.*/ | |
|
19 | .ExternalClass {width:100%;} /* Force Hotmail to display emails at full width */ | |
|
20 | .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} | |
|
21 | /* Forces Hotmail to display normal line spacing. More on that: http://www.emailonacid.com/forum/viewthread/43/ */ | |
|
22 | #backgroundTable {margin:0; padding:0; line-height: 100% !important;} | |
|
23 | /* End reset */ | |
|
24 | ||
|
25 | /* defaults for images*/ | |
|
26 | img {outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;} | |
|
27 | a img {border:none;} | |
|
28 | .image_fix {display:block;} | |
|
29 | ||
|
30 | body {line-height:1.2em;} | |
|
31 | p {margin: 0 0 20px;} | |
|
32 | h1, h2, h3, h4, h5, h6 {color:#323232!important;} | |
|
33 | a {color:#427cc9;text-decoration:none;outline:none;cursor:pointer;} | |
|
34 | a:focus {outline:none;} | |
|
35 | a:hover {color: #305b91;} | |
|
36 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {color:#427cc9!important;text-decoration:none!important;} | |
|
37 | h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {color: #305b91!important;} | |
|
38 | h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {color: #305b91!important;} | |
|
39 | table {font-size:13px;border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt;} | |
|
40 | table td {padding:.65em 1em .65em 0;border-collapse:collapse;vertical-align:top;text-align:left;} | |
|
41 | input {display:inline;border-radius:2px;border-style:solid;border: 1px solid #dbd9da;padding:.5em;} | |
|
42 | input:focus {outline: 1px solid #979797} | |
|
43 | @media only screen and (-webkit-min-device-pixel-ratio: 2) { | |
|
44 | /* Put your iPhone 4g styles in here */ | |
|
45 | } | |
|
46 | ||
|
47 | /* Android targeting */ | |
|
48 | @media only screen and (-webkit-device-pixel-ratio:.75){ | |
|
49 | /* Put CSS for low density (ldpi) Android layouts in here */ | |
|
50 | } | |
|
51 | @media only screen and (-webkit-device-pixel-ratio:1){ | |
|
52 | /* Put CSS for medium density (mdpi) Android layouts in here */ | |
|
53 | } | |
|
54 | @media only screen and (-webkit-device-pixel-ratio:1.5){ | |
|
55 | /* Put CSS for high density (hdpi) Android layouts in here */ | |
|
56 | } | |
|
57 | /* end Android targeting */ | |
|
58 | ||
|
59 | </style> | |
|
60 | ||
|
61 | <!-- Targeting Windows Mobile --> | |
|
62 | <!--[if IEMobile 7]> | |
|
63 | <style type="text/css"> | |
|
64 | ||
|
65 | </style> | |
|
66 | <![endif]--> | |
|
67 | ||
|
68 | <!--[if gte mso 9]> | |
|
69 | <style> | |
|
70 | /* Target Outlook 2007 and 2010 */ | |
|
71 | </style> | |
|
72 | <![endif]--> | |
|
73 | </head> | |
|
74 | <body> | |
|
75 | <!-- Wrapper/Container Table: Use a wrapper table to control the width and the background color consistently of your email. Use this approach instead of setting attributes on the body tag. --> | |
|
76 | <table cellpadding="0" cellspacing="0" border="0" id="backgroundTable" align="left" style="margin:1%;width:97%;padding:0;font-family:sans-serif;font-weight:100;border:1px solid #dbd9da"> | |
|
77 | <tr> | |
|
78 | <td valign="top" style="padding:0;"> | |
|
79 | <table cellpadding="0" cellspacing="0" border="0" align="left" width="100%"> | |
|
80 | <tr><td style="width:100%;padding:7px;background-color:#202020" valign="top"> | |
|
81 | <a style="color:#eeeeee;text-decoration:none;" href="${instance_url}"> | |
|
82 | ${'RhodeCode'} | |
|
83 | </a> | |
|
84 | </td></tr> | |
|
85 | <tr> | |
|
86 | <td style="padding:15px;" valign="top"> | |
|
87 | % if data['push']['commits']: | |
|
88 | % for commit in data['push']['commits']: | |
|
89 | <a href="${commit['url']}">${commit['short_id']}</a> by ${commit['author']} at ${commit['date']} <br/> | |
|
90 | ${commit['message_html']} <br/> | |
|
91 | <br/> | |
|
92 | % endfor | |
|
93 | % else: | |
|
94 | No commit data | |
|
95 | % endif | |
|
96 | </td> | |
|
97 | </tr> | |
|
98 | </table> | |
|
99 | </td> | |
|
100 | </tr> | |
|
101 | </table> | |
|
102 | <!-- End of wrapper table --> | |
|
103 | <p><a style="margin-top:15px;margin-left:1%;font-family:sans-serif;font-weight:100;font-size:11px;color:#666666;text-decoration:none;" href="${instance_url}"> | |
|
104 | ${'This is a notification from RhodeCode. %(instance_url)s' % {'instance_url': instance_url}} | |
|
105 | </a></p> | |
|
106 | </body> | |
|
107 | </html> | |
|
108 | ''') | |
|
109 | ||
|
110 | ||
|
111 | # JIRA (EE ONLY) | |
|
112 | from rc_integrations import jira_tracker | |
|
113 | ||
|
114 | jira_tracker.COMMENT_TEMPLATE_PULL_REQUEST = jira_tracker.Template(''' | |
|
115 | ${action} by ${author} (status: ${status}). \n | |
|
116 | pull-request: ${url} | |
|
117 | ''') | |
|
118 | ||
|
119 | ||
|
120 | jira_tracker.COMMENT_TEMPLATE_COMMIT = jira_tracker.Template(''' | |
|
121 | Commit `${short_id}` by ${author} on `${branch}` branch references this issue. \n | |
|
122 | ${url}\n | |
|
123 | ||
|
124 | ## MODIFICATION add custom COMMIT message to the comment | |
|
125 | ${commit['message']} | |
|
126 | ''') | |
|
127 | ||
|
128 | ||
|
129 | jira_tracker.COMMENT_TEMPLATE_COMMIT_WITH_STATUS = jira_tracker.Template(''' | |
|
130 | Commit `${short_id}` by ${author} on `${branch}` branch changed this issue. \n | |
|
131 | '{url}\n | |
|
132 | ||
|
133 | ## MODIFICATION add custom COMMIT message to the comment | |
|
134 | ${commit['message']} | |
|
135 | ''') | |
|
136 | ||
|
137 | ||
|
138 | # REDMINE (EE ONLY) | |
|
139 | from rc_integrations import redmine_tracker | |
|
140 | ||
|
141 | redmine_tracker.COMMENT_TEMPLATE_COMMIT = redmine_tracker.Template(''' | |
|
142 | Commit `${short_id}` by ${author} on `${branch}` branch references this issue. \n | |
|
143 | commit: ${url}\n | |
|
144 | ||
|
145 | ## MODIFICATION add custom COMMIT message to the comment | |
|
146 | message: | |
|
147 | ``` | |
|
148 | ${commit['message']} | |
|
149 | ``` | |
|
150 | ||
|
151 | ''') | |
|
152 | ||
|
153 | redmine_tracker.COMMENT_TEMPLATE_COMMIT_WITH_STATUS = redmine_tracker.Template(''' | |
|
154 | Commit `${short_id}` by ${author} on `${branch}` branch changed this issue. \n | |
|
155 | commit: ${url}\n | |
|
156 | ||
|
157 | ## MODIFICATION add custom COMMIT message to the comment | |
|
158 | message: | |
|
159 | ``` | |
|
160 | ${commit['message']} | |
|
161 | ``` | |
|
162 | ||
|
163 | ''') | |
|
164 | ||
|
165 | redmine_tracker.COMMENT_TEMPLATE_PULL_REQUEST = redmine_tracker.Template(''' | |
|
166 | ${action} by ${author} (status: ${status}). \n' | |
|
167 | ${url}\n | |
|
168 | ||
|
169 | ## MODIFICATION add custom COMMIT message to the comment | |
|
170 | message: | |
|
171 | ``` | |
|
172 | ${commit['message']} | |
|
173 | ``` | |
|
174 | ||
|
175 | ''') |
@@ -0,0 +1,91 b'' | |||
|
1 | # Example to validate commit message or author using some sort of rules | |
|
2 | ||
|
3 | ||
|
4 | @has_kwargs({ | |
|
5 | 'server_url': 'url of instance that triggered this hook', | |
|
6 | 'config': 'path to .ini config used', | |
|
7 | 'scm': 'type of version control "git", "hg", "svn"', | |
|
8 | 'username': 'username of actor who triggered this event', | |
|
9 | 'ip': 'ip address of actor who triggered this hook', | |
|
10 | 'action': '', | |
|
11 | 'repository': 'repository name', | |
|
12 | 'repo_store_path': 'full path to where repositories are stored', | |
|
13 | 'commit_ids': 'pre transaction metadata for commit ids', | |
|
14 | 'hook_type': '', | |
|
15 | 'user_agent': 'Client user agent, e.g git or mercurial CLI version', | |
|
16 | }) | |
|
17 | @has_kwargs({ | |
|
18 | 'server_url': 'url of instance that triggered this hook', | |
|
19 | 'config': 'path to .ini config used', | |
|
20 | 'scm': 'type of version control "git", "hg", "svn"', | |
|
21 | 'username': 'username of actor who triggered this event', | |
|
22 | 'ip': 'ip address of actor who triggered this hook', | |
|
23 | 'action': '', | |
|
24 | 'repository': 'repository name', | |
|
25 | 'repo_store_path': 'full path to where repositories are stored', | |
|
26 | 'commit_ids': 'pre transaction metadata for commit ids', | |
|
27 | 'hook_type': '', | |
|
28 | 'user_agent': 'Client user agent, e.g git or mercurial CLI version', | |
|
29 | }) | |
|
30 | def _pre_push_hook(*args, **kwargs): | |
|
31 | """ | |
|
32 | Post push hook | |
|
33 | To stop version control from storing the transaction and send a message to user | |
|
34 | use non-zero HookResponse with a message, e.g return HookResponse(1, 'Not allowed') | |
|
35 | ||
|
36 | This message will be shown back to client during PUSH operation | |
|
37 | ||
|
38 | Commit ids might look like that:: | |
|
39 | ||
|
40 | [{u'hg_env|git_env': ..., | |
|
41 | u'multiple_heads': [], | |
|
42 | u'name': u'default', | |
|
43 | u'new_rev': u'd0befe0692e722e01d5677f27a104631cf798b69', | |
|
44 | u'old_rev': u'd0befe0692e722e01d5677f27a104631cf798b69', | |
|
45 | u'ref': u'', | |
|
46 | u'total_commits': 2, | |
|
47 | u'type': u'branch'}] | |
|
48 | """ | |
|
49 | import re | |
|
50 | from .helpers import extra_fields, extract_pre_commits | |
|
51 | from .utils import str2bool | |
|
52 | ||
|
53 | # returns list of dicts with key-val fetched from extra fields | |
|
54 | repo_extra_fields = extra_fields.run(**kwargs) | |
|
55 | ||
|
56 | # optionally use 'extra fields' to control the logic per repo | |
|
57 | should_validate = str2bool(repo_extra_fields.get('validate_author', True)) | |
|
58 | ||
|
59 | # optionally store validation regex into extra fields | |
|
60 | validation_regex = repo_extra_fields.get('validation_regex', '') | |
|
61 | ||
|
62 | def validate_commit_message(commit_message, message_regex=None): | |
|
63 | """ | |
|
64 | This function validates commit_message against some sort of rules. | |
|
65 | It should return a valid boolean, and a reason for failure | |
|
66 | """ | |
|
67 | ||
|
68 | if "secret_string" in commit_message: | |
|
69 | msg = "!!Push forbidden: secret string found in commit messages" | |
|
70 | return False, msg | |
|
71 | ||
|
72 | if validation_regex: | |
|
73 | regexp = re.compile(validation_regex) | |
|
74 | if not regexp.match(message): | |
|
75 | msg = "!!Push forbidden: commit message does not match regexp" | |
|
76 | return False, msg | |
|
77 | ||
|
78 | return True, '' | |
|
79 | ||
|
80 | if should_validate: | |
|
81 | # returns list of dicts with key-val fetched from extra fields | |
|
82 | commit_list = extract_pre_commits.run(**kwargs) | |
|
83 | ||
|
84 | for commit_data in commit_list: | |
|
85 | message = commit_data['message'] | |
|
86 | ||
|
87 | message_valid, reason = validate_commit_message(message, validation_regex) | |
|
88 | if not message_valid: | |
|
89 | return HookResponse(1, reason) | |
|
90 | ||
|
91 | return HookResponse(0, '') |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | [bumpversion] |
|
2 |
current_version = 4.1 |
|
|
2 | current_version = 4.15.0 | |
|
3 | 3 | message = release: Bump version {current_version} to {new_version} |
|
4 | 4 | |
|
5 | 5 | [bumpversion:file:rhodecode/VERSION] |
@@ -5,25 +5,20 b' done = false' | |||
|
5 | 5 | done = true |
|
6 | 6 | |
|
7 | 7 | [task:rc_tools_pinned] |
|
8 | done = true | |
|
9 | 8 | |
|
10 | 9 | [task:fixes_on_stable] |
|
11 | done = true | |
|
12 | 10 | |
|
13 | 11 | [task:pip2nix_generated] |
|
14 | done = true | |
|
15 | 12 | |
|
16 | 13 | [task:changelog_updated] |
|
17 | done = true | |
|
18 | 14 | |
|
19 | 15 | [task:generate_api_docs] |
|
20 | done = true | |
|
16 | ||
|
17 | [task:updated_translation] | |
|
21 | 18 | |
|
22 | 19 | [release] |
|
23 |
state = |
|
|
24 |
version = 4.1 |
|
|
25 | ||
|
26 | [task:updated_translation] | |
|
20 | state = in_progress | |
|
21 | version = 4.15.0 | |
|
27 | 22 | |
|
28 | 23 | [task:generate_js_routes] |
|
29 | 24 |
@@ -7,18 +7,20 b' About' | |||
|
7 | 7 | |
|
8 | 8 | ``RhodeCode`` is a fast and powerful management tool for Mercurial_ and GIT_ |
|
9 | 9 | and Subversion_ with a built in push/pull server, full text search, |
|
10 | pull requests and powerful code-review system. It works on http/https and | |
|
10 | pull requests and powerful code-review system. It works on http/https, SSH and | |
|
11 | 11 | has a few unique features like: |
|
12 | 12 | |
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 | - integration with all 3rd party issue trackers | |
|
13 | - plugable architecture from Pyramid web-framework. | |
|
14 | - advanced permission system with IP restrictions, inheritation, and user-groups. | |
|
15 | - rich set of authentication plugins including LDAP, ActiveDirectory, SAML 2.0, | |
|
16 | Atlassian Crowd, Http-Headers, Pam, Token-Auth, OAuth. | |
|
17 | - live code-review chat, and reviewer rules. | |
|
18 | - full web based file editing. | |
|
19 | - unified multi vcs support. | |
|
20 | - snippets (gist) system. | |
|
21 | - integration framework for Slack, CI systems, Webhooks. | |
|
22 | - integration with all 3rd party issue trackers. | |
|
23 | ||
|
22 | 24 | |
|
23 | 25 | RhodeCode also provides rich API, and multiple event hooks so it's easy |
|
24 | 26 | integrable with existing external systems. |
@@ -1,10 +1,11 b'' | |||
|
1 | 1 | |
|
2 | 2 | |
|
3 | 3 | ################################################################################ |
|
4 |
## |
|
|
4 | ## RHODECODE COMMUNITY EDITION CONFIGURATION ## | |
|
5 | 5 | ################################################################################ |
|
6 | 6 | |
|
7 | 7 | [DEFAULT] |
|
8 | ## Debug flag sets all loggers to debug, and enables request tracking | |
|
8 | 9 | debug = true |
|
9 | 10 | |
|
10 | 11 | ################################################################################ |
@@ -414,6 +415,7 b' search.location = %(here)s/data/index' | |||
|
414 | 415 | ######################################## |
|
415 | 416 | ## channelstream enables persistent connections and live notification |
|
416 | 417 | ## in the system. It's also used by the chat system |
|
418 | ||
|
417 | 419 | channelstream.enabled = false |
|
418 | 420 | |
|
419 | 421 | ## server address for channelstream server on the backend |
@@ -490,14 +492,6 b' appenlight.request_keys_blacklist =' | |||
|
490 | 492 | ## (by default the client ignores own entries: appenlight_client.client) |
|
491 | 493 | appenlight.log_namespace_blacklist = |
|
492 | 494 | |
|
493 | ||
|
494 | ################################################################################ | |
|
495 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## | |
|
496 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## | |
|
497 | ## execute malicious code after an exception is raised. ## | |
|
498 | ################################################################################ | |
|
499 | #set debug = false | |
|
500 | ||
|
501 | 495 | # enable debug style page |
|
502 | 496 | debug_style = true |
|
503 | 497 |
@@ -1,11 +1,12 b'' | |||
|
1 | 1 | |
|
2 | 2 | |
|
3 | 3 | ################################################################################ |
|
4 |
## |
|
|
4 | ## RHODECODE COMMUNITY EDITION CONFIGURATION ## | |
|
5 | 5 | ################################################################################ |
|
6 | 6 | |
|
7 | 7 | [DEFAULT] |
|
8 | debug = true | |
|
8 | ## Debug flag sets all loggers to debug, and enables request tracking | |
|
9 | debug = false | |
|
9 | 10 | |
|
10 | 11 | ################################################################################ |
|
11 | 12 | ## EMAIL CONFIGURATION ## |
@@ -389,6 +390,7 b' search.location = %(here)s/data/index' | |||
|
389 | 390 | ######################################## |
|
390 | 391 | ## channelstream enables persistent connections and live notification |
|
391 | 392 | ## in the system. It's also used by the chat system |
|
393 | ||
|
392 | 394 | channelstream.enabled = false |
|
393 | 395 | |
|
394 | 396 | ## server address for channelstream server on the backend |
@@ -466,14 +468,6 b' appenlight.request_keys_blacklist =' | |||
|
466 | 468 | appenlight.log_namespace_blacklist = |
|
467 | 469 | |
|
468 | 470 | |
|
469 | ################################################################################ | |
|
470 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## | |
|
471 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## | |
|
472 | ## execute malicious code after an exception is raised. ## | |
|
473 | ################################################################################ | |
|
474 | set debug = false | |
|
475 | ||
|
476 | ||
|
477 | 471 | ########################################### |
|
478 | 472 | ### MAIN RHODECODE DATABASE CONFIG ### |
|
479 | 473 | ########################################### |
@@ -524,6 +518,7 b' vcs.scm_app_implementation = http' | |||
|
524 | 518 | ## Push/Pull operations hooks protocol, available options are: |
|
525 | 519 | ## `http` - use http-rpc backend (default) |
|
526 | 520 | vcs.hooks.protocol = http |
|
521 | ||
|
527 | 522 | ## Host on which this instance is listening for hooks. If vcsserver is in other location |
|
528 | 523 | ## this should be adjusted. |
|
529 | 524 | vcs.hooks.host = 127.0.0.1 |
@@ -3,19 +3,19 b'' | |||
|
3 | 3 | Anonymous Users |
|
4 | 4 | --------------- |
|
5 | 5 | |
|
6 |
By default, |RC |
|
|
6 | By default, |RCE| provides |repo| access for registered users only. It can be | |
|
7 | 7 | configured to be **world-open** in terms of read and write permissions. This |
|
8 |
configuration is called "Anonymous Access" and allows |RC |
|
|
8 | configuration is called "Anonymous Access" and allows |RCE| to be used as a | |
|
9 | 9 | public hub where unregistered users have access to your |repos|. |
|
10 | 10 | |
|
11 | 11 | Anonymous access is useful for open source projects, universities, |
|
12 | 12 | or if running inside a restricted internal corporate network to serve |
|
13 | 13 | documents to all employees. Anonymous users get the default user permission |
|
14 |
settings that are applied across the whole |RC |
|
|
14 | settings that are applied across the whole |RCE| system. | |
|
15 | 15 | |
|
16 | 16 | To enable anonymous access to your |repos|, use the following steps: |
|
17 | 17 | |
|
18 |
1. From the |RC |
|
|
18 | 1. From the |RCE| interface, select :menuselection:`Admin --> Permissions`. | |
|
19 | 19 | 2. On the Application tab, check the :guilabel:`Allow anonymous access` box. |
|
20 | 20 | 3. Select :guilabel:`Save`. |
|
21 | 21 | 4. To set the anonymous user access permissions, which are based on the |
@@ -166,7 +166,7 b' 2. Add your custom hook details, you can' | |||
|
166 | 166 | ``pretxnchangegroup.example`` with value ``python:/path/to/custom_hook.py:my_func_name`` |
|
167 | 167 | 3. Select :guilabel:`Save` |
|
168 | 168 | |
|
169 |
Also, see the |
|
|
169 | Also, see the RhodeCode Extensions section of the :ref:`rc-tools` guide. RhodeCode | |
|
170 | 170 | Extensions can be used to add additional hooks to your instance and comes |
|
171 | 171 | with a number of pre-built plugins if you chose to install them. |
|
172 | 172 |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | Apache WSGI Configuration |
|
4 | 4 | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
5 | 5 | |
|
6 |
|RC |
|
|
6 | |RCE| can also be set up with Apache under ``mod_wsgi``. To configure this | |
|
7 | 7 | use the following steps. |
|
8 | 8 | |
|
9 | 9 | 1. Install ``mod_wsgi`` using the following command: |
@@ -50,6 +50,6 b' The following is an example ``wsgi`` dis' | |||
|
50 | 50 | .. note:: |
|
51 | 51 | |
|
52 | 52 | When using `mod_wsgi` the same version of |hg| must be running in your |
|
53 |
system's |PY| environment and on |RC |
|
|
53 | system's |PY| environment and on |RCE|. To check the |RCE| version, | |
|
54 | 54 | on the interface go to |
|
55 | 55 | :menuselection:`Admin --> Settings --> System Info` |
@@ -67,7 +67,7 b' sections.' | |||
|
67 | 67 | Default location: :file:`/home/{user}/.rccontrol/cache/MANIFEST` |
|
68 | 68 | |
|
69 | 69 | |RCC| uses this file to source the latest available builds from the |
|
70 |
secure |
|
|
70 | secure RhodeCode download channels. The only reason to mess with this file | |
|
71 | 71 | is if you need to do an offline installation, |
|
72 | 72 | see the :ref:`Offline Installation<control:offline-installer-ref>` |
|
73 | 73 | instructions, otherwise |RCC| will completely manage this file. |
@@ -3,6 +3,16 b'' | |||
|
3 | 3 | Enabling Debug Mode |
|
4 | 4 | ------------------- |
|
5 | 5 | |
|
6 | Debug Mode will enable debug logging, and request tracking middleware. Debug Mode | |
|
7 | enabled DEBUG log-level which allows tracking various information about authentication | |
|
8 | failures, LDAP connection, email etc. | |
|
9 | ||
|
10 | The request tracking will add a special | |
|
11 | unique ID: `| req_id:00000000-0000-0000-0000-000000000000` at the end of each log line. | |
|
12 | The req_id is the same for each individual requests, it means that if you want to | |
|
13 | track particular user logs only, and exclude other concurrent ones | |
|
14 | simply grep by `req_id` uuid which you'll have to find for the individual request. | |
|
15 | ||
|
6 | 16 | To enable debug mode on a |RCE| instance you need to set the debug property |
|
7 | 17 | in the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. To |
|
8 | 18 | do this, use the following steps |
@@ -11,14 +21,10 b' 1. Open the file and set the ``debug`` l' | |||
|
11 | 21 | 2. Restart you instance using the ``rccontrol restart`` command, |
|
12 | 22 | see the following example: |
|
13 | 23 | |
|
14 | You can also set the log level, the follow are the valid options; | |
|
15 | ``debug``, ``info``, ``warning``, or ``fatal``. | |
|
16 | ||
|
17 | 24 | .. code-block:: ini |
|
18 | 25 | |
|
19 | 26 | [DEFAULT] |
|
20 | 27 | debug = true |
|
21 | pdebug = false | |
|
22 | 28 | |
|
23 | 29 | .. code-block:: bash |
|
24 | 30 | |
@@ -27,6 +33,7 b' You can also set the log level, the foll' | |||
|
27 | 33 | Instance "enterprise-1" successfully stopped. |
|
28 | 34 | Instance "enterprise-1" successfully started. |
|
29 | 35 | |
|
36 | ||
|
30 | 37 | Debug and Logging Configuration |
|
31 | 38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
32 | 39 | |
@@ -47,7 +54,7 b' the ``debug`` level.' | |||
|
47 | 54 | ### LOGGING CONFIGURATION #### |
|
48 | 55 | ################################ |
|
49 | 56 | [loggers] |
|
50 | keys = root, sqlalchemy, rhodecode, ssh_wrapper | |
|
57 | keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper | |
|
51 | 58 | |
|
52 | 59 | [handlers] |
|
53 | 60 | keys = console, console_sql, file, file_rotating |
@@ -62,11 +69,16 b' the ``debug`` level.' | |||
|
62 | 69 | level = NOTSET |
|
63 | 70 | handlers = console |
|
64 | 71 | |
|
65 |
[logger_ |
|
|
72 | [logger_sqlalchemy] | |
|
73 | level = INFO | |
|
74 | handlers = console_sql | |
|
75 | qualname = sqlalchemy.engine | |
|
76 | propagate = 0 | |
|
77 | ||
|
78 | [logger_beaker] | |
|
66 | 79 | level = DEBUG |
|
67 | 80 | handlers = |
|
68 |
qualname = |
|
|
69 | ## "level = DEBUG" logs the route matched and routing variables. | |
|
81 | qualname = beaker.container | |
|
70 | 82 | propagate = 1 |
|
71 | 83 | |
|
72 | 84 | [logger_rhodecode] |
@@ -75,11 +87,16 b' the ``debug`` level.' | |||
|
75 | 87 | qualname = rhodecode |
|
76 | 88 | propagate = 1 |
|
77 | 89 | |
|
78 |
[logger_s |
|
|
79 |
level = |
|
|
80 |
handlers = |
|
|
81 |
qualname = s |
|
|
82 |
propagate = |
|
|
90 | [logger_ssh_wrapper] | |
|
91 | level = DEBUG | |
|
92 | handlers = | |
|
93 | qualname = ssh_wrapper | |
|
94 | propagate = 1 | |
|
95 | ||
|
96 | [logger_celery] | |
|
97 | level = DEBUG | |
|
98 | handlers = | |
|
99 | qualname = celery | |
|
83 | 100 | |
|
84 | 101 | ############## |
|
85 | 102 | ## HANDLERS ## |
@@ -87,19 +104,19 b' the ``debug`` level.' | |||
|
87 | 104 | |
|
88 | 105 | [handler_console] |
|
89 | 106 | class = StreamHandler |
|
90 | args = (sys.stderr,) | |
|
91 |
level = |
|
|
107 | args = (sys.stderr, ) | |
|
108 | level = DEBUG | |
|
92 | 109 | formatter = generic |
|
93 | 110 | |
|
94 | 111 | [handler_console_sql] |
|
95 | 112 | class = StreamHandler |
|
96 | args = (sys.stderr,) | |
|
97 |
level = |
|
|
113 | args = (sys.stderr, ) | |
|
114 | level = INFO | |
|
98 | 115 | formatter = generic |
|
99 | 116 | |
|
100 | 117 | [handler_file] |
|
101 | 118 | class = FileHandler |
|
102 | args = ('rhodecode.log', 'a',) | |
|
119 | args = ('rhodecode_debug.log', 'a',) | |
|
103 | 120 | level = INFO |
|
104 | 121 | formatter = generic |
|
105 | 122 | |
@@ -107,6 +124,25 b' the ``debug`` level.' | |||
|
107 | 124 | class = logging.handlers.TimedRotatingFileHandler |
|
108 | 125 | # 'D', 5 - rotate every 5days |
|
109 | 126 | # you can set 'h', 'midnight' |
|
110 | args = ('rhodecode.log', 'D', 5, 10,) | |
|
127 | args = ('rhodecode_debug_rotated.log', 'D', 5, 10,) | |
|
111 | 128 | level = INFO |
|
112 | 129 | formatter = generic |
|
130 | ||
|
131 | ################ | |
|
132 | ## FORMATTERS ## | |
|
133 | ################ | |
|
134 | ||
|
135 | [formatter_generic] | |
|
136 | class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter | |
|
137 | format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | |
|
138 | datefmt = %Y-%m-%d %H:%M:%S | |
|
139 | ||
|
140 | [formatter_color_formatter] | |
|
141 | class = rhodecode.lib.logging_formatter.ColorFormatter | |
|
142 | format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | |
|
143 | datefmt = %Y-%m-%d %H:%M:%S | |
|
144 | ||
|
145 | [formatter_color_formatter_sql] | |
|
146 | class = rhodecode.lib.logging_formatter.ColorFormatterSql | |
|
147 | format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | |
|
148 | datefmt = %Y-%m-%d %H:%M:%S No newline at end of file |
@@ -33,7 +33,7 b' Glossary' | |||
|
33 | 33 | Adding more machines or workers into your pool of resources. |
|
34 | 34 | |
|
35 | 35 | Instance |
|
36 |
A single installed version of one of the |
|
|
36 | A single installed version of one of the RhodeCode products. It could | |
|
37 | 37 | refer to |RCE| or the VCS server depending on the context. |
|
38 | 38 | |
|
39 | 39 | Plugin |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | Full-text Search |
|
4 | 4 | ---------------- |
|
5 | 5 | |
|
6 |
By default |
|
|
6 | By default RhodeCode is configured to use `Whoosh`_ to index |repos| and | |
|
7 | 7 | provide full-text search. |
|
8 | 8 | |
|
9 | 9 | |RCE| also provides support for `Elasticsearch`_ as a backend for scalable |
@@ -46,7 +46,7 b' Configure the ``.rhoderc`` File' | |||
|
46 | 46 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
47 | 47 | |
|
48 | 48 | |RCT| uses the :file:`/home/{user}/.rhoderc` file for connection details |
|
49 |
to |RC |
|
|
49 | to |RCE| instances. If this file is not automatically created, | |
|
50 | 50 | you can configure it using the following example. You need to configure the |
|
51 | 51 | details for each instance you want to index. |
|
52 | 52 | |
@@ -62,7 +62,7 b' details for each instance you want to in' | |||
|
62 | 62 | - VERSION: 1.5.0 |
|
63 | 63 | - URL: http://127.0.0.1:10000 |
|
64 | 64 | |
|
65 |
To get your API Token, on the |RC |
|
|
65 | To get your API Token, on the |RCE| interface go to | |
|
66 | 66 | :menuselection:`username --> My Account --> Auth tokens` |
|
67 | 67 | |
|
68 | 68 | .. code-block:: ini |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | Public Access |
|
4 | 4 | ------------- |
|
5 | 5 | |
|
6 |
By default |RC |
|
|
6 | By default |RCE| allows users to read all **public** |repos|. User | |
|
7 | 7 | permissions and |repo| access can be configured explicitly, |
|
8 | 8 | and those permissions will override any default settings. The default |
|
9 | 9 | settings can be found under the following section: |
@@ -7,7 +7,7 b' Extra fields attached to a |repo| allow ' | |||
|
7 | 7 | each repository. This allows storing custom data per-repository. |
|
8 | 8 | |
|
9 | 9 | It can be used in :ref:`integrations-webhook` or in |RCX|. |
|
10 |
To |
|
|
10 | To read more about |RCX|, see the :ref:`integrations-rcextensions` section. | |
|
11 | 11 | |
|
12 | 12 | |
|
13 | 13 | Enabling Extra Fields |
@@ -46,11 +46,6 b' This is the complete list of |repos| hoo' | |||
|
46 | 46 | Using Repository Hooks |
|
47 | 47 | ---------------------- |
|
48 | 48 | |
|
49 |
To use these hooks you need to |
|
|
50 |
:ref:`in |
|
|
49 | To use these hooks you need to setup |RCX|. For more information, see the | |
|
50 | :ref:`integrations-rcextensions` section. | |
|
51 | 51 | |
|
52 | Creating Extensions | |
|
53 | ------------------- | |
|
54 | ||
|
55 | To create your own extensions using these hooks, see the :ref:`dev-plug` | |
|
56 | section. |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | Setting Default Permissions |
|
4 | 4 | --------------------------- |
|
5 | 5 | |
|
6 |
Default permissions allow you to configure |RC |
|
|
6 | Default permissions allow you to configure |RCE| so that when a new |repo|, user group, | |
|
7 | 7 | or user is created their permissions are already defined. To set default permissions you need administrator |
|
8 | 8 | privileges. See the following sections for setting up your permissions system: |
|
9 | 9 | |
@@ -19,7 +19,7 b' Setting User defaults' | |||
|
19 | 19 | |
|
20 | 20 | To set default user permissions, use the following steps. |
|
21 | 21 | |
|
22 |
1. From the |RC |
|
|
22 | 1. From the |RCE| interface, select :menuselection:`Admin --> Permissions` | |
|
23 | 23 | 2. Select the :guilabel:`Global` tab from the left-hand menu. The permissions |
|
24 | 24 | set on this screen apply to users and user-groups across the whole instance. |
|
25 | 25 | 3. Save your changes |
@@ -31,7 +31,7 b' Setting User Group defaults' | |||
|
31 | 31 | |
|
32 | 32 | To set default user group permissions, use the following steps. |
|
33 | 33 | |
|
34 |
1. From the |RC |
|
|
34 | 1. From the |RCE| interface, select :menuselection:`Admin --> User groups` | |
|
35 | 35 | 2. Select :guilabel:`Permissions`, and configure the default user |
|
36 | 36 | permissions. All users will get these permissions unless |
|
37 | 37 | individually set. |
@@ -48,7 +48,7 b' Setting Repository defaults' | |||
|
48 | 48 | |
|
49 | 49 | To set default |repo| permissions, use the following steps. |
|
50 | 50 | |
|
51 |
1. From the |RC |
|
|
51 | 1. From the |RCE| interface, select :menuselection:`Admin --> Permissions` | |
|
52 | 52 | 2. Select the :guilabel:`Object` tab from the left-hand menu and set the |
|
53 | 53 | |perm| permissions |
|
54 | 54 | 3. Save your changes |
@@ -60,7 +60,7 b' Setting Repository Group defaults' | |||
|
60 | 60 | |
|
61 | 61 | To set default Repository Group permissions, use the following steps. |
|
62 | 62 | |
|
63 |
1. From the |RC |
|
|
63 | 1. From the |RCE| interface, select :menuselection:`Admin --> Repository Groups` | |
|
64 | 64 | 2. Select :guilabel:`Edit` beside the |repo| group you wish to configure |
|
65 | 65 | 3. On the left-hand pane select :guilabel:`Permissions` |
|
66 | 66 | 4. Set the default permissions for all |repos| created in this group |
@@ -3,12 +3,12 b'' | |||
|
3 | 3 | Repository Administration |
|
4 | 4 | ========================= |
|
5 | 5 | |
|
6 |
Repository permissions in |RC |
|
|
6 | Repository permissions in |RCE| can be managed in a number of different ways. | |
|
7 | 7 | This overview should give you an insight into how you could adopt particular |
|
8 | 8 | settings for your needs: |
|
9 | 9 | |
|
10 | 10 | * Global |repo| permissions: This allows you to set the default permissions |
|
11 |
for each new |repo| created within |RC |
|
|
11 | for each new |repo| created within |RCE|, see :ref:`repo-default-ref`. All | |
|
12 | 12 | |repos| created will inherit these permissions unless explicitly configured. |
|
13 | 13 | * Individual |repo| permissions: To set individual |repo| permissions, |
|
14 | 14 | see :ref:`set-repo-perms`. |
@@ -18,13 +18,14 b' Prerequisites' | |||
|
18 | 18 | .. tip:: |
|
19 | 19 | |
|
20 | 20 | We recommend using Wandisco repositories which provide latest SVN versions |
|
21 | for most platforms. | |
|
21 | for most platforms. If you skip this version you'll have to ensure the Client version | |
|
22 | is compatible with installed SVN version which might differ depending on the operating system. | |
|
22 | 23 | Here is an example how to add the Wandisco repositories for Ubuntu. |
|
23 | 24 | |
|
24 | 25 | .. code-block:: bash |
|
25 | 26 | |
|
26 |
$ sudo sh -c 'echo "deb http://opensource.wandisco.com/ubuntu `lsb_release -cs` svn1 |
|
|
27 | $ sudo wget -q http://opensource.wandisco.com/wandisco-debian.gpg -O- | sudo apt-key add - | |
|
27 | $ sudo sh -c 'echo "deb http://opensource.wandisco.com/ubuntu `lsb_release -cs` svn110" >> /etc/apt/sources.list.d/subversion110.list' | |
|
28 | $ sudo wget -q http://opensource.wandisco.com/wandisco-debian-new.gpg -O- | sudo apt-key add - | |
|
28 | 29 | $ sudo apt-get update |
|
29 | 30 | |
|
30 | 31 | Here is an example how to add the Wandisco repositories for Centos/Redhat. Using |
@@ -46,7 +47,7 b' Example installation of required compone' | |||
|
46 | 47 | .. code-block:: bash |
|
47 | 48 | |
|
48 | 49 | $ sudo apt-get install apache2 |
|
49 |
$ sudo apt-get install libapache2- |
|
|
50 | $ sudo apt-get install libapache2-svn | |
|
50 | 51 | |
|
51 | 52 | Once installed you need to enable ``dav_svn`` on Ubuntu: |
|
52 | 53 | |
@@ -76,6 +77,12 b' Once installed you need to enable ``dav_' | |||
|
76 | 77 | LoadModule headers_module modules/mod_headers.so |
|
77 | 78 | LoadModule authn_anon_module modules/mod_authn_anon.so |
|
78 | 79 | |
|
80 | .. tip:: | |
|
81 | ||
|
82 | To check the installed mod_dav_svn module version, you can use such command. | |
|
83 | ||
|
84 | `strings /usr/lib/apache2/modules/mod_dav_svn.so | grep 'Powered by'` | |
|
85 | ||
|
79 | 86 | |
|
80 | 87 | Configuring Apache Setup |
|
81 | 88 | ======================== |
@@ -59,7 +59,7 b' Supported Browsers' | |||
|
59 | 59 | System Requirements |
|
60 | 60 | ------------------- |
|
61 | 61 | |
|
62 |
|RC |
|
|
62 | |RCE| performs best on machines with ultra-fast hard disks. Generally disk | |
|
63 | 63 | performance is more important than CPU performance. In a corporate production |
|
64 | 64 | environment handling 1000s of users and |repos| you should deploy on a 12+ |
|
65 | 65 | core 64GB RAM server. In short, the more RAM the better. |
@@ -68,7 +68,7 b' core 64GB RAM server. In short, the more' | |||
|
68 | 68 | For example: |
|
69 | 69 | |
|
70 | 70 | - for team of 1 - 5 active users you can run on 1GB RAM machine with 1CPU |
|
71 |
- above 250 active users, |RC |
|
|
71 | - above 250 active users, |RCE| needs at least 8GB of memory. | |
|
72 | 72 | Number of CPUs is less important, but recommended to have at least 2-3 CPUs |
|
73 | 73 | |
|
74 | 74 | |
@@ -114,7 +114,7 b' Connection Methods' | |||
|
114 | 114 | |
|
115 | 115 | * HTTPS |
|
116 | 116 | * SSH |
|
117 |
* |RC |
|
|
117 | * |RCE| API | |
|
118 | 118 | |
|
119 | 119 | Internationalization Support |
|
120 | 120 | ---------------------------- |
@@ -146,7 +146,7 b' persistent sessions across nodes. Please' | |||
|
146 | 146 | |
|
147 | 147 | .. code-block:: ini |
|
148 | 148 | |
|
149 |
# use a |
|
|
149 | # use a unique generated long string | |
|
150 | 150 | beaker.session.secret = 70e116cae2274656ba7265fd860aebbd |
|
151 | 151 | |
|
152 | 152 | 3) Configure stored cached/archive cache to our shared NFS `rc-node-1` |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | User Administration |
|
4 | 4 | =================== |
|
5 | 5 | |
|
6 |
|RC |
|
|
6 | |RCE| enables you to define permissions for the following entities within the | |
|
7 | 7 | system; **users**, **user groups**, **repositories**, **repository groups**. |
|
8 | 8 | |
|
9 | 9 | Within each one of these entities you can set default settings, |
@@ -3,13 +3,13 b'' | |||
|
3 | 3 | VCS Server Management |
|
4 | 4 | --------------------- |
|
5 | 5 | |
|
6 |
The VCS Server handles |RC |
|
|
7 |
a VCS Server to run with a |RC |
|
|
8 |
the connection between |RC |
|
|
6 | The VCS Server handles |RCE| backend functionality. You need to configure | |
|
7 | a VCS Server to run with a |RCE| instance. If you do not, you will be missing | |
|
8 | the connection between |RCE| and its |repos|. This will cause error messages | |
|
9 | 9 | on the web interface. You can run your setup in the following configurations, |
|
10 | 10 | currently the best performance is one of following: |
|
11 | 11 | |
|
12 |
* One VCS Server per |RC |
|
|
12 | * One VCS Server per |RCE| instance. | |
|
13 | 13 | * One VCS Server handling multiple instances. |
|
14 | 14 | |
|
15 | 15 | .. important:: |
@@ -49,7 +49,7 b' To configure a |RCE| instance to use a V' | |||
|
49 | 49 | |RCE| VCS Server Options |
|
50 | 50 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
|
51 | 51 | |
|
52 |
The following list shows the available options on the |RC |
|
|
52 | The following list shows the available options on the |RCE| side of the | |
|
53 | 53 | connection to the VCS Server. The settings are configured per |
|
54 | 54 | instance in the |
|
55 | 55 | :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. |
@@ -75,7 +75,7 b' instance in the' | |||
|
75 | 75 | |
|
76 | 76 | \vcs.server <host:port> |
|
77 | 77 | Set the host, either hostname or IP Address, and port of the VCS server |
|
78 |
you wish to run with your |RC |
|
|
78 | you wish to run with your |RCE| instance. | |
|
79 | 79 | |
|
80 | 80 | .. code-block:: ini |
|
81 | 81 |
@@ -22,12 +22,12 b' API access can also be turned on for eac' | |||
|
22 | 22 | decorated with a `@LoginRequired` decorator. To enable API access, change |
|
23 | 23 | the standard login decorator to `@LoginRequired(api_access=True)`. |
|
24 | 24 | |
|
25 |
From |RC |
|
|
25 | From |RCE| version 1.7.0 you can configure a white list | |
|
26 | 26 | of views that have API access enabled by default. To enable these, |
|
27 |
edit the |RC |
|
|
27 | edit the |RCE| configuration ``.ini`` file. The default location is: | |
|
28 | 28 | |
|
29 |
* |RC |
|
|
30 |
* |RC |
|
|
29 | * |RCE| Pre-2.2.7 :file:`root/rhodecode/data/production.ini` | |
|
30 | * |RCE| 3.0 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` | |
|
31 | 31 | |
|
32 | 32 | To configure the white list, edit this section of the file. In this |
|
33 | 33 | configuration example, API access is granted to the patch/diff raw file and |
@@ -5,8 +5,8 b' Crowd' | |||
|
5 | 5 | |
|
6 | 6 | To enable Crowd authentication, use the following steps: |
|
7 | 7 | |
|
8 |
1. From the |RC |
|
|
9 |
2. |
|
|
8 | 1. From the |RCE| interface, go to :menuselection:`Admin --> Authentication` | |
|
9 | 2. Activate the ``rhodecode.lib.auth_modules.auth_crowd`` library and select | |
|
10 | 10 | :guilabel:`Save` |
|
11 | 11 | 3. On the Crowd plugin settings section, do the following: |
|
12 | 12 |
@@ -3,25 +3,24 b'' | |||
|
3 | 3 | LDAP/AD With User Groups Sync |
|
4 | 4 | ----------------------------- |
|
5 | 5 | |
|
6 | |RCM| supports LDAP (Lightweight Directory Access Protocol) or | |
|
6 | **This plugin is available only in EE Edition.** | |
|
7 | ||
|
8 | |RCE| supports LDAP (Lightweight Directory Access Protocol) or | |
|
7 | 9 | AD (active Directory) authentication. |
|
8 | All LDAP versions are supported, with the following |RCM| plugins managing each: | |
|
9 | ||
|
10 | * For LDAP/AD with user group sync use ``LDAP + User Groups (egg:rhodecode-enterprise-ee#ldap_group)`` | |
|
10 | All LDAP versions are currently supported. | |
|
11 | 11 | |
|
12 | 12 | RhodeCode reads all data defined from plugin and creates corresponding |
|
13 | 13 | accounts on local database after receiving data from LDAP. This is done on |
|
14 | 14 | every user log-in including operations like pushing/pulling/checkout. |
|
15 | 15 | In addition group membership is read from LDAP and following operations are done: |
|
16 | 16 | |
|
17 |
- automatic addition of user to |RC |
|
|
18 |
- automatic removal of user from any other |RC |
|
|
17 | - automatic addition of user to |RCE| user group | |
|
18 | - automatic removal of user from any other |RCE| user groups not specified in LDAP. | |
|
19 | 19 | The removal is done *only* on groups that are marked to be synced from ldap. |
|
20 | 20 | This setting can be changed in advanced settings on user groups |
|
21 |
- automatic creation of user groups if they aren't yet existing in |RC |
|
|
21 | - automatic creation of user groups if they aren't yet existing in |RCE| | |
|
22 | 22 | - marking user as super-admins if he is a member of any admin group defined in plugin settings |
|
23 | 23 | |
|
24 | This plugin is available only in EE Edition. | |
|
25 | 24 | |
|
26 | 25 | .. important:: |
|
27 | 26 | |
@@ -39,11 +38,12 b' LDAP Configuration Steps' | |||
|
39 | 38 | |
|
40 | 39 | To configure |LDAP|, use the following steps: |
|
41 | 40 | |
|
42 |
1. From the |RC |
|
|
41 | 1. From the |RCE| interface, select | |
|
43 | 42 | :menuselection:`Admin --> Authentication` |
|
44 |
2. |
|
|
45 | 3. Select the :guilabel:`Enabled` check box in the plugin configuration section | |
|
46 | 4. Add the required LDAP information and :guilabel:`Save`, for more details, | |
|
43 | 2. Activate the `LDAP + User Groups` plugin and select :guilabel:`Save` | |
|
44 | 3. Go to newly available menu option called `LDAP + User Groups` on the left side. | |
|
45 | 4. Check the `enabled` check box in the plugin configuration section, | |
|
46 | and fill in the required LDAP information and :guilabel:`Save`, for more details, | |
|
47 | 47 | see :ref:`config-ldap-groups-examples` |
|
48 | 48 | |
|
49 | 49 | For a more detailed description of LDAP objects, see :ref:`ldap-gloss-ref`: |
@@ -52,59 +52,107 b' For a more detailed description of LDAP ' | |||
|
52 | 52 | |
|
53 | 53 | Example LDAP configuration |
|
54 | 54 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
55 | .. code-block:: bash | |
|
55 | ||
|
56 | Below is example setup that can be used with Active Directory and LDAP server with groups sync:: | |
|
57 | ||
|
58 | *option*: `enabled` => `True` | |
|
59 | # Enable or disable this authentication plugin. | |
|
60 | ||
|
61 | *option*: `cache_ttl` => `360` | |
|
62 | # Amount of seconds to cache the authentication and permissions check response call for this plugin. | |
|
63 | # Useful for expensive calls like LDAP to improve the performance of the system (0 means disabled). | |
|
64 | ||
|
65 | *option*: `host` => `192.168.245.143,192.168.1.240` | |
|
66 | # Host[s] of the LDAP Server | |
|
67 | # (e.g., 192.168.2.154, or ldap-server.domain.com. | |
|
68 | # Multiple servers can be specified using commas | |
|
69 | ||
|
70 | *option*: `port` => `389` | |
|
71 | # Custom port that the LDAP server is listening on. Default value is: 389, use 689 for LDAPS(SSL) | |
|
72 | ||
|
73 | *option*: `timeout` => `300` | |
|
74 | # Timeout for LDAP connection | |
|
75 | ||
|
76 | *option*: `dn_user` => `Administrator@rhodecode.com` | |
|
77 | # Optional user DN/account to connect to LDAP if authentication is required. | |
|
78 | # e.g., cn=admin,dc=mydomain,dc=com, or uid=root,cn=users,dc=mydomain,dc=com, or admin@mydomain.com | |
|
79 | ||
|
80 | *option*: `dn_pass` => `SomeSecret` | |
|
81 | # Password to authenticate for given user DN. | |
|
82 | ||
|
83 | *option*: `tls_kind` => `PLAIN` | |
|
84 | # TLS Type | |
|
85 | ||
|
86 | *option*: `tls_reqcert` => `NEVER` | |
|
87 | # Require Cert over TLS?. Self-signed and custom certificates can be used when | |
|
88 | # `RhodeCode Certificate` found in admin > settings > system info page is extended. | |
|
89 | ||
|
90 | *option*: `tls_cert_file` => `` | |
|
91 | # This specifies the PEM-format file path containing certificates for use in TLS connection. | |
|
92 | # If not specified `TLS Cert dir` will be used | |
|
93 | ||
|
94 | *option*: `tls_cert_dir` => `/etc/openldap/cacerts` | |
|
95 | # This specifies the path of a directory that contains individual CA certificates in separate files. | |
|
96 | ||
|
97 | *option*: `base_dn` => `dc=rhodecode,dc=com` | |
|
98 | # Base DN to search. Dynamic bind is supported. Add `$login` marker in it to be replaced with current user credentials | |
|
99 | # (e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com) | |
|
100 | ||
|
101 | *option*: `user_search_base` => `ou=RC-Users` | |
|
102 | # User search base will extend the Base DN | |
|
103 | # (e.g., ou=Users will result in ou=Users,dc=mydomain,dc=com root DN) | |
|
56 | 104 | |
|
57 | # Auth Cache TTL, Defines the caching for authentication to offload LDAP server. | |
|
58 | # This means that cache result will be saved for 3600 before contacting LDAP server to verify the user access | |
|
59 | 3600 | |
|
60 | # Host, comma seperated format is optionally possible to specify more than 1 server | |
|
61 | https://ldap1.server.com/ldap-admin/,https://ldap2.server.com/ldap-admin/ | |
|
62 | # Default LDAP Port, use 689 for LDAPS | |
|
63 | 389 | |
|
64 | # Account, used for SimpleBind if LDAP server requires an authentication | |
|
65 | e.g admin@server.com | |
|
66 | # Password used for simple bind | |
|
67 | ldap-user-password | |
|
68 | # LDAP connection security | |
|
69 | LDAPS | |
|
70 | # Certificate checks level | |
|
71 | DEMAND | |
|
72 | # Base DN | |
|
73 | cn=Rufus Magillacuddy,ou=users,dc=rhodecode,dc=com | |
|
74 | # User Search Base | |
|
75 | ou=groups,ou=users | |
|
76 | # LDAP search filter to narrow the results | |
|
77 | (objectClass=person) | |
|
78 | # LDAP search scope | |
|
79 | SUBTREE | |
|
80 | # Login attribute | |
|
81 | sAMAccountName | |
|
82 | # First Name Attribute to read | |
|
83 | givenName | |
|
84 | # Last Name Attribute to read | |
|
85 | sn | |
|
86 | # Email Attribute to read email address from | |
|
87 | ||
|
88 | # group extraction method | |
|
89 | rfc2307bis | |
|
90 | # Group search base | |
|
91 | ou=RC-Groups | |
|
92 | # Group Name Attribute, field to read the group name from | |
|
93 | sAMAAccountName | |
|
94 | # User Member of Attribute, field in which groups are stored | |
|
95 | memberOf | |
|
96 | # LDAP Group Search Filter, allows narrowing the results | |
|
105 | *option*: `user_search_filter` => `` | |
|
106 | # Filter to narrow results | |
|
107 | # (e.g., (&(objectCategory=Person)(objectClass=user)), or | |
|
108 | # (memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com))) | |
|
109 | ||
|
110 | *option*: `search_scope` => `SUBTREE` | |
|
111 | # How deep to search LDAP. If unsure set to SUBTREE | |
|
112 | ||
|
113 | *option*: `attr_login` => `sAMAccountName` | |
|
114 | # LDAP Attribute to map to user name (e.g., uid, or sAMAccountName) | |
|
115 | ||
|
116 | *option*: `attr_email` => `mail` | |
|
117 | # LDAP Attribute to map to email address (e.g., mail). | |
|
118 | # Emails are a crucial part of RhodeCode. | |
|
119 | # If possible add a valid email attribute to ldap users. | |
|
120 | ||
|
121 | *option*: `attr_firstname` => `givenName` | |
|
122 | # LDAP Attribute to map to first name (e.g., givenName) | |
|
123 | ||
|
124 | *option*: `attr_lastname` => `sn` | |
|
125 | # LDAP Attribute to map to last name (e.g., sn) | |
|
126 | ||
|
127 | *option*: `group_extraction_type` => `rfc2307bis` | |
|
128 | # With rfc2307, group members are listed by name in the memberUid attribute | |
|
129 | # With rfc2307bis (Microsoft AD compatible) group members are listed by DN and stored in the member attribute | |
|
97 | 130 |
|
|
98 | # Admin Groups. Comma separated list of groups. If user is member of | |
|
99 | # any of those he will be marked as super-admin in RhodeCode | |
|
100 | admins, management | |
|
131 | *option*: `group_search_base` => `ou=RC-Groups` | |
|
132 | # Group search base will extend the Base DN (e.g. ou=Groups will result in ou=Groups,dc=mydomain,dc=com) | |
|
101 | 133 | |
|
134 | *option*: `group_name_attr` => `sAMAccountName` | |
|
135 | # LDAP Attribute to map to group name (e.g., cn, or sAMAccountName) | |
|
136 | ||
|
137 | *option*: `user_member_of` => `memberOf` | |
|
138 | # Users Attribute used to fetch the group membership. | |
|
139 | # Use if users have stored group membership inside their attributes | |
|
140 | # (e.g., memberOf, or userMemberOf) | |
|
102 | 141 | |
|
103 | Below is example setup that can be used with Active Directory and ldap groups. | |
|
142 | *option*: `group_search_filter` => `` | |
|
143 | # Filter to narrow results (e.g., (&(objectCategory=Group)(objectClass=group)), etc) | |
|
144 | ||
|
145 | *option*: `group_member_of` => `memberOf` | |
|
146 | # LDAP Attribute used to resolve the parent group (e.g., memberOf) | |
|
104 | 147 |
|
|
105 | .. image:: ../images/ldap-groups-example.png | |
|
106 | :alt: LDAP/AD setup example | |
|
107 | :scale: 50 % | |
|
148 | *option*: `admin_groups` => `Admins,Management` | |
|
149 | # A comma separated list of group names that identify users as RhodeCode Administrators (e.g., admins) | |
|
150 | ||
|
151 | *option*: `admin_groups_sync` => `full` | |
|
152 | # Way to sync Admin groups. | |
|
153 | # Full means admin flag is set to on or off according to membership in administrator group defined above. | |
|
154 | # On-only means the flag is only set to on, and not turned off once user is no longer a member | |
|
155 | ||
|
108 | 156 |
|
|
109 | 157 | .. toctree:: |
|
110 | 158 |
@@ -3,11 +3,9 b'' | |||
|
3 | 3 | LDAP/AD |
|
4 | 4 | ------- |
|
5 | 5 | |
|
6 |
|RC |
|
|
6 | |RCE| supports LDAP (Lightweight Directory Access Protocol) or | |
|
7 | 7 | AD (active Directory) authentication. |
|
8 | All LDAP versions are supported, with the following |RCM| plugins managing each: | |
|
9 | ||
|
10 | * For LDAP or Active Directory use ``LDAP (egg:rhodecode-enterprise-ce#ldap)`` | |
|
8 | All LDAP versions are currently supported. | |
|
11 | 9 | |
|
12 | 10 | RhodeCode reads all data defined from plugin and creates corresponding |
|
13 | 11 | accounts on local database after receiving data from LDAP. This is done on |
@@ -30,11 +28,12 b' LDAP Configuration Steps' | |||
|
30 | 28 | |
|
31 | 29 | To configure |LDAP|, use the following steps: |
|
32 | 30 | |
|
33 |
1. From the |RC |
|
|
31 | 1. From the |RCE| interface, select | |
|
34 | 32 | :menuselection:`Admin --> Authentication` |
|
35 |
2. |
|
|
36 | 3. Select the :guilabel:`Enabled` check box in the plugin configuration section | |
|
37 | 4. Add the required LDAP information and :guilabel:`Save`, for more details, | |
|
33 | 2. Activate the `LDAP` plugin and select :guilabel:`Save` | |
|
34 | 3. Go to newly available menu option called `LDAP` on the left side. | |
|
35 | 4. Check the `enabled` check box in the plugin configuration section, | |
|
36 | and fill in the required LDAP information and :guilabel:`Save`, for more details, | |
|
38 | 37 | see :ref:`config-ldap-examples` |
|
39 | 38 | |
|
40 | 39 | For a more detailed description of LDAP objects, see :ref:`ldap-gloss-ref`: |
@@ -43,44 +42,73 b' For a more detailed description of LDAP ' | |||
|
43 | 42 | |
|
44 | 43 | Example LDAP configuration |
|
45 | 44 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
46 | .. code-block:: bash | |
|
45 | ||
|
46 | Below is example setup that can be used with Active Directory/LDAP server:: | |
|
47 | ||
|
48 | *option*: `enabled` => `True` | |
|
49 | # Enable or disable this authentication plugin. | |
|
50 | ||
|
51 | *option*: `cache_ttl` => `360` | |
|
52 | # Amount of seconds to cache the authentication and permissions check response call for this plugin. | |
|
53 | # Useful for expensive calls like LDAP to improve the performance of the system (0 means disabled). | |
|
54 | ||
|
55 | *option*: `host` => `192.168.245.143,192.168.1.240` | |
|
56 | # Host[s] of the LDAP Server | |
|
57 | # (e.g., 192.168.2.154, or ldap-server.domain.com. | |
|
58 | # Multiple servers can be specified using commas | |
|
59 | ||
|
60 | *option*: `port` => `389` | |
|
61 | # Custom port that the LDAP server is listening on. Default value is: 389, use 689 for LDAPS(SSL) | |
|
62 | ||
|
63 | *option*: `timeout` => `300` | |
|
64 | # Timeout for LDAP connection | |
|
65 | ||
|
66 | *option*: `dn_user` => `Administrator@rhodecode.com` | |
|
67 | # Optional user DN/account to connect to LDAP if authentication is required. | |
|
68 | # e.g., cn=admin,dc=mydomain,dc=com, or uid=root,cn=users,dc=mydomain,dc=com, or admin@mydomain.com | |
|
69 | ||
|
70 | *option*: `dn_pass` => `SomeSecret` | |
|
71 | # Password to authenticate for given user DN. | |
|
72 | ||
|
73 | *option*: `tls_kind` => `PLAIN` | |
|
74 | # TLS Type | |
|
47 | 75 | |
|
48 | # Auth Cache TTL, Defines the caching for authentication to offload LDAP server. | |
|
49 | # This means that cache result will be saved for 3600 before contacting LDAP server to verify the user access | |
|
50 | 3600 | |
|
51 | # Host, comma seperated format is optionally possible to specify more than 1 server | |
|
52 | https://ldap1.server.com/ldap-admin/,https://ldap2.server.com/ldap-admin/ | |
|
53 | # Default LDAP Port, use 689 for LDAPS | |
|
54 | 389 | |
|
55 | # Account, used for SimpleBind if LDAP server requires an authentication | |
|
56 | e.g admin@server.com | |
|
57 | # Password used for simple bind | |
|
58 | ldap-user-password | |
|
59 | # LDAP connection security | |
|
60 | LDAPS | |
|
61 | # Certificate checks level | |
|
62 | DEMAND | |
|
63 | # Base DN | |
|
64 | cn=Rufus Magillacuddy,ou=users,dc=rhodecode,dc=com | |
|
65 | # LDAP search filter to narrow the results | |
|
66 | (objectClass=person) | |
|
67 | # LDAP search scope | |
|
68 | SUBTREE | |
|
69 | # Login attribute | |
|
70 | sAMAccountName | |
|
71 | # First Name Attribute to read | |
|
72 | givenName | |
|
73 | # Last Name Attribute to read | |
|
74 | sn | |
|
75 | # Email Attribute to read email address from | |
|
76 | ||
|
76 | *option*: `tls_reqcert` => `NEVER` | |
|
77 | # Require Cert over TLS?. Self-signed and custom certificates can be used when | |
|
78 | # `RhodeCode Certificate` found in admin > settings > system info page is extended. | |
|
79 | ||
|
80 | *option*: `tls_cert_file` => `` | |
|
81 | # This specifies the PEM-format file path containing certificates for use in TLS connection. | |
|
82 | # If not specified `TLS Cert dir` will be used | |
|
83 | ||
|
84 | *option*: `tls_cert_dir` => `/etc/openldap/cacerts` | |
|
85 | # This specifies the path of a directory that contains individual CA certificates in separate files. | |
|
86 | ||
|
87 | *option*: `base_dn` => `cn=Rufus Magillacuddy,ou=users,dc=rhodecode,dc=com` | |
|
88 | # Base DN to search. Dynamic bind is supported. Add `$login` marker in it to be replaced with current user credentials | |
|
89 | # (e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com) | |
|
77 | 90 | |
|
91 | *option*: `filter` => `(objectClass=person)` | |
|
92 | # Filter to narrow results | |
|
93 | # (e.g., (&(objectCategory=Person)(objectClass=user)), or | |
|
94 | # (memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com))) | |
|
78 | 95 | |
|
79 | Below is example setup that can be used with Active Directory/LDAP server. | |
|
96 | *option*: `search_scope` => `SUBTREE` | |
|
97 | # How deep to search LDAP. If unsure set to SUBTREE | |
|
98 | ||
|
99 | *option*: `attr_login` => `sAMAccountName` | |
|
100 | # LDAP Attribute to map to user name (e.g., uid, or sAMAccountName) | |
|
80 | 101 |
|
|
81 | .. image:: ../images/ldap-example.png | |
|
82 | :alt: LDAP/AD setup example | |
|
83 | :scale: 50 % | |
|
102 | *option*: `attr_email` => `mail` | |
|
103 | # LDAP Attribute to map to email address (e.g., mail). | |
|
104 | # Emails are a crucial part of RhodeCode. | |
|
105 | # If possible add a valid email attribute to ldap users. | |
|
106 | ||
|
107 | *option*: `attr_firstname` => `givenName` | |
|
108 | # LDAP Attribute to map to first name (e.g., givenName) | |
|
109 | ||
|
110 | *option*: `attr_lastname` => `sn` | |
|
111 | # LDAP Attribute to map to last name (e.g., sn) | |
|
84 | 112 |
|
|
85 | 113 |
|
|
86 | 114 | .. toctree:: |
@@ -5,8 +5,8 b' PAM' | |||
|
5 | 5 | |
|
6 | 6 | To enable PAM authentication, use the following steps: |
|
7 | 7 | |
|
8 |
1. From the |RC |
|
|
9 |
2. |
|
|
8 | 1. From the |RCE| interface, go to :menuselection:`Admin --> Authentication` | |
|
9 | 2. Activate the ``rhodecode.lib.auth_modules.auth_pam`` library and select save | |
|
10 | 10 | 3. On the PAM plugin settings section, do the following: |
|
11 | 11 | |
|
12 | 12 | * Check the :guilabel:`Enable` checkbox |
@@ -3,7 +3,10 b'' | |||
|
3 | 3 | Authentication Tokens |
|
4 | 4 | --------------------- |
|
5 | 5 | |
|
6 | |RCE| has 4 different kinds of authentication tokens. | |
|
6 | |RCE| has 4 different kinds of authentication tokens. `API token`, `Feed tokens` work | |
|
7 | without a need to enable any additional authentication. `VCS tokens` require dedicated | |
|
8 | authentication plugin to be activated. `Web Interface tokens` are controlled by the | |
|
9 | white_list configuration. | |
|
7 | 10 | |
|
8 | 11 | * *API tokens*: API tokens can only be used to execute |RCE| API operations. |
|
9 | 12 | You can store your API token and assign it to each instance in |
@@ -11,15 +14,7 b' Authentication Tokens' | |||
|
11 | 14 | example in :ref:`indexing-ref` section for more details. |
|
12 | 15 | |
|
13 | 16 | * *Feed tokens*: The feed token can only be used to access the RSS feed. |
|
14 |
|
|
|
15 | ||
|
16 | * *VCS tokens*: You can use these to authenticate with |git|, |hg| and |svn| | |
|
17 | operations instead of a password. They are designed to be used with | |
|
18 | CI Servers or other third party tools that require |repo| access. | |
|
19 | They are also a good replacement for SSH based access. | |
|
20 | To use these tokens you need be enabled special authentication method on | |
|
21 | |RCE|, as they are disabled by default. | |
|
22 | See :ref:`enable-vcs-tokens`. | |
|
17 | Usually those are safe to store inside your RSS feed reader. | |
|
23 | 18 | |
|
24 | 19 | * *Web Interface tokens*: These token allows users to access the web |
|
25 | 20 | interface of |RCE| without logging in. |
@@ -41,7 +36,16 b' Authentication Tokens' | |||
|
41 | 36 | https://rhodecode.com/repo/archive/tip.zip?auth_token=<web-api-token> |
|
42 | 37 | |
|
43 | 38 | # To show commit diff without logging into Web UI |
|
44 |
https://rhodecode.com/repo/ |
|
|
39 | https://rhodecode.com/repo/raw-diff/<sha>?auth_token=<web-api-token> | |
|
40 | ||
|
41 | * *VCS tokens*: You can use these to authenticate with |git|, |hg| and |svn| | |
|
42 | operations instead of a password. They are designed to be used with | |
|
43 | CI Servers or other third party tools that require |repo| access. | |
|
44 | They are also a good replacement for SSH based access. | |
|
45 | To use these tokens you need be enabled special authentication method on | |
|
46 | |RCE|, as they are disabled by default. | |
|
47 | See :ref:`enable-vcs-tokens`. | |
|
48 | ||
|
45 | 49 | |
|
46 | 50 | .. _enable-vcs-tokens: |
|
47 | 51 | |
@@ -51,7 +55,7 b' Enabling VCS Tokens' | |||
|
51 | 55 | To enable VCS Tokens, use the following steps: |
|
52 | 56 | |
|
53 | 57 | 1. Go to :menuselection:`Admin --> Authentication`. |
|
54 |
2. |
|
|
58 | 2. Activate the ``rhodecode.lib.auth_modules.auth_token`` plugin. | |
|
55 | 59 | 3. Click :guilabel:`Save`. |
|
56 | 60 | |
|
57 | 61 | Authentication Token Tips |
@@ -67,7 +71,7 b' Creating Tokens' | |||
|
67 | 71 | |
|
68 | 72 | To create authentication tokens for an user, use the following steps: |
|
69 | 73 | |
|
70 |
1. From the |RC |
|
|
74 | 1. From the |RCE| interface go to | |
|
71 | 75 | :menuselection:`Username --> My Account --> Auth tokens`. |
|
72 | 76 | |
|
73 | 77 | 2. Label and Add the tokens you wish to use with |RCE|. |
@@ -4,29 +4,31 b' Authentication Options' | |||
|
4 | 4 | ====================== |
|
5 | 5 | |
|
6 | 6 | |RCE| provides a built in authentication against its own database. This is |
|
7 |
implemented using `` |
|
|
8 | enabled by default. | |
|
7 | implemented using ``RhodeCode Internal`` plugin. This plugin is enabled by default. | |
|
9 | 8 | Additionally, |RCE| provides a Pluggable Authentication System. This gives the |
|
10 | 9 | administrator greater control over how users authenticate with the system. |
|
11 | 10 | |
|
12 | 11 | .. important:: |
|
13 | 12 | |
|
14 |
You can disable the built in |RC |
|
|
15 |
`` |
|
|
13 | You can disable the built in |RCE| authentication plugin | |
|
14 | ``RhodeCode Internal`` and force all authentication to go | |
|
16 | 15 | through your authentication plugin of choice e.g LDAP only. |
|
17 | 16 | However, if you do this, and your external authentication tools fails, |
|
18 | you will be unable to access |RCM|. | |
|
17 | accessing |RCE| will be blocked unless a fallback plugin is | |
|
18 | enabled via :file: rhodecode.ini | |
|
19 | 19 | |
|
20 | |RCM| comes with the following user authentication management plugins: | |
|
20 | ||
|
21 | |RCE| comes with the following user authentication management plugins: | |
|
21 | 22 | |
|
22 | 23 | |
|
23 | 24 | .. toctree:: |
|
24 | 25 | |
|
26 | auth-token | |
|
25 | 27 | auth-ldap |
|
26 | 28 | auth-ldap-groups |
|
29 | auth-saml-generic | |
|
30 | auth-saml-onelogin | |
|
31 | auth-saml-duosecurity | |
|
27 | 32 | auth-crowd |
|
28 | 33 | auth-pam |
|
29 | auth-token | |
|
30 | 34 | ssh-connection |
|
31 | ||
|
32 |
@@ -3,27 +3,73 b'' | |||
|
3 | 3 | Active Directory |
|
4 | 4 | ---------------- |
|
5 | 5 | |
|
6 |
|RC |
|
|
6 | |RCE| can use Microsoft Active Directory for user authentication. This is | |
|
7 | 7 | done through an LDAP or LDAPS connection to Active Directory. Use the |
|
8 | 8 | following example LDAP configuration setting to set your Active Directory |
|
9 |
authentication |
|
|
10 | ||
|
11 | .. code-block:: ini | |
|
12 | ||
|
13 | # Set the Base DN | |
|
14 | Base DN = OU=SBSUsers,OU=Users,OU=MyBusiness,DC=v3sys,DC=local | |
|
15 | # Set the Active Directory SAM-Account-Name | |
|
16 | Login Attribute = sAMAccountName | |
|
17 | # Set the Active Directory user name | |
|
18 | First Name Attribute = usernameame | |
|
19 | # Set the Active Directory user surname | |
|
20 | Last Name Attribute = user_surname | |
|
21 | # Set the Active Directory user email | |
|
22 | E-mail Attribute = userEmail | |
|
9 | authentication:: | |
|
23 | 10 | |
|
24 | 11 | |
|
25 | Below is example setup that can be used with Active Directory and ldap groups. | |
|
12 | *option*: `enabled` => `True` | |
|
13 | # Enable or disable this authentication plugin. | |
|
14 | ||
|
15 | *option*: `cache_ttl` => `360` | |
|
16 | # Amount of seconds to cache the authentication and permissions check response call for this plugin. | |
|
17 | # Useful for expensive calls like LDAP to improve the performance of the system (0 means disabled). | |
|
18 | ||
|
19 | *option*: `host` => `192.168.245.143,192.168.1.240` | |
|
20 | # Host[s] of the LDAP Server | |
|
21 | # (e.g., 192.168.2.154, or ldap-server.domain.com. | |
|
22 | # Multiple servers can be specified using commas | |
|
23 | ||
|
24 | *option*: `port` => `389` | |
|
25 | # Custom port that the LDAP server is listening on. Default value is: 389, use 689 for LDAPS(SSL) | |
|
26 | ||
|
27 | *option*: `timeout` => `300` | |
|
28 | # Timeout for LDAP connection | |
|
29 | ||
|
30 | *option*: `dn_user` => `Administrator@rhodecode.com` | |
|
31 | # Optional user DN/account to connect to LDAP if authentication is required. | |
|
32 | # e.g., cn=admin,dc=mydomain,dc=com, or uid=root,cn=users,dc=mydomain,dc=com, or admin@mydomain.com | |
|
33 | ||
|
34 | *option*: `dn_pass` => `SomeSecret` | |
|
35 | # Password to authenticate for given user DN. | |
|
36 | ||
|
37 | *option*: `tls_kind` => `PLAIN` | |
|
38 | # TLS Type | |
|
39 | ||
|
40 | *option*: `tls_reqcert` => `NEVER` | |
|
41 | # Require Cert over TLS?. Self-signed and custom certificates can be used when | |
|
42 | # `RhodeCode Certificate` found in admin > settings > system info page is extended. | |
|
26 | 43 | |
|
27 | .. image:: ../images/ldap-groups-example.png | |
|
28 | :alt: LDAP/AD setup example | |
|
29 | :scale: 50 % No newline at end of file | |
|
44 | *option*: `tls_cert_file` => `` | |
|
45 | # This specifies the PEM-format file path containing certificates for use in TLS connection. | |
|
46 | # If not specified `TLS Cert dir` will be used | |
|
47 | ||
|
48 | *option*: `tls_cert_dir` => `/etc/openldap/cacerts` | |
|
49 | # This specifies the path of a directory that contains individual CA certificates in separate files. | |
|
50 | ||
|
51 | *option*: `base_dn` => `OU=SBSUsers,OU=Users,OU=MyBusiness,DC=v3sys,DC=local` | |
|
52 | # Base DN to search. Dynamic bind is supported. Add `$login` marker in it to be replaced with current user credentials | |
|
53 | # (e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com) | |
|
54 | ||
|
55 | *option*: `filter` => `(objectClass=person)` | |
|
56 | # Filter to narrow results | |
|
57 | # (e.g., (&(objectCategory=Person)(objectClass=user)), or | |
|
58 | # (memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com))) | |
|
59 | ||
|
60 | *option*: `search_scope` => `SUBTREE` | |
|
61 | # How deep to search LDAP. If unsure set to SUBTREE | |
|
62 | ||
|
63 | *option*: `attr_login` => `sAMAccountName` | |
|
64 | # LDAP Attribute to map to user name (e.g., uid, or sAMAccountName) | |
|
65 | ||
|
66 | *option*: `attr_email` => `userEmail` | |
|
67 | # LDAP Attribute to map to email address (e.g., mail). | |
|
68 | # Emails are a crucial part of RhodeCode. | |
|
69 | # If possible add a valid email attribute to ldap users. | |
|
70 | ||
|
71 | *option*: `attr_firstname` => `user_firstname` | |
|
72 | # LDAP Attribute to map to first name (e.g., givenName) | |
|
73 | ||
|
74 | *option*: `attr_lastname` => `user_surname` | |
|
75 | # LDAP Attribute to map to last name (e.g., sn) |
@@ -46,7 +46,7 b' The following LDAP attributes are requir' | |||
|
46 | 46 | * The LDAP username or account used to connect to |RCE|. This will be added |
|
47 | 47 | to the LDAP filter for locating the user object. |
|
48 | 48 | * For example, if an LDAP filter is specified as `LDAPFILTER`, |
|
49 | the login attribute is specified as `uid`, and the user connects as | |
|
49 | the login/username attribute is specified as `uid`, and the user connects as | |
|
50 | 50 | `jsmith`, then the LDAP Filter will be like the following example. |
|
51 | 51 | |
|
52 | 52 | .. code-block:: vim |
@@ -68,7 +68,7 b' The following LDAP attributes are requir' | |||
|
68 | 68 | Optional settings |
|
69 | 69 | ^^^^^^^^^^^^^^^^^ |
|
70 | 70 | |
|
71 |
The following are optional when enabling LDAP on |RC |
|
|
71 | The following are optional when enabling LDAP on |RCE| | |
|
72 | 72 | |
|
73 | 73 | * An LDAP account is only required if the LDAP server does not allow |
|
74 | 74 | anonymous browsing of records. |
@@ -104,10 +104,4 b' The following are optional when enabling' | |||
|
104 | 104 | following directory: `/etc/openldap/cacerts` |
|
105 | 105 | |
|
106 | 106 | |
|
107 | Below is example setup that can be used with Active Directory and ldap groups. | |
|
108 | ||
|
109 | .. image:: ../images/ldap-groups-example.png | |
|
110 | :alt: LDAP/AD setup example | |
|
111 | :scale: 50 % | |
|
112 | ||
|
113 | 107 | .. _RFC 2254: http://www.rfc-base.org/rfc-2254.html No newline at end of file |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | Code Review |
|
4 | 4 | =========== |
|
5 | 5 | |
|
6 |
|RC |
|
|
6 | |RCE| provides two ways in which you can review code. You can review |prs| or | |
|
7 | 7 | commits. To better understand |prs|, see the :ref:`pull-requests-ref` |
|
8 | 8 | and :ref:`collaborate-ref` sections. For more information about why |
|
9 | 9 | code review matters, see these posts on the topic: |
@@ -16,7 +16,7 b' review purposes.' | |||
|
16 | 16 | Reviewing Changes |
|
17 | 17 | ----------------- |
|
18 | 18 | |
|
19 |
|RC |
|
|
19 | |RCE| displays all code changes made with each commit. Removed content is | |
|
20 | 20 | marked in red and new content in green. |
|
21 | 21 | |
|
22 | 22 | .. image:: ../images/plain-diff.png |
@@ -10,7 +10,7 b' 3. Leave a commit message that outlines ' | |||
|
10 | 10 | 4. Set the review status to :guilabel:`Approved` |
|
11 | 11 | 5. Select :guilabel:`Comment` |
|
12 | 12 | |
|
13 |
If you approve the |pr|, you will be able to merge automatically if |RC |
|
|
13 | If you approve the |pr|, you will be able to merge automatically if |RCE| | |
|
14 | 14 | detects that it can do so safely. You will see this message: |
|
15 | 15 | |
|
16 | 16 | :guilabel:`This pull request can be automatically merged.` |
@@ -7,7 +7,7 b' Collaboration' | |||
|
7 | 7 | |
|
8 | 8 | Forking and branching does not work with |svn| |repos|. |
|
9 | 9 | |
|
10 |
Collaboration in |RC |
|
|
10 | Collaboration in |RCE| is accomplished through a combination of the following | |
|
11 | 11 | functions: |
|
12 | 12 | |
|
13 | 13 | .. only:: latex |
@@ -55,7 +55,7 b' on the web interface. To branch a |git| ' | |||
|
55 | 55 | $ git commit -a -m "ghost script: initial file" |
|
56 | 56 | $ git push |
|
57 | 57 | |
|
58 |
Once it is pushed to the |RC |
|
|
58 | Once it is pushed to the |RCE| server, you can switch to the newly created | |
|
59 | 59 | branch using the following steps: |
|
60 | 60 | |
|
61 | 61 | 1. Select :menuselection:`Admin --> Repositories`. |
@@ -4,7 +4,7 b' Using Notifications' | |||
|
4 | 4 | ------------------- |
|
5 | 5 | |
|
6 | 6 | To notify users of items that require their attention you can use the mention |
|
7 |
function. The mention function allows you to use ``@username`` within |RC |
|
|
7 | function. The mention function allows you to use ``@username`` within |RCE|. | |
|
8 | 8 | The notification function can be used within the following |
|
9 | 9 | items to highlight their need for attention: |
|
10 | 10 |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | Merge a |pr| |
|
4 | 4 | ------------ |
|
5 | 5 | |
|
6 |
|RC |
|
|
6 | |RCE| can detect if it can automatically merge the changes in a |pr|. If it | |
|
7 | 7 | can, you will see the following message: |
|
8 | 8 | :guilabel:`This pull request can be automatically merged.` To merge, |
|
9 | 9 | click the big blue button! To enable this feature, see :ref:`server-side-merge`. |
@@ -21,7 +21,7 b' messages:' | |||
|
21 | 21 | Manual Merge a |PR| |
|
22 | 22 | ^^^^^^^^^^^^^^^^^^^ |
|
23 | 23 | |
|
24 |
If |RC |
|
|
24 | If |RCE| cannot safely merge the changes in a |pr|, | |
|
25 | 25 | usually due to conflicts, you need to manually merge the changes on the |
|
26 | 26 | command line. You can see more information for each |repo| type at the |
|
27 | 27 | following links: |
@@ -1,7 +1,7 b'' | |||
|
1 | 1 | Notifications Overview |
|
2 | 2 | ---------------------- |
|
3 | 3 | |
|
4 |
|RC |
|
|
4 | |RCE| has an integrated notification system which alerts users to requests | |
|
5 | 5 | that they have received. Notifications can occur for the following reasons: |
|
6 | 6 | |
|
7 | 7 | * Pull request reviews |
@@ -3,7 +3,7 b' Pull request management' | |||
|
3 | 3 | |
|
4 | 4 | .. only:: html |
|
5 | 5 | |
|
6 |
There are two ways of tracking |prs| within |RC |
|
|
6 | There are two ways of tracking |prs| within |RCE|. | |
|
7 | 7 | |
|
8 | 8 | 1. :ref:`prs-your-review` |
|
9 | 9 | 2. :ref:`prs-per-repo` |
@@ -15,7 +15,7 b' Pull requests for your review' | |||
|
15 | 15 | |
|
16 | 16 | To view pull requests for your review, use the following steps: |
|
17 | 17 | |
|
18 |
1. From the |RC |
|
|
18 | 1. From the |RCE| interface, Select | |
|
19 | 19 | :menuselection:`username --> Notifications` |
|
20 | 20 | 2. Select :guilabel:`Pull Requests` |
|
21 | 21 |
@@ -20,7 +20,7 b' 3. Set the review status from one of the' | |||
|
20 | 20 | 4. Select Comment |
|
21 | 21 | |
|
22 | 22 | When the |pr| is approved by all reviewers you will be able to merge |
|
23 |
automatically if |RC |
|
|
23 | automatically if |RCE| detects that it can do so safely. You will see this | |
|
24 | 24 | message: `This pull request can be automatically merged.` |
|
25 | 25 | |
|
26 | 26 | If rejected, you can fix the issues raised during review and then update the |
@@ -1,7 +1,7 b'' | |||
|
1 | 1 | Supported Workflows |
|
2 | 2 | ------------------- |
|
3 | 3 | |
|
4 |
|RC |
|
|
4 | |RCE| can be used to develop using a variety of different workflows. | |
|
5 | 5 | |
|
6 | 6 | * Centralized, using |svn|, |git|, or |hg| |repos| |
|
7 | 7 | * Feature-Branch, using |git| or |hg| |repos| |
@@ -20,10 +20,7 b" rst_epilog = '''" | |||
|
20 | 20 | .. |psf| replace:: Python Software Foundation |
|
21 | 21 | .. |repo| replace:: repository |
|
22 | 22 | .. |repos| replace:: repositories |
|
23 | .. |RCI| replace:: RhodeCode Control | |
|
24 | 23 | .. |RCC| replace:: RhodeCode Control |
|
25 | .. |RCV| replace:: RhodeCode Enterprise | |
|
26 | .. |RCM| replace:: RhodeCode Enterprise | |
|
27 | 24 | .. |RCE| replace:: RhodeCode Enterprise |
|
28 | 25 | .. |RCCE| replace:: RhodeCode Community |
|
29 | 26 | .. |RCEE| replace:: RhodeCode Enterprise |
@@ -31,6 +28,5 b" rst_epilog = '''" | |||
|
31 | 28 | .. |RCT| replace:: RhodeCode Tools |
|
32 | 29 | .. |RCEBOLD| replace:: **RhodeCode Enterprise** |
|
33 | 30 | .. |RCEITALICS| replace:: `RhodeCode Enterprise` |
|
34 | .. |RC| replace:: RhodeCode | |
|
35 | 31 | .. |RNS| replace:: Release Notes |
|
36 | 32 | ''' |
@@ -18,7 +18,7 b' so to clarify what is meant each time, r' | |||
|
18 | 18 | Hooks |
|
19 | 19 | ----- |
|
20 | 20 | |
|
21 |
Within |RC |
|
|
21 | Within |RCE| there are two types of supported hooks. | |
|
22 | 22 | |
|
23 | 23 | * **Internal built-in hooks**: The internal |hg|, |git| or |svn| hooks are |
|
24 | 24 | triggered by different VCS operations, like push, pull, |
@@ -1,13 +1,13 b'' | |||
|
1 |
|RC |
|
|
1 | |RCE| | |
|
2 | 2 | ===== |
|
3 | 3 | |
|
4 |
|RC |
|
|
4 | |RCE| is a high-performance source code management and collaboration system. | |
|
5 | 5 | It enables you to develop projects securely behind the firewall while |
|
6 | 6 | providing collaboration tools that work with |git|, |hg|, |
|
7 | 7 | and |svn| |repos|. The user interface allows you to create, edit, |
|
8 | 8 | and commit files and |repos| while managing their security permissions. |
|
9 | 9 | |
|
10 |
|RC |
|
|
10 | |RCE| provides the following features: | |
|
11 | 11 | |
|
12 | 12 | * Source code management. |
|
13 | 13 | * Extended permissions management. |
@@ -18,7 +18,7 b' and commit files and |repos| while manag' | |||
|
18 | 18 | * Web-based hook management. |
|
19 | 19 | * Native |svn| support. |
|
20 | 20 | * Migration from existing databases. |
|
21 |
* |RC |
|
|
21 | * |RCE| SDK. | |
|
22 | 22 | * Built-in analytics |
|
23 | 23 | * Built in integrations including: Slack, Webhooks (used for Jenkins/TeamCity and other CIs), Jira, Redmine, Hipchat |
|
24 | 24 | * Pluggable authentication system. |
@@ -5,8 +5,24 b' Supported Databases' | |||
|
5 | 5 | |
|
6 | 6 | .. important:: |
|
7 | 7 | |
|
8 |
We do not recommend using SQLite in a production environment |
|
|
9 | supported by |RCE| for evaluation purposes. | |
|
8 | We do not recommend using SQLite in a production environment of more than 5 people. | |
|
9 | It is not suited for higher usage and mayb cause problems. | |
|
10 | ||
|
11 | ||
|
12 | |RCE| supports the following databases. The recommended encoding is UTF-8. | |
|
13 | ||
|
14 | .. only:: latex | |
|
15 | ||
|
16 | * :ref:`install-sqlite-database` | |
|
17 | * :ref:`install-mysql-database` | |
|
18 | * :ref:`install-postgresql-database` | |
|
19 | ||
|
20 | .. toctree:: | |
|
21 | ||
|
22 | using-mysql | |
|
23 | using-postgresql | |
|
24 | using-sqllite | |
|
25 | ||
|
10 | 26 | |
|
11 | 27 | Database Overview |
|
12 | 28 | ----------------- |
@@ -48,21 +64,3 b' following example to configure the corre' | |||
|
48 | 64 | # for the RCE instance you are installing |
|
49 | 65 | Database name: example-db-name-for-2xx # The 2xx version database |
|
50 | 66 | Database name: example-db-name-for-3xx # The 3xx version database |
|
51 | ||
|
52 | Supported Databases | |
|
53 | ------------------- | |
|
54 | ||
|
55 | |RCM| supports the following databases. The recommended encoding is Unicode | |
|
56 | UTF-8. | |
|
57 | ||
|
58 | .. only:: latex | |
|
59 | ||
|
60 | * :ref:`install-sqlite-database` | |
|
61 | * :ref:`install-mysql-database` | |
|
62 | * :ref:`install-postgresql-database` | |
|
63 | ||
|
64 | .. toctree:: | |
|
65 | ||
|
66 | using-mysql | |
|
67 | using-postgresql | |
|
68 | using-sqllite |
@@ -4,7 +4,7 b' Post Installation Tasks' | |||
|
4 | 4 | ======================= |
|
5 | 5 | |
|
6 | 6 | The following tasks are the most common post installation requirements. Use |
|
7 |
the information in these sections to configure your instance of |RC |
|
|
7 | the information in these sections to configure your instance of |RCE|. | |
|
8 | 8 | |
|
9 | 9 | .. toctree:: |
|
10 | 10 |
@@ -3,21 +3,21 b'' | |||
|
3 | 3 | Migrating |repos| |
|
4 | 4 | ----------------- |
|
5 | 5 | |
|
6 |
If you have installed |RC |
|
|
6 | If you have installed |RCE| and have |repos| that you wish to migrate into | |
|
7 | 7 | the system, use the following instructions. |
|
8 | 8 | |
|
9 |
1. On the |RC |
|
|
9 | 1. On the |RCE| interface, check your |repo| storage location under | |
|
10 | 10 | :menuselection:`Admin --> Settings --> System Info`. For example, |
|
11 | 11 | Storage location: /home/{username}/repos. |
|
12 | 12 | |
|
13 |
2. Copy the |repos| that you want |RC |
|
|
13 | 2. Copy the |repos| that you want |RCE| to manage to this location. | |
|
14 | 14 | 3. Remap and rescan the |repos|, see :ref:`remap-rescan` |
|
15 | 15 | |
|
16 | 16 | .. important:: |
|
17 | 17 | |
|
18 |
Directories create |repo| groups inside |RC |
|
|
18 | Directories create |repo| groups inside |RCE|. | |
|
19 | 19 | |
|
20 |
Importing adds |RC |
|
|
20 | Importing adds |RCE| git hooks to your |repos|. | |
|
21 | 21 | |
|
22 | 22 | You should verify if custom ``.hg`` or ``.hgrc`` files inside |
|
23 |
repositories should be adjusted since |RC |
|
|
23 | repositories should be adjusted since |RCE| reads the content of them. |
@@ -27,9 +27,12 b' 2. Run the |RCC| installer and accept th' | |||
|
27 | 27 | |
|
28 | 28 | .. code-block:: bash |
|
29 | 29 | |
|
30 |
$ chmod |
|
|
30 | $ chmod +x RhodeCode-installer-linux-* | |
|
31 | 31 | $ ./RhodeCode-installer-linux-* |
|
32 | 32 | |
|
33 | Do you accept the RhodeCode Control license? | |
|
34 | Press [Y] to accept license and [V] to view license text: y | |
|
35 | ||
|
33 | 36 | 3. Install a VCS Server, and configure it to start at boot. |
|
34 | 37 | |
|
35 | 38 | .. code-block:: bash |
@@ -3,12 +3,12 b'' | |||
|
3 | 3 | Set up Email |
|
4 | 4 | ------------ |
|
5 | 5 | |
|
6 |
To setup email with your |RC |
|
|
6 | To setup email with your |RCE| instance, open the default | |
|
7 | 7 | :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` |
|
8 | 8 | file and uncomment and configure the email section. If it is not there, |
|
9 | 9 | use the below example to insert it. |
|
10 | 10 | |
|
11 |
Once configured you can check the settings for your |RC |
|
|
11 | Once configured you can check the settings for your |RCE| instance on the | |
|
12 | 12 | :menuselection:`Admin --> Settings --> Email` page. |
|
13 | 13 | |
|
14 | 14 | .. code-block:: ini |
@@ -4,15 +4,15 b' MySQL or MariaDB' | |||
|
4 | 4 | ---------------- |
|
5 | 5 | |
|
6 | 6 | To use a MySQL or MariaDB database you should install and configure the |
|
7 |
database before installing |RC |
|
|
7 | database before installing |RCE|. This is because during |RCE| installation | |
|
8 | 8 | you will setup a connection to your MySQL or MariaDB database. To work with |
|
9 | 9 | either, use the following steps: |
|
10 | 10 | |
|
11 | 11 | 1. Depending on your |os|, install a MySQL or MariaDB database following the |
|
12 | 12 | appropriate instructions from the `MySQL website`_ or `MariaDB website`_. |
|
13 | 13 | 2. Configure the database with a username and password which you will use |
|
14 |
with |RC |
|
|
15 |
3. Install |RC |
|
|
14 | with |RCE|. | |
|
15 | 3. Install |RCE|, and during installation select MySQL as your database. | |
|
16 | 16 | 4. Enter the following information during the database setup: |
|
17 | 17 | |
|
18 | 18 | * Your network IP Address |
@@ -4,15 +4,15 b' PostgreSQL' | |||
|
4 | 4 | ---------- |
|
5 | 5 | |
|
6 | 6 | To use a PostgreSQL database, you should install and configure the database |
|
7 |
before installing |RC |
|
|
7 | before installing |RCE|. This is because during |RCE| installation you will | |
|
8 | 8 | setup the connection to your PostgreSQL database. To work with PostgreSQL, |
|
9 | 9 | use the following steps: |
|
10 | 10 | |
|
11 | 11 | 1. Depending on your |os|, install a PostgreSQL database following the |
|
12 | 12 | appropriate instructions from the `PostgreSQL website`_. |
|
13 | 13 | 2. Configure the database with a username and password, which you will use |
|
14 |
with |RC |
|
|
15 |
3. Install |RC |
|
|
14 | with |RCE|. | |
|
15 | 3. Install |RCE|, and during installation select PostgreSQL as your database. | |
|
16 | 16 | 4. Enter the following information during the database setup: |
|
17 | 17 | |
|
18 | 18 | * Your network IP Address |
@@ -9,15 +9,15 b' SQLite' | |||
|
9 | 9 | as it has an internal locking mechanism which can become a performance |
|
10 | 10 | bottleneck when there are more than 5 concurrent users. |
|
11 | 11 | |
|
12 |
|RC |
|
|
12 | |RCE| installs SQLite as the default database if you do not specify another | |
|
13 | 13 | during installation. SQLite is suitable for small teams, |
|
14 | 14 | projects with a low load, and evaluation purposes since it is built into |
|
15 |
|RC |
|
|
15 | |RCE| and does not require any additional database server. | |
|
16 | 16 | |
|
17 | 17 | Using MySQL or PostgreSQL in an large setup gives you much greater |
|
18 | 18 | performance, and while migration tools exist to move from one database type |
|
19 | 19 | to another, it is better to get it right first time and to immediately use |
|
20 |
MySQL or PostgreSQL when you deploy |RC |
|
|
20 | MySQL or PostgreSQL when you deploy |RCE| in a production environment. | |
|
21 | 21 | |
|
22 | 22 | Migrating From SQLite to PostgreSQL |
|
23 | 23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
@@ -11,20 +11,20 b' different Slack channels, for example.' | |||
|
11 | 11 | Supported integrations |
|
12 | 12 | ^^^^^^^^^^^^^^^^^^^^^^ |
|
13 | 13 | |
|
14 | ================================ ============ ======================================== | |
|
15 |
Type/Name |
|
|
16 | ================================ ============ ======================================== | |
|
17 | :ref:`integrations-webhook` |RCCEshort| Trigger events as `json` to a custom url | |
|
18 | :ref:`integrations-slack` |RCCEshort| Integrate with https://slack.com/ | |
|
19 | :ref:`integrations-hipchat` |RCCEshort| Integrate with https://www.hipchat.com/ | |
|
20 | :ref:`integrations-email` |RCCEshort| Send repo push commits by email | |
|
21 | :ref:`integrations-ci` |RCCEshort| Trigger Builds for Common CI Systems | |
|
22 | :ref:`integrations-rcextensions` |RCCEshort| Advanced low-level integration framework | |
|
14 | ================================ ================== ======================================== | |
|
15 | Type/Name RhodeCode Edition Description | |
|
16 | ================================ ================== ======================================== | |
|
17 | :ref:`integrations-webhook` |RCCEshort| Trigger events as `json` to a custom url | |
|
18 | :ref:`integrations-slack` |RCCEshort| Integrate with https://slack.com/ | |
|
19 | :ref:`integrations-hipchat` |RCCEshort| Integrate with https://www.hipchat.com/ | |
|
20 | :ref:`integrations-email` |RCCEshort| Send repo push commits by email | |
|
21 | :ref:`integrations-ci` |RCCEshort| Trigger Builds for Common CI Systems | |
|
22 | :ref:`integrations-rcextensions` |RCCEshort| Advanced low-level integration framework | |
|
23 | 23 | |
|
24 | :ref:`integrations-jenkins` |RCEEshort| Trigger Builds for Jenkins CI System | |
|
25 | :ref:`integrations-redmine` |RCEEshort| Close/Resolve/Reference Redmine issues | |
|
26 | :ref:`integrations-jira` |RCEEshort| Close/Resolve/Reference JIRA issues | |
|
27 | ================================ ============ ======================================== | |
|
24 | :ref:`integrations-jenkins` |RCEEshort| Trigger Builds for Jenkins CI System | |
|
25 | :ref:`integrations-redmine` |RCEEshort| Close/Resolve/Reference Redmine issues | |
|
26 | :ref:`integrations-jira` |RCEEshort| Close/Resolve/Reference JIRA issues | |
|
27 | ================================ ================== ======================================== | |
|
28 | 28 | |
|
29 | 29 | .. _creating-integrations: |
|
30 | 30 |
@@ -9,7 +9,7 b' You can set an issue tracker connection ' | |||
|
9 | 9 | * At the |repo| level, you can configure an integration with a different issue |
|
10 | 10 | tracker. |
|
11 | 11 | |
|
12 |
To integrate |RC |
|
|
12 | To integrate |RCE| with an issue tracker, you need to define a regular | |
|
13 | 13 | expression that will fetch the issue ID stored in commit messages, and replace |
|
14 | 14 | it with a URL. This enables |RCE| to generate a link matching each issue to the |
|
15 | 15 | target |repo|. |
@@ -7,7 +7,7 b' Error Message' | |||
|
7 | 7 | Error creating repository repo-name |
|
8 | 8 | |
|
9 | 9 | Cause |
|
10 |
As of |RC |
|
|
10 | As of |RCE| 3.0, a VCS Server is required to run backend operations. | |
|
11 | 11 | |
|
12 | 12 | Solution |
|
13 | 13 | Install a VCS Server. See the `Install a VCS Server`_ section of |RCC| |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | Nix Packaging |
|
4 | 4 | ============= |
|
5 | 5 | |
|
6 |
|RC |
|
|
6 | |RCE| is installed using |Nix Package Manager|. The Nix environment provides | |
|
7 | 7 | the following features for maintenance and deployment: |
|
8 | 8 | |
|
9 | 9 | * Atomic upgrades and rollbacks |
@@ -5,11 +5,11 b'' | |||
|
5 | 5 | |
|
6 | 6 | self: super: { |
|
7 | 7 | "alabaster" = super.buildPythonPackage { |
|
8 |
name = "alabaster-0.7.1 |
|
|
8 | name = "alabaster-0.7.12"; | |
|
9 | 9 | doCheck = false; |
|
10 | 10 | src = fetchurl { |
|
11 |
url = "https://files.pythonhosted.org/packages/ |
|
|
12 | sha256 = "1mvm69xsn5xf1jc45kdq1mn0yq0pfn54mv2jcww4s1vwqx6iyfxn"; | |
|
11 | url = "https://files.pythonhosted.org/packages/cc/b4/ed8dcb0d67d5cfb7f83c4d5463a7614cb1d078ad7ae890c9143edebbf072/alabaster-0.7.12.tar.gz"; | |
|
12 | sha256 = "00nwwjj2d2ym4s2kk217x7jkx1hnczc3fvm8yxbqmsp6b0nxfqd6"; | |
|
13 | 13 | }; |
|
14 | 14 | }; |
|
15 | 15 | "babel" = super.buildPythonPackage { |
@@ -24,11 +24,11 b' self: super: {' | |||
|
24 | 24 | }; |
|
25 | 25 | }; |
|
26 | 26 | "certifi" = super.buildPythonPackage { |
|
27 |
name = "certifi-2018. |
|
|
27 | name = "certifi-2018.11.29"; | |
|
28 | 28 | doCheck = false; |
|
29 | 29 | src = fetchurl { |
|
30 | url = "https://files.pythonhosted.org/packages/e1/0f/f8d5e939184547b3bdc6128551b831a62832713aa98c2ccdf8c47ecc7f17/certifi-2018.8.24.tar.gz"; | |
|
31 | sha256 = "0f0nhrj9mlrf79iway4578wrsgmjh0fmacl9zv8zjckdy7b90rip"; | |
|
30 | url = "https://files.pythonhosted.org/packages/55/54/3ce77783acba5979ce16674fc98b1920d00b01d337cfaaf5db22543505ed/certifi-2018.11.29.tar.gz"; | |
|
31 | sha256 = "1dvccavd2fzq4j37w0sznylp92ps14zi6gvlxzm23in0yhzciya7"; | |
|
32 | 32 | }; |
|
33 | 33 | }; |
|
34 | 34 | "chardet" = super.buildPythonPackage { |
@@ -83,31 +83,31 b' self: super: {' | |||
|
83 | 83 | }; |
|
84 | 84 | }; |
|
85 | 85 | "packaging" = super.buildPythonPackage { |
|
86 |
name = "packaging-1 |
|
|
86 | name = "packaging-18.0"; | |
|
87 | 87 | doCheck = false; |
|
88 | 88 | propagatedBuildInputs = [ |
|
89 | 89 | self."pyparsing" |
|
90 | 90 | self."six" |
|
91 | 91 | ]; |
|
92 | 92 | src = fetchurl { |
|
93 |
url = "https://files.pythonhosted.org/packages/77 |
|
|
94 | sha256 = "0nrpayk8kij1zm9sjnk38ldz3a6705ggvw8ljylqbrb4vmqbf6gh"; | |
|
93 | url = "https://files.pythonhosted.org/packages/cf/50/1f10d2626df0aa97ce6b62cf6ebe14f605f4e101234f7748b8da4138a8ed/packaging-18.0.tar.gz"; | |
|
94 | sha256 = "01wq9c53ix5rz6qg2c98gy8n4ff768rmanifm8m5jpjiaizj51h8"; | |
|
95 | 95 | }; |
|
96 | 96 | }; |
|
97 | 97 | "pygments" = super.buildPythonPackage { |
|
98 |
name = "pygments-2. |
|
|
98 | name = "pygments-2.3.0"; | |
|
99 | 99 | doCheck = false; |
|
100 | 100 | src = fetchurl { |
|
101 |
url = "https://files.pythonhosted.org/packages/ |
|
|
102 | sha256 = "1k78qdvir1yb1c634nkv6rbga8wv4289xarghmsbbvzhvr311bnv"; | |
|
101 | url = "https://files.pythonhosted.org/packages/63/a2/91c31c4831853dedca2a08a0f94d788fc26a48f7281c99a303769ad2721b/Pygments-2.3.0.tar.gz"; | |
|
102 | sha256 = "1z34ms51dh4jq4h3cizp7vd1dmsxcbvffkjsd2xxfav22nn6lrl2"; | |
|
103 | 103 | }; |
|
104 | 104 | }; |
|
105 | 105 | "pyparsing" = super.buildPythonPackage { |
|
106 |
name = "pyparsing-2. |
|
|
106 | name = "pyparsing-2.3.0"; | |
|
107 | 107 | doCheck = false; |
|
108 | 108 | src = fetchurl { |
|
109 |
url = "https://files.pythonhosted.org/packages/3 |
|
|
110 | sha256 = "016b9gh606aa44sq92jslm89bg874ia0yyiyb643fa6dgbsbqch8"; | |
|
109 | url = "https://files.pythonhosted.org/packages/d0/09/3e6a5eeb6e04467b737d55f8bba15247ac0876f98fae659e58cd744430c6/pyparsing-2.3.0.tar.gz"; | |
|
110 | sha256 = "14k5v7n3xqw8kzf42x06bzp184spnlkya2dpjyflax6l3yrallzk"; | |
|
111 | 111 | }; |
|
112 | 112 | }; |
|
113 | 113 | "pytz" = super.buildPythonPackage { |
@@ -119,7 +119,7 b' self: super: {' | |||
|
119 | 119 | }; |
|
120 | 120 | }; |
|
121 | 121 | "requests" = super.buildPythonPackage { |
|
122 |
name = "requests-2. |
|
|
122 | name = "requests-2.20.1"; | |
|
123 | 123 | doCheck = false; |
|
124 | 124 | propagatedBuildInputs = [ |
|
125 | 125 | self."chardet" |
@@ -128,16 +128,16 b' self: super: {' | |||
|
128 | 128 | self."certifi" |
|
129 | 129 | ]; |
|
130 | 130 | src = fetchurl { |
|
131 |
url = "https://files.pythonhosted.org/packages/54 |
|
|
132 | sha256 = "0snf8xxdzsgh1x2zv3vilvbrv9jbpmnfagzzb1rjmmvflckdh8pc"; | |
|
131 | url = "https://files.pythonhosted.org/packages/40/35/298c36d839547b50822985a2cf0611b3b978a5ab7a5af5562b8ebe3e1369/requests-2.20.1.tar.gz"; | |
|
132 | sha256 = "0qzj6cgv3k9wyj7wlxgz7xq0cfg4jbbkfm24pp8dnhczwl31527a"; | |
|
133 | 133 | }; |
|
134 | 134 | }; |
|
135 | 135 | "setuptools" = super.buildPythonPackage { |
|
136 |
name = "setuptools-40.2 |
|
|
136 | name = "setuptools-40.6.2"; | |
|
137 | 137 | doCheck = false; |
|
138 | 138 | src = fetchurl { |
|
139 |
url = "https://files.pythonhosted.org/packages/ |
|
|
140 | sha256 = "19ng5m7kigllg3x96c91y3a2k28g6kwnbb1v4warrnp4xma1v227"; | |
|
139 | url = "https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip"; | |
|
140 | sha256 = "0r2c5hapirlzm34h7pl1lgkm6gk7bcrlrdj28qgsvaqg3f74vfw6"; | |
|
141 | 141 | }; |
|
142 | 142 | }; |
|
143 | 143 | "six" = super.buildPythonPackage { |
@@ -157,7 +157,7 b' self: super: {' | |||
|
157 | 157 | }; |
|
158 | 158 | }; |
|
159 | 159 | "sphinx" = super.buildPythonPackage { |
|
160 |
name = "sphinx-1. |
|
|
160 | name = "sphinx-1.8.2"; | |
|
161 | 161 | doCheck = false; |
|
162 | 162 | propagatedBuildInputs = [ |
|
163 | 163 | self."six" |
@@ -175,8 +175,8 b' self: super: {' | |||
|
175 | 175 | self."typing" |
|
176 | 176 | ]; |
|
177 | 177 | src = fetchurl { |
|
178 |
url = "https://files.pythonhosted.org/packages/ |
|
|
179 | sha256 = "1ryz0w4c31930f1br2sjwrxwx9cmsy7cqdb0d81g98n9bj250w50"; | |
|
178 | url = "https://files.pythonhosted.org/packages/4c/ea/7388faba7cf02999e1bc42f6a8eb1ea0120aec3dd93474cee21cea2d693f/Sphinx-1.8.2.tar.gz"; | |
|
179 | sha256 = "1sia2h5rfzy76rbsd69ghr8bbidhsjzzinf3f523dcmivp5k41qj"; | |
|
180 | 180 | }; |
|
181 | 181 | }; |
|
182 | 182 | "sphinx-rtd-theme" = super.buildPythonPackage { |
@@ -207,11 +207,11 b' self: super: {' | |||
|
207 | 207 | }; |
|
208 | 208 | }; |
|
209 | 209 | "urllib3" = super.buildPythonPackage { |
|
210 |
name = "urllib3-1.2 |
|
|
210 | name = "urllib3-1.24.1"; | |
|
211 | 211 | doCheck = false; |
|
212 | 212 | src = fetchurl { |
|
213 |
url = "https://files.pythonhosted.org/packages/ |
|
|
214 | sha256 = "1bvbd35q3zdcd7gsv38fwpizy7p06dr0154g5gfybrvnbvhwb2m6"; | |
|
213 | url = "https://files.pythonhosted.org/packages/b1/53/37d82ab391393565f2f831b8eedbffd57db5a718216f82f1a8b4d381a1c1/urllib3-1.24.1.tar.gz"; | |
|
214 | sha256 = "08lwd9f3hqznyf32vnzwvp87pchx062nkbgyrf67rwlkgj0jk5fy"; | |
|
215 | 215 | }; |
|
216 | 216 | }; |
|
217 | 217 |
@@ -1,7 +1,7 b'' | |||
|
1 | 1 | |RCE| 3.0.0 |RNS| |
|
2 | 2 | ----------------- |
|
3 | 3 | |
|
4 |
As |RC |
|
|
4 | As |RCE| 3.0 is a big release, the release notes have been split into the following sections: | |
|
5 | 5 | |
|
6 | 6 | * :ref:`general-rn-ref` |
|
7 | 7 | * :ref:`security-rn-ref` |
@@ -9,6 +9,7 b' Release Notes' | |||
|
9 | 9 | .. toctree:: |
|
10 | 10 | :maxdepth: 1 |
|
11 | 11 | |
|
12 | release-notes-4.15.0.rst | |
|
12 | 13 | release-notes-4.14.1.rst |
|
13 | 14 | release-notes-4.14.0.rst |
|
14 | 15 | release-notes-4.13.3.rst |
@@ -1,8 +1,8 b'' | |||
|
1 |
sphinx==1. |
|
|
1 | sphinx==1.8.2 | |
|
2 | 2 | six==1.11.0 |
|
3 | 3 | sphinx_rtd_theme==0.4.1 |
|
4 | 4 | docutils==0.14.0 |
|
5 |
pygments==2. |
|
|
5 | pygments==2.3.0 | |
|
6 | 6 | markupsafe==1.0.0 |
|
7 | 7 | jinja2==2.9.6 |
|
8 | 8 | pytz==2018.4 |
@@ -44,10 +44,10 b' following example:' | |||
|
44 | 44 | Installing |RCT| |
|
45 | 45 | ^^^^^^^^^^^^^^^^ |
|
46 | 46 | |
|
47 |
|RCT| enable you to automate many of the most common |RC |
|
|
47 | |RCT| enable you to automate many of the most common |RCE| functions through | |
|
48 | 48 | the API. Installing them on a local machine lets you carry out maintenance on |
|
49 | 49 | the server remotely. Once installed you can use them to index your |repos| |
|
50 |
to setup full-text search, strip commits, or install |
|
|
50 | to setup full-text search, strip commits, or install RhodeCode Extensions for | |
|
51 | 51 | additional functionality. |
|
52 | 52 | |
|
53 | 53 | For more detailed instructions about using |RCT| for indexing and full-text |
@@ -3,7 +3,7 b'' | |||
|
3 | 3 | |RCT| |
|
4 | 4 | ===== |
|
5 | 5 | |
|
6 |
|RCT| enable you to automate many of the most common |RC |
|
|
6 | |RCT| enable you to automate many of the most common |RCE| functions through | |
|
7 | 7 | the API. |
|
8 | 8 | |
|
9 | 9 | .. toctree:: |
@@ -16,7 +16,7 b' rhodecode-tools' | |||
|
16 | 16 | --------------- |
|
17 | 17 | |
|
18 | 18 | Use |RCT| to setup automation, run the indexer, and install extensions for |
|
19 |
your |RC |
|
|
19 | your |RCE| instances. Options: | |
|
20 | 20 | |
|
21 | 21 | .. rst-class:: dl-horizontal |
|
22 | 22 | |
@@ -49,7 +49,7 b' Example usage:' | |||
|
49 | 49 | rhodecode-api |
|
50 | 50 | ------------- |
|
51 | 51 | |
|
52 |
The |
|
|
52 | The RhodeCode API lets you connect to |RCE| and carry out management tasks from a | |
|
53 | 53 | remote machine, for more information about the API, see the :ref:`api`. To |
|
54 | 54 | pass arguments on the command-line use the ``method:option`` syntax. |
|
55 | 55 | |
@@ -117,7 +117,7 b' Options:' | |||
|
117 | 117 | rhodecode-cleanup-gists |
|
118 | 118 | ----------------------- |
|
119 | 119 | |
|
120 |
Use this to delete gists within |RC |
|
|
120 | Use this to delete gists within |RCE|. Options: | |
|
121 | 121 | |
|
122 | 122 | .. rst-class:: dl-horizontal |
|
123 | 123 | |
@@ -166,7 +166,7 b' Example usage:' | |||
|
166 | 166 | rhodecode-cleanup-repos |
|
167 | 167 | ----------------------- |
|
168 | 168 | |
|
169 |
Use this to manage |repos| and |repo| groups within |RC |
|
|
169 | Use this to manage |repos| and |repo| groups within |RCE|. Options: | |
|
170 | 170 | |
|
171 | 171 | .. rst-class:: dl-horizontal |
|
172 | 172 | |
@@ -280,7 +280,7 b' the using :ref:`integrations-rcextension' | |||
|
280 | 280 | rhodecode-gist |
|
281 | 281 | -------------- |
|
282 | 282 | |
|
283 |
Use this to create, list, show, or delete gists within |RC |
|
|
283 | Use this to create, list, show, or delete gists within |RCE|. Options: | |
|
284 | 284 | |
|
285 | 285 | .. rst-class:: dl-horizontal |
|
286 | 286 |
@@ -7,7 +7,7 b' To install |RCT| correctly, see the inst' | |||
|
7 | 7 | :ref:`install-tools`, and :ref:`config-rhoderc`. |
|
8 | 8 | |
|
9 | 9 | Once |RCT| is installed, and the :file:`/home/{user}/.rhoderc` file is |
|
10 |
configured you can then use |RCT| on each |RC |
|
|
10 | configured you can then use |RCT| on each |RCE| instance to carry out admin | |
|
11 | 11 | tasks. Use the following example to configure that file, |
|
12 | 12 | and once configured see the :ref:`tools-cli` for more details. |
|
13 | 13 |
@@ -95,10 +95,10 b' but below is the example shortcut.' | |||
|
95 | 95 | |
|
96 | 96 | # Check that the script is uploaded to your home directory |
|
97 | 97 | $ ls -1 |
|
98 | RhodeCode-installer-linux-391_b1a804c4d69b_d6c087d520e3 | |
|
98 | RhodeCode-installer-linux-buildYYYYXXXX_ZZZZ | |
|
99 | 99 | |
|
100 | 100 | # Change the script permissions |
|
101 |
$ chmod |
|
|
101 | $ chmod +x RhodeCode-installer-linux* | |
|
102 | 102 | |
|
103 | 103 | # Run the installer and accept the prompts |
|
104 | 104 | $ ./RhodeCode-installer-linux-* |
@@ -7,13 +7,13 b'' | |||
|
7 | 7 | Git Large File Storage (or LFS) is a new, open-source extension to Git that |
|
8 | 8 | aims to improve handling of large files. It does this by replacing large files |
|
9 | 9 | in your repository—such as graphics and videos—with simple text pointers. |
|
10 |
|
|
|
10 | RhodeCode Server includes an embedded LFS object store server, allowing storage of | |
|
11 | 11 | large files without the need for an external object store. |
|
12 | 12 | Git LFS is disabled by default, globally, and for each individual repository. |
|
13 | 13 | |
|
14 | 14 | .. note:: |
|
15 | 15 | |
|
16 |
|
|
|
16 | RhodeCode implements V2 API of Git LFS. Please make sure your git client is | |
|
17 | 17 | using the latest version (2.0.X recommended) to leverage full feature set |
|
18 | 18 | of the V2 API. |
|
19 | 19 | |
@@ -22,7 +22,7 b' Git LFS is disabled by default, globally' | |||
|
22 | 22 | Enabling Git LFS |
|
23 | 23 | ++++++++++++++++ |
|
24 | 24 | |
|
25 |
Git LFS is disabled by default within |
|
|
25 | Git LFS is disabled by default within RhodeCode Server. | |
|
26 | 26 | |
|
27 | 27 | To enable Git LFS Globally: |
|
28 | 28 | |
@@ -87,7 +87,7 b' size in bytes. For example::' | |||
|
87 | 87 | |
|
88 | 88 | |
|
89 | 89 | The object itself will be uploaded to a separate location via the Git LFS Batch API. |
|
90 |
The transfer is validated and authorized by |
|
|
90 | The transfer is validated and authorized by RhodeCode server itself. | |
|
91 | 91 | |
|
92 | 92 | If give repository has Git LFS disabled, a proper message will be sent back to |
|
93 | 93 | the client and upload of LFS objects will be forbidden. |
@@ -13,7 +13,7 b' of the current revision. This saves both' | |||
|
13 | 13 | Enabling HG Largefiles |
|
14 | 14 | ++++++++++++++++++++++ |
|
15 | 15 | |
|
16 |
Mercurial Largefiles extension is disabled by default within |
|
|
16 | Mercurial Largefiles extension is disabled by default within RhodeCode Server. | |
|
17 | 17 | |
|
18 | 18 | To enable Mercurial Largefiles Globally: |
|
19 | 19 |
@@ -25,7 +25,7 b' Pre-requisites' | |||
|
25 | 25 | * For MySQL, do not use `localhost` in the database connection string of the |
|
26 | 26 | :file:`rhodecode.ini` file. |
|
27 | 27 | * InnoDB must be the database tables engine. |
|
28 |
* Contact |
|
|
28 | * Contact RhodeCode for a new licence Key/Token pair. If you don't, a trial licence | |
|
29 | 29 | will be applied so you are not locked out of the upgraded instance. |
|
30 | 30 | |
|
31 | 31 | You can find the specific instructions to carry out these pre-requisite steps |
@@ -3,19 +3,19 b'' | |||
|
3 | 3 | Getting Started with VCS |
|
4 | 4 | ------------------------ |
|
5 | 5 | |
|
6 |
When using |RC |
|
|
6 | When using |RCE|, you will be working with |git|, |svn| or |hg| |repos| from the | |
|
7 | 7 | command line or using a GUI client such as Tortoise, Tower or SourceTree. |
|
8 | 8 | |
|
9 |
|RC |
|
|
9 | |RCE| uses a standard |git|, |svn| and |hg| protocols. So all tools that | |
|
10 | 10 | can interact with there protocols are supported, including Eclipse or PyCharm |
|
11 | 11 | plugins. |
|
12 | 12 | |
|
13 | 13 | |
|
14 | 14 | If you have never used either before, the following information should |
|
15 | 15 | help you set up your local machine so that you can sync changes with the |
|
16 |
|RC |
|
|
16 | |RCE| server. | |
|
17 | 17 | |
|
18 |
All of the following instructions assume you have a |RC |
|
|
18 | All of the following instructions assume you have a |RCE| account, | |
|
19 | 19 | and you can access your |repos| from the web interface. |
|
20 | 20 | |
|
21 | 21 | .. note:: |
@@ -3,14 +3,14 b' File Editing' | |||
|
3 | 3 | |
|
4 | 4 | To edit files using the online editor, use the following steps. |
|
5 | 5 | |
|
6 |
1. From the |RC |
|
|
6 | 1. From the |RCE| interface, select :menuselection:`Admin --> Repositories` | |
|
7 | 7 | 2. Select the |repo| in which you want to edit a file. |
|
8 | 8 | 3. Select the :guilabel:`file` view of the |repo|, and double-click on the file. |
|
9 | 9 | 4. To open the editor, select the :guilabel:`edit on branch:default` button. |
|
10 | 10 | |
|
11 |
* If the filename has an extension |RC |
|
|
11 | * If the filename has an extension |RCE| recognises, | |
|
12 | 12 | the syntax highlighting will appear automatically. |
|
13 |
* If the filename does not have an extension |RC |
|
|
13 | * If the filename does not have an extension |RCE| recognises, | |
|
14 | 14 | you can set the language syntax highlighter by |
|
15 | 15 | choosing from the file type drop down menu. |
|
16 | 16 | 5. To save your changes, select :guilabel:`Commit changes` |
@@ -4,7 +4,7 b' Gist Editing' | |||
|
4 | 4 | ^^^^^^^^^^^^ |
|
5 | 5 | |
|
6 | 6 | Gists are standalone files that only the creator can edit. To work with |
|
7 |
gists, click on the :guilabel:`Gists` tab on the |RC |
|
|
7 | gists, click on the :guilabel:`Gists` tab on the |RCE| header. The gist | |
|
8 | 8 | editor also has syntax highlighting. |
|
9 | 9 | |
|
10 | 10 | You can set the following properties for each gist: |
@@ -13,7 +13,7 b' You can set the following properties for' | |||
|
13 | 13 | and will show up in searches. |
|
14 | 14 | * :guilabel:`Gist Lifetime`: You can set a gist to expire after a set |
|
15 | 15 | period by using the :guilabel:`Gist Lifetime` dropdown menu. |
|
16 |
This means that when the gist expires it will be deleted from the |RC |
|
|
16 | This means that when the gist expires it will be deleted from the |RCE| | |
|
17 | 17 | gist database. |
|
18 | 18 | * :guilabel:`Private`: This means that the gist will not show up in searches. |
|
19 | 19 | * :guilabel:`Gist access level`: If you create a private gist you can have |
@@ -1,7 +1,7 b'' | |||
|
1 | 1 | Online Editing |
|
2 | 2 | -------------- |
|
3 | 3 | |
|
4 |
|RC |
|
|
4 | |RCE| has an integrated online editor, allowing you to edit files in the | |
|
5 | 5 | browser. The online editor has syntax highlighting and the ability to fork, |
|
6 | 6 | merge, and commit changes to files. |
|
7 | 7 |
@@ -13,13 +13,13 b' let' | |||
|
13 | 13 | sha512 = "tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA=="; |
|
14 | 14 | }; |
|
15 | 15 | }; |
|
16 |
"@polymer/iron-a11y-announcer-3.0. |
|
|
16 | "@polymer/iron-a11y-announcer-3.0.2" = { | |
|
17 | 17 | name = "_at_polymer_slash_iron-a11y-announcer"; |
|
18 | 18 | packageName = "@polymer/iron-a11y-announcer"; |
|
19 |
version = "3.0. |
|
|
20 | src = fetchurl { | |
|
21 |
url = "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.0. |
|
|
22 | sha512 = "Xiqmpz0AEEbMNGYPpbrXBIrcI/xaR4tn77pmSLfxVKGGwjEUR/YrRgyIwXp4EN7lvst1dFC8kyl2hLga0uDIVQ=="; | |
|
19 | version = "3.0.2"; | |
|
20 | src = fetchurl { | |
|
21 | url = "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.0.2.tgz"; | |
|
22 | sha512 = "LqnMF39mXyxSSRbTHRzGbcJS8nU0NVTo2raBOgOlpxw5yfGJUVcwaTJ/qy5NtWCZLRfa4suycf0oAkuUjHTXHQ=="; | |
|
23 | 23 | }; |
|
24 | 24 | }; |
|
25 | 25 | "@polymer/iron-a11y-keys-3.0.1" = { |
@@ -229,13 +229,13 b' let' | |||
|
229 | 229 | sha1 = "e7365648c1b42136a59c7d5040637b3b5c83b614"; |
|
230 | 230 | }; |
|
231 | 231 | }; |
|
232 |
"@types/node-6.14. |
|
|
232 | "@types/node-6.14.2" = { | |
|
233 | 233 | name = "_at_types_slash_node"; |
|
234 | 234 | packageName = "@types/node"; |
|
235 |
version = "6.14. |
|
|
236 | src = fetchurl { | |
|
237 |
url = "https://registry.npmjs.org/@types/node/-/node-6.14. |
|
|
238 | sha512 = "6tQyh4Q4B5pECcXBOQDZ5KjyBIxRZGzrweGPM47sAYTdVG4+7R+2EGMTmp0h6ZwgqHrFRCeg2gdhsG9xXEl2Sg=="; | |
|
235 | version = "6.14.2"; | |
|
236 | src = fetchurl { | |
|
237 | url = "https://registry.npmjs.org/@types/node/-/node-6.14.2.tgz"; | |
|
238 | sha512 = "JWB3xaVfsfnFY8Ofc9rTB/op0fqqTSqy4vBcVk1LuRJvta7KTX+D//fCkiTMeLGhdr2EbFZzQjC97gvmPilk9Q=="; | |
|
239 | 239 | }; |
|
240 | 240 | }; |
|
241 | 241 | "@types/parse5-2.2.34" = { |
@@ -409,22 +409,22 b' let' | |||
|
409 | 409 | sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA=="; |
|
410 | 410 | }; |
|
411 | 411 | }; |
|
412 |
"@webcomponents/shadycss-1. |
|
|
412 | "@webcomponents/shadycss-1.6.0" = { | |
|
413 | 413 | name = "_at_webcomponents_slash_shadycss"; |
|
414 | 414 | packageName = "@webcomponents/shadycss"; |
|
415 |
version = "1. |
|
|
416 | src = fetchurl { | |
|
417 |
url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1. |
|
|
418 | sha512 = "0OyrmVc7S+INtzoqP2ofAo+OdVn2Nj0Qvq4wD9FEGN7nMmLRxaD2mzy6hD6EslzxUSuGH302CDU4KXiY66SEqg=="; | |
|
419 | }; | |
|
420 | }; | |
|
421 |
"@webcomponents/webcomponentsjs-2.1 |
|
|
415 | version = "1.6.0"; | |
|
416 | src = fetchurl { | |
|
417 | url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.6.0.tgz"; | |
|
418 | sha512 = "iURGZZU6BaiRJtGgjMn208QxPkY11QwT/VmuHNa4Yb+kJxU/WODe4C8b0LDOtnk4KJzJg50hCfwvPRAjePEzbA=="; | |
|
419 | }; | |
|
420 | }; | |
|
421 | "@webcomponents/webcomponentsjs-2.2.1" = { | |
|
422 | 422 | name = "_at_webcomponents_slash_webcomponentsjs"; |
|
423 | 423 | packageName = "@webcomponents/webcomponentsjs"; |
|
424 |
version = "2.1 |
|
|
425 | src = fetchurl { | |
|
426 |
url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.1 |
|
|
427 | sha512 = "0UHJNY88lR3pnEYtBVT7F8cuuxOiITQGWJa0LxoELqkBSB7IabzJFOj5K99PajD3CGAsWpjB0CAeijfe376Y1w=="; | |
|
424 | version = "2.2.1"; | |
|
425 | src = fetchurl { | |
|
426 | url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.1.tgz"; | |
|
427 | sha512 = "lZZ+Lkke6JhsJcQQqSVk1Pny6/8y4qhJ98LO7a/MwBSRO8WqHqK1X2vscfeL8vOnYGFnmBUyVG95lwYv/AXyLQ=="; | |
|
428 | 428 | }; |
|
429 | 429 | }; |
|
430 | 430 | "@xtuc/ieee754-1.2.0" = { |
@@ -499,13 +499,13 b' let' | |||
|
499 | 499 | sha1 = "82ffb02b29e662ae53bdc20af15947706739c536"; |
|
500 | 500 | }; |
|
501 | 501 | }; |
|
502 |
"ajv-6. |
|
|
502 | "ajv-6.6.1" = { | |
|
503 | 503 | name = "ajv"; |
|
504 | 504 | packageName = "ajv"; |
|
505 |
version = "6. |
|
|
506 | src = fetchurl { | |
|
507 |
url = "https://registry.npmjs.org/ajv/-/ajv-6. |
|
|
508 | sha512 = "4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg=="; | |
|
505 | version = "6.6.1"; | |
|
506 | src = fetchurl { | |
|
507 | url = "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz"; | |
|
508 | sha512 = "ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww=="; | |
|
509 | 509 | }; |
|
510 | 510 | }; |
|
511 | 511 | "ajv-keywords-3.2.0" = { |
@@ -1454,13 +1454,13 b' let' | |||
|
1454 | 1454 | sha512 = "DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg=="; |
|
1455 | 1455 | }; |
|
1456 | 1456 | }; |
|
1457 |
"bluebird-3.5. |
|
|
1457 | "bluebird-3.5.3" = { | |
|
1458 | 1458 | name = "bluebird"; |
|
1459 | 1459 | packageName = "bluebird"; |
|
1460 |
version = "3.5. |
|
|
1461 | src = fetchurl { | |
|
1462 |
url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5. |
|
|
1463 | sha512 = "dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg=="; | |
|
1460 | version = "3.5.3"; | |
|
1461 | src = fetchurl { | |
|
1462 | url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz"; | |
|
1463 | sha512 = "/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="; | |
|
1464 | 1464 | }; |
|
1465 | 1465 | }; |
|
1466 | 1466 | "bn.js-4.11.8" = { |
@@ -1661,13 +1661,13 b' let' | |||
|
1661 | 1661 | sha1 = "9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"; |
|
1662 | 1662 | }; |
|
1663 | 1663 | }; |
|
1664 |
"camelcase- |
|
|
1664 | "camelcase-5.0.0" = { | |
|
1665 | 1665 | name = "camelcase"; |
|
1666 | 1666 | packageName = "camelcase"; |
|
1667 |
version = " |
|
|
1668 | src = fetchurl { | |
|
1669 |
url = "https://registry.npmjs.org/camelcase/-/camelcase- |
|
|
1670 | sha1 = "d545635be1e33c542649c69173e5de6acfae34dd"; | |
|
1667 | version = "5.0.0"; | |
|
1668 | src = fetchurl { | |
|
1669 | url = "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz"; | |
|
1670 | sha512 = "faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA=="; | |
|
1671 | 1671 | }; |
|
1672 | 1672 | }; |
|
1673 | 1673 | "caniuse-api-1.6.1" = { |
@@ -1679,22 +1679,22 b' let' | |||
|
1679 | 1679 | sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"; |
|
1680 | 1680 | }; |
|
1681 | 1681 | }; |
|
1682 |
"caniuse-db-1.0.300009 |
|
|
1682 | "caniuse-db-1.0.30000912" = { | |
|
1683 | 1683 | name = "caniuse-db"; |
|
1684 | 1684 | packageName = "caniuse-db"; |
|
1685 |
version = "1.0.300009 |
|
|
1686 | src = fetchurl { | |
|
1687 |
url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.300009 |
|
|
1688 | sha512 = "fvicVRDlhHIQpt/bmbLl3hDHKUZb5ZP8O2OuZLz2fSEPlUBbvwwbhhqhGS617ldN6bDoo9A3+MQKQyFq0p7UXA=="; | |
|
1689 | }; | |
|
1690 | }; | |
|
1691 |
"caniuse-lite-1.0.300009 |
|
|
1685 | version = "1.0.30000912"; | |
|
1686 | src = fetchurl { | |
|
1687 | url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000912.tgz"; | |
|
1688 | sha512 = "uiepPdHcJ06Na9t15L5l+pp3NWQU4IETbmleghD6tqCqbIYqhHSu7nVfbK2gqPjfy+9jl/wHF1UQlyTszh9tJQ=="; | |
|
1689 | }; | |
|
1690 | }; | |
|
1691 | "caniuse-lite-1.0.30000912" = { | |
|
1692 | 1692 | name = "caniuse-lite"; |
|
1693 | 1693 | packageName = "caniuse-lite"; |
|
1694 |
version = "1.0.300009 |
|
|
1695 | src = fetchurl { | |
|
1696 |
url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.300009 |
|
|
1697 | sha512 = "xDVs8pBFr6bzq9pXUkLKpGQQnzsF/l6/yX38UnCkTcUcwC0rDl1NGZGildcJVTU+uGBxfsyniK/ZWagPNn1Oqw=="; | |
|
1694 | version = "1.0.30000912"; | |
|
1695 | src = fetchurl { | |
|
1696 | url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000912.tgz"; | |
|
1697 | sha512 = "M3zAtV36U+xw5mMROlTXpAHClmPAor6GPKAMD5Yi7glCB5sbMPFtnQ3rGpk4XqPdUrrTIaVYSJZxREZWNy8QJg=="; | |
|
1698 | 1698 | }; |
|
1699 | 1699 | }; |
|
1700 | 1700 | "caseless-0.12.0" = { |
@@ -1814,13 +1814,13 b' let' | |||
|
1814 | 1814 | sha1 = "22817534f24bfa4950c34d532d48ecbc621b8c14"; |
|
1815 | 1815 | }; |
|
1816 | 1816 | }; |
|
1817 |
"clipboard-2.0. |
|
|
1817 | "clipboard-2.0.4" = { | |
|
1818 | 1818 | name = "clipboard"; |
|
1819 | 1819 | packageName = "clipboard"; |
|
1820 |
version = "2.0. |
|
|
1821 | src = fetchurl { | |
|
1822 |
url = "https://registry.npmjs.org/clipboard/-/clipboard-2.0. |
|
|
1823 | sha512 = "7yhQBmtN+uYZmfRjjVjKa0dZdWuabzpSKGtyQZN+9C8xlC788SSJjOHWh7tzurfwTqTD5UDYAhIv5fRJg3sHjQ=="; | |
|
1820 | version = "2.0.4"; | |
|
1821 | src = fetchurl { | |
|
1822 | url = "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz"; | |
|
1823 | sha512 = "Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ=="; | |
|
1824 | 1824 | }; |
|
1825 | 1825 | }; |
|
1826 | 1826 | "cliui-2.1.0" = { |
@@ -2093,13 +2093,13 b' let' | |||
|
2093 | 2093 | sha1 = "676f6eb3c39997c2ee1ac3a924fd6124748f578d"; |
|
2094 | 2094 | }; |
|
2095 | 2095 | }; |
|
2096 |
"copy-webpack-plugin-4. |
|
|
2096 | "copy-webpack-plugin-4.6.0" = { | |
|
2097 | 2097 | name = "copy-webpack-plugin"; |
|
2098 | 2098 | packageName = "copy-webpack-plugin"; |
|
2099 |
version = "4. |
|
|
2100 | src = fetchurl { | |
|
2101 |
url = "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4. |
|
|
2102 | sha512 = "0lstlEyj74OAtYMrDxlNZsU7cwFijAI3Ofz2fD6Mpo9r4xCv4yegfa3uHIKvZY1NSuOtE9nvG6TAhJ+uz9gDaQ=="; | |
|
2099 | version = "4.6.0"; | |
|
2100 | src = fetchurl { | |
|
2101 | url = "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz"; | |
|
2102 | sha512 = "Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA=="; | |
|
2103 | 2103 | }; |
|
2104 | 2104 | }; |
|
2105 | 2105 | "core-js-2.5.7" = { |
@@ -2201,13 +2201,13 b' let' | |||
|
2201 | 2201 | sha1 = "2b3a110539c5355f1cd8d314623e870b121ec858"; |
|
2202 | 2202 | }; |
|
2203 | 2203 | }; |
|
2204 |
"css-selector-tokenizer-0.7. |
|
|
2204 | "css-selector-tokenizer-0.7.1" = { | |
|
2205 | 2205 | name = "css-selector-tokenizer"; |
|
2206 | 2206 | packageName = "css-selector-tokenizer"; |
|
2207 |
version = "0.7. |
|
|
2208 | src = fetchurl { | |
|
2209 |
url = "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7. |
|
|
2210 | sha1 = "e6988474ae8c953477bf5e7efecfceccd9cf4c86"; | |
|
2207 | version = "0.7.1"; | |
|
2208 | src = fetchurl { | |
|
2209 | url = "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz"; | |
|
2210 | sha512 = "xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA=="; | |
|
2211 | 2211 | }; |
|
2212 | 2212 | }; |
|
2213 | 2213 | "css-what-2.1.2" = { |
@@ -2318,15 +2318,6 b' let' | |||
|
2318 | 2318 | sha1 = "f6534d15148269b20352e7bee26f501f9a191290"; |
|
2319 | 2319 | }; |
|
2320 | 2320 | }; |
|
2321 | "decamelize-2.0.0" = { | |
|
2322 | name = "decamelize"; | |
|
2323 | packageName = "decamelize"; | |
|
2324 | version = "2.0.0"; | |
|
2325 | src = fetchurl { | |
|
2326 | url = "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz"; | |
|
2327 | sha512 = "Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg=="; | |
|
2328 | }; | |
|
2329 | }; | |
|
2330 | 2321 | "decode-uri-component-0.2.0" = { |
|
2331 | 2322 | name = "decode-uri-component"; |
|
2332 | 2323 | packageName = "decode-uri-component"; |
@@ -2561,13 +2552,13 b' let' | |||
|
2561 | 2552 | sha1 = "3a83a904e54353287874c564b7549386849a98c9"; |
|
2562 | 2553 | }; |
|
2563 | 2554 | }; |
|
2564 |
"electron-to-chromium-1.3.8 |
|
|
2555 | "electron-to-chromium-1.3.85" = { | |
|
2565 | 2556 | name = "electron-to-chromium"; |
|
2566 | 2557 | packageName = "electron-to-chromium"; |
|
2567 |
version = "1.3.8 |
|
|
2568 | src = fetchurl { | |
|
2569 |
url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.8 |
|
|
2570 | sha512 = "NI4nB2IWGcU4JVT1AE8kBb/dFor4zjLHMLsOROPahppeHrR0FG5uslxMmkp/thO1MvPjM2xhlKoY29/I60s0ew=="; | |
|
2558 | version = "1.3.85"; | |
|
2559 | src = fetchurl { | |
|
2560 | url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.85.tgz"; | |
|
2561 | sha512 = "kWSDVVF9t3mft2OHVZy4K85X2beP6c6mFm3teFS/mLSDJpQwuFIWHrULCX+w6H1E55ZYmFRlT+ATAFRwhrYzsw=="; | |
|
2571 | 2562 | }; |
|
2572 | 2563 | }; |
|
2573 | 2564 | "elliptic-6.4.1" = { |
@@ -2912,13 +2903,13 b' let' | |||
|
2912 | 2903 | sha1 = "d5142c0caee6b1189f87d3a76111064f86c8bbf2"; |
|
2913 | 2904 | }; |
|
2914 | 2905 | }; |
|
2915 |
"fastparse-1.1. |
|
|
2906 | "fastparse-1.1.2" = { | |
|
2916 | 2907 | name = "fastparse"; |
|
2917 | 2908 | packageName = "fastparse"; |
|
2918 |
version = "1.1. |
|
|
2919 | src = fetchurl { | |
|
2920 |
url = "https://registry.npmjs.org/fastparse/-/fastparse-1.1. |
|
|
2921 | sha1 = "d1e2643b38a94d7583b479060e6c4affc94071f8"; | |
|
2909 | version = "1.1.2"; | |
|
2910 | src = fetchurl { | |
|
2911 | url = "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz"; | |
|
2912 | sha512 = "483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ=="; | |
|
2922 | 2913 | }; |
|
2923 | 2914 | }; |
|
2924 | 2915 | "favico.js-0.3.10" = { |
@@ -3308,13 +3299,13 b' let' | |||
|
3308 | 3299 | sha1 = "15a4806a57547cb2d2dbf27f42e89a8c3451b364"; |
|
3309 | 3300 | }; |
|
3310 | 3301 | }; |
|
3311 |
"graceful-fs-4.1.1 |
|
|
3302 | "graceful-fs-4.1.15" = { | |
|
3312 | 3303 | name = "graceful-fs"; |
|
3313 | 3304 | packageName = "graceful-fs"; |
|
3314 |
version = "4.1.1 |
|
|
3315 | src = fetchurl { | |
|
3316 |
url = "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.1 |
|
|
3317 | sha1 = "0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"; | |
|
3305 | version = "4.1.15"; | |
|
3306 | src = fetchurl { | |
|
3307 | url = "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz"; | |
|
3308 | sha512 = "6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="; | |
|
3318 | 3309 | }; |
|
3319 | 3310 | }; |
|
3320 | 3311 | "grunt-0.4.5" = { |
@@ -3326,13 +3317,13 b' let' | |||
|
3326 | 3317 | sha1 = "56937cd5194324adff6d207631832a9d6ba4e7f0"; |
|
3327 | 3318 | }; |
|
3328 | 3319 | }; |
|
3329 |
"grunt-cli-1.3. |
|
|
3320 | "grunt-cli-1.3.2" = { | |
|
3330 | 3321 | name = "grunt-cli"; |
|
3331 | 3322 | packageName = "grunt-cli"; |
|
3332 |
version = "1.3. |
|
|
3333 | src = fetchurl { | |
|
3334 |
url = "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3. |
|
|
3335 | sha512 = "UwBRu/QpAjDc53DRLEkyilFdL0zenpxu+fddTIlsF/KJqdNcHaQmvyu1W3cDesZ9rqqZdKK5A8+QDIyLUEWoZQ=="; | |
|
3323 | version = "1.3.2"; | |
|
3324 | src = fetchurl { | |
|
3325 | url = "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz"; | |
|
3326 | sha512 = "8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ=="; | |
|
3336 | 3327 | }; |
|
3337 | 3328 | }; |
|
3338 | 3329 | "grunt-contrib-concat-0.5.1" = { |
@@ -4631,13 +4622,13 b' let' | |||
|
4631 | 4622 | sha1 = "6d4524e8b955f95d4f5b58851ce21dd72fb4e952"; |
|
4632 | 4623 | }; |
|
4633 | 4624 | }; |
|
4634 |
"lru-cache-4.1. |
|
|
4625 | "lru-cache-4.1.5" = { | |
|
4635 | 4626 | name = "lru-cache"; |
|
4636 | 4627 | packageName = "lru-cache"; |
|
4637 |
version = "4.1. |
|
|
4638 | src = fetchurl { | |
|
4639 |
url = "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1. |
|
|
4640 | sha512 = "fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA=="; | |
|
4628 | version = "4.1.5"; | |
|
4629 | src = fetchurl { | |
|
4630 | url = "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz"; | |
|
4631 | sha512 = "sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="; | |
|
4641 | 4632 | }; |
|
4642 | 4633 | }; |
|
4643 | 4634 | "make-dir-1.3.0" = { |
@@ -4658,13 +4649,13 b' let' | |||
|
4658 | 4649 | sha512 = "pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw=="; |
|
4659 | 4650 | }; |
|
4660 | 4651 | }; |
|
4661 |
"map-age-cleaner-0.1. |
|
|
4652 | "map-age-cleaner-0.1.3" = { | |
|
4662 | 4653 | name = "map-age-cleaner"; |
|
4663 | 4654 | packageName = "map-age-cleaner"; |
|
4664 |
version = "0.1. |
|
|
4665 | src = fetchurl { | |
|
4666 |
url = "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1. |
|
|
4667 | sha512 = "UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ=="; | |
|
4655 | version = "0.1.3"; | |
|
4656 | src = fetchurl { | |
|
4657 | url = "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz"; | |
|
4658 | sha512 = "bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w=="; | |
|
4668 | 4659 | }; |
|
4669 | 4660 | }; |
|
4670 | 4661 | "map-cache-0.2.2" = { |
@@ -5261,13 +5252,13 b' let' | |||
|
5261 | 5252 | sha512 = "hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ=="; |
|
5262 | 5253 | }; |
|
5263 | 5254 | }; |
|
5264 |
"pako-1.0. |
|
|
5255 | "pako-1.0.7" = { | |
|
5265 | 5256 | name = "pako"; |
|
5266 | 5257 | packageName = "pako"; |
|
5267 |
version = "1.0. |
|
|
5268 | src = fetchurl { | |
|
5269 |
url = "https://registry.npmjs.org/pako/-/pako-1.0. |
|
|
5270 | sha512 = "lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="; | |
|
5258 | version = "1.0.7"; | |
|
5259 | src = fetchurl { | |
|
5260 | url = "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz"; | |
|
5261 | sha512 = "3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ=="; | |
|
5271 | 5262 | }; |
|
5272 | 5263 | }; |
|
5273 | 5264 | "parallel-transform-1.1.0" = { |
@@ -5711,13 +5702,13 b' let' | |||
|
5711 | 5702 | sha1 = "b2c6a98c0072cf91b932d1a496508114311735bf"; |
|
5712 | 5703 | }; |
|
5713 | 5704 | }; |
|
5714 |
"postcss-modules-extract-imports-1.2. |
|
|
5705 | "postcss-modules-extract-imports-1.2.1" = { | |
|
5715 | 5706 | name = "postcss-modules-extract-imports"; |
|
5716 | 5707 | packageName = "postcss-modules-extract-imports"; |
|
5717 |
version = "1.2. |
|
|
5718 | src = fetchurl { | |
|
5719 |
url = "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2. |
|
|
5720 | sha1 = "66140ecece38ef06bf0d3e355d69bf59d141ea85"; | |
|
5708 | version = "1.2.1"; | |
|
5709 | src = fetchurl { | |
|
5710 | url = "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz"; | |
|
5711 | sha512 = "6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw=="; | |
|
5721 | 5712 | }; |
|
5722 | 5713 | }; |
|
5723 | 5714 | "postcss-modules-local-by-default-1.2.0" = { |
@@ -6737,13 +6728,13 b' let' | |||
|
6737 | 6728 | sha1 = "04e6926f662895354f3dd015203633b857297e2c"; |
|
6738 | 6729 | }; |
|
6739 | 6730 | }; |
|
6740 |
"sshpk-1.15. |
|
|
6731 | "sshpk-1.15.2" = { | |
|
6741 | 6732 | name = "sshpk"; |
|
6742 | 6733 | packageName = "sshpk"; |
|
6743 |
version = "1.15. |
|
|
6744 | src = fetchurl { | |
|
6745 |
url = "https://registry.npmjs.org/sshpk/-/sshpk-1.15. |
|
|
6746 | sha512 = "mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA=="; | |
|
6734 | version = "1.15.2"; | |
|
6735 | src = fetchurl { | |
|
6736 | url = "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz"; | |
|
6737 | sha512 = "Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA=="; | |
|
6747 | 6738 | }; |
|
6748 | 6739 | }; |
|
6749 | 6740 | "ssri-5.3.0" = { |
@@ -6863,6 +6854,15 b' let' | |||
|
6863 | 6854 | sha512 = "n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="; |
|
6864 | 6855 | }; |
|
6865 | 6856 | }; |
|
6857 | "string_decoder-1.2.0" = { | |
|
6858 | name = "string_decoder"; | |
|
6859 | packageName = "string_decoder"; | |
|
6860 | version = "1.2.0"; | |
|
6861 | src = fetchurl { | |
|
6862 | url = "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz"; | |
|
6863 | sha512 = "6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w=="; | |
|
6864 | }; | |
|
6865 | }; | |
|
6866 | 6866 | "stringstream-0.0.6" = { |
|
6867 | 6867 | name = "stringstream"; |
|
6868 | 6868 | packageName = "stringstream"; |
@@ -6971,22 +6971,22 b' let' | |||
|
6971 | 6971 | sha1 = "9f5772413952135c6fefbf40afe6a4faa88b4bb5"; |
|
6972 | 6972 | }; |
|
6973 | 6973 | }; |
|
6974 |
"tapable-0.2. |
|
|
6974 | "tapable-0.2.9" = { | |
|
6975 | 6975 | name = "tapable"; |
|
6976 | 6976 | packageName = "tapable"; |
|
6977 |
version = "0.2. |
|
|
6978 | src = fetchurl { | |
|
6979 |
url = "https://registry.npmjs.org/tapable/-/tapable-0.2. |
|
|
6980 | sha1 = "99372a5c999bf2df160afc0d74bed4f47948cd22"; | |
|
6981 | }; | |
|
6982 | }; | |
|
6983 |
"tapable-1.1. |
|
|
6977 | version = "0.2.9"; | |
|
6978 | src = fetchurl { | |
|
6979 | url = "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz"; | |
|
6980 | sha512 = "2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A=="; | |
|
6981 | }; | |
|
6982 | }; | |
|
6983 | "tapable-1.1.1" = { | |
|
6984 | 6984 | name = "tapable"; |
|
6985 | 6985 | packageName = "tapable"; |
|
6986 |
version = "1.1. |
|
|
6987 | src = fetchurl { | |
|
6988 |
url = "https://registry.npmjs.org/tapable/-/tapable-1.1. |
|
|
6989 | sha512 = "IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA=="; | |
|
6986 | version = "1.1.1"; | |
|
6987 | src = fetchurl { | |
|
6988 | url = "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz"; | |
|
6989 | sha512 = "9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA=="; | |
|
6990 | 6990 | }; |
|
6991 | 6991 | }; |
|
6992 | 6992 | "throttleit-1.0.0" = { |
@@ -7007,13 +7007,13 b' let' | |||
|
7007 | 7007 | sha1 = "0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"; |
|
7008 | 7008 | }; |
|
7009 | 7009 | }; |
|
7010 |
"through2-2.0. |
|
|
7010 | "through2-2.0.5" = { | |
|
7011 | 7011 | name = "through2"; |
|
7012 | 7012 | packageName = "through2"; |
|
7013 |
version = "2.0. |
|
|
7014 | src = fetchurl { | |
|
7015 |
url = "https://registry.npmjs.org/through2/-/through2-2.0. |
|
|
7016 | sha1 = "0004569b37c7c74ba39c43f3ced78d1ad94140be"; | |
|
7013 | version = "2.0.5"; | |
|
7014 | src = fetchurl { | |
|
7015 | url = "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"; | |
|
7016 | sha512 = "/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="; | |
|
7017 | 7017 | }; |
|
7018 | 7018 | }; |
|
7019 | 7019 | "timers-browserify-2.0.10" = { |
@@ -7439,13 +7439,13 b' let' | |||
|
7439 | 7439 | sha512 = "1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw=="; |
|
7440 | 7440 | }; |
|
7441 | 7441 | }; |
|
7442 |
"v8flags-3. |
|
|
7442 | "v8flags-3.1.1" = { | |
|
7443 | 7443 | name = "v8flags"; |
|
7444 | 7444 | packageName = "v8flags"; |
|
7445 |
version = "3. |
|
|
7446 | src = fetchurl { | |
|
7447 |
url = "https://registry.npmjs.org/v8flags/-/v8flags-3. |
|
|
7448 | sha512 = "6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA=="; | |
|
7445 | version = "3.1.1"; | |
|
7446 | src = fetchurl { | |
|
7447 | url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz"; | |
|
7448 | sha512 = "iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ=="; | |
|
7449 | 7449 | }; |
|
7450 | 7450 | }; |
|
7451 | 7451 | "vendors-1.0.2" = { |
@@ -7628,15 +7628,6 b' let' | |||
|
7628 | 7628 | sha1 = "b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"; |
|
7629 | 7629 | }; |
|
7630 | 7630 | }; |
|
7631 | "xregexp-4.0.0" = { | |
|
7632 | name = "xregexp"; | |
|
7633 | packageName = "xregexp"; | |
|
7634 | version = "4.0.0"; | |
|
7635 | src = fetchurl { | |
|
7636 | url = "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz"; | |
|
7637 | sha512 = "PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg=="; | |
|
7638 | }; | |
|
7639 | }; | |
|
7640 | 7631 | "xtend-4.0.1" = { |
|
7641 | 7632 | name = "xtend"; |
|
7642 | 7633 | packageName = "xtend"; |
@@ -7664,13 +7655,13 b' let' | |||
|
7664 | 7655 | sha1 = "1c11f9218f076089a47dd512f93c6699a6a81d52"; |
|
7665 | 7656 | }; |
|
7666 | 7657 | }; |
|
7667 |
"yargs-12.0. |
|
|
7658 | "yargs-12.0.5" = { | |
|
7668 | 7659 | name = "yargs"; |
|
7669 | 7660 | packageName = "yargs"; |
|
7670 |
version = "12.0. |
|
|
7671 | src = fetchurl { | |
|
7672 |
url = "https://registry.npmjs.org/yargs/-/yargs-12.0. |
|
|
7673 | sha512 = "e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ=="; | |
|
7661 | version = "12.0.5"; | |
|
7662 | src = fetchurl { | |
|
7663 | url = "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz"; | |
|
7664 | sha512 = "Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw=="; | |
|
7674 | 7665 | }; |
|
7675 | 7666 | }; |
|
7676 | 7667 | "yargs-3.10.0" = { |
@@ -7682,13 +7673,13 b' let' | |||
|
7682 | 7673 | sha1 = "f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"; |
|
7683 | 7674 | }; |
|
7684 | 7675 | }; |
|
7685 |
"yargs-parser-1 |
|
|
7676 | "yargs-parser-11.1.1" = { | |
|
7686 | 7677 | name = "yargs-parser"; |
|
7687 | 7678 | packageName = "yargs-parser"; |
|
7688 |
version = "1 |
|
|
7689 | src = fetchurl { | |
|
7690 |
url = "https://registry.npmjs.org/yargs-parser/-/yargs-parser-1 |
|
|
7691 | sha512 = "VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ=="; | |
|
7679 | version = "11.1.1"; | |
|
7680 | src = fetchurl { | |
|
7681 | url = "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz"; | |
|
7682 | sha512 = "C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ=="; | |
|
7692 | 7683 | }; |
|
7693 | 7684 | }; |
|
7694 | 7685 | "yauzl-2.4.1" = { |
@@ -7708,7 +7699,7 b' let' | |||
|
7708 | 7699 | src = ./..; |
|
7709 | 7700 | dependencies = [ |
|
7710 | 7701 | sources."@polymer/font-roboto-3.0.2" |
|
7711 |
sources."@polymer/iron-a11y-announcer-3.0. |
|
|
7702 | sources."@polymer/iron-a11y-announcer-3.0.2" | |
|
7712 | 7703 | sources."@polymer/iron-a11y-keys-3.0.1" |
|
7713 | 7704 | sources."@polymer/iron-a11y-keys-behavior-3.0.1" |
|
7714 | 7705 | sources."@polymer/iron-ajax-3.0.1" |
@@ -7732,7 +7723,7 b' let' | |||
|
7732 | 7723 | sources."@polymer/paper-tooltip-3.0.1" |
|
7733 | 7724 | sources."@polymer/polymer-3.1.0" |
|
7734 | 7725 | sources."@types/clone-0.1.30" |
|
7735 |
sources."@types/node-6.14. |
|
|
7726 | sources."@types/node-6.14.2" | |
|
7736 | 7727 | sources."@types/parse5-2.2.34" |
|
7737 | 7728 | sources."@webassemblyjs/ast-1.7.10" |
|
7738 | 7729 | sources."@webassemblyjs/floating-point-hex-parser-1.7.10" |
@@ -7752,8 +7743,8 b' let' | |||
|
7752 | 7743 | sources."@webassemblyjs/wasm-parser-1.7.10" |
|
7753 | 7744 | sources."@webassemblyjs/wast-parser-1.7.10" |
|
7754 | 7745 | sources."@webassemblyjs/wast-printer-1.7.10" |
|
7755 |
sources."@webcomponents/shadycss-1. |
|
|
7756 |
sources."@webcomponents/webcomponentsjs-2.1 |
|
|
7746 | sources."@webcomponents/shadycss-1.6.0" | |
|
7747 | sources."@webcomponents/webcomponentsjs-2.2.1" | |
|
7757 | 7748 | sources."@xtuc/ieee754-1.2.0" |
|
7758 | 7749 | sources."@xtuc/long-4.2.1" |
|
7759 | 7750 | sources."abbrev-1.1.1" |
@@ -7927,7 +7918,7 b' let' | |||
|
7927 | 7918 | sources."bcrypt-pbkdf-1.0.2" |
|
7928 | 7919 | sources."big.js-3.2.0" |
|
7929 | 7920 | sources."binary-extensions-1.12.0" |
|
7930 |
sources."bluebird-3.5. |
|
|
7921 | sources."bluebird-3.5.3" | |
|
7931 | 7922 | sources."bn.js-4.11.8" |
|
7932 | 7923 | sources."boolbase-1.0.0" |
|
7933 | 7924 | sources."boom-2.10.1" |
@@ -7952,22 +7943,22 b' let' | |||
|
7952 | 7943 | (sources."cacache-10.0.4" // { |
|
7953 | 7944 | dependencies = [ |
|
7954 | 7945 | sources."glob-7.1.3" |
|
7955 |
sources."graceful-fs-4.1.1 |
|
|
7956 |
sources."lru-cache-4.1. |
|
|
7946 | sources."graceful-fs-4.1.15" | |
|
7947 | sources."lru-cache-4.1.5" | |
|
7957 | 7948 | sources."minimatch-3.0.4" |
|
7958 | 7949 | sources."rimraf-2.6.2" |
|
7959 | 7950 | ]; |
|
7960 | 7951 | }) |
|
7961 | 7952 | sources."cache-base-1.0.1" |
|
7962 | 7953 | sources."camel-case-3.0.0" |
|
7963 |
sources."camelcase- |
|
|
7954 | sources."camelcase-5.0.0" | |
|
7964 | 7955 | (sources."caniuse-api-1.6.1" // { |
|
7965 | 7956 | dependencies = [ |
|
7966 | 7957 | sources."browserslist-1.7.7" |
|
7967 | 7958 | ]; |
|
7968 | 7959 | }) |
|
7969 |
sources."caniuse-db-1.0.300009 |
|
|
7970 |
sources."caniuse-lite-1.0.300009 |
|
|
7960 | sources."caniuse-db-1.0.30000912" | |
|
7961 | sources."caniuse-lite-1.0.30000912" | |
|
7971 | 7962 | sources."caseless-0.12.0" |
|
7972 | 7963 | sources."center-align-0.1.3" |
|
7973 | 7964 | sources."chalk-0.5.1" |
@@ -8017,7 +8008,7 b' let' | |||
|
8017 | 8008 | sources."minimatch-3.0.4" |
|
8018 | 8009 | ]; |
|
8019 | 8010 | }) |
|
8020 |
sources."clipboard-2.0. |
|
|
8011 | sources."clipboard-2.0.4" | |
|
8021 | 8012 | (sources."cliui-4.1.0" // { |
|
8022 | 8013 | dependencies = [ |
|
8023 | 8014 | sources."ansi-regex-3.0.0" |
@@ -8058,7 +8049,7 b' let' | |||
|
8058 | 8049 | ]; |
|
8059 | 8050 | }) |
|
8060 | 8051 | sources."copy-descriptor-0.1.1" |
|
8061 |
(sources."copy-webpack-plugin-4. |
|
|
8052 | (sources."copy-webpack-plugin-4.6.0" // { | |
|
8062 | 8053 | dependencies = [ |
|
8063 | 8054 | sources."is-glob-4.0.0" |
|
8064 | 8055 | sources."minimatch-3.0.4" |
@@ -8079,18 +8070,14 b' let' | |||
|
8079 | 8070 | sources."css-color-names-0.0.4" |
|
8080 | 8071 | sources."css-loader-0.28.11" |
|
8081 | 8072 | sources."css-select-1.2.0" |
|
8082 |
(sources."css-selector-tokenizer-0.7. |
|
|
8073 | (sources."css-selector-tokenizer-0.7.1" // { | |
|
8083 | 8074 | dependencies = [ |
|
8084 | 8075 | sources."regexpu-core-1.0.0" |
|
8085 | 8076 | ]; |
|
8086 | 8077 | }) |
|
8087 | 8078 | sources."css-what-2.1.2" |
|
8088 | 8079 | sources."cssesc-0.1.0" |
|
8089 |
|
|
|
8090 | dependencies = [ | |
|
8091 | sources."decamelize-1.2.0" | |
|
8092 | ]; | |
|
8093 | }) | |
|
8080 | sources."cssnano-3.10.0" | |
|
8094 | 8081 | sources."csso-2.3.2" |
|
8095 | 8082 | sources."cycle-1.0.3" |
|
8096 | 8083 | sources."cyclist-0.2.2" |
@@ -8102,7 +8089,7 b' let' | |||
|
8102 | 8089 | sources."date-now-0.1.4" |
|
8103 | 8090 | sources."dateformat-1.0.2-1.2.3" |
|
8104 | 8091 | sources."debug-2.6.9" |
|
8105 |
sources."decamelize-2 |
|
|
8092 | sources."decamelize-1.2.0" | |
|
8106 | 8093 | sources."decode-uri-component-0.2.0" |
|
8107 | 8094 | sources."deep-for-each-2.0.3" |
|
8108 | 8095 | sources."define-properties-1.1.3" |
@@ -8139,13 +8126,13 b' let' | |||
|
8139 | 8126 | ]; |
|
8140 | 8127 | }) |
|
8141 | 8128 | sources."ecc-jsbn-0.1.2" |
|
8142 |
sources."electron-to-chromium-1.3.8 |
|
|
8129 | sources."electron-to-chromium-1.3.85" | |
|
8143 | 8130 | sources."elliptic-6.4.1" |
|
8144 | 8131 | sources."emojis-list-2.1.0" |
|
8145 | 8132 | sources."end-of-stream-1.4.1" |
|
8146 | 8133 | (sources."enhanced-resolve-4.1.0" // { |
|
8147 | 8134 | dependencies = [ |
|
8148 |
sources."graceful-fs-4.1.1 |
|
|
8135 | sources."graceful-fs-4.1.15" | |
|
8149 | 8136 | ]; |
|
8150 | 8137 | }) |
|
8151 | 8138 | sources."entities-1.0.0" |
@@ -8203,7 +8190,7 b' let' | |||
|
8203 | 8190 | sources."eyes-0.1.8" |
|
8204 | 8191 | sources."fast-deep-equal-2.0.1" |
|
8205 | 8192 | sources."fast-json-stable-stringify-2.0.0" |
|
8206 |
sources."fastparse-1.1. |
|
|
8193 | sources."fastparse-1.1.2" | |
|
8207 | 8194 | sources."favico.js-0.3.10" |
|
8208 | 8195 | sources."faye-websocket-0.4.4" |
|
8209 | 8196 | sources."fd-slicer-1.0.1" |
@@ -8244,12 +8231,12 b' let' | |||
|
8244 | 8231 | }) |
|
8245 | 8232 | (sources."fs-extra-1.0.0" // { |
|
8246 | 8233 | dependencies = [ |
|
8247 |
sources."graceful-fs-4.1.1 |
|
|
8234 | sources."graceful-fs-4.1.15" | |
|
8248 | 8235 | ]; |
|
8249 | 8236 | }) |
|
8250 | 8237 | (sources."fs-write-stream-atomic-1.0.10" // { |
|
8251 | 8238 | dependencies = [ |
|
8252 |
sources."graceful-fs-4.1.1 |
|
|
8239 | sources."graceful-fs-4.1.15" | |
|
8253 | 8240 | ]; |
|
8254 | 8241 | }) |
|
8255 | 8242 | sources."fs.realpath-1.0.0" |
@@ -8293,7 +8280,7 b' let' | |||
|
8293 | 8280 | sources."good-listener-1.2.2" |
|
8294 | 8281 | sources."graceful-fs-1.2.3" |
|
8295 | 8282 | sources."grunt-0.4.5" |
|
8296 |
(sources."grunt-cli-1.3. |
|
|
8283 | (sources."grunt-cli-1.3.2" // { | |
|
8297 | 8284 | dependencies = [ |
|
8298 | 8285 | sources."nopt-4.0.1" |
|
8299 | 8286 | ]; |
@@ -8477,7 +8464,7 b' let' | |||
|
8477 | 8464 | sources."json5-0.5.1" |
|
8478 | 8465 | (sources."jsonfile-2.4.0" // { |
|
8479 | 8466 | dependencies = [ |
|
8480 |
sources."graceful-fs-4.1.1 |
|
|
8467 | sources."graceful-fs-4.1.15" | |
|
8481 | 8468 | ]; |
|
8482 | 8469 | }) |
|
8483 | 8470 | sources."jsonify-0.0.0" |
@@ -8490,14 +8477,14 b' let' | |||
|
8490 | 8477 | sources."kind-of-6.0.2" |
|
8491 | 8478 | (sources."klaw-1.3.1" // { |
|
8492 | 8479 | dependencies = [ |
|
8493 |
sources."graceful-fs-4.1.1 |
|
|
8480 | sources."graceful-fs-4.1.15" | |
|
8494 | 8481 | ]; |
|
8495 | 8482 | }) |
|
8496 | 8483 | sources."lazy-cache-1.0.4" |
|
8497 | 8484 | sources."lcid-2.0.0" |
|
8498 | 8485 | (sources."less-2.7.3" // { |
|
8499 | 8486 | dependencies = [ |
|
8500 |
sources."graceful-fs-4.1.1 |
|
|
8487 | sources."graceful-fs-4.1.15" | |
|
8501 | 8488 | ]; |
|
8502 | 8489 | }) |
|
8503 | 8490 | (sources."liftoff-2.5.0" // { |
@@ -8520,7 +8507,7 b' let' | |||
|
8520 | 8507 | sources."lru-cache-2.7.3" |
|
8521 | 8508 | sources."make-dir-1.3.0" |
|
8522 | 8509 | sources."make-iterator-1.0.1" |
|
8523 |
sources."map-age-cleaner-0.1. |
|
|
8510 | sources."map-age-cleaner-0.1.3" | |
|
8524 | 8511 | sources."map-cache-0.2.2" |
|
8525 | 8512 | sources."map-visit-1.0.0" |
|
8526 | 8513 | sources."math-expression-evaluator-1.2.17" |
@@ -8566,8 +8553,12 b' let' | |||
|
8566 | 8553 | sources."no-case-2.3.2" |
|
8567 | 8554 | (sources."node-libs-browser-2.1.0" // { |
|
8568 | 8555 | dependencies = [ |
|
8569 | sources."readable-stream-2.3.6" | |
|
8570 | sources."string_decoder-1.1.1" | |
|
8556 | (sources."readable-stream-2.3.6" // { | |
|
8557 | dependencies = [ | |
|
8558 | sources."string_decoder-1.1.1" | |
|
8559 | ]; | |
|
8560 | }) | |
|
8561 | sources."string_decoder-1.2.0" | |
|
8571 | 8562 | ]; |
|
8572 | 8563 | }) |
|
8573 | 8564 | sources."nopt-1.0.10" |
@@ -8616,7 +8607,7 b' let' | |||
|
8616 | 8607 | sources."p-limit-1.3.0" |
|
8617 | 8608 | sources."p-locate-2.0.0" |
|
8618 | 8609 | sources."p-try-1.0.0" |
|
8619 |
sources."pako-1.0. |
|
|
8610 | sources."pako-1.0.7" | |
|
8620 | 8611 | (sources."parallel-transform-1.1.0" // { |
|
8621 | 8612 | dependencies = [ |
|
8622 | 8613 | sources."readable-stream-2.3.6" |
@@ -8706,7 +8697,7 b' let' | |||
|
8706 | 8697 | sources."postcss-minify-gradients-1.0.5" |
|
8707 | 8698 | sources."postcss-minify-params-1.2.2" |
|
8708 | 8699 | sources."postcss-minify-selectors-2.1.1" |
|
8709 |
(sources."postcss-modules-extract-imports-1.2. |
|
|
8700 | (sources."postcss-modules-extract-imports-1.2.1" // { | |
|
8710 | 8701 | dependencies = [ |
|
8711 | 8702 | sources."ansi-styles-3.2.1" |
|
8712 | 8703 | sources."chalk-2.4.1" |
@@ -8783,7 +8774,7 b' let' | |||
|
8783 | 8774 | }) |
|
8784 | 8775 | (sources."readdirp-2.2.1" // { |
|
8785 | 8776 | dependencies = [ |
|
8786 |
sources."graceful-fs-4.1.1 |
|
|
8777 | sources."graceful-fs-4.1.15" | |
|
8787 | 8778 | sources."readable-stream-2.3.6" |
|
8788 | 8779 | sources."string_decoder-1.1.1" |
|
8789 | 8780 | ]; |
@@ -8851,7 +8842,7 b' let' | |||
|
8851 | 8842 | sources."sax-1.2.4" |
|
8852 | 8843 | (sources."schema-utils-0.4.7" // { |
|
8853 | 8844 | dependencies = [ |
|
8854 |
sources."ajv-6. |
|
|
8845 | sources."ajv-6.6.1" | |
|
8855 | 8846 | ]; |
|
8856 | 8847 | }) |
|
8857 | 8848 | sources."select-1.1.2" |
@@ -8909,7 +8900,7 b' let' | |||
|
8909 | 8900 | sources."split-1.0.1" |
|
8910 | 8901 | sources."split-string-3.1.0" |
|
8911 | 8902 | sources."sprintf-js-1.0.3" |
|
8912 |
(sources."sshpk-1.15. |
|
|
8903 | (sources."sshpk-1.15.2" // { | |
|
8913 | 8904 | dependencies = [ |
|
8914 | 8905 | sources."assert-plus-1.0.0" |
|
8915 | 8906 | ]; |
@@ -8971,10 +8962,10 b' let' | |||
|
8971 | 8962 | sources."js-yaml-3.7.0" |
|
8972 | 8963 | ]; |
|
8973 | 8964 | }) |
|
8974 |
sources."tapable-1.1. |
|
|
8965 | sources."tapable-1.1.1" | |
|
8975 | 8966 | sources."throttleit-1.0.0" |
|
8976 | 8967 | sources."through-2.3.8" |
|
8977 |
(sources."through2-2.0. |
|
|
8968 | (sources."through2-2.0.5" // { | |
|
8978 | 8969 | dependencies = [ |
|
8979 | 8970 | sources."readable-stream-2.3.6" |
|
8980 | 8971 | sources."string_decoder-1.1.1" |
@@ -9004,9 +8995,9 b' let' | |||
|
9004 | 8995 | dependencies = [ |
|
9005 | 8996 | sources."colors-1.3.2" |
|
9006 | 8997 | sources."enhanced-resolve-3.4.1" |
|
9007 |
sources."graceful-fs-4.1.1 |
|
|
8998 | sources."graceful-fs-4.1.15" | |
|
9008 | 8999 | sources."loader-utils-0.2.17" |
|
9009 |
sources."tapable-0.2. |
|
|
9000 | sources."tapable-0.2.9" | |
|
9010 | 9001 | ]; |
|
9011 | 9002 | }) |
|
9012 | 9003 | sources."tslib-1.9.3" |
@@ -9075,7 +9066,7 b' let' | |||
|
9075 | 9066 | sources."utila-0.4.0" |
|
9076 | 9067 | sources."uuid-3.3.2" |
|
9077 | 9068 | sources."v8-compile-cache-2.0.2" |
|
9078 |
sources."v8flags-3. |
|
|
9069 | sources."v8flags-3.1.1" | |
|
9079 | 9070 | sources."vendors-1.0.2" |
|
9080 | 9071 | (sources."verror-1.10.0" // { |
|
9081 | 9072 | dependencies = [ |
@@ -9085,13 +9076,13 b' let' | |||
|
9085 | 9076 | sources."vm-browserify-0.0.4" |
|
9086 | 9077 | (sources."watchpack-1.6.0" // { |
|
9087 | 9078 | dependencies = [ |
|
9088 |
sources."graceful-fs-4.1.1 |
|
|
9079 | sources."graceful-fs-4.1.15" | |
|
9089 | 9080 | ]; |
|
9090 | 9081 | }) |
|
9091 | 9082 | sources."waypoints-4.0.1" |
|
9092 | 9083 | (sources."webpack-4.23.1" // { |
|
9093 | 9084 | dependencies = [ |
|
9094 |
sources."ajv-6. |
|
|
9085 | sources."ajv-6.6.1" | |
|
9095 | 9086 | ]; |
|
9096 | 9087 | }) |
|
9097 | 9088 | (sources."webpack-cli-3.1.2" // { |
@@ -9119,7 +9110,6 b' let' | |||
|
9119 | 9110 | sources."camelcase-1.2.1" |
|
9120 | 9111 | sources."chalk-1.1.3" |
|
9121 | 9112 | sources."cliui-2.1.0" |
|
9122 | sources."decamelize-1.2.0" | |
|
9123 | 9113 | sources."has-ansi-2.0.0" |
|
9124 | 9114 | sources."strip-ansi-3.0.1" |
|
9125 | 9115 | sources."supports-color-2.0.0" |
@@ -9147,11 +9137,10 b' let' | |||
|
9147 | 9137 | ]; |
|
9148 | 9138 | }) |
|
9149 | 9139 | sources."wrappy-1.0.2" |
|
9150 | sources."xregexp-4.0.0" | |
|
9151 | 9140 | sources."xtend-4.0.1" |
|
9152 | 9141 | sources."y18n-4.0.0" |
|
9153 | 9142 | sources."yallist-2.1.2" |
|
9154 |
(sources."yargs-12.0. |
|
|
9143 | (sources."yargs-12.0.5" // { | |
|
9155 | 9144 | dependencies = [ |
|
9156 | 9145 | sources."find-up-3.0.0" |
|
9157 | 9146 | sources."locate-path-3.0.0" |
@@ -9160,7 +9149,7 b' let' | |||
|
9160 | 9149 | sources."p-try-2.0.0" |
|
9161 | 9150 | ]; |
|
9162 | 9151 | }) |
|
9163 |
sources."yargs-parser-1 |
|
|
9152 | sources."yargs-parser-11.1.1" | |
|
9164 | 9153 | sources."yauzl-2.4.1" |
|
9165 | 9154 | ]; |
|
9166 | 9155 | buildInputs = globalBuildInputs; |
@@ -72,7 +72,7 b' self: super: {' | |||
|
72 | 72 | ]; |
|
73 | 73 | }); |
|
74 | 74 | |
|
75 | "nbconvert" = super."nbconvert".override (attrs: { | |
|
75 | "nbconvert" = super."nbconvert".override (attrs: { | |
|
76 | 76 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ [ |
|
77 | 77 | # marcink: plug in jupyter-client for notebook rendering |
|
78 | 78 | self."jupyter-client" |
@@ -120,10 +120,12 b' self: super: {' | |||
|
120 | 120 | pkgs.curl |
|
121 | 121 | pkgs.openssl |
|
122 | 122 | ]; |
|
123 | ||
|
123 | 124 | preConfigure = '' |
|
124 | 125 | substituteInPlace setup.py --replace '--static-libs' '--libs' |
|
125 | 126 | export PYCURL_SSL_LIBRARY=openssl |
|
126 | 127 | ''; |
|
128 | ||
|
127 | 129 | meta = { |
|
128 | 130 | license = pkgs.lib.licenses.mit; |
|
129 | 131 | }; |
@@ -168,14 +170,32 b' self: super: {' | |||
|
168 | 170 | propagatedBuildInputs = [ |
|
169 | 171 | pkgs.pam |
|
170 | 172 | ]; |
|
173 | ||
|
171 | 174 | # TODO: johbo: Check if this can be avoided, or transform into |
|
172 | 175 | # a real patch |
|
173 | 176 | patchPhase = '' |
|
174 | 177 | substituteInPlace pam.py \ |
|
175 | 178 | --replace 'find_library("pam")' '"${pkgs.pam}/lib/libpam.so.0"' |
|
176 | 179 | ''; |
|
180 | ||
|
177 | 181 | }); |
|
178 | 182 | |
|
183 | "python-saml" = super."python-saml".override (attrs: { | |
|
184 | buildInputs = [ | |
|
185 | pkgs.libxml2 | |
|
186 | pkgs.libxslt | |
|
187 | ]; | |
|
188 | }); | |
|
189 | ||
|
190 | "dm.xmlsec.binding" = super."dm.xmlsec.binding".override (attrs: { | |
|
191 | buildInputs = [ | |
|
192 | pkgs.libxml2 | |
|
193 | pkgs.libxslt | |
|
194 | pkgs.xmlsec | |
|
195 | pkgs.libtool | |
|
196 | ]; | |
|
197 | }); | |
|
198 | ||
|
179 | 199 | "pyzmq" = super."pyzmq".override (attrs: { |
|
180 | 200 | buildInputs = [ |
|
181 | 201 | pkgs.czmq |
@@ -5,7 +5,7 b'' | |||
|
5 | 5 | |
|
6 | 6 | self: super: { |
|
7 | 7 | "alembic" = super.buildPythonPackage { |
|
8 |
name = "alembic-0. |
|
|
8 | name = "alembic-1.0.5"; | |
|
9 | 9 | doCheck = false; |
|
10 | 10 | propagatedBuildInputs = [ |
|
11 | 11 | self."sqlalchemy" |
@@ -14,8 +14,8 b' self: super: {' | |||
|
14 | 14 | self."python-dateutil" |
|
15 | 15 | ]; |
|
16 | 16 | src = fetchurl { |
|
17 |
url = "https://files.pythonhosted.org/packages/ |
|
|
18 | sha256 = "0bmkq6isjbmy4p7nxfvfpknjsx7rb3xn9g00169y891hcfkkxgc5"; | |
|
17 | url = "https://files.pythonhosted.org/packages/1c/65/b8e4f5b2f345bb13b5e0a3fddd892b0b3f0e8ad4880e954fdc6a50d00d84/alembic-1.0.5.tar.gz"; | |
|
18 | sha256 = "0rpjqp2iq6p49x1nli18ivak1izz547nnjxi110mzrgc1v7dxzz9"; | |
|
19 | 19 | }; |
|
20 | 20 | meta = { |
|
21 | 21 | license = [ pkgs.lib.licenses.mit ]; |
@@ -36,7 +36,7 b' self: super: {' | |||
|
36 | 36 | }; |
|
37 | 37 | }; |
|
38 | 38 | "appenlight-client" = super.buildPythonPackage { |
|
39 |
name = "appenlight-client-0.6.2 |
|
|
39 | name = "appenlight-client-0.6.26"; | |
|
40 | 40 | doCheck = false; |
|
41 | 41 | propagatedBuildInputs = [ |
|
42 | 42 | self."webob" |
@@ -44,8 +44,8 b' self: super: {' | |||
|
44 | 44 | self."six" |
|
45 | 45 | ]; |
|
46 | 46 | src = fetchurl { |
|
47 |
url = "https://files.pythonhosted.org/packages/fa |
|
|
48 | sha256 = "1r9l2rfg677nxhamdbyb9y4fs1zgy2dy1p19c68fnvqkxz40y627"; | |
|
47 | url = "https://files.pythonhosted.org/packages/2e/56/418fc10379b96e795ee39a15e69a730c222818af04c3821fa354eaa859ec/appenlight_client-0.6.26.tar.gz"; | |
|
48 | sha256 = "0s9xw3sb8s3pk73k78nnq4jil3q4mk6bczfa1fmgfx61kdxl2712"; | |
|
49 | 49 | }; |
|
50 | 50 | meta = { |
|
51 | 51 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -146,15 +146,15 b' self: super: {' | |||
|
146 | 146 | }; |
|
147 | 147 | }; |
|
148 | 148 | "bleach" = super.buildPythonPackage { |
|
149 |
name = "bleach-2 |
|
|
149 | name = "bleach-3.0.2"; | |
|
150 | 150 | doCheck = false; |
|
151 | 151 | propagatedBuildInputs = [ |
|
152 | 152 | self."six" |
|
153 |
self." |
|
|
153 | self."webencodings" | |
|
154 | 154 | ]; |
|
155 | 155 | src = fetchurl { |
|
156 |
url = "https://files.pythonhosted.org/packages/ |
|
|
157 | sha256 = "1n337zbdml6z6zia0b1qgv6xiddx3qlwmcg9vk2mk60jcxhmzs8f"; | |
|
156 | url = "https://files.pythonhosted.org/packages/ae/31/680afc7d44040004296a2d8f0584983c2f2386448cd9d0964197e6c1160e/bleach-3.0.2.tar.gz"; | |
|
157 | sha256 = "06474zg7f73hv8h1xw2wcsmvn2ygj73zxgxxqg8zcx8ap1srdls8"; | |
|
158 | 158 | }; |
|
159 | 159 | meta = { |
|
160 | 160 | license = [ pkgs.lib.licenses.asl20 ]; |
@@ -230,15 +230,16 b' self: super: {' | |||
|
230 | 230 | }; |
|
231 | 231 | }; |
|
232 | 232 | "colander" = super.buildPythonPackage { |
|
233 |
name = "colander-1. |
|
|
233 | name = "colander-1.5.1"; | |
|
234 | 234 | doCheck = false; |
|
235 | 235 | propagatedBuildInputs = [ |
|
236 | 236 | self."translationstring" |
|
237 | 237 | self."iso8601" |
|
238 | self."enum34" | |
|
238 | 239 | ]; |
|
239 | 240 | src = fetchurl { |
|
240 |
url = "https://files.pythonhosted.org/packages/cc |
|
|
241 | sha256 = "0wjfphyr5aakv5hw73q287lbc15cbm0aardajv7i2mqf377rl3p2"; | |
|
241 | url = "https://files.pythonhosted.org/packages/ec/d1/fcca811a0a692c69d27e36b4d11a73acb98b4bab48323442642b6fd4386d/colander-1.5.1.tar.gz"; | |
|
242 | sha256 = "18ah4cwwxnpm6qxi6x9ipy51dal4spd343h44s5wd01cnhgrwsyq"; | |
|
242 | 243 | }; |
|
243 | 244 | meta = { |
|
244 | 245 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
@@ -317,7 +318,7 b' self: super: {' | |||
|
317 | 318 | }; |
|
318 | 319 | }; |
|
319 | 320 | "deform" = super.buildPythonPackage { |
|
320 |
name = "deform-2.0. |
|
|
321 | name = "deform-2.0.7"; | |
|
321 | 322 | doCheck = false; |
|
322 | 323 | propagatedBuildInputs = [ |
|
323 | 324 | self."chameleon" |
@@ -328,11 +329,37 b' self: super: {' | |||
|
328 | 329 | self."zope.deprecation" |
|
329 | 330 | ]; |
|
330 | 331 | src = fetchurl { |
|
331 |
url = "https://files.pythonhosted.org/packages/ |
|
|
332 | sha256 = "0ybg9zsnfac1kaxrjanmkjk0xaklf4d3piywxwr08l1cl1336kc7"; | |
|
332 | url = "https://files.pythonhosted.org/packages/cf/a1/bc234527b8f181de9acd80e796483c00007658d1e32b7de78f1c2e004d9a/deform-2.0.7.tar.gz"; | |
|
333 | sha256 = "0jnpi0zr2hjvbmiz6nm33yqv976dn9lf51vhlzqc0i75xcr9rwig"; | |
|
334 | }; | |
|
335 | meta = { | |
|
336 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
|
337 | }; | |
|
338 | }; | |
|
339 | "defusedxml" = super.buildPythonPackage { | |
|
340 | name = "defusedxml-0.5.0"; | |
|
341 | doCheck = false; | |
|
342 | src = fetchurl { | |
|
343 | url = "https://files.pythonhosted.org/packages/74/ba/4ba4e89e21b5a2e267d80736ea674609a0a33cc4435a6d748ef04f1f9374/defusedxml-0.5.0.tar.gz"; | |
|
344 | sha256 = "1x54n0h8hl92vvwyymx883fbqpqjwn2mc8fb383bcg3z9zwz5mr4"; | |
|
333 | 345 | }; |
|
334 | 346 | meta = { |
|
335 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
|
347 | license = [ pkgs.lib.licenses.psfl ]; | |
|
348 | }; | |
|
349 | }; | |
|
350 | "dm.xmlsec.binding" = super.buildPythonPackage { | |
|
351 | name = "dm.xmlsec.binding-1.3.7"; | |
|
352 | doCheck = false; | |
|
353 | propagatedBuildInputs = [ | |
|
354 | self."setuptools" | |
|
355 | self."lxml" | |
|
356 | ]; | |
|
357 | src = fetchurl { | |
|
358 | url = "https://files.pythonhosted.org/packages/2c/9e/7651982d50252692991acdae614af821fd6c79bc8dcd598ad71d55be8fc7/dm.xmlsec.binding-1.3.7.tar.gz"; | |
|
359 | sha256 = "03jjjscx1pz2nc0dwiw9nia02qbz1c6f0f9zkyr8fmvys2n5jkb3"; | |
|
360 | }; | |
|
361 | meta = { | |
|
362 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
|
336 | 363 | }; |
|
337 | 364 | }; |
|
338 | 365 | "docutils" = super.buildPythonPackage { |
@@ -490,14 +517,14 b' self: super: {' | |||
|
490 | 517 | }; |
|
491 | 518 | }; |
|
492 | 519 | "gevent" = super.buildPythonPackage { |
|
493 |
name = "gevent-1.3. |
|
|
520 | name = "gevent-1.3.7"; | |
|
494 | 521 | doCheck = false; |
|
495 | 522 | propagatedBuildInputs = [ |
|
496 | 523 | self."greenlet" |
|
497 | 524 | ]; |
|
498 | 525 | src = fetchurl { |
|
499 |
url = "https://files.pythonhosted.org/packages/49 |
|
|
500 | sha256 = "1ih4k73dqz2zb561hda99vbanja3m6cdch3mgxxn1mla3qwkqhbv"; | |
|
526 | url = "https://files.pythonhosted.org/packages/10/c1/9499b146bfa43aa4f1e0ed1bab1bd3209a4861d25650c11725036c731cf5/gevent-1.3.7.tar.gz"; | |
|
527 | sha256 = "0b0fr04qdk1p4sniv87fh8z5psac60x01pv054kpgi94520g81iz"; | |
|
501 | 528 | }; |
|
502 | 529 | meta = { |
|
503 | 530 | license = [ pkgs.lib.licenses.mit ]; |
@@ -547,27 +574,12 b' self: super: {' | |||
|
547 | 574 | license = [ pkgs.lib.licenses.mit ]; |
|
548 | 575 | }; |
|
549 | 576 | }; |
|
550 | "html5lib" = super.buildPythonPackage { | |
|
551 | name = "html5lib-1.0.1"; | |
|
552 | doCheck = false; | |
|
553 | propagatedBuildInputs = [ | |
|
554 | self."six" | |
|
555 | self."webencodings" | |
|
556 | ]; | |
|
557 | src = fetchurl { | |
|
558 | url = "https://files.pythonhosted.org/packages/85/3e/cf449cf1b5004e87510b9368e7a5f1acd8831c2d6691edd3c62a0823f98f/html5lib-1.0.1.tar.gz"; | |
|
559 | sha256 = "0dipzfrycv6j1jw82v9b7d8lzggx3x8xngx6l4xrqkxwvg7hvjv6"; | |
|
560 | }; | |
|
561 | meta = { | |
|
562 | license = [ pkgs.lib.licenses.mit ]; | |
|
563 | }; | |
|
564 | }; | |
|
565 | 577 | "hupper" = super.buildPythonPackage { |
|
566 |
name = "hupper-1. |
|
|
578 | name = "hupper-1.4.2"; | |
|
567 | 579 | doCheck = false; |
|
568 | 580 | src = fetchurl { |
|
569 | url = "https://files.pythonhosted.org/packages/cf/4b/467b826a84c8594b81f414b5ab6794e981951dac90ca40abaf9ea1cb36b0/hupper-1.3.1.tar.gz"; | |
|
570 | sha256 = "03mf13n6i4dd60wlb9m99ddl4m3lmly70cjp7f82vdkibfl1v6l9"; | |
|
581 | url = "https://files.pythonhosted.org/packages/f1/75/1915dc7650b4867fa3049256e24ca8eddb5989998fcec788cf52b9812dfc/hupper-1.4.2.tar.gz"; | |
|
582 | sha256 = "16vb9fkiaakdpcp6pn56h3w0dwvm67bxq2k2dv4i382qhqwphdzb"; | |
|
571 | 583 | }; |
|
572 | 584 | meta = { |
|
573 | 585 | license = [ pkgs.lib.licenses.mit ]; |
@@ -671,6 +683,20 b' self: super: {' | |||
|
671 | 683 | license = [ pkgs.lib.licenses.mit ]; |
|
672 | 684 | }; |
|
673 | 685 | }; |
|
686 | "isodate" = super.buildPythonPackage { | |
|
687 | name = "isodate-0.6.0"; | |
|
688 | doCheck = false; | |
|
689 | propagatedBuildInputs = [ | |
|
690 | self."six" | |
|
691 | ]; | |
|
692 | src = fetchurl { | |
|
693 | url = "https://files.pythonhosted.org/packages/b1/80/fb8c13a4cd38eb5021dc3741a9e588e4d1de88d895c1910c6fc8a08b7a70/isodate-0.6.0.tar.gz"; | |
|
694 | sha256 = "1n7jkz68kk5pwni540pr5zdh99bf6ywydk1p5pdrqisrawylldif"; | |
|
695 | }; | |
|
696 | meta = { | |
|
697 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
|
698 | }; | |
|
699 | }; | |
|
674 | 700 | "itsdangerous" = super.buildPythonPackage { |
|
675 | 701 | name = "itsdangerous-0.24"; |
|
676 | 702 | doCheck = false; |
@@ -756,11 +782,11 b' self: super: {' | |||
|
756 | 782 | }; |
|
757 | 783 | }; |
|
758 | 784 | "lxml" = super.buildPythonPackage { |
|
759 |
name = "lxml- |
|
|
785 | name = "lxml-4.2.5"; | |
|
760 | 786 | doCheck = false; |
|
761 | 787 | src = fetchurl { |
|
762 | url = "https://files.pythonhosted.org/packages/39/e8/a8e0b1fa65dd021d48fe21464f71783655f39a41f218293c1c590d54eb82/lxml-3.7.3.tar.gz"; | |
|
763 | sha256 = "1iv1jgkqn1hdh1xyxri6g0y1s67h01jzjkw2nhkx3rqylmw2sl5a"; | |
|
788 | url = "https://files.pythonhosted.org/packages/4b/20/ddf5eb3bd5c57582d2b4652b4bbcf8da301bdfe5d805cb94e805f4d7464d/lxml-4.2.5.tar.gz"; | |
|
789 | sha256 = "0zw0y9hs0nflxhl9cs6ipwwh53szi3w2x06wl0k9cylyqac0cwin"; | |
|
764 | 790 | }; |
|
765 | 791 | meta = { |
|
766 | 792 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -990,11 +1016,11 b' self: super: {' | |||
|
990 | 1016 | }; |
|
991 | 1017 | }; |
|
992 | 1018 | "peppercorn" = super.buildPythonPackage { |
|
993 |
name = "peppercorn-0. |
|
|
1019 | name = "peppercorn-0.6"; | |
|
994 | 1020 | doCheck = false; |
|
995 | 1021 | src = fetchurl { |
|
996 | url = "https://files.pythonhosted.org/packages/45/ec/a62ec317d1324a01567c5221b420742f094f05ee48097e5157d32be3755c/peppercorn-0.5.tar.gz"; | |
|
997 | sha256 = "0jvp144zn7yqk9kbpxc059167mlqk85i5lpvl1niw8gsa5fvl74j"; | |
|
1022 | url = "https://files.pythonhosted.org/packages/e4/77/93085de7108cdf1a0b092ff443872a8f9442c736d7ddebdf2f27627935f4/peppercorn-0.6.tar.gz"; | |
|
1023 | sha256 = "1ip4bfwcpwkq9hz2dai14k2cyabvwrnvcvrcmzxmqm04g8fnimwn"; | |
|
998 | 1024 | }; |
|
999 | 1025 | meta = { |
|
1000 | 1026 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
@@ -1139,15 +1165,15 b' self: super: {' | |||
|
1139 | 1165 | }; |
|
1140 | 1166 | }; |
|
1141 | 1167 | "py-gfm" = super.buildPythonPackage { |
|
1142 |
name = "py-gfm-0.1. |
|
|
1168 | name = "py-gfm-0.1.4"; | |
|
1143 | 1169 | doCheck = false; |
|
1144 | 1170 | propagatedBuildInputs = [ |
|
1145 | 1171 | self."setuptools" |
|
1146 | 1172 | self."markdown" |
|
1147 | 1173 | ]; |
|
1148 | 1174 | src = fetchurl { |
|
1149 |
url = "https://files.pythonhosted.org/packages/ |
|
|
1150 | sha256 = "162ggwwj0af9g3s1k8m4bfwbvis03x9pinnf35mj79pb90rf81zi"; | |
|
1175 | url = "https://files.pythonhosted.org/packages/06/ee/004a03a1d92bb386dae44f6dd087db541bc5093374f1637d4d4ae5596cc2/py-gfm-0.1.4.tar.gz"; | |
|
1176 | sha256 = "0zip06g2isivx8fzgqd4n9qzsa22c25jas1rsb7m2rnjg72m0rzg"; | |
|
1151 | 1177 | }; |
|
1152 | 1178 | meta = { |
|
1153 | 1179 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1212,11 +1238,11 b' self: super: {' | |||
|
1212 | 1238 | }; |
|
1213 | 1239 | }; |
|
1214 | 1240 | "pygments" = super.buildPythonPackage { |
|
1215 |
name = "pygments-2. |
|
|
1241 | name = "pygments-2.3.0"; | |
|
1216 | 1242 | doCheck = false; |
|
1217 | 1243 | src = fetchurl { |
|
1218 |
url = "https://files.pythonhosted.org/packages/ |
|
|
1219 | sha256 = "1k78qdvir1yb1c634nkv6rbga8wv4289xarghmsbbvzhvr311bnv"; | |
|
1244 | url = "https://files.pythonhosted.org/packages/63/a2/91c31c4831853dedca2a08a0f94d788fc26a48f7281c99a303769ad2721b/Pygments-2.3.0.tar.gz"; | |
|
1245 | sha256 = "1z34ms51dh4jq4h3cizp7vd1dmsxcbvffkjsd2xxfav22nn6lrl2"; | |
|
1220 | 1246 | }; |
|
1221 | 1247 | meta = { |
|
1222 | 1248 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1248,14 +1274,14 b' self: super: {' | |||
|
1248 | 1274 | }; |
|
1249 | 1275 | }; |
|
1250 | 1276 | "pyotp" = super.buildPythonPackage { |
|
1251 |
name = "pyotp-2.2. |
|
|
1277 | name = "pyotp-2.2.7"; | |
|
1252 | 1278 | doCheck = false; |
|
1253 | 1279 | src = fetchurl { |
|
1254 |
url = "https://files.pythonhosted.org/packages/67 |
|
|
1255 | sha256 = "0sdxxvr3j4j0pk26v258jpxhgpbnpmyqhvzhl24hsd50j7fk14fx"; | |
|
1280 | url = "https://files.pythonhosted.org/packages/b1/ab/477cda97b6ca7baced5106471cb1ac1fe698d1b035983b9f8ee3422989eb/pyotp-2.2.7.tar.gz"; | |
|
1281 | sha256 = "00p69nw431f0s2ilg0hnd77p1l22m06p9rq4f8zfapmavnmzw3xy"; | |
|
1256 | 1282 | }; |
|
1257 | 1283 | meta = { |
|
1258 |
license = [ pkgs.lib.licenses. |
|
|
1284 | license = [ pkgs.lib.licenses.mit ]; | |
|
1259 | 1285 | }; |
|
1260 | 1286 | }; |
|
1261 | 1287 | "pyparsing" = super.buildPythonPackage { |
@@ -1479,14 +1505,14 b' self: super: {' | |||
|
1479 | 1505 | }; |
|
1480 | 1506 | }; |
|
1481 | 1507 | "python-dateutil" = super.buildPythonPackage { |
|
1482 |
name = "python-dateutil-2.7. |
|
|
1508 | name = "python-dateutil-2.7.5"; | |
|
1483 | 1509 | doCheck = false; |
|
1484 | 1510 | propagatedBuildInputs = [ |
|
1485 | 1511 | self."six" |
|
1486 | 1512 | ]; |
|
1487 | 1513 | src = fetchurl { |
|
1488 | url = "https://files.pythonhosted.org/packages/a0/b0/a4e3241d2dee665fea11baec21389aec6886655cd4db7647ddf96c3fad15/python-dateutil-2.7.3.tar.gz"; | |
|
1489 | sha256 = "1f7h54lg0w2ckch7592xpjkh8dg87k2br256h0iw49zn6bg02w72"; | |
|
1514 | url = "https://files.pythonhosted.org/packages/0e/01/68747933e8d12263d41ce08119620d9a7e5eb72c876a3442257f74490da0/python-dateutil-2.7.5.tar.gz"; | |
|
1515 | sha256 = "00ngwcdw36w5b37b51mdwn3qxid9zdf3kpffv2q6n9kl05y2iyc8"; | |
|
1490 | 1516 | }; |
|
1491 | 1517 | meta = { |
|
1492 | 1518 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.asl20 { fullName = "Dual License"; } ]; |
@@ -1543,6 +1569,22 b' self: super: {' | |||
|
1543 | 1569 | license = [ { fullName = "License :: OSI Approved :: MIT License"; } pkgs.lib.licenses.mit ]; |
|
1544 | 1570 | }; |
|
1545 | 1571 | }; |
|
1572 | "python-saml" = super.buildPythonPackage { | |
|
1573 | name = "python-saml-2.4.2"; | |
|
1574 | doCheck = false; | |
|
1575 | propagatedBuildInputs = [ | |
|
1576 | self."dm.xmlsec.binding" | |
|
1577 | self."isodate" | |
|
1578 | self."defusedxml" | |
|
1579 | ]; | |
|
1580 | src = fetchurl { | |
|
1581 | url = "https://files.pythonhosted.org/packages/79/a8/a6611017e0883102fd5e2b73c9d90691b8134e38247c04ee1531d3dc647c/python-saml-2.4.2.tar.gz"; | |
|
1582 | sha256 = "0dls4hwvf13yg7x5yfjrghbywg8g38vn5vr0rsf70hli3ydbfm43"; | |
|
1583 | }; | |
|
1584 | meta = { | |
|
1585 | license = [ pkgs.lib.licenses.mit ]; | |
|
1586 | }; | |
|
1587 | }; | |
|
1546 | 1588 | "pytz" = super.buildPythonPackage { |
|
1547 | 1589 | name = "pytz-2018.4"; |
|
1548 | 1590 | doCheck = false; |
@@ -1615,7 +1657,7 b' self: super: {' | |||
|
1615 | 1657 | }; |
|
1616 | 1658 | }; |
|
1617 | 1659 | "rhodecode-enterprise-ce" = super.buildPythonPackage { |
|
1618 |
name = "rhodecode-enterprise-ce-4.1 |
|
|
1660 | name = "rhodecode-enterprise-ce-4.15.0"; | |
|
1619 | 1661 | buildInputs = [ |
|
1620 | 1662 | self."pytest" |
|
1621 | 1663 | self."py" |
@@ -1640,6 +1682,7 b' self: super: {' | |||
|
1640 | 1682 | self."attrs" |
|
1641 | 1683 | self."babel" |
|
1642 | 1684 | self."beaker" |
|
1685 | self."bleach" | |
|
1643 | 1686 | self."celery" |
|
1644 | 1687 | self."chameleon" |
|
1645 | 1688 | self."channelstream" |
@@ -1668,8 +1711,6 b' self: super: {' | |||
|
1668 | 1711 | self."markdown" |
|
1669 | 1712 | self."markupsafe" |
|
1670 | 1713 | self."msgpack-python" |
|
1671 | self."mysql-python" | |
|
1672 | self."pymysql" | |
|
1673 | 1714 | self."pyotp" |
|
1674 | 1715 | self."packaging" |
|
1675 | 1716 | self."paste" |
@@ -1678,7 +1719,6 b' self: super: {' | |||
|
1678 | 1719 | self."pathlib2" |
|
1679 | 1720 | self."peppercorn" |
|
1680 | 1721 | self."psutil" |
|
1681 | self."psycopg2" | |
|
1682 | 1722 | self."py-bcrypt" |
|
1683 | 1723 | self."pycrypto" |
|
1684 | 1724 | self."pycurl" |
@@ -1692,11 +1732,11 b' self: super: {' | |||
|
1692 | 1732 | self."pyramid-mako" |
|
1693 | 1733 | self."pyramid" |
|
1694 | 1734 | self."pyramid-mailer" |
|
1695 | self."pysqlite" | |
|
1696 | 1735 | self."python-dateutil" |
|
1697 | 1736 | self."python-ldap" |
|
1698 | 1737 | self."python-memcached" |
|
1699 | 1738 | self."python-pam" |
|
1739 | self."python-saml" | |
|
1700 | 1740 | self."pytz" |
|
1701 | 1741 | self."tzlocal" |
|
1702 | 1742 | self."pyzmq" |
@@ -1713,7 +1753,6 b' self: super: {' | |||
|
1713 | 1753 | self."supervisor" |
|
1714 | 1754 | self."tempita" |
|
1715 | 1755 | self."translationstring" |
|
1716 | self."trollius" | |
|
1717 | 1756 | self."urllib3" |
|
1718 | 1757 | self."urlobject" |
|
1719 | 1758 | self."venusian" |
@@ -1727,8 +1766,11 b' self: super: {' | |||
|
1727 | 1766 | self."zope.deprecation" |
|
1728 | 1767 | self."zope.event" |
|
1729 | 1768 | self."zope.interface" |
|
1769 | self."mysql-python" | |
|
1770 | self."pymysql" | |
|
1771 | self."pysqlite" | |
|
1772 | self."psycopg2" | |
|
1730 | 1773 | self."nbconvert" |
|
1731 | self."bleach" | |
|
1732 | 1774 | self."nbformat" |
|
1733 | 1775 | self."jupyter-client" |
|
1734 | 1776 | self."alembic" |
@@ -1822,11 +1864,11 b' self: super: {' | |||
|
1822 | 1864 | }; |
|
1823 | 1865 | }; |
|
1824 | 1866 | "setuptools" = super.buildPythonPackage { |
|
1825 |
name = "setuptools-40. |
|
|
1867 | name = "setuptools-40.6.2"; | |
|
1826 | 1868 | doCheck = false; |
|
1827 | 1869 | src = fetchurl { |
|
1828 |
url = "https://files.pythonhosted.org/packages/6 |
|
|
1829 | sha256 = "058v6zns4634n4al2nmmvp15j8nrgwn8wjrbdks47wk3vm05gg5c"; | |
|
1870 | url = "https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip"; | |
|
1871 | sha256 = "0r2c5hapirlzm34h7pl1lgkm6gk7bcrlrdj28qgsvaqg3f74vfw6"; | |
|
1830 | 1872 | }; |
|
1831 | 1873 | meta = { |
|
1832 | 1874 | license = [ pkgs.lib.licenses.mit ]; |
@@ -2002,20 +2044,6 b' self: super: {' | |||
|
2002 | 2044 | license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ]; |
|
2003 | 2045 | }; |
|
2004 | 2046 | }; |
|
2005 | "trollius" = super.buildPythonPackage { | |
|
2006 | name = "trollius-1.0.4"; | |
|
2007 | doCheck = false; | |
|
2008 | propagatedBuildInputs = [ | |
|
2009 | self."futures" | |
|
2010 | ]; | |
|
2011 | src = fetchurl { | |
|
2012 | url = "https://files.pythonhosted.org/packages/aa/e6/4141db437f55e6ee7a3fb69663239e3fde7841a811b4bef293145ad6c836/trollius-1.0.4.tar.gz"; | |
|
2013 | sha256 = "0xny8y12x3wrflmyn6xi8a7n3m3ac80fgmgzphx5jbbaxkjcm148"; | |
|
2014 | }; | |
|
2015 | meta = { | |
|
2016 | license = [ pkgs.lib.licenses.asl20 ]; | |
|
2017 | }; | |
|
2018 | }; | |
|
2019 | 2047 | "tzlocal" = super.buildPythonPackage { |
|
2020 | 2048 | name = "tzlocal-1.5.1"; |
|
2021 | 2049 | doCheck = false; |
@@ -32,6 +32,11 b' pkgs.stdenv.mkDerivation {' | |||
|
32 | 32 | # We need postgresql to be around |
|
33 | 33 | pkgs.postgresql |
|
34 | 34 | |
|
35 | # we need the below for saml | |
|
36 | pkgs.libxml2 | |
|
37 | pkgs.libxslt | |
|
38 | pkgs.xmlsec | |
|
39 | ||
|
35 | 40 | # Curl is needed for pycurl |
|
36 | 41 | pkgs.curl |
|
37 | 42 | ]; |
@@ -8,16 +8,17 b' atomicwrites==1.2.1' | |||
|
8 | 8 | attrs==18.2.0 |
|
9 | 9 | babel==1.3 |
|
10 | 10 | beaker==1.9.1 |
|
11 | bleach==3.0.2 | |
|
11 | 12 | celery==4.1.1 |
|
12 | 13 | chameleon==2.24 |
|
13 | 14 | channelstream==0.5.2 |
|
14 | 15 | click==6.6 |
|
15 |
colander==1. |
|
|
16 | colander==1.5.1 | |
|
16 | 17 | # our custom configobj |
|
17 | 18 | https://code.rhodecode.com/upstream/configobj/archive/a11ff0a0bd4fbda9e3a91267e720f88329efb4a6.tar.gz?md5=9916c524ea11a6c418217af6b28d4b3c#egg=configobj==5.0.6 |
|
18 | 19 | cssselect==1.0.3 |
|
19 | 20 | decorator==4.1.2 |
|
20 |
deform==2.0. |
|
|
21 | deform==2.0.7 | |
|
21 | 22 | docutils==0.14.0 |
|
22 | 23 | dogpile.cache==0.6.7 |
|
23 | 24 | dogpile.core==0.4.1 |
@@ -32,28 +33,25 b' itsdangerous==0.24' | |||
|
32 | 33 | jinja2==2.9.6 |
|
33 | 34 | billiard==3.5.0.3 |
|
34 | 35 | kombu==4.2.0 |
|
35 |
lxml== |
|
|
36 | lxml==4.2.5 | |
|
36 | 37 | mako==1.0.7 |
|
37 | 38 | markdown==2.6.11 |
|
38 | 39 | markupsafe==1.0.0 |
|
39 | 40 | msgpack-python==0.5.6 |
|
40 | mysql-python==1.2.5 | |
|
41 | pymysql==0.8.1 | |
|
42 | pyotp==2.2.6 | |
|
41 | pyotp==2.2.7 | |
|
43 | 42 | packaging==15.2 |
|
44 | 43 | paste==2.0.3 |
|
45 | 44 | pastedeploy==1.5.2 |
|
46 | 45 | pastescript==2.0.2 |
|
47 | 46 | pathlib2==2.3.2 |
|
48 |
peppercorn==0. |
|
|
47 | peppercorn==0.6 | |
|
49 | 48 | psutil==5.4.7 |
|
50 | psycopg2==2.7.5 | |
|
51 | 49 | py-bcrypt==0.4 |
|
52 | 50 | pycrypto==2.6.1 |
|
53 | 51 | pycurl==7.43.0.2 |
|
54 | 52 | pyflakes==0.8.1 |
|
55 | 53 | pygments-markdown-lexer==0.1.0.dev39 |
|
56 |
pygments==2. |
|
|
54 | pygments==2.3.0 | |
|
57 | 55 | pyparsing==1.5.7 |
|
58 | 56 | pyramid-beaker==0.8 |
|
59 | 57 | pyramid-debugtoolbar==4.4.0 |
@@ -61,15 +59,15 b' pyramid-jinja2==2.7' | |||
|
61 | 59 | pyramid-mako==1.0.2 |
|
62 | 60 | pyramid==1.9.2 |
|
63 | 61 | pyramid_mailer==0.15.1 |
|
64 | pysqlite==2.8.3 | |
|
65 | 62 | python-dateutil |
|
66 | 63 | python-ldap==3.1.0 |
|
67 | 64 | python-memcached==1.59 |
|
68 | 65 | python-pam==1.8.4 |
|
66 | python-saml | |
|
69 | 67 | pytz==2018.4 |
|
70 | 68 | tzlocal==1.5.1 |
|
71 | 69 | pyzmq==14.6.0 |
|
72 |
py-gfm==0.1. |
|
|
70 | py-gfm==0.1.4 | |
|
73 | 71 | redis==2.10.6 |
|
74 | 72 | repoze.lru==0.7 |
|
75 | 73 | requests==2.9.1 |
@@ -82,7 +80,6 b' subprocess32==3.5.2' | |||
|
82 | 80 | supervisor==3.3.4 |
|
83 | 81 | tempita==0.5.2 |
|
84 | 82 | translationstring==1.3 |
|
85 | trollius==1.0.4 | |
|
86 | 83 | urllib3==1.21 |
|
87 | 84 | urlobject==2.4.3 |
|
88 | 85 | venusian==1.1.0 |
@@ -97,22 +94,26 b' zope.deprecation==4.3.0' | |||
|
97 | 94 | zope.event==4.3.0 |
|
98 | 95 | zope.interface==4.5.0 |
|
99 | 96 | |
|
97 | # DB drivers | |
|
98 | mysql-python==1.2.5 | |
|
99 | pymysql==0.8.1 | |
|
100 | pysqlite==2.8.3 | |
|
101 | psycopg2==2.7.5 | |
|
100 | 102 | |
|
101 | 103 | # IPYTHON RENDERING |
|
102 | 104 | # entrypoints backport, pypi version doesn't support egg installs |
|
103 | 105 | https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1 |
|
104 | 106 | nbconvert==5.3.1 |
|
105 | bleach==2.1.4 | |
|
106 | 107 | nbformat==4.4.0 |
|
107 | 108 | jupyter_client==5.0.0 |
|
108 | 109 | |
|
109 | 110 | ## cli tools |
|
110 |
alembic== |
|
|
111 | alembic==1.0.5 | |
|
111 | 112 | invoke==0.13.0 |
|
112 | 113 | bumpversion==0.5.3 |
|
113 | 114 | |
|
114 | 115 | ## http servers |
|
115 |
gevent==1.3. |
|
|
116 | gevent==1.3.7 | |
|
116 | 117 | greenlet==0.4.15 |
|
117 | 118 | gunicorn==19.9.0 |
|
118 | 119 | waitress==1.1.0 |
@@ -126,7 +127,7 b' ipython==5.1.0' | |||
|
126 | 127 | https://code.rhodecode.com/rhodecode-tools-ce/archive/v1.0.1.tar.gz?md5=ffb5d6bcb855305b93cfe23ad42e500b#egg=rhodecode-tools==1.0.1 |
|
127 | 128 | |
|
128 | 129 | ## appenlight |
|
129 |
appenlight-client==0.6.2 |
|
|
130 | appenlight-client==0.6.26 | |
|
130 | 131 | |
|
131 | 132 | ## test related requirements |
|
132 | 133 | -r requirements_test.txt |
@@ -66,7 +66,7 b' class TestCreatePullRequestApi(object):' | |||
|
66 | 66 | expected_message = "Created new pull request `{title}`".format( |
|
67 | 67 | title=data['title']) |
|
68 | 68 | result = response.json |
|
69 |
assert result['error'] |
|
|
69 | assert result['error'] is None | |
|
70 | 70 | assert result['result']['msg'] == expected_message |
|
71 | 71 | pull_request_id = result['result']['pull_request_id'] |
|
72 | 72 | pull_request = PullRequestModel().get(pull_request_id) |
@@ -89,7 +89,7 b' class TestCreatePullRequestApi(object):' | |||
|
89 | 89 | expected_message = "Created new pull request `{title}`".format( |
|
90 | 90 | title=data['title']) |
|
91 | 91 | result = response.json |
|
92 |
assert result['error'] |
|
|
92 | assert result['error'] is None | |
|
93 | 93 | assert result['result']['msg'] == expected_message |
|
94 | 94 | pull_request_id = result['result']['pull_request_id'] |
|
95 | 95 | pull_request = PullRequestModel().get(pull_request_id) |
@@ -129,7 +129,7 b' class TestCreatePullRequestApi(object):' | |||
|
129 | 129 | expected_message = "Created new pull request `{title}`".format( |
|
130 | 130 | title=data['title']) |
|
131 | 131 | result = response.json |
|
132 |
assert result['error'] |
|
|
132 | assert result['error'] is None | |
|
133 | 133 | assert result['result']['msg'] == expected_message |
|
134 | 134 | pull_request_id = result['result']['pull_request_id'] |
|
135 | 135 | pull_request = PullRequestModel().get(pull_request_id) |
@@ -144,11 +144,15 b' class TestCreatePullRequestApi(object):' | |||
|
144 | 144 | entry['mandatory'] = rev.mandatory |
|
145 | 145 | actual_reviewers.append(entry) |
|
146 | 146 | |
|
147 | # default reviewer will be added who is an owner of the repo | |
|
148 | reviewers.append( | |
|
149 | {'username': pull_request.author.username, | |
|
150 | 'reasons': [u'Default reviewer', u'Repository owner']}, | |
|
151 | ) | |
|
147 | owner_username = pull_request.target_repo.user.username | |
|
148 | for spec_reviewer in reviewers[::]: | |
|
149 | # default reviewer will be added who is an owner of the repo | |
|
150 | # this get's overridden by a add owner to reviewers rule | |
|
151 | if spec_reviewer['username'] == owner_username: | |
|
152 | spec_reviewer['reasons'] = [u'Default reviewer', u'Repository owner'] | |
|
153 | # since owner is more important, we don't inherit mandatory flag | |
|
154 | del spec_reviewer['mandatory'] | |
|
155 | ||
|
152 | 156 | assert sorted(actual_reviewers, key=lambda e: e['username']) \ |
|
153 | 157 | == sorted(reviewers, key=lambda e: e['username']) |
|
154 | 158 | |
@@ -173,7 +177,7 b' class TestCreatePullRequestApi(object):' | |||
|
173 | 177 | expected_message = "Created new pull request `{title}`".format( |
|
174 | 178 | title=data['title']) |
|
175 | 179 | result = response.json |
|
176 |
assert result['error'] |
|
|
180 | assert result['error'] is None | |
|
177 | 181 | assert result['result']['msg'] == expected_message |
|
178 | 182 | pull_request_id = result['result']['pull_request_id'] |
|
179 | 183 | pull_request = PullRequestModel().get(pull_request_id) |
@@ -187,11 +191,14 b' class TestCreatePullRequestApi(object):' | |||
|
187 | 191 | if rev.mandatory: |
|
188 | 192 | entry['mandatory'] = rev.mandatory |
|
189 | 193 | actual_reviewers.append(entry) |
|
190 | # default reviewer will be added who is an owner of the repo | |
|
191 | reviewers.append( | |
|
192 | {'username': pull_request.author.user_id, | |
|
193 | 'reasons': [u'Default reviewer', u'Repository owner']}, | |
|
194 | ) | |
|
194 | ||
|
195 | owner_user_id = pull_request.target_repo.user.user_id | |
|
196 | for spec_reviewer in reviewers[::]: | |
|
197 | # default reviewer will be added who is an owner of the repo | |
|
198 | # this get's overridden by a add owner to reviewers rule | |
|
199 | if spec_reviewer['username'] == owner_user_id: | |
|
200 | spec_reviewer['reasons'] = [u'Default reviewer', u'Repository owner'] | |
|
201 | ||
|
195 | 202 | assert sorted(actual_reviewers, key=lambda e: e['username']) \ |
|
196 | 203 | == sorted(reviewers, key=lambda e: e['username']) |
|
197 | 204 |
|
1 | NO CONTENT: file renamed from rhodecode/apps/admin/interfaces.py to rhodecode/apps/_base/interfaces.py |
@@ -24,7 +24,7 b' import collections' | |||
|
24 | 24 | |
|
25 | 25 | from zope.interface import implementer |
|
26 | 26 | |
|
27 |
from rhodecode.apps. |
|
|
27 | from rhodecode.apps._base.interfaces import IAdminNavigationRegistry | |
|
28 | 28 | from rhodecode.lib.utils2 import str2bool |
|
29 | 29 | from rhodecode.translation import _ |
|
30 | 30 | |
@@ -117,10 +117,11 b' class NavigationRegistry(object):' | |||
|
117 | 117 | self._registered_entries[entry.key] = entry |
|
118 | 118 | |
|
119 | 119 | def get_navlist(self, request): |
|
120 | navlist = [NavListEntry(i.key, i.get_localized_name(request), | |
|
121 | i.generate_url(request), i.active_list) | |
|
122 | for i in self._registered_entries.values()] | |
|
123 | return navlist | |
|
120 | nav_list = [ | |
|
121 | NavListEntry(i.key, i.get_localized_name(request), | |
|
122 | i.generate_url(request), i.active_list) | |
|
123 | for i in self._registered_entries.values()] | |
|
124 | return nav_list | |
|
124 | 125 | |
|
125 | 126 | |
|
126 | 127 | def navigation_registry(request, registry=None): |
@@ -143,5 +144,5 b' def includeme(config):' | |||
|
143 | 144 | # Create admin navigation registry and add it to the pyramid registry. |
|
144 | 145 | settings = config.get_settings() |
|
145 | 146 | labs_active = str2bool(settings.get('labs_settings_active', False)) |
|
146 | navigation_registry = NavigationRegistry(labs_active=labs_active) | |
|
147 | config.registry.registerUtility(navigation_registry) No newline at end of file | |
|
147 | navigation_registry_instance = NavigationRegistry(labs_active=labs_active) | |
|
148 | config.registry.registerUtility(navigation_registry_instance) |
|
1 | NO CONTENT: file renamed from rhodecode/apps/admin/subscribers.py to rhodecode/apps/_base/subscribers.py |
@@ -429,7 +429,7 b' def admin_routes(config):' | |||
|
429 | 429 | |
|
430 | 430 | |
|
431 | 431 | def includeme(config): |
|
432 |
from rhodecode.apps. |
|
|
432 | from rhodecode.apps._base.navigation import includeme as nav_includeme | |
|
433 | 433 | |
|
434 | 434 | # Create admin navigation registry and add it to the pyramid registry. |
|
435 | 435 | nav_includeme(config) |
@@ -438,7 +438,5 b' def includeme(config):' | |||
|
438 | 438 | config.add_route(name='admin_home', pattern=ADMIN_PREFIX) |
|
439 | 439 | config.include(admin_routes, route_prefix=ADMIN_PREFIX) |
|
440 | 440 | |
|
441 | config.include('.subscribers') | |
|
442 | ||
|
443 | 441 | # Scan module for configuration decorators. |
|
444 | 442 | config.scan('.views', ignore='.tests') |
@@ -89,7 +89,7 b' class TestAuthSettingsView(object):' | |||
|
89 | 89 | 'timeout': 3600, |
|
90 | 90 | 'tls_kind': 'PLAIN', |
|
91 | 91 | 'tls_reqcert': 'NEVER', |
|
92 | ||
|
92 | 'tls_cert_dir':'/etc/openldap/cacerts', | |
|
93 | 93 | 'dn_user': 'test_user', |
|
94 | 94 | 'dn_pass': 'test_pass', |
|
95 | 95 | 'base_dn': 'test_base_dn', |
@@ -24,7 +24,7 b' from pyramid.httpexceptions import HTTPF' | |||
|
24 | 24 | from pyramid.view import view_config |
|
25 | 25 | |
|
26 | 26 | from rhodecode.apps._base import BaseAppView |
|
27 |
from rhodecode.apps. |
|
|
27 | from rhodecode.apps._base.navigation import navigation_list | |
|
28 | 28 | from rhodecode.lib import helpers as h |
|
29 | 29 | from rhodecode.lib.auth import ( |
|
30 | 30 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
@@ -24,7 +24,7 b' import logging' | |||
|
24 | 24 | from pyramid.view import view_config |
|
25 | 25 | |
|
26 | 26 | from rhodecode.apps._base import BaseAppView |
|
27 |
from rhodecode.apps. |
|
|
27 | from rhodecode.apps._base.navigation import navigation_list | |
|
28 | 28 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) |
|
29 | 29 | from rhodecode.lib.utils import read_opensource_licenses |
|
30 | 30 |
@@ -25,7 +25,7 b' import signal' | |||
|
25 | 25 | from pyramid.view import view_config |
|
26 | 26 | |
|
27 | 27 | from rhodecode.apps._base import BaseAppView |
|
28 |
from rhodecode.apps. |
|
|
28 | from rhodecode.apps._base.navigation import navigation_list | |
|
29 | 29 | from rhodecode.lib import system_info |
|
30 | 30 | from rhodecode.lib.auth import ( |
|
31 | 31 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
@@ -24,7 +24,7 b' from pyramid.view import view_config' | |||
|
24 | 24 | from pyramid.httpexceptions import HTTPFound |
|
25 | 25 | |
|
26 | 26 | from rhodecode.apps._base import BaseAppView |
|
27 |
from rhodecode.apps. |
|
|
27 | from rhodecode.apps._base.navigation import navigation_list | |
|
28 | 28 | from rhodecode.lib.auth import ( |
|
29 | 29 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
|
30 | 30 | from rhodecode.lib.utils2 import safe_int |
@@ -33,7 +33,7 b' from pyramid.renderers import render' | |||
|
33 | 33 | from pyramid.response import Response |
|
34 | 34 | |
|
35 | 35 | from rhodecode.apps._base import BaseAppView |
|
36 |
from rhodecode.apps. |
|
|
36 | from rhodecode.apps._base.navigation import navigation_list | |
|
37 | 37 | from rhodecode.apps.svn_support.config_keys import generate_config |
|
38 | 38 | from rhodecode.lib import helpers as h |
|
39 | 39 | from rhodecode.lib.auth import ( |
@@ -175,8 +175,7 b' class AdminSettingsView(BaseAppView):' | |||
|
175 | 175 | |
|
176 | 176 | try: |
|
177 | 177 | if c.visual.allow_repo_location_change: |
|
178 | model.update_global_path_setting( | |
|
179 | form_result['paths_root_path']) | |
|
178 | model.update_global_path_setting(form_result['paths_root_path']) | |
|
180 | 179 | |
|
181 | 180 | model.update_global_ssl_setting(form_result['web_push_ssl']) |
|
182 | 181 | model.update_global_hook_settings(form_result) |
@@ -25,7 +25,7 b' from pyramid.view import view_config' | |||
|
25 | 25 | |
|
26 | 26 | import rhodecode |
|
27 | 27 | from rhodecode.apps._base import BaseAppView |
|
28 |
from rhodecode.apps. |
|
|
28 | from rhodecode.apps._base.navigation import navigation_list | |
|
29 | 29 | from rhodecode.lib import helpers as h |
|
30 | 30 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) |
|
31 | 31 | from rhodecode.lib.utils2 import str2bool |
@@ -96,6 +96,7 b' class AdminSystemInfoSettingsView(BaseAp' | |||
|
96 | 96 | # RhodeCode specific |
|
97 | 97 | (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')), |
|
98 | 98 | (_('Latest version'), version, update_state), |
|
99 | (_('RhodeCode Base URL'), val('rhodecode_config')['config'].get('app.base_url'), state('rhodecode_config')), | |
|
99 | 100 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), |
|
100 | 101 | (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), |
|
101 | 102 | (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), |
@@ -185,7 +185,7 b' class AdminUsersView(BaseAppView, DataGr' | |||
|
185 | 185 | def users_new(self): |
|
186 | 186 | _ = self.request.translate |
|
187 | 187 | c = self.load_default_context() |
|
188 |
c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin. |
|
|
188 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
|
189 | 189 | self._set_personal_repo_group_template_vars(c) |
|
190 | 190 | return self._get_template_context(c) |
|
191 | 191 | |
@@ -198,7 +198,7 b' class AdminUsersView(BaseAppView, DataGr' | |||
|
198 | 198 | def users_create(self): |
|
199 | 199 | _ = self.request.translate |
|
200 | 200 | c = self.load_default_context() |
|
201 |
c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin. |
|
|
201 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
|
202 | 202 | user_model = UserModel() |
|
203 | 203 | user_form = UserForm(self.request.translate)() |
|
204 | 204 | try: |
@@ -63,7 +63,7 b' def maybe_create_history_store(event):' | |||
|
63 | 63 | settings = event.app.registry.settings |
|
64 | 64 | history_dir = settings.get('channelstream.history.location', '') |
|
65 | 65 | if history_dir and not os.path.exists(history_dir): |
|
66 | os.makedirs(history_dir, 0750) | |
|
66 | os.makedirs(history_dir, 0o750) | |
|
67 | 67 | |
|
68 | 68 | |
|
69 | 69 | def includeme(config): |
@@ -32,6 +32,7 b' from pyramid.view import view_config' | |||
|
32 | 32 | |
|
33 | 33 | from rhodecode.apps._base import BaseAppView |
|
34 | 34 | from rhodecode.authentication.base import authenticate, HTTP_TYPE |
|
35 | from rhodecode.authentication.plugins import auth_rhodecode | |
|
35 | 36 | from rhodecode.events import UserRegistered, trigger |
|
36 | 37 | from rhodecode.lib import helpers as h |
|
37 | 38 | from rhodecode.lib import audit_logger |
@@ -55,7 +56,7 b' CaptchaData = collections.namedtuple(' | |||
|
55 | 56 | 'CaptchaData', 'active, private_key, public_key') |
|
56 | 57 | |
|
57 | 58 | |
|
58 |
def |
|
|
59 | def store_user_in_session(session, username, remember=False): | |
|
59 | 60 | user = User.get_by_username(username, case_insensitive=True) |
|
60 | 61 | auth_user = AuthUser(user.user_id) |
|
61 | 62 | auth_user.set_authenticated() |
@@ -165,7 +166,7 b' class LoginView(BaseAppView):' | |||
|
165 | 166 | auth_info = authenticate( |
|
166 | 167 | '', '', self.request.environ, HTTP_TYPE, skip_missing=True) |
|
167 | 168 | if auth_info: |
|
168 |
headers = |
|
|
169 | headers = store_user_in_session( | |
|
169 | 170 | self.session, auth_info.get('username')) |
|
170 | 171 | raise HTTPFound(c.came_from, headers=headers) |
|
171 | 172 | except UserCreationError as e: |
@@ -186,7 +187,7 b' class LoginView(BaseAppView):' | |||
|
186 | 187 | self.session.invalidate() |
|
187 | 188 | form_result = login_form.to_python(self.request.POST) |
|
188 | 189 | # form checks for username/password, now we're authenticated |
|
189 |
headers = |
|
|
190 | headers = store_user_in_session( | |
|
190 | 191 | self.session, |
|
191 | 192 | username=form_result['username'], |
|
192 | 193 | remember=form_result['remember']) |
@@ -273,16 +274,26 b' class LoginView(BaseAppView):' | |||
|
273 | 274 | route_name='register', request_method='POST', |
|
274 | 275 | renderer='rhodecode:templates/register.mako') |
|
275 | 276 | def register_post(self): |
|
277 | from rhodecode.authentication.plugins import auth_rhodecode | |
|
278 | ||
|
276 | 279 | self.load_default_context() |
|
277 | 280 | captcha = self._get_captcha_data() |
|
278 | 281 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ |
|
279 | 282 | .AuthUser().permissions['global'] |
|
280 | 283 | |
|
284 | extern_name = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
|
285 | extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
|
286 | ||
|
281 | 287 | register_form = RegisterForm(self.request.translate)() |
|
282 | 288 | try: |
|
283 | 289 | |
|
284 | 290 | form_result = register_form.to_python(self.request.POST) |
|
285 | 291 | form_result['active'] = auto_active |
|
292 | external_identity = self.request.POST.get('external_identity') | |
|
293 | ||
|
294 | if external_identity: | |
|
295 | extern_name = external_identity | |
|
296 | extern_type = external_identity | |
|
286 | 297 | |
|
287 | 298 | if captcha.active: |
|
288 | 299 | captcha_status, captcha_message = self.validate_captcha( |
@@ -295,11 +306,17 b' class LoginView(BaseAppView):' | |||
|
295 | 306 | raise formencode.Invalid( |
|
296 | 307 | _msg, _value, None, error_dict=error_dict) |
|
297 | 308 | |
|
298 |
new_user = UserModel().create_registration( |
|
|
309 | new_user = UserModel().create_registration( | |
|
310 | form_result, extern_name=extern_name, extern_type=extern_type) | |
|
299 | 311 | |
|
300 | 312 | action_data = {'data': new_user.get_api_data(), |
|
301 | 313 | 'user_agent': self.request.user_agent} |
|
302 | 314 | |
|
315 | ||
|
316 | ||
|
317 | if external_identity: | |
|
318 | action_data['external_identity'] = external_identity | |
|
319 | ||
|
303 | 320 | audit_user = audit_logger.UserWrap( |
|
304 | 321 | username=new_user.username, |
|
305 | 322 | user_id=new_user.user_id, |
@@ -351,15 +368,24 b' class LoginView(BaseAppView):' | |||
|
351 | 368 | # matching emails |
|
352 | 369 | msg = _('If such email exists, a password reset link was sent to it.') |
|
353 | 370 | |
|
371 | def default_response(): | |
|
372 | log.debug('faking response on invalid password reset') | |
|
373 | # make this take 2s, to prevent brute forcing. | |
|
374 | time.sleep(2) | |
|
375 | h.flash(msg, category='success') | |
|
376 | return HTTPFound(self.request.route_path('reset_password')) | |
|
377 | ||
|
354 | 378 | if self.request.POST: |
|
355 | 379 | if h.HasPermissionAny('hg.password_reset.disabled')(): |
|
356 | 380 | _email = self.request.POST.get('email', '') |
|
357 | 381 | log.error('Failed attempt to reset password for `%s`.', _email) |
|
358 | h.flash(_('Password reset has been disabled.'), | |
|
359 | category='error') | |
|
382 | h.flash(_('Password reset has been disabled.'), category='error') | |
|
360 | 383 | return HTTPFound(self.request.route_path('reset_password')) |
|
361 | 384 | |
|
362 | 385 | password_reset_form = PasswordResetForm(self.request.translate)() |
|
386 | description = u'Generated token for password reset from {}'.format( | |
|
387 | datetime.datetime.now().isoformat()) | |
|
388 | ||
|
363 | 389 | try: |
|
364 | 390 | form_result = password_reset_form.to_python( |
|
365 | 391 | self.request.POST) |
@@ -379,10 +405,14 b' class LoginView(BaseAppView):' | |||
|
379 | 405 | # Generate reset URL and send mail. |
|
380 | 406 | user = User.get_by_email(user_email) |
|
381 | 407 | |
|
408 | # only allow rhodecode based users to reset their password | |
|
409 | # external auth shouldn't allow password reset | |
|
410 | if user and user.extern_type != auth_rhodecode.RhodeCodeAuthPlugin.uid: | |
|
411 | log.warning('User %s with external type `%s` tried a password reset. ' | |
|
412 | 'This try was rejected', user, user.extern_type) | |
|
413 | return default_response() | |
|
414 | ||
|
382 | 415 | # generate password reset token that expires in 10 minutes |
|
383 | description = u'Generated token for password reset from {}'.format( | |
|
384 | datetime.datetime.now().isoformat()) | |
|
385 | ||
|
386 | 416 | reset_token = UserModel().add_auth_token( |
|
387 | 417 | user=user, lifetime_minutes=10, |
|
388 | 418 | role=UserModel.auth_token_role.ROLE_PASSWORD_RESET, |
@@ -395,15 +425,14 b' class LoginView(BaseAppView):' | |||
|
395 | 425 | _query={'key': reset_token.api_key}) |
|
396 | 426 | UserModel().reset_password_link( |
|
397 | 427 | form_result, password_reset_url) |
|
398 | # Display success message and redirect. | |
|
399 | h.flash(msg, category='success') | |
|
400 | 428 | |
|
401 | 429 | action_data = {'email': user_email, |
|
402 | 430 | 'user_agent': self.request.user_agent} |
|
403 | 431 | audit_logger.store_web( |
|
404 | 432 | 'user.password.reset_request', action_data=action_data, |
|
405 | 433 | user=self._rhodecode_user, commit=True) |
|
406 | return HTTPFound(self.request.route_path('reset_password')) | |
|
434 | ||
|
435 | return default_response() | |
|
407 | 436 | |
|
408 | 437 | except formencode.Invalid as errors: |
|
409 | 438 | template_context.update({ |
@@ -418,11 +447,7 b' class LoginView(BaseAppView):' | |||
|
418 | 447 | # case of failed captcha |
|
419 | 448 | return self._get_template_context(c, **template_context) |
|
420 | 449 | |
|
421 | log.debug('faking response on invalid password reset') | |
|
422 | # make this take 2s, to prevent brute forcing. | |
|
423 | time.sleep(2) | |
|
424 | h.flash(msg, category='success') | |
|
425 | return HTTPFound(self.request.route_path('reset_password')) | |
|
450 | return default_response() | |
|
426 | 451 | |
|
427 | 452 | return self._get_template_context(c, **template_context) |
|
428 | 453 |
@@ -51,12 +51,12 b' def get_default_reviewers_data(' | |||
|
51 | 51 | """ Return json for default reviewers of a repository """ |
|
52 | 52 | |
|
53 | 53 | reasons = ['Default reviewer', 'Repository owner'] |
|
54 |
|
|
|
55 |
user= |
|
|
54 | json_reviewers = [reviewer_as_json( | |
|
55 | user=target_repo.user, reasons=reasons, mandatory=False, rules=None)] | |
|
56 | 56 | |
|
57 | 57 | return { |
|
58 | 58 | 'api_ver': 'v1', # define version for later possible schema upgrade |
|
59 |
'reviewers': |
|
|
59 | 'reviewers': json_reviewers, | |
|
60 | 60 | 'rules': {}, |
|
61 | 61 | 'rules_data': {}, |
|
62 | 62 | } |
@@ -211,7 +211,7 b' class RepoChangelogView(RepoAppView):' | |||
|
211 | 211 | base_commit = self.rhodecode_vcs_repo.get_commit(commit_id) |
|
212 | 212 | |
|
213 | 213 | try: |
|
214 |
collection = base_commit.get_ |
|
|
214 | collection = base_commit.get_path_history( | |
|
215 | 215 | f_path, limit=hist_limit, pre_load=pre_load) |
|
216 | 216 | if collection and partial_xhr: |
|
217 | 217 | # for ajax call we remove first one since we're looking |
@@ -221,7 +221,7 b' class RepoChangelogView(RepoAppView):' | |||
|
221 | 221 | # this node is not present at tip! |
|
222 | 222 | try: |
|
223 | 223 | commit = self._get_commit_or_redirect(commit_id) |
|
224 |
collection = commit.get_ |
|
|
224 | collection = commit.get_path_history(f_path) | |
|
225 | 225 | except RepositoryError as e: |
|
226 | 226 | h.flash(safe_str(e), category='warning') |
|
227 | 227 | redirect_url = h.route_path( |
@@ -315,7 +315,7 b' class RepoChangelogView(RepoAppView):' | |||
|
315 | 315 | raise HTTPFound( |
|
316 | 316 | h.route_path('repo_changelog', repo_name=self.db_repo_name)) |
|
317 | 317 | |
|
318 |
collection = base_commit.get_ |
|
|
318 | collection = base_commit.get_path_history( | |
|
319 | 319 | f_path, limit=hist_limit, pre_load=pre_load) |
|
320 | 320 | collection = list(reversed(collection)) |
|
321 | 321 | else: |
@@ -663,7 +663,7 b' class RepoFilesView(RepoAppView):' | |||
|
663 | 663 | pass |
|
664 | 664 | |
|
665 | 665 | if is_file: |
|
666 |
history = commit.get_ |
|
|
666 | history = commit.get_path_history(f_path) | |
|
667 | 667 | prev_commit_id = history[1].raw_id \ |
|
668 | 668 | if len(history) > 1 else prev_commit_id |
|
669 | 669 | prev_url = h.route_path( |
@@ -897,10 +897,10 b' class RepoFilesView(RepoAppView):' | |||
|
897 | 897 | if commits is None: |
|
898 | 898 | pre_load = ["author", "branch"] |
|
899 | 899 | try: |
|
900 |
commits = tip.get_ |
|
|
900 | commits = tip.get_path_history(f_path, pre_load=pre_load) | |
|
901 | 901 | except (NodeDoesNotExistError, CommitError): |
|
902 | 902 | # this node is not present at tip! |
|
903 |
commits = commit_obj.get_ |
|
|
903 | commits = commit_obj.get_path_history(f_path, pre_load=pre_load) | |
|
904 | 904 | |
|
905 | 905 | history = [] |
|
906 | 906 | commits_group = ([], _("Changesets")) |
@@ -25,6 +25,7 b' from pyramid.view import view_config' | |||
|
25 | 25 | from rhodecode.apps._base import RepoAppView |
|
26 | 26 | from rhodecode.apps.repository.utils import get_default_reviewers_data |
|
27 | 27 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
28 | from rhodecode.model.db import Repository | |
|
28 | 29 | |
|
29 | 30 | log = logging.getLogger(__name__) |
|
30 | 31 | |
@@ -53,8 +54,8 b' class RepoReviewRulesView(RepoAppView):' | |||
|
53 | 54 | renderer='json_ext') |
|
54 | 55 | def repo_default_reviewers_data(self): |
|
55 | 56 | self.load_default_context() |
|
57 | target_repo_name = self.request.GET.get('target_repo', self.db_repo.repo_name) | |
|
58 | target_repo = Repository.get_by_repo_name(target_repo_name) | |
|
56 | 59 | review_data = get_default_reviewers_data( |
|
57 |
self.db_repo.user, None, None, |
|
|
60 | self.db_repo.user, None, None, target_repo, None) | |
|
58 | 61 | return review_data |
|
59 | ||
|
60 |
@@ -35,15 +35,8 b' from .events import ModDavSvnConfigChang' | |||
|
35 | 35 | log = logging.getLogger(__name__) |
|
36 | 36 | |
|
37 | 37 | |
|
38 |
def |
|
|
39 | """ | |
|
40 | Generate the configuration file for use with subversion's mod_dav_svn | |
|
41 | module. The configuration has to contain a <Location> block for each | |
|
42 | available repository group because the mod_dav_svn module does not support | |
|
43 | repositories organized in sub folders. | |
|
44 | """ | |
|
45 | settings = registry.settings | |
|
46 | use_ssl = str2bool(registry.settings['force_https']) | |
|
38 | def write_mod_dav_svn_config(settings): | |
|
39 | use_ssl = str2bool(settings['force_https']) | |
|
47 | 40 | |
|
48 | 41 | config = _render_mod_dav_svn_config( |
|
49 | 42 | use_ssl=use_ssl, |
@@ -54,6 +47,17 b' def generate_mod_dav_svn_config(registry' | |||
|
54 | 47 | realm=get_rhodecode_realm(), template=settings[config_keys.template]) |
|
55 | 48 | _write_mod_dav_svn_config(config, settings[config_keys.config_file_path]) |
|
56 | 49 | |
|
50 | ||
|
51 | def generate_mod_dav_svn_config(registry): | |
|
52 | """ | |
|
53 | Generate the configuration file for use with subversion's mod_dav_svn | |
|
54 | module. The configuration has to contain a <Location> block for each | |
|
55 | available repository group because the mod_dav_svn module does not support | |
|
56 | repositories organized in sub folders. | |
|
57 | """ | |
|
58 | settings = registry.settings | |
|
59 | write_mod_dav_svn_config(settings) | |
|
60 | ||
|
57 | 61 | # Trigger an event on mod dav svn configuration change. |
|
58 | 62 | trigger(ModDavSvnConfigChange(), registry) |
|
59 | 63 |
@@ -19,7 +19,7 b'' | |||
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | 21 | |
|
22 |
from rhodecode.apps. |
|
|
22 | from rhodecode.apps._base.navigation import NavigationRegistry | |
|
23 | 23 | from rhodecode.apps._base import ADMIN_PREFIX |
|
24 | 24 | from rhodecode.lib.utils2 import str2bool |
|
25 | 25 |
@@ -18,11 +18,9 b'' | |||
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | import os | |
|
22 | 21 | import logging |
|
23 | 22 | import importlib |
|
24 | 23 | |
|
25 | from pkg_resources import iter_entry_points | |
|
26 | 24 | from pyramid.authentication import SessionAuthenticationPolicy |
|
27 | 25 | |
|
28 | 26 | from rhodecode.authentication.registry import AuthenticationPluginRegistry |
@@ -31,48 +29,26 b' from rhodecode.authentication.routes imp' | |||
|
31 | 29 | from rhodecode.apps._base import ADMIN_PREFIX |
|
32 | 30 | from rhodecode.model.settings import SettingsModel |
|
33 | 31 | |
|
34 | ||
|
35 | 32 | log = logging.getLogger(__name__) |
|
36 | 33 | |
|
37 | # Plugin ID prefixes to distinct between normal and legacy plugins. | |
|
38 | plugin_prefix = 'egg:' | |
|
39 | 34 | legacy_plugin_prefix = 'py:' |
|
40 | 35 | plugin_default_auth_ttl = 30 |
|
41 | 36 | |
|
42 | 37 | |
|
43 | # TODO: Currently this is only used to discover the authentication plugins. | |
|
44 | # Later on this may be used in a generic way to look up and include all kinds | |
|
45 | # of supported enterprise plugins. Therefore this has to be moved and | |
|
46 | # refactored to a real 'plugin look up' machinery. | |
|
47 | # TODO: When refactoring this think about splitting it up into distinct | |
|
48 | # discover, load and include phases. | |
|
49 | def _discover_plugins(config, entry_point='enterprise.plugins1'): | |
|
50 | for ep in iter_entry_points(entry_point): | |
|
51 | plugin_id = '{}{}#{}'.format( | |
|
52 | plugin_prefix, ep.dist.project_name, ep.name) | |
|
53 | log.debug('Plugin discovered: "%s"', plugin_id) | |
|
54 | try: | |
|
55 | module = ep.load() | |
|
56 | plugin = module(plugin_id=plugin_id) | |
|
57 | config.include(plugin.includeme) | |
|
58 | except Exception as e: | |
|
59 | log.exception( | |
|
60 | 'Exception while loading authentication plugin ' | |
|
61 | '"{}": {}'.format(plugin_id, e.message)) | |
|
62 | ||
|
63 | ||
|
64 | 38 | def _import_legacy_plugin(plugin_id): |
|
65 | 39 | module_name = plugin_id.split(legacy_plugin_prefix, 1)[-1] |
|
66 | 40 | module = importlib.import_module(module_name) |
|
67 | 41 | return module.plugin_factory(plugin_id=plugin_id) |
|
68 | 42 | |
|
69 | 43 | |
|
70 |
def |
|
|
44 | def discover_legacy_plugins(config, prefix=legacy_plugin_prefix): | |
|
71 | 45 | """ |
|
72 | 46 | Function that imports the legacy plugins stored in the 'auth_plugins' |
|
73 | 47 | setting in database which are using the specified prefix. Normally 'py:' is |
|
74 | 48 | used for the legacy plugins. |
|
75 | 49 | """ |
|
50 | log.debug('authentication: running legacy plugin discovery for prefix %s', | |
|
51 | legacy_plugin_prefix) | |
|
76 | 52 | try: |
|
77 | 53 | auth_plugins = SettingsModel().get_setting_by_name('auth_plugins') |
|
78 | 54 | enabled_plugins = auth_plugins.app_settings_value |
@@ -121,12 +97,3 b' def includeme(config):' | |||
|
121 | 97 | request_method='POST', |
|
122 | 98 | route_name='auth_home', |
|
123 | 99 | context=AuthnRootResource) |
|
124 | ||
|
125 | for key in ['RC_CMD_SETUP_RC', 'RC_CMD_UPGRADE_DB', 'RC_CMD_SSH_WRAPPER']: | |
|
126 | if os.environ.get(key): | |
|
127 | # skip this heavy step below on certain CLI commands | |
|
128 | return | |
|
129 | ||
|
130 | # Auto discover authentication plugins and include their configuration. | |
|
131 | _discover_plugins(config) | |
|
132 | _discover_legacy_plugins(config) |
@@ -38,7 +38,8 b' from rhodecode.authentication.schema imp' | |||
|
38 | 38 | from rhodecode.lib import rc_cache |
|
39 | 39 | from rhodecode.lib.auth import PasswordGenerator, _RhodeCodeCryptoBCrypt |
|
40 | 40 | from rhodecode.lib.utils2 import safe_int, safe_str |
|
41 | from rhodecode.lib.exceptions import LdapConnectionError | |
|
41 | from rhodecode.lib.exceptions import LdapConnectionError, LdapUsernameError, \ | |
|
42 | LdapPasswordError | |
|
42 | 43 | from rhodecode.model.db import User |
|
43 | 44 | from rhodecode.model.meta import Session |
|
44 | 45 | from rhodecode.model.settings import SettingsModel |
@@ -52,6 +53,8 b' log = logging.getLogger(__name__)' | |||
|
52 | 53 | VCS_TYPE = 'vcs' |
|
53 | 54 | HTTP_TYPE = 'http' |
|
54 | 55 | |
|
56 | external_auth_session_key = 'rhodecode.external_auth' | |
|
57 | ||
|
55 | 58 | |
|
56 | 59 | class hybrid_property(object): |
|
57 | 60 | """ |
@@ -93,6 +96,9 b' class LazyFormencode(object):' | |||
|
93 | 96 | |
|
94 | 97 | |
|
95 | 98 | class RhodeCodeAuthPluginBase(object): |
|
99 | # UID is used to register plugin to the registry | |
|
100 | uid = None | |
|
101 | ||
|
96 | 102 | # cache the authentication request for N amount of seconds. Some kind |
|
97 | 103 | # of authentication methods are very heavy and it's very efficient to cache |
|
98 | 104 | # the result of a call. If it's set to None (default) cache is off |
@@ -113,7 +119,7 b' class RhodeCodeAuthPluginBase(object):' | |||
|
113 | 119 | "active": |
|
114 | 120 | 'True|False defines active state of user internally for RhodeCode', |
|
115 | 121 | "active_from_extern": |
|
116 |
"True|False |
|
|
122 | "True|False|None, active state from the external auth, " | |
|
117 | 123 | "None means use definition from RhodeCode extern_type active value" |
|
118 | 124 | |
|
119 | 125 | } |
@@ -171,6 +177,20 b' class RhodeCodeAuthPluginBase(object):' | |||
|
171 | 177 | db_type = '{}.encrypted'.format(db_type) |
|
172 | 178 | return db_type |
|
173 | 179 | |
|
180 | @classmethod | |
|
181 | def docs(cls): | |
|
182 | """ | |
|
183 | Defines documentation url which helps with plugin setup | |
|
184 | """ | |
|
185 | return '' | |
|
186 | ||
|
187 | @classmethod | |
|
188 | def icon(cls): | |
|
189 | """ | |
|
190 | Defines ICON in SVG format for authentication method | |
|
191 | """ | |
|
192 | return '' | |
|
193 | ||
|
174 | 194 | def is_enabled(self): |
|
175 | 195 | """ |
|
176 | 196 | Returns true if this plugin is enabled. An enabled plugin can be |
@@ -563,7 +583,8 b' class RhodeCodeExternalAuthPlugin(RhodeC' | |||
|
563 | 583 | class AuthLdapBase(object): |
|
564 | 584 | |
|
565 | 585 | @classmethod |
|
566 | def _build_servers(cls, ldap_server_type, ldap_server, port): | |
|
586 | def _build_servers(cls, ldap_server_type, ldap_server, port, use_resolver=True): | |
|
587 | ||
|
567 | 588 | def host_resolver(host, port, full_resolve=True): |
|
568 | 589 | """ |
|
569 | 590 | Main work for this function is to prevent ldap connection issues, |
@@ -602,7 +623,7 b' class AuthLdapBase(object):' | |||
|
602 | 623 | return ', '.join( |
|
603 | 624 | ["{}://{}".format( |
|
604 | 625 | ldap_server_type, |
|
605 | host_resolver(host, port, full_resolve=full_resolve)) | |
|
626 | host_resolver(host, port, full_resolve=use_resolver and full_resolve)) | |
|
606 | 627 | for host in ldap_server]) |
|
607 | 628 | |
|
608 | 629 | @classmethod |
@@ -616,6 +637,19 b' class AuthLdapBase(object):' | |||
|
616 | 637 | uid = chop_at(username, "@%s" % server_addr) |
|
617 | 638 | return uid |
|
618 | 639 | |
|
640 | @classmethod | |
|
641 | def validate_username(cls, username): | |
|
642 | if "," in username: | |
|
643 | raise LdapUsernameError( | |
|
644 | "invalid character `,` in username: `{}`".format(username)) | |
|
645 | ||
|
646 | @classmethod | |
|
647 | def validate_password(cls, username, password): | |
|
648 | if not password: | |
|
649 | msg = "Authenticating user %s with blank password not allowed" | |
|
650 | log.warning(msg, username) | |
|
651 | raise LdapPasswordError(msg) | |
|
652 | ||
|
619 | 653 | |
|
620 | 654 | def loadplugin(plugin_id): |
|
621 | 655 | """ |
@@ -40,7 +40,7 b' from rhodecode.model.db import User' | |||
|
40 | 40 | log = logging.getLogger(__name__) |
|
41 | 41 | |
|
42 | 42 | |
|
43 |
def plugin_factory(plugin_id, *args, **kw |
|
|
43 | def plugin_factory(plugin_id, *args, **kwargs): | |
|
44 | 44 | """ |
|
45 | 45 | Factory function that is called during plugin discovery. |
|
46 | 46 | It returns the plugin instance. |
@@ -189,6 +189,7 b' class CrowdServer(object):' | |||
|
189 | 189 | |
|
190 | 190 | |
|
191 | 191 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
192 | uid = 'crowd' | |
|
192 | 193 | _settings_unsafe_keys = ['app_password'] |
|
193 | 194 | |
|
194 | 195 | def includeme(self, config): |
@@ -215,9 +216,13 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
215 | 216 | def get_display_name(self): |
|
216 | 217 | return _('CROWD') |
|
217 | 218 | |
|
219 | @classmethod | |
|
220 | def docs(cls): | |
|
221 | return "https://docs.rhodecode.com/RhodeCode-Enterprise/auth/auth-crowd.html" | |
|
222 | ||
|
218 | 223 | @hybrid_property |
|
219 | 224 | def name(self): |
|
220 | return "crowd" | |
|
225 | return u"crowd" | |
|
221 | 226 | |
|
222 | 227 | def use_fake_password(self): |
|
223 | 228 | return True |
@@ -283,3 +288,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
283 | 288 | log.debug("Final crowd user object: \n%s", formatted_json(user_attrs)) |
|
284 | 289 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
285 | 290 | return user_attrs |
|
291 | ||
|
292 | ||
|
293 | def includeme(config): | |
|
294 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) | |
|
295 | plugin_factory(plugin_id).includeme(config) |
@@ -34,7 +34,7 b' from rhodecode.model.db import User' | |||
|
34 | 34 | log = logging.getLogger(__name__) |
|
35 | 35 | |
|
36 | 36 | |
|
37 |
def plugin_factory(plugin_id, *args, **kw |
|
|
37 | def plugin_factory(plugin_id, *args, **kwargs): | |
|
38 | 38 | """ |
|
39 | 39 | Factory function that is called during plugin discovery. |
|
40 | 40 | It returns the plugin instance. |
@@ -75,7 +75,7 b' class HeadersSettingsSchema(AuthnPluginS' | |||
|
75 | 75 | |
|
76 | 76 | |
|
77 | 77 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
78 | ||
|
78 | uid = 'headers' | |
|
79 | 79 | def includeme(self, config): |
|
80 | 80 | config.add_authn_plugin(self) |
|
81 | 81 | config.add_authn_resource(self.get_id(), HeadersAuthnResource(self)) |
@@ -102,7 +102,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
102 | 102 | |
|
103 | 103 | @hybrid_property |
|
104 | 104 | def name(self): |
|
105 |
return |
|
|
105 | return u"headers" | |
|
106 | 106 | |
|
107 | 107 | @property |
|
108 | 108 | def is_headers_auth(self): |
@@ -223,3 +223,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
223 | 223 | |
|
224 | 224 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
225 | 225 | return user_attrs |
|
226 | ||
|
227 | ||
|
228 | def includeme(config): | |
|
229 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) | |
|
230 | plugin_factory(plugin_id).includeme(config) |
@@ -42,7 +42,7 b' from rhodecode.model.db import User' | |||
|
42 | 42 | log = logging.getLogger(__name__) |
|
43 | 43 | |
|
44 | 44 | |
|
45 |
def plugin_factory(plugin_id, *args, **kw |
|
|
45 | def plugin_factory(plugin_id, *args, **kwargs): | |
|
46 | 46 | """ |
|
47 | 47 | Factory function that is called during plugin discovery. |
|
48 | 48 | It returns the plugin instance. |
@@ -66,6 +66,7 b' class JasigCasSettingsSchema(AuthnPlugin' | |||
|
66 | 66 | |
|
67 | 67 | |
|
68 | 68 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
69 | uid = 'jasig_cas' | |
|
69 | 70 | |
|
70 | 71 | def includeme(self, config): |
|
71 | 72 | config.add_authn_plugin(self) |
@@ -93,7 +94,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
93 | 94 | |
|
94 | 95 | @hybrid_property |
|
95 | 96 | def name(self): |
|
96 | return "jasig-cas" | |
|
97 | return u"jasig-cas" | |
|
97 | 98 | |
|
98 | 99 | @property |
|
99 | 100 | def is_headers_auth(self): |
@@ -165,3 +166,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
165 | 166 | |
|
166 | 167 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
167 | 168 | return user_attrs |
|
169 | ||
|
170 | ||
|
171 | def includeme(config): | |
|
172 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) | |
|
173 | plugin_factory(plugin_id).includeme(config) |
@@ -53,7 +53,7 b' class LdapError(Exception):' | |||
|
53 | 53 | pass |
|
54 | 54 | |
|
55 | 55 | |
|
56 |
def plugin_factory(plugin_id, *args, **kw |
|
|
56 | def plugin_factory(plugin_id, *args, **kwargs): | |
|
57 | 57 | """ |
|
58 | 58 | Factory function that is called during plugin discovery. |
|
59 | 59 | It returns the plugin instance. |
@@ -66,6 +66,171 b' class LdapAuthnResource(AuthnPluginResou' | |||
|
66 | 66 | pass |
|
67 | 67 | |
|
68 | 68 | |
|
69 | class AuthLdap(AuthLdapBase): | |
|
70 | default_tls_cert_dir = '/etc/openldap/cacerts' | |
|
71 | ||
|
72 | def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='', | |
|
73 | tls_kind='PLAIN', tls_reqcert='DEMAND', tls_cert_file=None, | |
|
74 | tls_cert_dir=None, ldap_version=3, | |
|
75 | search_scope='SUBTREE', attr_login='uid', | |
|
76 | ldap_filter='', timeout=None): | |
|
77 | if ldap == Missing: | |
|
78 | raise LdapImportError("Missing or incompatible ldap library") | |
|
79 | ||
|
80 | self.debug = False | |
|
81 | self.timeout = timeout or 60 * 5 | |
|
82 | self.ldap_version = ldap_version | |
|
83 | self.ldap_server_type = 'ldap' | |
|
84 | ||
|
85 | self.TLS_KIND = tls_kind | |
|
86 | ||
|
87 | if self.TLS_KIND == 'LDAPS': | |
|
88 | port = port or 689 | |
|
89 | self.ldap_server_type += 's' | |
|
90 | ||
|
91 | OPT_X_TLS_DEMAND = 2 | |
|
92 | self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert, OPT_X_TLS_DEMAND) | |
|
93 | self.TLS_CERT_FILE = tls_cert_file or '' | |
|
94 | self.TLS_CERT_DIR = tls_cert_dir or self.default_tls_cert_dir | |
|
95 | ||
|
96 | # split server into list | |
|
97 | self.SERVER_ADDRESSES = self._get_server_list(server) | |
|
98 | self.LDAP_SERVER_PORT = port | |
|
99 | ||
|
100 | # USE FOR READ ONLY BIND TO LDAP SERVER | |
|
101 | self.attr_login = attr_login | |
|
102 | ||
|
103 | self.LDAP_BIND_DN = safe_str(bind_dn) | |
|
104 | self.LDAP_BIND_PASS = safe_str(bind_pass) | |
|
105 | ||
|
106 | self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope) | |
|
107 | self.BASE_DN = safe_str(base_dn) | |
|
108 | self.LDAP_FILTER = safe_str(ldap_filter) | |
|
109 | ||
|
110 | def _get_ldap_conn(self): | |
|
111 | ||
|
112 | if self.debug: | |
|
113 | ldap.set_option(ldap.OPT_DEBUG_LEVEL, 255) | |
|
114 | ||
|
115 | if self.TLS_CERT_FILE and hasattr(ldap, 'OPT_X_TLS_CACERTFILE'): | |
|
116 | ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.TLS_CERT_FILE) | |
|
117 | ||
|
118 | elif hasattr(ldap, 'OPT_X_TLS_CACERTDIR'): | |
|
119 | ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, self.TLS_CERT_DIR) | |
|
120 | ||
|
121 | if self.TLS_KIND != 'PLAIN': | |
|
122 | ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT) | |
|
123 | ||
|
124 | ldap.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF) | |
|
125 | ldap.set_option(ldap.OPT_RESTART, ldap.OPT_ON) | |
|
126 | ||
|
127 | # init connection now | |
|
128 | ldap_servers = self._build_servers( | |
|
129 | self.ldap_server_type, self.SERVER_ADDRESSES, self.LDAP_SERVER_PORT) | |
|
130 | log.debug('initializing LDAP connection to:%s', ldap_servers) | |
|
131 | ldap_conn = ldap.initialize(ldap_servers) | |
|
132 | ldap_conn.set_option(ldap.OPT_NETWORK_TIMEOUT, self.timeout) | |
|
133 | ldap_conn.set_option(ldap.OPT_TIMEOUT, self.timeout) | |
|
134 | ldap_conn.timeout = self.timeout | |
|
135 | ||
|
136 | if self.ldap_version == 2: | |
|
137 | ldap_conn.protocol = ldap.VERSION2 | |
|
138 | else: | |
|
139 | ldap_conn.protocol = ldap.VERSION3 | |
|
140 | ||
|
141 | if self.TLS_KIND == 'START_TLS': | |
|
142 | ldap_conn.start_tls_s() | |
|
143 | ||
|
144 | if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: | |
|
145 | log.debug('Trying simple_bind with password and given login DN: %r', | |
|
146 | self.LDAP_BIND_DN) | |
|
147 | ldap_conn.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS) | |
|
148 | ||
|
149 | return ldap_conn | |
|
150 | ||
|
151 | def fetch_attrs_from_simple_bind(self, server, dn, username, password): | |
|
152 | try: | |
|
153 | log.debug('Trying simple bind with %r', dn) | |
|
154 | server.simple_bind_s(dn, safe_str(password)) | |
|
155 | user = server.search_ext_s( | |
|
156 | dn, ldap.SCOPE_BASE, '(objectClass=*)', )[0] | |
|
157 | _, attrs = user | |
|
158 | return attrs | |
|
159 | ||
|
160 | except ldap.INVALID_CREDENTIALS: | |
|
161 | log.debug( | |
|
162 | "LDAP rejected password for user '%s': %s, org_exc:", | |
|
163 | username, dn, exc_info=True) | |
|
164 | ||
|
165 | def authenticate_ldap(self, username, password): | |
|
166 | """ | |
|
167 | Authenticate a user via LDAP and return his/her LDAP properties. | |
|
168 | ||
|
169 | Raises AuthenticationError if the credentials are rejected, or | |
|
170 | EnvironmentError if the LDAP server can't be reached. | |
|
171 | ||
|
172 | :param username: username | |
|
173 | :param password: password | |
|
174 | """ | |
|
175 | ||
|
176 | uid = self.get_uid(username, self.SERVER_ADDRESSES) | |
|
177 | user_attrs = {} | |
|
178 | dn = '' | |
|
179 | ||
|
180 | self.validate_password(username, password) | |
|
181 | self.validate_username(username) | |
|
182 | ||
|
183 | ldap_conn = None | |
|
184 | try: | |
|
185 | ldap_conn = self._get_ldap_conn() | |
|
186 | filter_ = '(&%s(%s=%s))' % ( | |
|
187 | self.LDAP_FILTER, self.attr_login, username) | |
|
188 | log.debug("Authenticating %r filter %s", self.BASE_DN, filter_) | |
|
189 | ||
|
190 | lobjects = ldap_conn.search_ext_s( | |
|
191 | self.BASE_DN, self.SEARCH_SCOPE, filter_) | |
|
192 | ||
|
193 | if not lobjects: | |
|
194 | log.debug("No matching LDAP objects for authentication " | |
|
195 | "of UID:'%s' username:(%s)", uid, username) | |
|
196 | raise ldap.NO_SUCH_OBJECT() | |
|
197 | ||
|
198 | log.debug('Found matching ldap object, trying to authenticate') | |
|
199 | for (dn, _attrs) in lobjects: | |
|
200 | if dn is None: | |
|
201 | continue | |
|
202 | ||
|
203 | user_attrs = self.fetch_attrs_from_simple_bind( | |
|
204 | ldap_conn, dn, username, password) | |
|
205 | if user_attrs: | |
|
206 | break | |
|
207 | else: | |
|
208 | raise LdapPasswordError( | |
|
209 | 'Failed to authenticate user `{}`' | |
|
210 | 'with given password'.format(username)) | |
|
211 | ||
|
212 | except ldap.NO_SUCH_OBJECT: | |
|
213 | log.debug("LDAP says no such user '%s' (%s), org_exc:", | |
|
214 | uid, username, exc_info=True) | |
|
215 | raise LdapUsernameError('Unable to find user') | |
|
216 | except ldap.SERVER_DOWN: | |
|
217 | org_exc = traceback.format_exc() | |
|
218 | raise LdapConnectionError( | |
|
219 | "LDAP can't access authentication " | |
|
220 | "server, org_exc:%s" % org_exc) | |
|
221 | finally: | |
|
222 | if ldap_conn: | |
|
223 | log.debug('ldap: connection release') | |
|
224 | try: | |
|
225 | ldap_conn.unbind_s() | |
|
226 | except Exception: | |
|
227 | # for any reason this can raise exception we must catch it | |
|
228 | # to not crush the server | |
|
229 | pass | |
|
230 | ||
|
231 | return dn, user_attrs | |
|
232 | ||
|
233 | ||
|
69 | 234 | class LdapSettingsSchema(AuthnPluginSettingsSchemaBase): |
|
70 | 235 | tls_kind_choices = ['PLAIN', 'LDAPS', 'START_TLS'] |
|
71 | 236 | tls_reqcert_choices = ['NEVER', 'ALLOW', 'TRY', 'DEMAND', 'HARD'] |
@@ -84,7 +249,7 b' class LdapSettingsSchema(AuthnPluginSett' | |||
|
84 | 249 | colander.Int(), |
|
85 | 250 | default=389, |
|
86 | 251 | description=_('Custom port that the LDAP server is listening on. ' |
|
87 | 'Default value is: 389'), | |
|
252 | 'Default value is: 389, use 689 for LDAPS(SSL)'), | |
|
88 | 253 | preparer=strip_whitespace, |
|
89 | 254 | title=_('Port'), |
|
90 | 255 | validator=colander.Range(min=0, max=65536), |
@@ -133,6 +298,22 b' class LdapSettingsSchema(AuthnPluginSett' | |||
|
133 | 298 | title=_('Certificate Checks'), |
|
134 | 299 | validator=colander.OneOf(tls_reqcert_choices), |
|
135 | 300 | widget='select') |
|
301 | tls_cert_file = colander.SchemaNode( | |
|
302 | colander.String(), | |
|
303 | default='', | |
|
304 | description=_('This specifies the PEM-format file path containing ' | |
|
305 | 'certificates for use in TLS connection.\n' | |
|
306 | 'If not specified `TLS Cert dir` will be used'), | |
|
307 | title=_('TLS Cert file'), | |
|
308 | missing='', | |
|
309 | widget='string') | |
|
310 | tls_cert_dir = colander.SchemaNode( | |
|
311 | colander.String(), | |
|
312 | default=AuthLdap.default_tls_cert_dir, | |
|
313 | description=_('This specifies the path of a directory that contains individual ' | |
|
314 | 'CA certificates in separate files.'), | |
|
315 | title=_('TLS Cert dir'), | |
|
316 | widget='string') | |
|
136 | 317 | base_dn = colander.SchemaNode( |
|
137 | 318 | colander.String(), |
|
138 | 319 | default='', |
@@ -169,6 +350,16 b' class LdapSettingsSchema(AuthnPluginSett' | |||
|
169 | 350 | title=_('Login Attribute'), |
|
170 | 351 | missing_msg=_('The LDAP Login attribute of the CN must be specified'), |
|
171 | 352 | widget='string') |
|
353 | attr_email = colander.SchemaNode( | |
|
354 | colander.String(), | |
|
355 | default='', | |
|
356 | description=_('LDAP Attribute to map to email address (e.g., mail).\n' | |
|
357 | 'Emails are a crucial part of RhodeCode. \n' | |
|
358 | 'If possible add a valid email attribute to ldap users.'), | |
|
359 | missing='', | |
|
360 | preparer=strip_whitespace, | |
|
361 | title=_('Email Attribute'), | |
|
362 | widget='string') | |
|
172 | 363 | attr_firstname = colander.SchemaNode( |
|
173 | 364 | colander.String(), |
|
174 | 365 | default='', |
@@ -185,182 +376,10 b' class LdapSettingsSchema(AuthnPluginSett' | |||
|
185 | 376 | preparer=strip_whitespace, |
|
186 | 377 | title=_('Last Name Attribute'), |
|
187 | 378 | widget='string') |
|
188 | attr_email = colander.SchemaNode( | |
|
189 | colander.String(), | |
|
190 | default='', | |
|
191 | description=_('LDAP Attribute to map to email address (e.g., mail).\n' | |
|
192 | 'Emails are a crucial part of RhodeCode. \n' | |
|
193 | 'If possible add a valid email attribute to ldap users.'), | |
|
194 | missing='', | |
|
195 | preparer=strip_whitespace, | |
|
196 | title=_('Email Attribute'), | |
|
197 | widget='string') | |
|
198 | ||
|
199 | ||
|
200 | class AuthLdap(AuthLdapBase): | |
|
201 | ||
|
202 | def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='', | |
|
203 | tls_kind='PLAIN', tls_reqcert='DEMAND', ldap_version=3, | |
|
204 | search_scope='SUBTREE', attr_login='uid', | |
|
205 | ldap_filter='', timeout=None): | |
|
206 | if ldap == Missing: | |
|
207 | raise LdapImportError("Missing or incompatible ldap library") | |
|
208 | ||
|
209 | self.debug = False | |
|
210 | self.timeout = timeout or 60 * 5 | |
|
211 | self.ldap_version = ldap_version | |
|
212 | self.ldap_server_type = 'ldap' | |
|
213 | ||
|
214 | self.TLS_KIND = tls_kind | |
|
215 | ||
|
216 | if self.TLS_KIND == 'LDAPS': | |
|
217 | port = port or 689 | |
|
218 | self.ldap_server_type += 's' | |
|
219 | ||
|
220 | OPT_X_TLS_DEMAND = 2 | |
|
221 | self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert, | |
|
222 | OPT_X_TLS_DEMAND) | |
|
223 | self.LDAP_SERVER = server | |
|
224 | # split server into list | |
|
225 | self.SERVER_ADDRESSES = self._get_server_list(server) | |
|
226 | self.LDAP_SERVER_PORT = port | |
|
227 | ||
|
228 | # USE FOR READ ONLY BIND TO LDAP SERVER | |
|
229 | self.attr_login = attr_login | |
|
230 | ||
|
231 | self.LDAP_BIND_DN = safe_str(bind_dn) | |
|
232 | self.LDAP_BIND_PASS = safe_str(bind_pass) | |
|
233 | ||
|
234 | self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope) | |
|
235 | self.BASE_DN = safe_str(base_dn) | |
|
236 | self.LDAP_FILTER = safe_str(ldap_filter) | |
|
237 | ||
|
238 | def _get_ldap_conn(self): | |
|
239 | ||
|
240 | if self.debug: | |
|
241 | ldap.set_option(ldap.OPT_DEBUG_LEVEL, 255) | |
|
242 | ||
|
243 | if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'): | |
|
244 | ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, '/etc/openldap/cacerts') | |
|
245 | if self.TLS_KIND != 'PLAIN': | |
|
246 | ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT) | |
|
247 | ||
|
248 | ldap.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF) | |
|
249 | ldap.set_option(ldap.OPT_RESTART, ldap.OPT_ON) | |
|
250 | ||
|
251 | # init connection now | |
|
252 | ldap_servers = self._build_servers( | |
|
253 | self.ldap_server_type, self.SERVER_ADDRESSES, self.LDAP_SERVER_PORT) | |
|
254 | log.debug('initializing LDAP connection to:%s', ldap_servers) | |
|
255 | ldap_conn = ldap.initialize(ldap_servers) | |
|
256 | ldap_conn.set_option(ldap.OPT_NETWORK_TIMEOUT, self.timeout) | |
|
257 | ldap_conn.set_option(ldap.OPT_TIMEOUT, self.timeout) | |
|
258 | ldap_conn.timeout = self.timeout | |
|
259 | ||
|
260 | if self.ldap_version == 2: | |
|
261 | ldap_conn.protocol = ldap.VERSION2 | |
|
262 | else: | |
|
263 | ldap_conn.protocol = ldap.VERSION3 | |
|
264 | ||
|
265 | if self.TLS_KIND == 'START_TLS': | |
|
266 | ldap_conn.start_tls_s() | |
|
267 | ||
|
268 | if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: | |
|
269 | log.debug('Trying simple_bind with password and given login DN: %s', | |
|
270 | self.LDAP_BIND_DN) | |
|
271 | ldap_conn.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS) | |
|
272 | ||
|
273 | return ldap_conn | |
|
274 | ||
|
275 | def fetch_attrs_from_simple_bind(self, server, dn, username, password): | |
|
276 | try: | |
|
277 | log.debug('Trying simple bind with %s', dn) | |
|
278 | server.simple_bind_s(dn, safe_str(password)) | |
|
279 | user = server.search_ext_s( | |
|
280 | dn, ldap.SCOPE_BASE, '(objectClass=*)', )[0] | |
|
281 | _, attrs = user | |
|
282 | return attrs | |
|
283 | ||
|
284 | except ldap.INVALID_CREDENTIALS: | |
|
285 | log.debug( | |
|
286 | "LDAP rejected password for user '%s': %s, org_exc:", | |
|
287 | username, dn, exc_info=True) | |
|
288 | ||
|
289 | def authenticate_ldap(self, username, password): | |
|
290 | """ | |
|
291 | Authenticate a user via LDAP and return his/her LDAP properties. | |
|
292 | ||
|
293 | Raises AuthenticationError if the credentials are rejected, or | |
|
294 | EnvironmentError if the LDAP server can't be reached. | |
|
295 | ||
|
296 | :param username: username | |
|
297 | :param password: password | |
|
298 | """ | |
|
299 | ||
|
300 | uid = self.get_uid(username, self.SERVER_ADDRESSES) | |
|
301 | user_attrs = {} | |
|
302 | dn = '' | |
|
303 | ||
|
304 | if not password: | |
|
305 | msg = "Authenticating user %s with blank password not allowed" | |
|
306 | log.warning(msg, username) | |
|
307 | raise LdapPasswordError(msg) | |
|
308 | if "," in username: | |
|
309 | raise LdapUsernameError( | |
|
310 | "invalid character `,` in username: `{}`".format(username)) | |
|
311 | ldap_conn = None | |
|
312 | try: | |
|
313 | ldap_conn = self._get_ldap_conn() | |
|
314 | filter_ = '(&%s(%s=%s))' % ( | |
|
315 | self.LDAP_FILTER, self.attr_login, username) | |
|
316 | log.debug( | |
|
317 | "Authenticating %r filter %s", self.BASE_DN, filter_) | |
|
318 | lobjects = ldap_conn.search_ext_s( | |
|
319 | self.BASE_DN, self.SEARCH_SCOPE, filter_) | |
|
320 | ||
|
321 | if not lobjects: | |
|
322 | log.debug("No matching LDAP objects for authentication " | |
|
323 | "of UID:'%s' username:(%s)", uid, username) | |
|
324 | raise ldap.NO_SUCH_OBJECT() | |
|
325 | ||
|
326 | log.debug('Found matching ldap object, trying to authenticate') | |
|
327 | for (dn, _attrs) in lobjects: | |
|
328 | if dn is None: | |
|
329 | continue | |
|
330 | ||
|
331 | user_attrs = self.fetch_attrs_from_simple_bind( | |
|
332 | ldap_conn, dn, username, password) | |
|
333 | if user_attrs: | |
|
334 | break | |
|
335 | ||
|
336 | else: | |
|
337 | raise LdapPasswordError( | |
|
338 | 'Failed to authenticate user `{}`' | |
|
339 | 'with given password'.format(username)) | |
|
340 | ||
|
341 | except ldap.NO_SUCH_OBJECT: | |
|
342 | log.debug("LDAP says no such user '%s' (%s), org_exc:", | |
|
343 | uid, username, exc_info=True) | |
|
344 | raise LdapUsernameError('Unable to find user') | |
|
345 | except ldap.SERVER_DOWN: | |
|
346 | org_exc = traceback.format_exc() | |
|
347 | raise LdapConnectionError( | |
|
348 | "LDAP can't access authentication " | |
|
349 | "server, org_exc:%s" % org_exc) | |
|
350 | finally: | |
|
351 | if ldap_conn: | |
|
352 | log.debug('ldap: connection release') | |
|
353 | try: | |
|
354 | ldap_conn.unbind_s() | |
|
355 | except Exception: | |
|
356 | # for any reason this can raise exception we must catch it | |
|
357 | # to not crush the server | |
|
358 | pass | |
|
359 | ||
|
360 | return dn, user_attrs | |
|
361 | 379 | |
|
362 | 380 | |
|
363 | 381 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
382 | uid = 'ldap' | |
|
364 | 383 | # used to define dynamic binding in the |
|
365 | 384 | DYNAMIC_BIND_VAR = '$login' |
|
366 | 385 | _settings_unsafe_keys = ['dn_pass'] |
@@ -389,9 +408,13 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
389 | 408 | def get_display_name(self): |
|
390 | 409 | return _('LDAP') |
|
391 | 410 | |
|
411 | @classmethod | |
|
412 | def docs(cls): | |
|
413 | return "https://docs.rhodecode.com/RhodeCode-Enterprise/auth/auth-ldap.html" | |
|
414 | ||
|
392 | 415 | @hybrid_property |
|
393 | 416 | def name(self): |
|
394 | return "ldap" | |
|
417 | return u"ldap" | |
|
395 | 418 | |
|
396 | 419 | def use_fake_password(self): |
|
397 | 420 | return True |
@@ -448,6 +471,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
448 | 471 | 'bind_pass': settings.get('dn_pass'), |
|
449 | 472 | 'tls_kind': settings.get('tls_kind'), |
|
450 | 473 | 'tls_reqcert': settings.get('tls_reqcert'), |
|
474 | 'tls_cert_file': settings.get('tls_cert_file'), | |
|
475 | 'tls_cert_dir': settings.get('tls_cert_dir'), | |
|
451 | 476 | 'search_scope': settings.get('search_scope'), |
|
452 | 477 | 'attr_login': settings.get('attr_login'), |
|
453 | 478 | 'ldap_version': 3, |
@@ -477,12 +502,11 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
477 | 502 | extern_type = getattr(userobj, 'extern_type', '') |
|
478 | 503 | |
|
479 | 504 | groups = [] |
|
505 | ||
|
480 | 506 | user_attrs = { |
|
481 | 507 | 'username': username, |
|
482 | 'firstname': safe_unicode( | |
|
483 |
|
|
|
484 | 'lastname': safe_unicode( | |
|
485 | get_ldap_attr('attr_lastname') or lastname), | |
|
508 | 'firstname': safe_unicode(get_ldap_attr('attr_firstname') or firstname), | |
|
509 | 'lastname': safe_unicode(get_ldap_attr('attr_lastname') or lastname), | |
|
486 | 510 | 'groups': groups, |
|
487 | 511 | 'user_group_sync': False, |
|
488 | 512 | 'email': get_ldap_attr('attr_email') or email, |
@@ -492,6 +516,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
492 | 516 | 'extern_name': user_dn, |
|
493 | 517 | 'extern_type': extern_type, |
|
494 | 518 | } |
|
519 | ||
|
495 | 520 | log.debug('ldap user: %s', user_attrs) |
|
496 | 521 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
497 | 522 | |
@@ -504,3 +529,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
504 | 529 | log.exception("Other exception") |
|
505 | 530 | return None |
|
506 | 531 | |
|
532 | ||
|
533 | def includeme(config): | |
|
534 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) | |
|
535 | plugin_factory(plugin_id).includeme(config) |
@@ -40,7 +40,7 b' from rhodecode.lib.colander_utils import' | |||
|
40 | 40 | log = logging.getLogger(__name__) |
|
41 | 41 | |
|
42 | 42 | |
|
43 |
def plugin_factory(plugin_id, *args, **kw |
|
|
43 | def plugin_factory(plugin_id, *args, **kwargs): | |
|
44 | 44 | """ |
|
45 | 45 | Factory function that is called during plugin discovery. |
|
46 | 46 | It returns the plugin instance. |
@@ -72,6 +72,7 b' class PamSettingsSchema(AuthnPluginSetti' | |||
|
72 | 72 | |
|
73 | 73 | |
|
74 | 74 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
75 | uid = 'pam' | |
|
75 | 76 | # PAM authentication can be slow. Repository operations involve a lot of |
|
76 | 77 | # auth calls. Little caching helps speedup push/pull operations significantly |
|
77 | 78 | AUTH_CACHE_TTL = 4 |
@@ -97,9 +98,13 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
97 | 98 | def get_display_name(self): |
|
98 | 99 | return _('PAM') |
|
99 | 100 | |
|
101 | @classmethod | |
|
102 | def docs(cls): | |
|
103 | return "https://docs.rhodecode.com/RhodeCode-Enterprise/auth/auth-pam.html" | |
|
104 | ||
|
100 | 105 | @hybrid_property |
|
101 | 106 | def name(self): |
|
102 | return "pam" | |
|
107 | return u"pam" | |
|
103 | 108 | |
|
104 | 109 | def get_settings_schema(self): |
|
105 | 110 | return PamSettingsSchema() |
@@ -159,3 +164,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
159 | 164 | log.debug("pamuser: %s", user_attrs) |
|
160 | 165 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
161 | 166 | return user_attrs |
|
167 | ||
|
168 | ||
|
169 | def includeme(config): | |
|
170 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) | |
|
171 | plugin_factory(plugin_id).includeme(config) |
@@ -34,7 +34,7 b' from rhodecode.model.db import User' | |||
|
34 | 34 | log = logging.getLogger(__name__) |
|
35 | 35 | |
|
36 | 36 | |
|
37 |
def plugin_factory(plugin_id, *args, **kw |
|
|
37 | def plugin_factory(plugin_id, *args, **kwargs): | |
|
38 | 38 | plugin = RhodeCodeAuthPlugin(plugin_id) |
|
39 | 39 | return plugin |
|
40 | 40 | |
@@ -44,6 +44,7 b' class RhodecodeAuthnResource(AuthnPlugin' | |||
|
44 | 44 | |
|
45 | 45 | |
|
46 | 46 | class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): |
|
47 | uid = 'rhodecode' | |
|
47 | 48 | |
|
48 | 49 | def includeme(self, config): |
|
49 | 50 | config.add_authn_plugin(self) |
@@ -64,11 +65,15 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
64 | 65 | context=RhodecodeAuthnResource) |
|
65 | 66 | |
|
66 | 67 | def get_display_name(self): |
|
67 |
return _('Rhode |
|
|
68 | return _('RhodeCode Internal') | |
|
69 | ||
|
70 | @classmethod | |
|
71 | def docs(cls): | |
|
72 | return "https://docs.rhodecode.com/RhodeCode-Enterprise/auth/auth.html" | |
|
68 | 73 | |
|
69 | 74 | @hybrid_property |
|
70 | 75 | def name(self): |
|
71 | return "rhodecode" | |
|
76 | return u"rhodecode" | |
|
72 | 77 | |
|
73 | 78 | def user_activation_state(self): |
|
74 | 79 | def_user_perms = User.get_default_user().AuthUser().permissions['global'] |
@@ -141,3 +146,8 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
141 | 146 | 'user `%s` failed to authenticate via %s, reason: account not ' |
|
142 | 147 | 'active.', username, self.name) |
|
143 | 148 | return None |
|
149 | ||
|
150 | ||
|
151 | def includeme(config): | |
|
152 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) | |
|
153 | plugin_factory(plugin_id).includeme(config) |
@@ -34,7 +34,7 b' from rhodecode.model.db import User, Use' | |||
|
34 | 34 | log = logging.getLogger(__name__) |
|
35 | 35 | |
|
36 | 36 | |
|
37 |
def plugin_factory(plugin_id, *args, **kw |
|
|
37 | def plugin_factory(plugin_id, *args, **kwargs): | |
|
38 | 38 | plugin = RhodeCodeAuthPlugin(plugin_id) |
|
39 | 39 | return plugin |
|
40 | 40 | |
@@ -47,6 +47,7 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
47 | 47 | """ |
|
48 | 48 | Enables usage of authentication tokens for vcs operations. |
|
49 | 49 | """ |
|
50 | uid = 'token' | |
|
50 | 51 | |
|
51 | 52 | def includeme(self, config): |
|
52 | 53 | config.add_authn_plugin(self) |
@@ -67,11 +68,15 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
67 | 68 | context=RhodecodeAuthnResource) |
|
68 | 69 | |
|
69 | 70 | def get_display_name(self): |
|
70 |
return _('Rhodecode Token |
|
|
71 | return _('Rhodecode Token') | |
|
72 | ||
|
73 | @classmethod | |
|
74 | def docs(cls): | |
|
75 | return "https://docs.rhodecode.com/RhodeCode-Enterprise/auth/auth-token.html" | |
|
71 | 76 | |
|
72 | 77 | @hybrid_property |
|
73 | 78 | def name(self): |
|
74 | return "authtoken" | |
|
79 | return u"authtoken" | |
|
75 | 80 | |
|
76 | 81 | def user_activation_state(self): |
|
77 | 82 | def_user_perms = User.get_default_user().AuthUser().permissions['global'] |
@@ -145,3 +150,8 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
145 | 150 | 'user `%s` failed to authenticate via %s, reason: account not ' |
|
146 | 151 | 'active.', username, self.name) |
|
147 | 152 | return None |
|
153 | ||
|
154 | ||
|
155 | def includeme(config): | |
|
156 | plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid) | |
|
157 | plugin_factory(plugin_id).includeme(config) |
@@ -19,6 +19,7 b'' | |||
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | 21 | import logging |
|
22 | import collections | |
|
22 | 23 | |
|
23 | 24 | from pyramid.exceptions import ConfigurationError |
|
24 | 25 | |
@@ -55,9 +56,9 b' class AuthnRootResource(AuthnResourceBas' | |||
|
55 | 56 | """ |
|
56 | 57 | |
|
57 | 58 | def __init__(self): |
|
58 |
self._store = |
|
|
59 | self._store = collections.OrderedDict() | |
|
59 | 60 | self._resource_name_map = {} |
|
60 |
self.display_name = _(' |
|
|
61 | self.display_name = _('Authentication Plugins') | |
|
61 | 62 | |
|
62 | 63 | def __getitem__(self, key): |
|
63 | 64 | """ |
@@ -87,23 +88,27 b' class AuthnRootResource(AuthnResourceBas' | |||
|
87 | 88 | # TODO: Store this info in the resource element. |
|
88 | 89 | return self._resource_name_map[resource_name] |
|
89 | 90 | |
|
90 | def get_sorted_list(self): | |
|
91 | def get_sorted_list(self, sort_key=None): | |
|
91 | 92 | """ |
|
92 | 93 | Returns a sorted list of sub resources for displaying purposes. |
|
93 | 94 | """ |
|
94 | def sort_key(resource): | |
|
95 | def default_sort_key(resource): | |
|
95 | 96 | return str.lower(safe_str(resource.display_name)) |
|
96 | 97 | |
|
97 | 98 | active = [item for item in self] |
|
98 | return sorted(active, key=sort_key) | |
|
99 | return sorted(active, key=sort_key or default_sort_key) | |
|
99 | 100 | |
|
100 | def get_nav_list(self): | |
|
101 | def get_nav_list(self, sort=True): | |
|
101 | 102 | """ |
|
102 | 103 | Returns a sorted list of resources for displaying the navigation. |
|
103 | 104 | """ |
|
104 | list = self.get_sorted_list() | |
|
105 | list.insert(0, self) | |
|
106 |
|
|
|
105 | if sort: | |
|
106 | nav_list = self.get_sorted_list() | |
|
107 | else: | |
|
108 | nav_list = [item for item in self] | |
|
109 | ||
|
110 | nav_list.insert(0, self) | |
|
111 | return nav_list | |
|
107 | 112 | |
|
108 | 113 | def add_authn_resource(self, config, plugin_id, resource): |
|
109 | 114 | """ |
@@ -23,6 +23,7 b' import sys' | |||
|
23 | 23 | import logging |
|
24 | 24 | import collections |
|
25 | 25 | import tempfile |
|
26 | import time | |
|
26 | 27 | |
|
27 | 28 | from paste.gzipper import make_gzip_middleware |
|
28 | 29 | import pyramid.events |
@@ -63,6 +64,14 b' def is_http_error(response):' | |||
|
63 | 64 | return response.status_code > 499 |
|
64 | 65 | |
|
65 | 66 | |
|
67 | def should_load_all(): | |
|
68 | """ | |
|
69 | Returns if all application components should be loaded. In some cases it's | |
|
70 | desired to skip apps loading for faster shell script execution | |
|
71 | """ | |
|
72 | return True | |
|
73 | ||
|
74 | ||
|
66 | 75 | def make_pyramid_app(global_config, **settings): |
|
67 | 76 | """ |
|
68 | 77 | Constructs the WSGI application based on Pyramid. |
@@ -78,8 +87,13 b' def make_pyramid_app(global_config, **se' | |||
|
78 | 87 | |
|
79 | 88 | # Allows to use format style "{ENV_NAME}" placeholders in the configuration. It |
|
80 | 89 | # will be replaced by the value of the environment variable "NAME" in this case. |
|
81 | environ = { | |
|
82 | 'ENV_{}'.format(key): value for key, value in os.environ.items()} | |
|
90 | start_time = time.time() | |
|
91 | ||
|
92 | debug = asbool(global_config.get('debug')) | |
|
93 | if debug: | |
|
94 | enable_debug() | |
|
95 | ||
|
96 | environ = {'ENV_{}'.format(key): value for key, value in os.environ.items()} | |
|
83 | 97 | |
|
84 | 98 | global_config = _substitute_values(global_config, environ) |
|
85 | 99 | settings = _substitute_values(settings, environ) |
@@ -105,8 +119,10 b' def make_pyramid_app(global_config, **se' | |||
|
105 | 119 | config.configure_celery(global_config['__file__']) |
|
106 | 120 | # creating the app uses a connection - return it after we are done |
|
107 | 121 | meta.Session.remove() |
|
122 | total_time = time.time() - start_time | |
|
123 | log.info('Pyramid app `%s` created and configured in %.2fs', | |
|
124 | pyramid_app.func_name, total_time) | |
|
108 | 125 | |
|
109 | log.info('Pyramid app %s created and configured.', pyramid_app) | |
|
110 | 126 | return pyramid_app |
|
111 | 127 | |
|
112 | 128 | |
@@ -215,6 +231,7 b' def includeme_first(config):' | |||
|
215 | 231 | |
|
216 | 232 | |
|
217 | 233 | def includeme(config): |
|
234 | log.debug('Initializing main includeme from %s', os.path.basename(__file__)) | |
|
218 | 235 | settings = config.registry.settings |
|
219 | 236 | config.set_request_factory(Request) |
|
220 | 237 | |
@@ -229,41 +246,58 b' def includeme(config):' | |||
|
229 | 246 | if asbool(settings.get('appenlight', 'false')): |
|
230 | 247 | config.include('appenlight_client.ext.pyramid_tween') |
|
231 | 248 | |
|
249 | load_all = should_load_all() | |
|
250 | ||
|
232 | 251 | # Includes which are required. The application would fail without them. |
|
233 | 252 | config.include('pyramid_mako') |
|
234 | 253 | config.include('pyramid_beaker') |
|
235 | 254 | config.include('rhodecode.lib.rc_cache') |
|
236 | 255 | |
|
256 | config.include('rhodecode.apps._base.navigation') | |
|
257 | config.include('rhodecode.apps._base.subscribers') | |
|
258 | config.include('rhodecode.tweens') | |
|
259 | ||
|
260 | config.include('rhodecode.integrations') | |
|
237 | 261 | config.include('rhodecode.authentication') |
|
238 | config.include('rhodecode.integrations') | |
|
262 | ||
|
263 | if load_all: | |
|
264 | from rhodecode.authentication import discover_legacy_plugins | |
|
265 | # load CE authentication plugins | |
|
266 | config.include('rhodecode.authentication.plugins.auth_crowd') | |
|
267 | config.include('rhodecode.authentication.plugins.auth_headers') | |
|
268 | config.include('rhodecode.authentication.plugins.auth_jasig_cas') | |
|
269 | config.include('rhodecode.authentication.plugins.auth_ldap') | |
|
270 | config.include('rhodecode.authentication.plugins.auth_pam') | |
|
271 | config.include('rhodecode.authentication.plugins.auth_rhodecode') | |
|
272 | config.include('rhodecode.authentication.plugins.auth_token') | |
|
273 | ||
|
274 | # Auto discover authentication plugins and include their configuration. | |
|
275 | discover_legacy_plugins(config) | |
|
239 | 276 | |
|
240 | 277 | # apps |
|
241 | 278 | config.include('rhodecode.apps._base') |
|
242 | config.include('rhodecode.apps.ops') | |
|
243 | 279 | |
|
244 | config.include('rhodecode.apps.admin') | |
|
245 |
config.include('rhodecode.apps. |
|
|
246 |
config.include('rhodecode.apps. |
|
|
247 |
config.include('rhodecode.apps. |
|
|
248 |
config.include('rhodecode.apps. |
|
|
249 |
config.include('rhodecode.apps. |
|
|
250 |
config.include('rhodecode.apps. |
|
|
251 |
config.include('rhodecode.apps. |
|
|
252 |
config.include('rhodecode.apps. |
|
|
253 |
config.include('rhodecode.apps.user_ |
|
|
254 |
config.include('rhodecode.apps. |
|
|
255 |
config.include('rhodecode.apps. |
|
|
256 |
config.include('rhodecode.apps. |
|
|
257 |
config.include('rhodecode.apps. |
|
|
258 |
config.include('rhodecode.apps. |
|
|
280 | if load_all: | |
|
281 | config.include('rhodecode.apps.ops') | |
|
282 | config.include('rhodecode.apps.admin') | |
|
283 | config.include('rhodecode.apps.channelstream') | |
|
284 | config.include('rhodecode.apps.login') | |
|
285 | config.include('rhodecode.apps.home') | |
|
286 | config.include('rhodecode.apps.journal') | |
|
287 | config.include('rhodecode.apps.repository') | |
|
288 | config.include('rhodecode.apps.repo_group') | |
|
289 | config.include('rhodecode.apps.user_group') | |
|
290 | config.include('rhodecode.apps.search') | |
|
291 | config.include('rhodecode.apps.user_profile') | |
|
292 | config.include('rhodecode.apps.user_group_profile') | |
|
293 | config.include('rhodecode.apps.my_account') | |
|
294 | config.include('rhodecode.apps.svn_support') | |
|
295 | config.include('rhodecode.apps.ssh_support') | |
|
296 | config.include('rhodecode.apps.gist') | |
|
297 | config.include('rhodecode.apps.debug_style') | |
|
298 | config.include('rhodecode.api') | |
|
259 | 299 | |
|
260 | config.include('rhodecode.apps.debug_style') | |
|
261 | config.include('rhodecode.tweens') | |
|
262 | config.include('rhodecode.api') | |
|
263 | ||
|
264 | config.add_route( | |
|
265 | 'rhodecode_support', 'https://rhodecode.com/help/', static=True) | |
|
266 | ||
|
300 | config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True) | |
|
267 | 301 | config.add_translation_dirs('rhodecode:i18n/') |
|
268 | 302 | settings['default_locale_name'] = settings.get('lang', 'en') |
|
269 | 303 | |
@@ -403,6 +437,114 b' def sanitize_settings_and_apply_defaults' | |||
|
403 | 437 | return settings |
|
404 | 438 | |
|
405 | 439 | |
|
440 | def enable_debug(): | |
|
441 | """ | |
|
442 | Helper to enable debug on running instance | |
|
443 | :return: | |
|
444 | """ | |
|
445 | import tempfile | |
|
446 | import textwrap | |
|
447 | import logging.config | |
|
448 | ||
|
449 | ini_template = textwrap.dedent(""" | |
|
450 | ##################################### | |
|
451 | ### DEBUG LOGGING CONFIGURATION #### | |
|
452 | ##################################### | |
|
453 | [loggers] | |
|
454 | keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper | |
|
455 | ||
|
456 | [handlers] | |
|
457 | keys = console, console_sql | |
|
458 | ||
|
459 | [formatters] | |
|
460 | keys = generic, color_formatter, color_formatter_sql | |
|
461 | ||
|
462 | ############# | |
|
463 | ## LOGGERS ## | |
|
464 | ############# | |
|
465 | [logger_root] | |
|
466 | level = NOTSET | |
|
467 | handlers = console | |
|
468 | ||
|
469 | [logger_sqlalchemy] | |
|
470 | level = INFO | |
|
471 | handlers = console_sql | |
|
472 | qualname = sqlalchemy.engine | |
|
473 | propagate = 0 | |
|
474 | ||
|
475 | [logger_beaker] | |
|
476 | level = DEBUG | |
|
477 | handlers = | |
|
478 | qualname = beaker.container | |
|
479 | propagate = 1 | |
|
480 | ||
|
481 | [logger_rhodecode] | |
|
482 | level = DEBUG | |
|
483 | handlers = | |
|
484 | qualname = rhodecode | |
|
485 | propagate = 1 | |
|
486 | ||
|
487 | [logger_ssh_wrapper] | |
|
488 | level = DEBUG | |
|
489 | handlers = | |
|
490 | qualname = ssh_wrapper | |
|
491 | propagate = 1 | |
|
492 | ||
|
493 | [logger_celery] | |
|
494 | level = DEBUG | |
|
495 | handlers = | |
|
496 | qualname = celery | |
|
497 | ||
|
498 | ||
|
499 | ############## | |
|
500 | ## HANDLERS ## | |
|
501 | ############## | |
|
502 | ||
|
503 | [handler_console] | |
|
504 | class = StreamHandler | |
|
505 | args = (sys.stderr, ) | |
|
506 | level = DEBUG | |
|
507 | formatter = color_formatter | |
|
508 | ||
|
509 | [handler_console_sql] | |
|
510 | # "level = DEBUG" logs SQL queries and results. | |
|
511 | # "level = INFO" logs SQL queries. | |
|
512 | # "level = WARN" logs neither. (Recommended for production systems.) | |
|
513 | class = StreamHandler | |
|
514 | args = (sys.stderr, ) | |
|
515 | level = WARN | |
|
516 | formatter = color_formatter_sql | |
|
517 | ||
|
518 | ################ | |
|
519 | ## FORMATTERS ## | |
|
520 | ################ | |
|
521 | ||
|
522 | [formatter_generic] | |
|
523 | class = rhodecode.lib.logging_formatter.ExceptionAwareFormatter | |
|
524 | format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s | |
|
525 | datefmt = %Y-%m-%d %H:%M:%S | |
|
526 | ||
|
527 | [formatter_color_formatter] | |
|
528 | class = rhodecode.lib.logging_formatter.ColorRequestTrackingFormatter | |
|
529 | format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | %(req_id)s | |
|
530 | datefmt = %Y-%m-%d %H:%M:%S | |
|
531 | ||
|
532 | [formatter_color_formatter_sql] | |
|
533 | class = rhodecode.lib.logging_formatter.ColorFormatterSql | |
|
534 | format = %(asctime)s.%(msecs)03d [%(process)d] %(levelname)-5.5s [%(name)s] %(message)s | |
|
535 | datefmt = %Y-%m-%d %H:%M:%S | |
|
536 | """) | |
|
537 | ||
|
538 | with tempfile.NamedTemporaryFile(prefix='rc_debug_logging_', suffix='.ini', | |
|
539 | delete=False) as f: | |
|
540 | log.info('Saved Temporary DEBUG config at %s', f.name) | |
|
541 | f.write(ini_template) | |
|
542 | ||
|
543 | logging.config.fileConfig(f.name) | |
|
544 | log.debug('DEBUG MODE ON') | |
|
545 | os.remove(f.name) | |
|
546 | ||
|
547 | ||
|
406 | 548 | def _sanitize_appenlight_settings(settings): |
|
407 | 549 | _bool_setting(settings, 'appenlight', 'false') |
|
408 | 550 | |
@@ -447,7 +589,7 b' def _sanitize_cache_settings(settings):' | |||
|
447 | 589 | |
|
448 | 590 | # ensure we have our dir created |
|
449 | 591 | if not os.path.isdir(default_cache_dir): |
|
450 | os.makedirs(default_cache_dir, mode=0755) | |
|
592 | os.makedirs(default_cache_dir, mode=0o755) | |
|
451 | 593 | |
|
452 | 594 | # exception store cache |
|
453 | 595 | _string_setting( |
@@ -578,5 +720,8 b' def _substitute_values(mapping, substitu' | |||
|
578 | 720 | raise ValueError( |
|
579 | 721 | 'Failed to substitute env variable: {}. ' |
|
580 | 722 | 'Make sure you have specified this env variable without ENV_ prefix'.format(e)) |
|
723 | except ValueError as e: | |
|
724 | log.warning('Failed to substitute ENV variable: %s', e) | |
|
725 | result = mapping | |
|
581 | 726 | |
|
582 | 727 | return result |
@@ -27,6 +27,7 b' us in hooks::' | |||
|
27 | 27 | """ |
|
28 | 28 | import re |
|
29 | 29 | import collections |
|
30 | import json | |
|
30 | 31 | |
|
31 | 32 | |
|
32 | 33 | def get_hg_commits(repo, refs): |
@@ -36,6 +37,31 b' def get_hg_commits(repo, refs):' | |||
|
36 | 37 | |
|
37 | 38 | def get_git_commits(repo, refs): |
|
38 | 39 | commits = [] |
|
40 | ||
|
41 | for data in refs: | |
|
42 | # we should now extract commit data | |
|
43 | old_rev = data['old_rev'] | |
|
44 | new_rev = data['new_rev'] | |
|
45 | ||
|
46 | if '00000000' in old_rev: | |
|
47 | # new branch, we don't need to extract nothing | |
|
48 | return commits | |
|
49 | ||
|
50 | git_env = dict(data['git_env']) | |
|
51 | cmd = [ | |
|
52 | 'log', | |
|
53 | '--pretty=format:{"commit_id": "%H", "author": "%aN <%aE>", "date": "%ad", "message": "%f"}', | |
|
54 | '{}...{}'.format(old_rev, new_rev) | |
|
55 | ] | |
|
56 | ||
|
57 | stdout, stderr = repo.run_git_command(cmd, extra_env=git_env) | |
|
58 | for line in stdout.splitlines(): | |
|
59 | try: | |
|
60 | data = json.loads(line) | |
|
61 | commits.append(data) | |
|
62 | except Exception: | |
|
63 | print('Failed to load data from GIT line') | |
|
64 | ||
|
39 | 65 | return commits |
|
40 | 66 | |
|
41 | 67 | |
@@ -51,13 +77,14 b' def run(*args, **kwargs):' | |||
|
51 | 77 | |
|
52 | 78 | commits = [] |
|
53 | 79 | |
|
54 | for rev_data in kwargs['commit_ids']: | |
|
55 | new_environ = dict((k, v) for k, v in rev_data['hg_env']) | |
|
56 | ||
|
57 | 80 | if vcs_type == 'git': |
|
81 | for rev_data in kwargs['commit_ids']: | |
|
82 | new_environ = dict((k, v) for k, v in rev_data['git_env']) | |
|
58 | 83 | commits = get_git_commits(vcs_repo, kwargs['commit_ids']) |
|
59 | 84 | |
|
60 | 85 | if vcs_type == 'hg': |
|
86 | for rev_data in kwargs['commit_ids']: | |
|
87 | new_environ = dict((k, v) for k, v in rev_data['hg_env']) | |
|
61 | 88 | commits = get_hg_commits(vcs_repo, kwargs['commit_ids']) |
|
62 | 89 | |
|
63 | 90 | return commits |
@@ -145,3 +145,41 b' def maybe_log_call(name, args, kwargs):' | |||
|
145 | 145 | if hasattr(rcextensions, 'calls'): |
|
146 | 146 | calls = rcextensions.calls |
|
147 | 147 | calls[name].append((args, kwargs)) |
|
148 | ||
|
149 | ||
|
150 | def str2bool(_str): | |
|
151 | """ | |
|
152 | returns True/False value from given string, it tries to translate the | |
|
153 | string into boolean | |
|
154 | ||
|
155 | :param _str: string value to translate into boolean | |
|
156 | :rtype: boolean | |
|
157 | :returns: boolean from given string | |
|
158 | """ | |
|
159 | if _str is None: | |
|
160 | return False | |
|
161 | if _str in (True, False): | |
|
162 | return _str | |
|
163 | _str = str(_str).strip().lower() | |
|
164 | return _str in ('t', 'true', 'y', 'yes', 'on', '1') | |
|
165 | ||
|
166 | ||
|
167 | def aslist(obj, sep=None, strip=True): | |
|
168 | """ | |
|
169 | Returns given string separated by sep as list | |
|
170 | ||
|
171 | :param obj: | |
|
172 | :param sep: | |
|
173 | :param strip: | |
|
174 | """ | |
|
175 | if isinstance(obj, (basestring,)): | |
|
176 | lst = obj.split(sep) | |
|
177 | if strip: | |
|
178 | lst = [v.strip() for v in lst] | |
|
179 | return lst | |
|
180 | elif isinstance(obj, (list, tuple)): | |
|
181 | return obj | |
|
182 | elif obj is None: | |
|
183 | return [] | |
|
184 | else: | |
|
185 | return [obj] No newline at end of file |
@@ -43,7 +43,7 b' then you can retrieve the url by simply ' | |||
|
43 | 43 | The redirection must be first implemented in our servers before |
|
44 | 44 | you can see it working. |
|
45 | 45 | """ |
|
46 | # flake8: noqa | |
|
46 | # pragma: no cover | |
|
47 | 47 | from __future__ import unicode_literals |
|
48 | 48 | |
|
49 | 49 | link_config = [ |
@@ -44,7 +44,7 b' def trigger(event, registry=None):' | |||
|
44 | 44 | integrations_event_handler(event) |
|
45 | 45 | |
|
46 | 46 | |
|
47 |
from rhodecode.events.user import ( # |
|
|
47 | from rhodecode.events.user import ( # pragma: no cover | |
|
48 | 48 | UserPreCreate, |
|
49 | 49 | UserPostCreate, |
|
50 | 50 | UserPreUpdate, |
@@ -52,7 +52,7 b' from rhodecode.events.user import ( # n' | |||
|
52 | 52 | UserPermissionsChange, |
|
53 | 53 | ) |
|
54 | 54 | |
|
55 |
from rhodecode.events.repo import ( # |
|
|
55 | from rhodecode.events.repo import ( # pragma: no cover | |
|
56 | 56 | RepoEvent, |
|
57 | 57 | RepoPreCreateEvent, RepoCreateEvent, |
|
58 | 58 | RepoPreDeleteEvent, RepoDeleteEvent, |
@@ -60,14 +60,14 b' from rhodecode.events.repo import ( # n' | |||
|
60 | 60 | RepoPrePullEvent, RepoPullEvent, |
|
61 | 61 | ) |
|
62 | 62 | |
|
63 |
from rhodecode.events.repo_group import ( # |
|
|
63 | from rhodecode.events.repo_group import ( # pragma: no cover | |
|
64 | 64 | RepoGroupEvent, |
|
65 | 65 | RepoGroupCreateEvent, |
|
66 | 66 | RepoGroupUpdateEvent, |
|
67 | 67 | RepoGroupDeleteEvent, |
|
68 | 68 | ) |
|
69 | 69 | |
|
70 |
from rhodecode.events.pullrequest import ( # |
|
|
70 | from rhodecode.events.pullrequest import ( # pragma: no cover | |
|
71 | 71 | PullRequestEvent, |
|
72 | 72 | PullRequestCreateEvent, |
|
73 | 73 | PullRequestUpdateEvent, |
@@ -32,6 +32,6 b' class IntegrationTypeRegistry(collection' | |||
|
32 | 32 | if key in self: |
|
33 | 33 | log.debug( |
|
34 | 34 | 'Overriding existing integration type %s (%s) with %s', |
|
35 | self[key], key, IntegrationType) | |
|
35 | self[key].__class__, key, IntegrationType) | |
|
36 | 36 | |
|
37 | 37 | self[key] = IntegrationType |
@@ -36,6 +36,26 b' from rhodecode.integrations.types.base i' | |||
|
36 | 36 | |
|
37 | 37 | log = logging.getLogger(__name__) |
|
38 | 38 | |
|
39 | REPO_PUSH_TEMPLATE = Template(''' | |
|
40 | <b>${data['actor']['username']}</b> pushed to repo <a href="${data['repo']['url']}">${data['repo']['repo_name']}</a>: | |
|
41 | <br> | |
|
42 | <ul> | |
|
43 | %for branch, branch_commits in branches_commits.items(): | |
|
44 | <li> | |
|
45 | % if branch: | |
|
46 | <a href="${branch_commits['branch']['url']}">branch: ${branch_commits['branch']['name']}</a> | |
|
47 | % else: | |
|
48 | to trunk | |
|
49 | % endif | |
|
50 | <ul> | |
|
51 | % for commit in branch_commits['commits']: | |
|
52 | <li><a href="${commit['url']}">${commit['short_id']}</a> - ${commit['message_html']}</li> | |
|
53 | % endfor | |
|
54 | </ul> | |
|
55 | </li> | |
|
56 | %endfor | |
|
57 | ''') | |
|
58 | ||
|
39 | 59 | |
|
40 | 60 | class HipchatSettingsSchema(colander.Schema): |
|
41 | 61 | color_choices = [ |
@@ -76,27 +96,6 b' class HipchatSettingsSchema(colander.Sch' | |||
|
76 | 96 | ) |
|
77 | 97 | |
|
78 | 98 | |
|
79 | repo_push_template = Template(''' | |
|
80 | <b>${data['actor']['username']}</b> pushed to repo <a href="${data['repo']['url']}">${data['repo']['repo_name']}</a>: | |
|
81 | <br> | |
|
82 | <ul> | |
|
83 | %for branch, branch_commits in branches_commits.items(): | |
|
84 | <li> | |
|
85 | % if branch: | |
|
86 | <a href="${branch_commits['branch']['url']}">branch: ${branch_commits['branch']['name']}</a> | |
|
87 | % else: | |
|
88 | to trunk | |
|
89 | % endif | |
|
90 | <ul> | |
|
91 | % for commit in branch_commits['commits']: | |
|
92 | <li><a href="${commit['url']}">${commit['short_id']}</a> - ${commit['message_html']}</li> | |
|
93 | % endfor | |
|
94 | </ul> | |
|
95 | </li> | |
|
96 | %endfor | |
|
97 | ''') | |
|
98 | ||
|
99 | ||
|
100 | 99 | class HipchatIntegrationType(IntegrationTypeBase, CommitParsingDataHandler): |
|
101 | 100 | key = 'hipchat' |
|
102 | 101 | display_name = _('Hipchat') |
@@ -226,7 +225,7 b' class HipchatIntegrationType(Integration' | |||
|
226 | 225 | data['push']['branches'], data['push']['commits']) |
|
227 | 226 | |
|
228 | 227 | result = render_with_traceback( |
|
229 | repo_push_template, | |
|
228 | REPO_PUSH_TEMPLATE, | |
|
230 | 229 | data=data, |
|
231 | 230 | branches_commits=branches_commits, |
|
232 | 231 | ) |
@@ -41,6 +41,30 b' from rhodecode.integrations.types.base i' | |||
|
41 | 41 | log = logging.getLogger(__name__) |
|
42 | 42 | |
|
43 | 43 | |
|
44 | def html_to_slack_links(message): | |
|
45 | return re.compile(r'<a .*?href=["\'](.+?)".*?>(.+?)</a>').sub( | |
|
46 | r'<\1|\2>', message) | |
|
47 | ||
|
48 | ||
|
49 | REPO_PUSH_TEMPLATE = Template(''' | |
|
50 | <% | |
|
51 | def branch_text(branch): | |
|
52 | if branch: | |
|
53 | return 'on branch: <{}|{}>'.format(branch_commits['branch']['url'], branch_commits['branch']['name']) | |
|
54 | else: | |
|
55 | ## case for SVN no branch push... | |
|
56 | return 'to trunk' | |
|
57 | %> \ | |
|
58 | ||
|
59 | % for branch, branch_commits in branches_commits.items(): | |
|
60 | ${len(branch_commits['commits'])} ${'commit' if len(branch_commits['commits']) == 1 else 'commits'} ${branch_text(branch)} | |
|
61 | % for commit in branch_commits['commits']: | |
|
62 | `<${commit['url']}|${commit['short_id']}>` - ${commit['message_html']|html_to_slack_links} | |
|
63 | % endfor | |
|
64 | % endfor | |
|
65 | ''') | |
|
66 | ||
|
67 | ||
|
44 | 68 | class SlackSettingsSchema(colander.Schema): |
|
45 | 69 | service = colander.SchemaNode( |
|
46 | 70 | colander.String(), |
@@ -258,7 +282,6 b' class SlackIntegrationType(IntegrationTy' | |||
|
258 | 282 | return title, text |
|
259 | 283 | |
|
260 | 284 | def format_repo_push_event(self, data): |
|
261 | ||
|
262 | 285 | branches_commits = self.aggregate_branch_data( |
|
263 | 286 | data['push']['branches'], data['push']['commits']) |
|
264 | 287 | |
@@ -267,25 +290,8 b' class SlackIntegrationType(IntegrationTy' | |||
|
267 | 290 | ''') |
|
268 | 291 | title = render_with_traceback(template, data=data) |
|
269 | 292 | |
|
270 | repo_push_template = Template(textwrap.dedent(r''' | |
|
271 | <% | |
|
272 | def branch_text(branch): | |
|
273 | if branch: | |
|
274 | return 'on branch: <{}|{}>'.format(branch_commits['branch']['url'], branch_commits['branch']['name']) | |
|
275 | else: | |
|
276 | ## case for SVN no branch push... | |
|
277 | return 'to trunk' | |
|
278 | %> \ | |
|
279 | % for branch, branch_commits in branches_commits.items(): | |
|
280 | ${len(branch_commits['commits'])} ${'commit' if len(branch_commits['commits']) == 1 else 'commits'} ${branch_text(branch)} | |
|
281 | % for commit in branch_commits['commits']: | |
|
282 | `<${commit['url']}|${commit['short_id']}>` - ${commit['message_html']|html_to_slack_links} | |
|
283 | % endfor | |
|
284 | % endfor | |
|
285 | ''')) | |
|
286 | ||
|
287 | 293 | text = render_with_traceback( |
|
288 | repo_push_template, | |
|
294 | REPO_PUSH_TEMPLATE, | |
|
289 | 295 | data=data, |
|
290 | 296 | branches_commits=branches_commits, |
|
291 | 297 | html_to_slack_links=html_to_slack_links, |
@@ -308,11 +314,6 b' class SlackIntegrationType(IntegrationTy' | |||
|
308 | 314 | return title, text |
|
309 | 315 | |
|
310 | 316 | |
|
311 | def html_to_slack_links(message): | |
|
312 | return re.compile(r'<a .*?href=["\'](.+?)".*?>(.+?)</a>').sub( | |
|
313 | r'<\1|\2>', message) | |
|
314 | ||
|
315 | ||
|
316 | 317 | @async_task(ignore_result=True, base=RequestContextTask) |
|
317 | 318 | def post_text_to_slack(settings, title, text, fields=None, overrides=None): |
|
318 | 319 | log.debug('sending %s (%s) to slack %s', title, text, settings['service']) |
@@ -25,9 +25,9 b' import webhelpers.paginate' | |||
|
25 | 25 | |
|
26 | 26 | from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPNotFound |
|
27 | 27 | |
|
28 | from rhodecode.integrations import integration_type_registry | |
|
28 | 29 | from rhodecode.apps._base import BaseAppView |
|
29 |
from rhodecode.i |
|
|
30 | from rhodecode.apps.admin.navigation import navigation_list | |
|
30 | from rhodecode.apps._base.navigation import navigation_list | |
|
31 | 31 | from rhodecode.lib.auth import ( |
|
32 | 32 | LoginRequired, CSRFRequired, HasPermissionAnyDecorator, |
|
33 | 33 | HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator) |
@@ -60,6 +60,7 b' markdown_tags = [' | |||
|
60 | 60 | "table", "thead", "tbody", "tfoot", "tr", "th", "td", |
|
61 | 61 | "img", |
|
62 | 62 | "a", |
|
63 | "input", | |
|
63 | 64 | ] |
|
64 | 65 | |
|
65 | 66 | markdown_attrs = { |
@@ -68,7 +69,8 b' markdown_attrs = {' | |||
|
68 | 69 | "a": ["href", "alt", "title", "name"], |
|
69 | 70 | "abbr": ["title"], |
|
70 | 71 | "acronym": ["title"], |
|
71 | "pre": ["lang"] | |
|
72 | "pre": ["lang"], | |
|
73 | "input": ["type", "disabled"] | |
|
72 | 74 | } |
|
73 | 75 | |
|
74 | 76 | standard_styles = [ |
@@ -33,7 +33,7 b' import importlib' | |||
|
33 | 33 | from celery import Celery |
|
34 | 34 | from celery import signals |
|
35 | 35 | from celery import Task |
|
36 |
from celery import exceptions # |
|
|
36 | from celery import exceptions # pragma: no cover | |
|
37 | 37 | from kombu.serialization import register |
|
38 | 38 | from pyramid.threadlocal import get_current_request |
|
39 | 39 |
@@ -40,12 +40,12 b' from sqlalchemy import (' | |||
|
40 | 40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, |
|
41 | 41 | Text, Float, PickleType) |
|
42 | 42 | from sqlalchemy.sql.expression import true, false |
|
43 |
from sqlalchemy.sql.functions import coalesce, count # |
|
|
43 | from sqlalchemy.sql.functions import coalesce, count # pragma: no cover | |
|
44 | 44 | from sqlalchemy.orm import ( |
|
45 | 45 | relationship, joinedload, class_mapper, validates, aliased) |
|
46 | 46 | from sqlalchemy.ext.declarative import declared_attr |
|
47 | 47 | from sqlalchemy.ext.hybrid import hybrid_property |
|
48 |
from sqlalchemy.exc import IntegrityError # |
|
|
48 | from sqlalchemy.exc import IntegrityError # pragma: no cover | |
|
49 | 49 | from sqlalchemy.dialects.mysql import LONGTEXT |
|
50 | 50 | from beaker.cache import cache_region |
|
51 | 51 | from zope.cachedescriptors.property import Lazy as LazyProperty |
@@ -40,12 +40,12 b' from sqlalchemy import (' | |||
|
40 | 40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, |
|
41 | 41 | Text, Float, PickleType) |
|
42 | 42 | from sqlalchemy.sql.expression import true, false |
|
43 |
from sqlalchemy.sql.functions import coalesce, count # |
|
|
43 | from sqlalchemy.sql.functions import coalesce, count # pragma: no cover | |
|
44 | 44 | from sqlalchemy.orm import ( |
|
45 | 45 | relationship, joinedload, class_mapper, validates, aliased) |
|
46 | 46 | from sqlalchemy.ext.declarative import declared_attr |
|
47 | 47 | from sqlalchemy.ext.hybrid import hybrid_property |
|
48 |
from sqlalchemy.exc import IntegrityError # |
|
|
48 | from sqlalchemy.exc import IntegrityError # pragma: no cover | |
|
49 | 49 | from sqlalchemy.dialects.mysql import LONGTEXT |
|
50 | 50 | from beaker.cache import cache_region |
|
51 | 51 | from zope.cachedescriptors.property import Lazy as LazyProperty |
@@ -41,7 +41,7 b' from sqlalchemy.ext.hybrid import hybrid' | |||
|
41 | 41 | from sqlalchemy.orm import ( |
|
42 | 42 | relationship, joinedload, class_mapper, validates, aliased) |
|
43 | 43 | from sqlalchemy.sql.expression import true |
|
44 |
from sqlalchemy.sql.functions import coalesce, count # |
|
|
44 | from sqlalchemy.sql.functions import coalesce, count # pragma: no cover | |
|
45 | 45 | from beaker.cache import cache_region |
|
46 | 46 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
47 | 47 |
@@ -95,7 +95,7 b' class diff_match_patch:' | |||
|
95 | 95 | Array of changes. |
|
96 | 96 | """ |
|
97 | 97 | # Set a deadline by which time the diff must be complete. |
|
98 |
if deadline |
|
|
98 | if deadline is None: | |
|
99 | 99 | # Unlike in most languages, Python counts time in seconds. |
|
100 | 100 | if self.Diff_Timeout <= 0: |
|
101 | 101 | deadline = sys.maxint |
@@ -103,7 +103,7 b' class diff_match_patch:' | |||
|
103 | 103 | deadline = time.time() + self.Diff_Timeout |
|
104 | 104 | |
|
105 | 105 | # Check for null inputs. |
|
106 |
if text1 |
|
|
106 | if text1 is None or text2 is None: | |
|
107 | 107 | raise ValueError("Null inputs. (diff_main)") |
|
108 | 108 | |
|
109 | 109 | # Check for equality (speedup). |
@@ -1227,7 +1227,7 b' class diff_match_patch:' | |||
|
1227 | 1227 | Best match index or -1. |
|
1228 | 1228 | """ |
|
1229 | 1229 | # Check for null inputs. |
|
1230 |
if text |
|
|
1230 | if text is None or pattern is None: | |
|
1231 | 1231 | raise ValueError("Null inputs. (match_main)") |
|
1232 | 1232 | |
|
1233 | 1233 | loc = max(0, min(loc, len(text))) |
@@ -1018,7 +1018,7 b' def style_metatag(tag_type, value):' | |||
|
1018 | 1018 | return html_value |
|
1019 | 1019 | |
|
1020 | 1020 | |
|
1021 | def bool2icon(value): | |
|
1021 | def bool2icon(value, show_at_false=True): | |
|
1022 | 1022 | """ |
|
1023 | 1023 | Returns boolean value of a given value, represented as html element with |
|
1024 | 1024 | classes that will represent icons |
@@ -1029,8 +1029,9 b' def bool2icon(value):' | |||
|
1029 | 1029 | if value: # does bool conversion |
|
1030 | 1030 | return HTML.tag('i', class_="icon-true") |
|
1031 | 1031 | else: # not true as bool |
|
1032 | return HTML.tag('i', class_="icon-false") | |
|
1033 | ||
|
1032 | if show_at_false: | |
|
1033 | return HTML.tag('i', class_="icon-false") | |
|
1034 | return HTML.tag('i') | |
|
1034 | 1035 | |
|
1035 | 1036 | #============================================================================== |
|
1036 | 1037 | # PERMS |
@@ -264,7 +264,7 b' class WhooshResultWrapper(object):' | |||
|
264 | 264 | # inside hit object, and we don't need all |
|
265 | 265 | res = dict(hit) |
|
266 | 266 | |
|
267 |
f_path = '' # |
|
|
267 | f_path = '' # pragma: no cover | |
|
268 | 268 | if self.search_type in ['content', 'path']: |
|
269 | 269 | f_path = res['path'][len(res['repository']):] |
|
270 | 270 | f_path = f_path.lstrip(os.sep) |
@@ -126,7 +126,8 b' class ColorFormatter(ExceptionAwareForma' | |||
|
126 | 126 | def _inject_req_id(record): |
|
127 | 127 | from pyramid.threadlocal import get_current_request |
|
128 | 128 | req = get_current_request() |
|
129 | req_id = 'req_id:%-36s ' % (getattr(req, 'req_id', None)) | |
|
129 | dummy = '00000000-0000-0000-0000-000000000000' | |
|
130 | req_id = 'req_id:%-36s' % (getattr(req, 'req_id', dummy)) | |
|
130 | 131 | record.req_id = req_id |
|
131 | 132 | |
|
132 | 133 |
@@ -22,36 +22,7 b' import re' | |||
|
22 | 22 | |
|
23 | 23 | import markdown |
|
24 | 24 | |
|
25 |
from mdx_gfm import GithubFlavoredMarkdownExtension # |
|
|
26 | ||
|
27 | ||
|
28 | class FlavoredCheckboxExtension(markdown.Extension): | |
|
29 | ||
|
30 | def extendMarkdown(self, md, md_globals): | |
|
31 | md.preprocessors.add('checklist', | |
|
32 | FlavoredCheckboxPreprocessor(md), '<reference') | |
|
33 | md.postprocessors.add('checklist', | |
|
34 | FlavoredCheckboxPostprocessor(md), '>unescape') | |
|
35 | ||
|
36 | ||
|
37 | class FlavoredCheckboxPreprocessor(markdown.preprocessors.Preprocessor): | |
|
38 | """ | |
|
39 | Replaces occurrences of [ ] or [x] to checkbox input | |
|
40 | """ | |
|
41 | ||
|
42 | pattern = re.compile(r'^([*-]) \[([ x])\]') | |
|
43 | ||
|
44 | def run(self, lines): | |
|
45 | return [self._transform_line(line) for line in lines] | |
|
46 | ||
|
47 | def _transform_line(self, line): | |
|
48 | return self.pattern.sub(self._replacer, line) | |
|
49 | ||
|
50 | def _replacer(self, match): | |
|
51 | list_prefix, state = match.groups() | |
|
52 | checked = '' if state == ' ' else ' checked="checked"' | |
|
53 | return '%s <input type="checkbox" disabled="disabled"%s>' % (list_prefix, | |
|
54 | checked) | |
|
25 | from mdx_gfm import GithubFlavoredMarkdownExtension # pragma: no cover | |
|
55 | 26 | |
|
56 | 27 | |
|
57 | 28 | class FlavoredCheckboxPostprocessor(markdown.postprocessors.Postprocessor): |
@@ -40,8 +40,7 b' from docutils.writers import html4css1' | |||
|
40 | 40 | import markdown |
|
41 | 41 | |
|
42 | 42 | from rhodecode.lib.markdown_ext import GithubFlavoredMarkdownExtension |
|
43 | from rhodecode.lib.utils2 import ( | |
|
44 | safe_str, safe_unicode, md5_safe, MENTIONS_REGEX) | |
|
43 | from rhodecode.lib.utils2 import (safe_unicode, md5_safe, MENTIONS_REGEX) | |
|
45 | 44 | |
|
46 | 45 | log = logging.getLogger(__name__) |
|
47 | 46 | |
@@ -172,6 +171,32 b' def relative_path(path, request_path, is' | |||
|
172 | 171 | return u'/' + final_path |
|
173 | 172 | |
|
174 | 173 | |
|
174 | _cached_markdown_renderer = None | |
|
175 | ||
|
176 | ||
|
177 | def get_markdown_renderer(extensions, output_format): | |
|
178 | global _cached_markdown_renderer | |
|
179 | ||
|
180 | if _cached_markdown_renderer is None: | |
|
181 | _cached_markdown_renderer = markdown.Markdown( | |
|
182 | extensions=extensions, | |
|
183 | enable_attributes=False, output_format=output_format) | |
|
184 | return _cached_markdown_renderer | |
|
185 | ||
|
186 | ||
|
187 | _cached_markdown_renderer_flavored = None | |
|
188 | ||
|
189 | ||
|
190 | def get_markdown_renderer_flavored(extensions, output_format): | |
|
191 | global _cached_markdown_renderer_flavored | |
|
192 | ||
|
193 | if _cached_markdown_renderer_flavored is None: | |
|
194 | _cached_markdown_renderer_flavored = markdown.Markdown( | |
|
195 | extensions=extensions + [GithubFlavoredMarkdownExtension()], | |
|
196 | enable_attributes=False, output_format=output_format) | |
|
197 | return _cached_markdown_renderer_flavored | |
|
198 | ||
|
199 | ||
|
175 | 200 | class MarkupRenderer(object): |
|
176 | 201 | RESTRUCTUREDTEXT_DISALLOWED_DIRECTIVES = ['include', 'meta', 'raw'] |
|
177 | 202 | |
@@ -183,14 +208,10 b' class MarkupRenderer(object):' | |||
|
183 | 208 | URL_PAT = re.compile(r'(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]' |
|
184 | 209 | r'|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)') |
|
185 | 210 | |
|
186 | extensions = ['codehilite', 'extra', 'def_list', 'sane_lists'] | |
|
211 | extensions = ['markdown.extensions.codehilite', 'markdown.extensions.extra', | |
|
212 | 'markdown.extensions.def_list', 'markdown.extensions.sane_lists'] | |
|
213 | ||
|
187 | 214 | output_format = 'html4' |
|
188 | markdown_renderer = markdown.Markdown( | |
|
189 | extensions, enable_attributes=False, output_format=output_format) | |
|
190 | ||
|
191 | markdown_renderer_flavored = markdown.Markdown( | |
|
192 | extensions + [GithubFlavoredMarkdownExtension()], | |
|
193 | enable_attributes=False, output_format=output_format) | |
|
194 | 215 | |
|
195 | 216 | # extension together with weights. Lower is first means we control how |
|
196 | 217 | # extensions are attached to readme names with those. |
@@ -346,9 +367,11 b' class MarkupRenderer(object):' | |||
|
346 | 367 | """ |
|
347 | 368 | |
|
348 | 369 | if flavored: |
|
349 |
markdown_renderer = |
|
|
370 | markdown_renderer = get_markdown_renderer_flavored( | |
|
371 | cls.extensions, cls.output_format) | |
|
350 | 372 | else: |
|
351 |
markdown_renderer = |
|
|
373 | markdown_renderer = get_markdown_renderer( | |
|
374 | cls.extensions, cls.output_format) | |
|
352 | 375 | |
|
353 | 376 | if mentions: |
|
354 | 377 | mention_pat = re.compile(MENTIONS_REGEX) |
@@ -452,7 +475,7 b' class MarkupRenderer(object):' | |||
|
452 | 475 | |
|
453 | 476 | return nb, resources |
|
454 | 477 | |
|
455 | def _sanitize_resources(resources): | |
|
478 | def _sanitize_resources(input_resources): | |
|
456 | 479 | """ |
|
457 | 480 | Skip/sanitize some of the CSS generated and included in jupyter |
|
458 | 481 | so it doesn't messes up UI so much |
@@ -464,8 +487,8 b' class MarkupRenderer(object):' | |||
|
464 | 487 | # _default_template_path_default, to achieve that |
|
465 | 488 | |
|
466 | 489 | # strip the reset CSS |
|
467 | resources[0] = resources[0][resources[0].find('/*! Source'):] | |
|
468 | return resources | |
|
490 | input_resources[0] = input_resources[0][input_resources[0].find('/*! Source'):] | |
|
491 | return input_resources | |
|
469 | 492 | |
|
470 | 493 | def as_html(notebook): |
|
471 | 494 | conf = Config() |
@@ -69,6 +69,11 b' class SimpleHg(simplevcs.SimpleVCS):' | |||
|
69 | 69 | 'statlfile': 'pull', |
|
70 | 70 | 'lheads': 'pull', |
|
71 | 71 | |
|
72 | # evolve | |
|
73 | 'evoext_obshashrange_v1': 'pull', | |
|
74 | 'evoext_obshash': 'pull', | |
|
75 | 'evoext_obshash1': 'pull', | |
|
76 | ||
|
72 | 77 | 'unbundle': 'push', |
|
73 | 78 | 'pushkey': 'push', |
|
74 | 79 | } |
@@ -20,7 +20,7 b'' | |||
|
20 | 20 | |
|
21 | 21 | import os |
|
22 | 22 | from pyramid.compat import configparser |
|
23 |
from pyramid.paster import bootstrap as pyramid_bootstrap, setup_logging # |
|
|
23 | from pyramid.paster import bootstrap as pyramid_bootstrap, setup_logging # pragma: no cover | |
|
24 | 24 | from pyramid.scripting import prepare |
|
25 | 25 | |
|
26 | 26 | from rhodecode.lib.request import Request |
@@ -37,6 +37,23 b' def get_app_config(ini_path):' | |||
|
37 | 37 | return appconfig('config:{}'.format(ini_path), relative_to=os.getcwd()) |
|
38 | 38 | |
|
39 | 39 | |
|
40 | class BootstrappedRequest(Request): | |
|
41 | """ | |
|
42 | Special version of Request Which has some available methods like in pyramid. | |
|
43 | Some code (used for template rendering) requires this, and we unsure it's present. | |
|
44 | """ | |
|
45 | ||
|
46 | def translate(self, msg): | |
|
47 | return msg | |
|
48 | ||
|
49 | def plularize(self, singular, plural, n): | |
|
50 | return singular | |
|
51 | ||
|
52 | def get_partial_renderer(self, tmpl_name): | |
|
53 | from rhodecode.lib.partial_renderer import get_partial_renderer | |
|
54 | return get_partial_renderer(request=self, tmpl_name=tmpl_name) | |
|
55 | ||
|
56 | ||
|
40 | 57 | def bootstrap(config_uri, request=None, options=None, env=None): |
|
41 | 58 | if env: |
|
42 | 59 | os.environ.update(env) |
@@ -48,7 +65,7 b' def bootstrap(config_uri, request=None, ' | |||
|
48 | 65 | except (configparser.NoSectionError, configparser.NoOptionError): |
|
49 | 66 | pass |
|
50 | 67 | |
|
51 | request = request or Request.blank('/', base_url=base_url) | |
|
68 | request = request or BootstrappedRequest.blank('/', base_url=base_url) | |
|
52 | 69 | |
|
53 | 70 | return pyramid_bootstrap(config_uri, request=request, options=options) |
|
54 | 71 |
@@ -50,8 +50,8 b' from rhodecode.lib.vcs.exceptions import' | |||
|
50 | 50 | log = logging.getLogger(__name__) |
|
51 | 51 | |
|
52 | 52 | |
|
53 | FILEMODE_DEFAULT = 0100644 | |
|
54 | FILEMODE_EXECUTABLE = 0100755 | |
|
53 | FILEMODE_DEFAULT = 0o100644 | |
|
54 | FILEMODE_EXECUTABLE = 0o100755 | |
|
55 | 55 | |
|
56 | 56 | Reference = collections.namedtuple('Reference', ('type', 'name', 'commit_id')) |
|
57 | 57 | MergeResponse = collections.namedtuple( |
@@ -209,7 +209,7 b' class BaseRepository(object):' | |||
|
209 | 209 | def get_create_shadow_cache_pr_path(self, db_repo): |
|
210 | 210 | path = db_repo.cached_diffs_dir |
|
211 | 211 | if not os.path.exists(path): |
|
212 | os.makedirs(path, 0755) | |
|
212 | os.makedirs(path, 0o755) | |
|
213 | 213 | return path |
|
214 | 214 | |
|
215 | 215 | @classmethod |
@@ -942,13 +942,13 b' class BaseCommit(object):' | |||
|
942 | 942 | """ |
|
943 | 943 | raise NotImplementedError |
|
944 | 944 | |
|
945 |
def get_ |
|
|
945 | def get_path_commit(self, path, pre_load=None): | |
|
946 | 946 | """ |
|
947 | 947 | Returns last commit of the file at the given `path`. |
|
948 | 948 | |
|
949 | 949 | :param pre_load: Optional. List of commit attributes to load. |
|
950 | 950 | """ |
|
951 |
commits = self.get_ |
|
|
951 | commits = self.get_path_history(path, limit=1, pre_load=pre_load) | |
|
952 | 952 | if not commits: |
|
953 | 953 | raise RepositoryError( |
|
954 | 954 | 'Failed to fetch history for path {}. ' |
@@ -956,7 +956,7 b' class BaseCommit(object):' | |||
|
956 | 956 | path)) |
|
957 | 957 | return commits[0] |
|
958 | 958 | |
|
959 |
def get_ |
|
|
959 | def get_path_history(self, path, limit=None, pre_load=None): | |
|
960 | 960 | """ |
|
961 | 961 | Returns history of file as reversed list of :class:`BaseCommit` |
|
962 | 962 | objects for which file at given `path` has been modified. |
@@ -1046,7 +1046,7 b' class BaseCommit(object):' | |||
|
1046 | 1046 | ('tags', ','.join(self.tags)), |
|
1047 | 1047 | ] |
|
1048 | 1048 | meta = ["%s:%s" % (f_name, value) for f_name, value in metadata] |
|
1049 | file_info.append(('.archival.txt', 0644, False, '\n'.join(meta))) | |
|
1049 | file_info.append(('.archival.txt', 0o644, False, '\n'.join(meta))) | |
|
1050 | 1050 | |
|
1051 | 1051 | connection.Hg.archive_repo(file_path, mtime, file_info, kind) |
|
1052 | 1052 | |
@@ -1194,8 +1194,8 b' class BaseCommit(object):' | |||
|
1194 | 1194 | self.idx = value |
|
1195 | 1195 | |
|
1196 | 1196 | def get_file_changeset(self, path): |
|
1197 |
warnings.warn("Use get_ |
|
|
1198 |
return self.get_ |
|
|
1197 | warnings.warn("Use get_path_commit instead", DeprecationWarning) | |
|
1198 | return self.get_path_commit(path) | |
|
1199 | 1199 | |
|
1200 | 1200 | |
|
1201 | 1201 | class BaseChangesetClass(type): |
@@ -1502,7 +1502,7 b' class EmptyCommit(BaseCommit):' | |||
|
1502 | 1502 | def id(self): |
|
1503 | 1503 | return self.raw_id |
|
1504 | 1504 | |
|
1505 |
def get_ |
|
|
1505 | def get_path_commit(self, path): | |
|
1506 | 1506 | return self |
|
1507 | 1507 | |
|
1508 | 1508 | def get_file_content(self, path): |
@@ -298,7 +298,7 b' class GitCommit(base.BaseCommit):' | |||
|
298 | 298 | id_, _ = self._get_id_for_path(path) |
|
299 | 299 | return self._remote.blob_raw_length(id_) |
|
300 | 300 | |
|
301 |
def get_ |
|
|
301 | def get_path_history(self, path, limit=None, pre_load=None): | |
|
302 | 302 | """ |
|
303 | 303 | Returns history of file as reversed list of `GitCommit` objects for |
|
304 | 304 | which file at given `path` has been modified. |
@@ -321,21 +321,6 b' class GitCommit(base.BaseCommit):' | |||
|
321 | 321 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) |
|
322 | 322 | for commit_id in commit_ids] |
|
323 | 323 | |
|
324 | # TODO: unused for now potential replacement for subprocess | |
|
325 | def get_file_history_2(self, path, limit=None, pre_load=None): | |
|
326 | """ | |
|
327 | Returns history of file as reversed list of `Commit` objects for | |
|
328 | which file at given `path` has been modified. | |
|
329 | """ | |
|
330 | self._get_filectx(path) | |
|
331 | f_path = safe_str(path) | |
|
332 | ||
|
333 | commit_ids = self._remote.get_file_history(f_path, self.id, limit) | |
|
334 | ||
|
335 | return [ | |
|
336 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) | |
|
337 | for commit_id in commit_ids] | |
|
338 | ||
|
339 | 324 | def get_file_annotate(self, path, pre_load=None): |
|
340 | 325 | """ |
|
341 | 326 | Returns a generator of four element tuples with |
@@ -161,7 +161,7 b' class GitRepository(BaseRepository):' | |||
|
161 | 161 | GitRepository.check_url(src_url, self.config) |
|
162 | 162 | |
|
163 | 163 | if create: |
|
164 | os.makedirs(self.path, mode=0755) | |
|
164 | os.makedirs(self.path, mode=0o755) | |
|
165 | 165 | |
|
166 | 166 | if bare: |
|
167 | 167 | self._remote.init_bare() |
@@ -252,13 +252,13 b' class MercurialCommit(base.BaseCommit):' | |||
|
252 | 252 | path = self._get_filectx(path) |
|
253 | 253 | return self._remote.fctx_size(self.idx, path) |
|
254 | 254 | |
|
255 |
def get_ |
|
|
255 | def get_path_history(self, path, limit=None, pre_load=None): | |
|
256 | 256 | """ |
|
257 | 257 | Returns history of file as reversed list of `MercurialCommit` objects |
|
258 | 258 | for which file at given ``path`` has been modified. |
|
259 | 259 | """ |
|
260 | 260 | path = self._get_filectx(path) |
|
261 |
hist = self._remote. |
|
|
261 | hist = self._remote.node_history(self.idx, path, limit) | |
|
262 | 262 | return [ |
|
263 | 263 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) |
|
264 | 264 | for commit_id in hist] |
@@ -355,7 +355,7 b' class MercurialRepository(BaseRepository' | |||
|
355 | 355 | create = False |
|
356 | 356 | |
|
357 | 357 | if create: |
|
358 | os.makedirs(self.path, mode=0755) | |
|
358 | os.makedirs(self.path, mode=0o755) | |
|
359 | 359 | |
|
360 | 360 | self._remote.localrepository(create) |
|
361 | 361 |
@@ -121,7 +121,7 b' class SubversionCommit(base.BaseCommit):' | |||
|
121 | 121 | path = self._fix_path(path) |
|
122 | 122 | return self._remote.get_file_size(safe_str(path), self._svn_rev) |
|
123 | 123 | |
|
124 |
def get_ |
|
|
124 | def get_path_history(self, path, limit=None, pre_load=None): | |
|
125 | 125 | path = safe_str(self._fix_path(path)) |
|
126 | 126 | history = self._remote.node_history(path, self._svn_rev, limit) |
|
127 | 127 | return [ |
@@ -31,7 +31,7 b' import greenlet' | |||
|
31 | 31 | |
|
32 | 32 | # Import everything from pycurl. |
|
33 | 33 | # This allows us to use this module as a drop in replacement of pycurl. |
|
34 |
from pycurl import * # |
|
|
34 | from pycurl import * # pragma: no cover | |
|
35 | 35 | |
|
36 | 36 | from gevent import core |
|
37 | 37 | from gevent.hub import Waiter |
@@ -404,7 +404,7 b' class FileNode(Node):' | |||
|
404 | 404 | def last_commit(self): |
|
405 | 405 | if self.commit: |
|
406 | 406 | pre_load = ["author", "date", "message"] |
|
407 |
return self.commit.get_ |
|
|
407 | return self.commit.get_path_commit(self.path, pre_load=pre_load) | |
|
408 | 408 | raise NodeError( |
|
409 | 409 | "Cannot retrieve last commit of the file without " |
|
410 | 410 | "related commit attribute") |
@@ -510,7 +510,7 b' class FileNode(Node):' | |||
|
510 | 510 | """ |
|
511 | 511 | if self.commit is None: |
|
512 | 512 | raise NodeError('Unable to get commit for this FileNode') |
|
513 |
return self.commit.get_ |
|
|
513 | return self.commit.get_path_history(self.path) | |
|
514 | 514 | |
|
515 | 515 | @LazyProperty |
|
516 | 516 | def annotate(self): |
@@ -724,6 +724,15 b' class DirNode(Node):' | |||
|
724 | 724 | |
|
725 | 725 | return size |
|
726 | 726 | |
|
727 | @LazyProperty | |
|
728 | def last_commit(self): | |
|
729 | if self.commit: | |
|
730 | pre_load = ["author", "date", "message"] | |
|
731 | return self.commit.get_path_commit(self.path, pre_load=pre_load) | |
|
732 | raise NodeError( | |
|
733 | "Cannot retrieve last commit of the file without " | |
|
734 | "related commit attribute") | |
|
735 | ||
|
727 | 736 | def __repr__(self): |
|
728 | 737 | return '<%s %r @ %s>' % (self.__class__.__name__, self.path, |
|
729 | 738 | getattr(self.commit, 'short_id', '')) |
@@ -21,6 +21,7 b'' | |||
|
21 | 21 | |
|
22 | 22 | import logging |
|
23 | 23 | |
|
24 | import rhodecode | |
|
24 | 25 | from rhodecode.model import meta, db |
|
25 | 26 | from rhodecode.lib.utils2 import obfuscate_url_pw, get_encryption_key |
|
26 | 27 | |
@@ -36,7 +37,7 b' def init_model(engine, encryption_key=No' | |||
|
36 | 37 | :param engine: engine to bind to |
|
37 | 38 | """ |
|
38 | 39 | engine_str = obfuscate_url_pw(str(engine.url)) |
|
39 | log.info("initializing db for %s", engine_str) | |
|
40 | log.info("RhodeCode %s initializing db for %s", rhodecode.__version__, engine_str) | |
|
40 | 41 | meta.Base.metadata.bind = engine |
|
41 | 42 | db.ENCRYPTION_KEY = encryption_key |
|
42 | 43 |
@@ -40,12 +40,12 b' from sqlalchemy import (' | |||
|
40 | 40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, |
|
41 | 41 | Text, Float, PickleType) |
|
42 | 42 | from sqlalchemy.sql.expression import true, false |
|
43 |
from sqlalchemy.sql.functions import coalesce, count # |
|
|
43 | from sqlalchemy.sql.functions import coalesce, count # pragma: no cover | |
|
44 | 44 | from sqlalchemy.orm import ( |
|
45 | 45 | relationship, joinedload, class_mapper, validates, aliased) |
|
46 | 46 | from sqlalchemy.ext.declarative import declared_attr |
|
47 | 47 | from sqlalchemy.ext.hybrid import hybrid_property |
|
48 |
from sqlalchemy.exc import IntegrityError # |
|
|
48 | from sqlalchemy.exc import IntegrityError # pragma: no cover | |
|
49 | 49 | from sqlalchemy.dialects.mysql import LONGTEXT |
|
50 | 50 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
51 | 51 | |
@@ -377,6 +377,12 b' class RhodeCodeSetting(Base, BaseModel):' | |||
|
377 | 377 | % (self.SETTINGS_TYPES.keys(), val)) |
|
378 | 378 | self._app_settings_type = val |
|
379 | 379 | |
|
380 | @classmethod | |
|
381 | def get_by_prefix(cls, prefix): | |
|
382 | return RhodeCodeSetting.query()\ | |
|
383 | .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ | |
|
384 | .all() | |
|
385 | ||
|
380 | 386 | def __unicode__(self): |
|
381 | 387 | return u"<%s('%s:%s[%s]')>" % ( |
|
382 | 388 | self.__class__.__name__, |
@@ -4143,20 +4149,16 b' class ExternalIdentity(Base, BaseModel):' | |||
|
4143 | 4149 | base_table_args |
|
4144 | 4150 | ) |
|
4145 | 4151 | |
|
4146 | external_id = Column('external_id', Unicode(255), default=u'', | |
|
4147 | primary_key=True) | |
|
4152 | external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) | |
|
4148 | 4153 | external_username = Column('external_username', Unicode(1024), default=u'') |
|
4149 | local_user_id = Column('local_user_id', Integer(), | |
|
4150 | ForeignKey('users.user_id'), primary_key=True) | |
|
4151 | provider_name = Column('provider_name', Unicode(255), default=u'', | |
|
4152 | primary_key=True) | |
|
4154 | local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) | |
|
4155 | provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) | |
|
4153 | 4156 | access_token = Column('access_token', String(1024), default=u'') |
|
4154 | 4157 | alt_token = Column('alt_token', String(1024), default=u'') |
|
4155 | 4158 | token_secret = Column('token_secret', String(1024), default=u'') |
|
4156 | 4159 | |
|
4157 | 4160 | @classmethod |
|
4158 | def by_external_id_and_provider(cls, external_id, provider_name, | |
|
4159 | local_user_id=None): | |
|
4161 | def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): | |
|
4160 | 4162 | """ |
|
4161 | 4163 | Returns ExternalIdentity instance based on search params |
|
4162 | 4164 | |
@@ -4198,6 +4200,13 b' class ExternalIdentity(Base, BaseModel):' | |||
|
4198 | 4200 | query = query.filter(cls.local_user_id == local_user_id) |
|
4199 | 4201 | return query |
|
4200 | 4202 | |
|
4203 | @classmethod | |
|
4204 | def load_provider_plugin(cls, plugin_id): | |
|
4205 | from rhodecode.authentication.base import loadplugin | |
|
4206 | _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) | |
|
4207 | auth_plugin = loadplugin(_plugin_id) | |
|
4208 | return auth_plugin | |
|
4209 | ||
|
4201 | 4210 | |
|
4202 | 4211 | class Integration(Base, BaseModel): |
|
4203 | 4212 | __tablename__ = 'integrations' |
@@ -95,15 +95,14 b' class NotificationModel(BaseModel):' | |||
|
95 | 95 | log.debug('sending notifications %s to admins: %s', |
|
96 | 96 | notification_type, recipients_objs) |
|
97 | 97 | else: |
|
98 |
recipients_objs = |
|
|
98 | recipients_objs = set() | |
|
99 | 99 | for u in recipients: |
|
100 | 100 | obj = self._get_user(u) |
|
101 | 101 | if obj: |
|
102 |
recipients_objs.a |
|
|
102 | recipients_objs.add(obj) | |
|
103 | 103 | else: # we didn't find this user, log the error and carry on |
|
104 | 104 | log.error('cannot notify unknown user %r', u) |
|
105 | 105 | |
|
106 | recipients_objs = set(recipients_objs) | |
|
107 | 106 | if not recipients_objs: |
|
108 | 107 | raise Exception('no valid recipients specified') |
|
109 | 108 | |
@@ -122,7 +121,7 b' class NotificationModel(BaseModel):' | |||
|
122 | 121 | return notification |
|
123 | 122 | |
|
124 | 123 | # don't send email to person who created this comment |
|
125 |
rec_objs = set(recipients_objs).difference( |
|
|
124 | rec_objs = set(recipients_objs).difference({created_by_obj}) | |
|
126 | 125 | |
|
127 | 126 | # now notify all recipients in question |
|
128 | 127 |
@@ -1576,10 +1576,8 b' class PullRequestModel(BaseModel):' | |||
|
1576 | 1576 | from rc_reviewers.utils import get_default_reviewers_data |
|
1577 | 1577 | from rc_reviewers.utils import validate_default_reviewers |
|
1578 | 1578 | except ImportError: |
|
1579 |
from rhodecode.apps.repository.utils import |
|
|
1580 | get_default_reviewers_data | |
|
1581 | from rhodecode.apps.repository.utils import \ | |
|
1582 | validate_default_reviewers | |
|
1579 | from rhodecode.apps.repository.utils import get_default_reviewers_data | |
|
1580 | from rhodecode.apps.repository.utils import validate_default_reviewers | |
|
1583 | 1581 | |
|
1584 | 1582 | return get_default_reviewers_data, validate_default_reviewers |
|
1585 | 1583 |
@@ -181,7 +181,7 b' class RepoGroupModel(BaseModel):' | |||
|
181 | 181 | self.check_exist_filesystem(group_name) |
|
182 | 182 | create_path = os.path.join(self.repos_path, group_name) |
|
183 | 183 | log.debug('creating new group in %s', create_path) |
|
184 | os.makedirs(create_path, mode=0755) | |
|
184 | os.makedirs(create_path, mode=0o755) | |
|
185 | 185 | log.debug('created group in %s', create_path) |
|
186 | 186 | |
|
187 | 187 | def _rename_group(self, old, new): |
@@ -582,7 +582,6 b' class VcsSettingsModel(object):' | |||
|
582 | 582 | self._create_or_update_ui( |
|
583 | 583 | self.repo_settings, *phases, value=safe_str(data[phases_key])) |
|
584 | 584 | |
|
585 | ||
|
586 | 585 | def create_or_update_global_hg_settings(self, data): |
|
587 | 586 | largefiles, largefiles_store, phases, hgsubversion, evolve \ |
|
588 | 587 | = self.GLOBAL_HG_SETTINGS |
@@ -344,8 +344,8 b' class UserModel(BaseModel):' | |||
|
344 | 344 | new_user.is_new_user = not edit |
|
345 | 345 | # for users that didn's specify auth type, we use RhodeCode built in |
|
346 | 346 | from rhodecode.authentication.plugins import auth_rhodecode |
|
347 |
extern_name = extern_name or auth_rhodecode.RhodeCodeAuthPlugin. |
|
|
348 |
extern_type = extern_type or auth_rhodecode.RhodeCodeAuthPlugin. |
|
|
347 | extern_name = extern_name or auth_rhodecode.RhodeCodeAuthPlugin.uid | |
|
348 | extern_type = extern_type or auth_rhodecode.RhodeCodeAuthPlugin.uid | |
|
349 | 349 | |
|
350 | 350 | try: |
|
351 | 351 | new_user.username = username |
@@ -392,14 +392,15 b' class UserModel(BaseModel):' | |||
|
392 | 392 | log.error(traceback.format_exc()) |
|
393 | 393 | raise |
|
394 | 394 | |
|
395 |
def create_registration(self, form_data |
|
|
395 | def create_registration(self, form_data, | |
|
396 | extern_name='rhodecode', extern_type='rhodecode'): | |
|
396 | 397 | from rhodecode.model.notification import NotificationModel |
|
397 | 398 | from rhodecode.model.notification import EmailNotificationModel |
|
398 | 399 | |
|
399 | 400 | try: |
|
400 | 401 | form_data['admin'] = False |
|
401 |
form_data['extern_name'] = |
|
|
402 |
form_data['extern_type'] = |
|
|
402 | form_data['extern_name'] = extern_name | |
|
403 | form_data['extern_type'] = extern_type | |
|
403 | 404 | new_user = self.create(form_data) |
|
404 | 405 | |
|
405 | 406 | self.sa.add(new_user) |
@@ -20,5 +20,5 b'' | |||
|
20 | 20 | |
|
21 | 21 | import colander |
|
22 | 22 | |
|
23 |
from colander import Invalid # |
|
|
23 | from colander import Invalid # pragma: no cover | |
|
24 | 24 |
@@ -27,10 +27,7 b'' | |||
|
27 | 27 | padding-left: 10px; |
|
28 | 28 | } |
|
29 | 29 | li { |
|
30 |
list-style-type: |
|
|
31 | } | |
|
32 | li:before { | |
|
33 | content: "\2014\00A0"; | |
|
30 | list-style-type: disc; | |
|
34 | 31 | } |
|
35 | 32 | .error_message { |
|
36 | 33 | font-weight: normal; |
@@ -89,7 +86,9 b'' | |||
|
89 | 86 | </div> |
|
90 | 87 | <div class="main"> |
|
91 | 88 | <h1> |
|
92 | 502 Bad Gateway | <span class="error_message">Backend server is unreachable</span> | |
|
89 | 502 Bad Gateway | |
|
90 | <br/> | |
|
91 | <span class="error_message">Backend server is unreachable</span> | |
|
93 | 92 | </h1> |
|
94 | 93 | <div class="inner-column"> |
|
95 | 94 | <h4>Possible Causes</h4> |
@@ -254,7 +254,7 b' input[type="button"] {' | |||
|
254 | 254 | .btn-social { |
|
255 | 255 | &:extend(.btn-default); |
|
256 | 256 | margin: 5px 5px 5px 0px; |
|
257 |
min-width: 1 |
|
|
257 | min-width: 160px; | |
|
258 | 258 | } |
|
259 | 259 | |
|
260 | 260 | // TODO: johbo: check these exceptions |
@@ -570,14 +570,17 b' div.annotatediv { margin-left: 2px; marg' | |||
|
570 | 570 | |
|
571 | 571 | .code { display: block; border:0px !important; } |
|
572 | 572 | .code-highlight, /* TODO: dan: merge codehilite into code-highlight */ |
|
573 | /* This can be generated with `pygmentize -S default -f html` */ | |
|
573 | 574 | .codehilite { |
|
574 | 575 | .hll { background-color: #ffffcc } |
|
575 | 576 | .c { color: #408080; font-style: italic } /* Comment */ |
|
576 | 577 | .err, .codehilite .err { border: none } /* Error */ |
|
577 | 578 | .k { color: #008000; font-weight: bold } /* Keyword */ |
|
578 | 579 | .o { color: #666666 } /* Operator */ |
|
580 | .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ | |
|
579 | 581 | .cm { color: #408080; font-style: italic } /* Comment.Multiline */ |
|
580 | 582 | .cp { color: #BC7A00 } /* Comment.Preproc */ |
|
583 | .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ | |
|
581 | 584 | .c1 { color: #408080; font-style: italic } /* Comment.Single */ |
|
582 | 585 | .cs { color: #408080; font-style: italic } /* Comment.Special */ |
|
583 | 586 | .gd { color: #A00000 } /* Generic.Deleted */ |
@@ -585,11 +588,11 b' div.annotatediv { margin-left: 2px; marg' | |||
|
585 | 588 | .gr { color: #FF0000 } /* Generic.Error */ |
|
586 | 589 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ |
|
587 | 590 | .gi { color: #00A000 } /* Generic.Inserted */ |
|
588 |
.go { color: #8 |
|
|
591 | .go { color: #888888 } /* Generic.Output */ | |
|
589 | 592 | .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ |
|
590 | 593 | .gs { font-weight: bold } /* Generic.Strong */ |
|
591 | 594 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ |
|
592 |
.gt { color: #004 |
|
|
595 | .gt { color: #0044DD } /* Generic.Traceback */ | |
|
593 | 596 | .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ |
|
594 | 597 | .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ |
|
595 | 598 | .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ |
@@ -612,12 +615,15 b' div.annotatediv { margin-left: 2px; marg' | |||
|
612 | 615 | .nv { color: #19177C } /* Name.Variable */ |
|
613 | 616 | .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ |
|
614 | 617 | .w { color: #bbbbbb } /* Text.Whitespace */ |
|
618 | .mb { color: #666666 } /* Literal.Number.Bin */ | |
|
615 | 619 | .mf { color: #666666 } /* Literal.Number.Float */ |
|
616 | 620 | .mh { color: #666666 } /* Literal.Number.Hex */ |
|
617 | 621 | .mi { color: #666666 } /* Literal.Number.Integer */ |
|
618 | 622 | .mo { color: #666666 } /* Literal.Number.Oct */ |
|
623 | .sa { color: #BA2121 } /* Literal.String.Affix */ | |
|
619 | 624 | .sb { color: #BA2121 } /* Literal.String.Backtick */ |
|
620 | 625 | .sc { color: #BA2121 } /* Literal.String.Char */ |
|
626 | .dl { color: #BA2121 } /* Literal.String.Delimiter */ | |
|
621 | 627 | .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ |
|
622 | 628 | .s2 { color: #BA2121 } /* Literal.String.Double */ |
|
623 | 629 | .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ |
@@ -628,9 +634,11 b' div.annotatediv { margin-left: 2px; marg' | |||
|
628 | 634 | .s1 { color: #BA2121 } /* Literal.String.Single */ |
|
629 | 635 | .ss { color: #19177C } /* Literal.String.Symbol */ |
|
630 | 636 | .bp { color: #008000 } /* Name.Builtin.Pseudo */ |
|
637 | .fm { color: #0000FF } /* Name.Function.Magic */ | |
|
631 | 638 | .vc { color: #19177C } /* Name.Variable.Class */ |
|
632 | 639 | .vg { color: #19177C } /* Name.Variable.Global */ |
|
633 | 640 | .vi { color: #19177C } /* Name.Variable.Instance */ |
|
641 | .vm { color: #19177C } /* Name.Variable.Magic */ | |
|
634 | 642 | .il { color: #666666 } /* Literal.Number.Integer.Long */ |
|
635 | 643 | } |
|
636 | 644 |
@@ -548,10 +548,9 b' form.comment-form {' | |||
|
548 | 548 | } |
|
549 | 549 | .nav-links li { |
|
550 | 550 | display: inline-block; |
|
551 | list-style-type: none; | |
|
551 | 552 | } |
|
552 | .nav-links li:before { | |
|
553 | content: ""; | |
|
554 | } | |
|
553 | ||
|
555 | 554 | .nav-links li a.disabled { |
|
556 | 555 | cursor: not-allowed; |
|
557 | 556 | } |
@@ -219,7 +219,6 b' form.rcform {' | |||
|
219 | 219 | li { |
|
220 | 220 | list-style-type: none; |
|
221 | 221 | |
|
222 | &:before { content:none; } | |
|
223 | 222 | &:after { |
|
224 | 223 | content: ""; |
|
225 | 224 | float: left; |
@@ -43,7 +43,9 b' a { cursor: pointer; }' | |||
|
43 | 43 | float: right; |
|
44 | 44 | clear: right; |
|
45 | 45 | |
|
46 | li:before { content:none; } | |
|
46 | li { | |
|
47 | list-style-type: none; | |
|
48 | } | |
|
47 | 49 | } |
|
48 | 50 | |
|
49 | 51 | //--- DEVICE-SPECIFIC CLASSES ---------------// |
@@ -126,6 +126,11 b' div.markdown-block h6 {' | |||
|
126 | 126 | overflow: visible !important; |
|
127 | 127 | } |
|
128 | 128 | |
|
129 | div.markdown-block h1, | |
|
130 | div.markdown-block h2 { | |
|
131 | border-bottom: 1px #e6e5e5 solid !important; | |
|
132 | } | |
|
133 | ||
|
129 | 134 | div.markdown-block h1 { |
|
130 | 135 | font-size: 32px; |
|
131 | 136 | margin: 15px 0 15px 0 !important; |
@@ -135,7 +140,6 b' div.markdown-block h1 {' | |||
|
135 | 140 | div.markdown-block h2 { |
|
136 | 141 | font-size: 24px !important; |
|
137 | 142 | margin: 34px 0 10px 0 !important; |
|
138 | border-top: 3px #e6e5e5 solid !important; | |
|
139 | 143 | padding-top: 15px !important; |
|
140 | 144 | padding-bottom: 8px !important; |
|
141 | 145 | } |
@@ -199,6 +203,7 b' div.markdown-block pre {' | |||
|
199 | 203 | div.markdown-block img { |
|
200 | 204 | border-style: none; |
|
201 | 205 | background-color: #fff; |
|
206 | padding-right: 20px; | |
|
202 | 207 | } |
|
203 | 208 | |
|
204 | 209 | |
@@ -317,9 +322,13 b' div.rst-block h3 {' | |||
|
317 | 322 | margin: 1em 0 !important; |
|
318 | 323 | } |
|
319 | 324 | |
|
325 | div.rst-block h1, | |
|
326 | div.rst-block h2 { | |
|
327 | border-bottom: 1px #e6e5e5 solid !important; | |
|
328 | } | |
|
329 | ||
|
320 | 330 | div.rst-block h2 { |
|
321 | 331 | margin-top: 1.5em !important; |
|
322 | border-top: 4px solid #e0e0e0 !important; | |
|
323 | 332 | padding-top: .5em !important; |
|
324 | 333 | } |
|
325 | 334 |
@@ -196,6 +196,16 b'' | |||
|
196 | 196 | .text-as-placeholder { |
|
197 | 197 | padding-top: @input-padding-px + @border-thickness-inputs; |
|
198 | 198 | } |
|
199 | ||
|
200 | .no-border { | |
|
201 | border: 1px; | |
|
202 | } | |
|
203 | ||
|
204 | .no-horizontal-padding { | |
|
205 | padding-left: 0; | |
|
206 | padding-right: 0; | |
|
207 | } | |
|
208 | ||
|
199 | 209 | } |
|
200 | 210 | |
|
201 | 211 | // TODO: johbo: Try to find a better integration of this bit. |
@@ -315,7 +315,6 b' ul.auth_plugins {' | |||
|
315 | 315 | margin-right: @padding; |
|
316 | 316 | } |
|
317 | 317 | |
|
318 | &:before { content: none; } | |
|
319 | 318 | } |
|
320 | 319 | } |
|
321 | 320 | |
@@ -1325,6 +1324,7 b' table.integrations {' | |||
|
1325 | 1324 | position: relative; |
|
1326 | 1325 | width: 100%; |
|
1327 | 1326 | padding-bottom: 8px; |
|
1327 | list-style-type: none; | |
|
1328 | 1328 | } |
|
1329 | 1329 | |
|
1330 | 1330 | .reviewer_entry { |
@@ -1719,8 +1719,8 b' BIN_FILENODE = 7' | |||
|
1719 | 1719 | padding: 0px 0px; |
|
1720 | 1720 | } |
|
1721 | 1721 | |
|
1722 |
.pull-request-merge li |
|
|
1723 |
|
|
|
1722 | .pull-request-merge li { | |
|
1723 | list-style-type: none; | |
|
1724 | 1724 | } |
|
1725 | 1725 | |
|
1726 | 1726 | .pull-request-merge .pull-request-wrap { |
@@ -1957,7 +1957,7 b' BIN_FILENODE = 7' | |||
|
1957 | 1957 | font-size: @journal-fontsize; |
|
1958 | 1958 | line-height: 1em; |
|
1959 | 1959 | |
|
1960 | &:before { content: none; } | |
|
1960 | list-style-type: none; | |
|
1961 | 1961 | } |
|
1962 | 1962 | } |
|
1963 | 1963 | } |
@@ -201,8 +201,7 b'' | |||
|
201 | 201 | padding: 0 2px; |
|
202 | 202 | } |
|
203 | 203 | } |
|
204 | ||
|
205 | &:before { content: none; } | |
|
204 | list-style-type: none; | |
|
206 | 205 | } |
|
207 | 206 | |
|
208 | 207 | > li { |
@@ -305,8 +304,7 b'' | |||
|
305 | 304 | line-height: 1em; |
|
306 | 305 | color: @grey3; |
|
307 | 306 | background-color: @grey6; |
|
308 | ||
|
309 | &:before { content: none; } | |
|
307 | list-style-type: none; | |
|
310 | 308 | |
|
311 | 309 | a { |
|
312 | 310 | display: block; |
@@ -398,8 +396,6 b'' | |||
|
398 | 396 | line-height: 1em; |
|
399 | 397 | list-style-type: none; |
|
400 | 398 | |
|
401 | &:before { content: none; } | |
|
402 | ||
|
403 | 399 | a { |
|
404 | 400 | display: block; |
|
405 | 401 | height: 16px; |
@@ -461,8 +457,6 b'' | |||
|
461 | 457 | line-height: 1em; |
|
462 | 458 | color: @grey6; |
|
463 | 459 | |
|
464 | &:before { content: none; } | |
|
465 | ||
|
466 | 460 | &>.select2-result-label { |
|
467 | 461 | padding: 8px 0; |
|
468 | 462 | border-bottom: @border-thickness solid @grey3; |
@@ -494,8 +488,7 b'' | |||
|
494 | 488 | line-height: 1em; |
|
495 | 489 | font-family: @text-light; |
|
496 | 490 | color: @grey2; |
|
497 | ||
|
498 | &:before { content: none; } | |
|
491 | list-style-type: none; | |
|
499 | 492 | |
|
500 | 493 | &:hover { |
|
501 | 494 | background-color: @grey3; |
@@ -520,8 +513,7 b'' | |||
|
520 | 513 | ul#context-pages { |
|
521 | 514 | li { |
|
522 | 515 | line-height: 1em; |
|
523 | ||
|
524 | &:before { content: none; } | |
|
516 | list-style-type: none; | |
|
525 | 517 | |
|
526 | 518 | a { |
|
527 | 519 | color: @grey3; |
@@ -622,6 +614,7 b' ul#context-pages {' | |||
|
622 | 614 | padding-bottom: @menupadding; |
|
623 | 615 | line-height: 1em; |
|
624 | 616 | color: @grey4; |
|
617 | list-style-type: none; | |
|
625 | 618 | |
|
626 | 619 | &.active a { |
|
627 | 620 | color: @grey2; |
@@ -630,8 +623,6 b' ul#context-pages {' | |||
|
630 | 623 | a { |
|
631 | 624 | color: @grey4; |
|
632 | 625 | } |
|
633 | ||
|
634 | &:before { content: none; } | |
|
635 | 626 | } |
|
636 | 627 | |
|
637 | 628 | } |
@@ -17,6 +17,11 b' div.readme_box h6 {' | |||
|
17 | 17 | overflow: visible !important; |
|
18 | 18 | } |
|
19 | 19 | |
|
20 | div.readme_box h1, | |
|
21 | div.readme_box h2 { | |
|
22 | border-bottom: 1px #e6e5e5 solid !important; | |
|
23 | } | |
|
24 | ||
|
20 | 25 | div.readme_box h1 { |
|
21 | 26 | font-size: 32px; |
|
22 | 27 | margin: 15px 0 15px 0 !important; |
@@ -26,7 +31,6 b' div.readme_box h1 {' | |||
|
26 | 31 | div.readme_box h2 { |
|
27 | 32 | font-size: 24px !important; |
|
28 | 33 | margin: 34px 0 10px 0 !important; |
|
29 | border-top: 3px #e6e5e5 solid !important; | |
|
30 | 34 | padding-top: 15px !important; |
|
31 | 35 | padding-bottom: 8px !important; |
|
32 | 36 | } |
@@ -90,6 +94,7 b' div.readme_box pre {' | |||
|
90 | 94 | div.readme_box img { |
|
91 | 95 | border-style: none; |
|
92 | 96 | background-color: #fff; |
|
97 | padding-right: 20px; | |
|
93 | 98 | } |
|
94 | 99 | |
|
95 | 100 | |
@@ -107,7 +112,7 b' div.readme_box ol {' | |||
|
107 | 112 | |
|
108 | 113 | div.readme_box ul li, |
|
109 | 114 | div.readme_box ol li { |
|
110 |
list-style: |
|
|
115 | list-style: disc !important; | |
|
111 | 116 | margin: 6px !important; |
|
112 | 117 | padding: 0 !important; |
|
113 | 118 | } |
@@ -174,8 +174,6 b' select.select2{height:28px;visibility:hi' | |||
|
174 | 174 | line-height: 1em; |
|
175 | 175 | list-style-type: none; |
|
176 | 176 | |
|
177 | &:before { content: none; } | |
|
178 | ||
|
179 | 177 | &:hover, |
|
180 | 178 | &.select2-highlighted { |
|
181 | 179 | background-color: @rclightblue; |
@@ -104,11 +104,7 b'' | |||
|
104 | 104 | padding-left: 0; |
|
105 | 105 | |
|
106 | 106 | li { |
|
107 | ||
|
108 | &:before { | |
|
109 | content: none; | |
|
110 | width: 0; | |
|
111 | } | |
|
107 | list-style-type: none; | |
|
112 | 108 | } |
|
113 | 109 | } |
|
114 | 110 | } |
@@ -64,7 +64,9 b' table.dataTable {' | |||
|
64 | 64 | .expired td { |
|
65 | 65 | background-color: @grey7; |
|
66 | 66 | } |
|
67 | ||
|
67 | .inactive td { | |
|
68 | background-color: @grey6; | |
|
69 | } | |
|
68 | 70 | th { |
|
69 | 71 | text-align: left; |
|
70 | 72 | font-weight: @text-semibold-weight; |
@@ -49,8 +49,6 b'' | |||
|
49 | 49 | margin: 0 0 @padding; |
|
50 | 50 | line-height: 1em; |
|
51 | 51 | list-style-type: none; |
|
52 | ||
|
53 | &:before { content: none; } | |
|
54 | 52 | } |
|
55 | 53 | } |
|
56 | 54 |
@@ -274,8 +274,11 b' mark,' | |||
|
274 | 274 | list-style: none; |
|
275 | 275 | text-align: right; |
|
276 | 276 | |
|
277 | li:before { content: none; } | |
|
278 |
|
|
|
277 | li { | |
|
278 | float: right; | |
|
279 | list-style-type: none; | |
|
280 | } | |
|
281 | ||
|
279 | 282 | a { |
|
280 | 283 | display: inline-block; |
|
281 | 284 | margin-left: @textmargin/2; |
@@ -338,15 +341,7 b' li {' | |||
|
338 | 341 | |
|
339 | 342 | ul li { |
|
340 | 343 | position: relative; |
|
341 | display: block; | |
|
342 | list-style-type: none; | |
|
343 | ||
|
344 | &:before { | |
|
345 | content: "\2014\00A0"; | |
|
346 | position: absolute; | |
|
347 | top: 0; | |
|
348 | left: -1.25em; | |
|
349 | } | |
|
344 | list-style-type: disc; | |
|
350 | 345 | |
|
351 | 346 | p:first-child { |
|
352 | 347 | display:inline; |
@@ -539,7 +534,7 b' address {' | |||
|
539 | 534 | color: @grey4; |
|
540 | 535 | font-family: @text-light; |
|
541 | 536 | &.pre-formatting { |
|
542 | white-space: pre; | |
|
537 | white-space: pre-wrap; | |
|
543 | 538 | } |
|
544 | 539 | } |
|
545 | 540 |
@@ -125,7 +125,7 b'' | |||
|
125 | 125 | @label-summary-minwidth: 80px; |
|
126 | 126 | @search-form-width: 400px; |
|
127 | 127 | @fields-input-m: 400px; |
|
128 |
@fields-input-l: |
|
|
128 | @fields-input-l: 720px; | |
|
129 | 129 | |
|
130 | 130 | // BUTTONS |
|
131 | 131 | @button-padding: .9em; |
@@ -14,7 +14,6 b' function registerRCRoutes() {' | |||
|
14 | 14 | // routes registration |
|
15 | 15 | pyroutes.register('favicon', '/favicon.ico', []); |
|
16 | 16 | pyroutes.register('robots', '/robots.txt', []); |
|
17 | pyroutes.register('auth_home', '/_admin/auth*traverse', []); | |
|
18 | 17 | pyroutes.register('global_integrations_new', '/_admin/integrations/new', []); |
|
19 | 18 | pyroutes.register('global_integrations_home', '/_admin/integrations', []); |
|
20 | 19 | pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']); |
@@ -30,6 +29,7 b' function registerRCRoutes() {' | |||
|
30 | 29 | pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']); |
|
31 | 30 | pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']); |
|
32 | 31 | pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']); |
|
32 | pyroutes.register('auth_home', '/_admin/auth*traverse', []); | |
|
33 | 33 | pyroutes.register('ops_ping', '/_admin/ops/ping', []); |
|
34 | 34 | pyroutes.register('ops_error_test', '/_admin/ops/error', []); |
|
35 | 35 | pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []); |
@@ -475,11 +475,10 b' class RcServerCommand(object):' | |||
|
475 | 475 | msg = '' |
|
476 | 476 | self.out('Exiting%s (-v to see traceback)' % msg) |
|
477 | 477 | |
|
478 | ||
|
479 | 478 | def loadapp(self, app_spec, name, relative_to, **kw): # pragma: no cover |
|
480 | 479 | return loadapp(app_spec, name=name, relative_to=relative_to, **kw) |
|
481 | 480 | |
|
482 | def loadserver(self, server_spec, name, relative_to, **kw): # pragma:no cover | |
|
481 | def loadserver(self, server_spec, name, relative_to, **kw): # pragma: no cover | |
|
483 | 482 | return loadserver( |
|
484 | 483 | server_spec, name=name, relative_to=relative_to, **kw) |
|
485 | 484 |
@@ -39,48 +39,56 b'' | |||
|
39 | 39 | |
|
40 | 40 | <div class="main-content-full-width"> |
|
41 | 41 | ${h.secure_form(request.resource_path(resource, route_name='auth_home'), request=request)} |
|
42 | <div class="form"> | |
|
43 | ||
|
44 | 42 | <div class="panel panel-default"> |
|
45 | 43 | |
|
46 | 44 | <div class="panel-heading"> |
|
47 | 45 | <h3 class="panel-title">${_("Enabled and Available Plugins")}</h3> |
|
48 | 46 | </div> |
|
49 | 47 | |
|
50 |
<div class=" |
|
|
48 | <div class="panel-body"> | |
|
51 | 49 | |
|
52 | <div class="field"> | |
|
53 |
<div class="label">${_(" |
|
|
50 | ||
|
51 | <div class="label">${_("Ordered Activated Plugins")}</div> | |
|
54 | 52 | <div class="textarea text-area editor"> |
|
55 |
${h.textarea('auth_plugins',cols= |
|
|
53 | ${h.textarea('auth_plugins',cols=120,rows=20,class_="medium")} | |
|
56 | 54 | </div> |
|
57 | <p class="help-block pre-formatting">${_('List of plugins, separated by commas.' | |
|
55 | <div class="field"> | |
|
56 | <p class="help-block pre-formatting">${_('List of plugins, separated by commas.' | |
|
58 | 57 | '\nThe order of the plugins is also the order in which ' |
|
59 |
'RhodeCode Enterprise will try to authenticate a user.')} |
|
|
60 |
</ |
|
|
58 | 'RhodeCode Enterprise will try to authenticate a user.')} | |
|
59 | </p> | |
|
60 | </div> | |
|
61 | 61 | |
|
62 |
< |
|
|
63 | <div class="label">${_('Available Built-in Plugins')}</div> | |
|
64 | <ul class="auth_plugins"> | |
|
65 | %for plugin in available_plugins: | |
|
66 | <li> | |
|
67 | <div class="auth_buttons"> | |
|
68 | <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${'btn-success' if plugin.get_id() in enabled_plugins else ''}"> | |
|
69 |
|
|
|
70 |
< |
|
|
71 | ${plugin.get_display_name()} (${plugin.get_id()}) | |
|
72 | </div> | |
|
73 |
</ |
|
|
74 | %endfor | |
|
75 | </ul> | |
|
76 |
< |
|
|
62 | <table class="rctable"> | |
|
63 | <th>${_('Activate')}</th> | |
|
64 | <th>${_('Plugin Name')}</th> | |
|
65 | <th>${_('Documentation')}</th> | |
|
66 | <th>${_('Plugin ID')}</th> | |
|
67 | <th>${_('Enabled')}</th> | |
|
68 | %for plugin in available_plugins: | |
|
69 | <tr class="${'inactive' if (not plugin.is_active() and plugin.get_id() in enabled_plugins) else ''}"> | |
|
70 | <td> | |
|
71 | <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${'btn-success' if plugin.get_id() in enabled_plugins else ''}"> | |
|
72 | ${_('activated') if plugin.get_id() in enabled_plugins else _('not active')} | |
|
73 | </span> | |
|
74 | </td> | |
|
75 | <td>${plugin.get_display_name()}</td> | |
|
76 | <td> | |
|
77 | % if plugin.docs(): | |
|
78 | <a href="${plugin.docs()}">docs</a> | |
|
79 | % endif | |
|
80 | </td> | |
|
81 | <td>${plugin.get_id()}</td> | |
|
82 | <td>${h.bool2icon(plugin.is_active(),show_at_false=False)}</td> | |
|
83 | </tr> | |
|
84 | %endfor | |
|
85 | </table> | |
|
77 | 86 | |
|
78 | 87 | <div class="buttons"> |
|
79 | 88 | ${h.submit('save',_('Save'),class_="btn")} |
|
80 | 89 | </div> |
|
81 | 90 | </div> |
|
82 | 91 | </div> |
|
83 | </div> | |
|
84 | 92 | ${h.end_form()} |
|
85 | 93 | </div> |
|
86 | 94 | </div> |
@@ -103,15 +111,15 b'' | |||
|
103 | 111 | elems.splice(elems.indexOf(plugin_id), 1); |
|
104 | 112 | auth_plugins_input.val(elems.join(',\n')); |
|
105 | 113 | $(cur_button).removeClass('btn-success'); |
|
106 |
cur_button.innerHTML = _gettext(' |
|
|
114 | cur_button.innerHTML = _gettext('not active'); | |
|
107 | 115 | } |
|
108 | 116 | else{ |
|
109 | if(elems.indexOf(plugin_id) == -1){ | |
|
110 | elems.push(plugin_id); | |
|
117 | if (elems.indexOf(plugin_id) === -1) { | |
|
118 | elems.push(plugin_id); | |
|
111 | 119 | } |
|
112 | 120 | auth_plugins_input.val(elems.join(',\n')); |
|
113 | 121 | $(cur_button).addClass('btn-success'); |
|
114 |
cur_button.innerHTML = _gettext(' |
|
|
122 | cur_button.innerHTML = _gettext('activated'); | |
|
115 | 123 | } |
|
116 | 124 | }); |
|
117 | 125 | </script> |
@@ -51,23 +51,29 b'' | |||
|
51 | 51 | <div class="form"> |
|
52 | 52 | |
|
53 | 53 | %for node in plugin.get_settings_schema(): |
|
54 | <% label_css_class = ("label-checkbox" if (node.widget == "bool") else "") %> | |
|
54 | <% | |
|
55 | label_to_type = {'label-checkbox': 'bool', 'label-textarea': 'textarea'} | |
|
56 | %> | |
|
57 | ||
|
55 | 58 | <div class="field"> |
|
56 |
<div class="label ${label_ |
|
|
59 | <div class="label ${label_to_type.get(node.widget)}"><label for="${node.name}">${node.title}</label></div> | |
|
57 | 60 | <div class="input"> |
|
58 | 61 | %if node.widget in ["string", "int", "unicode"]: |
|
59 |
${h.text(node.name, defaults.get(node.name), class_=" |
|
|
62 | ${h.text(node.name, defaults.get(node.name), class_="large")} | |
|
60 | 63 | %elif node.widget == "password": |
|
61 |
${h.password(node.name, defaults.get(node.name), class_=" |
|
|
64 | ${h.password(node.name, defaults.get(node.name), class_="large")} | |
|
62 | 65 | %elif node.widget == "bool": |
|
63 | 66 | <div class="checkbox">${h.checkbox(node.name, True, checked=defaults.get(node.name))}</div> |
|
64 | 67 | %elif node.widget == "select": |
|
65 | ${h.select(node.name, defaults.get(node.name), node.validator.choices)} | |
|
68 | ${h.select(node.name, defaults.get(node.name), node.validator.choices, class_="select2AuthSetting")} | |
|
69 | %elif node.widget == "textarea": | |
|
70 | <div class="textarea" style="margin-left: 0px">${h.textarea(node.name, defaults.get(node.name), rows=10)}</div> | |
|
66 | 71 | %elif node.widget == "readonly": |
|
67 | 72 | ${node.default} |
|
68 | 73 | %else: |
|
69 | 74 | This field is of type ${node.typ}, which cannot be displayed. Must be one of [string|int|bool|select]. |
|
70 | 75 | %endif |
|
76 | ||
|
71 | 77 |
|
|
72 | 78 | <span class="error-message">${errors.get(node.name)}</span> |
|
73 | 79 | <br /> |
@@ -91,6 +97,18 b'' | |||
|
91 | 97 | ${h.end_form()} |
|
92 | 98 | </div> |
|
93 | 99 | </div> |
|
100 | ||
|
101 | % if request.GET.get('schema'): | |
|
102 | ## this is for development and creation of example configurations for documentation | |
|
103 | <pre> | |
|
104 | % for node in plugin.get_settings_schema(): | |
|
105 | *option*: `${node.name}` => `${defaults.get(node.name)}`${'\n # '.join(['']+node.description.splitlines())} | |
|
106 | ||
|
107 | % endfor | |
|
108 | </pre> | |
|
109 | ||
|
110 | % endif | |
|
111 | ||
|
94 | 112 | </div> |
|
95 | 113 | </div> |
|
96 | 114 | </div> |
@@ -98,8 +116,7 b'' | |||
|
98 | 116 | </div> |
|
99 | 117 | </div> |
|
100 | 118 | |
|
101 | ## TODO: Ugly hack to get ldap select elements to work. | |
|
102 | ## Find a solution to integrate this nicely. | |
|
119 | ||
|
103 | 120 | <script> |
|
104 | 121 | $(document).ready(function() { |
|
105 | 122 | var select2Options = { |
@@ -107,12 +124,9 b'' | |||
|
107 | 124 | dropdownCssClass: 'drop-menu-dropdown', |
|
108 | 125 | dropdownAutoWidth: true, |
|
109 | 126 | minimumResultsForSearch: -1 |
|
110 |
|
|
|
111 |
|
|
|
112 | $("#tls_reqcert").select2(select2Options); | |
|
113 | $("#search_scope").select2(select2Options); | |
|
114 | $("#group_extraction_type").select2(select2Options); | |
|
115 | $("#admin_groups_sync").select2(select2Options); | |
|
127 | }; | |
|
128 | $('.select2AuthSetting').select2(select2Options); | |
|
129 | ||
|
116 | 130 | }); |
|
117 | 131 | </script> |
|
118 | 132 | </%def> |
@@ -32,10 +32,10 b'' | |||
|
32 | 32 | <li class="${'active' if c.active in ['ssh_keys', 'ssh_keys_generate'] else ''}"><a href="${h.route_path('my_account_ssh_keys')}">${_('SSH Keys')}</a></li> |
|
33 | 33 | <li class="${'active' if c.active=='user_group_membership' else ''}"><a href="${h.route_path('my_account_user_group_membership')}">${_('User Group Membership')}</a></li> |
|
34 | 34 | |
|
35 | ## TODO: Find a better integration of oauth views into navigation. | |
|
36 |
<% my_account_ |
|
|
37 |
% if my_account_ |
|
|
38 |
<li class="${'active' if c.active==' |
|
|
35 | ## TODO: Find a better integration of oauth/saml views into navigation. | |
|
36 | <% my_account_external_url = h.route_path_or_none('my_account_external_identity') %> | |
|
37 | % if my_account_external_url: | |
|
38 | <li class="${'active' if c.active=='external_identity' else ''}"><a href="${my_account_external_url}">${_('External Identities')}</a></li> | |
|
39 | 39 | % endif |
|
40 | 40 | <li class="${'active' if c.active=='emails' else ''}"><a href="${h.route_path('my_account_emails')}">${_('Emails')}</a></li> |
|
41 | 41 | <li class="${'active' if c.active=='repos' else ''}"><a href="${h.route_path('my_account_repos')}">${_('Repositories')}</a></li> |
@@ -49,9 +49,7 b' Currently the following views are set:' | |||
|
49 | 49 | % for route_name, view_fqn, view_url, active in c.view_data: |
|
50 | 50 | <tr> |
|
51 | 51 | <td class="td-x"> |
|
52 | % if active: | |
|
53 | ${h.bool2icon(active)} | |
|
54 | % endif | |
|
52 | ${h.bool2icon(active, show_at_false=False)} | |
|
55 | 53 | </td> |
|
56 | 54 | <td class="td-x">${view_fqn}</td> |
|
57 | 55 | <td class="td-x" title="${route_name}">${view_url}</td> |
@@ -102,6 +102,7 b'' | |||
|
102 | 102 | <option value="clicky">Clicky</option> |
|
103 | 103 | <option value="server_announce">${_('Server Announcement')}</option> |
|
104 | 104 | <option value="flash_filtering">${_('Flash message filtering')}</option> |
|
105 | <option value="custom_logo">${_('Custom logos')}</option> | |
|
105 | 106 | </select> |
|
106 | 107 | </div> |
|
107 | 108 | <div style="padding: 10px 0px"></div> |
@@ -212,7 +213,7 b'' | |||
|
212 | 213 | // This can be used to send a global maintenance messages or other |
|
213 | 214 | // important messages to all users of the RhodeCode Enterprise system. |
|
214 | 215 | |
|
215 | $(document).ready(function(e){ | |
|
216 | $(document).ready(function(e) { | |
|
216 | 217 | |
|
217 | 218 | // EDIT - put your message below |
|
218 | 219 | var message = "TYPE YOUR MESSAGE HERE"; |
@@ -248,6 +249,32 b'' | |||
|
248 | 249 | </%text> |
|
249 | 250 | </script> |
|
250 | 251 | |
|
252 | ||
|
253 | <script id="custom_logo_tmpl" type='text/x-template'> | |
|
254 | <%text filter="h"> | |
|
255 | <script> | |
|
256 | ||
|
257 | $(document).ready(function(e) { | |
|
258 | // 1) Set custom logo on login/register pages. | |
|
259 | ||
|
260 | // external URL, custom company logo | |
|
261 | //$('.sign-in-image').attr("src", "http://server.com/logo_path/custom_logo.png"); | |
|
262 | ||
|
263 | // Alternative logo from static folder | |
|
264 | $('.sign-in-image').attr("src", "/_static/rhodecode/images/RhodeCode_Logo_Black.png"); | |
|
265 | ||
|
266 | // option to set width/height, adjust if required to make your image look good. | |
|
267 | $('.sign-in-image').css({"width": "300px", "height": "345px"}); | |
|
268 | ||
|
269 | // 2) Header logo on top bar | |
|
270 | $('.logo-wrapper').find('img').attr('src', 'http://server.com/logo_path/custom_header_logo.png') | |
|
271 | ||
|
272 | }); | |
|
273 | </script> | |
|
274 | </%text> | |
|
275 | </script> | |
|
276 | ||
|
277 | ||
|
251 | 278 | <script> |
|
252 | 279 | var pre_cm = initCodeMirror('rhodecode_pre_code', '', false); |
|
253 | 280 | var pre_old = pre_cm.getValue(); |
@@ -255,7 +282,7 b' var pre_old = pre_cm.getValue();' | |||
|
255 | 282 | var post_cm = initCodeMirror('rhodecode_post_code', '', false); |
|
256 | 283 | var post_old = post_cm.getValue(); |
|
257 | 284 | |
|
258 | var get_data = function(type, old){ | |
|
285 | var get_data = function(type, old) { | |
|
259 | 286 | var get_tmpl = function(tmpl_name){ |
|
260 | 287 | // unescape some stuff |
|
261 | 288 | return htmlEnDeCode.htmlDecode($('#'+tmpl_name+'_tmpl').html()); |
@@ -265,7 +292,8 b' var get_data = function(type, old){' | |||
|
265 | 292 | 'ga': get_tmpl('ga'), |
|
266 | 293 | 'clicky': get_tmpl('clicky'), |
|
267 | 294 | 'server_announce': get_tmpl('server_announce'), |
|
268 | 'flash_filtering': get_tmpl('flash_filtering') | |
|
295 | 'flash_filtering': get_tmpl('flash_filtering'), | |
|
296 | 'custom_logo': get_tmpl('custom_logo') | |
|
269 | 297 | }[type] |
|
270 | 298 | }; |
|
271 | 299 |
@@ -103,11 +103,12 b'' | |||
|
103 | 103 | </div> |
|
104 | 104 | <div class="field"> |
|
105 | 105 | <div class="label-text"> |
|
106 |
${_(' |
|
|
106 | ${_('Authentication type')}: | |
|
107 | 107 | </div> |
|
108 | 108 | <div class="input"> |
|
109 | 109 | <p>${c.extern_type}</p> |
|
110 | 110 | ${h.hidden('extern_type', readonly="readonly")} |
|
111 | <p class="help-block">${_('User was created using an external source. He is bound to authentication using this method.')}</p> | |
|
111 | 112 | </div> |
|
112 | 113 | </div> |
|
113 | 114 | <div class="field"> |
@@ -127,7 +128,7 b'' | |||
|
127 | 128 | ## allowed_languages is defined in the users.py |
|
128 | 129 | ## c.language comes from base.py as a default language |
|
129 | 130 | ${h.select('language', c.language, c.allowed_languages)} |
|
130 | <p class="help-block">${h.literal(_('Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p> | |
|
131 | <p class="help-block">${h.literal(_('User interface language. Help translate %(rc_link)s into your language.') % {'rc_link': h.link_to('RhodeCode Enterprise', h.route_url('rhodecode_translations'))})}</p> | |
|
131 | 132 | </div> |
|
132 | 133 | </div> |
|
133 | 134 | <div class="buttons"> |
@@ -4,7 +4,8 b'' | |||
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | 6 | <p> |
|
7 |
${_('Below is a 2048 bit generated SSH RSA key. |
|
|
7 | ${_('Below is a 2048 bit generated SSH RSA key.')}<br/> | |
|
8 | ${_('If You wish to use it to access RhodeCode via the SSH please save the private key and click `Use this generated key` at the bottom.')} | |
|
8 | 9 | </p> |
|
9 | 10 | <h4>${_('Private key')}</h4> |
|
10 | 11 | <pre> |
@@ -27,9 +27,6 b" c.template_context['default_user'] = {" | |||
|
27 | 27 | %> |
|
28 | 28 | <html xmlns="http://www.w3.org/1999/xhtml"> |
|
29 | 29 | <head> |
|
30 | ||
|
31 | <script src="${h.asset('js/vendors/webcomponentsjs/custom-elements-es5-adapter.js', ver=c.rhodecode_version_hash)}"></script> | |
|
32 | <script src="${h.asset('js/vendors/webcomponentsjs/webcomponents-bundle.js', ver=c.rhodecode_version_hash)}"></script> | |
|
33 | 30 | <title>${self.title()}</title> |
|
34 | 31 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
35 | 32 | |
@@ -46,6 +43,8 b" c.template_context['default_user'] = {" | |||
|
46 | 43 | </%def> |
|
47 | 44 | ${self.robots()} |
|
48 | 45 | <link rel="icon" href="${h.asset('images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" /> |
|
46 | <script src="${h.asset('js/vendors/webcomponentsjs/custom-elements-es5-adapter.js', ver=c.rhodecode_version_hash)}"></script> | |
|
47 | <script src="${h.asset('js/vendors/webcomponentsjs/webcomponents-bundle.js', ver=c.rhodecode_version_hash)}"></script> | |
|
49 | 48 | |
|
50 | 49 | ## CSS definitions |
|
51 | 50 | <%def name="css()"> |
@@ -5,13 +5,16 b'' | |||
|
5 | 5 | <title>Error - ${c.error_message}</title> |
|
6 | 6 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
7 | 7 | <meta name="robots" content="index, nofollow"/> |
|
8 | <link rel="icon" href="${h.asset('images/favicon.ico')}" sizes="16x16 32x32" type="image/png" /> | |
|
9 | 8 | |
|
10 | 9 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
11 | 10 | %if c.redirect_time: |
|
12 | 11 | <meta http-equiv="refresh" content="${c.redirect_time}; url=${c.url_redirect}"/> |
|
13 | 12 | %endif |
|
14 | 13 | |
|
14 | <link rel="icon" href="${h.asset('images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" /> | |
|
15 | <script src="${h.asset('js/vendors/webcomponentsjs/custom-elements-es5-adapter.js', ver=c.rhodecode_version_hash)}"></script> | |
|
16 | <script src="${h.asset('js/vendors/webcomponentsjs/webcomponents-bundle.js', ver=c.rhodecode_version_hash)}"></script> | |
|
17 | ||
|
15 | 18 | <link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/> |
|
16 | 19 | <style>body { background:#eeeeee; }</style> |
|
17 | 20 | <script type="text/javascript"> |
@@ -31,7 +34,9 b'' | |||
|
31 | 34 | <span class="error-branding"> |
|
32 | 35 | ${h.branding(c.rhodecode_name)} |
|
33 | 36 | </span><br/> |
|
34 | ${c.error_message} | <span class="error_message">${c.error_explanation}</span> | |
|
37 | ${c.error_message} | |
|
38 | <br/> | |
|
39 | <span class="error_message">${c.error_explanation}</span> | |
|
35 | 40 | </h1> |
|
36 | 41 | % if c.messages: |
|
37 | 42 | % for message in c.messages: |
@@ -32,8 +32,8 b'' | |||
|
32 | 32 | <div id="register" class="right-column"> |
|
33 | 33 | <!-- login --> |
|
34 | 34 | <div class="sign-in-title"> |
|
35 |
% if |
|
|
36 |
<h1>${_('Create an account linked with {}').format( |
|
|
35 | % if external_auth_provider: | |
|
36 | <h1>${_('Create an account linked with {}').format(external_auth_provider)}</h1> | |
|
37 | 37 | % else: |
|
38 | 38 | <h1>${_('Create an account')}</h1> |
|
39 | 39 | % endif |
@@ -50,7 +50,9 b'' | |||
|
50 | 50 | <br /> |
|
51 | 51 | %endif |
|
52 | 52 | |
|
53 |
% if |
|
|
53 | % if external_auth_provider: | |
|
54 | ## store internal marker about external identity | |
|
55 | ${h.hidden('external_identity', external_auth_provider)} | |
|
54 | 56 |
|
|
55 | 57 | <div style="display: none"> |
|
56 | 58 | % endif |
@@ -69,7 +71,7 b'' | |||
|
69 | 71 | <br /> |
|
70 | 72 | %endif |
|
71 | 73 | |
|
72 |
% if |
|
|
74 | % if external_auth_provider: | |
|
73 | 75 | ## hide password prompts for social auth |
|
74 | 76 | </div> |
|
75 | 77 | % endif |
@@ -45,7 +45,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
45 | 45 | |
|
46 | 46 | @hybrid_property |
|
47 | 47 | def name(self): |
|
48 | return "external_test" | |
|
48 | return u"external_test" | |
|
49 | 49 | |
|
50 | 50 | def settings(self): |
|
51 | 51 | settings = [ |
@@ -30,7 +30,7 b' from rhodecode.model import db' | |||
|
30 | 30 | class RcTestAuthPlugin(RhodeCodeAuthPluginBase): |
|
31 | 31 | |
|
32 | 32 | def name(self): |
|
33 | return 'stub_auth' | |
|
33 | return u'stub_auth' | |
|
34 | 34 | |
|
35 | 35 | |
|
36 | 36 | def test_authenticate_returns_from_auth(stub_auth_data): |
@@ -77,6 +77,8 b' class StubVCSController(simplevcs.Simple' | |||
|
77 | 77 | def vcscontroller(baseapp, config_stub, request_stub): |
|
78 | 78 | config_stub.testing_securitypolicy() |
|
79 | 79 | config_stub.include('rhodecode.authentication') |
|
80 | config_stub.include('rhodecode.authentication.plugins.auth_rhodecode') | |
|
81 | config_stub.include('rhodecode.authentication.plugins.auth_token') | |
|
80 | 82 | |
|
81 | 83 | controller = StubVCSController( |
|
82 | 84 | baseapp.config.get_settings(), request_stub.registry) |
@@ -46,7 +46,7 b' class ReviewerMock(object):' | |||
|
46 | 46 | class MemberMock(object): |
|
47 | 47 | def __init__(self, reviewer_def): |
|
48 | 48 | self.reviewer_def = reviewer_def |
|
49 | self.user_id = random.randint(1, 1024) | |
|
49 | self.user_id = random.randint(1, 1024*1024) | |
|
50 | 50 | |
|
51 | 51 | |
|
52 | 52 | class Statuses(object): |
@@ -193,6 +193,8 b' def test_ValidPasswordsMatch(localizer):' | |||
|
193 | 193 | def test_ValidAuth(localizer, config_stub): |
|
194 | 194 | config_stub.testing_securitypolicy() |
|
195 | 195 | config_stub.include('rhodecode.authentication') |
|
196 | config_stub.include('rhodecode.authentication.plugins.auth_rhodecode') | |
|
197 | config_stub.include('rhodecode.authentication.plugins.auth_token') | |
|
196 | 198 | |
|
197 | 199 | validator = v.ValidAuth(localizer) |
|
198 | 200 | valid_creds = { |
@@ -310,9 +310,9 b' class TestCommits(BackendTestMixin):' | |||
|
310 | 310 | with pytest.raises(CommitDoesNotExistError): |
|
311 | 311 | commit.next() |
|
312 | 312 | |
|
313 |
def test_get_ |
|
|
313 | def test_get_path_commit(self): | |
|
314 | 314 | commit = self.repo.get_commit() |
|
315 |
commit.get_ |
|
|
315 | commit.get_path_commit('file_4.txt') | |
|
316 | 316 | assert commit.message == 'Commit 4' |
|
317 | 317 | |
|
318 | 318 | def test_get_filenodes_generator(self): |
@@ -571,19 +571,19 b' class TestCommitsChanges(BackendTestMixi' | |||
|
571 | 571 | assert FILEMODE_DEFAULT == commit.get_file_mode('foo/bał') |
|
572 | 572 | assert FILEMODE_DEFAULT == commit.get_file_mode(u'foo/bał') |
|
573 | 573 | |
|
574 |
def test_get_ |
|
|
574 | def test_get_path_history(self): | |
|
575 | 575 | commit = self.repo.get_commit() |
|
576 |
history = commit.get_ |
|
|
576 | history = commit.get_path_history('foo/bar') | |
|
577 | 577 | assert len(history) == 2 |
|
578 | 578 | |
|
579 |
def test_get_ |
|
|
579 | def test_get_path_history_with_limit(self): | |
|
580 | 580 | commit = self.repo.get_commit() |
|
581 |
history = commit.get_ |
|
|
581 | history = commit.get_path_history('foo/bar', limit=1) | |
|
582 | 582 | assert len(history) == 1 |
|
583 | 583 | |
|
584 |
def test_get_ |
|
|
584 | def test_get_path_history_first_commit(self): | |
|
585 | 585 | commit = self.repo[0] |
|
586 |
history = commit.get_ |
|
|
586 | history = commit.get_path_history('foo/bar') | |
|
587 | 587 | assert len(history) == 1 |
|
588 | 588 | |
|
589 | 589 |
@@ -538,7 +538,7 b' TODO: To be written...' | |||
|
538 | 538 | 'sys.exit(1)', |
|
539 | 539 | ] |
|
540 | 540 | f.write('\n'.join(script_lines)) |
|
541 | os.chmod(hook_path, 0755) | |
|
541 | os.chmod(hook_path, 0o755) | |
|
542 | 542 | |
|
543 | 543 | def test_local_push_does_not_execute_hook(self): |
|
544 | 544 | target_repo = self.get_empty_repo() |
@@ -1061,7 +1061,7 b' class TestGitSpecificWithRepo(BackendTes' | |||
|
1061 | 1061 | FileNode('foobar/static/js/admin/base.js', content='base'), |
|
1062 | 1062 | FileNode( |
|
1063 | 1063 | 'foobar/static/admin', content='admin', |
|
1064 | mode=0120000), # this is a link | |
|
1064 | mode=0o120000), # this is a link | |
|
1065 | 1065 | FileNode('foo', content='foo'), |
|
1066 | 1066 | ], |
|
1067 | 1067 | }, |
@@ -190,13 +190,13 b' class TestNodeBasics:' | |||
|
190 | 190 | assert not mode & stat.S_IXOTH |
|
191 | 191 | |
|
192 | 192 | def test_file_node_is_executable(self): |
|
193 | node = FileNode('foobar', 'empty... almost', mode=0100755) | |
|
193 | node = FileNode('foobar', 'empty... almost', mode=0o100755) | |
|
194 | 194 | assert node.is_executable |
|
195 | 195 | |
|
196 | node = FileNode('foobar', 'empty... almost', mode=0100500) | |
|
196 | node = FileNode('foobar', 'empty... almost', mode=0o100500) | |
|
197 | 197 | assert node.is_executable |
|
198 | 198 | |
|
199 | node = FileNode('foobar', 'empty... almost', mode=0100644) | |
|
199 | node = FileNode('foobar', 'empty... almost', mode=0o100644) | |
|
200 | 200 | assert not node.is_executable |
|
201 | 201 | |
|
202 | 202 | def test_file_node_is_not_symlink(self): |
@@ -259,13 +259,13 b' class TestRepositoryGetCommonAncestor:' | |||
|
259 | 259 | commit_id1=original[0].raw_id, |
|
260 | 260 | commit_id2=unrelated[0].raw_id, |
|
261 | 261 | repo2=unrelated |
|
262 |
) |
|
|
262 | ) is None | |
|
263 | 263 | |
|
264 | 264 | assert original.get_common_ancestor( |
|
265 | 265 | commit_id1=original[-1].raw_id, |
|
266 | 266 | commit_id2=unrelated[-1].raw_id, |
|
267 | 267 | repo2=unrelated |
|
268 |
) |
|
|
268 | ) is None | |
|
269 | 269 | |
|
270 | 270 | |
|
271 | 271 | @pytest.mark.backends("git", "hg") |
@@ -148,15 +148,6 b' setup(' | |||
|
148 | 148 | }, |
|
149 | 149 | paster_plugins=['PasteScript'], |
|
150 | 150 | entry_points={ |
|
151 | 'enterprise.plugins1': [ | |
|
152 | 'crowd=rhodecode.authentication.plugins.auth_crowd:plugin_factory', | |
|
153 | 'headers=rhodecode.authentication.plugins.auth_headers:plugin_factory', | |
|
154 | 'jasig_cas=rhodecode.authentication.plugins.auth_jasig_cas:plugin_factory', | |
|
155 | 'ldap=rhodecode.authentication.plugins.auth_ldap:plugin_factory', | |
|
156 | 'pam=rhodecode.authentication.plugins.auth_pam:plugin_factory', | |
|
157 | 'rhodecode=rhodecode.authentication.plugins.auth_rhodecode:plugin_factory', | |
|
158 | 'token=rhodecode.authentication.plugins.auth_token:plugin_factory', | |
|
159 | ], | |
|
160 | 151 | 'paste.app_factory': [ |
|
161 | 152 | 'main=rhodecode.config.middleware:make_pyramid_app', |
|
162 | 153 | ], |
|
1 | NO CONTENT: file was removed, binary diff hidden |
|
1 | NO CONTENT: file was removed, binary diff hidden |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now