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 |
|
NO CONTENT: new file 100644, binary diff hidden |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
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 | [bumpversion] |
|
1 | [bumpversion] | |
2 |
current_version = 4.1 |
|
2 | current_version = 4.15.0 | |
3 | message = release: Bump version {current_version} to {new_version} |
|
3 | message = release: Bump version {current_version} to {new_version} | |
4 |
|
4 | |||
5 | [bumpversion:file:rhodecode/VERSION] |
|
5 | [bumpversion:file:rhodecode/VERSION] |
@@ -5,25 +5,20 b' done = false' | |||||
5 | done = true |
|
5 | done = true | |
6 |
|
6 | |||
7 | [task:rc_tools_pinned] |
|
7 | [task:rc_tools_pinned] | |
8 | done = true |
|
|||
9 |
|
8 | |||
10 | [task:fixes_on_stable] |
|
9 | [task:fixes_on_stable] | |
11 | done = true |
|
|||
12 |
|
10 | |||
13 | [task:pip2nix_generated] |
|
11 | [task:pip2nix_generated] | |
14 | done = true |
|
|||
15 |
|
12 | |||
16 | [task:changelog_updated] |
|
13 | [task:changelog_updated] | |
17 | done = true |
|
|||
18 |
|
14 | |||
19 | [task:generate_api_docs] |
|
15 | [task:generate_api_docs] | |
20 | done = true |
|
16 | ||
|
17 | [task:updated_translation] | |||
21 |
|
18 | |||
22 | [release] |
|
19 | [release] | |
23 |
state = |
|
20 | state = in_progress | |
24 |
version = 4.1 |
|
21 | version = 4.15.0 | |
25 |
|
||||
26 | [task:updated_translation] |
|
|||
27 |
|
22 | |||
28 | [task:generate_js_routes] |
|
23 | [task:generate_js_routes] | |
29 |
|
24 |
@@ -7,18 +7,20 b' About' | |||||
7 |
|
7 | |||
8 | ``RhodeCode`` is a fast and powerful management tool for Mercurial_ and GIT_ |
|
8 | ``RhodeCode`` is a fast and powerful management tool for Mercurial_ and GIT_ | |
9 | and Subversion_ with a built in push/pull server, full text search, |
|
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 | has a few unique features like: |
|
11 | has a few unique features like: | |
12 |
|
12 | |||
13 |
|
|
13 | - plugable architecture from Pyramid web-framework. | |
14 |
|
|
14 | - advanced permission system with IP restrictions, inheritation, and user-groups. | |
15 |
|
|
15 | - rich set of authentication plugins including LDAP, ActiveDirectory, SAML 2.0, | |
16 |
|
|
16 | Atlassian Crowd, Http-Headers, Pam, Token-Auth, OAuth. | |
17 |
|
|
17 | - live code-review chat, and reviewer rules. | |
18 |
|
|
18 | - full web based file editing. | |
19 |
|
|
19 | - unified multi vcs support. | |
20 |
|
|
20 | - snippets (gist) system. | |
21 | - integration with all 3rd party issue trackers |
|
21 | - integration framework for Slack, CI systems, Webhooks. | |
|
22 | - integration with all 3rd party issue trackers. | |||
|
23 | ||||
22 |
|
24 | |||
23 | RhodeCode also provides rich API, and multiple event hooks so it's easy |
|
25 | RhodeCode also provides rich API, and multiple event hooks so it's easy | |
24 | integrable with existing external systems. |
|
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 | [DEFAULT] |
|
7 | [DEFAULT] | |
|
8 | ## Debug flag sets all loggers to debug, and enables request tracking | |||
8 | debug = true |
|
9 | debug = true | |
9 |
|
10 | |||
10 | ################################################################################ |
|
11 | ################################################################################ | |
@@ -414,6 +415,7 b' search.location = %(here)s/data/index' | |||||
414 | ######################################## |
|
415 | ######################################## | |
415 | ## channelstream enables persistent connections and live notification |
|
416 | ## channelstream enables persistent connections and live notification | |
416 | ## in the system. It's also used by the chat system |
|
417 | ## in the system. It's also used by the chat system | |
|
418 | ||||
417 | channelstream.enabled = false |
|
419 | channelstream.enabled = false | |
418 |
|
420 | |||
419 | ## server address for channelstream server on the backend |
|
421 | ## server address for channelstream server on the backend | |
@@ -490,14 +492,6 b' appenlight.request_keys_blacklist =' | |||||
490 | ## (by default the client ignores own entries: appenlight_client.client) |
|
492 | ## (by default the client ignores own entries: appenlight_client.client) | |
491 | appenlight.log_namespace_blacklist = |
|
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 | # enable debug style page |
|
495 | # enable debug style page | |
502 | debug_style = true |
|
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 | [DEFAULT] |
|
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 | ## EMAIL CONFIGURATION ## |
|
12 | ## EMAIL CONFIGURATION ## | |
@@ -389,6 +390,7 b' search.location = %(here)s/data/index' | |||||
389 | ######################################## |
|
390 | ######################################## | |
390 | ## channelstream enables persistent connections and live notification |
|
391 | ## channelstream enables persistent connections and live notification | |
391 | ## in the system. It's also used by the chat system |
|
392 | ## in the system. It's also used by the chat system | |
|
393 | ||||
392 | channelstream.enabled = false |
|
394 | channelstream.enabled = false | |
393 |
|
395 | |||
394 | ## server address for channelstream server on the backend |
|
396 | ## server address for channelstream server on the backend | |
@@ -466,14 +468,6 b' appenlight.request_keys_blacklist =' | |||||
466 | appenlight.log_namespace_blacklist = |
|
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 | ### MAIN RHODECODE DATABASE CONFIG ### |
|
472 | ### MAIN RHODECODE DATABASE CONFIG ### | |
479 | ########################################### |
|
473 | ########################################### | |
@@ -524,6 +518,7 b' vcs.scm_app_implementation = http' | |||||
524 | ## Push/Pull operations hooks protocol, available options are: |
|
518 | ## Push/Pull operations hooks protocol, available options are: | |
525 | ## `http` - use http-rpc backend (default) |
|
519 | ## `http` - use http-rpc backend (default) | |
526 | vcs.hooks.protocol = http |
|
520 | vcs.hooks.protocol = http | |
|
521 | ||||
527 | ## Host on which this instance is listening for hooks. If vcsserver is in other location |
|
522 | ## Host on which this instance is listening for hooks. If vcsserver is in other location | |
528 | ## this should be adjusted. |
|
523 | ## this should be adjusted. | |
529 | vcs.hooks.host = 127.0.0.1 |
|
524 | vcs.hooks.host = 127.0.0.1 |
@@ -3,19 +3,19 b'' | |||||
3 | Anonymous Users |
|
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 | configured to be **world-open** in terms of read and write permissions. This |
|
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 | public hub where unregistered users have access to your |repos|. |
|
9 | public hub where unregistered users have access to your |repos|. | |
10 |
|
10 | |||
11 | Anonymous access is useful for open source projects, universities, |
|
11 | Anonymous access is useful for open source projects, universities, | |
12 | or if running inside a restricted internal corporate network to serve |
|
12 | or if running inside a restricted internal corporate network to serve | |
13 | documents to all employees. Anonymous users get the default user permission |
|
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 | To enable anonymous access to your |repos|, use the following steps: |
|
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 | 2. On the Application tab, check the :guilabel:`Allow anonymous access` box. |
|
19 | 2. On the Application tab, check the :guilabel:`Allow anonymous access` box. | |
20 | 3. Select :guilabel:`Save`. |
|
20 | 3. Select :guilabel:`Save`. | |
21 | 4. To set the anonymous user access permissions, which are based on the |
|
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 | ``pretxnchangegroup.example`` with value ``python:/path/to/custom_hook.py:my_func_name`` |
|
166 | ``pretxnchangegroup.example`` with value ``python:/path/to/custom_hook.py:my_func_name`` | |
167 | 3. Select :guilabel:`Save` |
|
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 | Extensions can be used to add additional hooks to your instance and comes |
|
170 | Extensions can be used to add additional hooks to your instance and comes | |
171 | with a number of pre-built plugins if you chose to install them. |
|
171 | with a number of pre-built plugins if you chose to install them. | |
172 |
|
172 |
@@ -3,7 +3,7 b'' | |||||
3 | Apache WSGI Configuration |
|
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 | use the following steps. |
|
7 | use the following steps. | |
8 |
|
8 | |||
9 | 1. Install ``mod_wsgi`` using the following command: |
|
9 | 1. Install ``mod_wsgi`` using the following command: | |
@@ -50,6 +50,6 b' The following is an example ``wsgi`` dis' | |||||
50 | .. note:: |
|
50 | .. note:: | |
51 |
|
51 | |||
52 | When using `mod_wsgi` the same version of |hg| must be running in your |
|
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 | on the interface go to |
|
54 | on the interface go to | |
55 | :menuselection:`Admin --> Settings --> System Info` |
|
55 | :menuselection:`Admin --> Settings --> System Info` |
@@ -67,7 +67,7 b' sections.' | |||||
67 | Default location: :file:`/home/{user}/.rccontrol/cache/MANIFEST` |
|
67 | Default location: :file:`/home/{user}/.rccontrol/cache/MANIFEST` | |
68 |
|
68 | |||
69 | |RCC| uses this file to source the latest available builds from the |
|
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 | is if you need to do an offline installation, |
|
71 | is if you need to do an offline installation, | |
72 | see the :ref:`Offline Installation<control:offline-installer-ref>` |
|
72 | see the :ref:`Offline Installation<control:offline-installer-ref>` | |
73 | instructions, otherwise |RCC| will completely manage this file. |
|
73 | instructions, otherwise |RCC| will completely manage this file. |
@@ -3,6 +3,16 b'' | |||||
3 | Enabling Debug Mode |
|
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 | To enable debug mode on a |RCE| instance you need to set the debug property |
|
16 | To enable debug mode on a |RCE| instance you need to set the debug property | |
7 | in the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. To |
|
17 | in the :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. To | |
8 | do this, use the following steps |
|
18 | do this, use the following steps | |
@@ -11,14 +21,10 b' 1. Open the file and set the ``debug`` l' | |||||
11 | 2. Restart you instance using the ``rccontrol restart`` command, |
|
21 | 2. Restart you instance using the ``rccontrol restart`` command, | |
12 | see the following example: |
|
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 | .. code-block:: ini |
|
24 | .. code-block:: ini | |
18 |
|
25 | |||
19 | [DEFAULT] |
|
26 | [DEFAULT] | |
20 | debug = true |
|
27 | debug = true | |
21 | pdebug = false |
|
|||
22 |
|
28 | |||
23 | .. code-block:: bash |
|
29 | .. code-block:: bash | |
24 |
|
30 | |||
@@ -27,6 +33,7 b' You can also set the log level, the foll' | |||||
27 | Instance "enterprise-1" successfully stopped. |
|
33 | Instance "enterprise-1" successfully stopped. | |
28 | Instance "enterprise-1" successfully started. |
|
34 | Instance "enterprise-1" successfully started. | |
29 |
|
35 | |||
|
36 | ||||
30 | Debug and Logging Configuration |
|
37 | Debug and Logging Configuration | |
31 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
32 |
|
39 | |||
@@ -47,7 +54,7 b' the ``debug`` level.' | |||||
47 | ### LOGGING CONFIGURATION #### |
|
54 | ### LOGGING CONFIGURATION #### | |
48 | ################################ |
|
55 | ################################ | |
49 | [loggers] |
|
56 | [loggers] | |
50 | keys = root, sqlalchemy, rhodecode, ssh_wrapper |
|
57 | keys = root, sqlalchemy, beaker, celery, rhodecode, ssh_wrapper | |
51 |
|
58 | |||
52 | [handlers] |
|
59 | [handlers] | |
53 | keys = console, console_sql, file, file_rotating |
|
60 | keys = console, console_sql, file, file_rotating | |
@@ -62,11 +69,16 b' the ``debug`` level.' | |||||
62 | level = NOTSET |
|
69 | level = NOTSET | |
63 | handlers = console |
|
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 | level = DEBUG |
|
79 | level = DEBUG | |
67 | handlers = |
|
80 | handlers = | |
68 |
qualname = |
|
81 | qualname = beaker.container | |
69 | ## "level = DEBUG" logs the route matched and routing variables. |
|
|||
70 | propagate = 1 |
|
82 | propagate = 1 | |
71 |
|
83 | |||
72 | [logger_rhodecode] |
|
84 | [logger_rhodecode] | |
@@ -75,11 +87,16 b' the ``debug`` level.' | |||||
75 | qualname = rhodecode |
|
87 | qualname = rhodecode | |
76 | propagate = 1 |
|
88 | propagate = 1 | |
77 |
|
89 | |||
78 |
[logger_s |
|
90 | [logger_ssh_wrapper] | |
79 |
level = |
|
91 | level = DEBUG | |
80 |
handlers = |
|
92 | handlers = | |
81 |
qualname = s |
|
93 | qualname = ssh_wrapper | |
82 |
propagate = |
|
94 | propagate = 1 | |
|
95 | ||||
|
96 | [logger_celery] | |||
|
97 | level = DEBUG | |||
|
98 | handlers = | |||
|
99 | qualname = celery | |||
83 |
|
100 | |||
84 | ############## |
|
101 | ############## | |
85 | ## HANDLERS ## |
|
102 | ## HANDLERS ## | |
@@ -87,19 +104,19 b' the ``debug`` level.' | |||||
87 |
|
104 | |||
88 | [handler_console] |
|
105 | [handler_console] | |
89 | class = StreamHandler |
|
106 | class = StreamHandler | |
90 | args = (sys.stderr,) |
|
107 | args = (sys.stderr, ) | |
91 |
level = |
|
108 | level = DEBUG | |
92 | formatter = generic |
|
109 | formatter = generic | |
93 |
|
110 | |||
94 | [handler_console_sql] |
|
111 | [handler_console_sql] | |
95 | class = StreamHandler |
|
112 | class = StreamHandler | |
96 | args = (sys.stderr,) |
|
113 | args = (sys.stderr, ) | |
97 |
level = |
|
114 | level = INFO | |
98 | formatter = generic |
|
115 | formatter = generic | |
99 |
|
116 | |||
100 | [handler_file] |
|
117 | [handler_file] | |
101 | class = FileHandler |
|
118 | class = FileHandler | |
102 | args = ('rhodecode.log', 'a',) |
|
119 | args = ('rhodecode_debug.log', 'a',) | |
103 | level = INFO |
|
120 | level = INFO | |
104 | formatter = generic |
|
121 | formatter = generic | |
105 |
|
122 | |||
@@ -107,6 +124,25 b' the ``debug`` level.' | |||||
107 | class = logging.handlers.TimedRotatingFileHandler |
|
124 | class = logging.handlers.TimedRotatingFileHandler | |
108 | # 'D', 5 - rotate every 5days |
|
125 | # 'D', 5 - rotate every 5days | |
109 | # you can set 'h', 'midnight' |
|
126 | # you can set 'h', 'midnight' | |
110 | args = ('rhodecode.log', 'D', 5, 10,) |
|
127 | args = ('rhodecode_debug_rotated.log', 'D', 5, 10,) | |
111 | level = INFO |
|
128 | level = INFO | |
112 | formatter = generic |
|
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 | Adding more machines or workers into your pool of resources. |
|
33 | Adding more machines or workers into your pool of resources. | |
34 |
|
34 | |||
35 | Instance |
|
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 | refer to |RCE| or the VCS server depending on the context. |
|
37 | refer to |RCE| or the VCS server depending on the context. | |
38 |
|
38 | |||
39 | Plugin |
|
39 | Plugin |
@@ -3,7 +3,7 b'' | |||||
3 | Full-text Search |
|
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 | provide full-text search. |
|
7 | provide full-text search. | |
8 |
|
8 | |||
9 | |RCE| also provides support for `Elasticsearch`_ as a backend for scalable |
|
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 | |RCT| uses the :file:`/home/{user}/.rhoderc` file for connection details |
|
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 | you can configure it using the following example. You need to configure the |
|
50 | you can configure it using the following example. You need to configure the | |
51 | details for each instance you want to index. |
|
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 | - VERSION: 1.5.0 |
|
62 | - VERSION: 1.5.0 | |
63 | - URL: http://127.0.0.1:10000 |
|
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 | :menuselection:`username --> My Account --> Auth tokens` |
|
66 | :menuselection:`username --> My Account --> Auth tokens` | |
67 |
|
67 | |||
68 | .. code-block:: ini |
|
68 | .. code-block:: ini |
@@ -3,7 +3,7 b'' | |||||
3 | Public Access |
|
3 | Public Access | |
4 | ------------- |
|
4 | ------------- | |
5 |
|
5 | |||
6 |
By default |RC |
|
6 | By default |RCE| allows users to read all **public** |repos|. User | |
7 | permissions and |repo| access can be configured explicitly, |
|
7 | permissions and |repo| access can be configured explicitly, | |
8 | and those permissions will override any default settings. The default |
|
8 | and those permissions will override any default settings. The default | |
9 | settings can be found under the following section: |
|
9 | settings can be found under the following section: |
@@ -7,7 +7,7 b' Extra fields attached to a |repo| allow ' | |||||
7 | each repository. This allows storing custom data per-repository. |
|
7 | each repository. This allows storing custom data per-repository. | |
8 |
|
8 | |||
9 | It can be used in :ref:`integrations-webhook` or in |RCX|. |
|
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 | Enabling Extra Fields |
|
13 | Enabling Extra Fields |
@@ -46,11 +46,6 b' This is the complete list of |repos| hoo' | |||||
46 | Using Repository Hooks |
|
46 | Using Repository Hooks | |
47 | ---------------------- |
|
47 | ---------------------- | |
48 |
|
48 | |||
49 |
To use these hooks you need to |
|
49 | To use these hooks you need to setup |RCX|. For more information, see the | |
50 |
:ref:`in |
|
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 | Setting Default Permissions |
|
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 | or user is created their permissions are already defined. To set default permissions you need administrator |
|
7 | or user is created their permissions are already defined. To set default permissions you need administrator | |
8 | privileges. See the following sections for setting up your permissions system: |
|
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 | To set default user permissions, use the following steps. |
|
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 | 2. Select the :guilabel:`Global` tab from the left-hand menu. The permissions |
|
23 | 2. Select the :guilabel:`Global` tab from the left-hand menu. The permissions | |
24 | set on this screen apply to users and user-groups across the whole instance. |
|
24 | set on this screen apply to users and user-groups across the whole instance. | |
25 | 3. Save your changes |
|
25 | 3. Save your changes | |
@@ -31,7 +31,7 b' Setting User Group defaults' | |||||
31 |
|
31 | |||
32 | To set default user group permissions, use the following steps. |
|
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 | 2. Select :guilabel:`Permissions`, and configure the default user |
|
35 | 2. Select :guilabel:`Permissions`, and configure the default user | |
36 | permissions. All users will get these permissions unless |
|
36 | permissions. All users will get these permissions unless | |
37 | individually set. |
|
37 | individually set. | |
@@ -48,7 +48,7 b' Setting Repository defaults' | |||||
48 |
|
48 | |||
49 | To set default |repo| permissions, use the following steps. |
|
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 | 2. Select the :guilabel:`Object` tab from the left-hand menu and set the |
|
52 | 2. Select the :guilabel:`Object` tab from the left-hand menu and set the | |
53 | |perm| permissions |
|
53 | |perm| permissions | |
54 | 3. Save your changes |
|
54 | 3. Save your changes | |
@@ -60,7 +60,7 b' Setting Repository Group defaults' | |||||
60 |
|
60 | |||
61 | To set default Repository Group permissions, use the following steps. |
|
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 | 2. Select :guilabel:`Edit` beside the |repo| group you wish to configure |
|
64 | 2. Select :guilabel:`Edit` beside the |repo| group you wish to configure | |
65 | 3. On the left-hand pane select :guilabel:`Permissions` |
|
65 | 3. On the left-hand pane select :guilabel:`Permissions` | |
66 | 4. Set the default permissions for all |repos| created in this group |
|
66 | 4. Set the default permissions for all |repos| created in this group |
@@ -3,12 +3,12 b'' | |||||
3 | Repository Administration |
|
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 | This overview should give you an insight into how you could adopt particular |
|
7 | This overview should give you an insight into how you could adopt particular | |
8 | settings for your needs: |
|
8 | settings for your needs: | |
9 |
|
9 | |||
10 | * Global |repo| permissions: This allows you to set the default permissions |
|
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 | |repos| created will inherit these permissions unless explicitly configured. |
|
12 | |repos| created will inherit these permissions unless explicitly configured. | |
13 | * Individual |repo| permissions: To set individual |repo| permissions, |
|
13 | * Individual |repo| permissions: To set individual |repo| permissions, | |
14 | see :ref:`set-repo-perms`. |
|
14 | see :ref:`set-repo-perms`. |
@@ -18,13 +18,14 b' Prerequisites' | |||||
18 | .. tip:: |
|
18 | .. tip:: | |
19 |
|
19 | |||
20 | We recommend using Wandisco repositories which provide latest SVN versions |
|
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 | Here is an example how to add the Wandisco repositories for Ubuntu. |
|
23 | Here is an example how to add the Wandisco repositories for Ubuntu. | |
23 |
|
24 | |||
24 | .. code-block:: bash |
|
25 | .. code-block:: bash | |
25 |
|
26 | |||
26 |
$ sudo sh -c 'echo "deb http://opensource.wandisco.com/ubuntu `lsb_release -cs` svn1 |
|
27 | $ sudo sh -c 'echo "deb http://opensource.wandisco.com/ubuntu `lsb_release -cs` svn110" >> /etc/apt/sources.list.d/subversion110.list' | |
27 | $ sudo wget -q http://opensource.wandisco.com/wandisco-debian.gpg -O- | sudo apt-key add - |
|
28 | $ sudo wget -q http://opensource.wandisco.com/wandisco-debian-new.gpg -O- | sudo apt-key add - | |
28 | $ sudo apt-get update |
|
29 | $ sudo apt-get update | |
29 |
|
30 | |||
30 | Here is an example how to add the Wandisco repositories for Centos/Redhat. Using |
|
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 | .. code-block:: bash |
|
47 | .. code-block:: bash | |
47 |
|
48 | |||
48 | $ sudo apt-get install apache2 |
|
49 | $ sudo apt-get install apache2 | |
49 |
$ sudo apt-get install libapache2- |
|
50 | $ sudo apt-get install libapache2-svn | |
50 |
|
51 | |||
51 | Once installed you need to enable ``dav_svn`` on Ubuntu: |
|
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 | LoadModule headers_module modules/mod_headers.so |
|
77 | LoadModule headers_module modules/mod_headers.so | |
77 | LoadModule authn_anon_module modules/mod_authn_anon.so |
|
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 | Configuring Apache Setup |
|
87 | Configuring Apache Setup | |
81 | ======================== |
|
88 | ======================== |
@@ -59,7 +59,7 b' Supported Browsers' | |||||
59 | System Requirements |
|
59 | System Requirements | |
60 | ------------------- |
|
60 | ------------------- | |
61 |
|
61 | |||
62 |
|RC |
|
62 | |RCE| performs best on machines with ultra-fast hard disks. Generally disk | |
63 | performance is more important than CPU performance. In a corporate production |
|
63 | performance is more important than CPU performance. In a corporate production | |
64 | environment handling 1000s of users and |repos| you should deploy on a 12+ |
|
64 | environment handling 1000s of users and |repos| you should deploy on a 12+ | |
65 | core 64GB RAM server. In short, the more RAM the better. |
|
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 | For example: |
|
68 | For example: | |
69 |
|
69 | |||
70 | - for team of 1 - 5 active users you can run on 1GB RAM machine with 1CPU |
|
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 | Number of CPUs is less important, but recommended to have at least 2-3 CPUs |
|
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 | * HTTPS |
|
115 | * HTTPS | |
116 | * SSH |
|
116 | * SSH | |
117 |
* |RC |
|
117 | * |RCE| API | |
118 |
|
118 | |||
119 | Internationalization Support |
|
119 | Internationalization Support | |
120 | ---------------------------- |
|
120 | ---------------------------- |
@@ -146,7 +146,7 b' persistent sessions across nodes. Please' | |||||
146 |
|
146 | |||
147 | .. code-block:: ini |
|
147 | .. code-block:: ini | |
148 |
|
148 | |||
149 |
# use a |
|
149 | # use a unique generated long string | |
150 | beaker.session.secret = 70e116cae2274656ba7265fd860aebbd |
|
150 | beaker.session.secret = 70e116cae2274656ba7265fd860aebbd | |
151 |
|
151 | |||
152 | 3) Configure stored cached/archive cache to our shared NFS `rc-node-1` |
|
152 | 3) Configure stored cached/archive cache to our shared NFS `rc-node-1` |
@@ -3,7 +3,7 b'' | |||||
3 | User Administration |
|
3 | User Administration | |
4 | =================== |
|
4 | =================== | |
5 |
|
5 | |||
6 |
|RC |
|
6 | |RCE| enables you to define permissions for the following entities within the | |
7 | system; **users**, **user groups**, **repositories**, **repository groups**. |
|
7 | system; **users**, **user groups**, **repositories**, **repository groups**. | |
8 |
|
8 | |||
9 | Within each one of these entities you can set default settings, |
|
9 | Within each one of these entities you can set default settings, |
@@ -3,13 +3,13 b'' | |||||
3 | VCS Server Management |
|
3 | VCS Server Management | |
4 | --------------------- |
|
4 | --------------------- | |
5 |
|
5 | |||
6 |
The VCS Server handles |RC |
|
6 | The VCS Server handles |RCE| backend functionality. You need to configure | |
7 |
a VCS Server to run with a |RC |
|
7 | a VCS Server to run with a |RCE| instance. If you do not, you will be missing | |
8 |
the connection between |RC |
|
8 | the connection between |RCE| and its |repos|. This will cause error messages | |
9 | on the web interface. You can run your setup in the following configurations, |
|
9 | on the web interface. You can run your setup in the following configurations, | |
10 | currently the best performance is one of following: |
|
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 | * One VCS Server handling multiple instances. |
|
13 | * One VCS Server handling multiple instances. | |
14 |
|
14 | |||
15 | .. important:: |
|
15 | .. important:: | |
@@ -49,7 +49,7 b' To configure a |RCE| instance to use a V' | |||||
49 | |RCE| VCS Server Options |
|
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 | connection to the VCS Server. The settings are configured per |
|
53 | connection to the VCS Server. The settings are configured per | |
54 | instance in the |
|
54 | instance in the | |
55 | :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. |
|
55 | :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. | |
@@ -75,7 +75,7 b' instance in the' | |||||
75 |
|
75 | |||
76 | \vcs.server <host:port> |
|
76 | \vcs.server <host:port> | |
77 | Set the host, either hostname or IP Address, and port of the VCS server |
|
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 | .. code-block:: ini |
|
80 | .. code-block:: ini | |
81 |
|
81 |
@@ -22,12 +22,12 b' API access can also be turned on for eac' | |||||
22 | decorated with a `@LoginRequired` decorator. To enable API access, change |
|
22 | decorated with a `@LoginRequired` decorator. To enable API access, change | |
23 | the standard login decorator to `@LoginRequired(api_access=True)`. |
|
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 | of views that have API access enabled by default. To enable these, |
|
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 |
|
29 | * |RCE| Pre-2.2.7 :file:`root/rhodecode/data/production.ini` | |
30 |
* |RC |
|
30 | * |RCE| 3.0 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` | |
31 |
|
31 | |||
32 | To configure the white list, edit this section of the file. In this |
|
32 | To configure the white list, edit this section of the file. In this | |
33 | configuration example, API access is granted to the patch/diff raw file and |
|
33 | configuration example, API access is granted to the patch/diff raw file and |
@@ -5,8 +5,8 b' Crowd' | |||||
5 |
|
5 | |||
6 | To enable Crowd authentication, use the following steps: |
|
6 | To enable Crowd authentication, use the following steps: | |
7 |
|
7 | |||
8 |
1. From the |RC |
|
8 | 1. From the |RCE| interface, go to :menuselection:`Admin --> Authentication` | |
9 |
2. |
|
9 | 2. Activate the ``rhodecode.lib.auth_modules.auth_crowd`` library and select | |
10 | :guilabel:`Save` |
|
10 | :guilabel:`Save` | |
11 | 3. On the Crowd plugin settings section, do the following: |
|
11 | 3. On the Crowd plugin settings section, do the following: | |
12 |
|
12 |
@@ -3,25 +3,24 b'' | |||||
3 | LDAP/AD With User Groups Sync |
|
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 | AD (active Directory) authentication. |
|
9 | AD (active Directory) authentication. | |
8 | All LDAP versions are supported, with the following |RCM| plugins managing each: |
|
10 | All LDAP versions are currently supported. | |
9 |
|
||||
10 | * For LDAP/AD with user group sync use ``LDAP + User Groups (egg:rhodecode-enterprise-ee#ldap_group)`` |
|
|||
11 |
|
11 | |||
12 | RhodeCode reads all data defined from plugin and creates corresponding |
|
12 | RhodeCode reads all data defined from plugin and creates corresponding | |
13 | accounts on local database after receiving data from LDAP. This is done on |
|
13 | accounts on local database after receiving data from LDAP. This is done on | |
14 | every user log-in including operations like pushing/pulling/checkout. |
|
14 | every user log-in including operations like pushing/pulling/checkout. | |
15 | In addition group membership is read from LDAP and following operations are done: |
|
15 | In addition group membership is read from LDAP and following operations are done: | |
16 |
|
16 | |||
17 |
- automatic addition of user to |RC |
|
17 | - automatic addition of user to |RCE| user group | |
18 |
- automatic removal of user from any other |RC |
|
18 | - automatic removal of user from any other |RCE| user groups not specified in LDAP. | |
19 | The removal is done *only* on groups that are marked to be synced from ldap. |
|
19 | The removal is done *only* on groups that are marked to be synced from ldap. | |
20 | This setting can be changed in advanced settings on user groups |
|
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 | - marking user as super-admins if he is a member of any admin group defined in plugin settings |
|
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 | .. important:: |
|
25 | .. important:: | |
27 |
|
26 | |||
@@ -39,11 +38,12 b' LDAP Configuration Steps' | |||||
39 |
|
38 | |||
40 | To configure |LDAP|, use the following steps: |
|
39 | To configure |LDAP|, use the following steps: | |
41 |
|
40 | |||
42 |
1. From the |RC |
|
41 | 1. From the |RCE| interface, select | |
43 | :menuselection:`Admin --> Authentication` |
|
42 | :menuselection:`Admin --> Authentication` | |
44 |
2. |
|
43 | 2. Activate the `LDAP + User Groups` plugin and select :guilabel:`Save` | |
45 | 3. Select the :guilabel:`Enabled` check box in the plugin configuration section |
|
44 | 3. Go to newly available menu option called `LDAP + User Groups` on the left side. | |
46 | 4. Add the required LDAP information and :guilabel:`Save`, for more details, |
|
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 | see :ref:`config-ldap-groups-examples` |
|
47 | see :ref:`config-ldap-groups-examples` | |
48 |
|
48 | |||
49 | For a more detailed description of LDAP objects, see :ref:`ldap-gloss-ref`: |
|
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 | Example LDAP configuration |
|
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. |
|
105 | *option*: `user_search_filter` => `` | |
58 | # This means that cache result will be saved for 3600 before contacting LDAP server to verify the user access |
|
106 | # Filter to narrow results | |
59 | 3600 |
|
107 | # (e.g., (&(objectCategory=Person)(objectClass=user)), or | |
60 | # Host, comma seperated format is optionally possible to specify more than 1 server |
|
108 | # (memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com))) | |
61 | https://ldap1.server.com/ldap-admin/,https://ldap2.server.com/ldap-admin/ |
|
109 | ||
62 | # Default LDAP Port, use 689 for LDAPS |
|
110 | *option*: `search_scope` => `SUBTREE` | |
63 | 389 |
|
111 | # How deep to search LDAP. If unsure set to SUBTREE | |
64 | # Account, used for SimpleBind if LDAP server requires an authentication |
|
112 | ||
65 | e.g admin@server.com |
|
113 | *option*: `attr_login` => `sAMAccountName` | |
66 | # Password used for simple bind |
|
114 | # LDAP Attribute to map to user name (e.g., uid, or sAMAccountName) | |
67 | ldap-user-password |
|
115 | ||
68 | # LDAP connection security |
|
116 | *option*: `attr_email` => `mail` | |
69 | LDAPS |
|
117 | # LDAP Attribute to map to email address (e.g., mail). | |
70 | # Certificate checks level |
|
118 | # Emails are a crucial part of RhodeCode. | |
71 | DEMAND |
|
119 | # If possible add a valid email attribute to ldap users. | |
72 | # Base DN |
|
120 | ||
73 | cn=Rufus Magillacuddy,ou=users,dc=rhodecode,dc=com |
|
121 | *option*: `attr_firstname` => `givenName` | |
74 | # User Search Base |
|
122 | # LDAP Attribute to map to first name (e.g., givenName) | |
75 | ou=groups,ou=users |
|
123 | ||
76 | # LDAP search filter to narrow the results |
|
124 | *option*: `attr_lastname` => `sn` | |
77 | (objectClass=person) |
|
125 | # LDAP Attribute to map to last name (e.g., sn) | |
78 | # LDAP search scope |
|
126 | ||
79 | SUBTREE |
|
127 | *option*: `group_extraction_type` => `rfc2307bis` | |
80 | # Login attribute |
|
128 | # With rfc2307, group members are listed by name in the memberUid attribute | |
81 | sAMAccountName |
|
129 | # With rfc2307bis (Microsoft AD compatible) group members are listed by DN and stored in the member attribute | |
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 |
|
|||
97 |
|
|
130 | ||
98 | # Admin Groups. Comma separated list of groups. If user is member of |
|
131 | *option*: `group_search_base` => `ou=RC-Groups` | |
99 | # any of those he will be marked as super-admin in RhodeCode |
|
132 | # Group search base will extend the Base DN (e.g. ou=Groups will result in ou=Groups,dc=mydomain,dc=com) | |
100 | admins, management |
|
|||
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 |
|
148 | *option*: `admin_groups` => `Admins,Management` | |
106 | :alt: LDAP/AD setup example |
|
149 | # A comma separated list of group names that identify users as RhodeCode Administrators (e.g., admins) | |
107 | :scale: 50 % |
|
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 | .. toctree:: |
|
157 | .. toctree:: | |
110 |
|
158 |
@@ -3,11 +3,9 b'' | |||||
3 | LDAP/AD |
|
3 | LDAP/AD | |
4 | ------- |
|
4 | ------- | |
5 |
|
5 | |||
6 |
|RC |
|
6 | |RCE| supports LDAP (Lightweight Directory Access Protocol) or | |
7 | AD (active Directory) authentication. |
|
7 | AD (active Directory) authentication. | |
8 | All LDAP versions are supported, with the following |RCM| plugins managing each: |
|
8 | All LDAP versions are currently supported. | |
9 |
|
||||
10 | * For LDAP or Active Directory use ``LDAP (egg:rhodecode-enterprise-ce#ldap)`` |
|
|||
11 |
|
9 | |||
12 | RhodeCode reads all data defined from plugin and creates corresponding |
|
10 | RhodeCode reads all data defined from plugin and creates corresponding | |
13 | accounts on local database after receiving data from LDAP. This is done on |
|
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 | To configure |LDAP|, use the following steps: |
|
29 | To configure |LDAP|, use the following steps: | |
32 |
|
30 | |||
33 |
1. From the |RC |
|
31 | 1. From the |RCE| interface, select | |
34 | :menuselection:`Admin --> Authentication` |
|
32 | :menuselection:`Admin --> Authentication` | |
35 |
2. |
|
33 | 2. Activate the `LDAP` plugin and select :guilabel:`Save` | |
36 | 3. Select the :guilabel:`Enabled` check box in the plugin configuration section |
|
34 | 3. Go to newly available menu option called `LDAP` on the left side. | |
37 | 4. Add the required LDAP information and :guilabel:`Save`, for more details, |
|
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 | see :ref:`config-ldap-examples` |
|
37 | see :ref:`config-ldap-examples` | |
39 |
|
38 | |||
40 | For a more detailed description of LDAP objects, see :ref:`ldap-gloss-ref`: |
|
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 | Example LDAP configuration |
|
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. |
|
76 | *option*: `tls_reqcert` => `NEVER` | |
49 | # This means that cache result will be saved for 3600 before contacting LDAP server to verify the user access |
|
77 | # Require Cert over TLS?. Self-signed and custom certificates can be used when | |
50 | 3600 |
|
78 | # `RhodeCode Certificate` found in admin > settings > system info page is extended. | |
51 | # Host, comma seperated format is optionally possible to specify more than 1 server |
|
79 | ||
52 | https://ldap1.server.com/ldap-admin/,https://ldap2.server.com/ldap-admin/ |
|
80 | *option*: `tls_cert_file` => `` | |
53 | # Default LDAP Port, use 689 for LDAPS |
|
81 | # This specifies the PEM-format file path containing certificates for use in TLS connection. | |
54 | 389 |
|
82 | # If not specified `TLS Cert dir` will be used | |
55 | # Account, used for SimpleBind if LDAP server requires an authentication |
|
83 | ||
56 | e.g admin@server.com |
|
84 | *option*: `tls_cert_dir` => `/etc/openldap/cacerts` | |
57 | # Password used for simple bind |
|
85 | # This specifies the path of a directory that contains individual CA certificates in separate files. | |
58 | ldap-user-password |
|
86 | ||
59 | # LDAP connection security |
|
87 | *option*: `base_dn` => `cn=Rufus Magillacuddy,ou=users,dc=rhodecode,dc=com` | |
60 | LDAPS |
|
88 | # Base DN to search. Dynamic bind is supported. Add `$login` marker in it to be replaced with current user credentials | |
61 | # Certificate checks level |
|
89 | # (e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com) | |
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 |
|
||||
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 |
|
102 | *option*: `attr_email` => `mail` | |
82 | :alt: LDAP/AD setup example |
|
103 | # LDAP Attribute to map to email address (e.g., mail). | |
83 | :scale: 50 % |
|
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 | .. toctree:: |
|
114 | .. toctree:: |
@@ -5,8 +5,8 b' PAM' | |||||
5 |
|
5 | |||
6 | To enable PAM authentication, use the following steps: |
|
6 | To enable PAM authentication, use the following steps: | |
7 |
|
7 | |||
8 |
1. From the |RC |
|
8 | 1. From the |RCE| interface, go to :menuselection:`Admin --> Authentication` | |
9 |
2. |
|
9 | 2. Activate the ``rhodecode.lib.auth_modules.auth_pam`` library and select save | |
10 | 3. On the PAM plugin settings section, do the following: |
|
10 | 3. On the PAM plugin settings section, do the following: | |
11 |
|
11 | |||
12 | * Check the :guilabel:`Enable` checkbox |
|
12 | * Check the :guilabel:`Enable` checkbox |
@@ -3,7 +3,10 b'' | |||||
3 | Authentication Tokens |
|
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 | * *API tokens*: API tokens can only be used to execute |RCE| API operations. |
|
11 | * *API tokens*: API tokens can only be used to execute |RCE| API operations. | |
9 | You can store your API token and assign it to each instance in |
|
12 | You can store your API token and assign it to each instance in | |
@@ -11,15 +14,7 b' Authentication Tokens' | |||||
11 | example in :ref:`indexing-ref` section for more details. |
|
14 | example in :ref:`indexing-ref` section for more details. | |
12 |
|
15 | |||
13 | * *Feed tokens*: The feed token can only be used to access the RSS feed. |
|
16 | * *Feed tokens*: The feed token can only be used to access the RSS feed. | |
14 |
|
|
17 | Usually those are safe to store inside your RSS feed reader. | |
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`. |
|
|||
23 |
|
18 | |||
24 | * *Web Interface tokens*: These token allows users to access the web |
|
19 | * *Web Interface tokens*: These token allows users to access the web | |
25 | interface of |RCE| without logging in. |
|
20 | interface of |RCE| without logging in. | |
@@ -41,7 +36,16 b' Authentication Tokens' | |||||
41 | https://rhodecode.com/repo/archive/tip.zip?auth_token=<web-api-token> |
|
36 | https://rhodecode.com/repo/archive/tip.zip?auth_token=<web-api-token> | |
42 |
|
37 | |||
43 | # To show commit diff without logging into Web UI |
|
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 | .. _enable-vcs-tokens: |
|
50 | .. _enable-vcs-tokens: | |
47 |
|
51 | |||
@@ -51,7 +55,7 b' Enabling VCS Tokens' | |||||
51 | To enable VCS Tokens, use the following steps: |
|
55 | To enable VCS Tokens, use the following steps: | |
52 |
|
56 | |||
53 | 1. Go to :menuselection:`Admin --> Authentication`. |
|
57 | 1. Go to :menuselection:`Admin --> Authentication`. | |
54 |
2. |
|
58 | 2. Activate the ``rhodecode.lib.auth_modules.auth_token`` plugin. | |
55 | 3. Click :guilabel:`Save`. |
|
59 | 3. Click :guilabel:`Save`. | |
56 |
|
60 | |||
57 | Authentication Token Tips |
|
61 | Authentication Token Tips | |
@@ -67,7 +71,7 b' Creating Tokens' | |||||
67 |
|
71 | |||
68 | To create authentication tokens for an user, use the following steps: |
|
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 | :menuselection:`Username --> My Account --> Auth tokens`. |
|
75 | :menuselection:`Username --> My Account --> Auth tokens`. | |
72 |
|
76 | |||
73 | 2. Label and Add the tokens you wish to use with |RCE|. |
|
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 | |RCE| provides a built in authentication against its own database. This is |
|
6 | |RCE| provides a built in authentication against its own database. This is | |
7 |
implemented using `` |
|
7 | implemented using ``RhodeCode Internal`` plugin. This plugin is enabled by default. | |
8 | enabled by default. |
|
|||
9 | Additionally, |RCE| provides a Pluggable Authentication System. This gives the |
|
8 | Additionally, |RCE| provides a Pluggable Authentication System. This gives the | |
10 | administrator greater control over how users authenticate with the system. |
|
9 | administrator greater control over how users authenticate with the system. | |
11 |
|
10 | |||
12 | .. important:: |
|
11 | .. important:: | |
13 |
|
12 | |||
14 |
You can disable the built in |RC |
|
13 | You can disable the built in |RCE| authentication plugin | |
15 |
`` |
|
14 | ``RhodeCode Internal`` and force all authentication to go | |
16 | through your authentication plugin of choice e.g LDAP only. |
|
15 | through your authentication plugin of choice e.g LDAP only. | |
17 | However, if you do this, and your external authentication tools fails, |
|
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 | .. toctree:: |
|
24 | .. toctree:: | |
24 |
|
25 | |||
|
26 | auth-token | |||
25 | auth-ldap |
|
27 | auth-ldap | |
26 | auth-ldap-groups |
|
28 | auth-ldap-groups | |
|
29 | auth-saml-generic | |||
|
30 | auth-saml-onelogin | |||
|
31 | auth-saml-duosecurity | |||
27 | auth-crowd |
|
32 | auth-crowd | |
28 | auth-pam |
|
33 | auth-pam | |
29 | auth-token |
|
|||
30 | ssh-connection |
|
34 | ssh-connection | |
31 |
|
||||
32 |
|
@@ -3,27 +3,73 b'' | |||||
3 | Active Directory |
|
3 | Active Directory | |
4 | ---------------- |
|
4 | ---------------- | |
5 |
|
5 | |||
6 |
|RC |
|
6 | |RCE| can use Microsoft Active Directory for user authentication. This is | |
7 | done through an LDAP or LDAPS connection to Active Directory. Use the |
|
7 | done through an LDAP or LDAPS connection to Active Directory. Use the | |
8 | following example LDAP configuration setting to set your Active Directory |
|
8 | following example LDAP configuration setting to set your Active Directory | |
9 |
authentication |
|
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 |
|
|||
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 |
|
44 | *option*: `tls_cert_file` => `` | |
28 | :alt: LDAP/AD setup example |
|
45 | # This specifies the PEM-format file path containing certificates for use in TLS connection. | |
29 | :scale: 50 % No newline at end of file |
|
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 | * The LDAP username or account used to connect to |RCE|. This will be added |
|
46 | * The LDAP username or account used to connect to |RCE|. This will be added | |
47 | to the LDAP filter for locating the user object. |
|
47 | to the LDAP filter for locating the user object. | |
48 | * For example, if an LDAP filter is specified as `LDAPFILTER`, |
|
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 | `jsmith`, then the LDAP Filter will be like the following example. |
|
50 | `jsmith`, then the LDAP Filter will be like the following example. | |
51 |
|
51 | |||
52 | .. code-block:: vim |
|
52 | .. code-block:: vim | |
@@ -68,7 +68,7 b' The following LDAP attributes are requir' | |||||
68 | Optional settings |
|
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 | * An LDAP account is only required if the LDAP server does not allow |
|
73 | * An LDAP account is only required if the LDAP server does not allow | |
74 | anonymous browsing of records. |
|
74 | anonymous browsing of records. | |
@@ -104,10 +104,4 b' The following are optional when enabling' | |||||
104 | following directory: `/etc/openldap/cacerts` |
|
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 | .. _RFC 2254: http://www.rfc-base.org/rfc-2254.html No newline at end of file |
|
107 | .. _RFC 2254: http://www.rfc-base.org/rfc-2254.html |
@@ -3,7 +3,7 b'' | |||||
3 | Code Review |
|
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 | commits. To better understand |prs|, see the :ref:`pull-requests-ref` |
|
7 | commits. To better understand |prs|, see the :ref:`pull-requests-ref` | |
8 | and :ref:`collaborate-ref` sections. For more information about why |
|
8 | and :ref:`collaborate-ref` sections. For more information about why | |
9 | code review matters, see these posts on the topic: |
|
9 | code review matters, see these posts on the topic: |
@@ -16,7 +16,7 b' review purposes.' | |||||
16 | Reviewing Changes |
|
16 | Reviewing Changes | |
17 | ----------------- |
|
17 | ----------------- | |
18 |
|
18 | |||
19 |
|RC |
|
19 | |RCE| displays all code changes made with each commit. Removed content is | |
20 | marked in red and new content in green. |
|
20 | marked in red and new content in green. | |
21 |
|
21 | |||
22 | .. image:: ../images/plain-diff.png |
|
22 | .. image:: ../images/plain-diff.png |
@@ -10,7 +10,7 b' 3. Leave a commit message that outlines ' | |||||
10 | 4. Set the review status to :guilabel:`Approved` |
|
10 | 4. Set the review status to :guilabel:`Approved` | |
11 | 5. Select :guilabel:`Comment` |
|
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 | detects that it can do so safely. You will see this message: |
|
14 | detects that it can do so safely. You will see this message: | |
15 |
|
15 | |||
16 | :guilabel:`This pull request can be automatically merged.` |
|
16 | :guilabel:`This pull request can be automatically merged.` |
@@ -7,7 +7,7 b' Collaboration' | |||||
7 |
|
7 | |||
8 | Forking and branching does not work with |svn| |repos|. |
|
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 | functions: |
|
11 | functions: | |
12 |
|
12 | |||
13 | .. only:: latex |
|
13 | .. only:: latex |
@@ -55,7 +55,7 b' on the web interface. To branch a |git| ' | |||||
55 | $ git commit -a -m "ghost script: initial file" |
|
55 | $ git commit -a -m "ghost script: initial file" | |
56 | $ git push |
|
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 | branch using the following steps: |
|
59 | branch using the following steps: | |
60 |
|
60 | |||
61 | 1. Select :menuselection:`Admin --> Repositories`. |
|
61 | 1. Select :menuselection:`Admin --> Repositories`. |
@@ -4,7 +4,7 b' Using Notifications' | |||||
4 | ------------------- |
|
4 | ------------------- | |
5 |
|
5 | |||
6 | To notify users of items that require their attention you can use the mention |
|
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 | The notification function can be used within the following |
|
8 | The notification function can be used within the following | |
9 | items to highlight their need for attention: |
|
9 | items to highlight their need for attention: | |
10 |
|
10 |
@@ -3,7 +3,7 b'' | |||||
3 | Merge a |pr| |
|
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 | can, you will see the following message: |
|
7 | can, you will see the following message: | |
8 | :guilabel:`This pull request can be automatically merged.` To merge, |
|
8 | :guilabel:`This pull request can be automatically merged.` To merge, | |
9 | click the big blue button! To enable this feature, see :ref:`server-side-merge`. |
|
9 | click the big blue button! To enable this feature, see :ref:`server-side-merge`. | |
@@ -21,7 +21,7 b' messages:' | |||||
21 | Manual Merge a |PR| |
|
21 | Manual Merge a |PR| | |
22 | ^^^^^^^^^^^^^^^^^^^ |
|
22 | ^^^^^^^^^^^^^^^^^^^ | |
23 |
|
23 | |||
24 |
If |RC |
|
24 | If |RCE| cannot safely merge the changes in a |pr|, | |
25 | usually due to conflicts, you need to manually merge the changes on the |
|
25 | usually due to conflicts, you need to manually merge the changes on the | |
26 | command line. You can see more information for each |repo| type at the |
|
26 | command line. You can see more information for each |repo| type at the | |
27 | following links: |
|
27 | following links: |
@@ -1,7 +1,7 b'' | |||||
1 | Notifications Overview |
|
1 | Notifications Overview | |
2 | ---------------------- |
|
2 | ---------------------- | |
3 |
|
3 | |||
4 |
|RC |
|
4 | |RCE| has an integrated notification system which alerts users to requests | |
5 | that they have received. Notifications can occur for the following reasons: |
|
5 | that they have received. Notifications can occur for the following reasons: | |
6 |
|
6 | |||
7 | * Pull request reviews |
|
7 | * Pull request reviews |
@@ -3,7 +3,7 b' Pull request management' | |||||
3 |
|
3 | |||
4 | .. only:: html |
|
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 | 1. :ref:`prs-your-review` |
|
8 | 1. :ref:`prs-your-review` | |
9 | 2. :ref:`prs-per-repo` |
|
9 | 2. :ref:`prs-per-repo` | |
@@ -15,7 +15,7 b' Pull requests for your review' | |||||
15 |
|
15 | |||
16 | To view pull requests for your review, use the following steps: |
|
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 | :menuselection:`username --> Notifications` |
|
19 | :menuselection:`username --> Notifications` | |
20 | 2. Select :guilabel:`Pull Requests` |
|
20 | 2. Select :guilabel:`Pull Requests` | |
21 |
|
21 |
@@ -20,7 +20,7 b' 3. Set the review status from one of the' | |||||
20 | 4. Select Comment |
|
20 | 4. Select Comment | |
21 |
|
21 | |||
22 | When the |pr| is approved by all reviewers you will be able to merge |
|
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 | message: `This pull request can be automatically merged.` |
|
24 | message: `This pull request can be automatically merged.` | |
25 |
|
25 | |||
26 | If rejected, you can fix the issues raised during review and then update the |
|
26 | If rejected, you can fix the issues raised during review and then update the |
@@ -1,7 +1,7 b'' | |||||
1 | Supported Workflows |
|
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 | * Centralized, using |svn|, |git|, or |hg| |repos| |
|
6 | * Centralized, using |svn|, |git|, or |hg| |repos| | |
7 | * Feature-Branch, using |git| or |hg| |repos| |
|
7 | * Feature-Branch, using |git| or |hg| |repos| |
@@ -20,10 +20,7 b" rst_epilog = '''" | |||||
20 | .. |psf| replace:: Python Software Foundation |
|
20 | .. |psf| replace:: Python Software Foundation | |
21 | .. |repo| replace:: repository |
|
21 | .. |repo| replace:: repository | |
22 | .. |repos| replace:: repositories |
|
22 | .. |repos| replace:: repositories | |
23 | .. |RCI| replace:: RhodeCode Control |
|
|||
24 | .. |RCC| replace:: RhodeCode Control |
|
23 | .. |RCC| replace:: RhodeCode Control | |
25 | .. |RCV| replace:: RhodeCode Enterprise |
|
|||
26 | .. |RCM| replace:: RhodeCode Enterprise |
|
|||
27 | .. |RCE| replace:: RhodeCode Enterprise |
|
24 | .. |RCE| replace:: RhodeCode Enterprise | |
28 | .. |RCCE| replace:: RhodeCode Community |
|
25 | .. |RCCE| replace:: RhodeCode Community | |
29 | .. |RCEE| replace:: RhodeCode Enterprise |
|
26 | .. |RCEE| replace:: RhodeCode Enterprise | |
@@ -31,6 +28,5 b" rst_epilog = '''" | |||||
31 | .. |RCT| replace:: RhodeCode Tools |
|
28 | .. |RCT| replace:: RhodeCode Tools | |
32 | .. |RCEBOLD| replace:: **RhodeCode Enterprise** |
|
29 | .. |RCEBOLD| replace:: **RhodeCode Enterprise** | |
33 | .. |RCEITALICS| replace:: `RhodeCode Enterprise` |
|
30 | .. |RCEITALICS| replace:: `RhodeCode Enterprise` | |
34 | .. |RC| replace:: RhodeCode |
|
|||
35 | .. |RNS| replace:: Release Notes |
|
31 | .. |RNS| replace:: Release Notes | |
36 | ''' |
|
32 | ''' |
@@ -18,7 +18,7 b' so to clarify what is meant each time, r' | |||||
18 | Hooks |
|
18 | Hooks | |
19 | ----- |
|
19 | ----- | |
20 |
|
20 | |||
21 |
Within |RC |
|
21 | Within |RCE| there are two types of supported hooks. | |
22 |
|
22 | |||
23 | * **Internal built-in hooks**: The internal |hg|, |git| or |svn| hooks are |
|
23 | * **Internal built-in hooks**: The internal |hg|, |git| or |svn| hooks are | |
24 | triggered by different VCS operations, like push, pull, |
|
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 | It enables you to develop projects securely behind the firewall while |
|
5 | It enables you to develop projects securely behind the firewall while | |
6 | providing collaboration tools that work with |git|, |hg|, |
|
6 | providing collaboration tools that work with |git|, |hg|, | |
7 | and |svn| |repos|. The user interface allows you to create, edit, |
|
7 | and |svn| |repos|. The user interface allows you to create, edit, | |
8 | and commit files and |repos| while managing their security permissions. |
|
8 | and commit files and |repos| while managing their security permissions. | |
9 |
|
9 | |||
10 |
|RC |
|
10 | |RCE| provides the following features: | |
11 |
|
11 | |||
12 | * Source code management. |
|
12 | * Source code management. | |
13 | * Extended permissions management. |
|
13 | * Extended permissions management. | |
@@ -18,7 +18,7 b' and commit files and |repos| while manag' | |||||
18 | * Web-based hook management. |
|
18 | * Web-based hook management. | |
19 | * Native |svn| support. |
|
19 | * Native |svn| support. | |
20 | * Migration from existing databases. |
|
20 | * Migration from existing databases. | |
21 |
* |RC |
|
21 | * |RCE| SDK. | |
22 | * Built-in analytics |
|
22 | * Built-in analytics | |
23 | * Built in integrations including: Slack, Webhooks (used for Jenkins/TeamCity and other CIs), Jira, Redmine, Hipchat |
|
23 | * Built in integrations including: Slack, Webhooks (used for Jenkins/TeamCity and other CIs), Jira, Redmine, Hipchat | |
24 | * Pluggable authentication system. |
|
24 | * Pluggable authentication system. |
@@ -5,8 +5,24 b' Supported Databases' | |||||
5 |
|
5 | |||
6 | .. important:: |
|
6 | .. important:: | |
7 |
|
7 | |||
8 |
We do not recommend using SQLite in a production environment |
|
8 | We do not recommend using SQLite in a production environment of more than 5 people. | |
9 | supported by |RCE| for evaluation purposes. |
|
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 | Database Overview |
|
27 | Database Overview | |
12 | ----------------- |
|
28 | ----------------- | |
@@ -48,21 +64,3 b' following example to configure the corre' | |||||
48 | # for the RCE instance you are installing |
|
64 | # for the RCE instance you are installing | |
49 | Database name: example-db-name-for-2xx # The 2xx version database |
|
65 | Database name: example-db-name-for-2xx # The 2xx version database | |
50 | Database name: example-db-name-for-3xx # The 3xx version database |
|
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 | The following tasks are the most common post installation requirements. Use |
|
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 | .. toctree:: |
|
9 | .. toctree:: | |
10 |
|
10 |
@@ -3,21 +3,21 b'' | |||||
3 | Migrating |repos| |
|
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 | the system, use the following instructions. |
|
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 | :menuselection:`Admin --> Settings --> System Info`. For example, |
|
10 | :menuselection:`Admin --> Settings --> System Info`. For example, | |
11 | Storage location: /home/{username}/repos. |
|
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 | 3. Remap and rescan the |repos|, see :ref:`remap-rescan` |
|
14 | 3. Remap and rescan the |repos|, see :ref:`remap-rescan` | |
15 |
|
15 | |||
16 | .. important:: |
|
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 | You should verify if custom ``.hg`` or ``.hgrc`` files inside |
|
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 | .. code-block:: bash |
|
28 | .. code-block:: bash | |
29 |
|
29 | |||
30 |
$ chmod |
|
30 | $ chmod +x RhodeCode-installer-linux-* | |
31 | $ ./RhodeCode-installer-linux-* |
|
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 | 3. Install a VCS Server, and configure it to start at boot. |
|
36 | 3. Install a VCS Server, and configure it to start at boot. | |
34 |
|
37 | |||
35 | .. code-block:: bash |
|
38 | .. code-block:: bash |
@@ -3,12 +3,12 b'' | |||||
3 | Set up Email |
|
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 | :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` |
|
7 | :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` | |
8 | file and uncomment and configure the email section. If it is not there, |
|
8 | file and uncomment and configure the email section. If it is not there, | |
9 | use the below example to insert it. |
|
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 | :menuselection:`Admin --> Settings --> Email` page. |
|
12 | :menuselection:`Admin --> Settings --> Email` page. | |
13 |
|
13 | |||
14 | .. code-block:: ini |
|
14 | .. code-block:: ini |
@@ -4,15 +4,15 b' MySQL or MariaDB' | |||||
4 | ---------------- |
|
4 | ---------------- | |
5 |
|
5 | |||
6 | To use a MySQL or MariaDB database you should install and configure the |
|
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 | you will setup a connection to your MySQL or MariaDB database. To work with |
|
8 | you will setup a connection to your MySQL or MariaDB database. To work with | |
9 | either, use the following steps: |
|
9 | either, use the following steps: | |
10 |
|
10 | |||
11 | 1. Depending on your |os|, install a MySQL or MariaDB database following the |
|
11 | 1. Depending on your |os|, install a MySQL or MariaDB database following the | |
12 | appropriate instructions from the `MySQL website`_ or `MariaDB website`_. |
|
12 | appropriate instructions from the `MySQL website`_ or `MariaDB website`_. | |
13 | 2. Configure the database with a username and password which you will use |
|
13 | 2. Configure the database with a username and password which you will use | |
14 |
with |RC |
|
14 | with |RCE|. | |
15 |
3. Install |RC |
|
15 | 3. Install |RCE|, and during installation select MySQL as your database. | |
16 | 4. Enter the following information during the database setup: |
|
16 | 4. Enter the following information during the database setup: | |
17 |
|
17 | |||
18 | * Your network IP Address |
|
18 | * Your network IP Address |
@@ -4,15 +4,15 b' PostgreSQL' | |||||
4 | ---------- |
|
4 | ---------- | |
5 |
|
5 | |||
6 | To use a PostgreSQL database, you should install and configure the database |
|
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 | setup the connection to your PostgreSQL database. To work with PostgreSQL, |
|
8 | setup the connection to your PostgreSQL database. To work with PostgreSQL, | |
9 | use the following steps: |
|
9 | use the following steps: | |
10 |
|
10 | |||
11 | 1. Depending on your |os|, install a PostgreSQL database following the |
|
11 | 1. Depending on your |os|, install a PostgreSQL database following the | |
12 | appropriate instructions from the `PostgreSQL website`_. |
|
12 | appropriate instructions from the `PostgreSQL website`_. | |
13 | 2. Configure the database with a username and password, which you will use |
|
13 | 2. Configure the database with a username and password, which you will use | |
14 |
with |RC |
|
14 | with |RCE|. | |
15 |
3. Install |RC |
|
15 | 3. Install |RCE|, and during installation select PostgreSQL as your database. | |
16 | 4. Enter the following information during the database setup: |
|
16 | 4. Enter the following information during the database setup: | |
17 |
|
17 | |||
18 | * Your network IP Address |
|
18 | * Your network IP Address |
@@ -9,15 +9,15 b' SQLite' | |||||
9 | as it has an internal locking mechanism which can become a performance |
|
9 | as it has an internal locking mechanism which can become a performance | |
10 | bottleneck when there are more than 5 concurrent users. |
|
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 | during installation. SQLite is suitable for small teams, |
|
13 | during installation. SQLite is suitable for small teams, | |
14 | projects with a low load, and evaluation purposes since it is built into |
|
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 | Using MySQL or PostgreSQL in an large setup gives you much greater |
|
17 | Using MySQL or PostgreSQL in an large setup gives you much greater | |
18 | performance, and while migration tools exist to move from one database type |
|
18 | performance, and while migration tools exist to move from one database type | |
19 | to another, it is better to get it right first time and to immediately use |
|
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 | Migrating From SQLite to PostgreSQL |
|
22 | Migrating From SQLite to PostgreSQL | |
23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
@@ -11,20 +11,20 b' different Slack channels, for example.' | |||||
11 | Supported integrations |
|
11 | Supported integrations | |
12 | ^^^^^^^^^^^^^^^^^^^^^^ |
|
12 | ^^^^^^^^^^^^^^^^^^^^^^ | |
13 |
|
13 | |||
14 | ================================ ============ ======================================== |
|
14 | ================================ ================== ======================================== | |
15 |
Type/Name |
|
15 | Type/Name RhodeCode Edition Description | |
16 | ================================ ============ ======================================== |
|
16 | ================================ ================== ======================================== | |
17 | :ref:`integrations-webhook` |RCCEshort| Trigger events as `json` to a custom url |
|
17 | :ref:`integrations-webhook` |RCCEshort| Trigger events as `json` to a custom url | |
18 | :ref:`integrations-slack` |RCCEshort| Integrate with https://slack.com/ |
|
18 | :ref:`integrations-slack` |RCCEshort| Integrate with https://slack.com/ | |
19 | :ref:`integrations-hipchat` |RCCEshort| Integrate with https://www.hipchat.com/ |
|
19 | :ref:`integrations-hipchat` |RCCEshort| Integrate with https://www.hipchat.com/ | |
20 | :ref:`integrations-email` |RCCEshort| Send repo push commits by email |
|
20 | :ref:`integrations-email` |RCCEshort| Send repo push commits by email | |
21 | :ref:`integrations-ci` |RCCEshort| Trigger Builds for Common CI Systems |
|
21 | :ref:`integrations-ci` |RCCEshort| Trigger Builds for Common CI Systems | |
22 | :ref:`integrations-rcextensions` |RCCEshort| Advanced low-level integration framework |
|
22 | :ref:`integrations-rcextensions` |RCCEshort| Advanced low-level integration framework | |
23 |
|
23 | |||
24 | :ref:`integrations-jenkins` |RCEEshort| Trigger Builds for Jenkins CI System |
|
24 | :ref:`integrations-jenkins` |RCEEshort| Trigger Builds for Jenkins CI System | |
25 | :ref:`integrations-redmine` |RCEEshort| Close/Resolve/Reference Redmine issues |
|
25 | :ref:`integrations-redmine` |RCEEshort| Close/Resolve/Reference Redmine issues | |
26 | :ref:`integrations-jira` |RCEEshort| Close/Resolve/Reference JIRA issues |
|
26 | :ref:`integrations-jira` |RCEEshort| Close/Resolve/Reference JIRA issues | |
27 | ================================ ============ ======================================== |
|
27 | ================================ ================== ======================================== | |
28 |
|
28 | |||
29 | .. _creating-integrations: |
|
29 | .. _creating-integrations: | |
30 |
|
30 |
@@ -9,7 +9,7 b' You can set an issue tracker connection ' | |||||
9 | * At the |repo| level, you can configure an integration with a different issue |
|
9 | * At the |repo| level, you can configure an integration with a different issue | |
10 | tracker. |
|
10 | tracker. | |
11 |
|
11 | |||
12 |
To integrate |RC |
|
12 | To integrate |RCE| with an issue tracker, you need to define a regular | |
13 | expression that will fetch the issue ID stored in commit messages, and replace |
|
13 | expression that will fetch the issue ID stored in commit messages, and replace | |
14 | it with a URL. This enables |RCE| to generate a link matching each issue to the |
|
14 | it with a URL. This enables |RCE| to generate a link matching each issue to the | |
15 | target |repo|. |
|
15 | target |repo|. |
@@ -7,7 +7,7 b' Error Message' | |||||
7 | Error creating repository repo-name |
|
7 | Error creating repository repo-name | |
8 |
|
8 | |||
9 | Cause |
|
9 | Cause | |
10 |
As of |RC |
|
10 | As of |RCE| 3.0, a VCS Server is required to run backend operations. | |
11 |
|
11 | |||
12 | Solution |
|
12 | Solution | |
13 | Install a VCS Server. See the `Install a VCS Server`_ section of |RCC| |
|
13 | Install a VCS Server. See the `Install a VCS Server`_ section of |RCC| |
@@ -3,7 +3,7 b'' | |||||
3 | Nix Packaging |
|
3 | Nix Packaging | |
4 | ============= |
|
4 | ============= | |
5 |
|
5 | |||
6 |
|RC |
|
6 | |RCE| is installed using |Nix Package Manager|. The Nix environment provides | |
7 | the following features for maintenance and deployment: |
|
7 | the following features for maintenance and deployment: | |
8 |
|
8 | |||
9 | * Atomic upgrades and rollbacks |
|
9 | * Atomic upgrades and rollbacks |
@@ -5,11 +5,11 b'' | |||||
5 |
|
5 | |||
6 | self: super: { |
|
6 | self: super: { | |
7 | "alabaster" = super.buildPythonPackage { |
|
7 | "alabaster" = super.buildPythonPackage { | |
8 |
name = "alabaster-0.7.1 |
|
8 | name = "alabaster-0.7.12"; | |
9 | doCheck = false; |
|
9 | doCheck = false; | |
10 | src = fetchurl { |
|
10 | src = fetchurl { | |
11 |
url = "https://files.pythonhosted.org/packages/ |
|
11 | url = "https://files.pythonhosted.org/packages/cc/b4/ed8dcb0d67d5cfb7f83c4d5463a7614cb1d078ad7ae890c9143edebbf072/alabaster-0.7.12.tar.gz"; | |
12 | sha256 = "1mvm69xsn5xf1jc45kdq1mn0yq0pfn54mv2jcww4s1vwqx6iyfxn"; |
|
12 | sha256 = "00nwwjj2d2ym4s2kk217x7jkx1hnczc3fvm8yxbqmsp6b0nxfqd6"; | |
13 | }; |
|
13 | }; | |
14 | }; |
|
14 | }; | |
15 | "babel" = super.buildPythonPackage { |
|
15 | "babel" = super.buildPythonPackage { | |
@@ -24,11 +24,11 b' self: super: {' | |||||
24 | }; |
|
24 | }; | |
25 | }; |
|
25 | }; | |
26 | "certifi" = super.buildPythonPackage { |
|
26 | "certifi" = super.buildPythonPackage { | |
27 |
name = "certifi-2018. |
|
27 | name = "certifi-2018.11.29"; | |
28 | doCheck = false; |
|
28 | doCheck = false; | |
29 | src = fetchurl { |
|
29 | src = fetchurl { | |
30 | url = "https://files.pythonhosted.org/packages/e1/0f/f8d5e939184547b3bdc6128551b831a62832713aa98c2ccdf8c47ecc7f17/certifi-2018.8.24.tar.gz"; |
|
30 | url = "https://files.pythonhosted.org/packages/55/54/3ce77783acba5979ce16674fc98b1920d00b01d337cfaaf5db22543505ed/certifi-2018.11.29.tar.gz"; | |
31 | sha256 = "0f0nhrj9mlrf79iway4578wrsgmjh0fmacl9zv8zjckdy7b90rip"; |
|
31 | sha256 = "1dvccavd2fzq4j37w0sznylp92ps14zi6gvlxzm23in0yhzciya7"; | |
32 | }; |
|
32 | }; | |
33 | }; |
|
33 | }; | |
34 | "chardet" = super.buildPythonPackage { |
|
34 | "chardet" = super.buildPythonPackage { | |
@@ -83,31 +83,31 b' self: super: {' | |||||
83 | }; |
|
83 | }; | |
84 | }; |
|
84 | }; | |
85 | "packaging" = super.buildPythonPackage { |
|
85 | "packaging" = super.buildPythonPackage { | |
86 |
name = "packaging-1 |
|
86 | name = "packaging-18.0"; | |
87 | doCheck = false; |
|
87 | doCheck = false; | |
88 | propagatedBuildInputs = [ |
|
88 | propagatedBuildInputs = [ | |
89 | self."pyparsing" |
|
89 | self."pyparsing" | |
90 | self."six" |
|
90 | self."six" | |
91 | ]; |
|
91 | ]; | |
92 | src = fetchurl { |
|
92 | src = fetchurl { | |
93 |
url = "https://files.pythonhosted.org/packages/77 |
|
93 | url = "https://files.pythonhosted.org/packages/cf/50/1f10d2626df0aa97ce6b62cf6ebe14f605f4e101234f7748b8da4138a8ed/packaging-18.0.tar.gz"; | |
94 | sha256 = "0nrpayk8kij1zm9sjnk38ldz3a6705ggvw8ljylqbrb4vmqbf6gh"; |
|
94 | sha256 = "01wq9c53ix5rz6qg2c98gy8n4ff768rmanifm8m5jpjiaizj51h8"; | |
95 | }; |
|
95 | }; | |
96 | }; |
|
96 | }; | |
97 | "pygments" = super.buildPythonPackage { |
|
97 | "pygments" = super.buildPythonPackage { | |
98 |
name = "pygments-2. |
|
98 | name = "pygments-2.3.0"; | |
99 | doCheck = false; |
|
99 | doCheck = false; | |
100 | src = fetchurl { |
|
100 | src = fetchurl { | |
101 |
url = "https://files.pythonhosted.org/packages/ |
|
101 | url = "https://files.pythonhosted.org/packages/63/a2/91c31c4831853dedca2a08a0f94d788fc26a48f7281c99a303769ad2721b/Pygments-2.3.0.tar.gz"; | |
102 | sha256 = "1k78qdvir1yb1c634nkv6rbga8wv4289xarghmsbbvzhvr311bnv"; |
|
102 | sha256 = "1z34ms51dh4jq4h3cizp7vd1dmsxcbvffkjsd2xxfav22nn6lrl2"; | |
103 | }; |
|
103 | }; | |
104 | }; |
|
104 | }; | |
105 | "pyparsing" = super.buildPythonPackage { |
|
105 | "pyparsing" = super.buildPythonPackage { | |
106 |
name = "pyparsing-2. |
|
106 | name = "pyparsing-2.3.0"; | |
107 | doCheck = false; |
|
107 | doCheck = false; | |
108 | src = fetchurl { |
|
108 | src = fetchurl { | |
109 |
url = "https://files.pythonhosted.org/packages/3 |
|
109 | url = "https://files.pythonhosted.org/packages/d0/09/3e6a5eeb6e04467b737d55f8bba15247ac0876f98fae659e58cd744430c6/pyparsing-2.3.0.tar.gz"; | |
110 | sha256 = "016b9gh606aa44sq92jslm89bg874ia0yyiyb643fa6dgbsbqch8"; |
|
110 | sha256 = "14k5v7n3xqw8kzf42x06bzp184spnlkya2dpjyflax6l3yrallzk"; | |
111 | }; |
|
111 | }; | |
112 | }; |
|
112 | }; | |
113 | "pytz" = super.buildPythonPackage { |
|
113 | "pytz" = super.buildPythonPackage { | |
@@ -119,7 +119,7 b' self: super: {' | |||||
119 | }; |
|
119 | }; | |
120 | }; |
|
120 | }; | |
121 | "requests" = super.buildPythonPackage { |
|
121 | "requests" = super.buildPythonPackage { | |
122 |
name = "requests-2. |
|
122 | name = "requests-2.20.1"; | |
123 | doCheck = false; |
|
123 | doCheck = false; | |
124 | propagatedBuildInputs = [ |
|
124 | propagatedBuildInputs = [ | |
125 | self."chardet" |
|
125 | self."chardet" | |
@@ -128,16 +128,16 b' self: super: {' | |||||
128 | self."certifi" |
|
128 | self."certifi" | |
129 | ]; |
|
129 | ]; | |
130 | src = fetchurl { |
|
130 | src = fetchurl { | |
131 |
url = "https://files.pythonhosted.org/packages/54 |
|
131 | url = "https://files.pythonhosted.org/packages/40/35/298c36d839547b50822985a2cf0611b3b978a5ab7a5af5562b8ebe3e1369/requests-2.20.1.tar.gz"; | |
132 | sha256 = "0snf8xxdzsgh1x2zv3vilvbrv9jbpmnfagzzb1rjmmvflckdh8pc"; |
|
132 | sha256 = "0qzj6cgv3k9wyj7wlxgz7xq0cfg4jbbkfm24pp8dnhczwl31527a"; | |
133 | }; |
|
133 | }; | |
134 | }; |
|
134 | }; | |
135 | "setuptools" = super.buildPythonPackage { |
|
135 | "setuptools" = super.buildPythonPackage { | |
136 |
name = "setuptools-40.2 |
|
136 | name = "setuptools-40.6.2"; | |
137 | doCheck = false; |
|
137 | doCheck = false; | |
138 | src = fetchurl { |
|
138 | src = fetchurl { | |
139 |
url = "https://files.pythonhosted.org/packages/ |
|
139 | url = "https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip"; | |
140 | sha256 = "19ng5m7kigllg3x96c91y3a2k28g6kwnbb1v4warrnp4xma1v227"; |
|
140 | sha256 = "0r2c5hapirlzm34h7pl1lgkm6gk7bcrlrdj28qgsvaqg3f74vfw6"; | |
141 | }; |
|
141 | }; | |
142 | }; |
|
142 | }; | |
143 | "six" = super.buildPythonPackage { |
|
143 | "six" = super.buildPythonPackage { | |
@@ -157,7 +157,7 b' self: super: {' | |||||
157 | }; |
|
157 | }; | |
158 | }; |
|
158 | }; | |
159 | "sphinx" = super.buildPythonPackage { |
|
159 | "sphinx" = super.buildPythonPackage { | |
160 |
name = "sphinx-1. |
|
160 | name = "sphinx-1.8.2"; | |
161 | doCheck = false; |
|
161 | doCheck = false; | |
162 | propagatedBuildInputs = [ |
|
162 | propagatedBuildInputs = [ | |
163 | self."six" |
|
163 | self."six" | |
@@ -175,8 +175,8 b' self: super: {' | |||||
175 | self."typing" |
|
175 | self."typing" | |
176 | ]; |
|
176 | ]; | |
177 | src = fetchurl { |
|
177 | src = fetchurl { | |
178 |
url = "https://files.pythonhosted.org/packages/ |
|
178 | url = "https://files.pythonhosted.org/packages/4c/ea/7388faba7cf02999e1bc42f6a8eb1ea0120aec3dd93474cee21cea2d693f/Sphinx-1.8.2.tar.gz"; | |
179 | sha256 = "1ryz0w4c31930f1br2sjwrxwx9cmsy7cqdb0d81g98n9bj250w50"; |
|
179 | sha256 = "1sia2h5rfzy76rbsd69ghr8bbidhsjzzinf3f523dcmivp5k41qj"; | |
180 | }; |
|
180 | }; | |
181 | }; |
|
181 | }; | |
182 | "sphinx-rtd-theme" = super.buildPythonPackage { |
|
182 | "sphinx-rtd-theme" = super.buildPythonPackage { | |
@@ -207,11 +207,11 b' self: super: {' | |||||
207 | }; |
|
207 | }; | |
208 | }; |
|
208 | }; | |
209 | "urllib3" = super.buildPythonPackage { |
|
209 | "urllib3" = super.buildPythonPackage { | |
210 |
name = "urllib3-1.2 |
|
210 | name = "urllib3-1.24.1"; | |
211 | doCheck = false; |
|
211 | doCheck = false; | |
212 | src = fetchurl { |
|
212 | src = fetchurl { | |
213 |
url = "https://files.pythonhosted.org/packages/ |
|
213 | url = "https://files.pythonhosted.org/packages/b1/53/37d82ab391393565f2f831b8eedbffd57db5a718216f82f1a8b4d381a1c1/urllib3-1.24.1.tar.gz"; | |
214 | sha256 = "1bvbd35q3zdcd7gsv38fwpizy7p06dr0154g5gfybrvnbvhwb2m6"; |
|
214 | sha256 = "08lwd9f3hqznyf32vnzwvp87pchx062nkbgyrf67rwlkgj0jk5fy"; | |
215 | }; |
|
215 | }; | |
216 | }; |
|
216 | }; | |
217 |
|
217 |
@@ -1,7 +1,7 b'' | |||||
1 | |RCE| 3.0.0 |RNS| |
|
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 | * :ref:`general-rn-ref` |
|
6 | * :ref:`general-rn-ref` | |
7 | * :ref:`security-rn-ref` |
|
7 | * :ref:`security-rn-ref` |
@@ -9,6 +9,7 b' Release Notes' | |||||
9 | .. toctree:: |
|
9 | .. toctree:: | |
10 | :maxdepth: 1 |
|
10 | :maxdepth: 1 | |
11 |
|
11 | |||
|
12 | release-notes-4.15.0.rst | |||
12 | release-notes-4.14.1.rst |
|
13 | release-notes-4.14.1.rst | |
13 | release-notes-4.14.0.rst |
|
14 | release-notes-4.14.0.rst | |
14 | release-notes-4.13.3.rst |
|
15 | release-notes-4.13.3.rst |
@@ -1,8 +1,8 b'' | |||||
1 |
sphinx==1. |
|
1 | sphinx==1.8.2 | |
2 | six==1.11.0 |
|
2 | six==1.11.0 | |
3 | sphinx_rtd_theme==0.4.1 |
|
3 | sphinx_rtd_theme==0.4.1 | |
4 | docutils==0.14.0 |
|
4 | docutils==0.14.0 | |
5 |
pygments==2. |
|
5 | pygments==2.3.0 | |
6 | markupsafe==1.0.0 |
|
6 | markupsafe==1.0.0 | |
7 | jinja2==2.9.6 |
|
7 | jinja2==2.9.6 | |
8 | pytz==2018.4 |
|
8 | pytz==2018.4 |
@@ -44,10 +44,10 b' following example:' | |||||
44 | Installing |RCT| |
|
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 | the API. Installing them on a local machine lets you carry out maintenance on |
|
48 | the API. Installing them on a local machine lets you carry out maintenance on | |
49 | the server remotely. Once installed you can use them to index your |repos| |
|
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 | additional functionality. |
|
51 | additional functionality. | |
52 |
|
52 | |||
53 | For more detailed instructions about using |RCT| for indexing and full-text |
|
53 | For more detailed instructions about using |RCT| for indexing and full-text |
@@ -3,7 +3,7 b'' | |||||
3 | |RCT| |
|
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 | the API. |
|
7 | the API. | |
8 |
|
8 | |||
9 | .. toctree:: |
|
9 | .. toctree:: |
@@ -16,7 +16,7 b' rhodecode-tools' | |||||
16 | --------------- |
|
16 | --------------- | |
17 |
|
17 | |||
18 | Use |RCT| to setup automation, run the indexer, and install extensions for |
|
18 | Use |RCT| to setup automation, run the indexer, and install extensions for | |
19 |
your |RC |
|
19 | your |RCE| instances. Options: | |
20 |
|
20 | |||
21 | .. rst-class:: dl-horizontal |
|
21 | .. rst-class:: dl-horizontal | |
22 |
|
22 | |||
@@ -49,7 +49,7 b' Example usage:' | |||||
49 | rhodecode-api |
|
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 | remote machine, for more information about the API, see the :ref:`api`. To |
|
53 | remote machine, for more information about the API, see the :ref:`api`. To | |
54 | pass arguments on the command-line use the ``method:option`` syntax. |
|
54 | pass arguments on the command-line use the ``method:option`` syntax. | |
55 |
|
55 | |||
@@ -117,7 +117,7 b' Options:' | |||||
117 | rhodecode-cleanup-gists |
|
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 | .. rst-class:: dl-horizontal |
|
122 | .. rst-class:: dl-horizontal | |
123 |
|
123 | |||
@@ -166,7 +166,7 b' Example usage:' | |||||
166 | rhodecode-cleanup-repos |
|
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 | .. rst-class:: dl-horizontal |
|
171 | .. rst-class:: dl-horizontal | |
172 |
|
172 | |||
@@ -280,7 +280,7 b' the using :ref:`integrations-rcextension' | |||||
280 | rhodecode-gist |
|
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 | .. rst-class:: dl-horizontal |
|
285 | .. rst-class:: dl-horizontal | |
286 |
|
286 |
@@ -7,7 +7,7 b' To install |RCT| correctly, see the inst' | |||||
7 | :ref:`install-tools`, and :ref:`config-rhoderc`. |
|
7 | :ref:`install-tools`, and :ref:`config-rhoderc`. | |
8 |
|
8 | |||
9 | Once |RCT| is installed, and the :file:`/home/{user}/.rhoderc` file is |
|
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 | tasks. Use the following example to configure that file, |
|
11 | tasks. Use the following example to configure that file, | |
12 | and once configured see the :ref:`tools-cli` for more details. |
|
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 | # Check that the script is uploaded to your home directory |
|
96 | # Check that the script is uploaded to your home directory | |
97 | $ ls -1 |
|
97 | $ ls -1 | |
98 | RhodeCode-installer-linux-391_b1a804c4d69b_d6c087d520e3 |
|
98 | RhodeCode-installer-linux-buildYYYYXXXX_ZZZZ | |
99 |
|
99 | |||
100 | # Change the script permissions |
|
100 | # Change the script permissions | |
101 |
$ chmod |
|
101 | $ chmod +x RhodeCode-installer-linux* | |
102 |
|
102 | |||
103 | # Run the installer and accept the prompts |
|
103 | # Run the installer and accept the prompts | |
104 | $ ./RhodeCode-installer-linux-* |
|
104 | $ ./RhodeCode-installer-linux-* |
@@ -7,13 +7,13 b'' | |||||
7 | Git Large File Storage (or LFS) is a new, open-source extension to Git that |
|
7 | Git Large File Storage (or LFS) is a new, open-source extension to Git that | |
8 | aims to improve handling of large files. It does this by replacing large files |
|
8 | aims to improve handling of large files. It does this by replacing large files | |
9 | in your repository—such as graphics and videos—with simple text pointers. |
|
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 | large files without the need for an external object store. |
|
11 | large files without the need for an external object store. | |
12 | Git LFS is disabled by default, globally, and for each individual repository. |
|
12 | Git LFS is disabled by default, globally, and for each individual repository. | |
13 |
|
13 | |||
14 | .. note:: |
|
14 | .. note:: | |
15 |
|
15 | |||
16 |
|
|
16 | RhodeCode implements V2 API of Git LFS. Please make sure your git client is | |
17 | using the latest version (2.0.X recommended) to leverage full feature set |
|
17 | using the latest version (2.0.X recommended) to leverage full feature set | |
18 | of the V2 API. |
|
18 | of the V2 API. | |
19 |
|
19 | |||
@@ -22,7 +22,7 b' Git LFS is disabled by default, globally' | |||||
22 | Enabling Git LFS |
|
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 | To enable Git LFS Globally: |
|
27 | To enable Git LFS Globally: | |
28 |
|
28 | |||
@@ -87,7 +87,7 b' size in bytes. For example::' | |||||
87 |
|
87 | |||
88 |
|
88 | |||
89 | The object itself will be uploaded to a separate location via the Git LFS Batch API. |
|
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 | If give repository has Git LFS disabled, a proper message will be sent back to |
|
92 | If give repository has Git LFS disabled, a proper message will be sent back to | |
93 | the client and upload of LFS objects will be forbidden. |
|
93 | the client and upload of LFS objects will be forbidden. |
@@ -13,7 +13,7 b' of the current revision. This saves both' | |||||
13 | Enabling HG Largefiles |
|
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 | To enable Mercurial Largefiles Globally: |
|
18 | To enable Mercurial Largefiles Globally: | |
19 |
|
19 |
@@ -25,7 +25,7 b' Pre-requisites' | |||||
25 | * For MySQL, do not use `localhost` in the database connection string of the |
|
25 | * For MySQL, do not use `localhost` in the database connection string of the | |
26 | :file:`rhodecode.ini` file. |
|
26 | :file:`rhodecode.ini` file. | |
27 | * InnoDB must be the database tables engine. |
|
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 | will be applied so you are not locked out of the upgraded instance. |
|
29 | will be applied so you are not locked out of the upgraded instance. | |
30 |
|
30 | |||
31 | You can find the specific instructions to carry out these pre-requisite steps |
|
31 | You can find the specific instructions to carry out these pre-requisite steps |
@@ -3,19 +3,19 b'' | |||||
3 | Getting Started with VCS |
|
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 | command line or using a GUI client such as Tortoise, Tower or SourceTree. |
|
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 | can interact with there protocols are supported, including Eclipse or PyCharm |
|
10 | can interact with there protocols are supported, including Eclipse or PyCharm | |
11 | plugins. |
|
11 | plugins. | |
12 |
|
12 | |||
13 |
|
13 | |||
14 | If you have never used either before, the following information should |
|
14 | If you have never used either before, the following information should | |
15 | help you set up your local machine so that you can sync changes with the |
|
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 | and you can access your |repos| from the web interface. |
|
19 | and you can access your |repos| from the web interface. | |
20 |
|
20 | |||
21 | .. note:: |
|
21 | .. note:: |
@@ -3,14 +3,14 b' File Editing' | |||||
3 |
|
3 | |||
4 | To edit files using the online editor, use the following steps. |
|
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 | 2. Select the |repo| in which you want to edit a file. |
|
7 | 2. Select the |repo| in which you want to edit a file. | |
8 | 3. Select the :guilabel:`file` view of the |repo|, and double-click on the file. |
|
8 | 3. Select the :guilabel:`file` view of the |repo|, and double-click on the file. | |
9 | 4. To open the editor, select the :guilabel:`edit on branch:default` button. |
|
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 | the syntax highlighting will appear automatically. |
|
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 | you can set the language syntax highlighter by |
|
14 | you can set the language syntax highlighter by | |
15 | choosing from the file type drop down menu. |
|
15 | choosing from the file type drop down menu. | |
16 | 5. To save your changes, select :guilabel:`Commit changes` |
|
16 | 5. To save your changes, select :guilabel:`Commit changes` |
@@ -4,7 +4,7 b' Gist Editing' | |||||
4 | ^^^^^^^^^^^^ |
|
4 | ^^^^^^^^^^^^ | |
5 |
|
5 | |||
6 | Gists are standalone files that only the creator can edit. To work with |
|
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 | editor also has syntax highlighting. |
|
8 | editor also has syntax highlighting. | |
9 |
|
9 | |||
10 | You can set the following properties for each gist: |
|
10 | You can set the following properties for each gist: | |
@@ -13,7 +13,7 b' You can set the following properties for' | |||||
13 | and will show up in searches. |
|
13 | and will show up in searches. | |
14 | * :guilabel:`Gist Lifetime`: You can set a gist to expire after a set |
|
14 | * :guilabel:`Gist Lifetime`: You can set a gist to expire after a set | |
15 | period by using the :guilabel:`Gist Lifetime` dropdown menu. |
|
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 | gist database. |
|
17 | gist database. | |
18 | * :guilabel:`Private`: This means that the gist will not show up in searches. |
|
18 | * :guilabel:`Private`: This means that the gist will not show up in searches. | |
19 | * :guilabel:`Gist access level`: If you create a private gist you can have |
|
19 | * :guilabel:`Gist access level`: If you create a private gist you can have |
@@ -1,7 +1,7 b'' | |||||
1 | Online Editing |
|
1 | Online Editing | |
2 | -------------- |
|
2 | -------------- | |
3 |
|
3 | |||
4 |
|RC |
|
4 | |RCE| has an integrated online editor, allowing you to edit files in the | |
5 | browser. The online editor has syntax highlighting and the ability to fork, |
|
5 | browser. The online editor has syntax highlighting and the ability to fork, | |
6 | merge, and commit changes to files. |
|
6 | merge, and commit changes to files. | |
7 |
|
7 |
@@ -13,13 +13,13 b' let' | |||||
13 | sha512 = "tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA=="; |
|
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 | name = "_at_polymer_slash_iron-a11y-announcer"; |
|
17 | name = "_at_polymer_slash_iron-a11y-announcer"; | |
18 | packageName = "@polymer/iron-a11y-announcer"; |
|
18 | packageName = "@polymer/iron-a11y-announcer"; | |
19 |
version = "3.0. |
|
19 | version = "3.0.2"; | |
20 | src = fetchurl { |
|
20 | src = fetchurl { | |
21 |
url = "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.0. |
|
21 | url = "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.0.2.tgz"; | |
22 | sha512 = "Xiqmpz0AEEbMNGYPpbrXBIrcI/xaR4tn77pmSLfxVKGGwjEUR/YrRgyIwXp4EN7lvst1dFC8kyl2hLga0uDIVQ=="; |
|
22 | sha512 = "LqnMF39mXyxSSRbTHRzGbcJS8nU0NVTo2raBOgOlpxw5yfGJUVcwaTJ/qy5NtWCZLRfa4suycf0oAkuUjHTXHQ=="; | |
23 | }; |
|
23 | }; | |
24 | }; |
|
24 | }; | |
25 | "@polymer/iron-a11y-keys-3.0.1" = { |
|
25 | "@polymer/iron-a11y-keys-3.0.1" = { | |
@@ -229,13 +229,13 b' let' | |||||
229 | sha1 = "e7365648c1b42136a59c7d5040637b3b5c83b614"; |
|
229 | sha1 = "e7365648c1b42136a59c7d5040637b3b5c83b614"; | |
230 | }; |
|
230 | }; | |
231 | }; |
|
231 | }; | |
232 |
"@types/node-6.14. |
|
232 | "@types/node-6.14.2" = { | |
233 | name = "_at_types_slash_node"; |
|
233 | name = "_at_types_slash_node"; | |
234 | packageName = "@types/node"; |
|
234 | packageName = "@types/node"; | |
235 |
version = "6.14. |
|
235 | version = "6.14.2"; | |
236 | src = fetchurl { |
|
236 | src = fetchurl { | |
237 |
url = "https://registry.npmjs.org/@types/node/-/node-6.14. |
|
237 | url = "https://registry.npmjs.org/@types/node/-/node-6.14.2.tgz"; | |
238 | sha512 = "6tQyh4Q4B5pECcXBOQDZ5KjyBIxRZGzrweGPM47sAYTdVG4+7R+2EGMTmp0h6ZwgqHrFRCeg2gdhsG9xXEl2Sg=="; |
|
238 | sha512 = "JWB3xaVfsfnFY8Ofc9rTB/op0fqqTSqy4vBcVk1LuRJvta7KTX+D//fCkiTMeLGhdr2EbFZzQjC97gvmPilk9Q=="; | |
239 | }; |
|
239 | }; | |
240 | }; |
|
240 | }; | |
241 | "@types/parse5-2.2.34" = { |
|
241 | "@types/parse5-2.2.34" = { | |
@@ -409,22 +409,22 b' let' | |||||
409 | sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA=="; |
|
409 | sha512 = "mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA=="; | |
410 | }; |
|
410 | }; | |
411 | }; |
|
411 | }; | |
412 |
"@webcomponents/shadycss-1. |
|
412 | "@webcomponents/shadycss-1.6.0" = { | |
413 | name = "_at_webcomponents_slash_shadycss"; |
|
413 | name = "_at_webcomponents_slash_shadycss"; | |
414 | packageName = "@webcomponents/shadycss"; |
|
414 | packageName = "@webcomponents/shadycss"; | |
415 |
version = "1. |
|
415 | version = "1.6.0"; | |
416 | src = fetchurl { |
|
416 | src = fetchurl { | |
417 |
url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1. |
|
417 | url = "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.6.0.tgz"; | |
418 | sha512 = "0OyrmVc7S+INtzoqP2ofAo+OdVn2Nj0Qvq4wD9FEGN7nMmLRxaD2mzy6hD6EslzxUSuGH302CDU4KXiY66SEqg=="; |
|
418 | sha512 = "iURGZZU6BaiRJtGgjMn208QxPkY11QwT/VmuHNa4Yb+kJxU/WODe4C8b0LDOtnk4KJzJg50hCfwvPRAjePEzbA=="; | |
419 | }; |
|
419 | }; | |
420 | }; |
|
420 | }; | |
421 |
"@webcomponents/webcomponentsjs-2.1 |
|
421 | "@webcomponents/webcomponentsjs-2.2.1" = { | |
422 | name = "_at_webcomponents_slash_webcomponentsjs"; |
|
422 | name = "_at_webcomponents_slash_webcomponentsjs"; | |
423 | packageName = "@webcomponents/webcomponentsjs"; |
|
423 | packageName = "@webcomponents/webcomponentsjs"; | |
424 |
version = "2.1 |
|
424 | version = "2.2.1"; | |
425 | src = fetchurl { |
|
425 | src = fetchurl { | |
426 |
url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.1 |
|
426 | url = "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.1.tgz"; | |
427 | sha512 = "0UHJNY88lR3pnEYtBVT7F8cuuxOiITQGWJa0LxoELqkBSB7IabzJFOj5K99PajD3CGAsWpjB0CAeijfe376Y1w=="; |
|
427 | sha512 = "lZZ+Lkke6JhsJcQQqSVk1Pny6/8y4qhJ98LO7a/MwBSRO8WqHqK1X2vscfeL8vOnYGFnmBUyVG95lwYv/AXyLQ=="; | |
428 | }; |
|
428 | }; | |
429 | }; |
|
429 | }; | |
430 | "@xtuc/ieee754-1.2.0" = { |
|
430 | "@xtuc/ieee754-1.2.0" = { | |
@@ -499,13 +499,13 b' let' | |||||
499 | sha1 = "82ffb02b29e662ae53bdc20af15947706739c536"; |
|
499 | sha1 = "82ffb02b29e662ae53bdc20af15947706739c536"; | |
500 | }; |
|
500 | }; | |
501 | }; |
|
501 | }; | |
502 |
"ajv-6. |
|
502 | "ajv-6.6.1" = { | |
503 | name = "ajv"; |
|
503 | name = "ajv"; | |
504 | packageName = "ajv"; |
|
504 | packageName = "ajv"; | |
505 |
version = "6. |
|
505 | version = "6.6.1"; | |
506 | src = fetchurl { |
|
506 | src = fetchurl { | |
507 |
url = "https://registry.npmjs.org/ajv/-/ajv-6. |
|
507 | url = "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz"; | |
508 | sha512 = "4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg=="; |
|
508 | sha512 = "ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww=="; | |
509 | }; |
|
509 | }; | |
510 | }; |
|
510 | }; | |
511 | "ajv-keywords-3.2.0" = { |
|
511 | "ajv-keywords-3.2.0" = { | |
@@ -1454,13 +1454,13 b' let' | |||||
1454 | sha512 = "DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg=="; |
|
1454 | sha512 = "DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg=="; | |
1455 | }; |
|
1455 | }; | |
1456 | }; |
|
1456 | }; | |
1457 |
"bluebird-3.5. |
|
1457 | "bluebird-3.5.3" = { | |
1458 | name = "bluebird"; |
|
1458 | name = "bluebird"; | |
1459 | packageName = "bluebird"; |
|
1459 | packageName = "bluebird"; | |
1460 |
version = "3.5. |
|
1460 | version = "3.5.3"; | |
1461 | src = fetchurl { |
|
1461 | src = fetchurl { | |
1462 |
url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5. |
|
1462 | url = "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz"; | |
1463 | sha512 = "dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg=="; |
|
1463 | sha512 = "/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="; | |
1464 | }; |
|
1464 | }; | |
1465 | }; |
|
1465 | }; | |
1466 | "bn.js-4.11.8" = { |
|
1466 | "bn.js-4.11.8" = { | |
@@ -1661,13 +1661,13 b' let' | |||||
1661 | sha1 = "9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"; |
|
1661 | sha1 = "9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"; | |
1662 | }; |
|
1662 | }; | |
1663 | }; |
|
1663 | }; | |
1664 |
"camelcase- |
|
1664 | "camelcase-5.0.0" = { | |
1665 | name = "camelcase"; |
|
1665 | name = "camelcase"; | |
1666 | packageName = "camelcase"; |
|
1666 | packageName = "camelcase"; | |
1667 |
version = " |
|
1667 | version = "5.0.0"; | |
1668 | src = fetchurl { |
|
1668 | src = fetchurl { | |
1669 |
url = "https://registry.npmjs.org/camelcase/-/camelcase- |
|
1669 | url = "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz"; | |
1670 | sha1 = "d545635be1e33c542649c69173e5de6acfae34dd"; |
|
1670 | sha512 = "faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA=="; | |
1671 | }; |
|
1671 | }; | |
1672 | }; |
|
1672 | }; | |
1673 | "caniuse-api-1.6.1" = { |
|
1673 | "caniuse-api-1.6.1" = { | |
@@ -1679,22 +1679,22 b' let' | |||||
1679 | sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"; |
|
1679 | sha1 = "b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"; | |
1680 | }; |
|
1680 | }; | |
1681 | }; |
|
1681 | }; | |
1682 |
"caniuse-db-1.0.300009 |
|
1682 | "caniuse-db-1.0.30000912" = { | |
1683 | name = "caniuse-db"; |
|
1683 | name = "caniuse-db"; | |
1684 | packageName = "caniuse-db"; |
|
1684 | packageName = "caniuse-db"; | |
1685 |
version = "1.0.300009 |
|
1685 | version = "1.0.30000912"; | |
1686 | src = fetchurl { |
|
1686 | src = fetchurl { | |
1687 |
url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.300009 |
|
1687 | url = "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000912.tgz"; | |
1688 | sha512 = "fvicVRDlhHIQpt/bmbLl3hDHKUZb5ZP8O2OuZLz2fSEPlUBbvwwbhhqhGS617ldN6bDoo9A3+MQKQyFq0p7UXA=="; |
|
1688 | sha512 = "uiepPdHcJ06Na9t15L5l+pp3NWQU4IETbmleghD6tqCqbIYqhHSu7nVfbK2gqPjfy+9jl/wHF1UQlyTszh9tJQ=="; | |
1689 | }; |
|
1689 | }; | |
1690 | }; |
|
1690 | }; | |
1691 |
"caniuse-lite-1.0.300009 |
|
1691 | "caniuse-lite-1.0.30000912" = { | |
1692 | name = "caniuse-lite"; |
|
1692 | name = "caniuse-lite"; | |
1693 | packageName = "caniuse-lite"; |
|
1693 | packageName = "caniuse-lite"; | |
1694 |
version = "1.0.300009 |
|
1694 | version = "1.0.30000912"; | |
1695 | src = fetchurl { |
|
1695 | src = fetchurl { | |
1696 |
url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.300009 |
|
1696 | url = "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000912.tgz"; | |
1697 | sha512 = "xDVs8pBFr6bzq9pXUkLKpGQQnzsF/l6/yX38UnCkTcUcwC0rDl1NGZGildcJVTU+uGBxfsyniK/ZWagPNn1Oqw=="; |
|
1697 | sha512 = "M3zAtV36U+xw5mMROlTXpAHClmPAor6GPKAMD5Yi7glCB5sbMPFtnQ3rGpk4XqPdUrrTIaVYSJZxREZWNy8QJg=="; | |
1698 | }; |
|
1698 | }; | |
1699 | }; |
|
1699 | }; | |
1700 | "caseless-0.12.0" = { |
|
1700 | "caseless-0.12.0" = { | |
@@ -1814,13 +1814,13 b' let' | |||||
1814 | sha1 = "22817534f24bfa4950c34d532d48ecbc621b8c14"; |
|
1814 | sha1 = "22817534f24bfa4950c34d532d48ecbc621b8c14"; | |
1815 | }; |
|
1815 | }; | |
1816 | }; |
|
1816 | }; | |
1817 |
"clipboard-2.0. |
|
1817 | "clipboard-2.0.4" = { | |
1818 | name = "clipboard"; |
|
1818 | name = "clipboard"; | |
1819 | packageName = "clipboard"; |
|
1819 | packageName = "clipboard"; | |
1820 |
version = "2.0. |
|
1820 | version = "2.0.4"; | |
1821 | src = fetchurl { |
|
1821 | src = fetchurl { | |
1822 |
url = "https://registry.npmjs.org/clipboard/-/clipboard-2.0. |
|
1822 | url = "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz"; | |
1823 | sha512 = "7yhQBmtN+uYZmfRjjVjKa0dZdWuabzpSKGtyQZN+9C8xlC788SSJjOHWh7tzurfwTqTD5UDYAhIv5fRJg3sHjQ=="; |
|
1823 | sha512 = "Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ=="; | |
1824 | }; |
|
1824 | }; | |
1825 | }; |
|
1825 | }; | |
1826 | "cliui-2.1.0" = { |
|
1826 | "cliui-2.1.0" = { | |
@@ -2093,13 +2093,13 b' let' | |||||
2093 | sha1 = "676f6eb3c39997c2ee1ac3a924fd6124748f578d"; |
|
2093 | sha1 = "676f6eb3c39997c2ee1ac3a924fd6124748f578d"; | |
2094 | }; |
|
2094 | }; | |
2095 | }; |
|
2095 | }; | |
2096 |
"copy-webpack-plugin-4. |
|
2096 | "copy-webpack-plugin-4.6.0" = { | |
2097 | name = "copy-webpack-plugin"; |
|
2097 | name = "copy-webpack-plugin"; | |
2098 | packageName = "copy-webpack-plugin"; |
|
2098 | packageName = "copy-webpack-plugin"; | |
2099 |
version = "4. |
|
2099 | version = "4.6.0"; | |
2100 | src = fetchurl { |
|
2100 | src = fetchurl { | |
2101 |
url = "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4. |
|
2101 | url = "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz"; | |
2102 | sha512 = "0lstlEyj74OAtYMrDxlNZsU7cwFijAI3Ofz2fD6Mpo9r4xCv4yegfa3uHIKvZY1NSuOtE9nvG6TAhJ+uz9gDaQ=="; |
|
2102 | sha512 = "Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA=="; | |
2103 | }; |
|
2103 | }; | |
2104 | }; |
|
2104 | }; | |
2105 | "core-js-2.5.7" = { |
|
2105 | "core-js-2.5.7" = { | |
@@ -2201,13 +2201,13 b' let' | |||||
2201 | sha1 = "2b3a110539c5355f1cd8d314623e870b121ec858"; |
|
2201 | sha1 = "2b3a110539c5355f1cd8d314623e870b121ec858"; | |
2202 | }; |
|
2202 | }; | |
2203 | }; |
|
2203 | }; | |
2204 |
"css-selector-tokenizer-0.7. |
|
2204 | "css-selector-tokenizer-0.7.1" = { | |
2205 | name = "css-selector-tokenizer"; |
|
2205 | name = "css-selector-tokenizer"; | |
2206 | packageName = "css-selector-tokenizer"; |
|
2206 | packageName = "css-selector-tokenizer"; | |
2207 |
version = "0.7. |
|
2207 | version = "0.7.1"; | |
2208 | src = fetchurl { |
|
2208 | src = fetchurl { | |
2209 |
url = "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7. |
|
2209 | url = "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz"; | |
2210 | sha1 = "e6988474ae8c953477bf5e7efecfceccd9cf4c86"; |
|
2210 | sha512 = "xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA=="; | |
2211 | }; |
|
2211 | }; | |
2212 | }; |
|
2212 | }; | |
2213 | "css-what-2.1.2" = { |
|
2213 | "css-what-2.1.2" = { | |
@@ -2318,15 +2318,6 b' let' | |||||
2318 | sha1 = "f6534d15148269b20352e7bee26f501f9a191290"; |
|
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 | "decode-uri-component-0.2.0" = { |
|
2321 | "decode-uri-component-0.2.0" = { | |
2331 | name = "decode-uri-component"; |
|
2322 | name = "decode-uri-component"; | |
2332 | packageName = "decode-uri-component"; |
|
2323 | packageName = "decode-uri-component"; | |
@@ -2561,13 +2552,13 b' let' | |||||
2561 | sha1 = "3a83a904e54353287874c564b7549386849a98c9"; |
|
2552 | sha1 = "3a83a904e54353287874c564b7549386849a98c9"; | |
2562 | }; |
|
2553 | }; | |
2563 | }; |
|
2554 | }; | |
2564 |
"electron-to-chromium-1.3.8 |
|
2555 | "electron-to-chromium-1.3.85" = { | |
2565 | name = "electron-to-chromium"; |
|
2556 | name = "electron-to-chromium"; | |
2566 | packageName = "electron-to-chromium"; |
|
2557 | packageName = "electron-to-chromium"; | |
2567 |
version = "1.3.8 |
|
2558 | version = "1.3.85"; | |
2568 | src = fetchurl { |
|
2559 | src = fetchurl { | |
2569 |
url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.8 |
|
2560 | url = "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.85.tgz"; | |
2570 | sha512 = "NI4nB2IWGcU4JVT1AE8kBb/dFor4zjLHMLsOROPahppeHrR0FG5uslxMmkp/thO1MvPjM2xhlKoY29/I60s0ew=="; |
|
2561 | sha512 = "kWSDVVF9t3mft2OHVZy4K85X2beP6c6mFm3teFS/mLSDJpQwuFIWHrULCX+w6H1E55ZYmFRlT+ATAFRwhrYzsw=="; | |
2571 | }; |
|
2562 | }; | |
2572 | }; |
|
2563 | }; | |
2573 | "elliptic-6.4.1" = { |
|
2564 | "elliptic-6.4.1" = { | |
@@ -2912,13 +2903,13 b' let' | |||||
2912 | sha1 = "d5142c0caee6b1189f87d3a76111064f86c8bbf2"; |
|
2903 | sha1 = "d5142c0caee6b1189f87d3a76111064f86c8bbf2"; | |
2913 | }; |
|
2904 | }; | |
2914 | }; |
|
2905 | }; | |
2915 |
"fastparse-1.1. |
|
2906 | "fastparse-1.1.2" = { | |
2916 | name = "fastparse"; |
|
2907 | name = "fastparse"; | |
2917 | packageName = "fastparse"; |
|
2908 | packageName = "fastparse"; | |
2918 |
version = "1.1. |
|
2909 | version = "1.1.2"; | |
2919 | src = fetchurl { |
|
2910 | src = fetchurl { | |
2920 |
url = "https://registry.npmjs.org/fastparse/-/fastparse-1.1. |
|
2911 | url = "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz"; | |
2921 | sha1 = "d1e2643b38a94d7583b479060e6c4affc94071f8"; |
|
2912 | sha512 = "483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ=="; | |
2922 | }; |
|
2913 | }; | |
2923 | }; |
|
2914 | }; | |
2924 | "favico.js-0.3.10" = { |
|
2915 | "favico.js-0.3.10" = { | |
@@ -3308,13 +3299,13 b' let' | |||||
3308 | sha1 = "15a4806a57547cb2d2dbf27f42e89a8c3451b364"; |
|
3299 | sha1 = "15a4806a57547cb2d2dbf27f42e89a8c3451b364"; | |
3309 | }; |
|
3300 | }; | |
3310 | }; |
|
3301 | }; | |
3311 |
"graceful-fs-4.1.1 |
|
3302 | "graceful-fs-4.1.15" = { | |
3312 | name = "graceful-fs"; |
|
3303 | name = "graceful-fs"; | |
3313 | packageName = "graceful-fs"; |
|
3304 | packageName = "graceful-fs"; | |
3314 |
version = "4.1.1 |
|
3305 | version = "4.1.15"; | |
3315 | src = fetchurl { |
|
3306 | src = fetchurl { | |
3316 |
url = "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.1 |
|
3307 | url = "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz"; | |
3317 | sha1 = "0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"; |
|
3308 | sha512 = "6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="; | |
3318 | }; |
|
3309 | }; | |
3319 | }; |
|
3310 | }; | |
3320 | "grunt-0.4.5" = { |
|
3311 | "grunt-0.4.5" = { | |
@@ -3326,13 +3317,13 b' let' | |||||
3326 | sha1 = "56937cd5194324adff6d207631832a9d6ba4e7f0"; |
|
3317 | sha1 = "56937cd5194324adff6d207631832a9d6ba4e7f0"; | |
3327 | }; |
|
3318 | }; | |
3328 | }; |
|
3319 | }; | |
3329 |
"grunt-cli-1.3. |
|
3320 | "grunt-cli-1.3.2" = { | |
3330 | name = "grunt-cli"; |
|
3321 | name = "grunt-cli"; | |
3331 | packageName = "grunt-cli"; |
|
3322 | packageName = "grunt-cli"; | |
3332 |
version = "1.3. |
|
3323 | version = "1.3.2"; | |
3333 | src = fetchurl { |
|
3324 | src = fetchurl { | |
3334 |
url = "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3. |
|
3325 | url = "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz"; | |
3335 | sha512 = "UwBRu/QpAjDc53DRLEkyilFdL0zenpxu+fddTIlsF/KJqdNcHaQmvyu1W3cDesZ9rqqZdKK5A8+QDIyLUEWoZQ=="; |
|
3326 | sha512 = "8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ=="; | |
3336 | }; |
|
3327 | }; | |
3337 | }; |
|
3328 | }; | |
3338 | "grunt-contrib-concat-0.5.1" = { |
|
3329 | "grunt-contrib-concat-0.5.1" = { | |
@@ -4631,13 +4622,13 b' let' | |||||
4631 | sha1 = "6d4524e8b955f95d4f5b58851ce21dd72fb4e952"; |
|
4622 | sha1 = "6d4524e8b955f95d4f5b58851ce21dd72fb4e952"; | |
4632 | }; |
|
4623 | }; | |
4633 | }; |
|
4624 | }; | |
4634 |
"lru-cache-4.1. |
|
4625 | "lru-cache-4.1.5" = { | |
4635 | name = "lru-cache"; |
|
4626 | name = "lru-cache"; | |
4636 | packageName = "lru-cache"; |
|
4627 | packageName = "lru-cache"; | |
4637 |
version = "4.1. |
|
4628 | version = "4.1.5"; | |
4638 | src = fetchurl { |
|
4629 | src = fetchurl { | |
4639 |
url = "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1. |
|
4630 | url = "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz"; | |
4640 | sha512 = "fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA=="; |
|
4631 | sha512 = "sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g=="; | |
4641 | }; |
|
4632 | }; | |
4642 | }; |
|
4633 | }; | |
4643 | "make-dir-1.3.0" = { |
|
4634 | "make-dir-1.3.0" = { | |
@@ -4658,13 +4649,13 b' let' | |||||
4658 | sha512 = "pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw=="; |
|
4649 | sha512 = "pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw=="; | |
4659 | }; |
|
4650 | }; | |
4660 | }; |
|
4651 | }; | |
4661 |
"map-age-cleaner-0.1. |
|
4652 | "map-age-cleaner-0.1.3" = { | |
4662 | name = "map-age-cleaner"; |
|
4653 | name = "map-age-cleaner"; | |
4663 | packageName = "map-age-cleaner"; |
|
4654 | packageName = "map-age-cleaner"; | |
4664 |
version = "0.1. |
|
4655 | version = "0.1.3"; | |
4665 | src = fetchurl { |
|
4656 | src = fetchurl { | |
4666 |
url = "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1. |
|
4657 | url = "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz"; | |
4667 | sha512 = "UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ=="; |
|
4658 | sha512 = "bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w=="; | |
4668 | }; |
|
4659 | }; | |
4669 | }; |
|
4660 | }; | |
4670 | "map-cache-0.2.2" = { |
|
4661 | "map-cache-0.2.2" = { | |
@@ -5261,13 +5252,13 b' let' | |||||
5261 | sha512 = "hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ=="; |
|
5252 | sha512 = "hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ=="; | |
5262 | }; |
|
5253 | }; | |
5263 | }; |
|
5254 | }; | |
5264 |
"pako-1.0. |
|
5255 | "pako-1.0.7" = { | |
5265 | name = "pako"; |
|
5256 | name = "pako"; | |
5266 | packageName = "pako"; |
|
5257 | packageName = "pako"; | |
5267 |
version = "1.0. |
|
5258 | version = "1.0.7"; | |
5268 | src = fetchurl { |
|
5259 | src = fetchurl { | |
5269 |
url = "https://registry.npmjs.org/pako/-/pako-1.0. |
|
5260 | url = "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz"; | |
5270 | sha512 = "lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="; |
|
5261 | sha512 = "3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ=="; | |
5271 | }; |
|
5262 | }; | |
5272 | }; |
|
5263 | }; | |
5273 | "parallel-transform-1.1.0" = { |
|
5264 | "parallel-transform-1.1.0" = { | |
@@ -5711,13 +5702,13 b' let' | |||||
5711 | sha1 = "b2c6a98c0072cf91b932d1a496508114311735bf"; |
|
5702 | sha1 = "b2c6a98c0072cf91b932d1a496508114311735bf"; | |
5712 | }; |
|
5703 | }; | |
5713 | }; |
|
5704 | }; | |
5714 |
"postcss-modules-extract-imports-1.2. |
|
5705 | "postcss-modules-extract-imports-1.2.1" = { | |
5715 | name = "postcss-modules-extract-imports"; |
|
5706 | name = "postcss-modules-extract-imports"; | |
5716 | packageName = "postcss-modules-extract-imports"; |
|
5707 | packageName = "postcss-modules-extract-imports"; | |
5717 |
version = "1.2. |
|
5708 | version = "1.2.1"; | |
5718 | src = fetchurl { |
|
5709 | src = fetchurl { | |
5719 |
url = "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2. |
|
5710 | url = "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz"; | |
5720 | sha1 = "66140ecece38ef06bf0d3e355d69bf59d141ea85"; |
|
5711 | sha512 = "6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw=="; | |
5721 | }; |
|
5712 | }; | |
5722 | }; |
|
5713 | }; | |
5723 | "postcss-modules-local-by-default-1.2.0" = { |
|
5714 | "postcss-modules-local-by-default-1.2.0" = { | |
@@ -6737,13 +6728,13 b' let' | |||||
6737 | sha1 = "04e6926f662895354f3dd015203633b857297e2c"; |
|
6728 | sha1 = "04e6926f662895354f3dd015203633b857297e2c"; | |
6738 | }; |
|
6729 | }; | |
6739 | }; |
|
6730 | }; | |
6740 |
"sshpk-1.15. |
|
6731 | "sshpk-1.15.2" = { | |
6741 | name = "sshpk"; |
|
6732 | name = "sshpk"; | |
6742 | packageName = "sshpk"; |
|
6733 | packageName = "sshpk"; | |
6743 |
version = "1.15. |
|
6734 | version = "1.15.2"; | |
6744 | src = fetchurl { |
|
6735 | src = fetchurl { | |
6745 |
url = "https://registry.npmjs.org/sshpk/-/sshpk-1.15. |
|
6736 | url = "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz"; | |
6746 | sha512 = "mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA=="; |
|
6737 | sha512 = "Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA=="; | |
6747 | }; |
|
6738 | }; | |
6748 | }; |
|
6739 | }; | |
6749 | "ssri-5.3.0" = { |
|
6740 | "ssri-5.3.0" = { | |
@@ -6863,6 +6854,15 b' let' | |||||
6863 | sha512 = "n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="; |
|
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 | "stringstream-0.0.6" = { |
|
6866 | "stringstream-0.0.6" = { | |
6867 | name = "stringstream"; |
|
6867 | name = "stringstream"; | |
6868 | packageName = "stringstream"; |
|
6868 | packageName = "stringstream"; | |
@@ -6971,22 +6971,22 b' let' | |||||
6971 | sha1 = "9f5772413952135c6fefbf40afe6a4faa88b4bb5"; |
|
6971 | sha1 = "9f5772413952135c6fefbf40afe6a4faa88b4bb5"; | |
6972 | }; |
|
6972 | }; | |
6973 | }; |
|
6973 | }; | |
6974 |
"tapable-0.2. |
|
6974 | "tapable-0.2.9" = { | |
6975 | name = "tapable"; |
|
6975 | name = "tapable"; | |
6976 | packageName = "tapable"; |
|
6976 | packageName = "tapable"; | |
6977 |
version = "0.2. |
|
6977 | version = "0.2.9"; | |
6978 | src = fetchurl { |
|
6978 | src = fetchurl { | |
6979 |
url = "https://registry.npmjs.org/tapable/-/tapable-0.2. |
|
6979 | url = "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz"; | |
6980 | sha1 = "99372a5c999bf2df160afc0d74bed4f47948cd22"; |
|
6980 | sha512 = "2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A=="; | |
6981 | }; |
|
6981 | }; | |
6982 | }; |
|
6982 | }; | |
6983 |
"tapable-1.1. |
|
6983 | "tapable-1.1.1" = { | |
6984 | name = "tapable"; |
|
6984 | name = "tapable"; | |
6985 | packageName = "tapable"; |
|
6985 | packageName = "tapable"; | |
6986 |
version = "1.1. |
|
6986 | version = "1.1.1"; | |
6987 | src = fetchurl { |
|
6987 | src = fetchurl { | |
6988 |
url = "https://registry.npmjs.org/tapable/-/tapable-1.1. |
|
6988 | url = "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz"; | |
6989 | sha512 = "IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA=="; |
|
6989 | sha512 = "9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA=="; | |
6990 | }; |
|
6990 | }; | |
6991 | }; |
|
6991 | }; | |
6992 | "throttleit-1.0.0" = { |
|
6992 | "throttleit-1.0.0" = { | |
@@ -7007,13 +7007,13 b' let' | |||||
7007 | sha1 = "0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"; |
|
7007 | sha1 = "0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"; | |
7008 | }; |
|
7008 | }; | |
7009 | }; |
|
7009 | }; | |
7010 |
"through2-2.0. |
|
7010 | "through2-2.0.5" = { | |
7011 | name = "through2"; |
|
7011 | name = "through2"; | |
7012 | packageName = "through2"; |
|
7012 | packageName = "through2"; | |
7013 |
version = "2.0. |
|
7013 | version = "2.0.5"; | |
7014 | src = fetchurl { |
|
7014 | src = fetchurl { | |
7015 |
url = "https://registry.npmjs.org/through2/-/through2-2.0. |
|
7015 | url = "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"; | |
7016 | sha1 = "0004569b37c7c74ba39c43f3ced78d1ad94140be"; |
|
7016 | sha512 = "/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="; | |
7017 | }; |
|
7017 | }; | |
7018 | }; |
|
7018 | }; | |
7019 | "timers-browserify-2.0.10" = { |
|
7019 | "timers-browserify-2.0.10" = { | |
@@ -7439,13 +7439,13 b' let' | |||||
7439 | sha512 = "1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw=="; |
|
7439 | sha512 = "1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw=="; | |
7440 | }; |
|
7440 | }; | |
7441 | }; |
|
7441 | }; | |
7442 |
"v8flags-3. |
|
7442 | "v8flags-3.1.1" = { | |
7443 | name = "v8flags"; |
|
7443 | name = "v8flags"; | |
7444 | packageName = "v8flags"; |
|
7444 | packageName = "v8flags"; | |
7445 |
version = "3. |
|
7445 | version = "3.1.1"; | |
7446 | src = fetchurl { |
|
7446 | src = fetchurl { | |
7447 |
url = "https://registry.npmjs.org/v8flags/-/v8flags-3. |
|
7447 | url = "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz"; | |
7448 | sha512 = "6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA=="; |
|
7448 | sha512 = "iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ=="; | |
7449 | }; |
|
7449 | }; | |
7450 | }; |
|
7450 | }; | |
7451 | "vendors-1.0.2" = { |
|
7451 | "vendors-1.0.2" = { | |
@@ -7628,15 +7628,6 b' let' | |||||
7628 | sha1 = "b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"; |
|
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 | "xtend-4.0.1" = { |
|
7631 | "xtend-4.0.1" = { | |
7641 | name = "xtend"; |
|
7632 | name = "xtend"; | |
7642 | packageName = "xtend"; |
|
7633 | packageName = "xtend"; | |
@@ -7664,13 +7655,13 b' let' | |||||
7664 | sha1 = "1c11f9218f076089a47dd512f93c6699a6a81d52"; |
|
7655 | sha1 = "1c11f9218f076089a47dd512f93c6699a6a81d52"; | |
7665 | }; |
|
7656 | }; | |
7666 | }; |
|
7657 | }; | |
7667 |
"yargs-12.0. |
|
7658 | "yargs-12.0.5" = { | |
7668 | name = "yargs"; |
|
7659 | name = "yargs"; | |
7669 | packageName = "yargs"; |
|
7660 | packageName = "yargs"; | |
7670 |
version = "12.0. |
|
7661 | version = "12.0.5"; | |
7671 | src = fetchurl { |
|
7662 | src = fetchurl { | |
7672 |
url = "https://registry.npmjs.org/yargs/-/yargs-12.0. |
|
7663 | url = "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz"; | |
7673 | sha512 = "e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ=="; |
|
7664 | sha512 = "Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw=="; | |
7674 | }; |
|
7665 | }; | |
7675 | }; |
|
7666 | }; | |
7676 | "yargs-3.10.0" = { |
|
7667 | "yargs-3.10.0" = { | |
@@ -7682,13 +7673,13 b' let' | |||||
7682 | sha1 = "f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"; |
|
7673 | sha1 = "f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"; | |
7683 | }; |
|
7674 | }; | |
7684 | }; |
|
7675 | }; | |
7685 |
"yargs-parser-1 |
|
7676 | "yargs-parser-11.1.1" = { | |
7686 | name = "yargs-parser"; |
|
7677 | name = "yargs-parser"; | |
7687 | packageName = "yargs-parser"; |
|
7678 | packageName = "yargs-parser"; | |
7688 |
version = "1 |
|
7679 | version = "11.1.1"; | |
7689 | src = fetchurl { |
|
7680 | src = fetchurl { | |
7690 |
url = "https://registry.npmjs.org/yargs-parser/-/yargs-parser-1 |
|
7681 | url = "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz"; | |
7691 | sha512 = "VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ=="; |
|
7682 | sha512 = "C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ=="; | |
7692 | }; |
|
7683 | }; | |
7693 | }; |
|
7684 | }; | |
7694 | "yauzl-2.4.1" = { |
|
7685 | "yauzl-2.4.1" = { | |
@@ -7708,7 +7699,7 b' let' | |||||
7708 | src = ./..; |
|
7699 | src = ./..; | |
7709 | dependencies = [ |
|
7700 | dependencies = [ | |
7710 | sources."@polymer/font-roboto-3.0.2" |
|
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 | sources."@polymer/iron-a11y-keys-3.0.1" |
|
7703 | sources."@polymer/iron-a11y-keys-3.0.1" | |
7713 | sources."@polymer/iron-a11y-keys-behavior-3.0.1" |
|
7704 | sources."@polymer/iron-a11y-keys-behavior-3.0.1" | |
7714 | sources."@polymer/iron-ajax-3.0.1" |
|
7705 | sources."@polymer/iron-ajax-3.0.1" | |
@@ -7732,7 +7723,7 b' let' | |||||
7732 | sources."@polymer/paper-tooltip-3.0.1" |
|
7723 | sources."@polymer/paper-tooltip-3.0.1" | |
7733 | sources."@polymer/polymer-3.1.0" |
|
7724 | sources."@polymer/polymer-3.1.0" | |
7734 | sources."@types/clone-0.1.30" |
|
7725 | sources."@types/clone-0.1.30" | |
7735 |
sources."@types/node-6.14. |
|
7726 | sources."@types/node-6.14.2" | |
7736 | sources."@types/parse5-2.2.34" |
|
7727 | sources."@types/parse5-2.2.34" | |
7737 | sources."@webassemblyjs/ast-1.7.10" |
|
7728 | sources."@webassemblyjs/ast-1.7.10" | |
7738 | sources."@webassemblyjs/floating-point-hex-parser-1.7.10" |
|
7729 | sources."@webassemblyjs/floating-point-hex-parser-1.7.10" | |
@@ -7752,8 +7743,8 b' let' | |||||
7752 | sources."@webassemblyjs/wasm-parser-1.7.10" |
|
7743 | sources."@webassemblyjs/wasm-parser-1.7.10" | |
7753 | sources."@webassemblyjs/wast-parser-1.7.10" |
|
7744 | sources."@webassemblyjs/wast-parser-1.7.10" | |
7754 | sources."@webassemblyjs/wast-printer-1.7.10" |
|
7745 | sources."@webassemblyjs/wast-printer-1.7.10" | |
7755 |
sources."@webcomponents/shadycss-1. |
|
7746 | sources."@webcomponents/shadycss-1.6.0" | |
7756 |
sources."@webcomponents/webcomponentsjs-2.1 |
|
7747 | sources."@webcomponents/webcomponentsjs-2.2.1" | |
7757 | sources."@xtuc/ieee754-1.2.0" |
|
7748 | sources."@xtuc/ieee754-1.2.0" | |
7758 | sources."@xtuc/long-4.2.1" |
|
7749 | sources."@xtuc/long-4.2.1" | |
7759 | sources."abbrev-1.1.1" |
|
7750 | sources."abbrev-1.1.1" | |
@@ -7927,7 +7918,7 b' let' | |||||
7927 | sources."bcrypt-pbkdf-1.0.2" |
|
7918 | sources."bcrypt-pbkdf-1.0.2" | |
7928 | sources."big.js-3.2.0" |
|
7919 | sources."big.js-3.2.0" | |
7929 | sources."binary-extensions-1.12.0" |
|
7920 | sources."binary-extensions-1.12.0" | |
7930 |
sources."bluebird-3.5. |
|
7921 | sources."bluebird-3.5.3" | |
7931 | sources."bn.js-4.11.8" |
|
7922 | sources."bn.js-4.11.8" | |
7932 | sources."boolbase-1.0.0" |
|
7923 | sources."boolbase-1.0.0" | |
7933 | sources."boom-2.10.1" |
|
7924 | sources."boom-2.10.1" | |
@@ -7952,22 +7943,22 b' let' | |||||
7952 | (sources."cacache-10.0.4" // { |
|
7943 | (sources."cacache-10.0.4" // { | |
7953 | dependencies = [ |
|
7944 | dependencies = [ | |
7954 | sources."glob-7.1.3" |
|
7945 | sources."glob-7.1.3" | |
7955 |
sources."graceful-fs-4.1.1 |
|
7946 | sources."graceful-fs-4.1.15" | |
7956 |
sources."lru-cache-4.1. |
|
7947 | sources."lru-cache-4.1.5" | |
7957 | sources."minimatch-3.0.4" |
|
7948 | sources."minimatch-3.0.4" | |
7958 | sources."rimraf-2.6.2" |
|
7949 | sources."rimraf-2.6.2" | |
7959 | ]; |
|
7950 | ]; | |
7960 | }) |
|
7951 | }) | |
7961 | sources."cache-base-1.0.1" |
|
7952 | sources."cache-base-1.0.1" | |
7962 | sources."camel-case-3.0.0" |
|
7953 | sources."camel-case-3.0.0" | |
7963 |
sources."camelcase- |
|
7954 | sources."camelcase-5.0.0" | |
7964 | (sources."caniuse-api-1.6.1" // { |
|
7955 | (sources."caniuse-api-1.6.1" // { | |
7965 | dependencies = [ |
|
7956 | dependencies = [ | |
7966 | sources."browserslist-1.7.7" |
|
7957 | sources."browserslist-1.7.7" | |
7967 | ]; |
|
7958 | ]; | |
7968 | }) |
|
7959 | }) | |
7969 |
sources."caniuse-db-1.0.300009 |
|
7960 | sources."caniuse-db-1.0.30000912" | |
7970 |
sources."caniuse-lite-1.0.300009 |
|
7961 | sources."caniuse-lite-1.0.30000912" | |
7971 | sources."caseless-0.12.0" |
|
7962 | sources."caseless-0.12.0" | |
7972 | sources."center-align-0.1.3" |
|
7963 | sources."center-align-0.1.3" | |
7973 | sources."chalk-0.5.1" |
|
7964 | sources."chalk-0.5.1" | |
@@ -8017,7 +8008,7 b' let' | |||||
8017 | sources."minimatch-3.0.4" |
|
8008 | sources."minimatch-3.0.4" | |
8018 | ]; |
|
8009 | ]; | |
8019 | }) |
|
8010 | }) | |
8020 |
sources."clipboard-2.0. |
|
8011 | sources."clipboard-2.0.4" | |
8021 | (sources."cliui-4.1.0" // { |
|
8012 | (sources."cliui-4.1.0" // { | |
8022 | dependencies = [ |
|
8013 | dependencies = [ | |
8023 | sources."ansi-regex-3.0.0" |
|
8014 | sources."ansi-regex-3.0.0" | |
@@ -8058,7 +8049,7 b' let' | |||||
8058 | ]; |
|
8049 | ]; | |
8059 | }) |
|
8050 | }) | |
8060 | sources."copy-descriptor-0.1.1" |
|
8051 | sources."copy-descriptor-0.1.1" | |
8061 |
(sources."copy-webpack-plugin-4. |
|
8052 | (sources."copy-webpack-plugin-4.6.0" // { | |
8062 | dependencies = [ |
|
8053 | dependencies = [ | |
8063 | sources."is-glob-4.0.0" |
|
8054 | sources."is-glob-4.0.0" | |
8064 | sources."minimatch-3.0.4" |
|
8055 | sources."minimatch-3.0.4" | |
@@ -8079,18 +8070,14 b' let' | |||||
8079 | sources."css-color-names-0.0.4" |
|
8070 | sources."css-color-names-0.0.4" | |
8080 | sources."css-loader-0.28.11" |
|
8071 | sources."css-loader-0.28.11" | |
8081 | sources."css-select-1.2.0" |
|
8072 | sources."css-select-1.2.0" | |
8082 |
(sources."css-selector-tokenizer-0.7. |
|
8073 | (sources."css-selector-tokenizer-0.7.1" // { | |
8083 | dependencies = [ |
|
8074 | dependencies = [ | |
8084 | sources."regexpu-core-1.0.0" |
|
8075 | sources."regexpu-core-1.0.0" | |
8085 | ]; |
|
8076 | ]; | |
8086 | }) |
|
8077 | }) | |
8087 | sources."css-what-2.1.2" |
|
8078 | sources."css-what-2.1.2" | |
8088 | sources."cssesc-0.1.0" |
|
8079 | sources."cssesc-0.1.0" | |
8089 |
|
|
8080 | sources."cssnano-3.10.0" | |
8090 | dependencies = [ |
|
|||
8091 | sources."decamelize-1.2.0" |
|
|||
8092 | ]; |
|
|||
8093 | }) |
|
|||
8094 | sources."csso-2.3.2" |
|
8081 | sources."csso-2.3.2" | |
8095 | sources."cycle-1.0.3" |
|
8082 | sources."cycle-1.0.3" | |
8096 | sources."cyclist-0.2.2" |
|
8083 | sources."cyclist-0.2.2" | |
@@ -8102,7 +8089,7 b' let' | |||||
8102 | sources."date-now-0.1.4" |
|
8089 | sources."date-now-0.1.4" | |
8103 | sources."dateformat-1.0.2-1.2.3" |
|
8090 | sources."dateformat-1.0.2-1.2.3" | |
8104 | sources."debug-2.6.9" |
|
8091 | sources."debug-2.6.9" | |
8105 |
sources."decamelize-2 |
|
8092 | sources."decamelize-1.2.0" | |
8106 | sources."decode-uri-component-0.2.0" |
|
8093 | sources."decode-uri-component-0.2.0" | |
8107 | sources."deep-for-each-2.0.3" |
|
8094 | sources."deep-for-each-2.0.3" | |
8108 | sources."define-properties-1.1.3" |
|
8095 | sources."define-properties-1.1.3" | |
@@ -8139,13 +8126,13 b' let' | |||||
8139 | ]; |
|
8126 | ]; | |
8140 | }) |
|
8127 | }) | |
8141 | sources."ecc-jsbn-0.1.2" |
|
8128 | sources."ecc-jsbn-0.1.2" | |
8142 |
sources."electron-to-chromium-1.3.8 |
|
8129 | sources."electron-to-chromium-1.3.85" | |
8143 | sources."elliptic-6.4.1" |
|
8130 | sources."elliptic-6.4.1" | |
8144 | sources."emojis-list-2.1.0" |
|
8131 | sources."emojis-list-2.1.0" | |
8145 | sources."end-of-stream-1.4.1" |
|
8132 | sources."end-of-stream-1.4.1" | |
8146 | (sources."enhanced-resolve-4.1.0" // { |
|
8133 | (sources."enhanced-resolve-4.1.0" // { | |
8147 | dependencies = [ |
|
8134 | dependencies = [ | |
8148 |
sources."graceful-fs-4.1.1 |
|
8135 | sources."graceful-fs-4.1.15" | |
8149 | ]; |
|
8136 | ]; | |
8150 | }) |
|
8137 | }) | |
8151 | sources."entities-1.0.0" |
|
8138 | sources."entities-1.0.0" | |
@@ -8203,7 +8190,7 b' let' | |||||
8203 | sources."eyes-0.1.8" |
|
8190 | sources."eyes-0.1.8" | |
8204 | sources."fast-deep-equal-2.0.1" |
|
8191 | sources."fast-deep-equal-2.0.1" | |
8205 | sources."fast-json-stable-stringify-2.0.0" |
|
8192 | sources."fast-json-stable-stringify-2.0.0" | |
8206 |
sources."fastparse-1.1. |
|
8193 | sources."fastparse-1.1.2" | |
8207 | sources."favico.js-0.3.10" |
|
8194 | sources."favico.js-0.3.10" | |
8208 | sources."faye-websocket-0.4.4" |
|
8195 | sources."faye-websocket-0.4.4" | |
8209 | sources."fd-slicer-1.0.1" |
|
8196 | sources."fd-slicer-1.0.1" | |
@@ -8244,12 +8231,12 b' let' | |||||
8244 | }) |
|
8231 | }) | |
8245 | (sources."fs-extra-1.0.0" // { |
|
8232 | (sources."fs-extra-1.0.0" // { | |
8246 | dependencies = [ |
|
8233 | dependencies = [ | |
8247 |
sources."graceful-fs-4.1.1 |
|
8234 | sources."graceful-fs-4.1.15" | |
8248 | ]; |
|
8235 | ]; | |
8249 | }) |
|
8236 | }) | |
8250 | (sources."fs-write-stream-atomic-1.0.10" // { |
|
8237 | (sources."fs-write-stream-atomic-1.0.10" // { | |
8251 | dependencies = [ |
|
8238 | dependencies = [ | |
8252 |
sources."graceful-fs-4.1.1 |
|
8239 | sources."graceful-fs-4.1.15" | |
8253 | ]; |
|
8240 | ]; | |
8254 | }) |
|
8241 | }) | |
8255 | sources."fs.realpath-1.0.0" |
|
8242 | sources."fs.realpath-1.0.0" | |
@@ -8293,7 +8280,7 b' let' | |||||
8293 | sources."good-listener-1.2.2" |
|
8280 | sources."good-listener-1.2.2" | |
8294 | sources."graceful-fs-1.2.3" |
|
8281 | sources."graceful-fs-1.2.3" | |
8295 | sources."grunt-0.4.5" |
|
8282 | sources."grunt-0.4.5" | |
8296 |
(sources."grunt-cli-1.3. |
|
8283 | (sources."grunt-cli-1.3.2" // { | |
8297 | dependencies = [ |
|
8284 | dependencies = [ | |
8298 | sources."nopt-4.0.1" |
|
8285 | sources."nopt-4.0.1" | |
8299 | ]; |
|
8286 | ]; | |
@@ -8477,7 +8464,7 b' let' | |||||
8477 | sources."json5-0.5.1" |
|
8464 | sources."json5-0.5.1" | |
8478 | (sources."jsonfile-2.4.0" // { |
|
8465 | (sources."jsonfile-2.4.0" // { | |
8479 | dependencies = [ |
|
8466 | dependencies = [ | |
8480 |
sources."graceful-fs-4.1.1 |
|
8467 | sources."graceful-fs-4.1.15" | |
8481 | ]; |
|
8468 | ]; | |
8482 | }) |
|
8469 | }) | |
8483 | sources."jsonify-0.0.0" |
|
8470 | sources."jsonify-0.0.0" | |
@@ -8490,14 +8477,14 b' let' | |||||
8490 | sources."kind-of-6.0.2" |
|
8477 | sources."kind-of-6.0.2" | |
8491 | (sources."klaw-1.3.1" // { |
|
8478 | (sources."klaw-1.3.1" // { | |
8492 | dependencies = [ |
|
8479 | dependencies = [ | |
8493 |
sources."graceful-fs-4.1.1 |
|
8480 | sources."graceful-fs-4.1.15" | |
8494 | ]; |
|
8481 | ]; | |
8495 | }) |
|
8482 | }) | |
8496 | sources."lazy-cache-1.0.4" |
|
8483 | sources."lazy-cache-1.0.4" | |
8497 | sources."lcid-2.0.0" |
|
8484 | sources."lcid-2.0.0" | |
8498 | (sources."less-2.7.3" // { |
|
8485 | (sources."less-2.7.3" // { | |
8499 | dependencies = [ |
|
8486 | dependencies = [ | |
8500 |
sources."graceful-fs-4.1.1 |
|
8487 | sources."graceful-fs-4.1.15" | |
8501 | ]; |
|
8488 | ]; | |
8502 | }) |
|
8489 | }) | |
8503 | (sources."liftoff-2.5.0" // { |
|
8490 | (sources."liftoff-2.5.0" // { | |
@@ -8520,7 +8507,7 b' let' | |||||
8520 | sources."lru-cache-2.7.3" |
|
8507 | sources."lru-cache-2.7.3" | |
8521 | sources."make-dir-1.3.0" |
|
8508 | sources."make-dir-1.3.0" | |
8522 | sources."make-iterator-1.0.1" |
|
8509 | sources."make-iterator-1.0.1" | |
8523 |
sources."map-age-cleaner-0.1. |
|
8510 | sources."map-age-cleaner-0.1.3" | |
8524 | sources."map-cache-0.2.2" |
|
8511 | sources."map-cache-0.2.2" | |
8525 | sources."map-visit-1.0.0" |
|
8512 | sources."map-visit-1.0.0" | |
8526 | sources."math-expression-evaluator-1.2.17" |
|
8513 | sources."math-expression-evaluator-1.2.17" | |
@@ -8566,8 +8553,12 b' let' | |||||
8566 | sources."no-case-2.3.2" |
|
8553 | sources."no-case-2.3.2" | |
8567 | (sources."node-libs-browser-2.1.0" // { |
|
8554 | (sources."node-libs-browser-2.1.0" // { | |
8568 | dependencies = [ |
|
8555 | dependencies = [ | |
8569 | sources."readable-stream-2.3.6" |
|
8556 | (sources."readable-stream-2.3.6" // { | |
8570 | sources."string_decoder-1.1.1" |
|
8557 | dependencies = [ | |
|
8558 | sources."string_decoder-1.1.1" | |||
|
8559 | ]; | |||
|
8560 | }) | |||
|
8561 | sources."string_decoder-1.2.0" | |||
8571 | ]; |
|
8562 | ]; | |
8572 | }) |
|
8563 | }) | |
8573 | sources."nopt-1.0.10" |
|
8564 | sources."nopt-1.0.10" | |
@@ -8616,7 +8607,7 b' let' | |||||
8616 | sources."p-limit-1.3.0" |
|
8607 | sources."p-limit-1.3.0" | |
8617 | sources."p-locate-2.0.0" |
|
8608 | sources."p-locate-2.0.0" | |
8618 | sources."p-try-1.0.0" |
|
8609 | sources."p-try-1.0.0" | |
8619 |
sources."pako-1.0. |
|
8610 | sources."pako-1.0.7" | |
8620 | (sources."parallel-transform-1.1.0" // { |
|
8611 | (sources."parallel-transform-1.1.0" // { | |
8621 | dependencies = [ |
|
8612 | dependencies = [ | |
8622 | sources."readable-stream-2.3.6" |
|
8613 | sources."readable-stream-2.3.6" | |
@@ -8706,7 +8697,7 b' let' | |||||
8706 | sources."postcss-minify-gradients-1.0.5" |
|
8697 | sources."postcss-minify-gradients-1.0.5" | |
8707 | sources."postcss-minify-params-1.2.2" |
|
8698 | sources."postcss-minify-params-1.2.2" | |
8708 | sources."postcss-minify-selectors-2.1.1" |
|
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 | dependencies = [ |
|
8701 | dependencies = [ | |
8711 | sources."ansi-styles-3.2.1" |
|
8702 | sources."ansi-styles-3.2.1" | |
8712 | sources."chalk-2.4.1" |
|
8703 | sources."chalk-2.4.1" | |
@@ -8783,7 +8774,7 b' let' | |||||
8783 | }) |
|
8774 | }) | |
8784 | (sources."readdirp-2.2.1" // { |
|
8775 | (sources."readdirp-2.2.1" // { | |
8785 | dependencies = [ |
|
8776 | dependencies = [ | |
8786 |
sources."graceful-fs-4.1.1 |
|
8777 | sources."graceful-fs-4.1.15" | |
8787 | sources."readable-stream-2.3.6" |
|
8778 | sources."readable-stream-2.3.6" | |
8788 | sources."string_decoder-1.1.1" |
|
8779 | sources."string_decoder-1.1.1" | |
8789 | ]; |
|
8780 | ]; | |
@@ -8851,7 +8842,7 b' let' | |||||
8851 | sources."sax-1.2.4" |
|
8842 | sources."sax-1.2.4" | |
8852 | (sources."schema-utils-0.4.7" // { |
|
8843 | (sources."schema-utils-0.4.7" // { | |
8853 | dependencies = [ |
|
8844 | dependencies = [ | |
8854 |
sources."ajv-6. |
|
8845 | sources."ajv-6.6.1" | |
8855 | ]; |
|
8846 | ]; | |
8856 | }) |
|
8847 | }) | |
8857 | sources."select-1.1.2" |
|
8848 | sources."select-1.1.2" | |
@@ -8909,7 +8900,7 b' let' | |||||
8909 | sources."split-1.0.1" |
|
8900 | sources."split-1.0.1" | |
8910 | sources."split-string-3.1.0" |
|
8901 | sources."split-string-3.1.0" | |
8911 | sources."sprintf-js-1.0.3" |
|
8902 | sources."sprintf-js-1.0.3" | |
8912 |
(sources."sshpk-1.15. |
|
8903 | (sources."sshpk-1.15.2" // { | |
8913 | dependencies = [ |
|
8904 | dependencies = [ | |
8914 | sources."assert-plus-1.0.0" |
|
8905 | sources."assert-plus-1.0.0" | |
8915 | ]; |
|
8906 | ]; | |
@@ -8971,10 +8962,10 b' let' | |||||
8971 | sources."js-yaml-3.7.0" |
|
8962 | sources."js-yaml-3.7.0" | |
8972 | ]; |
|
8963 | ]; | |
8973 | }) |
|
8964 | }) | |
8974 |
sources."tapable-1.1. |
|
8965 | sources."tapable-1.1.1" | |
8975 | sources."throttleit-1.0.0" |
|
8966 | sources."throttleit-1.0.0" | |
8976 | sources."through-2.3.8" |
|
8967 | sources."through-2.3.8" | |
8977 |
(sources."through2-2.0. |
|
8968 | (sources."through2-2.0.5" // { | |
8978 | dependencies = [ |
|
8969 | dependencies = [ | |
8979 | sources."readable-stream-2.3.6" |
|
8970 | sources."readable-stream-2.3.6" | |
8980 | sources."string_decoder-1.1.1" |
|
8971 | sources."string_decoder-1.1.1" | |
@@ -9004,9 +8995,9 b' let' | |||||
9004 | dependencies = [ |
|
8995 | dependencies = [ | |
9005 | sources."colors-1.3.2" |
|
8996 | sources."colors-1.3.2" | |
9006 | sources."enhanced-resolve-3.4.1" |
|
8997 | sources."enhanced-resolve-3.4.1" | |
9007 |
sources."graceful-fs-4.1.1 |
|
8998 | sources."graceful-fs-4.1.15" | |
9008 | sources."loader-utils-0.2.17" |
|
8999 | sources."loader-utils-0.2.17" | |
9009 |
sources."tapable-0.2. |
|
9000 | sources."tapable-0.2.9" | |
9010 | ]; |
|
9001 | ]; | |
9011 | }) |
|
9002 | }) | |
9012 | sources."tslib-1.9.3" |
|
9003 | sources."tslib-1.9.3" | |
@@ -9075,7 +9066,7 b' let' | |||||
9075 | sources."utila-0.4.0" |
|
9066 | sources."utila-0.4.0" | |
9076 | sources."uuid-3.3.2" |
|
9067 | sources."uuid-3.3.2" | |
9077 | sources."v8-compile-cache-2.0.2" |
|
9068 | sources."v8-compile-cache-2.0.2" | |
9078 |
sources."v8flags-3. |
|
9069 | sources."v8flags-3.1.1" | |
9079 | sources."vendors-1.0.2" |
|
9070 | sources."vendors-1.0.2" | |
9080 | (sources."verror-1.10.0" // { |
|
9071 | (sources."verror-1.10.0" // { | |
9081 | dependencies = [ |
|
9072 | dependencies = [ | |
@@ -9085,13 +9076,13 b' let' | |||||
9085 | sources."vm-browserify-0.0.4" |
|
9076 | sources."vm-browserify-0.0.4" | |
9086 | (sources."watchpack-1.6.0" // { |
|
9077 | (sources."watchpack-1.6.0" // { | |
9087 | dependencies = [ |
|
9078 | dependencies = [ | |
9088 |
sources."graceful-fs-4.1.1 |
|
9079 | sources."graceful-fs-4.1.15" | |
9089 | ]; |
|
9080 | ]; | |
9090 | }) |
|
9081 | }) | |
9091 | sources."waypoints-4.0.1" |
|
9082 | sources."waypoints-4.0.1" | |
9092 | (sources."webpack-4.23.1" // { |
|
9083 | (sources."webpack-4.23.1" // { | |
9093 | dependencies = [ |
|
9084 | dependencies = [ | |
9094 |
sources."ajv-6. |
|
9085 | sources."ajv-6.6.1" | |
9095 | ]; |
|
9086 | ]; | |
9096 | }) |
|
9087 | }) | |
9097 | (sources."webpack-cli-3.1.2" // { |
|
9088 | (sources."webpack-cli-3.1.2" // { | |
@@ -9119,7 +9110,6 b' let' | |||||
9119 | sources."camelcase-1.2.1" |
|
9110 | sources."camelcase-1.2.1" | |
9120 | sources."chalk-1.1.3" |
|
9111 | sources."chalk-1.1.3" | |
9121 | sources."cliui-2.1.0" |
|
9112 | sources."cliui-2.1.0" | |
9122 | sources."decamelize-1.2.0" |
|
|||
9123 | sources."has-ansi-2.0.0" |
|
9113 | sources."has-ansi-2.0.0" | |
9124 | sources."strip-ansi-3.0.1" |
|
9114 | sources."strip-ansi-3.0.1" | |
9125 | sources."supports-color-2.0.0" |
|
9115 | sources."supports-color-2.0.0" | |
@@ -9147,11 +9137,10 b' let' | |||||
9147 | ]; |
|
9137 | ]; | |
9148 | }) |
|
9138 | }) | |
9149 | sources."wrappy-1.0.2" |
|
9139 | sources."wrappy-1.0.2" | |
9150 | sources."xregexp-4.0.0" |
|
|||
9151 | sources."xtend-4.0.1" |
|
9140 | sources."xtend-4.0.1" | |
9152 | sources."y18n-4.0.0" |
|
9141 | sources."y18n-4.0.0" | |
9153 | sources."yallist-2.1.2" |
|
9142 | sources."yallist-2.1.2" | |
9154 |
(sources."yargs-12.0. |
|
9143 | (sources."yargs-12.0.5" // { | |
9155 | dependencies = [ |
|
9144 | dependencies = [ | |
9156 | sources."find-up-3.0.0" |
|
9145 | sources."find-up-3.0.0" | |
9157 | sources."locate-path-3.0.0" |
|
9146 | sources."locate-path-3.0.0" | |
@@ -9160,7 +9149,7 b' let' | |||||
9160 | sources."p-try-2.0.0" |
|
9149 | sources."p-try-2.0.0" | |
9161 | ]; |
|
9150 | ]; | |
9162 | }) |
|
9151 | }) | |
9163 |
sources."yargs-parser-1 |
|
9152 | sources."yargs-parser-11.1.1" | |
9164 | sources."yauzl-2.4.1" |
|
9153 | sources."yauzl-2.4.1" | |
9165 | ]; |
|
9154 | ]; | |
9166 | buildInputs = globalBuildInputs; |
|
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 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ [ |
|
76 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ [ | |
77 | # marcink: plug in jupyter-client for notebook rendering |
|
77 | # marcink: plug in jupyter-client for notebook rendering | |
78 | self."jupyter-client" |
|
78 | self."jupyter-client" | |
@@ -120,10 +120,12 b' self: super: {' | |||||
120 | pkgs.curl |
|
120 | pkgs.curl | |
121 | pkgs.openssl |
|
121 | pkgs.openssl | |
122 | ]; |
|
122 | ]; | |
|
123 | ||||
123 | preConfigure = '' |
|
124 | preConfigure = '' | |
124 | substituteInPlace setup.py --replace '--static-libs' '--libs' |
|
125 | substituteInPlace setup.py --replace '--static-libs' '--libs' | |
125 | export PYCURL_SSL_LIBRARY=openssl |
|
126 | export PYCURL_SSL_LIBRARY=openssl | |
126 | ''; |
|
127 | ''; | |
|
128 | ||||
127 | meta = { |
|
129 | meta = { | |
128 | license = pkgs.lib.licenses.mit; |
|
130 | license = pkgs.lib.licenses.mit; | |
129 | }; |
|
131 | }; | |
@@ -168,14 +170,32 b' self: super: {' | |||||
168 | propagatedBuildInputs = [ |
|
170 | propagatedBuildInputs = [ | |
169 | pkgs.pam |
|
171 | pkgs.pam | |
170 | ]; |
|
172 | ]; | |
|
173 | ||||
171 | # TODO: johbo: Check if this can be avoided, or transform into |
|
174 | # TODO: johbo: Check if this can be avoided, or transform into | |
172 | # a real patch |
|
175 | # a real patch | |
173 | patchPhase = '' |
|
176 | patchPhase = '' | |
174 | substituteInPlace pam.py \ |
|
177 | substituteInPlace pam.py \ | |
175 | --replace 'find_library("pam")' '"${pkgs.pam}/lib/libpam.so.0"' |
|
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 | "pyzmq" = super."pyzmq".override (attrs: { |
|
199 | "pyzmq" = super."pyzmq".override (attrs: { | |
180 | buildInputs = [ |
|
200 | buildInputs = [ | |
181 | pkgs.czmq |
|
201 | pkgs.czmq |
@@ -5,7 +5,7 b'' | |||||
5 |
|
5 | |||
6 | self: super: { |
|
6 | self: super: { | |
7 | "alembic" = super.buildPythonPackage { |
|
7 | "alembic" = super.buildPythonPackage { | |
8 |
name = "alembic-0. |
|
8 | name = "alembic-1.0.5"; | |
9 | doCheck = false; |
|
9 | doCheck = false; | |
10 | propagatedBuildInputs = [ |
|
10 | propagatedBuildInputs = [ | |
11 | self."sqlalchemy" |
|
11 | self."sqlalchemy" | |
@@ -14,8 +14,8 b' self: super: {' | |||||
14 | self."python-dateutil" |
|
14 | self."python-dateutil" | |
15 | ]; |
|
15 | ]; | |
16 | src = fetchurl { |
|
16 | src = fetchurl { | |
17 |
url = "https://files.pythonhosted.org/packages/ |
|
17 | url = "https://files.pythonhosted.org/packages/1c/65/b8e4f5b2f345bb13b5e0a3fddd892b0b3f0e8ad4880e954fdc6a50d00d84/alembic-1.0.5.tar.gz"; | |
18 | sha256 = "0bmkq6isjbmy4p7nxfvfpknjsx7rb3xn9g00169y891hcfkkxgc5"; |
|
18 | sha256 = "0rpjqp2iq6p49x1nli18ivak1izz547nnjxi110mzrgc1v7dxzz9"; | |
19 | }; |
|
19 | }; | |
20 | meta = { |
|
20 | meta = { | |
21 | license = [ pkgs.lib.licenses.mit ]; |
|
21 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -36,7 +36,7 b' self: super: {' | |||||
36 | }; |
|
36 | }; | |
37 | }; |
|
37 | }; | |
38 | "appenlight-client" = super.buildPythonPackage { |
|
38 | "appenlight-client" = super.buildPythonPackage { | |
39 |
name = "appenlight-client-0.6.2 |
|
39 | name = "appenlight-client-0.6.26"; | |
40 | doCheck = false; |
|
40 | doCheck = false; | |
41 | propagatedBuildInputs = [ |
|
41 | propagatedBuildInputs = [ | |
42 | self."webob" |
|
42 | self."webob" | |
@@ -44,8 +44,8 b' self: super: {' | |||||
44 | self."six" |
|
44 | self."six" | |
45 | ]; |
|
45 | ]; | |
46 | src = fetchurl { |
|
46 | src = fetchurl { | |
47 |
url = "https://files.pythonhosted.org/packages/fa |
|
47 | url = "https://files.pythonhosted.org/packages/2e/56/418fc10379b96e795ee39a15e69a730c222818af04c3821fa354eaa859ec/appenlight_client-0.6.26.tar.gz"; | |
48 | sha256 = "1r9l2rfg677nxhamdbyb9y4fs1zgy2dy1p19c68fnvqkxz40y627"; |
|
48 | sha256 = "0s9xw3sb8s3pk73k78nnq4jil3q4mk6bczfa1fmgfx61kdxl2712"; | |
49 | }; |
|
49 | }; | |
50 | meta = { |
|
50 | meta = { | |
51 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
51 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -146,15 +146,15 b' self: super: {' | |||||
146 | }; |
|
146 | }; | |
147 | }; |
|
147 | }; | |
148 | "bleach" = super.buildPythonPackage { |
|
148 | "bleach" = super.buildPythonPackage { | |
149 |
name = "bleach-2 |
|
149 | name = "bleach-3.0.2"; | |
150 | doCheck = false; |
|
150 | doCheck = false; | |
151 | propagatedBuildInputs = [ |
|
151 | propagatedBuildInputs = [ | |
152 | self."six" |
|
152 | self."six" | |
153 |
self." |
|
153 | self."webencodings" | |
154 | ]; |
|
154 | ]; | |
155 | src = fetchurl { |
|
155 | src = fetchurl { | |
156 |
url = "https://files.pythonhosted.org/packages/ |
|
156 | url = "https://files.pythonhosted.org/packages/ae/31/680afc7d44040004296a2d8f0584983c2f2386448cd9d0964197e6c1160e/bleach-3.0.2.tar.gz"; | |
157 | sha256 = "1n337zbdml6z6zia0b1qgv6xiddx3qlwmcg9vk2mk60jcxhmzs8f"; |
|
157 | sha256 = "06474zg7f73hv8h1xw2wcsmvn2ygj73zxgxxqg8zcx8ap1srdls8"; | |
158 | }; |
|
158 | }; | |
159 | meta = { |
|
159 | meta = { | |
160 | license = [ pkgs.lib.licenses.asl20 ]; |
|
160 | license = [ pkgs.lib.licenses.asl20 ]; | |
@@ -230,15 +230,16 b' self: super: {' | |||||
230 | }; |
|
230 | }; | |
231 | }; |
|
231 | }; | |
232 | "colander" = super.buildPythonPackage { |
|
232 | "colander" = super.buildPythonPackage { | |
233 |
name = "colander-1. |
|
233 | name = "colander-1.5.1"; | |
234 | doCheck = false; |
|
234 | doCheck = false; | |
235 | propagatedBuildInputs = [ |
|
235 | propagatedBuildInputs = [ | |
236 | self."translationstring" |
|
236 | self."translationstring" | |
237 | self."iso8601" |
|
237 | self."iso8601" | |
|
238 | self."enum34" | |||
238 | ]; |
|
239 | ]; | |
239 | src = fetchurl { |
|
240 | src = fetchurl { | |
240 |
url = "https://files.pythonhosted.org/packages/cc |
|
241 | url = "https://files.pythonhosted.org/packages/ec/d1/fcca811a0a692c69d27e36b4d11a73acb98b4bab48323442642b6fd4386d/colander-1.5.1.tar.gz"; | |
241 | sha256 = "0wjfphyr5aakv5hw73q287lbc15cbm0aardajv7i2mqf377rl3p2"; |
|
242 | sha256 = "18ah4cwwxnpm6qxi6x9ipy51dal4spd343h44s5wd01cnhgrwsyq"; | |
242 | }; |
|
243 | }; | |
243 | meta = { |
|
244 | meta = { | |
244 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
245 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
@@ -317,7 +318,7 b' self: super: {' | |||||
317 | }; |
|
318 | }; | |
318 | }; |
|
319 | }; | |
319 | "deform" = super.buildPythonPackage { |
|
320 | "deform" = super.buildPythonPackage { | |
320 |
name = "deform-2.0. |
|
321 | name = "deform-2.0.7"; | |
321 | doCheck = false; |
|
322 | doCheck = false; | |
322 | propagatedBuildInputs = [ |
|
323 | propagatedBuildInputs = [ | |
323 | self."chameleon" |
|
324 | self."chameleon" | |
@@ -328,11 +329,37 b' self: super: {' | |||||
328 | self."zope.deprecation" |
|
329 | self."zope.deprecation" | |
329 | ]; |
|
330 | ]; | |
330 | src = fetchurl { |
|
331 | src = fetchurl { | |
331 |
url = "https://files.pythonhosted.org/packages/ |
|
332 | url = "https://files.pythonhosted.org/packages/cf/a1/bc234527b8f181de9acd80e796483c00007658d1e32b7de78f1c2e004d9a/deform-2.0.7.tar.gz"; | |
332 | sha256 = "0ybg9zsnfac1kaxrjanmkjk0xaklf4d3piywxwr08l1cl1336kc7"; |
|
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 | meta = { |
|
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 | "docutils" = super.buildPythonPackage { |
|
365 | "docutils" = super.buildPythonPackage { | |
@@ -490,14 +517,14 b' self: super: {' | |||||
490 | }; |
|
517 | }; | |
491 | }; |
|
518 | }; | |
492 | "gevent" = super.buildPythonPackage { |
|
519 | "gevent" = super.buildPythonPackage { | |
493 |
name = "gevent-1.3. |
|
520 | name = "gevent-1.3.7"; | |
494 | doCheck = false; |
|
521 | doCheck = false; | |
495 | propagatedBuildInputs = [ |
|
522 | propagatedBuildInputs = [ | |
496 | self."greenlet" |
|
523 | self."greenlet" | |
497 | ]; |
|
524 | ]; | |
498 | src = fetchurl { |
|
525 | src = fetchurl { | |
499 |
url = "https://files.pythonhosted.org/packages/49 |
|
526 | url = "https://files.pythonhosted.org/packages/10/c1/9499b146bfa43aa4f1e0ed1bab1bd3209a4861d25650c11725036c731cf5/gevent-1.3.7.tar.gz"; | |
500 | sha256 = "1ih4k73dqz2zb561hda99vbanja3m6cdch3mgxxn1mla3qwkqhbv"; |
|
527 | sha256 = "0b0fr04qdk1p4sniv87fh8z5psac60x01pv054kpgi94520g81iz"; | |
501 | }; |
|
528 | }; | |
502 | meta = { |
|
529 | meta = { | |
503 | license = [ pkgs.lib.licenses.mit ]; |
|
530 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -547,27 +574,12 b' self: super: {' | |||||
547 | license = [ pkgs.lib.licenses.mit ]; |
|
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 | "hupper" = super.buildPythonPackage { |
|
577 | "hupper" = super.buildPythonPackage { | |
566 |
name = "hupper-1. |
|
578 | name = "hupper-1.4.2"; | |
567 | doCheck = false; |
|
579 | doCheck = false; | |
568 | src = fetchurl { |
|
580 | src = fetchurl { | |
569 | url = "https://files.pythonhosted.org/packages/cf/4b/467b826a84c8594b81f414b5ab6794e981951dac90ca40abaf9ea1cb36b0/hupper-1.3.1.tar.gz"; |
|
581 | url = "https://files.pythonhosted.org/packages/f1/75/1915dc7650b4867fa3049256e24ca8eddb5989998fcec788cf52b9812dfc/hupper-1.4.2.tar.gz"; | |
570 | sha256 = "03mf13n6i4dd60wlb9m99ddl4m3lmly70cjp7f82vdkibfl1v6l9"; |
|
582 | sha256 = "16vb9fkiaakdpcp6pn56h3w0dwvm67bxq2k2dv4i382qhqwphdzb"; | |
571 | }; |
|
583 | }; | |
572 | meta = { |
|
584 | meta = { | |
573 | license = [ pkgs.lib.licenses.mit ]; |
|
585 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -671,6 +683,20 b' self: super: {' | |||||
671 | license = [ pkgs.lib.licenses.mit ]; |
|
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 | "itsdangerous" = super.buildPythonPackage { |
|
700 | "itsdangerous" = super.buildPythonPackage { | |
675 | name = "itsdangerous-0.24"; |
|
701 | name = "itsdangerous-0.24"; | |
676 | doCheck = false; |
|
702 | doCheck = false; | |
@@ -756,11 +782,11 b' self: super: {' | |||||
756 | }; |
|
782 | }; | |
757 | }; |
|
783 | }; | |
758 | "lxml" = super.buildPythonPackage { |
|
784 | "lxml" = super.buildPythonPackage { | |
759 |
name = "lxml- |
|
785 | name = "lxml-4.2.5"; | |
760 | doCheck = false; |
|
786 | doCheck = false; | |
761 | src = fetchurl { |
|
787 | src = fetchurl { | |
762 | url = "https://files.pythonhosted.org/packages/39/e8/a8e0b1fa65dd021d48fe21464f71783655f39a41f218293c1c590d54eb82/lxml-3.7.3.tar.gz"; |
|
788 | url = "https://files.pythonhosted.org/packages/4b/20/ddf5eb3bd5c57582d2b4652b4bbcf8da301bdfe5d805cb94e805f4d7464d/lxml-4.2.5.tar.gz"; | |
763 | sha256 = "1iv1jgkqn1hdh1xyxri6g0y1s67h01jzjkw2nhkx3rqylmw2sl5a"; |
|
789 | sha256 = "0zw0y9hs0nflxhl9cs6ipwwh53szi3w2x06wl0k9cylyqac0cwin"; | |
764 | }; |
|
790 | }; | |
765 | meta = { |
|
791 | meta = { | |
766 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
792 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -990,11 +1016,11 b' self: super: {' | |||||
990 | }; |
|
1016 | }; | |
991 | }; |
|
1017 | }; | |
992 | "peppercorn" = super.buildPythonPackage { |
|
1018 | "peppercorn" = super.buildPythonPackage { | |
993 |
name = "peppercorn-0. |
|
1019 | name = "peppercorn-0.6"; | |
994 | doCheck = false; |
|
1020 | doCheck = false; | |
995 | src = fetchurl { |
|
1021 | src = fetchurl { | |
996 | url = "https://files.pythonhosted.org/packages/45/ec/a62ec317d1324a01567c5221b420742f094f05ee48097e5157d32be3755c/peppercorn-0.5.tar.gz"; |
|
1022 | url = "https://files.pythonhosted.org/packages/e4/77/93085de7108cdf1a0b092ff443872a8f9442c736d7ddebdf2f27627935f4/peppercorn-0.6.tar.gz"; | |
997 | sha256 = "0jvp144zn7yqk9kbpxc059167mlqk85i5lpvl1niw8gsa5fvl74j"; |
|
1023 | sha256 = "1ip4bfwcpwkq9hz2dai14k2cyabvwrnvcvrcmzxmqm04g8fnimwn"; | |
998 | }; |
|
1024 | }; | |
999 | meta = { |
|
1025 | meta = { | |
1000 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
1026 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
@@ -1139,15 +1165,15 b' self: super: {' | |||||
1139 | }; |
|
1165 | }; | |
1140 | }; |
|
1166 | }; | |
1141 | "py-gfm" = super.buildPythonPackage { |
|
1167 | "py-gfm" = super.buildPythonPackage { | |
1142 |
name = "py-gfm-0.1. |
|
1168 | name = "py-gfm-0.1.4"; | |
1143 | doCheck = false; |
|
1169 | doCheck = false; | |
1144 | propagatedBuildInputs = [ |
|
1170 | propagatedBuildInputs = [ | |
1145 | self."setuptools" |
|
1171 | self."setuptools" | |
1146 | self."markdown" |
|
1172 | self."markdown" | |
1147 | ]; |
|
1173 | ]; | |
1148 | src = fetchurl { |
|
1174 | src = fetchurl { | |
1149 |
url = "https://files.pythonhosted.org/packages/ |
|
1175 | url = "https://files.pythonhosted.org/packages/06/ee/004a03a1d92bb386dae44f6dd087db541bc5093374f1637d4d4ae5596cc2/py-gfm-0.1.4.tar.gz"; | |
1150 | sha256 = "162ggwwj0af9g3s1k8m4bfwbvis03x9pinnf35mj79pb90rf81zi"; |
|
1176 | sha256 = "0zip06g2isivx8fzgqd4n9qzsa22c25jas1rsb7m2rnjg72m0rzg"; | |
1151 | }; |
|
1177 | }; | |
1152 | meta = { |
|
1178 | meta = { | |
1153 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1179 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1212,11 +1238,11 b' self: super: {' | |||||
1212 | }; |
|
1238 | }; | |
1213 | }; |
|
1239 | }; | |
1214 | "pygments" = super.buildPythonPackage { |
|
1240 | "pygments" = super.buildPythonPackage { | |
1215 |
name = "pygments-2. |
|
1241 | name = "pygments-2.3.0"; | |
1216 | doCheck = false; |
|
1242 | doCheck = false; | |
1217 | src = fetchurl { |
|
1243 | src = fetchurl { | |
1218 |
url = "https://files.pythonhosted.org/packages/ |
|
1244 | url = "https://files.pythonhosted.org/packages/63/a2/91c31c4831853dedca2a08a0f94d788fc26a48f7281c99a303769ad2721b/Pygments-2.3.0.tar.gz"; | |
1219 | sha256 = "1k78qdvir1yb1c634nkv6rbga8wv4289xarghmsbbvzhvr311bnv"; |
|
1245 | sha256 = "1z34ms51dh4jq4h3cizp7vd1dmsxcbvffkjsd2xxfav22nn6lrl2"; | |
1220 | }; |
|
1246 | }; | |
1221 | meta = { |
|
1247 | meta = { | |
1222 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1248 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1248,14 +1274,14 b' self: super: {' | |||||
1248 | }; |
|
1274 | }; | |
1249 | }; |
|
1275 | }; | |
1250 | "pyotp" = super.buildPythonPackage { |
|
1276 | "pyotp" = super.buildPythonPackage { | |
1251 |
name = "pyotp-2.2. |
|
1277 | name = "pyotp-2.2.7"; | |
1252 | doCheck = false; |
|
1278 | doCheck = false; | |
1253 | src = fetchurl { |
|
1279 | src = fetchurl { | |
1254 |
url = "https://files.pythonhosted.org/packages/67 |
|
1280 | url = "https://files.pythonhosted.org/packages/b1/ab/477cda97b6ca7baced5106471cb1ac1fe698d1b035983b9f8ee3422989eb/pyotp-2.2.7.tar.gz"; | |
1255 | sha256 = "0sdxxvr3j4j0pk26v258jpxhgpbnpmyqhvzhl24hsd50j7fk14fx"; |
|
1281 | sha256 = "00p69nw431f0s2ilg0hnd77p1l22m06p9rq4f8zfapmavnmzw3xy"; | |
1256 | }; |
|
1282 | }; | |
1257 | meta = { |
|
1283 | meta = { | |
1258 |
license = [ pkgs.lib.licenses. |
|
1284 | license = [ pkgs.lib.licenses.mit ]; | |
1259 | }; |
|
1285 | }; | |
1260 | }; |
|
1286 | }; | |
1261 | "pyparsing" = super.buildPythonPackage { |
|
1287 | "pyparsing" = super.buildPythonPackage { | |
@@ -1479,14 +1505,14 b' self: super: {' | |||||
1479 | }; |
|
1505 | }; | |
1480 | }; |
|
1506 | }; | |
1481 | "python-dateutil" = super.buildPythonPackage { |
|
1507 | "python-dateutil" = super.buildPythonPackage { | |
1482 |
name = "python-dateutil-2.7. |
|
1508 | name = "python-dateutil-2.7.5"; | |
1483 | doCheck = false; |
|
1509 | doCheck = false; | |
1484 | propagatedBuildInputs = [ |
|
1510 | propagatedBuildInputs = [ | |
1485 | self."six" |
|
1511 | self."six" | |
1486 | ]; |
|
1512 | ]; | |
1487 | src = fetchurl { |
|
1513 | src = fetchurl { | |
1488 | url = "https://files.pythonhosted.org/packages/a0/b0/a4e3241d2dee665fea11baec21389aec6886655cd4db7647ddf96c3fad15/python-dateutil-2.7.3.tar.gz"; |
|
1514 | url = "https://files.pythonhosted.org/packages/0e/01/68747933e8d12263d41ce08119620d9a7e5eb72c876a3442257f74490da0/python-dateutil-2.7.5.tar.gz"; | |
1489 | sha256 = "1f7h54lg0w2ckch7592xpjkh8dg87k2br256h0iw49zn6bg02w72"; |
|
1515 | sha256 = "00ngwcdw36w5b37b51mdwn3qxid9zdf3kpffv2q6n9kl05y2iyc8"; | |
1490 | }; |
|
1516 | }; | |
1491 | meta = { |
|
1517 | meta = { | |
1492 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.asl20 { fullName = "Dual License"; } ]; |
|
1518 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.asl20 { fullName = "Dual License"; } ]; | |
@@ -1543,6 +1569,22 b' self: super: {' | |||||
1543 | license = [ { fullName = "License :: OSI Approved :: MIT License"; } pkgs.lib.licenses.mit ]; |
|
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 | "pytz" = super.buildPythonPackage { |
|
1588 | "pytz" = super.buildPythonPackage { | |
1547 | name = "pytz-2018.4"; |
|
1589 | name = "pytz-2018.4"; | |
1548 | doCheck = false; |
|
1590 | doCheck = false; | |
@@ -1615,7 +1657,7 b' self: super: {' | |||||
1615 | }; |
|
1657 | }; | |
1616 | }; |
|
1658 | }; | |
1617 | "rhodecode-enterprise-ce" = super.buildPythonPackage { |
|
1659 | "rhodecode-enterprise-ce" = super.buildPythonPackage { | |
1618 |
name = "rhodecode-enterprise-ce-4.1 |
|
1660 | name = "rhodecode-enterprise-ce-4.15.0"; | |
1619 | buildInputs = [ |
|
1661 | buildInputs = [ | |
1620 | self."pytest" |
|
1662 | self."pytest" | |
1621 | self."py" |
|
1663 | self."py" | |
@@ -1640,6 +1682,7 b' self: super: {' | |||||
1640 | self."attrs" |
|
1682 | self."attrs" | |
1641 | self."babel" |
|
1683 | self."babel" | |
1642 | self."beaker" |
|
1684 | self."beaker" | |
|
1685 | self."bleach" | |||
1643 | self."celery" |
|
1686 | self."celery" | |
1644 | self."chameleon" |
|
1687 | self."chameleon" | |
1645 | self."channelstream" |
|
1688 | self."channelstream" | |
@@ -1668,8 +1711,6 b' self: super: {' | |||||
1668 | self."markdown" |
|
1711 | self."markdown" | |
1669 | self."markupsafe" |
|
1712 | self."markupsafe" | |
1670 | self."msgpack-python" |
|
1713 | self."msgpack-python" | |
1671 | self."mysql-python" |
|
|||
1672 | self."pymysql" |
|
|||
1673 | self."pyotp" |
|
1714 | self."pyotp" | |
1674 | self."packaging" |
|
1715 | self."packaging" | |
1675 | self."paste" |
|
1716 | self."paste" | |
@@ -1678,7 +1719,6 b' self: super: {' | |||||
1678 | self."pathlib2" |
|
1719 | self."pathlib2" | |
1679 | self."peppercorn" |
|
1720 | self."peppercorn" | |
1680 | self."psutil" |
|
1721 | self."psutil" | |
1681 | self."psycopg2" |
|
|||
1682 | self."py-bcrypt" |
|
1722 | self."py-bcrypt" | |
1683 | self."pycrypto" |
|
1723 | self."pycrypto" | |
1684 | self."pycurl" |
|
1724 | self."pycurl" | |
@@ -1692,11 +1732,11 b' self: super: {' | |||||
1692 | self."pyramid-mako" |
|
1732 | self."pyramid-mako" | |
1693 | self."pyramid" |
|
1733 | self."pyramid" | |
1694 | self."pyramid-mailer" |
|
1734 | self."pyramid-mailer" | |
1695 | self."pysqlite" |
|
|||
1696 | self."python-dateutil" |
|
1735 | self."python-dateutil" | |
1697 | self."python-ldap" |
|
1736 | self."python-ldap" | |
1698 | self."python-memcached" |
|
1737 | self."python-memcached" | |
1699 | self."python-pam" |
|
1738 | self."python-pam" | |
|
1739 | self."python-saml" | |||
1700 | self."pytz" |
|
1740 | self."pytz" | |
1701 | self."tzlocal" |
|
1741 | self."tzlocal" | |
1702 | self."pyzmq" |
|
1742 | self."pyzmq" | |
@@ -1713,7 +1753,6 b' self: super: {' | |||||
1713 | self."supervisor" |
|
1753 | self."supervisor" | |
1714 | self."tempita" |
|
1754 | self."tempita" | |
1715 | self."translationstring" |
|
1755 | self."translationstring" | |
1716 | self."trollius" |
|
|||
1717 | self."urllib3" |
|
1756 | self."urllib3" | |
1718 | self."urlobject" |
|
1757 | self."urlobject" | |
1719 | self."venusian" |
|
1758 | self."venusian" | |
@@ -1727,8 +1766,11 b' self: super: {' | |||||
1727 | self."zope.deprecation" |
|
1766 | self."zope.deprecation" | |
1728 | self."zope.event" |
|
1767 | self."zope.event" | |
1729 | self."zope.interface" |
|
1768 | self."zope.interface" | |
|
1769 | self."mysql-python" | |||
|
1770 | self."pymysql" | |||
|
1771 | self."pysqlite" | |||
|
1772 | self."psycopg2" | |||
1730 | self."nbconvert" |
|
1773 | self."nbconvert" | |
1731 | self."bleach" |
|
|||
1732 | self."nbformat" |
|
1774 | self."nbformat" | |
1733 | self."jupyter-client" |
|
1775 | self."jupyter-client" | |
1734 | self."alembic" |
|
1776 | self."alembic" | |
@@ -1822,11 +1864,11 b' self: super: {' | |||||
1822 | }; |
|
1864 | }; | |
1823 | }; |
|
1865 | }; | |
1824 | "setuptools" = super.buildPythonPackage { |
|
1866 | "setuptools" = super.buildPythonPackage { | |
1825 |
name = "setuptools-40. |
|
1867 | name = "setuptools-40.6.2"; | |
1826 | doCheck = false; |
|
1868 | doCheck = false; | |
1827 | src = fetchurl { |
|
1869 | src = fetchurl { | |
1828 |
url = "https://files.pythonhosted.org/packages/6 |
|
1870 | url = "https://files.pythonhosted.org/packages/b0/d1/8acb42f391cba52e35b131e442e80deffbb8d0676b93261d761b1f0ef8fb/setuptools-40.6.2.zip"; | |
1829 | sha256 = "058v6zns4634n4al2nmmvp15j8nrgwn8wjrbdks47wk3vm05gg5c"; |
|
1871 | sha256 = "0r2c5hapirlzm34h7pl1lgkm6gk7bcrlrdj28qgsvaqg3f74vfw6"; | |
1830 | }; |
|
1872 | }; | |
1831 | meta = { |
|
1873 | meta = { | |
1832 | license = [ pkgs.lib.licenses.mit ]; |
|
1874 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -2002,20 +2044,6 b' self: super: {' | |||||
2002 | license = [ { fullName = "BSD-like (http://repoze.org/license.html)"; } ]; |
|
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 | "tzlocal" = super.buildPythonPackage { |
|
2047 | "tzlocal" = super.buildPythonPackage { | |
2020 | name = "tzlocal-1.5.1"; |
|
2048 | name = "tzlocal-1.5.1"; | |
2021 | doCheck = false; |
|
2049 | doCheck = false; |
@@ -32,6 +32,11 b' pkgs.stdenv.mkDerivation {' | |||||
32 | # We need postgresql to be around |
|
32 | # We need postgresql to be around | |
33 | pkgs.postgresql |
|
33 | pkgs.postgresql | |
34 |
|
34 | |||
|
35 | # we need the below for saml | |||
|
36 | pkgs.libxml2 | |||
|
37 | pkgs.libxslt | |||
|
38 | pkgs.xmlsec | |||
|
39 | ||||
35 | # Curl is needed for pycurl |
|
40 | # Curl is needed for pycurl | |
36 | pkgs.curl |
|
41 | pkgs.curl | |
37 | ]; |
|
42 | ]; |
@@ -8,16 +8,17 b' atomicwrites==1.2.1' | |||||
8 | attrs==18.2.0 |
|
8 | attrs==18.2.0 | |
9 | babel==1.3 |
|
9 | babel==1.3 | |
10 | beaker==1.9.1 |
|
10 | beaker==1.9.1 | |
|
11 | bleach==3.0.2 | |||
11 | celery==4.1.1 |
|
12 | celery==4.1.1 | |
12 | chameleon==2.24 |
|
13 | chameleon==2.24 | |
13 | channelstream==0.5.2 |
|
14 | channelstream==0.5.2 | |
14 | click==6.6 |
|
15 | click==6.6 | |
15 |
colander==1. |
|
16 | colander==1.5.1 | |
16 | # our custom configobj |
|
17 | # our custom configobj | |
17 | https://code.rhodecode.com/upstream/configobj/archive/a11ff0a0bd4fbda9e3a91267e720f88329efb4a6.tar.gz?md5=9916c524ea11a6c418217af6b28d4b3c#egg=configobj==5.0.6 |
|
18 | https://code.rhodecode.com/upstream/configobj/archive/a11ff0a0bd4fbda9e3a91267e720f88329efb4a6.tar.gz?md5=9916c524ea11a6c418217af6b28d4b3c#egg=configobj==5.0.6 | |
18 | cssselect==1.0.3 |
|
19 | cssselect==1.0.3 | |
19 | decorator==4.1.2 |
|
20 | decorator==4.1.2 | |
20 |
deform==2.0. |
|
21 | deform==2.0.7 | |
21 | docutils==0.14.0 |
|
22 | docutils==0.14.0 | |
22 | dogpile.cache==0.6.7 |
|
23 | dogpile.cache==0.6.7 | |
23 | dogpile.core==0.4.1 |
|
24 | dogpile.core==0.4.1 | |
@@ -32,28 +33,25 b' itsdangerous==0.24' | |||||
32 | jinja2==2.9.6 |
|
33 | jinja2==2.9.6 | |
33 | billiard==3.5.0.3 |
|
34 | billiard==3.5.0.3 | |
34 | kombu==4.2.0 |
|
35 | kombu==4.2.0 | |
35 |
lxml== |
|
36 | lxml==4.2.5 | |
36 | mako==1.0.7 |
|
37 | mako==1.0.7 | |
37 | markdown==2.6.11 |
|
38 | markdown==2.6.11 | |
38 | markupsafe==1.0.0 |
|
39 | markupsafe==1.0.0 | |
39 | msgpack-python==0.5.6 |
|
40 | msgpack-python==0.5.6 | |
40 | mysql-python==1.2.5 |
|
41 | pyotp==2.2.7 | |
41 | pymysql==0.8.1 |
|
|||
42 | pyotp==2.2.6 |
|
|||
43 | packaging==15.2 |
|
42 | packaging==15.2 | |
44 | paste==2.0.3 |
|
43 | paste==2.0.3 | |
45 | pastedeploy==1.5.2 |
|
44 | pastedeploy==1.5.2 | |
46 | pastescript==2.0.2 |
|
45 | pastescript==2.0.2 | |
47 | pathlib2==2.3.2 |
|
46 | pathlib2==2.3.2 | |
48 |
peppercorn==0. |
|
47 | peppercorn==0.6 | |
49 | psutil==5.4.7 |
|
48 | psutil==5.4.7 | |
50 | psycopg2==2.7.5 |
|
|||
51 | py-bcrypt==0.4 |
|
49 | py-bcrypt==0.4 | |
52 | pycrypto==2.6.1 |
|
50 | pycrypto==2.6.1 | |
53 | pycurl==7.43.0.2 |
|
51 | pycurl==7.43.0.2 | |
54 | pyflakes==0.8.1 |
|
52 | pyflakes==0.8.1 | |
55 | pygments-markdown-lexer==0.1.0.dev39 |
|
53 | pygments-markdown-lexer==0.1.0.dev39 | |
56 |
pygments==2. |
|
54 | pygments==2.3.0 | |
57 | pyparsing==1.5.7 |
|
55 | pyparsing==1.5.7 | |
58 | pyramid-beaker==0.8 |
|
56 | pyramid-beaker==0.8 | |
59 | pyramid-debugtoolbar==4.4.0 |
|
57 | pyramid-debugtoolbar==4.4.0 | |
@@ -61,15 +59,15 b' pyramid-jinja2==2.7' | |||||
61 | pyramid-mako==1.0.2 |
|
59 | pyramid-mako==1.0.2 | |
62 | pyramid==1.9.2 |
|
60 | pyramid==1.9.2 | |
63 | pyramid_mailer==0.15.1 |
|
61 | pyramid_mailer==0.15.1 | |
64 | pysqlite==2.8.3 |
|
|||
65 | python-dateutil |
|
62 | python-dateutil | |
66 | python-ldap==3.1.0 |
|
63 | python-ldap==3.1.0 | |
67 | python-memcached==1.59 |
|
64 | python-memcached==1.59 | |
68 | python-pam==1.8.4 |
|
65 | python-pam==1.8.4 | |
|
66 | python-saml | |||
69 | pytz==2018.4 |
|
67 | pytz==2018.4 | |
70 | tzlocal==1.5.1 |
|
68 | tzlocal==1.5.1 | |
71 | pyzmq==14.6.0 |
|
69 | pyzmq==14.6.0 | |
72 |
py-gfm==0.1. |
|
70 | py-gfm==0.1.4 | |
73 | redis==2.10.6 |
|
71 | redis==2.10.6 | |
74 | repoze.lru==0.7 |
|
72 | repoze.lru==0.7 | |
75 | requests==2.9.1 |
|
73 | requests==2.9.1 | |
@@ -82,7 +80,6 b' subprocess32==3.5.2' | |||||
82 | supervisor==3.3.4 |
|
80 | supervisor==3.3.4 | |
83 | tempita==0.5.2 |
|
81 | tempita==0.5.2 | |
84 | translationstring==1.3 |
|
82 | translationstring==1.3 | |
85 | trollius==1.0.4 |
|
|||
86 | urllib3==1.21 |
|
83 | urllib3==1.21 | |
87 | urlobject==2.4.3 |
|
84 | urlobject==2.4.3 | |
88 | venusian==1.1.0 |
|
85 | venusian==1.1.0 | |
@@ -97,22 +94,26 b' zope.deprecation==4.3.0' | |||||
97 | zope.event==4.3.0 |
|
94 | zope.event==4.3.0 | |
98 | zope.interface==4.5.0 |
|
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 | # IPYTHON RENDERING |
|
103 | # IPYTHON RENDERING | |
102 | # entrypoints backport, pypi version doesn't support egg installs |
|
104 | # entrypoints backport, pypi version doesn't support egg installs | |
103 | https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1 |
|
105 | https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1 | |
104 | nbconvert==5.3.1 |
|
106 | nbconvert==5.3.1 | |
105 | bleach==2.1.4 |
|
|||
106 | nbformat==4.4.0 |
|
107 | nbformat==4.4.0 | |
107 | jupyter_client==5.0.0 |
|
108 | jupyter_client==5.0.0 | |
108 |
|
109 | |||
109 | ## cli tools |
|
110 | ## cli tools | |
110 |
alembic== |
|
111 | alembic==1.0.5 | |
111 | invoke==0.13.0 |
|
112 | invoke==0.13.0 | |
112 | bumpversion==0.5.3 |
|
113 | bumpversion==0.5.3 | |
113 |
|
114 | |||
114 | ## http servers |
|
115 | ## http servers | |
115 |
gevent==1.3. |
|
116 | gevent==1.3.7 | |
116 | greenlet==0.4.15 |
|
117 | greenlet==0.4.15 | |
117 | gunicorn==19.9.0 |
|
118 | gunicorn==19.9.0 | |
118 | waitress==1.1.0 |
|
119 | waitress==1.1.0 | |
@@ -126,7 +127,7 b' ipython==5.1.0' | |||||
126 | https://code.rhodecode.com/rhodecode-tools-ce/archive/v1.0.1.tar.gz?md5=ffb5d6bcb855305b93cfe23ad42e500b#egg=rhodecode-tools==1.0.1 |
|
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 | ## appenlight |
|
129 | ## appenlight | |
129 |
appenlight-client==0.6.2 |
|
130 | appenlight-client==0.6.26 | |
130 |
|
131 | |||
131 | ## test related requirements |
|
132 | ## test related requirements | |
132 | -r requirements_test.txt |
|
133 | -r requirements_test.txt |
@@ -66,7 +66,7 b' class TestCreatePullRequestApi(object):' | |||||
66 | expected_message = "Created new pull request `{title}`".format( |
|
66 | expected_message = "Created new pull request `{title}`".format( | |
67 | title=data['title']) |
|
67 | title=data['title']) | |
68 | result = response.json |
|
68 | result = response.json | |
69 |
assert result['error'] |
|
69 | assert result['error'] is None | |
70 | assert result['result']['msg'] == expected_message |
|
70 | assert result['result']['msg'] == expected_message | |
71 | pull_request_id = result['result']['pull_request_id'] |
|
71 | pull_request_id = result['result']['pull_request_id'] | |
72 | pull_request = PullRequestModel().get(pull_request_id) |
|
72 | pull_request = PullRequestModel().get(pull_request_id) | |
@@ -89,7 +89,7 b' class TestCreatePullRequestApi(object):' | |||||
89 | expected_message = "Created new pull request `{title}`".format( |
|
89 | expected_message = "Created new pull request `{title}`".format( | |
90 | title=data['title']) |
|
90 | title=data['title']) | |
91 | result = response.json |
|
91 | result = response.json | |
92 |
assert result['error'] |
|
92 | assert result['error'] is None | |
93 | assert result['result']['msg'] == expected_message |
|
93 | assert result['result']['msg'] == expected_message | |
94 | pull_request_id = result['result']['pull_request_id'] |
|
94 | pull_request_id = result['result']['pull_request_id'] | |
95 | pull_request = PullRequestModel().get(pull_request_id) |
|
95 | pull_request = PullRequestModel().get(pull_request_id) | |
@@ -129,7 +129,7 b' class TestCreatePullRequestApi(object):' | |||||
129 | expected_message = "Created new pull request `{title}`".format( |
|
129 | expected_message = "Created new pull request `{title}`".format( | |
130 | title=data['title']) |
|
130 | title=data['title']) | |
131 | result = response.json |
|
131 | result = response.json | |
132 |
assert result['error'] |
|
132 | assert result['error'] is None | |
133 | assert result['result']['msg'] == expected_message |
|
133 | assert result['result']['msg'] == expected_message | |
134 | pull_request_id = result['result']['pull_request_id'] |
|
134 | pull_request_id = result['result']['pull_request_id'] | |
135 | pull_request = PullRequestModel().get(pull_request_id) |
|
135 | pull_request = PullRequestModel().get(pull_request_id) | |
@@ -144,11 +144,15 b' class TestCreatePullRequestApi(object):' | |||||
144 | entry['mandatory'] = rev.mandatory |
|
144 | entry['mandatory'] = rev.mandatory | |
145 | actual_reviewers.append(entry) |
|
145 | actual_reviewers.append(entry) | |
146 |
|
146 | |||
147 | # default reviewer will be added who is an owner of the repo |
|
147 | owner_username = pull_request.target_repo.user.username | |
148 | reviewers.append( |
|
148 | for spec_reviewer in reviewers[::]: | |
149 | {'username': pull_request.author.username, |
|
149 | # default reviewer will be added who is an owner of the repo | |
150 | 'reasons': [u'Default reviewer', u'Repository owner']}, |
|
150 | # this get's overridden by a add owner to reviewers rule | |
151 | ) |
|
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 | assert sorted(actual_reviewers, key=lambda e: e['username']) \ |
|
156 | assert sorted(actual_reviewers, key=lambda e: e['username']) \ | |
153 | == sorted(reviewers, key=lambda e: e['username']) |
|
157 | == sorted(reviewers, key=lambda e: e['username']) | |
154 |
|
158 | |||
@@ -173,7 +177,7 b' class TestCreatePullRequestApi(object):' | |||||
173 | expected_message = "Created new pull request `{title}`".format( |
|
177 | expected_message = "Created new pull request `{title}`".format( | |
174 | title=data['title']) |
|
178 | title=data['title']) | |
175 | result = response.json |
|
179 | result = response.json | |
176 |
assert result['error'] |
|
180 | assert result['error'] is None | |
177 | assert result['result']['msg'] == expected_message |
|
181 | assert result['result']['msg'] == expected_message | |
178 | pull_request_id = result['result']['pull_request_id'] |
|
182 | pull_request_id = result['result']['pull_request_id'] | |
179 | pull_request = PullRequestModel().get(pull_request_id) |
|
183 | pull_request = PullRequestModel().get(pull_request_id) | |
@@ -187,11 +191,14 b' class TestCreatePullRequestApi(object):' | |||||
187 | if rev.mandatory: |
|
191 | if rev.mandatory: | |
188 | entry['mandatory'] = rev.mandatory |
|
192 | entry['mandatory'] = rev.mandatory | |
189 | actual_reviewers.append(entry) |
|
193 | actual_reviewers.append(entry) | |
190 | # default reviewer will be added who is an owner of the repo |
|
194 | ||
191 | reviewers.append( |
|
195 | owner_user_id = pull_request.target_repo.user.user_id | |
192 | {'username': pull_request.author.user_id, |
|
196 | for spec_reviewer in reviewers[::]: | |
193 | 'reasons': [u'Default reviewer', u'Repository owner']}, |
|
197 | # default reviewer will be added who is an owner of the repo | |
194 | ) |
|
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 | assert sorted(actual_reviewers, key=lambda e: e['username']) \ |
|
202 | assert sorted(actual_reviewers, key=lambda e: e['username']) \ | |
196 | == sorted(reviewers, key=lambda e: e['username']) |
|
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 |
|
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 | from zope.interface import implementer |
|
25 | from zope.interface import implementer | |
26 |
|
26 | |||
27 |
from rhodecode.apps. |
|
27 | from rhodecode.apps._base.interfaces import IAdminNavigationRegistry | |
28 | from rhodecode.lib.utils2 import str2bool |
|
28 | from rhodecode.lib.utils2 import str2bool | |
29 | from rhodecode.translation import _ |
|
29 | from rhodecode.translation import _ | |
30 |
|
30 | |||
@@ -117,10 +117,11 b' class NavigationRegistry(object):' | |||||
117 | self._registered_entries[entry.key] = entry |
|
117 | self._registered_entries[entry.key] = entry | |
118 |
|
118 | |||
119 | def get_navlist(self, request): |
|
119 | def get_navlist(self, request): | |
120 | navlist = [NavListEntry(i.key, i.get_localized_name(request), |
|
120 | nav_list = [ | |
121 | i.generate_url(request), i.active_list) |
|
121 | NavListEntry(i.key, i.get_localized_name(request), | |
122 | for i in self._registered_entries.values()] |
|
122 | i.generate_url(request), i.active_list) | |
123 | return navlist |
|
123 | for i in self._registered_entries.values()] | |
|
124 | return nav_list | |||
124 |
|
125 | |||
125 |
|
126 | |||
126 | def navigation_registry(request, registry=None): |
|
127 | def navigation_registry(request, registry=None): | |
@@ -143,5 +144,5 b' def includeme(config):' | |||||
143 | # Create admin navigation registry and add it to the pyramid registry. |
|
144 | # Create admin navigation registry and add it to the pyramid registry. | |
144 | settings = config.get_settings() |
|
145 | settings = config.get_settings() | |
145 | labs_active = str2bool(settings.get('labs_settings_active', False)) |
|
146 | labs_active = str2bool(settings.get('labs_settings_active', False)) | |
146 | navigation_registry = NavigationRegistry(labs_active=labs_active) |
|
147 | navigation_registry_instance = NavigationRegistry(labs_active=labs_active) | |
147 | config.registry.registerUtility(navigation_registry) No newline at end of file |
|
148 | config.registry.registerUtility(navigation_registry_instance) |
1 | NO CONTENT: file renamed from rhodecode/apps/admin/subscribers.py to rhodecode/apps/_base/subscribers.py |
|
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 | def includeme(config): |
|
431 | def includeme(config): | |
432 |
from rhodecode.apps. |
|
432 | from rhodecode.apps._base.navigation import includeme as nav_includeme | |
433 |
|
433 | |||
434 | # Create admin navigation registry and add it to the pyramid registry. |
|
434 | # Create admin navigation registry and add it to the pyramid registry. | |
435 | nav_includeme(config) |
|
435 | nav_includeme(config) | |
@@ -438,7 +438,5 b' def includeme(config):' | |||||
438 | config.add_route(name='admin_home', pattern=ADMIN_PREFIX) |
|
438 | config.add_route(name='admin_home', pattern=ADMIN_PREFIX) | |
439 | config.include(admin_routes, route_prefix=ADMIN_PREFIX) |
|
439 | config.include(admin_routes, route_prefix=ADMIN_PREFIX) | |
440 |
|
440 | |||
441 | config.include('.subscribers') |
|
|||
442 |
|
||||
443 | # Scan module for configuration decorators. |
|
441 | # Scan module for configuration decorators. | |
444 | config.scan('.views', ignore='.tests') |
|
442 | config.scan('.views', ignore='.tests') |
@@ -89,7 +89,7 b' class TestAuthSettingsView(object):' | |||||
89 | 'timeout': 3600, |
|
89 | 'timeout': 3600, | |
90 | 'tls_kind': 'PLAIN', |
|
90 | 'tls_kind': 'PLAIN', | |
91 | 'tls_reqcert': 'NEVER', |
|
91 | 'tls_reqcert': 'NEVER', | |
92 |
|
92 | 'tls_cert_dir':'/etc/openldap/cacerts', | ||
93 | 'dn_user': 'test_user', |
|
93 | 'dn_user': 'test_user', | |
94 | 'dn_pass': 'test_pass', |
|
94 | 'dn_pass': 'test_pass', | |
95 | 'base_dn': 'test_base_dn', |
|
95 | 'base_dn': 'test_base_dn', |
@@ -24,7 +24,7 b' from pyramid.httpexceptions import HTTPF' | |||||
24 | from pyramid.view import view_config |
|
24 | from pyramid.view import view_config | |
25 |
|
25 | |||
26 | from rhodecode.apps._base import BaseAppView |
|
26 | from rhodecode.apps._base import BaseAppView | |
27 |
from rhodecode.apps. |
|
27 | from rhodecode.apps._base.navigation import navigation_list | |
28 | from rhodecode.lib import helpers as h |
|
28 | from rhodecode.lib import helpers as h | |
29 | from rhodecode.lib.auth import ( |
|
29 | from rhodecode.lib.auth import ( | |
30 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
|
30 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
@@ -24,7 +24,7 b' import logging' | |||||
24 | from pyramid.view import view_config |
|
24 | from pyramid.view import view_config | |
25 |
|
25 | |||
26 | from rhodecode.apps._base import BaseAppView |
|
26 | from rhodecode.apps._base import BaseAppView | |
27 |
from rhodecode.apps. |
|
27 | from rhodecode.apps._base.navigation import navigation_list | |
28 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) |
|
28 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) | |
29 | from rhodecode.lib.utils import read_opensource_licenses |
|
29 | from rhodecode.lib.utils import read_opensource_licenses | |
30 |
|
30 |
@@ -25,7 +25,7 b' import signal' | |||||
25 | from pyramid.view import view_config |
|
25 | from pyramid.view import view_config | |
26 |
|
26 | |||
27 | from rhodecode.apps._base import BaseAppView |
|
27 | from rhodecode.apps._base import BaseAppView | |
28 |
from rhodecode.apps. |
|
28 | from rhodecode.apps._base.navigation import navigation_list | |
29 | from rhodecode.lib import system_info |
|
29 | from rhodecode.lib import system_info | |
30 | from rhodecode.lib.auth import ( |
|
30 | from rhodecode.lib.auth import ( | |
31 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
|
31 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
@@ -24,7 +24,7 b' from pyramid.view import view_config' | |||||
24 | from pyramid.httpexceptions import HTTPFound |
|
24 | from pyramid.httpexceptions import HTTPFound | |
25 |
|
25 | |||
26 | from rhodecode.apps._base import BaseAppView |
|
26 | from rhodecode.apps._base import BaseAppView | |
27 |
from rhodecode.apps. |
|
27 | from rhodecode.apps._base.navigation import navigation_list | |
28 | from rhodecode.lib.auth import ( |
|
28 | from rhodecode.lib.auth import ( | |
29 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) |
|
29 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |
30 | from rhodecode.lib.utils2 import safe_int |
|
30 | from rhodecode.lib.utils2 import safe_int |
@@ -33,7 +33,7 b' from pyramid.renderers import render' | |||||
33 | from pyramid.response import Response |
|
33 | from pyramid.response import Response | |
34 |
|
34 | |||
35 | from rhodecode.apps._base import BaseAppView |
|
35 | from rhodecode.apps._base import BaseAppView | |
36 |
from rhodecode.apps. |
|
36 | from rhodecode.apps._base.navigation import navigation_list | |
37 | from rhodecode.apps.svn_support.config_keys import generate_config |
|
37 | from rhodecode.apps.svn_support.config_keys import generate_config | |
38 | from rhodecode.lib import helpers as h |
|
38 | from rhodecode.lib import helpers as h | |
39 | from rhodecode.lib.auth import ( |
|
39 | from rhodecode.lib.auth import ( | |
@@ -175,8 +175,7 b' class AdminSettingsView(BaseAppView):' | |||||
175 |
|
175 | |||
176 | try: |
|
176 | try: | |
177 | if c.visual.allow_repo_location_change: |
|
177 | if c.visual.allow_repo_location_change: | |
178 | model.update_global_path_setting( |
|
178 | model.update_global_path_setting(form_result['paths_root_path']) | |
179 | form_result['paths_root_path']) |
|
|||
180 |
|
179 | |||
181 | model.update_global_ssl_setting(form_result['web_push_ssl']) |
|
180 | model.update_global_ssl_setting(form_result['web_push_ssl']) | |
182 | model.update_global_hook_settings(form_result) |
|
181 | model.update_global_hook_settings(form_result) |
@@ -25,7 +25,7 b' from pyramid.view import view_config' | |||||
25 |
|
25 | |||
26 | import rhodecode |
|
26 | import rhodecode | |
27 | from rhodecode.apps._base import BaseAppView |
|
27 | from rhodecode.apps._base import BaseAppView | |
28 |
from rhodecode.apps. |
|
28 | from rhodecode.apps._base.navigation import navigation_list | |
29 | from rhodecode.lib import helpers as h |
|
29 | from rhodecode.lib import helpers as h | |
30 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) |
|
30 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) | |
31 | from rhodecode.lib.utils2 import str2bool |
|
31 | from rhodecode.lib.utils2 import str2bool | |
@@ -96,6 +96,7 b' class AdminSystemInfoSettingsView(BaseAp' | |||||
96 | # RhodeCode specific |
|
96 | # RhodeCode specific | |
97 | (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')), |
|
97 | (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')), | |
98 | (_('Latest version'), version, update_state), |
|
98 | (_('Latest version'), version, update_state), | |
|
99 | (_('RhodeCode Base URL'), val('rhodecode_config')['config'].get('app.base_url'), state('rhodecode_config')), | |||
99 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), |
|
100 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), | |
100 | (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), |
|
101 | (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), | |
101 | (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), |
|
102 | (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), |
@@ -185,7 +185,7 b' class AdminUsersView(BaseAppView, DataGr' | |||||
185 | def users_new(self): |
|
185 | def users_new(self): | |
186 | _ = self.request.translate |
|
186 | _ = self.request.translate | |
187 | c = self.load_default_context() |
|
187 | c = self.load_default_context() | |
188 |
c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin. |
|
188 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
189 | self._set_personal_repo_group_template_vars(c) |
|
189 | self._set_personal_repo_group_template_vars(c) | |
190 | return self._get_template_context(c) |
|
190 | return self._get_template_context(c) | |
191 |
|
191 | |||
@@ -198,7 +198,7 b' class AdminUsersView(BaseAppView, DataGr' | |||||
198 | def users_create(self): |
|
198 | def users_create(self): | |
199 | _ = self.request.translate |
|
199 | _ = self.request.translate | |
200 | c = self.load_default_context() |
|
200 | c = self.load_default_context() | |
201 |
c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin. |
|
201 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |
202 | user_model = UserModel() |
|
202 | user_model = UserModel() | |
203 | user_form = UserForm(self.request.translate)() |
|
203 | user_form = UserForm(self.request.translate)() | |
204 | try: |
|
204 | try: |
@@ -63,7 +63,7 b' def maybe_create_history_store(event):' | |||||
63 | settings = event.app.registry.settings |
|
63 | settings = event.app.registry.settings | |
64 | history_dir = settings.get('channelstream.history.location', '') |
|
64 | history_dir = settings.get('channelstream.history.location', '') | |
65 | if history_dir and not os.path.exists(history_dir): |
|
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 | def includeme(config): |
|
69 | def includeme(config): |
@@ -32,6 +32,7 b' from pyramid.view import view_config' | |||||
32 |
|
32 | |||
33 | from rhodecode.apps._base import BaseAppView |
|
33 | from rhodecode.apps._base import BaseAppView | |
34 | from rhodecode.authentication.base import authenticate, HTTP_TYPE |
|
34 | from rhodecode.authentication.base import authenticate, HTTP_TYPE | |
|
35 | from rhodecode.authentication.plugins import auth_rhodecode | |||
35 | from rhodecode.events import UserRegistered, trigger |
|
36 | from rhodecode.events import UserRegistered, trigger | |
36 | from rhodecode.lib import helpers as h |
|
37 | from rhodecode.lib import helpers as h | |
37 | from rhodecode.lib import audit_logger |
|
38 | from rhodecode.lib import audit_logger | |
@@ -55,7 +56,7 b' CaptchaData = collections.namedtuple(' | |||||
55 | 'CaptchaData', 'active, private_key, public_key') |
|
56 | 'CaptchaData', 'active, private_key, public_key') | |
56 |
|
57 | |||
57 |
|
58 | |||
58 |
def |
|
59 | def store_user_in_session(session, username, remember=False): | |
59 | user = User.get_by_username(username, case_insensitive=True) |
|
60 | user = User.get_by_username(username, case_insensitive=True) | |
60 | auth_user = AuthUser(user.user_id) |
|
61 | auth_user = AuthUser(user.user_id) | |
61 | auth_user.set_authenticated() |
|
62 | auth_user.set_authenticated() | |
@@ -165,7 +166,7 b' class LoginView(BaseAppView):' | |||||
165 | auth_info = authenticate( |
|
166 | auth_info = authenticate( | |
166 | '', '', self.request.environ, HTTP_TYPE, skip_missing=True) |
|
167 | '', '', self.request.environ, HTTP_TYPE, skip_missing=True) | |
167 | if auth_info: |
|
168 | if auth_info: | |
168 |
headers = |
|
169 | headers = store_user_in_session( | |
169 | self.session, auth_info.get('username')) |
|
170 | self.session, auth_info.get('username')) | |
170 | raise HTTPFound(c.came_from, headers=headers) |
|
171 | raise HTTPFound(c.came_from, headers=headers) | |
171 | except UserCreationError as e: |
|
172 | except UserCreationError as e: | |
@@ -186,7 +187,7 b' class LoginView(BaseAppView):' | |||||
186 | self.session.invalidate() |
|
187 | self.session.invalidate() | |
187 | form_result = login_form.to_python(self.request.POST) |
|
188 | form_result = login_form.to_python(self.request.POST) | |
188 | # form checks for username/password, now we're authenticated |
|
189 | # form checks for username/password, now we're authenticated | |
189 |
headers = |
|
190 | headers = store_user_in_session( | |
190 | self.session, |
|
191 | self.session, | |
191 | username=form_result['username'], |
|
192 | username=form_result['username'], | |
192 | remember=form_result['remember']) |
|
193 | remember=form_result['remember']) | |
@@ -273,16 +274,26 b' class LoginView(BaseAppView):' | |||||
273 | route_name='register', request_method='POST', |
|
274 | route_name='register', request_method='POST', | |
274 | renderer='rhodecode:templates/register.mako') |
|
275 | renderer='rhodecode:templates/register.mako') | |
275 | def register_post(self): |
|
276 | def register_post(self): | |
|
277 | from rhodecode.authentication.plugins import auth_rhodecode | |||
|
278 | ||||
276 | self.load_default_context() |
|
279 | self.load_default_context() | |
277 | captcha = self._get_captcha_data() |
|
280 | captcha = self._get_captcha_data() | |
278 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ |
|
281 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ | |
279 | .AuthUser().permissions['global'] |
|
282 | .AuthUser().permissions['global'] | |
280 |
|
283 | |||
|
284 | extern_name = auth_rhodecode.RhodeCodeAuthPlugin.uid | |||
|
285 | extern_type = auth_rhodecode.RhodeCodeAuthPlugin.uid | |||
|
286 | ||||
281 | register_form = RegisterForm(self.request.translate)() |
|
287 | register_form = RegisterForm(self.request.translate)() | |
282 | try: |
|
288 | try: | |
283 |
|
289 | |||
284 | form_result = register_form.to_python(self.request.POST) |
|
290 | form_result = register_form.to_python(self.request.POST) | |
285 | form_result['active'] = auto_active |
|
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 | if captcha.active: |
|
298 | if captcha.active: | |
288 | captcha_status, captcha_message = self.validate_captcha( |
|
299 | captcha_status, captcha_message = self.validate_captcha( | |
@@ -295,11 +306,17 b' class LoginView(BaseAppView):' | |||||
295 | raise formencode.Invalid( |
|
306 | raise formencode.Invalid( | |
296 | _msg, _value, None, error_dict=error_dict) |
|
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 | action_data = {'data': new_user.get_api_data(), |
|
312 | action_data = {'data': new_user.get_api_data(), | |
301 | 'user_agent': self.request.user_agent} |
|
313 | 'user_agent': self.request.user_agent} | |
302 |
|
314 | |||
|
315 | ||||
|
316 | ||||
|
317 | if external_identity: | |||
|
318 | action_data['external_identity'] = external_identity | |||
|
319 | ||||
303 | audit_user = audit_logger.UserWrap( |
|
320 | audit_user = audit_logger.UserWrap( | |
304 | username=new_user.username, |
|
321 | username=new_user.username, | |
305 | user_id=new_user.user_id, |
|
322 | user_id=new_user.user_id, | |
@@ -351,15 +368,24 b' class LoginView(BaseAppView):' | |||||
351 | # matching emails |
|
368 | # matching emails | |
352 | msg = _('If such email exists, a password reset link was sent to it.') |
|
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 | if self.request.POST: |
|
378 | if self.request.POST: | |
355 | if h.HasPermissionAny('hg.password_reset.disabled')(): |
|
379 | if h.HasPermissionAny('hg.password_reset.disabled')(): | |
356 | _email = self.request.POST.get('email', '') |
|
380 | _email = self.request.POST.get('email', '') | |
357 | log.error('Failed attempt to reset password for `%s`.', _email) |
|
381 | log.error('Failed attempt to reset password for `%s`.', _email) | |
358 | h.flash(_('Password reset has been disabled.'), |
|
382 | h.flash(_('Password reset has been disabled.'), category='error') | |
359 | category='error') |
|
|||
360 | return HTTPFound(self.request.route_path('reset_password')) |
|
383 | return HTTPFound(self.request.route_path('reset_password')) | |
361 |
|
384 | |||
362 | password_reset_form = PasswordResetForm(self.request.translate)() |
|
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 | try: |
|
389 | try: | |
364 | form_result = password_reset_form.to_python( |
|
390 | form_result = password_reset_form.to_python( | |
365 | self.request.POST) |
|
391 | self.request.POST) | |
@@ -379,10 +405,14 b' class LoginView(BaseAppView):' | |||||
379 | # Generate reset URL and send mail. |
|
405 | # Generate reset URL and send mail. | |
380 | user = User.get_by_email(user_email) |
|
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 | # generate password reset token that expires in 10 minutes |
|
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 | reset_token = UserModel().add_auth_token( |
|
416 | reset_token = UserModel().add_auth_token( | |
387 | user=user, lifetime_minutes=10, |
|
417 | user=user, lifetime_minutes=10, | |
388 | role=UserModel.auth_token_role.ROLE_PASSWORD_RESET, |
|
418 | role=UserModel.auth_token_role.ROLE_PASSWORD_RESET, | |
@@ -395,15 +425,14 b' class LoginView(BaseAppView):' | |||||
395 | _query={'key': reset_token.api_key}) |
|
425 | _query={'key': reset_token.api_key}) | |
396 | UserModel().reset_password_link( |
|
426 | UserModel().reset_password_link( | |
397 | form_result, password_reset_url) |
|
427 | form_result, password_reset_url) | |
398 | # Display success message and redirect. |
|
|||
399 | h.flash(msg, category='success') |
|
|||
400 |
|
428 | |||
401 | action_data = {'email': user_email, |
|
429 | action_data = {'email': user_email, | |
402 | 'user_agent': self.request.user_agent} |
|
430 | 'user_agent': self.request.user_agent} | |
403 | audit_logger.store_web( |
|
431 | audit_logger.store_web( | |
404 | 'user.password.reset_request', action_data=action_data, |
|
432 | 'user.password.reset_request', action_data=action_data, | |
405 | user=self._rhodecode_user, commit=True) |
|
433 | user=self._rhodecode_user, commit=True) | |
406 | return HTTPFound(self.request.route_path('reset_password')) |
|
434 | ||
|
435 | return default_response() | |||
407 |
|
436 | |||
408 | except formencode.Invalid as errors: |
|
437 | except formencode.Invalid as errors: | |
409 | template_context.update({ |
|
438 | template_context.update({ | |
@@ -418,11 +447,7 b' class LoginView(BaseAppView):' | |||||
418 | # case of failed captcha |
|
447 | # case of failed captcha | |
419 | return self._get_template_context(c, **template_context) |
|
448 | return self._get_template_context(c, **template_context) | |
420 |
|
449 | |||
421 | log.debug('faking response on invalid password reset') |
|
450 | return default_response() | |
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')) |
|
|||
426 |
|
451 | |||
427 | return self._get_template_context(c, **template_context) |
|
452 | return self._get_template_context(c, **template_context) | |
428 |
|
453 |
@@ -51,12 +51,12 b' def get_default_reviewers_data(' | |||||
51 | """ Return json for default reviewers of a repository """ |
|
51 | """ Return json for default reviewers of a repository """ | |
52 |
|
52 | |||
53 | reasons = ['Default reviewer', 'Repository owner'] |
|
53 | reasons = ['Default reviewer', 'Repository owner'] | |
54 |
|
|
54 | json_reviewers = [reviewer_as_json( | |
55 |
user= |
|
55 | user=target_repo.user, reasons=reasons, mandatory=False, rules=None)] | |
56 |
|
56 | |||
57 | return { |
|
57 | return { | |
58 | 'api_ver': 'v1', # define version for later possible schema upgrade |
|
58 | 'api_ver': 'v1', # define version for later possible schema upgrade | |
59 |
'reviewers': |
|
59 | 'reviewers': json_reviewers, | |
60 | 'rules': {}, |
|
60 | 'rules': {}, | |
61 | 'rules_data': {}, |
|
61 | 'rules_data': {}, | |
62 | } |
|
62 | } |
@@ -211,7 +211,7 b' class RepoChangelogView(RepoAppView):' | |||||
211 | base_commit = self.rhodecode_vcs_repo.get_commit(commit_id) |
|
211 | base_commit = self.rhodecode_vcs_repo.get_commit(commit_id) | |
212 |
|
212 | |||
213 | try: |
|
213 | try: | |
214 |
collection = base_commit.get_ |
|
214 | collection = base_commit.get_path_history( | |
215 | f_path, limit=hist_limit, pre_load=pre_load) |
|
215 | f_path, limit=hist_limit, pre_load=pre_load) | |
216 | if collection and partial_xhr: |
|
216 | if collection and partial_xhr: | |
217 | # for ajax call we remove first one since we're looking |
|
217 | # for ajax call we remove first one since we're looking | |
@@ -221,7 +221,7 b' class RepoChangelogView(RepoAppView):' | |||||
221 | # this node is not present at tip! |
|
221 | # this node is not present at tip! | |
222 | try: |
|
222 | try: | |
223 | commit = self._get_commit_or_redirect(commit_id) |
|
223 | commit = self._get_commit_or_redirect(commit_id) | |
224 |
collection = commit.get_ |
|
224 | collection = commit.get_path_history(f_path) | |
225 | except RepositoryError as e: |
|
225 | except RepositoryError as e: | |
226 | h.flash(safe_str(e), category='warning') |
|
226 | h.flash(safe_str(e), category='warning') | |
227 | redirect_url = h.route_path( |
|
227 | redirect_url = h.route_path( | |
@@ -315,7 +315,7 b' class RepoChangelogView(RepoAppView):' | |||||
315 | raise HTTPFound( |
|
315 | raise HTTPFound( | |
316 | h.route_path('repo_changelog', repo_name=self.db_repo_name)) |
|
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 | f_path, limit=hist_limit, pre_load=pre_load) |
|
319 | f_path, limit=hist_limit, pre_load=pre_load) | |
320 | collection = list(reversed(collection)) |
|
320 | collection = list(reversed(collection)) | |
321 | else: |
|
321 | else: |
@@ -663,7 +663,7 b' class RepoFilesView(RepoAppView):' | |||||
663 | pass |
|
663 | pass | |
664 |
|
664 | |||
665 | if is_file: |
|
665 | if is_file: | |
666 |
history = commit.get_ |
|
666 | history = commit.get_path_history(f_path) | |
667 | prev_commit_id = history[1].raw_id \ |
|
667 | prev_commit_id = history[1].raw_id \ | |
668 | if len(history) > 1 else prev_commit_id |
|
668 | if len(history) > 1 else prev_commit_id | |
669 | prev_url = h.route_path( |
|
669 | prev_url = h.route_path( | |
@@ -897,10 +897,10 b' class RepoFilesView(RepoAppView):' | |||||
897 | if commits is None: |
|
897 | if commits is None: | |
898 | pre_load = ["author", "branch"] |
|
898 | pre_load = ["author", "branch"] | |
899 | try: |
|
899 | try: | |
900 |
commits = tip.get_ |
|
900 | commits = tip.get_path_history(f_path, pre_load=pre_load) | |
901 | except (NodeDoesNotExistError, CommitError): |
|
901 | except (NodeDoesNotExistError, CommitError): | |
902 | # this node is not present at tip! |
|
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 | history = [] |
|
905 | history = [] | |
906 | commits_group = ([], _("Changesets")) |
|
906 | commits_group = ([], _("Changesets")) |
@@ -25,6 +25,7 b' from pyramid.view import view_config' | |||||
25 | from rhodecode.apps._base import RepoAppView |
|
25 | from rhodecode.apps._base import RepoAppView | |
26 | from rhodecode.apps.repository.utils import get_default_reviewers_data |
|
26 | from rhodecode.apps.repository.utils import get_default_reviewers_data | |
27 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
27 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator | |
|
28 | from rhodecode.model.db import Repository | |||
28 |
|
29 | |||
29 | log = logging.getLogger(__name__) |
|
30 | log = logging.getLogger(__name__) | |
30 |
|
31 | |||
@@ -53,8 +54,8 b' class RepoReviewRulesView(RepoAppView):' | |||||
53 | renderer='json_ext') |
|
54 | renderer='json_ext') | |
54 | def repo_default_reviewers_data(self): |
|
55 | def repo_default_reviewers_data(self): | |
55 | self.load_default_context() |
|
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 | review_data = get_default_reviewers_data( |
|
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 | return review_data |
|
61 | return review_data | |
59 |
|
||||
60 |
|
@@ -35,15 +35,8 b' from .events import ModDavSvnConfigChang' | |||||
35 | log = logging.getLogger(__name__) |
|
35 | log = logging.getLogger(__name__) | |
36 |
|
36 | |||
37 |
|
37 | |||
38 |
def |
|
38 | def write_mod_dav_svn_config(settings): | |
39 | """ |
|
39 | use_ssl = str2bool(settings['force_https']) | |
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']) |
|
|||
47 |
|
40 | |||
48 | config = _render_mod_dav_svn_config( |
|
41 | config = _render_mod_dav_svn_config( | |
49 | use_ssl=use_ssl, |
|
42 | use_ssl=use_ssl, | |
@@ -54,6 +47,17 b' def generate_mod_dav_svn_config(registry' | |||||
54 | realm=get_rhodecode_realm(), template=settings[config_keys.template]) |
|
47 | realm=get_rhodecode_realm(), template=settings[config_keys.template]) | |
55 | _write_mod_dav_svn_config(config, settings[config_keys.config_file_path]) |
|
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 | # Trigger an event on mod dav svn configuration change. |
|
61 | # Trigger an event on mod dav svn configuration change. | |
58 | trigger(ModDavSvnConfigChange(), registry) |
|
62 | trigger(ModDavSvnConfigChange(), registry) | |
59 |
|
63 |
@@ -19,7 +19,7 b'' | |||||
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 |
|
21 | |||
22 |
from rhodecode.apps. |
|
22 | from rhodecode.apps._base.navigation import NavigationRegistry | |
23 | from rhodecode.apps._base import ADMIN_PREFIX |
|
23 | from rhodecode.apps._base import ADMIN_PREFIX | |
24 | from rhodecode.lib.utils2 import str2bool |
|
24 | from rhodecode.lib.utils2 import str2bool | |
25 |
|
25 |
@@ -18,11 +18,9 b'' | |||||
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | import os |
|
|||
22 | import logging |
|
21 | import logging | |
23 | import importlib |
|
22 | import importlib | |
24 |
|
23 | |||
25 | from pkg_resources import iter_entry_points |
|
|||
26 | from pyramid.authentication import SessionAuthenticationPolicy |
|
24 | from pyramid.authentication import SessionAuthenticationPolicy | |
27 |
|
25 | |||
28 | from rhodecode.authentication.registry import AuthenticationPluginRegistry |
|
26 | from rhodecode.authentication.registry import AuthenticationPluginRegistry | |
@@ -31,48 +29,26 b' from rhodecode.authentication.routes imp' | |||||
31 | from rhodecode.apps._base import ADMIN_PREFIX |
|
29 | from rhodecode.apps._base import ADMIN_PREFIX | |
32 | from rhodecode.model.settings import SettingsModel |
|
30 | from rhodecode.model.settings import SettingsModel | |
33 |
|
31 | |||
34 |
|
||||
35 | log = logging.getLogger(__name__) |
|
32 | log = logging.getLogger(__name__) | |
36 |
|
33 | |||
37 | # Plugin ID prefixes to distinct between normal and legacy plugins. |
|
|||
38 | plugin_prefix = 'egg:' |
|
|||
39 | legacy_plugin_prefix = 'py:' |
|
34 | legacy_plugin_prefix = 'py:' | |
40 | plugin_default_auth_ttl = 30 |
|
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 | def _import_legacy_plugin(plugin_id): |
|
38 | def _import_legacy_plugin(plugin_id): | |
65 | module_name = plugin_id.split(legacy_plugin_prefix, 1)[-1] |
|
39 | module_name = plugin_id.split(legacy_plugin_prefix, 1)[-1] | |
66 | module = importlib.import_module(module_name) |
|
40 | module = importlib.import_module(module_name) | |
67 | return module.plugin_factory(plugin_id=plugin_id) |
|
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 | Function that imports the legacy plugins stored in the 'auth_plugins' |
|
46 | Function that imports the legacy plugins stored in the 'auth_plugins' | |
73 | setting in database which are using the specified prefix. Normally 'py:' is |
|
47 | setting in database which are using the specified prefix. Normally 'py:' is | |
74 | used for the legacy plugins. |
|
48 | used for the legacy plugins. | |
75 | """ |
|
49 | """ | |
|
50 | log.debug('authentication: running legacy plugin discovery for prefix %s', | |||
|
51 | legacy_plugin_prefix) | |||
76 | try: |
|
52 | try: | |
77 | auth_plugins = SettingsModel().get_setting_by_name('auth_plugins') |
|
53 | auth_plugins = SettingsModel().get_setting_by_name('auth_plugins') | |
78 | enabled_plugins = auth_plugins.app_settings_value |
|
54 | enabled_plugins = auth_plugins.app_settings_value | |
@@ -121,12 +97,3 b' def includeme(config):' | |||||
121 | request_method='POST', |
|
97 | request_method='POST', | |
122 | route_name='auth_home', |
|
98 | route_name='auth_home', | |
123 | context=AuthnRootResource) |
|
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 | from rhodecode.lib import rc_cache |
|
38 | from rhodecode.lib import rc_cache | |
39 | from rhodecode.lib.auth import PasswordGenerator, _RhodeCodeCryptoBCrypt |
|
39 | from rhodecode.lib.auth import PasswordGenerator, _RhodeCodeCryptoBCrypt | |
40 | from rhodecode.lib.utils2 import safe_int, safe_str |
|
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 | from rhodecode.model.db import User |
|
43 | from rhodecode.model.db import User | |
43 | from rhodecode.model.meta import Session |
|
44 | from rhodecode.model.meta import Session | |
44 | from rhodecode.model.settings import SettingsModel |
|
45 | from rhodecode.model.settings import SettingsModel | |
@@ -52,6 +53,8 b' log = logging.getLogger(__name__)' | |||||
52 | VCS_TYPE = 'vcs' |
|
53 | VCS_TYPE = 'vcs' | |
53 | HTTP_TYPE = 'http' |
|
54 | HTTP_TYPE = 'http' | |
54 |
|
55 | |||
|
56 | external_auth_session_key = 'rhodecode.external_auth' | |||
|
57 | ||||
55 |
|
58 | |||
56 | class hybrid_property(object): |
|
59 | class hybrid_property(object): | |
57 | """ |
|
60 | """ | |
@@ -93,6 +96,9 b' class LazyFormencode(object):' | |||||
93 |
|
96 | |||
94 |
|
97 | |||
95 | class RhodeCodeAuthPluginBase(object): |
|
98 | class RhodeCodeAuthPluginBase(object): | |
|
99 | # UID is used to register plugin to the registry | |||
|
100 | uid = None | |||
|
101 | ||||
96 | # cache the authentication request for N amount of seconds. Some kind |
|
102 | # cache the authentication request for N amount of seconds. Some kind | |
97 | # of authentication methods are very heavy and it's very efficient to cache |
|
103 | # of authentication methods are very heavy and it's very efficient to cache | |
98 | # the result of a call. If it's set to None (default) cache is off |
|
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 | "active": |
|
119 | "active": | |
114 | 'True|False defines active state of user internally for RhodeCode', |
|
120 | 'True|False defines active state of user internally for RhodeCode', | |
115 | "active_from_extern": |
|
121 | "active_from_extern": | |
116 |
"True|False |
|
122 | "True|False|None, active state from the external auth, " | |
117 | "None means use definition from RhodeCode extern_type active value" |
|
123 | "None means use definition from RhodeCode extern_type active value" | |
118 |
|
124 | |||
119 | } |
|
125 | } | |
@@ -171,6 +177,20 b' class RhodeCodeAuthPluginBase(object):' | |||||
171 | db_type = '{}.encrypted'.format(db_type) |
|
177 | db_type = '{}.encrypted'.format(db_type) | |
172 | return db_type |
|
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 | def is_enabled(self): |
|
194 | def is_enabled(self): | |
175 | """ |
|
195 | """ | |
176 | Returns true if this plugin is enabled. An enabled plugin can be |
|
196 | Returns true if this plugin is enabled. An enabled plugin can be | |
@@ -563,7 +583,8 b' class RhodeCodeExternalAuthPlugin(RhodeC' | |||||
563 | class AuthLdapBase(object): |
|
583 | class AuthLdapBase(object): | |
564 |
|
584 | |||
565 | @classmethod |
|
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 | def host_resolver(host, port, full_resolve=True): |
|
588 | def host_resolver(host, port, full_resolve=True): | |
568 | """ |
|
589 | """ | |
569 | Main work for this function is to prevent ldap connection issues, |
|
590 | Main work for this function is to prevent ldap connection issues, | |
@@ -602,7 +623,7 b' class AuthLdapBase(object):' | |||||
602 | return ', '.join( |
|
623 | return ', '.join( | |
603 | ["{}://{}".format( |
|
624 | ["{}://{}".format( | |
604 | ldap_server_type, |
|
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 | for host in ldap_server]) |
|
627 | for host in ldap_server]) | |
607 |
|
628 | |||
608 | @classmethod |
|
629 | @classmethod | |
@@ -616,6 +637,19 b' class AuthLdapBase(object):' | |||||
616 | uid = chop_at(username, "@%s" % server_addr) |
|
637 | uid = chop_at(username, "@%s" % server_addr) | |
617 | return uid |
|
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 | def loadplugin(plugin_id): |
|
654 | def loadplugin(plugin_id): | |
621 | """ |
|
655 | """ |
@@ -40,7 +40,7 b' from rhodecode.model.db import User' | |||||
40 | log = logging.getLogger(__name__) |
|
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 | Factory function that is called during plugin discovery. |
|
45 | Factory function that is called during plugin discovery. | |
46 | It returns the plugin instance. |
|
46 | It returns the plugin instance. | |
@@ -189,6 +189,7 b' class CrowdServer(object):' | |||||
189 |
|
189 | |||
190 |
|
190 | |||
191 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
191 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
|
192 | uid = 'crowd' | |||
192 | _settings_unsafe_keys = ['app_password'] |
|
193 | _settings_unsafe_keys = ['app_password'] | |
193 |
|
194 | |||
194 | def includeme(self, config): |
|
195 | def includeme(self, config): | |
@@ -215,9 +216,13 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
215 | def get_display_name(self): |
|
216 | def get_display_name(self): | |
216 | return _('CROWD') |
|
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 | @hybrid_property |
|
223 | @hybrid_property | |
219 | def name(self): |
|
224 | def name(self): | |
220 | return "crowd" |
|
225 | return u"crowd" | |
221 |
|
226 | |||
222 | def use_fake_password(self): |
|
227 | def use_fake_password(self): | |
223 | return True |
|
228 | return True | |
@@ -283,3 +288,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
283 | log.debug("Final crowd user object: \n%s", formatted_json(user_attrs)) |
|
288 | log.debug("Final crowd user object: \n%s", formatted_json(user_attrs)) | |
284 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
289 | log.info('user `%s` authenticated correctly', user_attrs['username']) | |
285 | return user_attrs |
|
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 | log = logging.getLogger(__name__) |
|
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 | Factory function that is called during plugin discovery. |
|
39 | Factory function that is called during plugin discovery. | |
40 | It returns the plugin instance. |
|
40 | It returns the plugin instance. | |
@@ -75,7 +75,7 b' class HeadersSettingsSchema(AuthnPluginS' | |||||
75 |
|
75 | |||
76 |
|
76 | |||
77 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
77 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
78 |
|
78 | uid = 'headers' | ||
79 | def includeme(self, config): |
|
79 | def includeme(self, config): | |
80 | config.add_authn_plugin(self) |
|
80 | config.add_authn_plugin(self) | |
81 | config.add_authn_resource(self.get_id(), HeadersAuthnResource(self)) |
|
81 | config.add_authn_resource(self.get_id(), HeadersAuthnResource(self)) | |
@@ -102,7 +102,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
102 |
|
102 | |||
103 | @hybrid_property |
|
103 | @hybrid_property | |
104 | def name(self): |
|
104 | def name(self): | |
105 |
return |
|
105 | return u"headers" | |
106 |
|
106 | |||
107 | @property |
|
107 | @property | |
108 | def is_headers_auth(self): |
|
108 | def is_headers_auth(self): | |
@@ -223,3 +223,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
223 |
|
223 | |||
224 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
224 | log.info('user `%s` authenticated correctly', user_attrs['username']) | |
225 | return user_attrs |
|
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 | log = logging.getLogger(__name__) |
|
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 | Factory function that is called during plugin discovery. |
|
47 | Factory function that is called during plugin discovery. | |
48 | It returns the plugin instance. |
|
48 | It returns the plugin instance. | |
@@ -66,6 +66,7 b' class JasigCasSettingsSchema(AuthnPlugin' | |||||
66 |
|
66 | |||
67 |
|
67 | |||
68 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
68 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
|
69 | uid = 'jasig_cas' | |||
69 |
|
70 | |||
70 | def includeme(self, config): |
|
71 | def includeme(self, config): | |
71 | config.add_authn_plugin(self) |
|
72 | config.add_authn_plugin(self) | |
@@ -93,7 +94,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
93 |
|
94 | |||
94 | @hybrid_property |
|
95 | @hybrid_property | |
95 | def name(self): |
|
96 | def name(self): | |
96 | return "jasig-cas" |
|
97 | return u"jasig-cas" | |
97 |
|
98 | |||
98 | @property |
|
99 | @property | |
99 | def is_headers_auth(self): |
|
100 | def is_headers_auth(self): | |
@@ -165,3 +166,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
165 |
|
166 | |||
166 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
167 | log.info('user `%s` authenticated correctly', user_attrs['username']) | |
167 | return user_attrs |
|
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 | pass |
|
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 | Factory function that is called during plugin discovery. |
|
58 | Factory function that is called during plugin discovery. | |
59 | It returns the plugin instance. |
|
59 | It returns the plugin instance. | |
@@ -66,6 +66,171 b' class LdapAuthnResource(AuthnPluginResou' | |||||
66 | pass |
|
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 | class LdapSettingsSchema(AuthnPluginSettingsSchemaBase): |
|
234 | class LdapSettingsSchema(AuthnPluginSettingsSchemaBase): | |
70 | tls_kind_choices = ['PLAIN', 'LDAPS', 'START_TLS'] |
|
235 | tls_kind_choices = ['PLAIN', 'LDAPS', 'START_TLS'] | |
71 | tls_reqcert_choices = ['NEVER', 'ALLOW', 'TRY', 'DEMAND', 'HARD'] |
|
236 | tls_reqcert_choices = ['NEVER', 'ALLOW', 'TRY', 'DEMAND', 'HARD'] | |
@@ -84,7 +249,7 b' class LdapSettingsSchema(AuthnPluginSett' | |||||
84 | colander.Int(), |
|
249 | colander.Int(), | |
85 | default=389, |
|
250 | default=389, | |
86 | description=_('Custom port that the LDAP server is listening on. ' |
|
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 | preparer=strip_whitespace, |
|
253 | preparer=strip_whitespace, | |
89 | title=_('Port'), |
|
254 | title=_('Port'), | |
90 | validator=colander.Range(min=0, max=65536), |
|
255 | validator=colander.Range(min=0, max=65536), | |
@@ -133,6 +298,22 b' class LdapSettingsSchema(AuthnPluginSett' | |||||
133 | title=_('Certificate Checks'), |
|
298 | title=_('Certificate Checks'), | |
134 | validator=colander.OneOf(tls_reqcert_choices), |
|
299 | validator=colander.OneOf(tls_reqcert_choices), | |
135 | widget='select') |
|
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 | base_dn = colander.SchemaNode( |
|
317 | base_dn = colander.SchemaNode( | |
137 | colander.String(), |
|
318 | colander.String(), | |
138 | default='', |
|
319 | default='', | |
@@ -169,6 +350,16 b' class LdapSettingsSchema(AuthnPluginSett' | |||||
169 | title=_('Login Attribute'), |
|
350 | title=_('Login Attribute'), | |
170 | missing_msg=_('The LDAP Login attribute of the CN must be specified'), |
|
351 | missing_msg=_('The LDAP Login attribute of the CN must be specified'), | |
171 | widget='string') |
|
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 | attr_firstname = colander.SchemaNode( |
|
363 | attr_firstname = colander.SchemaNode( | |
173 | colander.String(), |
|
364 | colander.String(), | |
174 | default='', |
|
365 | default='', | |
@@ -185,182 +376,10 b' class LdapSettingsSchema(AuthnPluginSett' | |||||
185 | preparer=strip_whitespace, |
|
376 | preparer=strip_whitespace, | |
186 | title=_('Last Name Attribute'), |
|
377 | title=_('Last Name Attribute'), | |
187 | widget='string') |
|
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 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
381 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
|
382 | uid = 'ldap' | |||
364 | # used to define dynamic binding in the |
|
383 | # used to define dynamic binding in the | |
365 | DYNAMIC_BIND_VAR = '$login' |
|
384 | DYNAMIC_BIND_VAR = '$login' | |
366 | _settings_unsafe_keys = ['dn_pass'] |
|
385 | _settings_unsafe_keys = ['dn_pass'] | |
@@ -389,9 +408,13 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
389 | def get_display_name(self): |
|
408 | def get_display_name(self): | |
390 | return _('LDAP') |
|
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 | @hybrid_property |
|
415 | @hybrid_property | |
393 | def name(self): |
|
416 | def name(self): | |
394 | return "ldap" |
|
417 | return u"ldap" | |
395 |
|
418 | |||
396 | def use_fake_password(self): |
|
419 | def use_fake_password(self): | |
397 | return True |
|
420 | return True | |
@@ -448,6 +471,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
448 | 'bind_pass': settings.get('dn_pass'), |
|
471 | 'bind_pass': settings.get('dn_pass'), | |
449 | 'tls_kind': settings.get('tls_kind'), |
|
472 | 'tls_kind': settings.get('tls_kind'), | |
450 | 'tls_reqcert': settings.get('tls_reqcert'), |
|
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 | 'search_scope': settings.get('search_scope'), |
|
476 | 'search_scope': settings.get('search_scope'), | |
452 | 'attr_login': settings.get('attr_login'), |
|
477 | 'attr_login': settings.get('attr_login'), | |
453 | 'ldap_version': 3, |
|
478 | 'ldap_version': 3, | |
@@ -477,12 +502,11 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
477 | extern_type = getattr(userobj, 'extern_type', '') |
|
502 | extern_type = getattr(userobj, 'extern_type', '') | |
478 |
|
503 | |||
479 | groups = [] |
|
504 | groups = [] | |
|
505 | ||||
480 | user_attrs = { |
|
506 | user_attrs = { | |
481 | 'username': username, |
|
507 | 'username': username, | |
482 | 'firstname': safe_unicode( |
|
508 | 'firstname': safe_unicode(get_ldap_attr('attr_firstname') or firstname), | |
483 |
|
|
509 | 'lastname': safe_unicode(get_ldap_attr('attr_lastname') or lastname), | |
484 | 'lastname': safe_unicode( |
|
|||
485 | get_ldap_attr('attr_lastname') or lastname), |
|
|||
486 | 'groups': groups, |
|
510 | 'groups': groups, | |
487 | 'user_group_sync': False, |
|
511 | 'user_group_sync': False, | |
488 | 'email': get_ldap_attr('attr_email') or email, |
|
512 | 'email': get_ldap_attr('attr_email') or email, | |
@@ -492,6 +516,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
492 | 'extern_name': user_dn, |
|
516 | 'extern_name': user_dn, | |
493 | 'extern_type': extern_type, |
|
517 | 'extern_type': extern_type, | |
494 | } |
|
518 | } | |
|
519 | ||||
495 | log.debug('ldap user: %s', user_attrs) |
|
520 | log.debug('ldap user: %s', user_attrs) | |
496 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
521 | log.info('user `%s` authenticated correctly', user_attrs['username']) | |
497 |
|
522 | |||
@@ -504,3 +529,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
504 | log.exception("Other exception") |
|
529 | log.exception("Other exception") | |
505 | return None |
|
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 | log = logging.getLogger(__name__) |
|
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 | Factory function that is called during plugin discovery. |
|
45 | Factory function that is called during plugin discovery. | |
46 | It returns the plugin instance. |
|
46 | It returns the plugin instance. | |
@@ -72,6 +72,7 b' class PamSettingsSchema(AuthnPluginSetti' | |||||
72 |
|
72 | |||
73 |
|
73 | |||
74 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
74 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
|
75 | uid = 'pam' | |||
75 | # PAM authentication can be slow. Repository operations involve a lot of |
|
76 | # PAM authentication can be slow. Repository operations involve a lot of | |
76 | # auth calls. Little caching helps speedup push/pull operations significantly |
|
77 | # auth calls. Little caching helps speedup push/pull operations significantly | |
77 | AUTH_CACHE_TTL = 4 |
|
78 | AUTH_CACHE_TTL = 4 | |
@@ -97,9 +98,13 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
97 | def get_display_name(self): |
|
98 | def get_display_name(self): | |
98 | return _('PAM') |
|
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 | @hybrid_property |
|
105 | @hybrid_property | |
101 | def name(self): |
|
106 | def name(self): | |
102 | return "pam" |
|
107 | return u"pam" | |
103 |
|
108 | |||
104 | def get_settings_schema(self): |
|
109 | def get_settings_schema(self): | |
105 | return PamSettingsSchema() |
|
110 | return PamSettingsSchema() | |
@@ -159,3 +164,8 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
159 | log.debug("pamuser: %s", user_attrs) |
|
164 | log.debug("pamuser: %s", user_attrs) | |
160 | log.info('user `%s` authenticated correctly', user_attrs['username']) |
|
165 | log.info('user `%s` authenticated correctly', user_attrs['username']) | |
161 | return user_attrs |
|
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 | log = logging.getLogger(__name__) |
|
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 | plugin = RhodeCodeAuthPlugin(plugin_id) |
|
38 | plugin = RhodeCodeAuthPlugin(plugin_id) | |
39 | return plugin |
|
39 | return plugin | |
40 |
|
40 | |||
@@ -44,6 +44,7 b' class RhodecodeAuthnResource(AuthnPlugin' | |||||
44 |
|
44 | |||
45 |
|
45 | |||
46 | class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): |
|
46 | class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): | |
|
47 | uid = 'rhodecode' | |||
47 |
|
48 | |||
48 | def includeme(self, config): |
|
49 | def includeme(self, config): | |
49 | config.add_authn_plugin(self) |
|
50 | config.add_authn_plugin(self) | |
@@ -64,11 +65,15 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
64 | context=RhodecodeAuthnResource) |
|
65 | context=RhodecodeAuthnResource) | |
65 |
|
66 | |||
66 | def get_display_name(self): |
|
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 | @hybrid_property |
|
74 | @hybrid_property | |
70 | def name(self): |
|
75 | def name(self): | |
71 | return "rhodecode" |
|
76 | return u"rhodecode" | |
72 |
|
77 | |||
73 | def user_activation_state(self): |
|
78 | def user_activation_state(self): | |
74 | def_user_perms = User.get_default_user().AuthUser().permissions['global'] |
|
79 | def_user_perms = User.get_default_user().AuthUser().permissions['global'] | |
@@ -141,3 +146,8 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
141 | 'user `%s` failed to authenticate via %s, reason: account not ' |
|
146 | 'user `%s` failed to authenticate via %s, reason: account not ' | |
142 | 'active.', username, self.name) |
|
147 | 'active.', username, self.name) | |
143 | return None |
|
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 | log = logging.getLogger(__name__) |
|
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 | plugin = RhodeCodeAuthPlugin(plugin_id) |
|
38 | plugin = RhodeCodeAuthPlugin(plugin_id) | |
39 | return plugin |
|
39 | return plugin | |
40 |
|
40 | |||
@@ -47,6 +47,7 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
47 | """ |
|
47 | """ | |
48 | Enables usage of authentication tokens for vcs operations. |
|
48 | Enables usage of authentication tokens for vcs operations. | |
49 | """ |
|
49 | """ | |
|
50 | uid = 'token' | |||
50 |
|
51 | |||
51 | def includeme(self, config): |
|
52 | def includeme(self, config): | |
52 | config.add_authn_plugin(self) |
|
53 | config.add_authn_plugin(self) | |
@@ -67,11 +68,15 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
67 | context=RhodecodeAuthnResource) |
|
68 | context=RhodecodeAuthnResource) | |
68 |
|
69 | |||
69 | def get_display_name(self): |
|
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 | @hybrid_property |
|
77 | @hybrid_property | |
73 | def name(self): |
|
78 | def name(self): | |
74 | return "authtoken" |
|
79 | return u"authtoken" | |
75 |
|
80 | |||
76 | def user_activation_state(self): |
|
81 | def user_activation_state(self): | |
77 | def_user_perms = User.get_default_user().AuthUser().permissions['global'] |
|
82 | def_user_perms = User.get_default_user().AuthUser().permissions['global'] | |
@@ -145,3 +150,8 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
145 | 'user `%s` failed to authenticate via %s, reason: account not ' |
|
150 | 'user `%s` failed to authenticate via %s, reason: account not ' | |
146 | 'active.', username, self.name) |
|
151 | 'active.', username, self.name) | |
147 | return None |
|
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 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | import logging |
|
21 | import logging | |
|
22 | import collections | |||
22 |
|
23 | |||
23 | from pyramid.exceptions import ConfigurationError |
|
24 | from pyramid.exceptions import ConfigurationError | |
24 |
|
25 | |||
@@ -55,9 +56,9 b' class AuthnRootResource(AuthnResourceBas' | |||||
55 | """ |
|
56 | """ | |
56 |
|
57 | |||
57 | def __init__(self): |
|
58 | def __init__(self): | |
58 |
self._store = |
|
59 | self._store = collections.OrderedDict() | |
59 | self._resource_name_map = {} |
|
60 | self._resource_name_map = {} | |
60 |
self.display_name = _(' |
|
61 | self.display_name = _('Authentication Plugins') | |
61 |
|
62 | |||
62 | def __getitem__(self, key): |
|
63 | def __getitem__(self, key): | |
63 | """ |
|
64 | """ | |
@@ -87,23 +88,27 b' class AuthnRootResource(AuthnResourceBas' | |||||
87 | # TODO: Store this info in the resource element. |
|
88 | # TODO: Store this info in the resource element. | |
88 | return self._resource_name_map[resource_name] |
|
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 | Returns a sorted list of sub resources for displaying purposes. |
|
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 | return str.lower(safe_str(resource.display_name)) |
|
96 | return str.lower(safe_str(resource.display_name)) | |
96 |
|
97 | |||
97 | active = [item for item in self] |
|
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 | Returns a sorted list of resources for displaying the navigation. |
|
103 | Returns a sorted list of resources for displaying the navigation. | |
103 | """ |
|
104 | """ | |
104 | list = self.get_sorted_list() |
|
105 | if sort: | |
105 | list.insert(0, self) |
|
106 | nav_list = self.get_sorted_list() | |
106 |
|
|
107 | else: | |
|
108 | nav_list = [item for item in self] | |||
|
109 | ||||
|
110 | nav_list.insert(0, self) | |||
|
111 | return nav_list | |||
107 |
|
112 | |||
108 | def add_authn_resource(self, config, plugin_id, resource): |
|
113 | def add_authn_resource(self, config, plugin_id, resource): | |
109 | """ |
|
114 | """ |
@@ -23,6 +23,7 b' import sys' | |||||
23 | import logging |
|
23 | import logging | |
24 | import collections |
|
24 | import collections | |
25 | import tempfile |
|
25 | import tempfile | |
|
26 | import time | |||
26 |
|
27 | |||
27 | from paste.gzipper import make_gzip_middleware |
|
28 | from paste.gzipper import make_gzip_middleware | |
28 | import pyramid.events |
|
29 | import pyramid.events | |
@@ -63,6 +64,14 b' def is_http_error(response):' | |||||
63 | return response.status_code > 499 |
|
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 | def make_pyramid_app(global_config, **settings): |
|
75 | def make_pyramid_app(global_config, **settings): | |
67 | """ |
|
76 | """ | |
68 | Constructs the WSGI application based on Pyramid. |
|
77 | Constructs the WSGI application based on Pyramid. | |
@@ -78,8 +87,13 b' def make_pyramid_app(global_config, **se' | |||||
78 |
|
87 | |||
79 | # Allows to use format style "{ENV_NAME}" placeholders in the configuration. It |
|
88 | # Allows to use format style "{ENV_NAME}" placeholders in the configuration. It | |
80 | # will be replaced by the value of the environment variable "NAME" in this case. |
|
89 | # will be replaced by the value of the environment variable "NAME" in this case. | |
81 | environ = { |
|
90 | start_time = time.time() | |
82 | 'ENV_{}'.format(key): value for key, value in os.environ.items()} |
|
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 | global_config = _substitute_values(global_config, environ) |
|
98 | global_config = _substitute_values(global_config, environ) | |
85 | settings = _substitute_values(settings, environ) |
|
99 | settings = _substitute_values(settings, environ) | |
@@ -105,8 +119,10 b' def make_pyramid_app(global_config, **se' | |||||
105 | config.configure_celery(global_config['__file__']) |
|
119 | config.configure_celery(global_config['__file__']) | |
106 | # creating the app uses a connection - return it after we are done |
|
120 | # creating the app uses a connection - return it after we are done | |
107 | meta.Session.remove() |
|
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 | return pyramid_app |
|
126 | return pyramid_app | |
111 |
|
127 | |||
112 |
|
128 | |||
@@ -215,6 +231,7 b' def includeme_first(config):' | |||||
215 |
|
231 | |||
216 |
|
232 | |||
217 | def includeme(config): |
|
233 | def includeme(config): | |
|
234 | log.debug('Initializing main includeme from %s', os.path.basename(__file__)) | |||
218 | settings = config.registry.settings |
|
235 | settings = config.registry.settings | |
219 | config.set_request_factory(Request) |
|
236 | config.set_request_factory(Request) | |
220 |
|
237 | |||
@@ -229,41 +246,58 b' def includeme(config):' | |||||
229 | if asbool(settings.get('appenlight', 'false')): |
|
246 | if asbool(settings.get('appenlight', 'false')): | |
230 | config.include('appenlight_client.ext.pyramid_tween') |
|
247 | config.include('appenlight_client.ext.pyramid_tween') | |
231 |
|
248 | |||
|
249 | load_all = should_load_all() | |||
|
250 | ||||
232 | # Includes which are required. The application would fail without them. |
|
251 | # Includes which are required. The application would fail without them. | |
233 | config.include('pyramid_mako') |
|
252 | config.include('pyramid_mako') | |
234 | config.include('pyramid_beaker') |
|
253 | config.include('pyramid_beaker') | |
235 | config.include('rhodecode.lib.rc_cache') |
|
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 | config.include('rhodecode.authentication') |
|
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 | # apps |
|
277 | # apps | |
241 | config.include('rhodecode.apps._base') |
|
278 | config.include('rhodecode.apps._base') | |
242 | config.include('rhodecode.apps.ops') |
|
|||
243 |
|
279 | |||
244 | config.include('rhodecode.apps.admin') |
|
280 | if load_all: | |
245 |
config.include('rhodecode.apps. |
|
281 | config.include('rhodecode.apps.ops') | |
246 |
config.include('rhodecode.apps. |
|
282 | config.include('rhodecode.apps.admin') | |
247 |
config.include('rhodecode.apps. |
|
283 | config.include('rhodecode.apps.channelstream') | |
248 |
config.include('rhodecode.apps. |
|
284 | config.include('rhodecode.apps.login') | |
249 |
config.include('rhodecode.apps. |
|
285 | config.include('rhodecode.apps.home') | |
250 |
config.include('rhodecode.apps. |
|
286 | config.include('rhodecode.apps.journal') | |
251 |
config.include('rhodecode.apps. |
|
287 | config.include('rhodecode.apps.repository') | |
252 |
config.include('rhodecode.apps. |
|
288 | config.include('rhodecode.apps.repo_group') | |
253 |
config.include('rhodecode.apps.user_ |
|
289 | config.include('rhodecode.apps.user_group') | |
254 |
config.include('rhodecode.apps. |
|
290 | config.include('rhodecode.apps.search') | |
255 |
config.include('rhodecode.apps. |
|
291 | config.include('rhodecode.apps.user_profile') | |
256 |
config.include('rhodecode.apps. |
|
292 | config.include('rhodecode.apps.user_group_profile') | |
257 |
config.include('rhodecode.apps. |
|
293 | config.include('rhodecode.apps.my_account') | |
258 |
config.include('rhodecode.apps. |
|
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') |
|
300 | config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True) | |
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 |
|
||||
267 | config.add_translation_dirs('rhodecode:i18n/') |
|
301 | config.add_translation_dirs('rhodecode:i18n/') | |
268 | settings['default_locale_name'] = settings.get('lang', 'en') |
|
302 | settings['default_locale_name'] = settings.get('lang', 'en') | |
269 |
|
303 | |||
@@ -403,6 +437,114 b' def sanitize_settings_and_apply_defaults' | |||||
403 | return settings |
|
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 | def _sanitize_appenlight_settings(settings): |
|
548 | def _sanitize_appenlight_settings(settings): | |
407 | _bool_setting(settings, 'appenlight', 'false') |
|
549 | _bool_setting(settings, 'appenlight', 'false') | |
408 |
|
550 | |||
@@ -447,7 +589,7 b' def _sanitize_cache_settings(settings):' | |||||
447 |
|
589 | |||
448 | # ensure we have our dir created |
|
590 | # ensure we have our dir created | |
449 | if not os.path.isdir(default_cache_dir): |
|
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 | # exception store cache |
|
594 | # exception store cache | |
453 | _string_setting( |
|
595 | _string_setting( | |
@@ -578,5 +720,8 b' def _substitute_values(mapping, substitu' | |||||
578 | raise ValueError( |
|
720 | raise ValueError( | |
579 | 'Failed to substitute env variable: {}. ' |
|
721 | 'Failed to substitute env variable: {}. ' | |
580 | 'Make sure you have specified this env variable without ENV_ prefix'.format(e)) |
|
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 | return result |
|
727 | return result |
@@ -27,6 +27,7 b' us in hooks::' | |||||
27 | """ |
|
27 | """ | |
28 | import re |
|
28 | import re | |
29 | import collections |
|
29 | import collections | |
|
30 | import json | |||
30 |
|
31 | |||
31 |
|
32 | |||
32 | def get_hg_commits(repo, refs): |
|
33 | def get_hg_commits(repo, refs): | |
@@ -36,6 +37,31 b' def get_hg_commits(repo, refs):' | |||||
36 |
|
37 | |||
37 | def get_git_commits(repo, refs): |
|
38 | def get_git_commits(repo, refs): | |
38 | commits = [] |
|
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 | return commits |
|
65 | return commits | |
40 |
|
66 | |||
41 |
|
67 | |||
@@ -51,13 +77,14 b' def run(*args, **kwargs):' | |||||
51 |
|
77 | |||
52 | commits = [] |
|
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 | if vcs_type == 'git': |
|
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 | commits = get_git_commits(vcs_repo, kwargs['commit_ids']) |
|
83 | commits = get_git_commits(vcs_repo, kwargs['commit_ids']) | |
59 |
|
84 | |||
60 | if vcs_type == 'hg': |
|
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 | commits = get_hg_commits(vcs_repo, kwargs['commit_ids']) |
|
88 | commits = get_hg_commits(vcs_repo, kwargs['commit_ids']) | |
62 |
|
89 | |||
63 | return commits |
|
90 | return commits |
@@ -145,3 +145,41 b' def maybe_log_call(name, args, kwargs):' | |||||
145 | if hasattr(rcextensions, 'calls'): |
|
145 | if hasattr(rcextensions, 'calls'): | |
146 | calls = rcextensions.calls |
|
146 | calls = rcextensions.calls | |
147 | calls[name].append((args, kwargs)) |
|
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 | The redirection must be first implemented in our servers before |
|
43 | The redirection must be first implemented in our servers before | |
44 | you can see it working. |
|
44 | you can see it working. | |
45 | """ |
|
45 | """ | |
46 | # flake8: noqa |
|
46 | # pragma: no cover | |
47 | from __future__ import unicode_literals |
|
47 | from __future__ import unicode_literals | |
48 |
|
48 | |||
49 | link_config = [ |
|
49 | link_config = [ |
@@ -44,7 +44,7 b' def trigger(event, registry=None):' | |||||
44 | integrations_event_handler(event) |
|
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 | UserPreCreate, |
|
48 | UserPreCreate, | |
49 | UserPostCreate, |
|
49 | UserPostCreate, | |
50 | UserPreUpdate, |
|
50 | UserPreUpdate, | |
@@ -52,7 +52,7 b' from rhodecode.events.user import ( # n' | |||||
52 | UserPermissionsChange, |
|
52 | UserPermissionsChange, | |
53 | ) |
|
53 | ) | |
54 |
|
54 | |||
55 |
from rhodecode.events.repo import ( # |
|
55 | from rhodecode.events.repo import ( # pragma: no cover | |
56 | RepoEvent, |
|
56 | RepoEvent, | |
57 | RepoPreCreateEvent, RepoCreateEvent, |
|
57 | RepoPreCreateEvent, RepoCreateEvent, | |
58 | RepoPreDeleteEvent, RepoDeleteEvent, |
|
58 | RepoPreDeleteEvent, RepoDeleteEvent, | |
@@ -60,14 +60,14 b' from rhodecode.events.repo import ( # n' | |||||
60 | RepoPrePullEvent, RepoPullEvent, |
|
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 | RepoGroupEvent, |
|
64 | RepoGroupEvent, | |
65 | RepoGroupCreateEvent, |
|
65 | RepoGroupCreateEvent, | |
66 | RepoGroupUpdateEvent, |
|
66 | RepoGroupUpdateEvent, | |
67 | RepoGroupDeleteEvent, |
|
67 | RepoGroupDeleteEvent, | |
68 | ) |
|
68 | ) | |
69 |
|
69 | |||
70 |
from rhodecode.events.pullrequest import ( # |
|
70 | from rhodecode.events.pullrequest import ( # pragma: no cover | |
71 | PullRequestEvent, |
|
71 | PullRequestEvent, | |
72 | PullRequestCreateEvent, |
|
72 | PullRequestCreateEvent, | |
73 | PullRequestUpdateEvent, |
|
73 | PullRequestUpdateEvent, |
@@ -32,6 +32,6 b' class IntegrationTypeRegistry(collection' | |||||
32 | if key in self: |
|
32 | if key in self: | |
33 | log.debug( |
|
33 | log.debug( | |
34 | 'Overriding existing integration type %s (%s) with %s', |
|
34 | 'Overriding existing integration type %s (%s) with %s', | |
35 | self[key], key, IntegrationType) |
|
35 | self[key].__class__, key, IntegrationType) | |
36 |
|
36 | |||
37 | self[key] = IntegrationType |
|
37 | self[key] = IntegrationType |
@@ -36,6 +36,26 b' from rhodecode.integrations.types.base i' | |||||
36 |
|
36 | |||
37 | log = logging.getLogger(__name__) |
|
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 | class HipchatSettingsSchema(colander.Schema): |
|
60 | class HipchatSettingsSchema(colander.Schema): | |
41 | color_choices = [ |
|
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 | class HipchatIntegrationType(IntegrationTypeBase, CommitParsingDataHandler): |
|
99 | class HipchatIntegrationType(IntegrationTypeBase, CommitParsingDataHandler): | |
101 | key = 'hipchat' |
|
100 | key = 'hipchat' | |
102 | display_name = _('Hipchat') |
|
101 | display_name = _('Hipchat') | |
@@ -226,7 +225,7 b' class HipchatIntegrationType(Integration' | |||||
226 | data['push']['branches'], data['push']['commits']) |
|
225 | data['push']['branches'], data['push']['commits']) | |
227 |
|
226 | |||
228 | result = render_with_traceback( |
|
227 | result = render_with_traceback( | |
229 | repo_push_template, |
|
228 | REPO_PUSH_TEMPLATE, | |
230 | data=data, |
|
229 | data=data, | |
231 | branches_commits=branches_commits, |
|
230 | branches_commits=branches_commits, | |
232 | ) |
|
231 | ) |
@@ -41,6 +41,30 b' from rhodecode.integrations.types.base i' | |||||
41 | log = logging.getLogger(__name__) |
|
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 | class SlackSettingsSchema(colander.Schema): |
|
68 | class SlackSettingsSchema(colander.Schema): | |
45 | service = colander.SchemaNode( |
|
69 | service = colander.SchemaNode( | |
46 | colander.String(), |
|
70 | colander.String(), | |
@@ -258,7 +282,6 b' class SlackIntegrationType(IntegrationTy' | |||||
258 | return title, text |
|
282 | return title, text | |
259 |
|
283 | |||
260 | def format_repo_push_event(self, data): |
|
284 | def format_repo_push_event(self, data): | |
261 |
|
||||
262 | branches_commits = self.aggregate_branch_data( |
|
285 | branches_commits = self.aggregate_branch_data( | |
263 | data['push']['branches'], data['push']['commits']) |
|
286 | data['push']['branches'], data['push']['commits']) | |
264 |
|
287 | |||
@@ -267,25 +290,8 b' class SlackIntegrationType(IntegrationTy' | |||||
267 | ''') |
|
290 | ''') | |
268 | title = render_with_traceback(template, data=data) |
|
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 | text = render_with_traceback( |
|
293 | text = render_with_traceback( | |
288 | repo_push_template, |
|
294 | REPO_PUSH_TEMPLATE, | |
289 | data=data, |
|
295 | data=data, | |
290 | branches_commits=branches_commits, |
|
296 | branches_commits=branches_commits, | |
291 | html_to_slack_links=html_to_slack_links, |
|
297 | html_to_slack_links=html_to_slack_links, | |
@@ -308,11 +314,6 b' class SlackIntegrationType(IntegrationTy' | |||||
308 | return title, text |
|
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 | @async_task(ignore_result=True, base=RequestContextTask) |
|
317 | @async_task(ignore_result=True, base=RequestContextTask) | |
317 | def post_text_to_slack(settings, title, text, fields=None, overrides=None): |
|
318 | def post_text_to_slack(settings, title, text, fields=None, overrides=None): | |
318 | log.debug('sending %s (%s) to slack %s', title, text, settings['service']) |
|
319 | log.debug('sending %s (%s) to slack %s', title, text, settings['service']) |
@@ -25,9 +25,9 b' import webhelpers.paginate' | |||||
25 |
|
25 | |||
26 | from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPNotFound |
|
26 | from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPNotFound | |
27 |
|
27 | |||
|
28 | from rhodecode.integrations import integration_type_registry | |||
28 | from rhodecode.apps._base import BaseAppView |
|
29 | from rhodecode.apps._base import BaseAppView | |
29 |
from rhodecode.i |
|
30 | from rhodecode.apps._base.navigation import navigation_list | |
30 | from rhodecode.apps.admin.navigation import navigation_list |
|
|||
31 | from rhodecode.lib.auth import ( |
|
31 | from rhodecode.lib.auth import ( | |
32 | LoginRequired, CSRFRequired, HasPermissionAnyDecorator, |
|
32 | LoginRequired, CSRFRequired, HasPermissionAnyDecorator, | |
33 | HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator) |
|
33 | HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator) |
@@ -60,6 +60,7 b' markdown_tags = [' | |||||
60 | "table", "thead", "tbody", "tfoot", "tr", "th", "td", |
|
60 | "table", "thead", "tbody", "tfoot", "tr", "th", "td", | |
61 | "img", |
|
61 | "img", | |
62 | "a", |
|
62 | "a", | |
|
63 | "input", | |||
63 | ] |
|
64 | ] | |
64 |
|
65 | |||
65 | markdown_attrs = { |
|
66 | markdown_attrs = { | |
@@ -68,7 +69,8 b' markdown_attrs = {' | |||||
68 | "a": ["href", "alt", "title", "name"], |
|
69 | "a": ["href", "alt", "title", "name"], | |
69 | "abbr": ["title"], |
|
70 | "abbr": ["title"], | |
70 | "acronym": ["title"], |
|
71 | "acronym": ["title"], | |
71 | "pre": ["lang"] |
|
72 | "pre": ["lang"], | |
|
73 | "input": ["type", "disabled"] | |||
72 | } |
|
74 | } | |
73 |
|
75 | |||
74 | standard_styles = [ |
|
76 | standard_styles = [ |
@@ -33,7 +33,7 b' import importlib' | |||||
33 | from celery import Celery |
|
33 | from celery import Celery | |
34 | from celery import signals |
|
34 | from celery import signals | |
35 | from celery import Task |
|
35 | from celery import Task | |
36 |
from celery import exceptions # |
|
36 | from celery import exceptions # pragma: no cover | |
37 | from kombu.serialization import register |
|
37 | from kombu.serialization import register | |
38 | from pyramid.threadlocal import get_current_request |
|
38 | from pyramid.threadlocal import get_current_request | |
39 |
|
39 |
@@ -40,12 +40,12 b' from sqlalchemy import (' | |||||
40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, |
|
40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, | |
41 | Text, Float, PickleType) |
|
41 | Text, Float, PickleType) | |
42 | from sqlalchemy.sql.expression import true, false |
|
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 | from sqlalchemy.orm import ( |
|
44 | from sqlalchemy.orm import ( | |
45 | relationship, joinedload, class_mapper, validates, aliased) |
|
45 | relationship, joinedload, class_mapper, validates, aliased) | |
46 | from sqlalchemy.ext.declarative import declared_attr |
|
46 | from sqlalchemy.ext.declarative import declared_attr | |
47 | from sqlalchemy.ext.hybrid import hybrid_property |
|
47 | from sqlalchemy.ext.hybrid import hybrid_property | |
48 |
from sqlalchemy.exc import IntegrityError # |
|
48 | from sqlalchemy.exc import IntegrityError # pragma: no cover | |
49 | from sqlalchemy.dialects.mysql import LONGTEXT |
|
49 | from sqlalchemy.dialects.mysql import LONGTEXT | |
50 | from beaker.cache import cache_region |
|
50 | from beaker.cache import cache_region | |
51 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
51 | from zope.cachedescriptors.property import Lazy as LazyProperty |
@@ -40,12 +40,12 b' from sqlalchemy import (' | |||||
40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, |
|
40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, | |
41 | Text, Float, PickleType) |
|
41 | Text, Float, PickleType) | |
42 | from sqlalchemy.sql.expression import true, false |
|
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 | from sqlalchemy.orm import ( |
|
44 | from sqlalchemy.orm import ( | |
45 | relationship, joinedload, class_mapper, validates, aliased) |
|
45 | relationship, joinedload, class_mapper, validates, aliased) | |
46 | from sqlalchemy.ext.declarative import declared_attr |
|
46 | from sqlalchemy.ext.declarative import declared_attr | |
47 | from sqlalchemy.ext.hybrid import hybrid_property |
|
47 | from sqlalchemy.ext.hybrid import hybrid_property | |
48 |
from sqlalchemy.exc import IntegrityError # |
|
48 | from sqlalchemy.exc import IntegrityError # pragma: no cover | |
49 | from sqlalchemy.dialects.mysql import LONGTEXT |
|
49 | from sqlalchemy.dialects.mysql import LONGTEXT | |
50 | from beaker.cache import cache_region |
|
50 | from beaker.cache import cache_region | |
51 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
51 | from zope.cachedescriptors.property import Lazy as LazyProperty |
@@ -41,7 +41,7 b' from sqlalchemy.ext.hybrid import hybrid' | |||||
41 | from sqlalchemy.orm import ( |
|
41 | from sqlalchemy.orm import ( | |
42 | relationship, joinedload, class_mapper, validates, aliased) |
|
42 | relationship, joinedload, class_mapper, validates, aliased) | |
43 | from sqlalchemy.sql.expression import true |
|
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 | from beaker.cache import cache_region |
|
45 | from beaker.cache import cache_region | |
46 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
46 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
47 |
|
47 |
@@ -95,7 +95,7 b' class diff_match_patch:' | |||||
95 | Array of changes. |
|
95 | Array of changes. | |
96 | """ |
|
96 | """ | |
97 | # Set a deadline by which time the diff must be complete. |
|
97 | # Set a deadline by which time the diff must be complete. | |
98 |
if deadline |
|
98 | if deadline is None: | |
99 | # Unlike in most languages, Python counts time in seconds. |
|
99 | # Unlike in most languages, Python counts time in seconds. | |
100 | if self.Diff_Timeout <= 0: |
|
100 | if self.Diff_Timeout <= 0: | |
101 | deadline = sys.maxint |
|
101 | deadline = sys.maxint | |
@@ -103,7 +103,7 b' class diff_match_patch:' | |||||
103 | deadline = time.time() + self.Diff_Timeout |
|
103 | deadline = time.time() + self.Diff_Timeout | |
104 |
|
104 | |||
105 | # Check for null inputs. |
|
105 | # Check for null inputs. | |
106 |
if text1 |
|
106 | if text1 is None or text2 is None: | |
107 | raise ValueError("Null inputs. (diff_main)") |
|
107 | raise ValueError("Null inputs. (diff_main)") | |
108 |
|
108 | |||
109 | # Check for equality (speedup). |
|
109 | # Check for equality (speedup). | |
@@ -1227,7 +1227,7 b' class diff_match_patch:' | |||||
1227 | Best match index or -1. |
|
1227 | Best match index or -1. | |
1228 | """ |
|
1228 | """ | |
1229 | # Check for null inputs. |
|
1229 | # Check for null inputs. | |
1230 |
if text |
|
1230 | if text is None or pattern is None: | |
1231 | raise ValueError("Null inputs. (match_main)") |
|
1231 | raise ValueError("Null inputs. (match_main)") | |
1232 |
|
1232 | |||
1233 | loc = max(0, min(loc, len(text))) |
|
1233 | loc = max(0, min(loc, len(text))) |
@@ -1018,7 +1018,7 b' def style_metatag(tag_type, value):' | |||||
1018 | return html_value |
|
1018 | return html_value | |
1019 |
|
1019 | |||
1020 |
|
1020 | |||
1021 | def bool2icon(value): |
|
1021 | def bool2icon(value, show_at_false=True): | |
1022 | """ |
|
1022 | """ | |
1023 | Returns boolean value of a given value, represented as html element with |
|
1023 | Returns boolean value of a given value, represented as html element with | |
1024 | classes that will represent icons |
|
1024 | classes that will represent icons | |
@@ -1029,8 +1029,9 b' def bool2icon(value):' | |||||
1029 | if value: # does bool conversion |
|
1029 | if value: # does bool conversion | |
1030 | return HTML.tag('i', class_="icon-true") |
|
1030 | return HTML.tag('i', class_="icon-true") | |
1031 | else: # not true as bool |
|
1031 | else: # not true as bool | |
1032 | return HTML.tag('i', class_="icon-false") |
|
1032 | if show_at_false: | |
1033 |
|
1033 | return HTML.tag('i', class_="icon-false") | ||
|
1034 | return HTML.tag('i') | |||
1034 |
|
1035 | |||
1035 | #============================================================================== |
|
1036 | #============================================================================== | |
1036 | # PERMS |
|
1037 | # PERMS |
@@ -264,7 +264,7 b' class WhooshResultWrapper(object):' | |||||
264 | # inside hit object, and we don't need all |
|
264 | # inside hit object, and we don't need all | |
265 | res = dict(hit) |
|
265 | res = dict(hit) | |
266 |
|
266 | |||
267 |
f_path = '' # |
|
267 | f_path = '' # pragma: no cover | |
268 | if self.search_type in ['content', 'path']: |
|
268 | if self.search_type in ['content', 'path']: | |
269 | f_path = res['path'][len(res['repository']):] |
|
269 | f_path = res['path'][len(res['repository']):] | |
270 | f_path = f_path.lstrip(os.sep) |
|
270 | f_path = f_path.lstrip(os.sep) |
@@ -126,7 +126,8 b' class ColorFormatter(ExceptionAwareForma' | |||||
126 | def _inject_req_id(record): |
|
126 | def _inject_req_id(record): | |
127 | from pyramid.threadlocal import get_current_request |
|
127 | from pyramid.threadlocal import get_current_request | |
128 | req = get_current_request() |
|
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 | record.req_id = req_id |
|
131 | record.req_id = req_id | |
131 |
|
132 | |||
132 |
|
133 |
@@ -22,36 +22,7 b' import re' | |||||
22 |
|
22 | |||
23 | import markdown |
|
23 | import markdown | |
24 |
|
24 | |||
25 |
from mdx_gfm import GithubFlavoredMarkdownExtension # |
|
25 | from mdx_gfm import GithubFlavoredMarkdownExtension # pragma: no cover | |
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) |
|
|||
55 |
|
26 | |||
56 |
|
27 | |||
57 | class FlavoredCheckboxPostprocessor(markdown.postprocessors.Postprocessor): |
|
28 | class FlavoredCheckboxPostprocessor(markdown.postprocessors.Postprocessor): |
@@ -40,8 +40,7 b' from docutils.writers import html4css1' | |||||
40 | import markdown |
|
40 | import markdown | |
41 |
|
41 | |||
42 | from rhodecode.lib.markdown_ext import GithubFlavoredMarkdownExtension |
|
42 | from rhodecode.lib.markdown_ext import GithubFlavoredMarkdownExtension | |
43 | from rhodecode.lib.utils2 import ( |
|
43 | from rhodecode.lib.utils2 import (safe_unicode, md5_safe, MENTIONS_REGEX) | |
44 | safe_str, safe_unicode, md5_safe, MENTIONS_REGEX) |
|
|||
45 |
|
44 | |||
46 | log = logging.getLogger(__name__) |
|
45 | log = logging.getLogger(__name__) | |
47 |
|
46 | |||
@@ -172,6 +171,32 b' def relative_path(path, request_path, is' | |||||
172 | return u'/' + final_path |
|
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 | class MarkupRenderer(object): |
|
200 | class MarkupRenderer(object): | |
176 | RESTRUCTUREDTEXT_DISALLOWED_DIRECTIVES = ['include', 'meta', 'raw'] |
|
201 | RESTRUCTUREDTEXT_DISALLOWED_DIRECTIVES = ['include', 'meta', 'raw'] | |
177 |
|
202 | |||
@@ -183,14 +208,10 b' class MarkupRenderer(object):' | |||||
183 | URL_PAT = re.compile(r'(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]' |
|
208 | URL_PAT = re.compile(r'(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]' | |
184 | r'|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)') |
|
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 | output_format = 'html4' |
|
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 | # extension together with weights. Lower is first means we control how |
|
216 | # extension together with weights. Lower is first means we control how | |
196 | # extensions are attached to readme names with those. |
|
217 | # extensions are attached to readme names with those. | |
@@ -346,9 +367,11 b' class MarkupRenderer(object):' | |||||
346 | """ |
|
367 | """ | |
347 |
|
368 | |||
348 | if flavored: |
|
369 | if flavored: | |
349 |
markdown_renderer = |
|
370 | markdown_renderer = get_markdown_renderer_flavored( | |
|
371 | cls.extensions, cls.output_format) | |||
350 | else: |
|
372 | else: | |
351 |
markdown_renderer = |
|
373 | markdown_renderer = get_markdown_renderer( | |
|
374 | cls.extensions, cls.output_format) | |||
352 |
|
375 | |||
353 | if mentions: |
|
376 | if mentions: | |
354 | mention_pat = re.compile(MENTIONS_REGEX) |
|
377 | mention_pat = re.compile(MENTIONS_REGEX) | |
@@ -452,7 +475,7 b' class MarkupRenderer(object):' | |||||
452 |
|
475 | |||
453 | return nb, resources |
|
476 | return nb, resources | |
454 |
|
477 | |||
455 | def _sanitize_resources(resources): |
|
478 | def _sanitize_resources(input_resources): | |
456 | """ |
|
479 | """ | |
457 | Skip/sanitize some of the CSS generated and included in jupyter |
|
480 | Skip/sanitize some of the CSS generated and included in jupyter | |
458 | so it doesn't messes up UI so much |
|
481 | so it doesn't messes up UI so much | |
@@ -464,8 +487,8 b' class MarkupRenderer(object):' | |||||
464 | # _default_template_path_default, to achieve that |
|
487 | # _default_template_path_default, to achieve that | |
465 |
|
488 | |||
466 | # strip the reset CSS |
|
489 | # strip the reset CSS | |
467 | resources[0] = resources[0][resources[0].find('/*! Source'):] |
|
490 | input_resources[0] = input_resources[0][input_resources[0].find('/*! Source'):] | |
468 | return resources |
|
491 | return input_resources | |
469 |
|
492 | |||
470 | def as_html(notebook): |
|
493 | def as_html(notebook): | |
471 | conf = Config() |
|
494 | conf = Config() |
@@ -69,6 +69,11 b' class SimpleHg(simplevcs.SimpleVCS):' | |||||
69 | 'statlfile': 'pull', |
|
69 | 'statlfile': 'pull', | |
70 | 'lheads': 'pull', |
|
70 | 'lheads': 'pull', | |
71 |
|
71 | |||
|
72 | # evolve | |||
|
73 | 'evoext_obshashrange_v1': 'pull', | |||
|
74 | 'evoext_obshash': 'pull', | |||
|
75 | 'evoext_obshash1': 'pull', | |||
|
76 | ||||
72 | 'unbundle': 'push', |
|
77 | 'unbundle': 'push', | |
73 | 'pushkey': 'push', |
|
78 | 'pushkey': 'push', | |
74 | } |
|
79 | } |
@@ -20,7 +20,7 b'' | |||||
20 |
|
20 | |||
21 | import os |
|
21 | import os | |
22 | from pyramid.compat import configparser |
|
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 | from pyramid.scripting import prepare |
|
24 | from pyramid.scripting import prepare | |
25 |
|
25 | |||
26 | from rhodecode.lib.request import Request |
|
26 | from rhodecode.lib.request import Request | |
@@ -37,6 +37,23 b' def get_app_config(ini_path):' | |||||
37 | return appconfig('config:{}'.format(ini_path), relative_to=os.getcwd()) |
|
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 | def bootstrap(config_uri, request=None, options=None, env=None): |
|
57 | def bootstrap(config_uri, request=None, options=None, env=None): | |
41 | if env: |
|
58 | if env: | |
42 | os.environ.update(env) |
|
59 | os.environ.update(env) | |
@@ -48,7 +65,7 b' def bootstrap(config_uri, request=None, ' | |||||
48 | except (configparser.NoSectionError, configparser.NoOptionError): |
|
65 | except (configparser.NoSectionError, configparser.NoOptionError): | |
49 | pass |
|
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 | return pyramid_bootstrap(config_uri, request=request, options=options) |
|
70 | return pyramid_bootstrap(config_uri, request=request, options=options) | |
54 |
|
71 |
@@ -50,8 +50,8 b' from rhodecode.lib.vcs.exceptions import' | |||||
50 | log = logging.getLogger(__name__) |
|
50 | log = logging.getLogger(__name__) | |
51 |
|
51 | |||
52 |
|
52 | |||
53 | FILEMODE_DEFAULT = 0100644 |
|
53 | FILEMODE_DEFAULT = 0o100644 | |
54 | FILEMODE_EXECUTABLE = 0100755 |
|
54 | FILEMODE_EXECUTABLE = 0o100755 | |
55 |
|
55 | |||
56 | Reference = collections.namedtuple('Reference', ('type', 'name', 'commit_id')) |
|
56 | Reference = collections.namedtuple('Reference', ('type', 'name', 'commit_id')) | |
57 | MergeResponse = collections.namedtuple( |
|
57 | MergeResponse = collections.namedtuple( | |
@@ -209,7 +209,7 b' class BaseRepository(object):' | |||||
209 | def get_create_shadow_cache_pr_path(self, db_repo): |
|
209 | def get_create_shadow_cache_pr_path(self, db_repo): | |
210 | path = db_repo.cached_diffs_dir |
|
210 | path = db_repo.cached_diffs_dir | |
211 | if not os.path.exists(path): |
|
211 | if not os.path.exists(path): | |
212 | os.makedirs(path, 0755) |
|
212 | os.makedirs(path, 0o755) | |
213 | return path |
|
213 | return path | |
214 |
|
214 | |||
215 | @classmethod |
|
215 | @classmethod | |
@@ -942,13 +942,13 b' class BaseCommit(object):' | |||||
942 | """ |
|
942 | """ | |
943 | raise NotImplementedError |
|
943 | raise NotImplementedError | |
944 |
|
944 | |||
945 |
def get_ |
|
945 | def get_path_commit(self, path, pre_load=None): | |
946 | """ |
|
946 | """ | |
947 | Returns last commit of the file at the given `path`. |
|
947 | Returns last commit of the file at the given `path`. | |
948 |
|
948 | |||
949 | :param pre_load: Optional. List of commit attributes to load. |
|
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 | if not commits: |
|
952 | if not commits: | |
953 | raise RepositoryError( |
|
953 | raise RepositoryError( | |
954 | 'Failed to fetch history for path {}. ' |
|
954 | 'Failed to fetch history for path {}. ' | |
@@ -956,7 +956,7 b' class BaseCommit(object):' | |||||
956 | path)) |
|
956 | path)) | |
957 | return commits[0] |
|
957 | return commits[0] | |
958 |
|
958 | |||
959 |
def get_ |
|
959 | def get_path_history(self, path, limit=None, pre_load=None): | |
960 | """ |
|
960 | """ | |
961 | Returns history of file as reversed list of :class:`BaseCommit` |
|
961 | Returns history of file as reversed list of :class:`BaseCommit` | |
962 | objects for which file at given `path` has been modified. |
|
962 | objects for which file at given `path` has been modified. | |
@@ -1046,7 +1046,7 b' class BaseCommit(object):' | |||||
1046 | ('tags', ','.join(self.tags)), |
|
1046 | ('tags', ','.join(self.tags)), | |
1047 | ] |
|
1047 | ] | |
1048 | meta = ["%s:%s" % (f_name, value) for f_name, value in metadata] |
|
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 | connection.Hg.archive_repo(file_path, mtime, file_info, kind) |
|
1051 | connection.Hg.archive_repo(file_path, mtime, file_info, kind) | |
1052 |
|
1052 | |||
@@ -1194,8 +1194,8 b' class BaseCommit(object):' | |||||
1194 | self.idx = value |
|
1194 | self.idx = value | |
1195 |
|
1195 | |||
1196 | def get_file_changeset(self, path): |
|
1196 | def get_file_changeset(self, path): | |
1197 |
warnings.warn("Use get_ |
|
1197 | warnings.warn("Use get_path_commit instead", DeprecationWarning) | |
1198 |
return self.get_ |
|
1198 | return self.get_path_commit(path) | |
1199 |
|
1199 | |||
1200 |
|
1200 | |||
1201 | class BaseChangesetClass(type): |
|
1201 | class BaseChangesetClass(type): | |
@@ -1502,7 +1502,7 b' class EmptyCommit(BaseCommit):' | |||||
1502 | def id(self): |
|
1502 | def id(self): | |
1503 | return self.raw_id |
|
1503 | return self.raw_id | |
1504 |
|
1504 | |||
1505 |
def get_ |
|
1505 | def get_path_commit(self, path): | |
1506 | return self |
|
1506 | return self | |
1507 |
|
1507 | |||
1508 | def get_file_content(self, path): |
|
1508 | def get_file_content(self, path): |
@@ -298,7 +298,7 b' class GitCommit(base.BaseCommit):' | |||||
298 | id_, _ = self._get_id_for_path(path) |
|
298 | id_, _ = self._get_id_for_path(path) | |
299 | return self._remote.blob_raw_length(id_) |
|
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 | Returns history of file as reversed list of `GitCommit` objects for |
|
303 | Returns history of file as reversed list of `GitCommit` objects for | |
304 | which file at given `path` has been modified. |
|
304 | which file at given `path` has been modified. | |
@@ -321,21 +321,6 b' class GitCommit(base.BaseCommit):' | |||||
321 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) |
|
321 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) | |
322 | for commit_id in commit_ids] |
|
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 | def get_file_annotate(self, path, pre_load=None): |
|
324 | def get_file_annotate(self, path, pre_load=None): | |
340 | """ |
|
325 | """ | |
341 | Returns a generator of four element tuples with |
|
326 | Returns a generator of four element tuples with |
@@ -161,7 +161,7 b' class GitRepository(BaseRepository):' | |||||
161 | GitRepository.check_url(src_url, self.config) |
|
161 | GitRepository.check_url(src_url, self.config) | |
162 |
|
162 | |||
163 | if create: |
|
163 | if create: | |
164 | os.makedirs(self.path, mode=0755) |
|
164 | os.makedirs(self.path, mode=0o755) | |
165 |
|
165 | |||
166 | if bare: |
|
166 | if bare: | |
167 | self._remote.init_bare() |
|
167 | self._remote.init_bare() |
@@ -252,13 +252,13 b' class MercurialCommit(base.BaseCommit):' | |||||
252 | path = self._get_filectx(path) |
|
252 | path = self._get_filectx(path) | |
253 | return self._remote.fctx_size(self.idx, path) |
|
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 | Returns history of file as reversed list of `MercurialCommit` objects |
|
257 | Returns history of file as reversed list of `MercurialCommit` objects | |
258 | for which file at given ``path`` has been modified. |
|
258 | for which file at given ``path`` has been modified. | |
259 | """ |
|
259 | """ | |
260 | path = self._get_filectx(path) |
|
260 | path = self._get_filectx(path) | |
261 |
hist = self._remote. |
|
261 | hist = self._remote.node_history(self.idx, path, limit) | |
262 | return [ |
|
262 | return [ | |
263 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) |
|
263 | self.repository.get_commit(commit_id=commit_id, pre_load=pre_load) | |
264 | for commit_id in hist] |
|
264 | for commit_id in hist] |
@@ -355,7 +355,7 b' class MercurialRepository(BaseRepository' | |||||
355 | create = False |
|
355 | create = False | |
356 |
|
356 | |||
357 | if create: |
|
357 | if create: | |
358 | os.makedirs(self.path, mode=0755) |
|
358 | os.makedirs(self.path, mode=0o755) | |
359 |
|
359 | |||
360 | self._remote.localrepository(create) |
|
360 | self._remote.localrepository(create) | |
361 |
|
361 |
@@ -121,7 +121,7 b' class SubversionCommit(base.BaseCommit):' | |||||
121 | path = self._fix_path(path) |
|
121 | path = self._fix_path(path) | |
122 | return self._remote.get_file_size(safe_str(path), self._svn_rev) |
|
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 | path = safe_str(self._fix_path(path)) |
|
125 | path = safe_str(self._fix_path(path)) | |
126 | history = self._remote.node_history(path, self._svn_rev, limit) |
|
126 | history = self._remote.node_history(path, self._svn_rev, limit) | |
127 | return [ |
|
127 | return [ |
@@ -31,7 +31,7 b' import greenlet' | |||||
31 |
|
31 | |||
32 | # Import everything from pycurl. |
|
32 | # Import everything from pycurl. | |
33 | # This allows us to use this module as a drop in replacement of pycurl. |
|
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 | from gevent import core |
|
36 | from gevent import core | |
37 | from gevent.hub import Waiter |
|
37 | from gevent.hub import Waiter |
@@ -404,7 +404,7 b' class FileNode(Node):' | |||||
404 | def last_commit(self): |
|
404 | def last_commit(self): | |
405 | if self.commit: |
|
405 | if self.commit: | |
406 | pre_load = ["author", "date", "message"] |
|
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 | raise NodeError( |
|
408 | raise NodeError( | |
409 | "Cannot retrieve last commit of the file without " |
|
409 | "Cannot retrieve last commit of the file without " | |
410 | "related commit attribute") |
|
410 | "related commit attribute") | |
@@ -510,7 +510,7 b' class FileNode(Node):' | |||||
510 | """ |
|
510 | """ | |
511 | if self.commit is None: |
|
511 | if self.commit is None: | |
512 | raise NodeError('Unable to get commit for this FileNode') |
|
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 | @LazyProperty |
|
515 | @LazyProperty | |
516 | def annotate(self): |
|
516 | def annotate(self): | |
@@ -724,6 +724,15 b' class DirNode(Node):' | |||||
724 |
|
724 | |||
725 | return size |
|
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 | def __repr__(self): |
|
736 | def __repr__(self): | |
728 | return '<%s %r @ %s>' % (self.__class__.__name__, self.path, |
|
737 | return '<%s %r @ %s>' % (self.__class__.__name__, self.path, | |
729 | getattr(self.commit, 'short_id', '')) |
|
738 | getattr(self.commit, 'short_id', '')) |
@@ -21,6 +21,7 b'' | |||||
21 |
|
21 | |||
22 | import logging |
|
22 | import logging | |
23 |
|
23 | |||
|
24 | import rhodecode | |||
24 | from rhodecode.model import meta, db |
|
25 | from rhodecode.model import meta, db | |
25 | from rhodecode.lib.utils2 import obfuscate_url_pw, get_encryption_key |
|
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 | :param engine: engine to bind to |
|
37 | :param engine: engine to bind to | |
37 | """ |
|
38 | """ | |
38 | engine_str = obfuscate_url_pw(str(engine.url)) |
|
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 | meta.Base.metadata.bind = engine |
|
41 | meta.Base.metadata.bind = engine | |
41 | db.ENCRYPTION_KEY = encryption_key |
|
42 | db.ENCRYPTION_KEY = encryption_key | |
42 |
|
43 |
@@ -40,12 +40,12 b' from sqlalchemy import (' | |||||
40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, |
|
40 | Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, | |
41 | Text, Float, PickleType) |
|
41 | Text, Float, PickleType) | |
42 | from sqlalchemy.sql.expression import true, false |
|
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 | from sqlalchemy.orm import ( |
|
44 | from sqlalchemy.orm import ( | |
45 | relationship, joinedload, class_mapper, validates, aliased) |
|
45 | relationship, joinedload, class_mapper, validates, aliased) | |
46 | from sqlalchemy.ext.declarative import declared_attr |
|
46 | from sqlalchemy.ext.declarative import declared_attr | |
47 | from sqlalchemy.ext.hybrid import hybrid_property |
|
47 | from sqlalchemy.ext.hybrid import hybrid_property | |
48 |
from sqlalchemy.exc import IntegrityError # |
|
48 | from sqlalchemy.exc import IntegrityError # pragma: no cover | |
49 | from sqlalchemy.dialects.mysql import LONGTEXT |
|
49 | from sqlalchemy.dialects.mysql import LONGTEXT | |
50 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
50 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
51 |
|
51 | |||
@@ -377,6 +377,12 b' class RhodeCodeSetting(Base, BaseModel):' | |||||
377 | % (self.SETTINGS_TYPES.keys(), val)) |
|
377 | % (self.SETTINGS_TYPES.keys(), val)) | |
378 | self._app_settings_type = val |
|
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 | def __unicode__(self): |
|
386 | def __unicode__(self): | |
381 | return u"<%s('%s:%s[%s]')>" % ( |
|
387 | return u"<%s('%s:%s[%s]')>" % ( | |
382 | self.__class__.__name__, |
|
388 | self.__class__.__name__, | |
@@ -4143,20 +4149,16 b' class ExternalIdentity(Base, BaseModel):' | |||||
4143 | base_table_args |
|
4149 | base_table_args | |
4144 | ) |
|
4150 | ) | |
4145 |
|
4151 | |||
4146 | external_id = Column('external_id', Unicode(255), default=u'', |
|
4152 | external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) | |
4147 | primary_key=True) |
|
|||
4148 | external_username = Column('external_username', Unicode(1024), default=u'') |
|
4153 | external_username = Column('external_username', Unicode(1024), default=u'') | |
4149 | local_user_id = Column('local_user_id', Integer(), |
|
4154 | local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) | |
4150 | ForeignKey('users.user_id'), primary_key=True) |
|
4155 | provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) | |
4151 | provider_name = Column('provider_name', Unicode(255), default=u'', |
|
|||
4152 | primary_key=True) |
|
|||
4153 | access_token = Column('access_token', String(1024), default=u'') |
|
4156 | access_token = Column('access_token', String(1024), default=u'') | |
4154 | alt_token = Column('alt_token', String(1024), default=u'') |
|
4157 | alt_token = Column('alt_token', String(1024), default=u'') | |
4155 | token_secret = Column('token_secret', String(1024), default=u'') |
|
4158 | token_secret = Column('token_secret', String(1024), default=u'') | |
4156 |
|
4159 | |||
4157 | @classmethod |
|
4160 | @classmethod | |
4158 | def by_external_id_and_provider(cls, external_id, provider_name, |
|
4161 | def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): | |
4159 | local_user_id=None): |
|
|||
4160 | """ |
|
4162 | """ | |
4161 | Returns ExternalIdentity instance based on search params |
|
4163 | Returns ExternalIdentity instance based on search params | |
4162 |
|
4164 | |||
@@ -4198,6 +4200,13 b' class ExternalIdentity(Base, BaseModel):' | |||||
4198 | query = query.filter(cls.local_user_id == local_user_id) |
|
4200 | query = query.filter(cls.local_user_id == local_user_id) | |
4199 | return query |
|
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 | class Integration(Base, BaseModel): |
|
4211 | class Integration(Base, BaseModel): | |
4203 | __tablename__ = 'integrations' |
|
4212 | __tablename__ = 'integrations' |
@@ -95,15 +95,14 b' class NotificationModel(BaseModel):' | |||||
95 | log.debug('sending notifications %s to admins: %s', |
|
95 | log.debug('sending notifications %s to admins: %s', | |
96 | notification_type, recipients_objs) |
|
96 | notification_type, recipients_objs) | |
97 | else: |
|
97 | else: | |
98 |
recipients_objs = |
|
98 | recipients_objs = set() | |
99 | for u in recipients: |
|
99 | for u in recipients: | |
100 | obj = self._get_user(u) |
|
100 | obj = self._get_user(u) | |
101 | if obj: |
|
101 | if obj: | |
102 |
recipients_objs.a |
|
102 | recipients_objs.add(obj) | |
103 | else: # we didn't find this user, log the error and carry on |
|
103 | else: # we didn't find this user, log the error and carry on | |
104 | log.error('cannot notify unknown user %r', u) |
|
104 | log.error('cannot notify unknown user %r', u) | |
105 |
|
105 | |||
106 | recipients_objs = set(recipients_objs) |
|
|||
107 | if not recipients_objs: |
|
106 | if not recipients_objs: | |
108 | raise Exception('no valid recipients specified') |
|
107 | raise Exception('no valid recipients specified') | |
109 |
|
108 | |||
@@ -122,7 +121,7 b' class NotificationModel(BaseModel):' | |||||
122 | return notification |
|
121 | return notification | |
123 |
|
122 | |||
124 | # don't send email to person who created this comment |
|
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 | # now notify all recipients in question |
|
126 | # now notify all recipients in question | |
128 |
|
127 |
@@ -1576,10 +1576,8 b' class PullRequestModel(BaseModel):' | |||||
1576 | from rc_reviewers.utils import get_default_reviewers_data |
|
1576 | from rc_reviewers.utils import get_default_reviewers_data | |
1577 | from rc_reviewers.utils import validate_default_reviewers |
|
1577 | from rc_reviewers.utils import validate_default_reviewers | |
1578 | except ImportError: |
|
1578 | except ImportError: | |
1579 |
from rhodecode.apps.repository.utils import |
|
1579 | from rhodecode.apps.repository.utils import get_default_reviewers_data | |
1580 | get_default_reviewers_data |
|
1580 | from rhodecode.apps.repository.utils import validate_default_reviewers | |
1581 | from rhodecode.apps.repository.utils import \ |
|
|||
1582 | validate_default_reviewers |
|
|||
1583 |
|
1581 | |||
1584 | return get_default_reviewers_data, validate_default_reviewers |
|
1582 | return get_default_reviewers_data, validate_default_reviewers | |
1585 |
|
1583 |
@@ -181,7 +181,7 b' class RepoGroupModel(BaseModel):' | |||||
181 | self.check_exist_filesystem(group_name) |
|
181 | self.check_exist_filesystem(group_name) | |
182 | create_path = os.path.join(self.repos_path, group_name) |
|
182 | create_path = os.path.join(self.repos_path, group_name) | |
183 | log.debug('creating new group in %s', create_path) |
|
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 | log.debug('created group in %s', create_path) |
|
185 | log.debug('created group in %s', create_path) | |
186 |
|
186 | |||
187 | def _rename_group(self, old, new): |
|
187 | def _rename_group(self, old, new): |
@@ -582,7 +582,6 b' class VcsSettingsModel(object):' | |||||
582 | self._create_or_update_ui( |
|
582 | self._create_or_update_ui( | |
583 | self.repo_settings, *phases, value=safe_str(data[phases_key])) |
|
583 | self.repo_settings, *phases, value=safe_str(data[phases_key])) | |
584 |
|
584 | |||
585 |
|
||||
586 | def create_or_update_global_hg_settings(self, data): |
|
585 | def create_or_update_global_hg_settings(self, data): | |
587 | largefiles, largefiles_store, phases, hgsubversion, evolve \ |
|
586 | largefiles, largefiles_store, phases, hgsubversion, evolve \ | |
588 | = self.GLOBAL_HG_SETTINGS |
|
587 | = self.GLOBAL_HG_SETTINGS |
@@ -344,8 +344,8 b' class UserModel(BaseModel):' | |||||
344 | new_user.is_new_user = not edit |
|
344 | new_user.is_new_user = not edit | |
345 | # for users that didn's specify auth type, we use RhodeCode built in |
|
345 | # for users that didn's specify auth type, we use RhodeCode built in | |
346 | from rhodecode.authentication.plugins import auth_rhodecode |
|
346 | from rhodecode.authentication.plugins import auth_rhodecode | |
347 |
extern_name = extern_name or auth_rhodecode.RhodeCodeAuthPlugin. |
|
347 | extern_name = extern_name or auth_rhodecode.RhodeCodeAuthPlugin.uid | |
348 |
extern_type = extern_type or auth_rhodecode.RhodeCodeAuthPlugin. |
|
348 | extern_type = extern_type or auth_rhodecode.RhodeCodeAuthPlugin.uid | |
349 |
|
349 | |||
350 | try: |
|
350 | try: | |
351 | new_user.username = username |
|
351 | new_user.username = username | |
@@ -392,14 +392,15 b' class UserModel(BaseModel):' | |||||
392 | log.error(traceback.format_exc()) |
|
392 | log.error(traceback.format_exc()) | |
393 | raise |
|
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 | from rhodecode.model.notification import NotificationModel |
|
397 | from rhodecode.model.notification import NotificationModel | |
397 | from rhodecode.model.notification import EmailNotificationModel |
|
398 | from rhodecode.model.notification import EmailNotificationModel | |
398 |
|
399 | |||
399 | try: |
|
400 | try: | |
400 | form_data['admin'] = False |
|
401 | form_data['admin'] = False | |
401 |
form_data['extern_name'] = |
|
402 | form_data['extern_name'] = extern_name | |
402 |
form_data['extern_type'] = |
|
403 | form_data['extern_type'] = extern_type | |
403 | new_user = self.create(form_data) |
|
404 | new_user = self.create(form_data) | |
404 |
|
405 | |||
405 | self.sa.add(new_user) |
|
406 | self.sa.add(new_user) |
@@ -20,5 +20,5 b'' | |||||
20 |
|
20 | |||
21 | import colander |
|
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 | padding-left: 10px; |
|
27 | padding-left: 10px; | |
28 | } |
|
28 | } | |
29 | li { |
|
29 | li { | |
30 |
list-style-type: |
|
30 | list-style-type: disc; | |
31 | } |
|
|||
32 | li:before { |
|
|||
33 | content: "\2014\00A0"; |
|
|||
34 | } |
|
31 | } | |
35 | .error_message { |
|
32 | .error_message { | |
36 | font-weight: normal; |
|
33 | font-weight: normal; | |
@@ -89,7 +86,9 b'' | |||||
89 | </div> |
|
86 | </div> | |
90 | <div class="main"> |
|
87 | <div class="main"> | |
91 | <h1> |
|
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 | </h1> |
|
92 | </h1> | |
94 | <div class="inner-column"> |
|
93 | <div class="inner-column"> | |
95 | <h4>Possible Causes</h4> |
|
94 | <h4>Possible Causes</h4> |
@@ -254,7 +254,7 b' input[type="button"] {' | |||||
254 | .btn-social { |
|
254 | .btn-social { | |
255 | &:extend(.btn-default); |
|
255 | &:extend(.btn-default); | |
256 | margin: 5px 5px 5px 0px; |
|
256 | margin: 5px 5px 5px 0px; | |
257 |
min-width: 1 |
|
257 | min-width: 160px; | |
258 | } |
|
258 | } | |
259 |
|
259 | |||
260 | // TODO: johbo: check these exceptions |
|
260 | // TODO: johbo: check these exceptions |
@@ -570,14 +570,17 b' div.annotatediv { margin-left: 2px; marg' | |||||
570 |
|
570 | |||
571 | .code { display: block; border:0px !important; } |
|
571 | .code { display: block; border:0px !important; } | |
572 | .code-highlight, /* TODO: dan: merge codehilite into code-highlight */ |
|
572 | .code-highlight, /* TODO: dan: merge codehilite into code-highlight */ | |
|
573 | /* This can be generated with `pygmentize -S default -f html` */ | |||
573 | .codehilite { |
|
574 | .codehilite { | |
574 | .hll { background-color: #ffffcc } |
|
575 | .hll { background-color: #ffffcc } | |
575 | .c { color: #408080; font-style: italic } /* Comment */ |
|
576 | .c { color: #408080; font-style: italic } /* Comment */ | |
576 | .err, .codehilite .err { border: none } /* Error */ |
|
577 | .err, .codehilite .err { border: none } /* Error */ | |
577 | .k { color: #008000; font-weight: bold } /* Keyword */ |
|
578 | .k { color: #008000; font-weight: bold } /* Keyword */ | |
578 | .o { color: #666666 } /* Operator */ |
|
579 | .o { color: #666666 } /* Operator */ | |
|
580 | .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ | |||
579 | .cm { color: #408080; font-style: italic } /* Comment.Multiline */ |
|
581 | .cm { color: #408080; font-style: italic } /* Comment.Multiline */ | |
580 | .cp { color: #BC7A00 } /* Comment.Preproc */ |
|
582 | .cp { color: #BC7A00 } /* Comment.Preproc */ | |
|
583 | .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ | |||
581 | .c1 { color: #408080; font-style: italic } /* Comment.Single */ |
|
584 | .c1 { color: #408080; font-style: italic } /* Comment.Single */ | |
582 | .cs { color: #408080; font-style: italic } /* Comment.Special */ |
|
585 | .cs { color: #408080; font-style: italic } /* Comment.Special */ | |
583 | .gd { color: #A00000 } /* Generic.Deleted */ |
|
586 | .gd { color: #A00000 } /* Generic.Deleted */ | |
@@ -585,11 +588,11 b' div.annotatediv { margin-left: 2px; marg' | |||||
585 | .gr { color: #FF0000 } /* Generic.Error */ |
|
588 | .gr { color: #FF0000 } /* Generic.Error */ | |
586 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ |
|
589 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ | |
587 | .gi { color: #00A000 } /* Generic.Inserted */ |
|
590 | .gi { color: #00A000 } /* Generic.Inserted */ | |
588 |
.go { color: #8 |
|
591 | .go { color: #888888 } /* Generic.Output */ | |
589 | .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ |
|
592 | .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ | |
590 | .gs { font-weight: bold } /* Generic.Strong */ |
|
593 | .gs { font-weight: bold } /* Generic.Strong */ | |
591 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ |
|
594 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ | |
592 |
.gt { color: #004 |
|
595 | .gt { color: #0044DD } /* Generic.Traceback */ | |
593 | .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ |
|
596 | .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ | |
594 | .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ |
|
597 | .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ | |
595 | .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ |
|
598 | .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ | |
@@ -612,12 +615,15 b' div.annotatediv { margin-left: 2px; marg' | |||||
612 | .nv { color: #19177C } /* Name.Variable */ |
|
615 | .nv { color: #19177C } /* Name.Variable */ | |
613 | .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ |
|
616 | .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ | |
614 | .w { color: #bbbbbb } /* Text.Whitespace */ |
|
617 | .w { color: #bbbbbb } /* Text.Whitespace */ | |
|
618 | .mb { color: #666666 } /* Literal.Number.Bin */ | |||
615 | .mf { color: #666666 } /* Literal.Number.Float */ |
|
619 | .mf { color: #666666 } /* Literal.Number.Float */ | |
616 | .mh { color: #666666 } /* Literal.Number.Hex */ |
|
620 | .mh { color: #666666 } /* Literal.Number.Hex */ | |
617 | .mi { color: #666666 } /* Literal.Number.Integer */ |
|
621 | .mi { color: #666666 } /* Literal.Number.Integer */ | |
618 | .mo { color: #666666 } /* Literal.Number.Oct */ |
|
622 | .mo { color: #666666 } /* Literal.Number.Oct */ | |
|
623 | .sa { color: #BA2121 } /* Literal.String.Affix */ | |||
619 | .sb { color: #BA2121 } /* Literal.String.Backtick */ |
|
624 | .sb { color: #BA2121 } /* Literal.String.Backtick */ | |
620 | .sc { color: #BA2121 } /* Literal.String.Char */ |
|
625 | .sc { color: #BA2121 } /* Literal.String.Char */ | |
|
626 | .dl { color: #BA2121 } /* Literal.String.Delimiter */ | |||
621 | .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ |
|
627 | .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ | |
622 | .s2 { color: #BA2121 } /* Literal.String.Double */ |
|
628 | .s2 { color: #BA2121 } /* Literal.String.Double */ | |
623 | .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ |
|
629 | .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ | |
@@ -628,9 +634,11 b' div.annotatediv { margin-left: 2px; marg' | |||||
628 | .s1 { color: #BA2121 } /* Literal.String.Single */ |
|
634 | .s1 { color: #BA2121 } /* Literal.String.Single */ | |
629 | .ss { color: #19177C } /* Literal.String.Symbol */ |
|
635 | .ss { color: #19177C } /* Literal.String.Symbol */ | |
630 | .bp { color: #008000 } /* Name.Builtin.Pseudo */ |
|
636 | .bp { color: #008000 } /* Name.Builtin.Pseudo */ | |
|
637 | .fm { color: #0000FF } /* Name.Function.Magic */ | |||
631 | .vc { color: #19177C } /* Name.Variable.Class */ |
|
638 | .vc { color: #19177C } /* Name.Variable.Class */ | |
632 | .vg { color: #19177C } /* Name.Variable.Global */ |
|
639 | .vg { color: #19177C } /* Name.Variable.Global */ | |
633 | .vi { color: #19177C } /* Name.Variable.Instance */ |
|
640 | .vi { color: #19177C } /* Name.Variable.Instance */ | |
|
641 | .vm { color: #19177C } /* Name.Variable.Magic */ | |||
634 | .il { color: #666666 } /* Literal.Number.Integer.Long */ |
|
642 | .il { color: #666666 } /* Literal.Number.Integer.Long */ | |
635 | } |
|
643 | } | |
636 |
|
644 |
@@ -548,10 +548,9 b' form.comment-form {' | |||||
548 | } |
|
548 | } | |
549 | .nav-links li { |
|
549 | .nav-links li { | |
550 | display: inline-block; |
|
550 | display: inline-block; | |
|
551 | list-style-type: none; | |||
551 | } |
|
552 | } | |
552 | .nav-links li:before { |
|
553 | ||
553 | content: ""; |
|
|||
554 | } |
|
|||
555 | .nav-links li a.disabled { |
|
554 | .nav-links li a.disabled { | |
556 | cursor: not-allowed; |
|
555 | cursor: not-allowed; | |
557 | } |
|
556 | } |
@@ -219,7 +219,6 b' form.rcform {' | |||||
219 | li { |
|
219 | li { | |
220 | list-style-type: none; |
|
220 | list-style-type: none; | |
221 |
|
221 | |||
222 | &:before { content:none; } |
|
|||
223 | &:after { |
|
222 | &:after { | |
224 | content: ""; |
|
223 | content: ""; | |
225 | float: left; |
|
224 | float: left; |
@@ -43,7 +43,9 b' a { cursor: pointer; }' | |||||
43 | float: right; |
|
43 | float: right; | |
44 | clear: right; |
|
44 | clear: right; | |
45 |
|
45 | |||
46 | li:before { content:none; } |
|
46 | li { | |
|
47 | list-style-type: none; | |||
|
48 | } | |||
47 | } |
|
49 | } | |
48 |
|
50 | |||
49 | //--- DEVICE-SPECIFIC CLASSES ---------------// |
|
51 | //--- DEVICE-SPECIFIC CLASSES ---------------// |
@@ -126,6 +126,11 b' div.markdown-block h6 {' | |||||
126 | overflow: visible !important; |
|
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 | div.markdown-block h1 { |
|
134 | div.markdown-block h1 { | |
130 | font-size: 32px; |
|
135 | font-size: 32px; | |
131 | margin: 15px 0 15px 0 !important; |
|
136 | margin: 15px 0 15px 0 !important; | |
@@ -135,7 +140,6 b' div.markdown-block h1 {' | |||||
135 | div.markdown-block h2 { |
|
140 | div.markdown-block h2 { | |
136 | font-size: 24px !important; |
|
141 | font-size: 24px !important; | |
137 | margin: 34px 0 10px 0 !important; |
|
142 | margin: 34px 0 10px 0 !important; | |
138 | border-top: 3px #e6e5e5 solid !important; |
|
|||
139 | padding-top: 15px !important; |
|
143 | padding-top: 15px !important; | |
140 | padding-bottom: 8px !important; |
|
144 | padding-bottom: 8px !important; | |
141 | } |
|
145 | } | |
@@ -199,6 +203,7 b' div.markdown-block pre {' | |||||
199 | div.markdown-block img { |
|
203 | div.markdown-block img { | |
200 | border-style: none; |
|
204 | border-style: none; | |
201 | background-color: #fff; |
|
205 | background-color: #fff; | |
|
206 | padding-right: 20px; | |||
202 | } |
|
207 | } | |
203 |
|
208 | |||
204 |
|
209 | |||
@@ -317,9 +322,13 b' div.rst-block h3 {' | |||||
317 | margin: 1em 0 !important; |
|
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 | div.rst-block h2 { |
|
330 | div.rst-block h2 { | |
321 | margin-top: 1.5em !important; |
|
331 | margin-top: 1.5em !important; | |
322 | border-top: 4px solid #e0e0e0 !important; |
|
|||
323 | padding-top: .5em !important; |
|
332 | padding-top: .5em !important; | |
324 | } |
|
333 | } | |
325 |
|
334 |
@@ -196,6 +196,16 b'' | |||||
196 | .text-as-placeholder { |
|
196 | .text-as-placeholder { | |
197 | padding-top: @input-padding-px + @border-thickness-inputs; |
|
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 | // TODO: johbo: Try to find a better integration of this bit. |
|
211 | // TODO: johbo: Try to find a better integration of this bit. |
@@ -315,7 +315,6 b' ul.auth_plugins {' | |||||
315 | margin-right: @padding; |
|
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 | position: relative; |
|
1324 | position: relative; | |
1326 | width: 100%; |
|
1325 | width: 100%; | |
1327 | padding-bottom: 8px; |
|
1326 | padding-bottom: 8px; | |
|
1327 | list-style-type: none; | |||
1328 | } |
|
1328 | } | |
1329 |
|
1329 | |||
1330 | .reviewer_entry { |
|
1330 | .reviewer_entry { | |
@@ -1719,8 +1719,8 b' BIN_FILENODE = 7' | |||||
1719 | padding: 0px 0px; |
|
1719 | padding: 0px 0px; | |
1720 | } |
|
1720 | } | |
1721 |
|
1721 | |||
1722 |
.pull-request-merge li |
|
1722 | .pull-request-merge li { | |
1723 |
|
|
1723 | list-style-type: none; | |
1724 | } |
|
1724 | } | |
1725 |
|
1725 | |||
1726 | .pull-request-merge .pull-request-wrap { |
|
1726 | .pull-request-merge .pull-request-wrap { | |
@@ -1957,7 +1957,7 b' BIN_FILENODE = 7' | |||||
1957 | font-size: @journal-fontsize; |
|
1957 | font-size: @journal-fontsize; | |
1958 | line-height: 1em; |
|
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 | padding: 0 2px; |
|
201 | padding: 0 2px; | |
202 | } |
|
202 | } | |
203 | } |
|
203 | } | |
204 |
|
204 | list-style-type: none; | ||
205 | &:before { content: none; } |
|
|||
206 | } |
|
205 | } | |
207 |
|
206 | |||
208 | > li { |
|
207 | > li { | |
@@ -305,8 +304,7 b'' | |||||
305 | line-height: 1em; |
|
304 | line-height: 1em; | |
306 | color: @grey3; |
|
305 | color: @grey3; | |
307 | background-color: @grey6; |
|
306 | background-color: @grey6; | |
308 |
|
307 | list-style-type: none; | ||
309 | &:before { content: none; } |
|
|||
310 |
|
308 | |||
311 | a { |
|
309 | a { | |
312 | display: block; |
|
310 | display: block; | |
@@ -398,8 +396,6 b'' | |||||
398 | line-height: 1em; |
|
396 | line-height: 1em; | |
399 | list-style-type: none; |
|
397 | list-style-type: none; | |
400 |
|
398 | |||
401 | &:before { content: none; } |
|
|||
402 |
|
||||
403 | a { |
|
399 | a { | |
404 | display: block; |
|
400 | display: block; | |
405 | height: 16px; |
|
401 | height: 16px; | |
@@ -461,8 +457,6 b'' | |||||
461 | line-height: 1em; |
|
457 | line-height: 1em; | |
462 | color: @grey6; |
|
458 | color: @grey6; | |
463 |
|
459 | |||
464 | &:before { content: none; } |
|
|||
465 |
|
||||
466 | &>.select2-result-label { |
|
460 | &>.select2-result-label { | |
467 | padding: 8px 0; |
|
461 | padding: 8px 0; | |
468 | border-bottom: @border-thickness solid @grey3; |
|
462 | border-bottom: @border-thickness solid @grey3; | |
@@ -494,8 +488,7 b'' | |||||
494 | line-height: 1em; |
|
488 | line-height: 1em; | |
495 | font-family: @text-light; |
|
489 | font-family: @text-light; | |
496 | color: @grey2; |
|
490 | color: @grey2; | |
497 |
|
491 | list-style-type: none; | ||
498 | &:before { content: none; } |
|
|||
499 |
|
492 | |||
500 | &:hover { |
|
493 | &:hover { | |
501 | background-color: @grey3; |
|
494 | background-color: @grey3; | |
@@ -520,8 +513,7 b'' | |||||
520 | ul#context-pages { |
|
513 | ul#context-pages { | |
521 | li { |
|
514 | li { | |
522 | line-height: 1em; |
|
515 | line-height: 1em; | |
523 |
|
516 | list-style-type: none; | ||
524 | &:before { content: none; } |
|
|||
525 |
|
517 | |||
526 | a { |
|
518 | a { | |
527 | color: @grey3; |
|
519 | color: @grey3; | |
@@ -622,6 +614,7 b' ul#context-pages {' | |||||
622 | padding-bottom: @menupadding; |
|
614 | padding-bottom: @menupadding; | |
623 | line-height: 1em; |
|
615 | line-height: 1em; | |
624 | color: @grey4; |
|
616 | color: @grey4; | |
|
617 | list-style-type: none; | |||
625 |
|
618 | |||
626 | &.active a { |
|
619 | &.active a { | |
627 | color: @grey2; |
|
620 | color: @grey2; | |
@@ -630,8 +623,6 b' ul#context-pages {' | |||||
630 | a { |
|
623 | a { | |
631 | color: @grey4; |
|
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 | overflow: visible !important; |
|
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 | div.readme_box h1 { |
|
25 | div.readme_box h1 { | |
21 | font-size: 32px; |
|
26 | font-size: 32px; | |
22 | margin: 15px 0 15px 0 !important; |
|
27 | margin: 15px 0 15px 0 !important; | |
@@ -26,7 +31,6 b' div.readme_box h1 {' | |||||
26 | div.readme_box h2 { |
|
31 | div.readme_box h2 { | |
27 | font-size: 24px !important; |
|
32 | font-size: 24px !important; | |
28 | margin: 34px 0 10px 0 !important; |
|
33 | margin: 34px 0 10px 0 !important; | |
29 | border-top: 3px #e6e5e5 solid !important; |
|
|||
30 | padding-top: 15px !important; |
|
34 | padding-top: 15px !important; | |
31 | padding-bottom: 8px !important; |
|
35 | padding-bottom: 8px !important; | |
32 | } |
|
36 | } | |
@@ -90,6 +94,7 b' div.readme_box pre {' | |||||
90 | div.readme_box img { |
|
94 | div.readme_box img { | |
91 | border-style: none; |
|
95 | border-style: none; | |
92 | background-color: #fff; |
|
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 | div.readme_box ul li, |
|
113 | div.readme_box ul li, | |
109 | div.readme_box ol li { |
|
114 | div.readme_box ol li { | |
110 |
list-style: |
|
115 | list-style: disc !important; | |
111 | margin: 6px !important; |
|
116 | margin: 6px !important; | |
112 | padding: 0 !important; |
|
117 | padding: 0 !important; | |
113 | } |
|
118 | } |
@@ -174,8 +174,6 b' select.select2{height:28px;visibility:hi' | |||||
174 | line-height: 1em; |
|
174 | line-height: 1em; | |
175 | list-style-type: none; |
|
175 | list-style-type: none; | |
176 |
|
176 | |||
177 | &:before { content: none; } |
|
|||
178 |
|
||||
179 | &:hover, |
|
177 | &:hover, | |
180 | &.select2-highlighted { |
|
178 | &.select2-highlighted { | |
181 | background-color: @rclightblue; |
|
179 | background-color: @rclightblue; |
@@ -104,11 +104,7 b'' | |||||
104 | padding-left: 0; |
|
104 | padding-left: 0; | |
105 |
|
105 | |||
106 | li { |
|
106 | li { | |
107 |
|
107 | list-style-type: none; | ||
108 | &:before { |
|
|||
109 | content: none; |
|
|||
110 | width: 0; |
|
|||
111 | } |
|
|||
112 | } |
|
108 | } | |
113 | } |
|
109 | } | |
114 | } |
|
110 | } |
@@ -64,7 +64,9 b' table.dataTable {' | |||||
64 | .expired td { |
|
64 | .expired td { | |
65 | background-color: @grey7; |
|
65 | background-color: @grey7; | |
66 | } |
|
66 | } | |
67 |
|
67 | .inactive td { | ||
|
68 | background-color: @grey6; | |||
|
69 | } | |||
68 | th { |
|
70 | th { | |
69 | text-align: left; |
|
71 | text-align: left; | |
70 | font-weight: @text-semibold-weight; |
|
72 | font-weight: @text-semibold-weight; |
@@ -49,8 +49,6 b'' | |||||
49 | margin: 0 0 @padding; |
|
49 | margin: 0 0 @padding; | |
50 | line-height: 1em; |
|
50 | line-height: 1em; | |
51 | list-style-type: none; |
|
51 | list-style-type: none; | |
52 |
|
||||
53 | &:before { content: none; } |
|
|||
54 | } |
|
52 | } | |
55 | } |
|
53 | } | |
56 |
|
54 |
@@ -274,8 +274,11 b' mark,' | |||||
274 | list-style: none; |
|
274 | list-style: none; | |
275 | text-align: right; |
|
275 | text-align: right; | |
276 |
|
276 | |||
277 | li:before { content: none; } |
|
277 | li { | |
278 |
|
|
278 | float: right; | |
|
279 | list-style-type: none; | |||
|
280 | } | |||
|
281 | ||||
279 | a { |
|
282 | a { | |
280 | display: inline-block; |
|
283 | display: inline-block; | |
281 | margin-left: @textmargin/2; |
|
284 | margin-left: @textmargin/2; | |
@@ -338,15 +341,7 b' li {' | |||||
338 |
|
341 | |||
339 | ul li { |
|
342 | ul li { | |
340 | position: relative; |
|
343 | position: relative; | |
341 | display: block; |
|
344 | list-style-type: disc; | |
342 | list-style-type: none; |
|
|||
343 |
|
||||
344 | &:before { |
|
|||
345 | content: "\2014\00A0"; |
|
|||
346 | position: absolute; |
|
|||
347 | top: 0; |
|
|||
348 | left: -1.25em; |
|
|||
349 | } |
|
|||
350 |
|
345 | |||
351 | p:first-child { |
|
346 | p:first-child { | |
352 | display:inline; |
|
347 | display:inline; | |
@@ -539,7 +534,7 b' address {' | |||||
539 | color: @grey4; |
|
534 | color: @grey4; | |
540 | font-family: @text-light; |
|
535 | font-family: @text-light; | |
541 | &.pre-formatting { |
|
536 | &.pre-formatting { | |
542 | white-space: pre; |
|
537 | white-space: pre-wrap; | |
543 | } |
|
538 | } | |
544 | } |
|
539 | } | |
545 |
|
540 |
@@ -125,7 +125,7 b'' | |||||
125 | @label-summary-minwidth: 80px; |
|
125 | @label-summary-minwidth: 80px; | |
126 | @search-form-width: 400px; |
|
126 | @search-form-width: 400px; | |
127 | @fields-input-m: 400px; |
|
127 | @fields-input-m: 400px; | |
128 |
@fields-input-l: |
|
128 | @fields-input-l: 720px; | |
129 |
|
129 | |||
130 | // BUTTONS |
|
130 | // BUTTONS | |
131 | @button-padding: .9em; |
|
131 | @button-padding: .9em; |
@@ -14,7 +14,6 b' function registerRCRoutes() {' | |||||
14 | // routes registration |
|
14 | // routes registration | |
15 | pyroutes.register('favicon', '/favicon.ico', []); |
|
15 | pyroutes.register('favicon', '/favicon.ico', []); | |
16 | pyroutes.register('robots', '/robots.txt', []); |
|
16 | pyroutes.register('robots', '/robots.txt', []); | |
17 | pyroutes.register('auth_home', '/_admin/auth*traverse', []); |
|
|||
18 | pyroutes.register('global_integrations_new', '/_admin/integrations/new', []); |
|
17 | pyroutes.register('global_integrations_new', '/_admin/integrations/new', []); | |
19 | pyroutes.register('global_integrations_home', '/_admin/integrations', []); |
|
18 | pyroutes.register('global_integrations_home', '/_admin/integrations', []); | |
20 | pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']); |
|
19 | pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']); | |
@@ -30,6 +29,7 b' function registerRCRoutes() {' | |||||
30 | pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']); |
|
29 | pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']); | |
31 | pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']); |
|
30 | pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']); | |
32 | pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']); |
|
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 | pyroutes.register('ops_ping', '/_admin/ops/ping', []); |
|
33 | pyroutes.register('ops_ping', '/_admin/ops/ping', []); | |
34 | pyroutes.register('ops_error_test', '/_admin/ops/error', []); |
|
34 | pyroutes.register('ops_error_test', '/_admin/ops/error', []); | |
35 | pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []); |
|
35 | pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []); |
@@ -475,11 +475,10 b' class RcServerCommand(object):' | |||||
475 | msg = '' |
|
475 | msg = '' | |
476 | self.out('Exiting%s (-v to see traceback)' % msg) |
|
476 | self.out('Exiting%s (-v to see traceback)' % msg) | |
477 |
|
477 | |||
478 |
|
||||
479 | def loadapp(self, app_spec, name, relative_to, **kw): # pragma: no cover |
|
478 | def loadapp(self, app_spec, name, relative_to, **kw): # pragma: no cover | |
480 | return loadapp(app_spec, name=name, relative_to=relative_to, **kw) |
|
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 | return loadserver( |
|
482 | return loadserver( | |
484 | server_spec, name=name, relative_to=relative_to, **kw) |
|
483 | server_spec, name=name, relative_to=relative_to, **kw) | |
485 |
|
484 |
@@ -39,48 +39,56 b'' | |||||
39 |
|
39 | |||
40 | <div class="main-content-full-width"> |
|
40 | <div class="main-content-full-width"> | |
41 | ${h.secure_form(request.resource_path(resource, route_name='auth_home'), request=request)} |
|
41 | ${h.secure_form(request.resource_path(resource, route_name='auth_home'), request=request)} | |
42 | <div class="form"> |
|
|||
43 |
|
||||
44 | <div class="panel panel-default"> |
|
42 | <div class="panel panel-default"> | |
45 |
|
43 | |||
46 | <div class="panel-heading"> |
|
44 | <div class="panel-heading"> | |
47 | <h3 class="panel-title">${_("Enabled and Available Plugins")}</h3> |
|
45 | <h3 class="panel-title">${_("Enabled and Available Plugins")}</h3> | |
48 | </div> |
|
46 | </div> | |
49 |
|
47 | |||
50 |
<div class=" |
|
48 | <div class="panel-body"> | |
51 |
|
49 | |||
52 | <div class="field"> |
|
50 | ||
53 |
<div class="label">${_(" |
|
51 | <div class="label">${_("Ordered Activated Plugins")}</div> | |
54 | <div class="textarea text-area editor"> |
|
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 | </div> |
|
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 | '\nThe order of the plugins is also the order in which ' |
|
57 | '\nThe order of the plugins is also the order in which ' | |
59 |
'RhodeCode Enterprise will try to authenticate a user.')} |
|
58 | 'RhodeCode Enterprise will try to authenticate a user.')} | |
60 |
</ |
|
59 | </p> | |
|
60 | </div> | |||
61 |
|
61 | |||
62 |
< |
|
62 | <table class="rctable"> | |
63 | <div class="label">${_('Available Built-in Plugins')}</div> |
|
63 | <th>${_('Activate')}</th> | |
64 | <ul class="auth_plugins"> |
|
64 | <th>${_('Plugin Name')}</th> | |
65 | %for plugin in available_plugins: |
|
65 | <th>${_('Documentation')}</th> | |
66 | <li> |
|
66 | <th>${_('Plugin ID')}</th> | |
67 | <div class="auth_buttons"> |
|
67 | <th>${_('Enabled')}</th> | |
68 | <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${'btn-success' if plugin.get_id() in enabled_plugins else ''}"> |
|
68 | %for plugin in available_plugins: | |
69 |
|
|
69 | <tr class="${'inactive' if (not plugin.is_active() and plugin.get_id() in enabled_plugins) else ''}"> | |
70 |
< |
|
70 | <td> | |
71 | ${plugin.get_display_name()} (${plugin.get_id()}) |
|
71 | <span plugin_id="${plugin.get_id()}" class="toggle-plugin btn ${'btn-success' if plugin.get_id() in enabled_plugins else ''}"> | |
72 | </div> |
|
72 | ${_('activated') if plugin.get_id() in enabled_plugins else _('not active')} | |
73 |
</ |
|
73 | </span> | |
74 | %endfor |
|
74 | </td> | |
75 | </ul> |
|
75 | <td>${plugin.get_display_name()}</td> | |
76 |
< |
|
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 | <div class="buttons"> |
|
87 | <div class="buttons"> | |
79 | ${h.submit('save',_('Save'),class_="btn")} |
|
88 | ${h.submit('save',_('Save'),class_="btn")} | |
80 | </div> |
|
89 | </div> | |
81 | </div> |
|
90 | </div> | |
82 | </div> |
|
91 | </div> | |
83 | </div> |
|
|||
84 | ${h.end_form()} |
|
92 | ${h.end_form()} | |
85 | </div> |
|
93 | </div> | |
86 | </div> |
|
94 | </div> | |
@@ -103,15 +111,15 b'' | |||||
103 | elems.splice(elems.indexOf(plugin_id), 1); |
|
111 | elems.splice(elems.indexOf(plugin_id), 1); | |
104 | auth_plugins_input.val(elems.join(',\n')); |
|
112 | auth_plugins_input.val(elems.join(',\n')); | |
105 | $(cur_button).removeClass('btn-success'); |
|
113 | $(cur_button).removeClass('btn-success'); | |
106 |
cur_button.innerHTML = _gettext(' |
|
114 | cur_button.innerHTML = _gettext('not active'); | |
107 | } |
|
115 | } | |
108 | else{ |
|
116 | else{ | |
109 | if(elems.indexOf(plugin_id) == -1){ |
|
117 | if (elems.indexOf(plugin_id) === -1) { | |
110 | elems.push(plugin_id); |
|
118 | elems.push(plugin_id); | |
111 | } |
|
119 | } | |
112 | auth_plugins_input.val(elems.join(',\n')); |
|
120 | auth_plugins_input.val(elems.join(',\n')); | |
113 | $(cur_button).addClass('btn-success'); |
|
121 | $(cur_button).addClass('btn-success'); | |
114 |
cur_button.innerHTML = _gettext(' |
|
122 | cur_button.innerHTML = _gettext('activated'); | |
115 | } |
|
123 | } | |
116 | }); |
|
124 | }); | |
117 | </script> |
|
125 | </script> |
@@ -51,23 +51,29 b'' | |||||
51 | <div class="form"> |
|
51 | <div class="form"> | |
52 |
|
52 | |||
53 | %for node in plugin.get_settings_schema(): |
|
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 | <div class="field"> |
|
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 | <div class="input"> |
|
60 | <div class="input"> | |
58 | %if node.widget in ["string", "int", "unicode"]: |
|
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 | %elif node.widget == "password": |
|
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 | %elif node.widget == "bool": |
|
65 | %elif node.widget == "bool": | |
63 | <div class="checkbox">${h.checkbox(node.name, True, checked=defaults.get(node.name))}</div> |
|
66 | <div class="checkbox">${h.checkbox(node.name, True, checked=defaults.get(node.name))}</div> | |
64 | %elif node.widget == "select": |
|
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 | %elif node.widget == "readonly": |
|
71 | %elif node.widget == "readonly": | |
67 | ${node.default} |
|
72 | ${node.default} | |
68 | %else: |
|
73 | %else: | |
69 | This field is of type ${node.typ}, which cannot be displayed. Must be one of [string|int|bool|select]. |
|
74 | This field is of type ${node.typ}, which cannot be displayed. Must be one of [string|int|bool|select]. | |
70 | %endif |
|
75 | %endif | |
|
76 | ||||
71 |
|
|
77 | %if node.name in errors: | |
72 | <span class="error-message">${errors.get(node.name)}</span> |
|
78 | <span class="error-message">${errors.get(node.name)}</span> | |
73 | <br /> |
|
79 | <br /> | |
@@ -91,6 +97,18 b'' | |||||
91 | ${h.end_form()} |
|
97 | ${h.end_form()} | |
92 | </div> |
|
98 | </div> | |
93 | </div> |
|
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 | </div> |
|
112 | </div> | |
95 | </div> |
|
113 | </div> | |
96 | </div> |
|
114 | </div> | |
@@ -98,8 +116,7 b'' | |||||
98 | </div> |
|
116 | </div> | |
99 | </div> |
|
117 | </div> | |
100 |
|
118 | |||
101 | ## TODO: Ugly hack to get ldap select elements to work. |
|
119 | ||
102 | ## Find a solution to integrate this nicely. |
|
|||
103 | <script> |
|
120 | <script> | |
104 | $(document).ready(function() { |
|
121 | $(document).ready(function() { | |
105 | var select2Options = { |
|
122 | var select2Options = { | |
@@ -107,12 +124,9 b'' | |||||
107 | dropdownCssClass: 'drop-menu-dropdown', |
|
124 | dropdownCssClass: 'drop-menu-dropdown', | |
108 | dropdownAutoWidth: true, |
|
125 | dropdownAutoWidth: true, | |
109 | minimumResultsForSearch: -1 |
|
126 | minimumResultsForSearch: -1 | |
110 |
|
|
127 | }; | |
111 |
|
|
128 | $('.select2AuthSetting').select2(select2Options); | |
112 | $("#tls_reqcert").select2(select2Options); |
|
129 | ||
113 | $("#search_scope").select2(select2Options); |
|
|||
114 | $("#group_extraction_type").select2(select2Options); |
|
|||
115 | $("#admin_groups_sync").select2(select2Options); |
|
|||
116 | }); |
|
130 | }); | |
117 | </script> |
|
131 | </script> | |
118 | </%def> |
|
132 | </%def> |
@@ -32,10 +32,10 b'' | |||||
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> |
|
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 | <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> |
|
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. |
|
35 | ## TODO: Find a better integration of oauth/saml views into navigation. | |
36 |
<% my_account_ |
|
36 | <% my_account_external_url = h.route_path_or_none('my_account_external_identity') %> | |
37 |
% if my_account_ |
|
37 | % if my_account_external_url: | |
38 |
<li class="${'active' if c.active==' |
|
38 | <li class="${'active' if c.active=='external_identity' else ''}"><a href="${my_account_external_url}">${_('External Identities')}</a></li> | |
39 | % endif |
|
39 | % endif | |
40 | <li class="${'active' if c.active=='emails' else ''}"><a href="${h.route_path('my_account_emails')}">${_('Emails')}</a></li> |
|
40 | <li class="${'active' if c.active=='emails' else ''}"><a href="${h.route_path('my_account_emails')}">${_('Emails')}</a></li> | |
41 | <li class="${'active' if c.active=='repos' else ''}"><a href="${h.route_path('my_account_repos')}">${_('Repositories')}</a></li> |
|
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 | % for route_name, view_fqn, view_url, active in c.view_data: |
|
49 | % for route_name, view_fqn, view_url, active in c.view_data: | |
50 | <tr> |
|
50 | <tr> | |
51 | <td class="td-x"> |
|
51 | <td class="td-x"> | |
52 | % if active: |
|
52 | ${h.bool2icon(active, show_at_false=False)} | |
53 | ${h.bool2icon(active)} |
|
|||
54 | % endif |
|
|||
55 | </td> |
|
53 | </td> | |
56 | <td class="td-x">${view_fqn}</td> |
|
54 | <td class="td-x">${view_fqn}</td> | |
57 | <td class="td-x" title="${route_name}">${view_url}</td> |
|
55 | <td class="td-x" title="${route_name}">${view_url}</td> |
@@ -102,6 +102,7 b'' | |||||
102 | <option value="clicky">Clicky</option> |
|
102 | <option value="clicky">Clicky</option> | |
103 | <option value="server_announce">${_('Server Announcement')}</option> |
|
103 | <option value="server_announce">${_('Server Announcement')}</option> | |
104 | <option value="flash_filtering">${_('Flash message filtering')}</option> |
|
104 | <option value="flash_filtering">${_('Flash message filtering')}</option> | |
|
105 | <option value="custom_logo">${_('Custom logos')}</option> | |||
105 | </select> |
|
106 | </select> | |
106 | </div> |
|
107 | </div> | |
107 | <div style="padding: 10px 0px"></div> |
|
108 | <div style="padding: 10px 0px"></div> | |
@@ -212,7 +213,7 b'' | |||||
212 | // This can be used to send a global maintenance messages or other |
|
213 | // This can be used to send a global maintenance messages or other | |
213 | // important messages to all users of the RhodeCode Enterprise system. |
|
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 | // EDIT - put your message below |
|
218 | // EDIT - put your message below | |
218 | var message = "TYPE YOUR MESSAGE HERE"; |
|
219 | var message = "TYPE YOUR MESSAGE HERE"; | |
@@ -248,6 +249,32 b'' | |||||
248 | </%text> |
|
249 | </%text> | |
249 | </script> |
|
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 | <script> |
|
278 | <script> | |
252 | var pre_cm = initCodeMirror('rhodecode_pre_code', '', false); |
|
279 | var pre_cm = initCodeMirror('rhodecode_pre_code', '', false); | |
253 | var pre_old = pre_cm.getValue(); |
|
280 | var pre_old = pre_cm.getValue(); | |
@@ -255,7 +282,7 b' var pre_old = pre_cm.getValue();' | |||||
255 | var post_cm = initCodeMirror('rhodecode_post_code', '', false); |
|
282 | var post_cm = initCodeMirror('rhodecode_post_code', '', false); | |
256 | var post_old = post_cm.getValue(); |
|
283 | var post_old = post_cm.getValue(); | |
257 |
|
284 | |||
258 | var get_data = function(type, old){ |
|
285 | var get_data = function(type, old) { | |
259 | var get_tmpl = function(tmpl_name){ |
|
286 | var get_tmpl = function(tmpl_name){ | |
260 | // unescape some stuff |
|
287 | // unescape some stuff | |
261 | return htmlEnDeCode.htmlDecode($('#'+tmpl_name+'_tmpl').html()); |
|
288 | return htmlEnDeCode.htmlDecode($('#'+tmpl_name+'_tmpl').html()); | |
@@ -265,7 +292,8 b' var get_data = function(type, old){' | |||||
265 | 'ga': get_tmpl('ga'), |
|
292 | 'ga': get_tmpl('ga'), | |
266 | 'clicky': get_tmpl('clicky'), |
|
293 | 'clicky': get_tmpl('clicky'), | |
267 | 'server_announce': get_tmpl('server_announce'), |
|
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 | }[type] |
|
297 | }[type] | |
270 | }; |
|
298 | }; | |
271 |
|
299 |
@@ -103,11 +103,12 b'' | |||||
103 | </div> |
|
103 | </div> | |
104 | <div class="field"> |
|
104 | <div class="field"> | |
105 | <div class="label-text"> |
|
105 | <div class="label-text"> | |
106 |
${_(' |
|
106 | ${_('Authentication type')}: | |
107 | </div> |
|
107 | </div> | |
108 | <div class="input"> |
|
108 | <div class="input"> | |
109 | <p>${c.extern_type}</p> |
|
109 | <p>${c.extern_type}</p> | |
110 | ${h.hidden('extern_type', readonly="readonly")} |
|
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 | </div> |
|
112 | </div> | |
112 | </div> |
|
113 | </div> | |
113 | <div class="field"> |
|
114 | <div class="field"> | |
@@ -127,7 +128,7 b'' | |||||
127 | ## allowed_languages is defined in the users.py |
|
128 | ## allowed_languages is defined in the users.py | |
128 | ## c.language comes from base.py as a default language |
|
129 | ## c.language comes from base.py as a default language | |
129 | ${h.select('language', c.language, c.allowed_languages)} |
|
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 | </div> |
|
132 | </div> | |
132 | </div> |
|
133 | </div> | |
133 | <div class="buttons"> |
|
134 | <div class="buttons"> |
@@ -4,7 +4,8 b'' | |||||
4 | </div> |
|
4 | </div> | |
5 | <div class="panel-body"> |
|
5 | <div class="panel-body"> | |
6 | <p> |
|
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 | </p> |
|
9 | </p> | |
9 | <h4>${_('Private key')}</h4> |
|
10 | <h4>${_('Private key')}</h4> | |
10 | <pre> |
|
11 | <pre> |
@@ -27,9 +27,6 b" c.template_context['default_user'] = {" | |||||
27 | %> |
|
27 | %> | |
28 | <html xmlns="http://www.w3.org/1999/xhtml"> |
|
28 | <html xmlns="http://www.w3.org/1999/xhtml"> | |
29 | <head> |
|
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 | <title>${self.title()}</title> |
|
30 | <title>${self.title()}</title> | |
34 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
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 | </%def> |
|
43 | </%def> | |
47 | ${self.robots()} |
|
44 | ${self.robots()} | |
48 | <link rel="icon" href="${h.asset('images/favicon.ico', ver=c.rhodecode_version_hash)}" sizes="16x16 32x32" type="image/png" /> |
|
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 | ## CSS definitions |
|
49 | ## CSS definitions | |
51 | <%def name="css()"> |
|
50 | <%def name="css()"> |
@@ -5,13 +5,16 b'' | |||||
5 | <title>Error - ${c.error_message}</title> |
|
5 | <title>Error - ${c.error_message}</title> | |
6 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
6 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> | |
7 | <meta name="robots" content="index, nofollow"/> |
|
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 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
9 | <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> | |
11 | %if c.redirect_time: |
|
10 | %if c.redirect_time: | |
12 | <meta http-equiv="refresh" content="${c.redirect_time}; url=${c.url_redirect}"/> |
|
11 | <meta http-equiv="refresh" content="${c.redirect_time}; url=${c.url_redirect}"/> | |
13 | %endif |
|
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 | <link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/> |
|
18 | <link rel="stylesheet" type="text/css" href="${h.asset('css/style.css', ver=c.rhodecode_version_hash)}" media="screen"/> | |
16 | <style>body { background:#eeeeee; }</style> |
|
19 | <style>body { background:#eeeeee; }</style> | |
17 | <script type="text/javascript"> |
|
20 | <script type="text/javascript"> | |
@@ -31,7 +34,9 b'' | |||||
31 | <span class="error-branding"> |
|
34 | <span class="error-branding"> | |
32 | ${h.branding(c.rhodecode_name)} |
|
35 | ${h.branding(c.rhodecode_name)} | |
33 | </span><br/> |
|
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 | </h1> |
|
40 | </h1> | |
36 | % if c.messages: |
|
41 | % if c.messages: | |
37 | % for message in c.messages: |
|
42 | % for message in c.messages: |
@@ -32,8 +32,8 b'' | |||||
32 | <div id="register" class="right-column"> |
|
32 | <div id="register" class="right-column"> | |
33 | <!-- login --> |
|
33 | <!-- login --> | |
34 | <div class="sign-in-title"> |
|
34 | <div class="sign-in-title"> | |
35 |
% if |
|
35 | % if external_auth_provider: | |
36 |
<h1>${_('Create an account linked with {}').format( |
|
36 | <h1>${_('Create an account linked with {}').format(external_auth_provider)}</h1> | |
37 | % else: |
|
37 | % else: | |
38 | <h1>${_('Create an account')}</h1> |
|
38 | <h1>${_('Create an account')}</h1> | |
39 | % endif |
|
39 | % endif | |
@@ -50,7 +50,9 b'' | |||||
50 | <br /> |
|
50 | <br /> | |
51 | %endif |
|
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 | ## hide password prompts for social auth | |
55 | <div style="display: none"> |
|
57 | <div style="display: none"> | |
56 | % endif |
|
58 | % endif | |
@@ -69,7 +71,7 b'' | |||||
69 | <br /> |
|
71 | <br /> | |
70 | %endif |
|
72 | %endif | |
71 |
|
73 | |||
72 |
% if |
|
74 | % if external_auth_provider: | |
73 | ## hide password prompts for social auth |
|
75 | ## hide password prompts for social auth | |
74 | </div> |
|
76 | </div> | |
75 | % endif |
|
77 | % endif |
@@ -45,7 +45,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
45 |
|
45 | |||
46 | @hybrid_property |
|
46 | @hybrid_property | |
47 | def name(self): |
|
47 | def name(self): | |
48 | return "external_test" |
|
48 | return u"external_test" | |
49 |
|
49 | |||
50 | def settings(self): |
|
50 | def settings(self): | |
51 | settings = [ |
|
51 | settings = [ |
@@ -30,7 +30,7 b' from rhodecode.model import db' | |||||
30 | class RcTestAuthPlugin(RhodeCodeAuthPluginBase): |
|
30 | class RcTestAuthPlugin(RhodeCodeAuthPluginBase): | |
31 |
|
31 | |||
32 | def name(self): |
|
32 | def name(self): | |
33 | return 'stub_auth' |
|
33 | return u'stub_auth' | |
34 |
|
34 | |||
35 |
|
35 | |||
36 | def test_authenticate_returns_from_auth(stub_auth_data): |
|
36 | def test_authenticate_returns_from_auth(stub_auth_data): |
@@ -77,6 +77,8 b' class StubVCSController(simplevcs.Simple' | |||||
77 | def vcscontroller(baseapp, config_stub, request_stub): |
|
77 | def vcscontroller(baseapp, config_stub, request_stub): | |
78 | config_stub.testing_securitypolicy() |
|
78 | config_stub.testing_securitypolicy() | |
79 | config_stub.include('rhodecode.authentication') |
|
79 | config_stub.include('rhodecode.authentication') | |
|
80 | config_stub.include('rhodecode.authentication.plugins.auth_rhodecode') | |||
|
81 | config_stub.include('rhodecode.authentication.plugins.auth_token') | |||
80 |
|
82 | |||
81 | controller = StubVCSController( |
|
83 | controller = StubVCSController( | |
82 | baseapp.config.get_settings(), request_stub.registry) |
|
84 | baseapp.config.get_settings(), request_stub.registry) |
@@ -46,7 +46,7 b' class ReviewerMock(object):' | |||||
46 | class MemberMock(object): |
|
46 | class MemberMock(object): | |
47 | def __init__(self, reviewer_def): |
|
47 | def __init__(self, reviewer_def): | |
48 | self.reviewer_def = reviewer_def |
|
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 | class Statuses(object): |
|
52 | class Statuses(object): |
@@ -193,6 +193,8 b' def test_ValidPasswordsMatch(localizer):' | |||||
193 | def test_ValidAuth(localizer, config_stub): |
|
193 | def test_ValidAuth(localizer, config_stub): | |
194 | config_stub.testing_securitypolicy() |
|
194 | config_stub.testing_securitypolicy() | |
195 | config_stub.include('rhodecode.authentication') |
|
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 | validator = v.ValidAuth(localizer) |
|
199 | validator = v.ValidAuth(localizer) | |
198 | valid_creds = { |
|
200 | valid_creds = { |
@@ -310,9 +310,9 b' class TestCommits(BackendTestMixin):' | |||||
310 | with pytest.raises(CommitDoesNotExistError): |
|
310 | with pytest.raises(CommitDoesNotExistError): | |
311 | commit.next() |
|
311 | commit.next() | |
312 |
|
312 | |||
313 |
def test_get_ |
|
313 | def test_get_path_commit(self): | |
314 | commit = self.repo.get_commit() |
|
314 | commit = self.repo.get_commit() | |
315 |
commit.get_ |
|
315 | commit.get_path_commit('file_4.txt') | |
316 | assert commit.message == 'Commit 4' |
|
316 | assert commit.message == 'Commit 4' | |
317 |
|
317 | |||
318 | def test_get_filenodes_generator(self): |
|
318 | def test_get_filenodes_generator(self): | |
@@ -571,19 +571,19 b' class TestCommitsChanges(BackendTestMixi' | |||||
571 | assert FILEMODE_DEFAULT == commit.get_file_mode('foo/bał') |
|
571 | assert FILEMODE_DEFAULT == commit.get_file_mode('foo/bał') | |
572 | assert FILEMODE_DEFAULT == commit.get_file_mode(u'foo/bał') |
|
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 | commit = self.repo.get_commit() |
|
575 | commit = self.repo.get_commit() | |
576 |
history = commit.get_ |
|
576 | history = commit.get_path_history('foo/bar') | |
577 | assert len(history) == 2 |
|
577 | assert len(history) == 2 | |
578 |
|
578 | |||
579 |
def test_get_ |
|
579 | def test_get_path_history_with_limit(self): | |
580 | commit = self.repo.get_commit() |
|
580 | commit = self.repo.get_commit() | |
581 |
history = commit.get_ |
|
581 | history = commit.get_path_history('foo/bar', limit=1) | |
582 | assert len(history) == 1 |
|
582 | assert len(history) == 1 | |
583 |
|
583 | |||
584 |
def test_get_ |
|
584 | def test_get_path_history_first_commit(self): | |
585 | commit = self.repo[0] |
|
585 | commit = self.repo[0] | |
586 |
history = commit.get_ |
|
586 | history = commit.get_path_history('foo/bar') | |
587 | assert len(history) == 1 |
|
587 | assert len(history) == 1 | |
588 |
|
588 | |||
589 |
|
589 |
@@ -538,7 +538,7 b' TODO: To be written...' | |||||
538 | 'sys.exit(1)', |
|
538 | 'sys.exit(1)', | |
539 | ] |
|
539 | ] | |
540 | f.write('\n'.join(script_lines)) |
|
540 | f.write('\n'.join(script_lines)) | |
541 | os.chmod(hook_path, 0755) |
|
541 | os.chmod(hook_path, 0o755) | |
542 |
|
542 | |||
543 | def test_local_push_does_not_execute_hook(self): |
|
543 | def test_local_push_does_not_execute_hook(self): | |
544 | target_repo = self.get_empty_repo() |
|
544 | target_repo = self.get_empty_repo() | |
@@ -1061,7 +1061,7 b' class TestGitSpecificWithRepo(BackendTes' | |||||
1061 | FileNode('foobar/static/js/admin/base.js', content='base'), |
|
1061 | FileNode('foobar/static/js/admin/base.js', content='base'), | |
1062 | FileNode( |
|
1062 | FileNode( | |
1063 | 'foobar/static/admin', content='admin', |
|
1063 | 'foobar/static/admin', content='admin', | |
1064 | mode=0120000), # this is a link |
|
1064 | mode=0o120000), # this is a link | |
1065 | FileNode('foo', content='foo'), |
|
1065 | FileNode('foo', content='foo'), | |
1066 | ], |
|
1066 | ], | |
1067 | }, |
|
1067 | }, |
@@ -190,13 +190,13 b' class TestNodeBasics:' | |||||
190 | assert not mode & stat.S_IXOTH |
|
190 | assert not mode & stat.S_IXOTH | |
191 |
|
191 | |||
192 | def test_file_node_is_executable(self): |
|
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 | assert node.is_executable |
|
194 | assert node.is_executable | |
195 |
|
195 | |||
196 | node = FileNode('foobar', 'empty... almost', mode=0100500) |
|
196 | node = FileNode('foobar', 'empty... almost', mode=0o100500) | |
197 | assert node.is_executable |
|
197 | assert node.is_executable | |
198 |
|
198 | |||
199 | node = FileNode('foobar', 'empty... almost', mode=0100644) |
|
199 | node = FileNode('foobar', 'empty... almost', mode=0o100644) | |
200 | assert not node.is_executable |
|
200 | assert not node.is_executable | |
201 |
|
201 | |||
202 | def test_file_node_is_not_symlink(self): |
|
202 | def test_file_node_is_not_symlink(self): |
@@ -259,13 +259,13 b' class TestRepositoryGetCommonAncestor:' | |||||
259 | commit_id1=original[0].raw_id, |
|
259 | commit_id1=original[0].raw_id, | |
260 | commit_id2=unrelated[0].raw_id, |
|
260 | commit_id2=unrelated[0].raw_id, | |
261 | repo2=unrelated |
|
261 | repo2=unrelated | |
262 |
) |
|
262 | ) is None | |
263 |
|
263 | |||
264 | assert original.get_common_ancestor( |
|
264 | assert original.get_common_ancestor( | |
265 | commit_id1=original[-1].raw_id, |
|
265 | commit_id1=original[-1].raw_id, | |
266 | commit_id2=unrelated[-1].raw_id, |
|
266 | commit_id2=unrelated[-1].raw_id, | |
267 | repo2=unrelated |
|
267 | repo2=unrelated | |
268 |
) |
|
268 | ) is None | |
269 |
|
269 | |||
270 |
|
270 | |||
271 | @pytest.mark.backends("git", "hg") |
|
271 | @pytest.mark.backends("git", "hg") |
@@ -148,15 +148,6 b' setup(' | |||||
148 | }, |
|
148 | }, | |
149 | paster_plugins=['PasteScript'], |
|
149 | paster_plugins=['PasteScript'], | |
150 | entry_points={ |
|
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 | 'paste.app_factory': [ |
|
151 | 'paste.app_factory': [ | |
161 | 'main=rhodecode.config.middleware:make_pyramid_app', |
|
152 | 'main=rhodecode.config.middleware:make_pyramid_app', | |
162 | ], |
|
153 | ], |
1 | NO CONTENT: file was removed, binary diff hidden |
|
NO CONTENT: file was removed, binary diff hidden |
1 | NO CONTENT: file was removed, binary diff hidden |
|
NO CONTENT: file was removed, binary diff hidden |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now