Show More
The requested changes are too big and content was truncated. Show full diff
@@ -0,0 +1,101 b'' | |||||
|
1 | .. _sec-your-server: | |||
|
2 | ||||
|
3 | Securing Your Server via Sophos UTM 9 | |||
|
4 | ------------------------------------- | |||
|
5 | ||||
|
6 | ||||
|
7 | ||||
|
8 | Below is an example configuration for Sophos UTM 9 Webserver Protection:: | |||
|
9 | ||||
|
10 | Sophos UTM 9 Webserver Protection | |||
|
11 | Web Application Firewall based on apache2 modesecurity2 | |||
|
12 | -------------------------------------------------- | |||
|
13 | 1. Firewall Profiles -> Firewall Profile | |||
|
14 | -------------------------------------------------- | |||
|
15 | Name: RhodeCode (can be anything) | |||
|
16 | Mode: Reject | |||
|
17 | Hardening & Signing: | |||
|
18 | [ ] Static URL hardeninig | |||
|
19 | [ ] Form hardening | |||
|
20 | [x] Cookie Signing | |||
|
21 | Filtering: | |||
|
22 | [x] Block clients with bad reputation | |||
|
23 | [x] Common Threats Filter | |||
|
24 | [ ] Rigid Filtering | |||
|
25 | Skip Filter Rules: | |||
|
26 | 960015 | |||
|
27 | 950120 | |||
|
28 | 981173 | |||
|
29 | 970901 | |||
|
30 | 960010 | |||
|
31 | 960032 | |||
|
32 | 960035 | |||
|
33 | 958291 | |||
|
34 | 970903 | |||
|
35 | 970003 | |||
|
36 | Common Threat Filter Categories: | |||
|
37 | [x] Protocol violations | |||
|
38 | [x] Protocol anomalies | |||
|
39 | [x] Request limit | |||
|
40 | [x] HTTP policy | |||
|
41 | [x] Bad robots | |||
|
42 | [x] Generic attacks | |||
|
43 | [x] SQL injection attacks | |||
|
44 | [x] XSS attacks | |||
|
45 | [x] Tight security | |||
|
46 | [x] Trojans | |||
|
47 | [x] Outbound | |||
|
48 | Scanning: | |||
|
49 | [ ] Enable antivirus scanning | |||
|
50 | [ ] Block uploads by MIME type | |||
|
51 | -------------------------------------------------- | |||
|
52 | 2. Web Application Firewall -> Real Webservers | |||
|
53 | -------------------------------------------------- | |||
|
54 | Name: RhodeCode (can be anything) | |||
|
55 | Host: Your RhodeCode-Server (UTM object) | |||
|
56 | Type: Encrypted (HTTPS) | |||
|
57 | Port: 443 | |||
|
58 | -------------------------------------------------- | |||
|
59 | 3. Web Application Firewall -> Virual Webservers | |||
|
60 | -------------------------------------------------- | |||
|
61 | Name: RhodeCode (can be anything) | |||
|
62 | Interface: WAN (your WAN interface) | |||
|
63 | Type: Encrypted (HTTPS) & redirect | |||
|
64 | Certificate: Wildcard or matching domain certificate | |||
|
65 | Domains (in case of Wildcard certificate): | |||
|
66 | rhodecode.yourcompany.com (match your DNS configuration) | |||
|
67 | gist.yourcompany.com (match your DNS & RhodeCode configuration) | |||
|
68 | Real Webservers for path '/': | |||
|
69 | [x] RhodeCode (created in step 2) | |||
|
70 | Firewall: RhodeCode (created in step 1) | |||
|
71 | -------------------------------------------------- | |||
|
72 | 4. Firewall Profiles -> Exceptions | |||
|
73 | -------------------------------------------------- | |||
|
74 | Name: RhodeCode exceptions (can be anything) | |||
|
75 | Skip these checks: | |||
|
76 | [ ] Cookie signing | |||
|
77 | [ ] Static URL Hardening | |||
|
78 | [ ] Form hardening | |||
|
79 | [x] Antivirus scanning | |||
|
80 | [x] True file type control | |||
|
81 | [ ] Block clients with bad reputation | |||
|
82 | Skip these categories: | |||
|
83 | [ ] Protocol violations | |||
|
84 | [x] Protocol anomalies | |||
|
85 | [x] Request limits | |||
|
86 | [ ] HTTP policy | |||
|
87 | [ ] Bad robots | |||
|
88 | [ ] Generic attacks | |||
|
89 | [ ] SQL injection attacks | |||
|
90 | [ ] XSS attacks | |||
|
91 | [ ] Tight security | |||
|
92 | [ ] Trojans | |||
|
93 | [x] Outbound | |||
|
94 | Virtual Webservers: | |||
|
95 | [x] RhodeCode (created in step 3) | |||
|
96 | For All Requests: | |||
|
97 | Web requests matching this pattern: | |||
|
98 | /_channelstream/ws | |||
|
99 | /Repository1/* | |||
|
100 | /Repository2/* | |||
|
101 | /Repository3/* No newline at end of file |
@@ -0,0 +1,152 b'' | |||||
|
1 | |RCE| 4.11.0 |RNS| | |||
|
2 | ------------------ | |||
|
3 | ||||
|
4 | Release Date | |||
|
5 | ^^^^^^^^^^^^ | |||
|
6 | ||||
|
7 | - 2018-02-01 | |||
|
8 | ||||
|
9 | ||||
|
10 | New Features | |||
|
11 | ^^^^^^^^^^^^ | |||
|
12 | ||||
|
13 | - Default reviewers(EE only): introduced new voting rule logic that allows | |||
|
14 | defining how many members of user group need to vote for approvals. E.g | |||
|
15 | adding 4 people group with security people, it can be specified that at least | |||
|
16 | 1 (or all) need to vote for approval from that group. | |||
|
17 | - Default reviewers(EE only): added source/target branch flow distinction and | |||
|
18 | option to add names to rules. | |||
|
19 | - RhodeCode-Scheduler (Beta, EE only): after celery 4.X upgrade we introduced a | |||
|
20 | new scheduler option. RhodeCode scheduler now allows specifying via super-admin | |||
|
21 | interface periodic tasks that should be run crontab style. | |||
|
22 | Currently available tasks are: | |||
|
23 | - repo maintenance: (repo quality/git gc) | |||
|
24 | - repo remote code pull: pull changed on periodic bases from given url | |||
|
25 | - repo remote code push: push all changes on periodic bases to given url | |||
|
26 | - check for updates | |||
|
27 | - Ui: a ssh clone uri was added to summary view for clone. This allows to | |||
|
28 | customize how the ssh clone url would look like, and also exposes SSH clone | |||
|
29 | url to summary page. | |||
|
30 | - Integrations: parse pushed tags, and lightweight tags for git. | |||
|
31 | - now aggregated as 'tags' key | |||
|
32 | - handles the case for email/webhook integrations | |||
|
33 | - Files browser: allow making a range selection of code lines with | |||
|
34 | shift-click from line numbers. | |||
|
35 | - Pull requests: allow opening PR from changelog based on selected refs for | |||
|
36 | git as well as hg. | |||
|
37 | - Process management: auto refresh option was added to the processes | |||
|
38 | page to live track usage. | |||
|
39 | - Api: pull-requests added option to fetch comments from a pull requests. | |||
|
40 | - Api: added new data called `permissions_summary` for user and | |||
|
41 | user_groups that expose the summary of permissions for each of those. | |||
|
42 | ||||
|
43 | ||||
|
44 | General | |||
|
45 | ^^^^^^^ | |||
|
46 | ||||
|
47 | - Core: removed all pylons dependencies and backward compatibility code. | |||
|
48 | RhodeCode is now 100% pyramid app. | |||
|
49 | - Audit logs: added user.register audit log entry. | |||
|
50 | - Celery: update celery support 4.X series. | |||
|
51 | - Logging: log traceback for errors that are known to help debugging. | |||
|
52 | - Pull requests: don't select first commit in case we don't have a default | |||
|
53 | branch for repository. Loading compare from commit 0 to something selected | |||
|
54 | is very heavy to compute. Now it's left to users to decide what | |||
|
55 | compare base to pick. | |||
|
56 | - Dependencies: bumped Mercurial version to 4.4.2 | |||
|
57 | - Dependencies: bumped hgevolve to 7.0.1 | |||
|
58 | - Dependencies: bumped libs not explicitly set by requirements | |||
|
59 | - ws4py to 0.4.2 | |||
|
60 | - scandir to 1.6 | |||
|
61 | - plaster to 1.0 | |||
|
62 | - mistune to 0.8 | |||
|
63 | - jupyter-core to 4.4.0 | |||
|
64 | - Dependencies: pin to rhodecode-tools 0.14.0 | |||
|
65 | - Dependencies: bumped click to 6.6.0 | |||
|
66 | - Dependencies: bumped transifex-clients to 0.12.5 | |||
|
67 | - Dependencies: bumped six to 1.11.0 | |||
|
68 | - Dependencies: bumped waitress to 1.1.0 | |||
|
69 | - Dependencies: bumped setproctitle 1.1.10 | |||
|
70 | - Dependencies: bumped iso8601 to 0.1.12 | |||
|
71 | - Dependencies: bumped repoze.lru to 0.7.0 | |||
|
72 | - Dependencies: bumped python-ldap to 2.4.45 | |||
|
73 | - Dependencies: bumped gnureadline 6.3.8 | |||
|
74 | - Dependencies: bumped bottle to 0.12.13 | |||
|
75 | - Dependencies: bumped psycopg2 2.7.3.2 | |||
|
76 | - Dependencies: bumped alembic to 0.9.6 | |||
|
77 | - Dependencies: bumped sqlalchemy to 1.1.15 | |||
|
78 | - Dependencies: bumped markupsafe to 1.0.0 | |||
|
79 | - Dependencies: bumped markdown to 2.6.9 | |||
|
80 | - Dependencies: bumped objgraph to 3.1.1 | |||
|
81 | - Dependencies: bumped psutil to 5.4.0 | |||
|
82 | - Dependencies: bumped docutils to 0.14.0 | |||
|
83 | - Dependencies: bumped decorator to 4.1.2 | |||
|
84 | - Dependencies: bumped pyramid-jinja to 2.7.0 | |||
|
85 | - Dependencies: bumped jinja to 2.9.6 | |||
|
86 | - Dependencies: bumped colander to 1.4.0 | |||
|
87 | - Dependencies: bumped mistune to 0.8.1 | |||
|
88 | - Dependencies: bumped webob to 1.7.4 | |||
|
89 | - Dependencies: dropped nose dependency. | |||
|
90 | ||||
|
91 | ||||
|
92 | Security | |||
|
93 | ^^^^^^^^ | |||
|
94 | ||||
|
95 | - Security(low): fix self xss on repo downloads picker for svn case. | |||
|
96 | ||||
|
97 | ||||
|
98 | Performance | |||
|
99 | ^^^^^^^^^^^ | |||
|
100 | ||||
|
101 | - Pyramid: removed pylons layer, this should result in general speed | |||
|
102 | improvement over previous version. | |||
|
103 | - Authentication: use cache_ttl for anonymous access taken from the | |||
|
104 | rhodecode main auth plugin. For operations like svn this boosts performance | |||
|
105 | significantly with anonymous access enabled. | |||
|
106 | - Issue trackers: cache the fetched issue tracker patterns in changelog | |||
|
107 | page before loop iteration to speed up fetching and parsing the tracker | |||
|
108 | patterns. | |||
|
109 | ||||
|
110 | ||||
|
111 | Fixes | |||
|
112 | ^^^^^ | |||
|
113 | ||||
|
114 | - Slack: expose the FULL message instead of title. | |||
|
115 | Slack uses it's own trim, we should avoid sending trimmed data and | |||
|
116 | let users via Slack trim logic control the data. | |||
|
117 | - Comments: place the left over comments (outdated/misplaced) to the left or | |||
|
118 | right side-by-side pane. This way the original context where they were | |||
|
119 | placed is kept. | |||
|
120 | - Comments: allow to properly initialize outdated comments that are attached | |||
|
121 | to the end of diffs. This allows resolving TODOs that are outdated. | |||
|
122 | - Git: handle cases of git push without branch specified in the eventing system. | |||
|
123 | - Git: merge simulation fixes. Fetch other branch data if it's different | |||
|
124 | from target. This prevents potentially missing commits error when doing a test merge. | |||
|
125 | Also fix edge cases using .gitattributes file modification that could | |||
|
126 | lead to the same problem. | |||
|
127 | - Age component: use local flag to fix the problem of wrongly reported last | |||
|
128 | update times on repository groups. | |||
|
129 | ||||
|
130 | ||||
|
131 | Upgrade notes | |||
|
132 | ^^^^^^^^^^^^^ | |||
|
133 | ||||
|
134 | Please note that this release is first in series that drops completely pylons | |||
|
135 | dependency. This means that certain `paster` commands are no longer available. | |||
|
136 | ||||
|
137 | Commands changed after dropping pylons compatibility layer: | |||
|
138 | - paster upgrade-db /path/ini_file => rc-upgrade-db /path/ini_file | |||
|
139 | - paster setup-app /path/ini_file => rc-setup-app /path/ini_file | |||
|
140 | - paster ishell /path/ini_file => rc-ishell /path/ini_file | |||
|
141 | - paster celeryd /path/ini_file => celery worker --app rhodecode.lib.celerylib.loader /path/ini_file | |||
|
142 | ||||
|
143 | Commands no longer available: | |||
|
144 | - paster make-config (replaced by rhodecode-config from rhodecode-tools package) | |||
|
145 | - paster update-repoinfo (replaced by API calls) | |||
|
146 | - paster cache-keys, no equivalent available, this command was removed. | |||
|
147 | ||||
|
148 | ||||
|
149 | RhodeCode 4.11 uses latest Celery 4.X series. This means that there's a new way to | |||
|
150 | run the celery workers. To upgrade to latest simply run | |||
|
151 | `rccontrol enable-module celery` to convert the currently running celery setup | |||
|
152 | into a new version that also powers the RhodeCode scheduler. |
@@ -0,0 +1,8 b'' | |||||
|
1 | Sphinx==1.6.5 | |||
|
2 | six==1.11.0 | |||
|
3 | sphinx_rtd_theme==0.2.5b1 | |||
|
4 | docutils==0.14.0 | |||
|
5 | Pygments==2.2.0 | |||
|
6 | MarkupSafe==1.0.0 | |||
|
7 | Jinja2==2.9.6 | |||
|
8 | pytz No newline at end of file |
@@ -0,0 +1,82 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | ||||
|
22 | import pytest | |||
|
23 | import urlobject | |||
|
24 | ||||
|
25 | from rhodecode.api.tests.utils import ( | |||
|
26 | build_data, api_call, assert_error, assert_ok) | |||
|
27 | from rhodecode.lib import helpers as h | |||
|
28 | from rhodecode.lib.utils2 import safe_unicode | |||
|
29 | ||||
|
30 | pytestmark = pytest.mark.backends("git", "hg") | |||
|
31 | ||||
|
32 | ||||
|
33 | @pytest.mark.usefixtures("testuser_api", "app") | |||
|
34 | class TestGetPullRequestComments(object): | |||
|
35 | ||||
|
36 | def test_api_get_pull_request_comments(self, pr_util, http_host_only_stub): | |||
|
37 | from rhodecode.model.pull_request import PullRequestModel | |||
|
38 | ||||
|
39 | pull_request = pr_util.create_pull_request(mergeable=True) | |||
|
40 | id_, params = build_data( | |||
|
41 | self.apikey, 'get_pull_request_comments', | |||
|
42 | pullrequestid=pull_request.pull_request_id) | |||
|
43 | ||||
|
44 | response = api_call(self.app, params) | |||
|
45 | ||||
|
46 | assert response.status == '200 OK' | |||
|
47 | resp_date = response.json['result'][0]['comment_created_on'] | |||
|
48 | resp_comment_id = response.json['result'][0]['comment_id'] | |||
|
49 | ||||
|
50 | expected = [ | |||
|
51 | {'comment_author': {'active': True, | |||
|
52 | 'full_name_or_username': 'RhodeCode Admin', | |||
|
53 | 'username': 'test_admin'}, | |||
|
54 | 'comment_created_on': resp_date, | |||
|
55 | 'comment_f_path': None, | |||
|
56 | 'comment_id': resp_comment_id, | |||
|
57 | 'comment_lineno': None, | |||
|
58 | 'comment_status': {'status': 'under_review', | |||
|
59 | 'status_lbl': 'Under Review'}, | |||
|
60 | 'comment_text': 'Auto status change to |new_status|\n\n.. |new_status| replace:: *"Under Review"*', | |||
|
61 | 'comment_type': 'note', | |||
|
62 | 'pull_request_version': None} | |||
|
63 | ] | |||
|
64 | assert_ok(id_, expected, response.body) | |||
|
65 | ||||
|
66 | def test_api_get_pull_request_comments_repo_error(self, pr_util): | |||
|
67 | pull_request = pr_util.create_pull_request() | |||
|
68 | id_, params = build_data( | |||
|
69 | self.apikey, 'get_pull_request_comments', | |||
|
70 | repoid=666, pullrequestid=pull_request.pull_request_id) | |||
|
71 | response = api_call(self.app, params) | |||
|
72 | ||||
|
73 | expected = 'repository `666` does not exist' | |||
|
74 | assert_error(id_, expected, given=response.body) | |||
|
75 | ||||
|
76 | def test_api_get_pull_request_comments_pull_request_error(self): | |||
|
77 | id_, params = build_data( | |||
|
78 | self.apikey, 'get_pull_request_comments', pullrequestid=666) | |||
|
79 | response = api_call(self.app, params) | |||
|
80 | ||||
|
81 | expected = 'pull request `666` does not exist' | |||
|
82 | assert_error(id_, expected, given=response.body) |
This diff has been collapsed as it changes many lines, (764 lines changed) Show them Hide them | |||||
@@ -0,0 +1,764 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | ||||
|
22 | import logging | |||
|
23 | import collections | |||
|
24 | ||||
|
25 | import datetime | |||
|
26 | import formencode | |||
|
27 | import formencode.htmlfill | |||
|
28 | ||||
|
29 | import rhodecode | |||
|
30 | from pyramid.view import view_config | |||
|
31 | from pyramid.httpexceptions import HTTPFound, HTTPNotFound | |||
|
32 | from pyramid.renderers import render | |||
|
33 | from pyramid.response import Response | |||
|
34 | ||||
|
35 | from rhodecode.apps._base import BaseAppView | |||
|
36 | from rhodecode.apps.admin.navigation import navigation_list | |||
|
37 | from rhodecode.apps.svn_support.config_keys import generate_config | |||
|
38 | from rhodecode.lib import helpers as h | |||
|
39 | from rhodecode.lib.auth import ( | |||
|
40 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |||
|
41 | from rhodecode.lib.celerylib import tasks, run_task | |||
|
42 | from rhodecode.lib.utils import repo2db_mapper | |||
|
43 | from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict | |||
|
44 | from rhodecode.lib.index import searcher_from_config | |||
|
45 | ||||
|
46 | from rhodecode.model.db import RhodeCodeUi, Repository | |||
|
47 | from rhodecode.model.forms import (ApplicationSettingsForm, | |||
|
48 | ApplicationUiSettingsForm, ApplicationVisualisationForm, | |||
|
49 | LabsSettingsForm, IssueTrackerPatternsForm) | |||
|
50 | from rhodecode.model.repo_group import RepoGroupModel | |||
|
51 | ||||
|
52 | from rhodecode.model.scm import ScmModel | |||
|
53 | from rhodecode.model.notification import EmailNotificationModel | |||
|
54 | from rhodecode.model.meta import Session | |||
|
55 | from rhodecode.model.settings import ( | |||
|
56 | IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound, | |||
|
57 | SettingsModel) | |||
|
58 | ||||
|
59 | ||||
|
60 | log = logging.getLogger(__name__) | |||
|
61 | ||||
|
62 | ||||
|
63 | class AdminSettingsView(BaseAppView): | |||
|
64 | ||||
|
65 | def load_default_context(self): | |||
|
66 | c = self._get_local_tmpl_context() | |||
|
67 | c.labs_active = str2bool( | |||
|
68 | rhodecode.CONFIG.get('labs_settings_active', 'true')) | |||
|
69 | c.navlist = navigation_list(self.request) | |||
|
70 | ||||
|
71 | return c | |||
|
72 | ||||
|
73 | @classmethod | |||
|
74 | def _get_ui_settings(cls): | |||
|
75 | ret = RhodeCodeUi.query().all() | |||
|
76 | ||||
|
77 | if not ret: | |||
|
78 | raise Exception('Could not get application ui settings !') | |||
|
79 | settings = {} | |||
|
80 | for each in ret: | |||
|
81 | k = each.ui_key | |||
|
82 | v = each.ui_value | |||
|
83 | if k == '/': | |||
|
84 | k = 'root_path' | |||
|
85 | ||||
|
86 | if k in ['push_ssl', 'publish', 'enabled']: | |||
|
87 | v = str2bool(v) | |||
|
88 | ||||
|
89 | if k.find('.') != -1: | |||
|
90 | k = k.replace('.', '_') | |||
|
91 | ||||
|
92 | if each.ui_section in ['hooks', 'extensions']: | |||
|
93 | v = each.ui_active | |||
|
94 | ||||
|
95 | settings[each.ui_section + '_' + k] = v | |||
|
96 | return settings | |||
|
97 | ||||
|
98 | @classmethod | |||
|
99 | def _form_defaults(cls): | |||
|
100 | defaults = SettingsModel().get_all_settings() | |||
|
101 | defaults.update(cls._get_ui_settings()) | |||
|
102 | ||||
|
103 | defaults.update({ | |||
|
104 | 'new_svn_branch': '', | |||
|
105 | 'new_svn_tag': '', | |||
|
106 | }) | |||
|
107 | return defaults | |||
|
108 | ||||
|
109 | @LoginRequired() | |||
|
110 | @HasPermissionAllDecorator('hg.admin') | |||
|
111 | @view_config( | |||
|
112 | route_name='admin_settings_vcs', request_method='GET', | |||
|
113 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
114 | def settings_vcs(self): | |||
|
115 | c = self.load_default_context() | |||
|
116 | c.active = 'vcs' | |||
|
117 | model = VcsSettingsModel() | |||
|
118 | c.svn_branch_patterns = model.get_global_svn_branch_patterns() | |||
|
119 | c.svn_tag_patterns = model.get_global_svn_tag_patterns() | |||
|
120 | ||||
|
121 | settings = self.request.registry.settings | |||
|
122 | c.svn_proxy_generate_config = settings[generate_config] | |||
|
123 | ||||
|
124 | defaults = self._form_defaults() | |||
|
125 | ||||
|
126 | model.create_largeobjects_dirs_if_needed(defaults['paths_root_path']) | |||
|
127 | ||||
|
128 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
129 | self._get_template_context(c), self.request) | |||
|
130 | html = formencode.htmlfill.render( | |||
|
131 | data, | |||
|
132 | defaults=defaults, | |||
|
133 | encoding="UTF-8", | |||
|
134 | force_defaults=False | |||
|
135 | ) | |||
|
136 | return Response(html) | |||
|
137 | ||||
|
138 | @LoginRequired() | |||
|
139 | @HasPermissionAllDecorator('hg.admin') | |||
|
140 | @CSRFRequired() | |||
|
141 | @view_config( | |||
|
142 | route_name='admin_settings_vcs_update', request_method='POST', | |||
|
143 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
144 | def settings_vcs_update(self): | |||
|
145 | _ = self.request.translate | |||
|
146 | c = self.load_default_context() | |||
|
147 | c.active = 'vcs' | |||
|
148 | ||||
|
149 | model = VcsSettingsModel() | |||
|
150 | c.svn_branch_patterns = model.get_global_svn_branch_patterns() | |||
|
151 | c.svn_tag_patterns = model.get_global_svn_tag_patterns() | |||
|
152 | ||||
|
153 | settings = self.request.registry.settings | |||
|
154 | c.svn_proxy_generate_config = settings[generate_config] | |||
|
155 | ||||
|
156 | application_form = ApplicationUiSettingsForm(self.request.translate)() | |||
|
157 | ||||
|
158 | try: | |||
|
159 | form_result = application_form.to_python(dict(self.request.POST)) | |||
|
160 | except formencode.Invalid as errors: | |||
|
161 | h.flash( | |||
|
162 | _("Some form inputs contain invalid data."), | |||
|
163 | category='error') | |||
|
164 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
165 | self._get_template_context(c), self.request) | |||
|
166 | html = formencode.htmlfill.render( | |||
|
167 | data, | |||
|
168 | defaults=errors.value, | |||
|
169 | errors=errors.error_dict or {}, | |||
|
170 | prefix_error=False, | |||
|
171 | encoding="UTF-8", | |||
|
172 | force_defaults=False | |||
|
173 | ) | |||
|
174 | return Response(html) | |||
|
175 | ||||
|
176 | try: | |||
|
177 | if c.visual.allow_repo_location_change: | |||
|
178 | model.update_global_path_setting( | |||
|
179 | form_result['paths_root_path']) | |||
|
180 | ||||
|
181 | model.update_global_ssl_setting(form_result['web_push_ssl']) | |||
|
182 | model.update_global_hook_settings(form_result) | |||
|
183 | ||||
|
184 | model.create_or_update_global_svn_settings(form_result) | |||
|
185 | model.create_or_update_global_hg_settings(form_result) | |||
|
186 | model.create_or_update_global_git_settings(form_result) | |||
|
187 | model.create_or_update_global_pr_settings(form_result) | |||
|
188 | except Exception: | |||
|
189 | log.exception("Exception while updating settings") | |||
|
190 | h.flash(_('Error occurred during updating ' | |||
|
191 | 'application settings'), category='error') | |||
|
192 | else: | |||
|
193 | Session().commit() | |||
|
194 | h.flash(_('Updated VCS settings'), category='success') | |||
|
195 | raise HTTPFound(h.route_path('admin_settings_vcs')) | |||
|
196 | ||||
|
197 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
198 | self._get_template_context(c), self.request) | |||
|
199 | html = formencode.htmlfill.render( | |||
|
200 | data, | |||
|
201 | defaults=self._form_defaults(), | |||
|
202 | encoding="UTF-8", | |||
|
203 | force_defaults=False | |||
|
204 | ) | |||
|
205 | return Response(html) | |||
|
206 | ||||
|
207 | @LoginRequired() | |||
|
208 | @HasPermissionAllDecorator('hg.admin') | |||
|
209 | @CSRFRequired() | |||
|
210 | @view_config( | |||
|
211 | route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST', | |||
|
212 | renderer='json_ext', xhr=True) | |||
|
213 | def settings_vcs_delete_svn_pattern(self): | |||
|
214 | delete_pattern_id = self.request.POST.get('delete_svn_pattern') | |||
|
215 | model = VcsSettingsModel() | |||
|
216 | try: | |||
|
217 | model.delete_global_svn_pattern(delete_pattern_id) | |||
|
218 | except SettingNotFound: | |||
|
219 | log.exception( | |||
|
220 | 'Failed to delete svn_pattern with id %s', delete_pattern_id) | |||
|
221 | raise HTTPNotFound() | |||
|
222 | ||||
|
223 | Session().commit() | |||
|
224 | return True | |||
|
225 | ||||
|
226 | @LoginRequired() | |||
|
227 | @HasPermissionAllDecorator('hg.admin') | |||
|
228 | @view_config( | |||
|
229 | route_name='admin_settings_mapping', request_method='GET', | |||
|
230 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
231 | def settings_mapping(self): | |||
|
232 | c = self.load_default_context() | |||
|
233 | c.active = 'mapping' | |||
|
234 | ||||
|
235 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
236 | self._get_template_context(c), self.request) | |||
|
237 | html = formencode.htmlfill.render( | |||
|
238 | data, | |||
|
239 | defaults=self._form_defaults(), | |||
|
240 | encoding="UTF-8", | |||
|
241 | force_defaults=False | |||
|
242 | ) | |||
|
243 | return Response(html) | |||
|
244 | ||||
|
245 | @LoginRequired() | |||
|
246 | @HasPermissionAllDecorator('hg.admin') | |||
|
247 | @CSRFRequired() | |||
|
248 | @view_config( | |||
|
249 | route_name='admin_settings_mapping_update', request_method='POST', | |||
|
250 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
251 | def settings_mapping_update(self): | |||
|
252 | _ = self.request.translate | |||
|
253 | c = self.load_default_context() | |||
|
254 | c.active = 'mapping' | |||
|
255 | rm_obsolete = self.request.POST.get('destroy', False) | |||
|
256 | invalidate_cache = self.request.POST.get('invalidate', False) | |||
|
257 | log.debug( | |||
|
258 | 'rescanning repo location with destroy obsolete=%s', rm_obsolete) | |||
|
259 | ||||
|
260 | if invalidate_cache: | |||
|
261 | log.debug('invalidating all repositories cache') | |||
|
262 | for repo in Repository.get_all(): | |||
|
263 | ScmModel().mark_for_invalidation(repo.repo_name, delete=True) | |||
|
264 | ||||
|
265 | filesystem_repos = ScmModel().repo_scan() | |||
|
266 | added, removed = repo2db_mapper(filesystem_repos, rm_obsolete) | |||
|
267 | _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-' | |||
|
268 | h.flash(_('Repositories successfully ' | |||
|
269 | 'rescanned added: %s ; removed: %s') % | |||
|
270 | (_repr(added), _repr(removed)), | |||
|
271 | category='success') | |||
|
272 | raise HTTPFound(h.route_path('admin_settings_mapping')) | |||
|
273 | ||||
|
274 | @LoginRequired() | |||
|
275 | @HasPermissionAllDecorator('hg.admin') | |||
|
276 | @view_config( | |||
|
277 | route_name='admin_settings', request_method='GET', | |||
|
278 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
279 | @view_config( | |||
|
280 | route_name='admin_settings_global', request_method='GET', | |||
|
281 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
282 | def settings_global(self): | |||
|
283 | c = self.load_default_context() | |||
|
284 | c.active = 'global' | |||
|
285 | c.personal_repo_group_default_pattern = RepoGroupModel()\ | |||
|
286 | .get_personal_group_name_pattern() | |||
|
287 | ||||
|
288 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
289 | self._get_template_context(c), self.request) | |||
|
290 | html = formencode.htmlfill.render( | |||
|
291 | data, | |||
|
292 | defaults=self._form_defaults(), | |||
|
293 | encoding="UTF-8", | |||
|
294 | force_defaults=False | |||
|
295 | ) | |||
|
296 | return Response(html) | |||
|
297 | ||||
|
298 | @LoginRequired() | |||
|
299 | @HasPermissionAllDecorator('hg.admin') | |||
|
300 | @CSRFRequired() | |||
|
301 | @view_config( | |||
|
302 | route_name='admin_settings_update', request_method='POST', | |||
|
303 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
304 | @view_config( | |||
|
305 | route_name='admin_settings_global_update', request_method='POST', | |||
|
306 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
307 | def settings_global_update(self): | |||
|
308 | _ = self.request.translate | |||
|
309 | c = self.load_default_context() | |||
|
310 | c.active = 'global' | |||
|
311 | c.personal_repo_group_default_pattern = RepoGroupModel()\ | |||
|
312 | .get_personal_group_name_pattern() | |||
|
313 | application_form = ApplicationSettingsForm(self.request.translate)() | |||
|
314 | try: | |||
|
315 | form_result = application_form.to_python(dict(self.request.POST)) | |||
|
316 | except formencode.Invalid as errors: | |||
|
317 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
318 | self._get_template_context(c), self.request) | |||
|
319 | html = formencode.htmlfill.render( | |||
|
320 | data, | |||
|
321 | defaults=errors.value, | |||
|
322 | errors=errors.error_dict or {}, | |||
|
323 | prefix_error=False, | |||
|
324 | encoding="UTF-8", | |||
|
325 | force_defaults=False | |||
|
326 | ) | |||
|
327 | return Response(html) | |||
|
328 | ||||
|
329 | settings = [ | |||
|
330 | ('title', 'rhodecode_title', 'unicode'), | |||
|
331 | ('realm', 'rhodecode_realm', 'unicode'), | |||
|
332 | ('pre_code', 'rhodecode_pre_code', 'unicode'), | |||
|
333 | ('post_code', 'rhodecode_post_code', 'unicode'), | |||
|
334 | ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'), | |||
|
335 | ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'), | |||
|
336 | ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'), | |||
|
337 | ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'), | |||
|
338 | ] | |||
|
339 | try: | |||
|
340 | for setting, form_key, type_ in settings: | |||
|
341 | sett = SettingsModel().create_or_update_setting( | |||
|
342 | setting, form_result[form_key], type_) | |||
|
343 | Session().add(sett) | |||
|
344 | ||||
|
345 | Session().commit() | |||
|
346 | SettingsModel().invalidate_settings_cache() | |||
|
347 | h.flash(_('Updated application settings'), category='success') | |||
|
348 | except Exception: | |||
|
349 | log.exception("Exception while updating application settings") | |||
|
350 | h.flash( | |||
|
351 | _('Error occurred during updating application settings'), | |||
|
352 | category='error') | |||
|
353 | ||||
|
354 | raise HTTPFound(h.route_path('admin_settings_global')) | |||
|
355 | ||||
|
356 | @LoginRequired() | |||
|
357 | @HasPermissionAllDecorator('hg.admin') | |||
|
358 | @view_config( | |||
|
359 | route_name='admin_settings_visual', request_method='GET', | |||
|
360 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
361 | def settings_visual(self): | |||
|
362 | c = self.load_default_context() | |||
|
363 | c.active = 'visual' | |||
|
364 | ||||
|
365 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
366 | self._get_template_context(c), self.request) | |||
|
367 | html = formencode.htmlfill.render( | |||
|
368 | data, | |||
|
369 | defaults=self._form_defaults(), | |||
|
370 | encoding="UTF-8", | |||
|
371 | force_defaults=False | |||
|
372 | ) | |||
|
373 | return Response(html) | |||
|
374 | ||||
|
375 | @LoginRequired() | |||
|
376 | @HasPermissionAllDecorator('hg.admin') | |||
|
377 | @CSRFRequired() | |||
|
378 | @view_config( | |||
|
379 | route_name='admin_settings_visual_update', request_method='POST', | |||
|
380 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
381 | def settings_visual_update(self): | |||
|
382 | _ = self.request.translate | |||
|
383 | c = self.load_default_context() | |||
|
384 | c.active = 'visual' | |||
|
385 | application_form = ApplicationVisualisationForm(self.request.translate)() | |||
|
386 | try: | |||
|
387 | form_result = application_form.to_python(dict(self.request.POST)) | |||
|
388 | except formencode.Invalid as errors: | |||
|
389 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
390 | self._get_template_context(c), self.request) | |||
|
391 | html = formencode.htmlfill.render( | |||
|
392 | data, | |||
|
393 | defaults=errors.value, | |||
|
394 | errors=errors.error_dict or {}, | |||
|
395 | prefix_error=False, | |||
|
396 | encoding="UTF-8", | |||
|
397 | force_defaults=False | |||
|
398 | ) | |||
|
399 | return Response(html) | |||
|
400 | ||||
|
401 | try: | |||
|
402 | settings = [ | |||
|
403 | ('show_public_icon', 'rhodecode_show_public_icon', 'bool'), | |||
|
404 | ('show_private_icon', 'rhodecode_show_private_icon', 'bool'), | |||
|
405 | ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'), | |||
|
406 | ('repository_fields', 'rhodecode_repository_fields', 'bool'), | |||
|
407 | ('dashboard_items', 'rhodecode_dashboard_items', 'int'), | |||
|
408 | ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'), | |||
|
409 | ('show_version', 'rhodecode_show_version', 'bool'), | |||
|
410 | ('use_gravatar', 'rhodecode_use_gravatar', 'bool'), | |||
|
411 | ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'), | |||
|
412 | ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'), | |||
|
413 | ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'), | |||
|
414 | ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'), | |||
|
415 | ('support_url', 'rhodecode_support_url', 'unicode'), | |||
|
416 | ('show_revision_number', 'rhodecode_show_revision_number', 'bool'), | |||
|
417 | ('show_sha_length', 'rhodecode_show_sha_length', 'int'), | |||
|
418 | ] | |||
|
419 | for setting, form_key, type_ in settings: | |||
|
420 | sett = SettingsModel().create_or_update_setting( | |||
|
421 | setting, form_result[form_key], type_) | |||
|
422 | Session().add(sett) | |||
|
423 | ||||
|
424 | Session().commit() | |||
|
425 | SettingsModel().invalidate_settings_cache() | |||
|
426 | h.flash(_('Updated visualisation settings'), category='success') | |||
|
427 | except Exception: | |||
|
428 | log.exception("Exception updating visualization settings") | |||
|
429 | h.flash(_('Error occurred during updating ' | |||
|
430 | 'visualisation settings'), | |||
|
431 | category='error') | |||
|
432 | ||||
|
433 | raise HTTPFound(h.route_path('admin_settings_visual')) | |||
|
434 | ||||
|
435 | @LoginRequired() | |||
|
436 | @HasPermissionAllDecorator('hg.admin') | |||
|
437 | @view_config( | |||
|
438 | route_name='admin_settings_issuetracker', request_method='GET', | |||
|
439 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
440 | def settings_issuetracker(self): | |||
|
441 | c = self.load_default_context() | |||
|
442 | c.active = 'issuetracker' | |||
|
443 | defaults = SettingsModel().get_all_settings() | |||
|
444 | ||||
|
445 | entry_key = 'rhodecode_issuetracker_pat_' | |||
|
446 | ||||
|
447 | c.issuetracker_entries = {} | |||
|
448 | for k, v in defaults.items(): | |||
|
449 | if k.startswith(entry_key): | |||
|
450 | uid = k[len(entry_key):] | |||
|
451 | c.issuetracker_entries[uid] = None | |||
|
452 | ||||
|
453 | for uid in c.issuetracker_entries: | |||
|
454 | c.issuetracker_entries[uid] = AttributeDict({ | |||
|
455 | 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid), | |||
|
456 | 'url': defaults.get('rhodecode_issuetracker_url_' + uid), | |||
|
457 | 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid), | |||
|
458 | 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid), | |||
|
459 | }) | |||
|
460 | ||||
|
461 | return self._get_template_context(c) | |||
|
462 | ||||
|
463 | @LoginRequired() | |||
|
464 | @HasPermissionAllDecorator('hg.admin') | |||
|
465 | @CSRFRequired() | |||
|
466 | @view_config( | |||
|
467 | route_name='admin_settings_issuetracker_test', request_method='POST', | |||
|
468 | renderer='string', xhr=True) | |||
|
469 | def settings_issuetracker_test(self): | |||
|
470 | return h.urlify_commit_message( | |||
|
471 | self.request.POST.get('test_text', ''), | |||
|
472 | 'repo_group/test_repo1') | |||
|
473 | ||||
|
474 | @LoginRequired() | |||
|
475 | @HasPermissionAllDecorator('hg.admin') | |||
|
476 | @CSRFRequired() | |||
|
477 | @view_config( | |||
|
478 | route_name='admin_settings_issuetracker_update', request_method='POST', | |||
|
479 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
480 | def settings_issuetracker_update(self): | |||
|
481 | _ = self.request.translate | |||
|
482 | self.load_default_context() | |||
|
483 | settings_model = IssueTrackerSettingsModel() | |||
|
484 | ||||
|
485 | try: | |||
|
486 | form = IssueTrackerPatternsForm(self.request.translate)() | |||
|
487 | data = form.to_python(self.request.POST) | |||
|
488 | except formencode.Invalid as errors: | |||
|
489 | log.exception('Failed to add new pattern') | |||
|
490 | error = errors | |||
|
491 | h.flash(_('Invalid issue tracker pattern: {}'.format(error)), | |||
|
492 | category='error') | |||
|
493 | raise HTTPFound(h.route_path('admin_settings_issuetracker')) | |||
|
494 | ||||
|
495 | if data: | |||
|
496 | for uid in data.get('delete_patterns', []): | |||
|
497 | settings_model.delete_entries(uid) | |||
|
498 | ||||
|
499 | for pattern in data.get('patterns', []): | |||
|
500 | for setting, value, type_ in pattern: | |||
|
501 | sett = settings_model.create_or_update_setting( | |||
|
502 | setting, value, type_) | |||
|
503 | Session().add(sett) | |||
|
504 | ||||
|
505 | Session().commit() | |||
|
506 | ||||
|
507 | SettingsModel().invalidate_settings_cache() | |||
|
508 | h.flash(_('Updated issue tracker entries'), category='success') | |||
|
509 | raise HTTPFound(h.route_path('admin_settings_issuetracker')) | |||
|
510 | ||||
|
511 | @LoginRequired() | |||
|
512 | @HasPermissionAllDecorator('hg.admin') | |||
|
513 | @CSRFRequired() | |||
|
514 | @view_config( | |||
|
515 | route_name='admin_settings_issuetracker_delete', request_method='POST', | |||
|
516 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
517 | def settings_issuetracker_delete(self): | |||
|
518 | _ = self.request.translate | |||
|
519 | self.load_default_context() | |||
|
520 | uid = self.request.POST.get('uid') | |||
|
521 | try: | |||
|
522 | IssueTrackerSettingsModel().delete_entries(uid) | |||
|
523 | except Exception: | |||
|
524 | log.exception('Failed to delete issue tracker setting %s', uid) | |||
|
525 | raise HTTPNotFound() | |||
|
526 | h.flash(_('Removed issue tracker entry'), category='success') | |||
|
527 | raise HTTPFound(h.route_path('admin_settings_issuetracker')) | |||
|
528 | ||||
|
529 | @LoginRequired() | |||
|
530 | @HasPermissionAllDecorator('hg.admin') | |||
|
531 | @view_config( | |||
|
532 | route_name='admin_settings_email', request_method='GET', | |||
|
533 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
534 | def settings_email(self): | |||
|
535 | c = self.load_default_context() | |||
|
536 | c.active = 'email' | |||
|
537 | c.rhodecode_ini = rhodecode.CONFIG | |||
|
538 | ||||
|
539 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
540 | self._get_template_context(c), self.request) | |||
|
541 | html = formencode.htmlfill.render( | |||
|
542 | data, | |||
|
543 | defaults=self._form_defaults(), | |||
|
544 | encoding="UTF-8", | |||
|
545 | force_defaults=False | |||
|
546 | ) | |||
|
547 | return Response(html) | |||
|
548 | ||||
|
549 | @LoginRequired() | |||
|
550 | @HasPermissionAllDecorator('hg.admin') | |||
|
551 | @CSRFRequired() | |||
|
552 | @view_config( | |||
|
553 | route_name='admin_settings_email_update', request_method='POST', | |||
|
554 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
555 | def settings_email_update(self): | |||
|
556 | _ = self.request.translate | |||
|
557 | c = self.load_default_context() | |||
|
558 | c.active = 'email' | |||
|
559 | ||||
|
560 | test_email = self.request.POST.get('test_email') | |||
|
561 | ||||
|
562 | if not test_email: | |||
|
563 | h.flash(_('Please enter email address'), category='error') | |||
|
564 | raise HTTPFound(h.route_path('admin_settings_email')) | |||
|
565 | ||||
|
566 | email_kwargs = { | |||
|
567 | 'date': datetime.datetime.now(), | |||
|
568 | 'user': c.rhodecode_user, | |||
|
569 | 'rhodecode_version': c.rhodecode_version | |||
|
570 | } | |||
|
571 | ||||
|
572 | (subject, headers, email_body, | |||
|
573 | email_body_plaintext) = EmailNotificationModel().render_email( | |||
|
574 | EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs) | |||
|
575 | ||||
|
576 | recipients = [test_email] if test_email else None | |||
|
577 | ||||
|
578 | run_task(tasks.send_email, recipients, subject, | |||
|
579 | email_body_plaintext, email_body) | |||
|
580 | ||||
|
581 | h.flash(_('Send email task created'), category='success') | |||
|
582 | raise HTTPFound(h.route_path('admin_settings_email')) | |||
|
583 | ||||
|
584 | @LoginRequired() | |||
|
585 | @HasPermissionAllDecorator('hg.admin') | |||
|
586 | @view_config( | |||
|
587 | route_name='admin_settings_hooks', request_method='GET', | |||
|
588 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
589 | def settings_hooks(self): | |||
|
590 | c = self.load_default_context() | |||
|
591 | c.active = 'hooks' | |||
|
592 | ||||
|
593 | model = SettingsModel() | |||
|
594 | c.hooks = model.get_builtin_hooks() | |||
|
595 | c.custom_hooks = model.get_custom_hooks() | |||
|
596 | ||||
|
597 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
598 | self._get_template_context(c), self.request) | |||
|
599 | html = formencode.htmlfill.render( | |||
|
600 | data, | |||
|
601 | defaults=self._form_defaults(), | |||
|
602 | encoding="UTF-8", | |||
|
603 | force_defaults=False | |||
|
604 | ) | |||
|
605 | return Response(html) | |||
|
606 | ||||
|
607 | @LoginRequired() | |||
|
608 | @HasPermissionAllDecorator('hg.admin') | |||
|
609 | @CSRFRequired() | |||
|
610 | @view_config( | |||
|
611 | route_name='admin_settings_hooks_update', request_method='POST', | |||
|
612 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
613 | @view_config( | |||
|
614 | route_name='admin_settings_hooks_delete', request_method='POST', | |||
|
615 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
616 | def settings_hooks_update(self): | |||
|
617 | _ = self.request.translate | |||
|
618 | c = self.load_default_context() | |||
|
619 | c.active = 'hooks' | |||
|
620 | if c.visual.allow_custom_hooks_settings: | |||
|
621 | ui_key = self.request.POST.get('new_hook_ui_key') | |||
|
622 | ui_value = self.request.POST.get('new_hook_ui_value') | |||
|
623 | ||||
|
624 | hook_id = self.request.POST.get('hook_id') | |||
|
625 | new_hook = False | |||
|
626 | ||||
|
627 | model = SettingsModel() | |||
|
628 | try: | |||
|
629 | if ui_value and ui_key: | |||
|
630 | model.create_or_update_hook(ui_key, ui_value) | |||
|
631 | h.flash(_('Added new hook'), category='success') | |||
|
632 | new_hook = True | |||
|
633 | elif hook_id: | |||
|
634 | RhodeCodeUi.delete(hook_id) | |||
|
635 | Session().commit() | |||
|
636 | ||||
|
637 | # check for edits | |||
|
638 | update = False | |||
|
639 | _d = self.request.POST.dict_of_lists() | |||
|
640 | for k, v in zip(_d.get('hook_ui_key', []), | |||
|
641 | _d.get('hook_ui_value_new', [])): | |||
|
642 | model.create_or_update_hook(k, v) | |||
|
643 | update = True | |||
|
644 | ||||
|
645 | if update and not new_hook: | |||
|
646 | h.flash(_('Updated hooks'), category='success') | |||
|
647 | Session().commit() | |||
|
648 | except Exception: | |||
|
649 | log.exception("Exception during hook creation") | |||
|
650 | h.flash(_('Error occurred during hook creation'), | |||
|
651 | category='error') | |||
|
652 | ||||
|
653 | raise HTTPFound(h.route_path('admin_settings_hooks')) | |||
|
654 | ||||
|
655 | @LoginRequired() | |||
|
656 | @HasPermissionAllDecorator('hg.admin') | |||
|
657 | @view_config( | |||
|
658 | route_name='admin_settings_search', request_method='GET', | |||
|
659 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
660 | def settings_search(self): | |||
|
661 | c = self.load_default_context() | |||
|
662 | c.active = 'search' | |||
|
663 | ||||
|
664 | searcher = searcher_from_config(self.request.registry.settings) | |||
|
665 | c.statistics = searcher.statistics(self.request.translate) | |||
|
666 | ||||
|
667 | return self._get_template_context(c) | |||
|
668 | ||||
|
669 | @LoginRequired() | |||
|
670 | @HasPermissionAllDecorator('hg.admin') | |||
|
671 | @view_config( | |||
|
672 | route_name='admin_settings_labs', request_method='GET', | |||
|
673 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
674 | def settings_labs(self): | |||
|
675 | c = self.load_default_context() | |||
|
676 | if not c.labs_active: | |||
|
677 | raise HTTPFound(h.route_path('admin_settings')) | |||
|
678 | ||||
|
679 | c.active = 'labs' | |||
|
680 | c.lab_settings = _LAB_SETTINGS | |||
|
681 | ||||
|
682 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
683 | self._get_template_context(c), self.request) | |||
|
684 | html = formencode.htmlfill.render( | |||
|
685 | data, | |||
|
686 | defaults=self._form_defaults(), | |||
|
687 | encoding="UTF-8", | |||
|
688 | force_defaults=False | |||
|
689 | ) | |||
|
690 | return Response(html) | |||
|
691 | ||||
|
692 | @LoginRequired() | |||
|
693 | @HasPermissionAllDecorator('hg.admin') | |||
|
694 | @CSRFRequired() | |||
|
695 | @view_config( | |||
|
696 | route_name='admin_settings_labs_update', request_method='POST', | |||
|
697 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
698 | def settings_labs_update(self): | |||
|
699 | _ = self.request.translate | |||
|
700 | c = self.load_default_context() | |||
|
701 | c.active = 'labs' | |||
|
702 | ||||
|
703 | application_form = LabsSettingsForm(self.request.translate)() | |||
|
704 | try: | |||
|
705 | form_result = application_form.to_python(dict(self.request.POST)) | |||
|
706 | except formencode.Invalid as errors: | |||
|
707 | h.flash( | |||
|
708 | _('Some form inputs contain invalid data.'), | |||
|
709 | category='error') | |||
|
710 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
711 | self._get_template_context(c), self.request) | |||
|
712 | html = formencode.htmlfill.render( | |||
|
713 | data, | |||
|
714 | defaults=errors.value, | |||
|
715 | errors=errors.error_dict or {}, | |||
|
716 | prefix_error=False, | |||
|
717 | encoding="UTF-8", | |||
|
718 | force_defaults=False | |||
|
719 | ) | |||
|
720 | return Response(html) | |||
|
721 | ||||
|
722 | try: | |||
|
723 | session = Session() | |||
|
724 | for setting in _LAB_SETTINGS: | |||
|
725 | setting_name = setting.key[len('rhodecode_'):] | |||
|
726 | sett = SettingsModel().create_or_update_setting( | |||
|
727 | setting_name, form_result[setting.key], setting.type) | |||
|
728 | session.add(sett) | |||
|
729 | ||||
|
730 | except Exception: | |||
|
731 | log.exception('Exception while updating lab settings') | |||
|
732 | h.flash(_('Error occurred during updating labs settings'), | |||
|
733 | category='error') | |||
|
734 | else: | |||
|
735 | Session().commit() | |||
|
736 | SettingsModel().invalidate_settings_cache() | |||
|
737 | h.flash(_('Updated Labs settings'), category='success') | |||
|
738 | raise HTTPFound(h.route_path('admin_settings_labs')) | |||
|
739 | ||||
|
740 | data = render('rhodecode:templates/admin/settings/settings.mako', | |||
|
741 | self._get_template_context(c), self.request) | |||
|
742 | html = formencode.htmlfill.render( | |||
|
743 | data, | |||
|
744 | defaults=self._form_defaults(), | |||
|
745 | encoding="UTF-8", | |||
|
746 | force_defaults=False | |||
|
747 | ) | |||
|
748 | return Response(html) | |||
|
749 | ||||
|
750 | ||||
|
751 | # :param key: name of the setting including the 'rhodecode_' prefix | |||
|
752 | # :param type: the RhodeCodeSetting type to use. | |||
|
753 | # :param group: the i18ned group in which we should dispaly this setting | |||
|
754 | # :param label: the i18ned label we should display for this setting | |||
|
755 | # :param help: the i18ned help we should dispaly for this setting | |||
|
756 | LabSetting = collections.namedtuple( | |||
|
757 | 'LabSetting', ('key', 'type', 'group', 'label', 'help')) | |||
|
758 | ||||
|
759 | ||||
|
760 | # This list has to be kept in sync with the form | |||
|
761 | # rhodecode.model.forms.LabsSettingsForm. | |||
|
762 | _LAB_SETTINGS = [ | |||
|
763 | ||||
|
764 | ] |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
@@ -1,5 +1,5 b'' | |||||
1 | [bumpversion] |
|
1 | [bumpversion] | |
2 |
current_version = 4.1 |
|
2 | current_version = 4.11.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] |
@@ -3,15 +3,11 b'' | |||||
3 | branch = True |
|
3 | branch = True | |
4 |
|
4 | |||
5 | include = |
|
5 | include = | |
6 |
rhodecode/ |
|
6 | rhodecode/* | |
7 | rhodecode/model/* |
|
|||
8 | rhodecode/controllers/* |
|
|||
9 |
|
7 | |||
10 | omit = |
|
8 | omit = | |
11 | rhodecode/lib/vcs/remote/* |
|
|||
12 | rhodecode/lib/dbmigrate/* |
|
9 | rhodecode/lib/dbmigrate/* | |
13 | rhodecode/lib/paster_commands/* |
|
10 | rhodecode/lib/paster_commands/* | |
14 | rhodecode/tests/* |
|
|||
15 |
|
11 | |||
16 | [report] |
|
12 | [report] | |
17 |
|
13 |
@@ -21,7 +21,7 b' syntax: regexp' | |||||
21 | ^\.rhodecode$ |
|
21 | ^\.rhodecode$ | |
22 |
|
22 | |||
23 | ^rcextensions |
|
23 | ^rcextensions | |
24 |
^ |
|
24 | ^.dev | |
25 | ^._dev |
|
25 | ^._dev | |
26 | ^build/ |
|
26 | ^build/ | |
27 | ^bower_components/ |
|
27 | ^bower_components/ |
@@ -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.11.0 | |
25 |
|
||||
26 | [task:updated_translation] |
|
|||
27 |
|
22 | |||
28 | [task:generate_js_routes] |
|
23 | [task:generate_js_routes] | |
29 |
|
24 |
@@ -79,7 +79,7 b' asyncore_use_poll = true' | |||||
79 | #proc_name = rhodecode |
|
79 | #proc_name = rhodecode | |
80 | ## type of worker class, one of sync, gevent |
|
80 | ## type of worker class, one of sync, gevent | |
81 | ## recommended for bigger setup is using of of other than sync one |
|
81 | ## recommended for bigger setup is using of of other than sync one | |
82 |
#worker_class = |
|
82 | #worker_class = gevent | |
83 | ## The maximum number of simultaneous clients. Valid only for Gevent |
|
83 | ## The maximum number of simultaneous clients. Valid only for Gevent | |
84 | #worker_connections = 10 |
|
84 | #worker_connections = 10 | |
85 | ## max number of requests that worker will handle before being gracefully |
|
85 | ## max number of requests that worker will handle before being gracefully | |
@@ -295,29 +295,21 b' labs_settings_active = true' | |||||
295 | #################################### |
|
295 | #################################### | |
296 | ### CELERY CONFIG #### |
|
296 | ### CELERY CONFIG #### | |
297 | #################################### |
|
297 | #################################### | |
298 | use_celery = false |
|
298 | ## run: /path/to/celery worker \ | |
299 | broker.host = localhost |
|
299 | ## -E --beat --app rhodecode.lib.celerylib.loader \ | |
300 | broker.vhost = rabbitmqhost |
|
300 | ## --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler \ | |
301 | broker.port = 5672 |
|
301 | ## --loglevel DEBUG --ini /path/to/rhodecode.ini | |
302 | broker.user = rabbitmq |
|
|||
303 | broker.password = qweqwe |
|
|||
304 |
|
||||
305 | celery.imports = rhodecode.lib.celerylib.tasks |
|
|||
306 |
|
302 | |||
307 | celery.result.backend = amqp |
|
303 | use_celery = false | |
308 | celery.result.dburi = amqp:// |
|
|||
309 | celery.result.serialier = json |
|
|||
310 |
|
304 | |||
311 | #celery.send.task.error.emails = true |
|
305 | ## connection url to the message broker (default rabbitmq) | |
312 | #celery.amqp.task.result.expires = 18000 |
|
306 | celery.broker_url = amqp://rabbitmq:qweqwe@localhost:5672/rabbitmqhost | |
313 |
|
307 | |||
314 | celeryd.concurrency = 2 |
|
308 | ## maximum tasks to execute before worker restart | |
315 | #celeryd.log.file = celeryd.log |
|
309 | celery.max_tasks_per_child = 100 | |
316 | celeryd.log.level = debug |
|
|||
317 | celeryd.max.tasks.per.child = 1 |
|
|||
318 |
|
310 | |||
319 | ## tasks will never be sent to the queue, but executed locally instead. |
|
311 | ## tasks will never be sent to the queue, but executed locally instead. | |
320 |
celery.always |
|
312 | celery.task_always_eager = false | |
321 |
|
313 | |||
322 | #################################### |
|
314 | #################################### | |
323 | ### BEAKER CACHE #### |
|
315 | ### BEAKER CACHE #### | |
@@ -567,7 +559,7 b' vcs.hooks.protocol = http' | |||||
567 |
|
559 | |||
568 | vcs.server.log_level = debug |
|
560 | vcs.server.log_level = debug | |
569 | ## Start VCSServer with this instance as a subprocess, usefull for development |
|
561 | ## Start VCSServer with this instance as a subprocess, usefull for development | |
570 |
vcs.start_server = |
|
562 | vcs.start_server = false | |
571 |
|
563 | |||
572 | ## List of enabled VCS backends, available options are: |
|
564 | ## List of enabled VCS backends, available options are: | |
573 | ## `hg` - mercurial |
|
565 | ## `hg` - mercurial | |
@@ -649,7 +641,7 b' custom.conf = 1' | |||||
649 | ### LOGGING CONFIGURATION #### |
|
641 | ### LOGGING CONFIGURATION #### | |
650 | ################################ |
|
642 | ################################ | |
651 | [loggers] |
|
643 | [loggers] | |
652 | keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper |
|
644 | keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper, celery | |
653 |
|
645 | |||
654 | [handlers] |
|
646 | [handlers] | |
655 | keys = console, console_sql |
|
647 | keys = console, console_sql | |
@@ -688,6 +680,11 b' handlers =' | |||||
688 | qualname = ssh_wrapper |
|
680 | qualname = ssh_wrapper | |
689 | propagate = 1 |
|
681 | propagate = 1 | |
690 |
|
682 | |||
|
683 | [logger_celery] | |||
|
684 | level = DEBUG | |||
|
685 | handlers = | |||
|
686 | qualname = celery | |||
|
687 | ||||
691 |
|
688 | |||
692 | ############## |
|
689 | ############## | |
693 | ## HANDLERS ## |
|
690 | ## HANDLERS ## |
@@ -28,9 +28,30 b" accesslog = '-'" | |||||
28 | loglevel = 'debug' |
|
28 | loglevel = 'debug' | |
29 |
|
29 | |||
30 | # SECURITY |
|
30 | # SECURITY | |
|
31 | ||||
|
32 | # The maximum size of HTTP request line in bytes. | |||
31 | limit_request_line = 4094 |
|
33 | limit_request_line = 4094 | |
32 | limit_request_fields = 100 |
|
34 | ||
33 | limit_request_field_size = 8190 |
|
35 | # Limit the number of HTTP headers fields in a request. | |
|
36 | limit_request_fields = 1024 | |||
|
37 | ||||
|
38 | # Limit the allowed size of an HTTP request header field. | |||
|
39 | # Value is a positive number or 0. | |||
|
40 | # Setting it to 0 will allow unlimited header field sizes. | |||
|
41 | limit_request_field_size = 0 | |||
|
42 | ||||
|
43 | ||||
|
44 | # Timeout for graceful workers restart. | |||
|
45 | # After receiving a restart signal, workers have this much time to finish | |||
|
46 | # serving requests. Workers still alive after the timeout (starting from the | |||
|
47 | # receipt of the restart signal) are force killed. | |||
|
48 | graceful_timeout = 30 | |||
|
49 | ||||
|
50 | ||||
|
51 | # The number of seconds to wait for requests on a Keep-Alive connection. | |||
|
52 | # Generally set in the 1-5 seconds range. | |||
|
53 | keepalive = 2 | |||
|
54 | ||||
34 |
|
55 | |||
35 | # SERVER MECHANICS |
|
56 | # SERVER MECHANICS | |
36 | # None == system temp dir |
|
57 | # None == system temp dir | |
@@ -57,10 +78,18 b' def pre_exec(server):' | |||||
57 | server.log.info("Forked child, re-executing.") |
|
78 | server.log.info("Forked child, re-executing.") | |
58 |
|
79 | |||
59 |
|
80 | |||
|
81 | def on_starting(server): | |||
|
82 | server.log.info("Server is starting.") | |||
|
83 | ||||
|
84 | ||||
60 | def when_ready(server): |
|
85 | def when_ready(server): | |
61 | server.log.info("Server is ready. Spawning workers") |
|
86 | server.log.info("Server is ready. Spawning workers") | |
62 |
|
87 | |||
63 |
|
88 | |||
|
89 | def on_reload(server): | |||
|
90 | pass | |||
|
91 | ||||
|
92 | ||||
64 | def worker_int(worker): |
|
93 | def worker_int(worker): | |
65 | worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid) |
|
94 | worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid) | |
66 |
|
95 | |||
@@ -81,6 +110,14 b' def worker_abort(worker):' | |||||
81 | worker.log.info("[<%-10s>] worker received SIGABRT signal", worker.pid) |
|
110 | worker.log.info("[<%-10s>] worker received SIGABRT signal", worker.pid) | |
82 |
|
111 | |||
83 |
|
112 | |||
|
113 | def worker_exit(server, worker): | |||
|
114 | worker.log.info("[<%-10s>] worker exit", worker.pid) | |||
|
115 | ||||
|
116 | ||||
|
117 | def child_exit(server, worker): | |||
|
118 | worker.log.info("[<%-10s>] worker child exit", worker.pid) | |||
|
119 | ||||
|
120 | ||||
84 | def pre_request(worker, req): |
|
121 | def pre_request(worker, req): | |
85 | return |
|
122 | return | |
86 | worker.log.debug("[<%-10s>] PRE WORKER: %s %s", |
|
123 | worker.log.debug("[<%-10s>] PRE WORKER: %s %s", | |
@@ -93,6 +130,7 b' def post_request(worker, req, environ, r' | |||||
93 | req.method, req.path, resp.status_code) |
|
130 | req.method, req.path, resp.status_code) | |
94 |
|
131 | |||
95 |
|
132 | |||
|
133 | ||||
96 | class RhodeCodeLogger(Logger): |
|
134 | class RhodeCodeLogger(Logger): | |
97 | """ |
|
135 | """ | |
98 | Custom Logger that allows some customization that gunicorn doesn't allow |
|
136 | Custom Logger that allows some customization that gunicorn doesn't allow |
@@ -79,7 +79,7 b' workers = 2' | |||||
79 | proc_name = rhodecode |
|
79 | proc_name = rhodecode | |
80 | ## type of worker class, one of sync, gevent |
|
80 | ## type of worker class, one of sync, gevent | |
81 | ## recommended for bigger setup is using of of other than sync one |
|
81 | ## recommended for bigger setup is using of of other than sync one | |
82 |
worker_class = |
|
82 | worker_class = gevent | |
83 | ## The maximum number of simultaneous clients. Valid only for Gevent |
|
83 | ## The maximum number of simultaneous clients. Valid only for Gevent | |
84 | #worker_connections = 10 |
|
84 | #worker_connections = 10 | |
85 | ## max number of requests that worker will handle before being gracefully |
|
85 | ## max number of requests that worker will handle before being gracefully | |
@@ -270,29 +270,21 b' labs_settings_active = true' | |||||
270 | #################################### |
|
270 | #################################### | |
271 | ### CELERY CONFIG #### |
|
271 | ### CELERY CONFIG #### | |
272 | #################################### |
|
272 | #################################### | |
273 | use_celery = false |
|
273 | ## run: /path/to/celery worker \ | |
274 | broker.host = localhost |
|
274 | ## -E --beat --app rhodecode.lib.celerylib.loader \ | |
275 | broker.vhost = rabbitmqhost |
|
275 | ## --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler \ | |
276 | broker.port = 5672 |
|
276 | ## --loglevel DEBUG --ini /path/to/rhodecode.ini | |
277 | broker.user = rabbitmq |
|
|||
278 | broker.password = qweqwe |
|
|||
279 |
|
||||
280 | celery.imports = rhodecode.lib.celerylib.tasks |
|
|||
281 |
|
277 | |||
282 | celery.result.backend = amqp |
|
278 | use_celery = false | |
283 | celery.result.dburi = amqp:// |
|
|||
284 | celery.result.serialier = json |
|
|||
285 |
|
279 | |||
286 | #celery.send.task.error.emails = true |
|
280 | ## connection url to the message broker (default rabbitmq) | |
287 | #celery.amqp.task.result.expires = 18000 |
|
281 | celery.broker_url = amqp://rabbitmq:qweqwe@localhost:5672/rabbitmqhost | |
288 |
|
282 | |||
289 | celeryd.concurrency = 2 |
|
283 | ## maximum tasks to execute before worker restart | |
290 | #celeryd.log.file = celeryd.log |
|
284 | celery.max_tasks_per_child = 100 | |
291 | celeryd.log.level = debug |
|
|||
292 | celeryd.max.tasks.per.child = 1 |
|
|||
293 |
|
285 | |||
294 | ## tasks will never be sent to the queue, but executed locally instead. |
|
286 | ## tasks will never be sent to the queue, but executed locally instead. | |
295 |
celery.always |
|
287 | celery.task_always_eager = false | |
296 |
|
288 | |||
297 | #################################### |
|
289 | #################################### | |
298 | ### BEAKER CACHE #### |
|
290 | ### BEAKER CACHE #### | |
@@ -619,7 +611,7 b' custom.conf = 1' | |||||
619 | ### LOGGING CONFIGURATION #### |
|
611 | ### LOGGING CONFIGURATION #### | |
620 | ################################ |
|
612 | ################################ | |
621 | [loggers] |
|
613 | [loggers] | |
622 | keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper |
|
614 | keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper, celery | |
623 |
|
615 | |||
624 | [handlers] |
|
616 | [handlers] | |
625 | keys = console, console_sql |
|
617 | keys = console, console_sql | |
@@ -658,6 +650,11 b' handlers =' | |||||
658 | qualname = ssh_wrapper |
|
650 | qualname = ssh_wrapper | |
659 | propagate = 1 |
|
651 | propagate = 1 | |
660 |
|
652 | |||
|
653 | [logger_celery] | |||
|
654 | level = DEBUG | |||
|
655 | handlers = | |||
|
656 | qualname = celery | |||
|
657 | ||||
661 |
|
658 | |||
662 | ############## |
|
659 | ############## | |
663 | ## HANDLERS ## |
|
660 | ## HANDLERS ## |
@@ -185,6 +185,7 b' let' | |||||
185 | ln -s ${self.supervisor}/bin/supervisor* $out/bin/ |
|
185 | ln -s ${self.supervisor}/bin/supervisor* $out/bin/ | |
186 | ln -s ${self.PasteScript}/bin/paster $out/bin/ |
|
186 | ln -s ${self.PasteScript}/bin/paster $out/bin/ | |
187 | ln -s ${self.channelstream}/bin/channelstream $out/bin/ |
|
187 | ln -s ${self.channelstream}/bin/channelstream $out/bin/ | |
|
188 | ln -s ${self.celery}/bin/celery $out/bin/ | |||
188 |
|
189 | |||
189 | # rhodecode-tools |
|
190 | # rhodecode-tools | |
190 | ln -s ${self.rhodecode-tools}/bin/rhodecode-* $out/bin/ |
|
191 | ln -s ${self.rhodecode-tools}/bin/rhodecode-* $out/bin/ |
@@ -70,7 +70,7 b' backup location:' | |||||
70 | $ mysql -u <uname> -p <pass> rhodecode_db_name < mysql-db-backup |
|
70 | $ mysql -u <uname> -p <pass> rhodecode_db_name < mysql-db-backup | |
71 |
|
71 | |||
72 | # For PostgreSQL DBs |
|
72 | # For PostgreSQL DBs | |
73 | $ PGPASSWORD=<pass> pg_dump rhodecode_db_name > postgresql-db-backup |
|
73 | $ PGPASSWORD=<pass> pg_dump --inserts -U <uname> -h localhost rhodecode_db_name > postgresql-db-backup | |
74 | # PosgreSQL restore |
|
74 | # PosgreSQL restore | |
75 | $ PGPASSWORD=<pass> psql -U <uname> -h localhost -d rhodecode_db_name -1 -f postgresql-db-backup |
|
75 | $ PGPASSWORD=<pass> psql -U <uname> -h localhost -d rhodecode_db_name -1 -f postgresql-db-backup | |
76 |
|
76 |
@@ -47,7 +47,7 b' the ``debug`` level.' | |||||
47 | ### LOGGING CONFIGURATION #### |
|
47 | ### LOGGING CONFIGURATION #### | |
48 | ################################ |
|
48 | ################################ | |
49 | [loggers] |
|
49 | [loggers] | |
50 |
keys = root, |
|
50 | keys = root, sqlalchemy, beaker, rhodecode, ssh_wrapper | |
51 |
|
51 | |||
52 | [handlers] |
|
52 | [handlers] | |
53 | keys = console, console_sql, file, file_rotating |
|
53 | keys = console, console_sql, file, file_rotating | |
@@ -75,12 +75,6 b' the ``debug`` level.' | |||||
75 | qualname = beaker.container |
|
75 | qualname = beaker.container | |
76 | propagate = 1 |
|
76 | propagate = 1 | |
77 |
|
77 | |||
78 | [logger_templates] |
|
|||
79 | level = INFO |
|
|||
80 | handlers = |
|
|||
81 | qualname = pylons.templating |
|
|||
82 | propagate = 1 |
|
|||
83 |
|
||||
84 | [logger_rhodecode] |
|
78 | [logger_rhodecode] | |
85 | level = DEBUG |
|
79 | level = DEBUG | |
86 | handlers = |
|
80 | handlers = |
@@ -9,7 +9,7 b' timeout during large pushes.' | |||||
9 | .. code-block:: nginx |
|
9 | .. code-block:: nginx | |
10 |
|
10 | |||
11 | proxy_redirect off; |
|
11 | proxy_redirect off; | |
12 | proxy_set_header Host $host; |
|
12 | proxy_set_header Host $http_host; | |
13 |
|
13 | |||
14 | ## needed for container auth |
|
14 | ## needed for container auth | |
15 | # proxy_set_header REMOTE_USER $remote_user; |
|
15 | # proxy_set_header REMOTE_USER $remote_user; |
@@ -13,3 +13,4 b' instances are configured in as secure a ' | |||||
13 | sec-x-frame |
|
13 | sec-x-frame | |
14 | sec-instance-basics |
|
14 | sec-instance-basics | |
15 | sec-ip-white |
|
15 | sec-ip-white | |
|
16 | sec-sophos-umc |
@@ -38,13 +38,13 b' changeset_comment' | |||||
38 |
|
38 | |||
39 | Example error output: |
|
39 | Example error output: | |
40 |
|
40 | |||
41 |
.. code-block:: j |
|
41 | .. code-block:: json | |
42 |
|
42 | |||
43 | { |
|
43 | { | |
44 |
"id" : |
|
44 | "id" : <id_given_in_input>, | |
45 | "result" : { |
|
45 | "result" : { | |
46 | "msg": "Commented on commit `<revision>` for repository `<repoid>`", |
|
46 | "msg": "Commented on commit `<revision>` for repository `<repoid>`", | |
47 |
"status_change": null or |
|
47 | "status_change": null or <status>, | |
48 | "success": true |
|
48 | "success": true | |
49 | }, |
|
49 | }, | |
50 | "error" : null |
|
50 | "error" : null |
@@ -6,7 +6,7 b' pull_request methods' | |||||
6 | close_pull_request |
|
6 | close_pull_request | |
7 | ------------------ |
|
7 | ------------------ | |
8 |
|
8 | |||
9 |
.. py:function:: close_pull_request(apiuser, |
|
9 | .. py:function:: close_pull_request(apiuser, pullrequestid, repoid=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>, message=<Optional:''>) | |
10 |
|
10 | |||
11 | Close the pull request specified by `pullrequestid`. |
|
11 | Close the pull request specified by `pullrequestid`. | |
12 |
|
12 | |||
@@ -39,7 +39,7 b' close_pull_request' | |||||
39 | comment_pull_request |
|
39 | comment_pull_request | |
40 | -------------------- |
|
40 | -------------------- | |
41 |
|
41 | |||
42 |
.. py:function:: comment_pull_request(apiuser, |
|
42 | .. py:function:: comment_pull_request(apiuser, pullrequestid, repoid=<Optional:None>, message=<Optional:None>, commit_id=<Optional:None>, status=<Optional:None>, comment_type=<Optional:u'note'>, resolves_comment_id=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>) | |
43 |
|
43 | |||
44 | Comment on the pull request specified with the `pullrequestid`, |
|
44 | Comment on the pull request specified with the `pullrequestid`, | |
45 | in the |repo| specified by the `repoid`, and optionally change the |
|
45 | in the |repo| specified by the `repoid`, and optionally change the | |
@@ -47,7 +47,7 b' comment_pull_request' | |||||
47 |
|
47 | |||
48 | :param apiuser: This is filled automatically from the |authtoken|. |
|
48 | :param apiuser: This is filled automatically from the |authtoken|. | |
49 | :type apiuser: AuthUser |
|
49 | :type apiuser: AuthUser | |
50 |
:param repoid: |
|
50 | :param repoid: Optional repository name or repository ID. | |
51 | :type repoid: str or int |
|
51 | :type repoid: str or int | |
52 | :param pullrequestid: The pull request ID. |
|
52 | :param pullrequestid: The pull request ID. | |
53 | :type pullrequestid: int |
|
53 | :type pullrequestid: int | |
@@ -120,14 +120,14 b' create_pull_request' | |||||
120 | get_pull_request |
|
120 | get_pull_request | |
121 | ---------------- |
|
121 | ---------------- | |
122 |
|
122 | |||
123 |
.. py:function:: get_pull_request(apiuser, |
|
123 | .. py:function:: get_pull_request(apiuser, pullrequestid, repoid=<Optional:None>) | |
124 |
|
124 | |||
125 | Get a pull request based on the given ID. |
|
125 | Get a pull request based on the given ID. | |
126 |
|
126 | |||
127 | :param apiuser: This is filled automatically from the |authtoken|. |
|
127 | :param apiuser: This is filled automatically from the |authtoken|. | |
128 | :type apiuser: AuthUser |
|
128 | :type apiuser: AuthUser | |
129 |
:param repoid: |
|
129 | :param repoid: Optional, repository name or repository ID from where | |
130 | request was opened. |
|
130 | the pull request was opened. | |
131 | :type repoid: str or int |
|
131 | :type repoid: str or int | |
132 | :param pullrequestid: ID of the requested pull request. |
|
132 | :param pullrequestid: ID of the requested pull request. | |
133 | :type pullrequestid: int |
|
133 | :type pullrequestid: int | |
@@ -199,6 +199,48 b' get_pull_request' | |||||
199 | "error": null |
|
199 | "error": null | |
200 |
|
200 | |||
201 |
|
201 | |||
|
202 | get_pull_request_comments | |||
|
203 | ------------------------- | |||
|
204 | ||||
|
205 | .. py:function:: get_pull_request_comments(apiuser, pullrequestid, repoid=<Optional:None>) | |||
|
206 | ||||
|
207 | Get all comments of pull request specified with the `pullrequestid` | |||
|
208 | ||||
|
209 | :param apiuser: This is filled automatically from the |authtoken|. | |||
|
210 | :type apiuser: AuthUser | |||
|
211 | :param repoid: Optional repository name or repository ID. | |||
|
212 | :type repoid: str or int | |||
|
213 | :param pullrequestid: The pull request ID. | |||
|
214 | :type pullrequestid: int | |||
|
215 | ||||
|
216 | Example output: | |||
|
217 | ||||
|
218 | .. code-block:: bash | |||
|
219 | ||||
|
220 | id : <id_given_in_input> | |||
|
221 | result : [ | |||
|
222 | { | |||
|
223 | "comment_author": { | |||
|
224 | "active": true, | |||
|
225 | "full_name_or_username": "Tom Gore", | |||
|
226 | "username": "admin" | |||
|
227 | }, | |||
|
228 | "comment_created_on": "2017-01-02T18:43:45.533", | |||
|
229 | "comment_f_path": null, | |||
|
230 | "comment_id": 25, | |||
|
231 | "comment_lineno": null, | |||
|
232 | "comment_status": { | |||
|
233 | "status": "under_review", | |||
|
234 | "status_lbl": "Under Review" | |||
|
235 | }, | |||
|
236 | "comment_text": "Example text", | |||
|
237 | "comment_type": null, | |||
|
238 | "pull_request_version": null | |||
|
239 | } | |||
|
240 | ], | |||
|
241 | error : null | |||
|
242 | ||||
|
243 | ||||
202 | get_pull_requests |
|
244 | get_pull_requests | |
203 | ----------------- |
|
245 | ----------------- | |
204 |
|
246 | |||
@@ -208,7 +250,7 b' get_pull_requests' | |||||
208 |
|
250 | |||
209 | :param apiuser: This is filled automatically from the |authtoken|. |
|
251 | :param apiuser: This is filled automatically from the |authtoken|. | |
210 | :type apiuser: AuthUser |
|
252 | :type apiuser: AuthUser | |
211 |
:param repoid: |
|
253 | :param repoid: Optional repository name or repository ID. | |
212 | :type repoid: str or int |
|
254 | :type repoid: str or int | |
213 | :param status: Only return pull requests with the specified status. |
|
255 | :param status: Only return pull requests with the specified status. | |
214 | Valid options are. |
|
256 | Valid options are. | |
@@ -289,14 +331,14 b' get_pull_requests' | |||||
289 | merge_pull_request |
|
331 | merge_pull_request | |
290 | ------------------ |
|
332 | ------------------ | |
291 |
|
333 | |||
292 |
.. py:function:: merge_pull_request(apiuser, |
|
334 | .. py:function:: merge_pull_request(apiuser, pullrequestid, repoid=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>) | |
293 |
|
335 | |||
294 | Merge the pull request specified by `pullrequestid` into its target |
|
336 | Merge the pull request specified by `pullrequestid` into its target | |
295 | repository. |
|
337 | repository. | |
296 |
|
338 | |||
297 | :param apiuser: This is filled automatically from the |authtoken|. |
|
339 | :param apiuser: This is filled automatically from the |authtoken|. | |
298 | :type apiuser: AuthUser |
|
340 | :type apiuser: AuthUser | |
299 |
:param repoid: |
|
341 | :param repoid: Optional, repository name or repository ID of the | |
300 | target repository to which the |pr| is to be merged. |
|
342 | target repository to which the |pr| is to be merged. | |
301 | :type repoid: str or int |
|
343 | :type repoid: str or int | |
302 | :param pullrequestid: ID of the pull request which shall be merged. |
|
344 | :param pullrequestid: ID of the pull request which shall be merged. | |
@@ -326,13 +368,13 b' merge_pull_request' | |||||
326 | update_pull_request |
|
368 | update_pull_request | |
327 | ------------------- |
|
369 | ------------------- | |
328 |
|
370 | |||
329 |
.. py:function:: update_pull_request(apiuser, |
|
371 | .. py:function:: update_pull_request(apiuser, pullrequestid, repoid=<Optional:None>, title=<Optional:''>, description=<Optional:''>, reviewers=<Optional:None>, update_commits=<Optional:None>) | |
330 |
|
372 | |||
331 | Updates a pull request. |
|
373 | Updates a pull request. | |
332 |
|
374 | |||
333 | :param apiuser: This is filled automatically from the |authtoken|. |
|
375 | :param apiuser: This is filled automatically from the |authtoken|. | |
334 | :type apiuser: AuthUser |
|
376 | :type apiuser: AuthUser | |
335 |
:param repoid: |
|
377 | :param repoid: Optional repository name or repository ID. | |
336 | :type repoid: str or int |
|
378 | :type repoid: str or int | |
337 | :param pullrequestid: The pull request ID. |
|
379 | :param pullrequestid: The pull request ID. | |
338 | :type pullrequestid: int |
|
380 | :type pullrequestid: int |
@@ -115,7 +115,7 b' get_repo_group' | |||||
115 | "group_description": "repo group description", |
|
115 | "group_description": "repo group description", | |
116 | "group_id": 14, |
|
116 | "group_id": 14, | |
117 | "group_name": "group name", |
|
117 | "group_name": "group name", | |
118 |
" |
|
118 | "permissions": [ | |
119 | { |
|
119 | { | |
120 | "name": "super-admin-username", |
|
120 | "name": "super-admin-username", | |
121 | "origin": "super-admin", |
|
121 | "origin": "super-admin", |
@@ -306,26 +306,6 b' get_repo' | |||||
306 | "lock_reason": null, |
|
306 | "lock_reason": null, | |
307 | "locked_by": null, |
|
307 | "locked_by": null, | |
308 | "locked_date": null, |
|
308 | "locked_date": null, | |
309 | "members": [ |
|
|||
310 | { |
|
|||
311 | "name": "super-admin-name", |
|
|||
312 | "origin": "super-admin", |
|
|||
313 | "permission": "repository.admin", |
|
|||
314 | "type": "user" |
|
|||
315 | }, |
|
|||
316 | { |
|
|||
317 | "name": "owner-name", |
|
|||
318 | "origin": "owner", |
|
|||
319 | "permission": "repository.admin", |
|
|||
320 | "type": "user" |
|
|||
321 | }, |
|
|||
322 | { |
|
|||
323 | "name": "user-group-name", |
|
|||
324 | "origin": "permission", |
|
|||
325 | "permission": "repository.write", |
|
|||
326 | "type": "user_group" |
|
|||
327 | } |
|
|||
328 | ], |
|
|||
329 | "owner": "owner-name", |
|
309 | "owner": "owner-name", | |
330 | "permissions": [ |
|
310 | "permissions": [ | |
331 | { |
|
311 | { | |
@@ -533,9 +513,6 b' get_repo_settings' | |||||
533 | "hooks_outgoing_pull_logger": true, |
|
513 | "hooks_outgoing_pull_logger": true, | |
534 | "phases_publish": "True", |
|
514 | "phases_publish": "True", | |
535 | "rhodecode_hg_use_rebase_for_merging": true, |
|
515 | "rhodecode_hg_use_rebase_for_merging": true, | |
536 | "rhodecode_hg_close_branch_before_merging": false, |
|
|||
537 | "rhodecode_git_use_rebase_for_merging": true, |
|
|||
538 | "rhodecode_git_close_branch_before_merging": false, |
|
|||
539 | "rhodecode_pr_merge_enabled": true, |
|
516 | "rhodecode_pr_merge_enabled": true, | |
540 | "rhodecode_use_outdated_comments": true |
|
517 | "rhodecode_use_outdated_comments": true | |
541 | } |
|
518 | } |
@@ -162,7 +162,7 b' get_user_group' | |||||
162 | "active": true, |
|
162 | "active": true, | |
163 | "group_description": "group description", |
|
163 | "group_description": "group description", | |
164 | "group_name": "group name", |
|
164 | "group_name": "group name", | |
165 |
" |
|
165 | "permissions": [ | |
166 | { |
|
166 | { | |
167 | "name": "owner-name", |
|
167 | "name": "owner-name", | |
168 | "origin": "owner", |
|
168 | "origin": "owner", | |
@@ -183,6 +183,12 b' get_user_group' | |||||
183 | "type": "user_group" |
|
183 | "type": "user_group" | |
184 | } |
|
184 | } | |
185 | ], |
|
185 | ], | |
|
186 | "permissions_summary": { | |||
|
187 | "repositories": { | |||
|
188 | "aa-root-level-repo-1": "repository.admin" | |||
|
189 | }, | |||
|
190 | "repositories_groups": {} | |||
|
191 | }, | |||
186 | "owner": "owner name", |
|
192 | "owner": "owner name", | |
187 | "users": [], |
|
193 | "users": [], | |
188 | "users_group_id": 2 |
|
194 | "users_group_id": 2 |
@@ -160,7 +160,8 b' get_user' | |||||
160 | "last_login": "Timestamp", |
|
160 | "last_login": "Timestamp", | |
161 | "last_activity": "Timestamp", |
|
161 | "last_activity": "Timestamp", | |
162 | "lastname": "surnae", |
|
162 | "lastname": "surnae", | |
163 |
"permissions": |
|
163 | "permissions": <deprecated>, | |
|
164 | "permissions_summary": { | |||
164 | "global": [ |
|
165 | "global": [ | |
165 | "hg.inherit_default_perms.true", |
|
166 | "hg.inherit_default_perms.true", | |
166 | "usergroup.read", |
|
167 | "usergroup.read", | |
@@ -178,7 +179,7 b' get_user' | |||||
178 | "repositories": { "username/example": "repository.write"}, |
|
179 | "repositories": { "username/example": "repository.write"}, | |
179 | "repositories_groups": { "user-group/repo": "group.none" }, |
|
180 | "repositories_groups": { "user-group/repo": "group.none" }, | |
180 | "user_groups": { "user_group_name": "usergroup.read" } |
|
181 | "user_groups": { "user_group_name": "usergroup.read" } | |
181 |
} |
|
182 | } | |
182 | "user_id": 32, |
|
183 | "user_id": 32, | |
183 | "username": "username" |
|
184 | "username": "username" | |
184 | } |
|
185 | } |
@@ -64,7 +64,7 b' 2. Enable the SSH module on instance.' | |||||
64 | ssh.wrapper_cmd_allow_shell = false |
|
64 | ssh.wrapper_cmd_allow_shell = false | |
65 |
|
65 | |||
66 | ## Enables logging, and detailed output send back to the client during SSH |
|
66 | ## Enables logging, and detailed output send back to the client during SSH | |
67 |
## operations. Useful |
|
67 | ## operations. Useful for debugging, shouldn't be used in production. | |
68 | ssh.enable_debug_logging = false |
|
68 | ssh.enable_debug_logging = false | |
69 |
|
69 | |||
70 | ## Paths to binary executable, by default they are the names, but we can |
|
70 | ## Paths to binary executable, by default they are the names, but we can | |
@@ -111,20 +111,22 b' 4. Add the public key to your user accou' | |||||
111 | Then add, remove your SSH key and try connecting again. |
|
111 | Then add, remove your SSH key and try connecting again. | |
112 | Debug logging will be printed to help find the problems on the server side. |
|
112 | Debug logging will be printed to help find the problems on the server side. | |
113 |
|
113 | |||
114 | Test connection using the ssh command from the local machine |
|
114 | Test connection using the ssh command from the local machine. Make sure | |
|
115 | to use the use who is running the |RCE| server, and not your username from | |||
|
116 | the web interface. | |||
115 |
|
117 | |||
116 |
|
118 | |||
117 | For SVN: |
|
119 | For SVN: | |
118 |
|
120 | |||
119 | .. code-block:: bash |
|
121 | .. code-block:: bash | |
120 |
|
122 | |||
121 | SVN_SSH="ssh -i ~/.ssh/id_rsa_test_ssh" svn checkout svn+ssh://rhodecode@rc-server/repo_name |
|
123 | SVN_SSH="ssh -i ~/.ssh/id_rsa_test_ssh_private.key" svn checkout svn+ssh://rhodecode@rc-server/repo_name | |
122 |
|
124 | |||
123 | For GIT: |
|
125 | For GIT: | |
124 |
|
126 | |||
125 | .. code-block:: bash |
|
127 | .. code-block:: bash | |
126 |
|
128 | |||
127 | GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa_test_ssh' git clone ssh://rhodecode@rc-server/repo_name |
|
129 | GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa_test_ssh_private.key' git clone ssh://rhodecode@rc-server/repo_name | |
128 |
|
130 | |||
129 | For Mercurial: |
|
131 | For Mercurial: | |
130 |
|
132 | |||
@@ -133,6 +135,6 b' 4. Add the public key to your user accou' | |||||
133 | Add to hgrc: |
|
135 | Add to hgrc: | |
134 |
|
136 | |||
135 | [ui] |
|
137 | [ui] | |
136 | ssh = ssh -C -i ~/.ssh/id_rsa_test_ssh |
|
138 | ssh = ssh -C -i ~/.ssh/id_rsa_test_ssh_private.key | |
137 |
|
139 | |||
138 | hg clone ssh://rhodecode@rc-server/repo_name |
|
140 | hg clone ssh://rhodecode@rc-server/repo_name |
@@ -11,128 +11,253 b' let' | |||||
11 | python = pkgs.python27Packages.python; |
|
11 | python = pkgs.python27Packages.python; | |
12 |
|
12 | |||
13 | Jinja2 = buildPythonPackage rec { |
|
13 | Jinja2 = buildPythonPackage rec { | |
14 |
name = "Jinja2-2. |
|
14 | name = "Jinja2-2.9.6"; | |
|
15 | buildInputs = []; | |||
|
16 | doCheck = false; | |||
|
17 | propagatedBuildInputs = [MarkupSafe]; | |||
15 | src = fetchurl { |
|
18 | src = fetchurl { | |
16 | url = "http://pypi.python.org/packages/source/J/Jinja2/${name}.tar.gz"; |
|
19 | url = "https://pypi.python.org/packages/90/61/f820ff0076a2599dd39406dcb858ecb239438c02ce706c8e91131ab9c7f1/Jinja2-2.9.6.tar.gz"; | |
17 | md5 = "b9dffd2f3b43d673802fe857c8445b1a"; |
|
20 | md5 = "6411537324b4dba0956aaa8109f3c77b"; | |
18 | }; |
|
21 | }; | |
19 | propagatedBuildInputs = [ MarkupSafe ]; |
|
|||
20 | }; |
|
22 | }; | |
21 |
|
23 | |||
22 | MarkupSafe = buildPythonPackage rec { |
|
24 | MarkupSafe = buildPythonPackage rec { | |
23 |
name = "MarkupSafe-0 |
|
25 | name = "MarkupSafe-1.0"; | |
|
26 | buildInputs = []; | |||
|
27 | doCheck = false; | |||
|
28 | propagatedBuildInputs = []; | |||
24 | src = fetchurl { |
|
29 | src = fetchurl { | |
25 |
url = "https://pypi.python.org/packages/ |
|
30 | url = "https://pypi.python.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz"; | |
26 | md5 = "f5ab3deee4c37cd6a922fb81e730da6e"; |
|
31 | md5 = "2fcedc9284d50e577b5192e8e3578355"; | |
27 | }; |
|
32 | }; | |
28 | }; |
|
33 | }; | |
29 |
|
34 | |||
30 |
Pygments = buildPythonPackage |
|
35 | Pygments = buildPythonPackage { | |
31 |
name = "Pygments-2. |
|
36 | name = "Pygments-2.2.0"; | |
|
37 | buildInputs = []; | |||
32 | doCheck = false; |
|
38 | doCheck = false; | |
|
39 | propagatedBuildInputs = []; | |||
33 | src = fetchurl { |
|
40 | src = fetchurl { | |
34 |
url = "https://pypi.python.org/packages/ |
|
41 | url = "https://pypi.python.org/packages/71/2a/2e4e77803a8bd6408a2903340ac498cb0a2181811af7c9ec92cb70b0308a/Pygments-2.2.0.tar.gz"; | |
35 | md5 = "ed3fba2467c8afcda4d317e4ef2c6150"; |
|
42 | md5 = "13037baca42f16917cbd5ad2fab50844"; | |
36 | }; |
|
|||
37 | }; |
|
|||
38 |
|
||||
39 | alabaster = buildPythonPackage rec { |
|
|||
40 | name = "alabaster-0.7.3"; |
|
|||
41 | src = fetchurl { |
|
|||
42 | url = "https://pypi.python.org/packages/source/a/alabaster/${name}.tar.gz"; |
|
|||
43 | md5 = "67428d1383fd833f1282fed5deba0898"; |
|
|||
44 | }; |
|
43 | }; | |
45 | }; |
|
44 | }; | |
46 |
|
45 | |||
47 |
|
|
46 | Sphinx = buildPythonPackage (rec { | |
48 |
name = " |
|
47 | name = "Sphinx-1.6.5"; | |
49 | src = fetchurl { |
|
48 | src = fetchurl { | |
50 | url = "https://pypi.python.org/packages/source/s/six/${name}.tar.gz"; |
|
49 | url = "https://pypi.python.org/packages/8b/7e/b188d9a3b9c938e736e02a74c1363c2888e095d770df2c72b4c312f9fdcb/Sphinx-1.6.5.tar.gz"; | |
51 | md5 = "476881ef4012262dfc8adc645ee786c4"; |
|
50 | md5 = "cd73118c21ec610432e63e6421ec54f1"; | |
|
51 | }; | |||
|
52 | propagatedBuildInputs = [ | |||
|
53 | six | |||
|
54 | Jinja2 | |||
|
55 | Pygments | |||
|
56 | docutils | |||
|
57 | snowballstemmer | |||
|
58 | babel | |||
|
59 | alabaster | |||
|
60 | imagesize | |||
|
61 | requests | |||
|
62 | setuptools | |||
|
63 | sphinxcontrib-websupport | |||
|
64 | typing | |||
|
65 | ||||
|
66 | # special cases | |||
|
67 | pytz | |||
|
68 | sphinx_rtd_theme | |||
|
69 | ||||
|
70 | ]; | |||
|
71 | }); | |||
|
72 | ||||
|
73 | alabaster = buildPythonPackage rec { | |||
|
74 | name = "alabaster-0.7.10"; | |||
|
75 | buildInputs = []; | |||
|
76 | doCheck = false; | |||
|
77 | propagatedBuildInputs = []; | |||
|
78 | src = fetchurl { | |||
|
79 | url = "https://pypi.python.org/packages/d0/a5/e3a9ad3ee86aceeff71908ae562580643b955ea1b1d4f08ed6f7e8396bd7/alabaster-0.7.10.tar.gz"; | |||
|
80 | md5 = "7934dccf38801faa105f6e7b4784f493"; | |||
52 | }; |
|
81 | }; | |
53 | }; |
|
82 | }; | |
54 |
|
83 | |||
55 |
|
|
84 | babel = buildPythonPackage { | |
56 |
name = " |
|
85 | name = "babel-2.5.1"; | |
|
86 | buildInputs = []; | |||
|
87 | doCheck = false; | |||
|
88 | propagatedBuildInputs = [pytz]; | |||
57 | src = fetchurl { |
|
89 | src = fetchurl { | |
58 | url = "https://pypi.python.org/packages/source/s/snowballstemmer/${name}.tar.gz"; |
|
90 | url = "https://pypi.python.org/packages/5a/22/63f1dbb8514bb7e0d0c8a85cc9b14506599a075e231985f98afd70430e1f/Babel-2.5.1.tar.gz"; | |
59 | md5 = "51f2ef829db8129dd0f2354f0b209970"; |
|
91 | md5 = "60228b3ce93a203357158b909afe8ae1"; | |
60 | }; |
|
92 | }; | |
61 | }; |
|
93 | }; | |
62 |
|
94 | |||
63 |
|
|
95 | certifi = buildPythonPackage { | |
64 |
name = " |
|
96 | name = "certifi-2017.11.5"; | |
|
97 | buildInputs = []; | |||
|
98 | doCheck = false; | |||
|
99 | propagatedBuildInputs = []; | |||
65 | src = fetchurl { |
|
100 | src = fetchurl { | |
66 | url = "https://pypi.python.org/packages/source/p/pytz/${name}.tar.gz"; |
|
101 | url = "https://pypi.python.org/packages/23/3f/8be01c50ed24a4bd6b8da799839066ce0288f66f5e11f0367323467f0cbc/certifi-2017.11.5.tar.gz"; | |
67 | md5 = "08440d994cfbbf13d3343362cc3173f7"; |
|
102 | md5 = "c15ac46ed1fe4b607ff3405928f9a992"; | |
|
103 | }; | |||
|
104 | }; | |||
|
105 | ||||
|
106 | chardet = buildPythonPackage { | |||
|
107 | name = "chardet-3.0.4"; | |||
|
108 | buildInputs = []; | |||
|
109 | doCheck = false; | |||
|
110 | propagatedBuildInputs = []; | |||
|
111 | src = fetchurl { | |||
|
112 | url = "https://pypi.python.org/packages/fc/bb/a5768c230f9ddb03acc9ef3f0d4a3cf93462473795d18e9535498c8f929d/chardet-3.0.4.tar.gz"; | |||
|
113 | md5 = "7dd1ba7f9c77e32351b0a0cfacf4055c"; | |||
68 | }; |
|
114 | }; | |
69 | }; |
|
115 | }; | |
70 |
|
116 | |||
71 |
|
|
117 | docutils = buildPythonPackage { | |
72 |
name = " |
|
118 | name = "docutils-0.14"; | |
|
119 | buildInputs = []; | |||
|
120 | doCheck = false; | |||
|
121 | propagatedBuildInputs = []; | |||
73 | src = fetchurl { |
|
122 | src = fetchurl { | |
74 | url = "https://pypi.python.org/packages/source/B/Babel/${name}.tar.gz"; |
|
123 | url = "https://pypi.python.org/packages/84/f4/5771e41fdf52aabebbadecc9381d11dea0fa34e4759b4071244fa094804c/docutils-0.14.tar.gz"; | |
75 | md5 = "5264ceb02717843cbc9ffce8e6e06bdb"; |
|
124 | md5 = "c53768d63db3873b7d452833553469de"; | |
76 | }; |
|
125 | }; | |
77 | propagatedBuildInputs = [ |
|
|||
78 | pytz |
|
|||
79 | ]; |
|
|||
80 | }; |
|
126 | }; | |
81 |
|
127 | |||
82 |
i |
|
128 | idna = buildPythonPackage { | |
|
129 | name = "idna-2.6"; | |||
|
130 | buildInputs = []; | |||
|
131 | doCheck = false; | |||
|
132 | propagatedBuildInputs = []; | |||
|
133 | src = fetchurl { | |||
|
134 | url = "https://pypi.python.org/packages/f4/bd/0467d62790828c23c47fc1dfa1b1f052b24efdf5290f071c7a91d0d82fd3/idna-2.6.tar.gz"; | |||
|
135 | md5 = "c706e2790b016bd0ed4edd2d4ba4d147"; | |||
|
136 | }; | |||
|
137 | }; | |||
|
138 | ||||
|
139 | imagesize = buildPythonPackage { | |||
83 | name = "imagesize-0.7.1"; |
|
140 | name = "imagesize-0.7.1"; | |
|
141 | buildInputs = []; | |||
|
142 | doCheck = false; | |||
|
143 | propagatedBuildInputs = []; | |||
84 | src = fetchurl { |
|
144 | src = fetchurl { | |
85 |
url = "https://pypi.python.org/packages/53/72/6c6f1e787d9cab2cc733cf042f125abec07209a58308831c9f292504e826/ |
|
145 | url = "https://pypi.python.org/packages/53/72/6c6f1e787d9cab2cc733cf042f125abec07209a58308831c9f292504e826/imagesize-0.7.1.tar.gz"; | |
86 | md5 = "976148283286a6ba5f69b0f81aef8052"; |
|
146 | md5 = "976148283286a6ba5f69b0f81aef8052"; | |
87 | }; |
|
147 | }; | |
88 | }; |
|
148 | }; | |
89 |
|
149 | |||
90 |
|
|
150 | pytz = buildPythonPackage { | |
91 |
name = " |
|
151 | name = "pytz-2017.3"; | |
|
152 | buildInputs = []; | |||
|
153 | doCheck = false; | |||
|
154 | propagatedBuildInputs = []; | |||
92 | src = fetchurl { |
|
155 | src = fetchurl { | |
93 | url = "https://pypi.python.org/packages/1f/f6/e54a7aad73e35232356103771ae76306dadd8546b024c646fbe75135571c/${name}.tar.gz"; |
|
156 | url = "https://pypi.python.org/packages/60/88/d3152c234da4b2a1f7a989f89609ea488225eaea015bc16fbde2b3fdfefa/pytz-2017.3.zip"; | |
94 | md5 = "5ec718a4855917e149498bba91b74e67"; |
|
157 | md5 = "7006b56c0d68a162d9fe57d4249c3171"; | |
|
158 | }; | |||
|
159 | }; | |||
|
160 | ||||
|
161 | requests = buildPythonPackage { | |||
|
162 | name = "requests-2.18.4"; | |||
|
163 | buildInputs = []; | |||
|
164 | doCheck = false; | |||
|
165 | propagatedBuildInputs = [chardet idna urllib3 certifi]; | |||
|
166 | src = fetchurl { | |||
|
167 | url = "https://pypi.python.org/packages/b0/e1/eab4fc3752e3d240468a8c0b284607899d2fbfb236a56b7377a329aa8d09/requests-2.18.4.tar.gz"; | |||
|
168 | md5 = "081412b2ef79bdc48229891af13f4d82"; | |||
95 | }; |
|
169 | }; | |
96 | propagatedBuildInputs = [ |
|
170 | }; | |
97 | docutils |
|
171 | ||
98 | Jinja2 |
|
172 | setuptools = buildPythonPackage { | |
99 | Pygments |
|
173 | name = "setuptools-36.6.0"; | |
100 | alabaster |
|
174 | buildInputs = []; | |
101 | six |
|
175 | doCheck = false; | |
102 | snowballstemmer |
|
176 | propagatedBuildInputs = []; | |
103 | pytz |
|
177 | src = fetchurl { | |
104 | babel |
|
178 | url = "https://pypi.python.org/packages/45/29/8814bf414e7cd1031e1a3c8a4169218376e284ea2553cc0822a6ea1c2d78/setuptools-36.6.0.zip"; | |
105 | imagesize |
|
179 | md5 = "74663b15117d9a2cc5295d76011e6fd1"; | |
|
180 | }; | |||
|
181 | }; | |||
106 |
|
182 | |||
107 | # TODO: johbo: Had to include it here so that can be imported |
|
183 | six = buildPythonPackage { | |
108 | sphinx_rtd_theme |
|
184 | name = "six-1.11.0"; | |
109 | ]; |
|
185 | buildInputs = []; | |
110 | }); |
|
186 | doCheck = false; | |
|
187 | propagatedBuildInputs = []; | |||
|
188 | src = fetchurl { | |||
|
189 | url = "https://pypi.python.org/packages/16/d8/bc6316cf98419719bd59c91742194c111b6f2e85abac88e496adefaf7afe/six-1.11.0.tar.gz"; | |||
|
190 | md5 = "d12789f9baf7e9fb2524c0c64f1773f8"; | |||
|
191 | }; | |||
|
192 | }; | |||
111 |
|
193 | |||
112 |
|
|
194 | snowballstemmer = buildPythonPackage { | |
113 |
name = " |
|
195 | name = "snowballstemmer-1.2.1"; | |
|
196 | buildInputs = []; | |||
|
197 | doCheck = false; | |||
|
198 | propagatedBuildInputs = []; | |||
114 | src = fetchurl { |
|
199 | src = fetchurl { | |
115 | url = "https://pypi.python.org/packages/source/d/docutils/${name}.tar.gz"; |
|
200 | url = "https://pypi.python.org/packages/20/6b/d2a7cb176d4d664d94a6debf52cd8dbae1f7203c8e42426daa077051d59c/snowballstemmer-1.2.1.tar.gz"; | |
116 | md5 = "4622263b62c5c771c03502afa3157768"; |
|
201 | md5 = "643b019667a708a922172e33a99bf2fa"; | |
117 | }; |
|
202 | }; | |
118 | }; |
|
203 | }; | |
119 |
|
204 | |||
120 |
sphinx |
|
205 | sphinx-rtd-theme = buildPythonPackage { | |
121 |
name = "sphinx |
|
206 | name = "sphinx-rtd-theme-0.2.5b1"; | |
|
207 | buildInputs = []; | |||
|
208 | doCheck = false; | |||
|
209 | propagatedBuildInputs = []; | |||
|
210 | src = fetchurl { | |||
|
211 | url = "https://pypi.python.org/packages/59/e4/9e3a74a3271e6734911d3f549e8439db53b8ac29adf10c8f698e6c86246b/sphinx_rtd_theme-0.2.5b1.tar.gz"; | |||
|
212 | md5 = "0923473a43bd2527f32151f195f2a521"; | |||
|
213 | }; | |||
|
214 | }; | |||
|
215 | ||||
|
216 | sphinxcontrib-websupport = buildPythonPackage { | |||
|
217 | name = "sphinxcontrib-websupport-1.0.1"; | |||
|
218 | buildInputs = []; | |||
|
219 | doCheck = false; | |||
|
220 | propagatedBuildInputs = []; | |||
122 | src = fetchurl { |
|
221 | src = fetchurl { | |
123 | url = "https://pypi.python.org/packages/source/s/sphinx_rtd_theme/${name}.tar.gz"; |
|
222 | url = "https://pypi.python.org/packages/c5/6b/f0630436b931ad4f8331a9399ca18a7d447f0fcc0c7178fb56b1aee68d01/sphinxcontrib-websupport-1.0.1.tar.gz"; | |
124 | md5 = "86a25c8d47147c872e42dc84cc66f97b"; |
|
223 | md5 = "84df26463b1ba65b07f926dbe2055665"; | |
|
224 | }; | |||
|
225 | }; | |||
|
226 | ||||
|
227 | typing = buildPythonPackage { | |||
|
228 | name = "typing-3.6.2"; | |||
|
229 | buildInputs = []; | |||
|
230 | doCheck = false; | |||
|
231 | propagatedBuildInputs = []; | |||
|
232 | src = fetchurl { | |||
|
233 | url = "https://pypi.python.org/packages/ca/38/16ba8d542e609997fdcd0214628421c971f8c395084085354b11ff4ac9c3/typing-3.6.2.tar.gz"; | |||
|
234 | md5 = "143af0bf3afd1887622771f2f1ffe8e1"; | |||
|
235 | }; | |||
|
236 | }; | |||
|
237 | ||||
|
238 | urllib3 = buildPythonPackage { | |||
|
239 | name = "urllib3-1.22"; | |||
|
240 | buildInputs = []; | |||
|
241 | doCheck = false; | |||
|
242 | propagatedBuildInputs = []; | |||
|
243 | src = fetchurl { | |||
|
244 | url = "https://pypi.python.org/packages/ee/11/7c59620aceedcc1ef65e156cc5ce5a24ef87be4107c2b74458464e437a5d/urllib3-1.22.tar.gz"; | |||
|
245 | md5 = "0da7bed3fe94bf7dc59ae37885cc72f7"; | |||
|
246 | }; | |||
|
247 | }; | |||
|
248 | ||||
|
249 | ||||
|
250 | sphinx_rtd_theme = buildPythonPackage rec { | |||
|
251 | name = "sphinx-rtd-theme-0.2.5b1"; | |||
|
252 | buildInputs = []; | |||
|
253 | doCheck = false; | |||
|
254 | propagatedBuildInputs = []; | |||
|
255 | src = fetchurl { | |||
|
256 | url = "https://pypi.python.org/packages/59/e4/9e3a74a3271e6734911d3f549e8439db53b8ac29adf10c8f698e6c86246b/sphinx_rtd_theme-0.2.5b1.tar.gz"; | |||
|
257 | md5 = "0923473a43bd2527f32151f195f2a521"; | |||
125 | }; |
|
258 | }; | |
126 |
|
259 | |||
127 | # Note: johbo: Sphinx needs this package and this package needs sphinx, |
|
|||
128 | # ignore the requirements file to solve this cycle. |
|
|||
129 | postPatch = '' |
|
|||
130 | rm requirements.txt |
|
|||
131 | touch requirements.txt |
|
|||
132 | ''; |
|
|||
133 |
|
260 | |||
134 | # TODO: johbo: Tests would require sphinx and this creates recursion issues |
|
|||
135 | doCheck = false; |
|
|||
136 | }; |
|
261 | }; | |
137 |
|
262 | |||
138 | in python.buildEnv.override { |
|
263 | in python.buildEnv.override { |
@@ -9,6 +9,7 b' Release Notes' | |||||
9 | .. toctree:: |
|
9 | .. toctree:: | |
10 | :maxdepth: 1 |
|
10 | :maxdepth: 1 | |
11 |
|
11 | |||
|
12 | release-notes-4.11.0.rst | |||
12 | release-notes-4.10.6.rst |
|
13 | release-notes-4.10.6.rst | |
13 | release-notes-4.10.5.rst |
|
14 | release-notes-4.10.5.rst | |
14 | release-notes-4.10.4.rst |
|
15 | release-notes-4.10.4.rst |
@@ -42,6 +42,8 b'' | |||||
42 | "<%= dirs.js.src %>/bootstrap.js", |
|
42 | "<%= dirs.js.src %>/bootstrap.js", | |
43 | "<%= dirs.js.src %>/i18n_utils.js", |
|
43 | "<%= dirs.js.src %>/i18n_utils.js", | |
44 | "<%= dirs.js.src %>/deform.js", |
|
44 | "<%= dirs.js.src %>/deform.js", | |
|
45 | "<%= dirs.js.src %>/ejs.js", | |||
|
46 | "<%= dirs.js.src %>/ejs_templates/utils.js", | |||
45 | "<%= dirs.js.src %>/plugins/jquery.pjax.js", |
|
47 | "<%= dirs.js.src %>/plugins/jquery.pjax.js", | |
46 | "<%= dirs.js.src %>/plugins/jquery.dataTables.js", |
|
48 | "<%= dirs.js.src %>/plugins/jquery.dataTables.js", | |
47 | "<%= dirs.js.src %>/plugins/flavoured_checkbox.js", |
|
49 | "<%= dirs.js.src %>/plugins/flavoured_checkbox.js", |
@@ -7,7 +7,7 b' buildEnv { name = "bower-env"; ignoreCol' | |||||
7 | (fetchbower "paper-tooltip" "PolymerElements/paper-tooltip#1.1.3" "PolymerElements/paper-tooltip#^1.1.2" "0vmrm1n8k9sk9nvqy03q177axy22pia6i3j1gxbk72j3pqiqvg6k") |
|
7 | (fetchbower "paper-tooltip" "PolymerElements/paper-tooltip#1.1.3" "PolymerElements/paper-tooltip#^1.1.2" "0vmrm1n8k9sk9nvqy03q177axy22pia6i3j1gxbk72j3pqiqvg6k") | |
8 | (fetchbower "paper-toast" "PolymerElements/paper-toast#1.3.0" "PolymerElements/paper-toast#^1.3.0" "0x9rqxsks5455s8pk4aikpp99ijdn6kxr9gvhwh99nbcqdzcxq1m") |
|
8 | (fetchbower "paper-toast" "PolymerElements/paper-toast#1.3.0" "PolymerElements/paper-toast#^1.3.0" "0x9rqxsks5455s8pk4aikpp99ijdn6kxr9gvhwh99nbcqdzcxq1m") | |
9 | (fetchbower "paper-toggle-button" "PolymerElements/paper-toggle-button#1.2.0" "PolymerElements/paper-toggle-button#^1.2.0" "0mphcng3ngspbpg4jjn0mb91nvr4xc1phq3qswib15h6sfww1b2w") |
|
9 | (fetchbower "paper-toggle-button" "PolymerElements/paper-toggle-button#1.2.0" "PolymerElements/paper-toggle-button#^1.2.0" "0mphcng3ngspbpg4jjn0mb91nvr4xc1phq3qswib15h6sfww1b2w") | |
10 |
(fetchbower "iron-ajax" "PolymerElements/iron-ajax#1.4. |
|
10 | (fetchbower "iron-ajax" "PolymerElements/iron-ajax#1.4.4" "PolymerElements/iron-ajax#^1.4.4" "0jpi7ik3zljw8yh2ccc85r26lcpzmkc2nl1kn6fqdx57zkzk9v5b") | |
11 | (fetchbower "iron-autogrow-textarea" "PolymerElements/iron-autogrow-textarea#1.0.13" "PolymerElements/iron-autogrow-textarea#^1.0.13" "0zwhpl97vii1s8k0lgain8i9dnw29b0mxc5ixdscx9las13n2lqq") |
|
11 | (fetchbower "iron-autogrow-textarea" "PolymerElements/iron-autogrow-textarea#1.0.13" "PolymerElements/iron-autogrow-textarea#^1.0.13" "0zwhpl97vii1s8k0lgain8i9dnw29b0mxc5ixdscx9las13n2lqq") | |
12 | (fetchbower "iron-a11y-keys" "PolymerElements/iron-a11y-keys#1.0.6" "PolymerElements/iron-a11y-keys#^1.0.6" "1xz3mgghfcxixq28sdb654iaxj4nyi1bzcwf77ydkms6fviqs9mv") |
|
12 | (fetchbower "iron-a11y-keys" "PolymerElements/iron-a11y-keys#1.0.6" "PolymerElements/iron-a11y-keys#^1.0.6" "1xz3mgghfcxixq28sdb654iaxj4nyi1bzcwf77ydkms6fviqs9mv") | |
13 | (fetchbower "iron-flex-layout" "PolymerElements/iron-flex-layout#1.3.1" "PolymerElements/iron-flex-layout#^1.0.0" "0nswv3ih3bhflgcd2wjfmddqswzgqxb2xbq65jk9w3rkj26hplbl") |
|
13 | (fetchbower "iron-flex-layout" "PolymerElements/iron-flex-layout#1.3.1" "PolymerElements/iron-flex-layout#^1.0.0" "0nswv3ih3bhflgcd2wjfmddqswzgqxb2xbq65jk9w3rkj26hplbl") |
@@ -31,6 +31,12 b' self: super: {' | |||||
31 | }; |
|
31 | }; | |
32 | }); |
|
32 | }); | |
33 |
|
33 | |||
|
34 | testpath = super.testpath.override (attrs: { | |||
|
35 | meta = { | |||
|
36 | license = [ pkgs.lib.licenses.mit ]; | |||
|
37 | }; | |||
|
38 | }); | |||
|
39 | ||||
34 | gnureadline = super.gnureadline.override (attrs: { |
|
40 | gnureadline = super.gnureadline.override (attrs: { | |
35 | buildInputs = attrs.buildInputs ++ [ |
|
41 | buildInputs = attrs.buildInputs ++ [ | |
36 | pkgs.ncurses |
|
42 | pkgs.ncurses | |
@@ -61,23 +67,6 b' self: super: {' | |||||
61 | ]; |
|
67 | ]; | |
62 | }); |
|
68 | }); | |
63 |
|
69 | |||
64 | celery = super.celery.override (attrs: { |
|
|||
65 | # The current version of kombu needs some patching to work with the |
|
|||
66 | # other libs. Should be removed once we update celery and kombu. |
|
|||
67 | patches = [ |
|
|||
68 | ./patch-celery-dateutil.diff |
|
|||
69 | ]; |
|
|||
70 | }); |
|
|||
71 |
|
||||
72 | kombu = super.kombu.override (attrs: { |
|
|||
73 | # The current version of kombu needs some patching to work with the |
|
|||
74 | # other libs. Should be removed once we update celery and kombu. |
|
|||
75 | patches = [ |
|
|||
76 | ./patch-kombu-py-2-7-11.diff |
|
|||
77 | ./patch-kombu-msgpack.diff |
|
|||
78 | ]; |
|
|||
79 | }); |
|
|||
80 |
|
||||
81 | lxml = super.lxml.override (attrs: { |
|
70 | lxml = super.lxml.override (attrs: { | |
82 | # johbo: On 16.09 we need this to compile on darwin, otherwise compilation |
|
71 | # johbo: On 16.09 we need this to compile on darwin, otherwise compilation | |
83 | # fails on Darwin. |
|
72 | # fails on Darwin. | |
@@ -114,10 +103,6 b' self: super: {' | |||||
114 | }; |
|
103 | }; | |
115 | }); |
|
104 | }); | |
116 |
|
105 | |||
117 | py-gfm = super.py-gfm.override { |
|
|||
118 | name = "py-gfm-0.1.3.rhodecode-upstream1"; |
|
|||
119 | }; |
|
|||
120 |
|
||||
121 | pycurl = super.pycurl.override (attrs: { |
|
106 | pycurl = super.pycurl.override (attrs: { | |
122 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ [ |
|
107 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ [ | |
123 | pkgs.curl |
|
108 | pkgs.curl | |
@@ -133,10 +118,6 b' self: super: {' | |||||
133 | }; |
|
118 | }; | |
134 | }); |
|
119 | }); | |
135 |
|
120 | |||
136 | Pylons = super.Pylons.override (attrs: { |
|
|||
137 | name = "Pylons-1.0.2.rhodecode-patch1"; |
|
|||
138 | }); |
|
|||
139 |
|
||||
140 | pyramid = super.pyramid.override (attrs: { |
|
121 | pyramid = super.pyramid.override (attrs: { | |
141 | postFixup = '' |
|
122 | postFixup = '' | |
142 | wrapPythonPrograms |
|
123 | wrapPythonPrograms | |
@@ -208,12 +189,6 b' self: super: {' | |||||
208 | }; |
|
189 | }; | |
209 | }); |
|
190 | }); | |
210 |
|
191 | |||
211 | amqplib = super.amqplib.override (attrs: { |
|
|||
212 | meta = { |
|
|||
213 | license = pkgs.lib.licenses.lgpl3; |
|
|||
214 | }; |
|
|||
215 | }); |
|
|||
216 |
|
||||
217 | docutils = super.docutils.override (attrs: { |
|
192 | docutils = super.docutils.override (attrs: { | |
218 | meta = { |
|
193 | meta = { | |
219 | license = pkgs.lib.licenses.bsd2; |
|
194 | license = pkgs.lib.licenses.bsd2; |
@@ -68,13 +68,13 b'' | |||||
68 | }; |
|
68 | }; | |
69 | }; |
|
69 | }; | |
70 | Jinja2 = super.buildPythonPackage { |
|
70 | Jinja2 = super.buildPythonPackage { | |
71 |
name = "Jinja2-2. |
|
71 | name = "Jinja2-2.9.6"; | |
72 | buildInputs = with self; []; |
|
72 | buildInputs = with self; []; | |
73 | doCheck = false; |
|
73 | doCheck = false; | |
74 | propagatedBuildInputs = with self; [MarkupSafe]; |
|
74 | propagatedBuildInputs = with self; [MarkupSafe]; | |
75 | src = fetchurl { |
|
75 | src = fetchurl { | |
76 |
url = "https://pypi.python.org/packages/ |
|
76 | url = "https://pypi.python.org/packages/90/61/f820ff0076a2599dd39406dcb858ecb239438c02ce706c8e91131ab9c7f1/Jinja2-2.9.6.tar.gz"; | |
77 | md5 = "b9dffd2f3b43d673802fe857c8445b1a"; |
|
77 | md5 = "6411537324b4dba0956aaa8109f3c77b"; | |
78 | }; |
|
78 | }; | |
79 | meta = { |
|
79 | meta = { | |
80 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
80 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -94,26 +94,26 b'' | |||||
94 | }; |
|
94 | }; | |
95 | }; |
|
95 | }; | |
96 | Markdown = super.buildPythonPackage { |
|
96 | Markdown = super.buildPythonPackage { | |
97 |
name = "Markdown-2.6. |
|
97 | name = "Markdown-2.6.9"; | |
98 | buildInputs = with self; []; |
|
98 | buildInputs = with self; []; | |
99 | doCheck = false; |
|
99 | doCheck = false; | |
100 | propagatedBuildInputs = with self; []; |
|
100 | propagatedBuildInputs = with self; []; | |
101 | src = fetchurl { |
|
101 | src = fetchurl { | |
102 | url = "https://pypi.python.org/packages/1d/25/3f6d2cb31ec42ca5bd3bfbea99b63892b735d76e26f20dd2dcc34ffe4f0d/Markdown-2.6.8.tar.gz"; |
|
102 | url = "https://pypi.python.org/packages/29/82/dfe242bcfd9eec0e7bf93a80a8f8d8515a95b980c44f5c0b45606397a423/Markdown-2.6.9.tar.gz"; | |
103 | md5 = "d9ef057a5bd185f6f536400a31fc5d45"; |
|
103 | md5 = "56547d362a9abcf30955b8950b08b5e3"; | |
104 | }; |
|
104 | }; | |
105 | meta = { |
|
105 | meta = { | |
106 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
106 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
107 | }; |
|
107 | }; | |
108 | }; |
|
108 | }; | |
109 | MarkupSafe = super.buildPythonPackage { |
|
109 | MarkupSafe = super.buildPythonPackage { | |
110 |
name = "MarkupSafe-0 |
|
110 | name = "MarkupSafe-1.0"; | |
111 | buildInputs = with self; []; |
|
111 | buildInputs = with self; []; | |
112 | doCheck = false; |
|
112 | doCheck = false; | |
113 | propagatedBuildInputs = with self; []; |
|
113 | propagatedBuildInputs = with self; []; | |
114 | src = fetchurl { |
|
114 | src = fetchurl { | |
115 |
url = "https://pypi.python.org/packages/ |
|
115 | url = "https://pypi.python.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz"; | |
116 | md5 = "f5ab3deee4c37cd6a922fb81e730da6e"; |
|
116 | md5 = "2fcedc9284d50e577b5192e8e3578355"; | |
117 | }; |
|
117 | }; | |
118 | meta = { |
|
118 | meta = { | |
119 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
119 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -159,13 +159,13 b'' | |||||
159 | }; |
|
159 | }; | |
160 | }; |
|
160 | }; | |
161 | PasteScript = super.buildPythonPackage { |
|
161 | PasteScript = super.buildPythonPackage { | |
162 |
name = "PasteScript- |
|
162 | name = "PasteScript-2.0.2"; | |
163 | buildInputs = with self; []; |
|
163 | buildInputs = with self; []; | |
164 | doCheck = false; |
|
164 | doCheck = false; | |
165 | propagatedBuildInputs = with self; [Paste PasteDeploy]; |
|
165 | propagatedBuildInputs = with self; [Paste PasteDeploy six]; | |
166 | src = fetchurl { |
|
166 | src = fetchurl { | |
167 |
url = "https://pypi.python.org/packages/ |
|
167 | url = "https://pypi.python.org/packages/e5/f0/78e766c3dcc61a4f3a6f71dd8c95168ae9c7a31722b5663d19c1fdf62cb6/PasteScript-2.0.2.tar.gz"; | |
168 | md5 = "4c72d78dcb6bb993f30536842c16af4d"; |
|
168 | md5 = "ccb3045445097192ca71a13b746c77b2"; | |
169 | }; |
|
169 | }; | |
170 | meta = { |
|
170 | meta = { | |
171 | license = [ pkgs.lib.licenses.mit ]; |
|
171 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -184,56 +184,30 b'' | |||||
184 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
184 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
185 | }; |
|
185 | }; | |
186 | }; |
|
186 | }; | |
187 | Pylons = super.buildPythonPackage { |
|
|||
188 | name = "Pylons-1.0.2.dev20171106"; |
|
|||
189 | buildInputs = with self; []; |
|
|||
190 | doCheck = false; |
|
|||
191 | propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; |
|
|||
192 | src = fetchurl { |
|
|||
193 | url = "https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f"; |
|
|||
194 | md5 = "f26633726fa2cd3a340316ee6a5d218f"; |
|
|||
195 | }; |
|
|||
196 | meta = { |
|
|||
197 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
|||
198 | }; |
|
|||
199 | }; |
|
|||
200 | Routes = super.buildPythonPackage { |
|
187 | Routes = super.buildPythonPackage { | |
201 |
name = "Routes- |
|
188 | name = "Routes-2.4.1"; | |
202 | buildInputs = with self; []; |
|
189 | buildInputs = with self; []; | |
203 | doCheck = false; |
|
190 | doCheck = false; | |
204 | propagatedBuildInputs = with self; [repoze.lru]; |
|
191 | propagatedBuildInputs = with self; [six repoze.lru]; | |
205 | src = fetchurl { |
|
192 | src = fetchurl { | |
206 |
url = "https://pypi.python.org/packages/ |
|
193 | url = "https://pypi.python.org/packages/33/38/ea827837e68d9c7dde4cff7ec122a93c319f0effc08ce92a17095576603f/Routes-2.4.1.tar.gz"; | |
207 | md5 = "d527b0ab7dd9172b1275a41f97448783"; |
|
194 | md5 = "c058dff6832941dec47e0d0052548ad8"; | |
208 | }; |
|
|||
209 | meta = { |
|
|||
210 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
|||
211 | }; |
|
|||
212 | }; |
|
|||
213 | SQLAlchemy = super.buildPythonPackage { |
|
|||
214 | name = "SQLAlchemy-1.1.11"; |
|
|||
215 | buildInputs = with self; []; |
|
|||
216 | doCheck = false; |
|
|||
217 | propagatedBuildInputs = with self; []; |
|
|||
218 | src = fetchurl { |
|
|||
219 | url = "https://pypi.python.org/packages/59/f1/28f2205c3175e6bf32300c0f30f9d91dbc9eb910debbff3ffecb88d18528/SQLAlchemy-1.1.11.tar.gz"; |
|
|||
220 | md5 = "3de387eddb4012083a4562928c511e43"; |
|
|||
221 | }; |
|
195 | }; | |
222 | meta = { |
|
196 | meta = { | |
223 | license = [ pkgs.lib.licenses.mit ]; |
|
197 | license = [ pkgs.lib.licenses.mit ]; | |
224 | }; |
|
198 | }; | |
225 | }; |
|
199 | }; | |
226 |
S |
|
200 | SQLAlchemy = super.buildPythonPackage { | |
227 |
name = "S |
|
201 | name = "SQLAlchemy-1.1.15"; | |
228 | buildInputs = with self; []; |
|
202 | buildInputs = with self; []; | |
229 | doCheck = false; |
|
203 | doCheck = false; | |
230 |
propagatedBuildInputs = with self; [ |
|
204 | propagatedBuildInputs = with self; []; | |
231 | src = fetchurl { |
|
205 | src = fetchurl { | |
232 | url = "https://pypi.python.org/packages/0a/50/34017e6efcd372893a416aba14b84a1a149fc7074537b0e9cb6ca7b7abe9/Sphinx-1.2.2.tar.gz"; |
|
206 | url = "https://pypi.python.org/packages/c2/f6/11fcc1ce19a7cb81b1c9377f4e27ce3813265611922e355905e57c44d164/SQLAlchemy-1.1.15.tar.gz"; | |
233 | md5 = "3dc73ccaa8d0bfb2d62fb671b1f7e8a4"; |
|
207 | md5 = "077f9bd3339957f53068b5572a152674"; | |
234 | }; |
|
208 | }; | |
235 | meta = { |
|
209 | meta = { | |
236 |
license = [ pkgs.lib.licenses. |
|
210 | license = [ pkgs.lib.licenses.mit ]; | |
237 | }; |
|
211 | }; | |
238 | }; |
|
212 | }; | |
239 | Tempita = super.buildPythonPackage { |
|
213 | Tempita = super.buildPythonPackage { | |
@@ -315,13 +289,13 b'' | |||||
315 | }; |
|
289 | }; | |
316 | }; |
|
290 | }; | |
317 | WebTest = super.buildPythonPackage { |
|
291 | WebTest = super.buildPythonPackage { | |
318 |
name = "WebTest-2.0.2 |
|
292 | name = "WebTest-2.0.29"; | |
319 | buildInputs = with self; []; |
|
293 | buildInputs = with self; []; | |
320 | doCheck = false; |
|
294 | doCheck = false; | |
321 | propagatedBuildInputs = with self; [six WebOb waitress beautifulsoup4]; |
|
295 | propagatedBuildInputs = with self; [six WebOb waitress beautifulsoup4]; | |
322 | src = fetchurl { |
|
296 | src = fetchurl { | |
323 |
url = "https://pypi.python.org/packages/80 |
|
297 | url = "https://pypi.python.org/packages/94/de/8f94738be649997da99c47b104aa3c3984ecec51a1d8153ed09638253d56/WebTest-2.0.29.tar.gz"; | |
324 | md5 = "54e6515ac71c51b6fc90179483c749ad"; |
|
298 | md5 = "30b4cf0d340b9a5335fac4389e6f84fc"; | |
325 | }; |
|
299 | }; | |
326 | meta = { |
|
300 | meta = { | |
327 | license = [ pkgs.lib.licenses.mit ]; |
|
301 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -341,52 +315,39 b'' | |||||
341 | }; |
|
315 | }; | |
342 | }; |
|
316 | }; | |
343 | alembic = super.buildPythonPackage { |
|
317 | alembic = super.buildPythonPackage { | |
344 |
name = "alembic-0.9. |
|
318 | name = "alembic-0.9.6"; | |
345 | buildInputs = with self; []; |
|
319 | buildInputs = with self; []; | |
346 | doCheck = false; |
|
320 | doCheck = false; | |
347 | propagatedBuildInputs = with self; [SQLAlchemy Mako python-editor python-dateutil]; |
|
321 | propagatedBuildInputs = with self; [SQLAlchemy Mako python-editor python-dateutil]; | |
348 | src = fetchurl { |
|
322 | src = fetchurl { | |
349 | url = "https://pypi.python.org/packages/78/48/b5b26e7218b415f40b60b92c53853d242e5456c0f19f6c66101d98ff5f2a/alembic-0.9.2.tar.gz"; |
|
323 | url = "https://pypi.python.org/packages/bf/b3/b28ea715824f8455635ece3c12f59d5d205f98cc378858e414e3aa6ebdbc/alembic-0.9.6.tar.gz"; | |
350 | md5 = "40daf8bae50969beea40efaaf0839ff4"; |
|
324 | md5 = "fcb096bccc87c8770bd07a04606cb989"; | |
351 | }; |
|
325 | }; | |
352 | meta = { |
|
326 | meta = { | |
353 | license = [ pkgs.lib.licenses.mit ]; |
|
327 | license = [ pkgs.lib.licenses.mit ]; | |
354 | }; |
|
328 | }; | |
355 | }; |
|
329 | }; | |
356 |
amqp |
|
330 | amqp = super.buildPythonPackage { | |
357 |
name = "amqp |
|
331 | name = "amqp-2.2.2"; | |
358 | buildInputs = with self; []; |
|
332 | buildInputs = with self; []; | |
359 | doCheck = false; |
|
333 | doCheck = false; | |
360 | propagatedBuildInputs = with self; []; |
|
334 | propagatedBuildInputs = with self; [vine]; | |
361 | src = fetchurl { |
|
335 | src = fetchurl { | |
362 | url = "https://pypi.python.org/packages/75/b7/8c2429bf8d92354a0118614f9a4d15e53bc69ebedce534284111de5a0102/amqplib-1.0.2.tgz"; |
|
336 | url = "https://pypi.python.org/packages/e0/70/9ab9ccd8247fb7d2adb717e9f6a0ed358c9e1ab2c349048b0352f9e80ee2/amqp-2.2.2.tar.gz"; | |
363 | md5 = "5c92f17fbedd99b2b4a836d4352d1e2f"; |
|
337 | md5 = "0971a3fd2d635ded45c349cfc17106bd"; | |
364 | }; |
|
|||
365 | meta = { |
|
|||
366 | license = [ { fullName = "LGPL"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ]; |
|
|||
367 | }; |
|
|||
368 | }; |
|
|||
369 | anyjson = super.buildPythonPackage { |
|
|||
370 | name = "anyjson-0.3.3"; |
|
|||
371 | buildInputs = with self; []; |
|
|||
372 | doCheck = false; |
|
|||
373 | propagatedBuildInputs = with self; []; |
|
|||
374 | src = fetchurl { |
|
|||
375 | url = "https://pypi.python.org/packages/c3/4d/d4089e1a3dd25b46bebdb55a992b0797cff657b4477bc32ce28038fdecbc/anyjson-0.3.3.tar.gz"; |
|
|||
376 | md5 = "2ea28d6ec311aeeebaf993cb3008b27c"; |
|
|||
377 | }; |
|
338 | }; | |
378 | meta = { |
|
339 | meta = { | |
379 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
340 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
380 | }; |
|
341 | }; | |
381 | }; |
|
342 | }; | |
382 | appenlight-client = super.buildPythonPackage { |
|
343 | appenlight-client = super.buildPythonPackage { | |
383 |
name = "appenlight-client-0.6.2 |
|
344 | name = "appenlight-client-0.6.22"; | |
384 | buildInputs = with self; []; |
|
345 | buildInputs = with self; []; | |
385 | doCheck = false; |
|
346 | doCheck = false; | |
386 | propagatedBuildInputs = with self; [WebOb requests six]; |
|
347 | propagatedBuildInputs = with self; [WebOb requests six]; | |
387 | src = fetchurl { |
|
348 | src = fetchurl { | |
388 |
url = "https://pypi.python.org/packages/ |
|
349 | url = "https://pypi.python.org/packages/73/37/0a64460fa9670b17c061adc433bc8be5079cba21e8b3a92d824adccb12bc/appenlight_client-0.6.22.tar.gz"; | |
389 | md5 = "273999ac854fdaefa8d0fb61965a4ed9"; |
|
350 | md5 = "641afc114a9a3b3af4f75b11c70968ee"; | |
390 | }; |
|
351 | }; | |
391 | meta = { |
|
352 | meta = { | |
392 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
353 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -431,27 +392,40 b'' | |||||
431 | license = [ pkgs.lib.licenses.mit ]; |
|
392 | license = [ pkgs.lib.licenses.mit ]; | |
432 | }; |
|
393 | }; | |
433 | }; |
|
394 | }; | |
|
395 | billiard = super.buildPythonPackage { | |||
|
396 | name = "billiard-3.5.0.3"; | |||
|
397 | buildInputs = with self; []; | |||
|
398 | doCheck = false; | |||
|
399 | propagatedBuildInputs = with self; []; | |||
|
400 | src = fetchurl { | |||
|
401 | url = "https://pypi.python.org/packages/39/ac/f5571210cca2e4f4532e38aaff242f26c8654c5e2436bee966c230647ccc/billiard-3.5.0.3.tar.gz"; | |||
|
402 | md5 = "113ba481e48400adbf6fbbf59a2f8554"; | |||
|
403 | }; | |||
|
404 | meta = { | |||
|
405 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |||
|
406 | }; | |||
|
407 | }; | |||
434 | bleach = super.buildPythonPackage { |
|
408 | bleach = super.buildPythonPackage { | |
435 |
name = "bleach-1. |
|
409 | name = "bleach-2.1.1"; | |
436 | buildInputs = with self; []; |
|
410 | buildInputs = with self; []; | |
437 | doCheck = false; |
|
411 | doCheck = false; | |
438 | propagatedBuildInputs = with self; [six html5lib]; |
|
412 | propagatedBuildInputs = with self; [six html5lib]; | |
439 | src = fetchurl { |
|
413 | src = fetchurl { | |
440 |
url = "https://pypi.python.org/packages/99 |
|
414 | url = "https://pypi.python.org/packages/d4/3f/d517089af35b01bb9bc4eac5ea04bae342b37a5e9abbb27b7c3ce0eae070/bleach-2.1.1.tar.gz"; | |
441 | md5 = "b663300efdf421b3b727b19d7be9c7e7"; |
|
415 | md5 = "7c5dfb1d66ea979b5a465afb12c82ec4"; | |
442 | }; |
|
416 | }; | |
443 | meta = { |
|
417 | meta = { | |
444 | license = [ pkgs.lib.licenses.asl20 ]; |
|
418 | license = [ pkgs.lib.licenses.asl20 ]; | |
445 | }; |
|
419 | }; | |
446 | }; |
|
420 | }; | |
447 | bottle = super.buildPythonPackage { |
|
421 | bottle = super.buildPythonPackage { | |
448 |
name = "bottle-0.12. |
|
422 | name = "bottle-0.12.13"; | |
449 | buildInputs = with self; []; |
|
423 | buildInputs = with self; []; | |
450 | doCheck = false; |
|
424 | doCheck = false; | |
451 | propagatedBuildInputs = with self; []; |
|
425 | propagatedBuildInputs = with self; []; | |
452 | src = fetchurl { |
|
426 | src = fetchurl { | |
453 |
url = "https://pypi.python.org/packages/52 |
|
427 | url = "https://pypi.python.org/packages/bd/99/04dc59ced52a8261ee0f965a8968717a255ea84a36013e527944dbf3468c/bottle-0.12.13.tar.gz"; | |
454 | md5 = "13132c0a8f607bf860810a6ee9064c5b"; |
|
428 | md5 = "d2fe1b48c1d49217e78bf326b1cad437"; | |
455 | }; |
|
429 | }; | |
456 | meta = { |
|
430 | meta = { | |
457 | license = [ pkgs.lib.licenses.mit ]; |
|
431 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -471,13 +445,13 b'' | |||||
471 | }; |
|
445 | }; | |
472 | }; |
|
446 | }; | |
473 | celery = super.buildPythonPackage { |
|
447 | celery = super.buildPythonPackage { | |
474 |
name = "celery- |
|
448 | name = "celery-4.1.0"; | |
475 | buildInputs = with self; []; |
|
449 | buildInputs = with self; []; | |
476 | doCheck = false; |
|
450 | doCheck = false; | |
477 |
propagatedBuildInputs = with self; [pyt |
|
451 | propagatedBuildInputs = with self; [pytz billiard kombu]; | |
478 | src = fetchurl { |
|
452 | src = fetchurl { | |
479 |
url = "https://pypi.python.org/packages/ |
|
453 | url = "https://pypi.python.org/packages/07/65/88a2a45fc80f487872c93121a701a53bbbc3d3d832016876fac84fc8d46a/celery-4.1.0.tar.gz"; | |
480 | md5 = "898bc87e54f278055b561316ba73e222"; |
|
454 | md5 = "db91e1d26936381127f01e150fe3054a"; | |
481 | }; |
|
455 | }; | |
482 | meta = { |
|
456 | meta = { | |
483 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
457 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -497,26 +471,26 b'' | |||||
497 | }; |
|
471 | }; | |
498 | }; |
|
472 | }; | |
499 | click = super.buildPythonPackage { |
|
473 | click = super.buildPythonPackage { | |
500 |
name = "click- |
|
474 | name = "click-6.6"; | |
501 | buildInputs = with self; []; |
|
475 | buildInputs = with self; []; | |
502 | doCheck = false; |
|
476 | doCheck = false; | |
503 | propagatedBuildInputs = with self; []; |
|
477 | propagatedBuildInputs = with self; []; | |
504 | src = fetchurl { |
|
478 | src = fetchurl { | |
505 | url = "https://pypi.python.org/packages/b7/34/a496632c4fb6c1ee76efedf77bb8d28b29363d839953d95095b12defe791/click-5.1.tar.gz"; |
|
479 | url = "https://pypi.python.org/packages/7a/00/c14926d8232b36b08218067bcd5853caefb4737cda3f0a47437151344792/click-6.6.tar.gz"; | |
506 | md5 = "9c5323008cccfe232a8b161fc8196d41"; |
|
480 | md5 = "d0b09582123605220ad6977175f3e51d"; | |
507 | }; |
|
481 | }; | |
508 | meta = { |
|
482 | meta = { | |
509 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
483 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
510 | }; |
|
484 | }; | |
511 | }; |
|
485 | }; | |
512 | colander = super.buildPythonPackage { |
|
486 | colander = super.buildPythonPackage { | |
513 |
name = "colander-1. |
|
487 | name = "colander-1.4"; | |
514 | buildInputs = with self; []; |
|
488 | buildInputs = with self; []; | |
515 | doCheck = false; |
|
489 | doCheck = false; | |
516 | propagatedBuildInputs = with self; [translationstring iso8601]; |
|
490 | propagatedBuildInputs = with self; [translationstring iso8601]; | |
517 | src = fetchurl { |
|
491 | src = fetchurl { | |
518 | url = "https://pypi.python.org/packages/54/a9/9862a561e015b2c7b56404c0b13828a8bdc51e05ab3703bd792cec064487/colander-1.3.3.tar.gz"; |
|
492 | url = "https://pypi.python.org/packages/cc/e2/c4e716ac4a426d8ad4dfe306c34f0018a22275d2420815784005bf771c84/colander-1.4.tar.gz"; | |
519 | md5 = "f5d783768c51d73695f49bbe95778ab4"; |
|
493 | md5 = "cbb8e403c2ba05aeaa419d51fdb93736"; | |
520 | }; |
|
494 | }; | |
521 | meta = { |
|
495 | meta = { | |
522 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
496 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
@@ -588,13 +562,13 b'' | |||||
588 | }; |
|
562 | }; | |
589 | }; |
|
563 | }; | |
590 | decorator = super.buildPythonPackage { |
|
564 | decorator = super.buildPythonPackage { | |
591 |
name = "decorator-4. |
|
565 | name = "decorator-4.1.2"; | |
592 | buildInputs = with self; []; |
|
566 | buildInputs = with self; []; | |
593 | doCheck = false; |
|
567 | doCheck = false; | |
594 | propagatedBuildInputs = with self; []; |
|
568 | propagatedBuildInputs = with self; []; | |
595 | src = fetchurl { |
|
569 | src = fetchurl { | |
596 | url = "https://pypi.python.org/packages/cc/ac/5a16f1fc0506ff72fcc8fd4e858e3a1c231f224ab79bb7c4c9b2094cc570/decorator-4.0.11.tar.gz"; |
|
570 | url = "https://pypi.python.org/packages/bb/e0/f6e41e9091e130bf16d4437dabbac3993908e4d6485ecbc985ef1352db94/decorator-4.1.2.tar.gz"; | |
597 | md5 = "73644c8f0bd4983d1b6a34b49adec0ae"; |
|
571 | md5 = "a0f7f4fe00ae2dde93494d90c192cf8c"; | |
598 | }; |
|
572 | }; | |
599 | meta = { |
|
573 | meta = { | |
600 | license = [ pkgs.lib.licenses.bsdOriginal { fullName = "new BSD License"; } ]; |
|
574 | license = [ pkgs.lib.licenses.bsdOriginal { fullName = "new BSD License"; } ]; | |
@@ -614,13 +588,13 b'' | |||||
614 | }; |
|
588 | }; | |
615 | }; |
|
589 | }; | |
616 | docutils = super.buildPythonPackage { |
|
590 | docutils = super.buildPythonPackage { | |
617 |
name = "docutils-0.1 |
|
591 | name = "docutils-0.14"; | |
618 | buildInputs = with self; []; |
|
592 | buildInputs = with self; []; | |
619 | doCheck = false; |
|
593 | doCheck = false; | |
620 | propagatedBuildInputs = with self; []; |
|
594 | propagatedBuildInputs = with self; []; | |
621 | src = fetchurl { |
|
595 | src = fetchurl { | |
622 |
url = "https://pypi.python.org/packages/ |
|
596 | url = "https://pypi.python.org/packages/84/f4/5771e41fdf52aabebbadecc9381d11dea0fa34e4759b4071244fa094804c/docutils-0.14.tar.gz"; | |
623 | md5 = "ea4a893c633c788be9b8078b6b305d53"; |
|
597 | md5 = "c53768d63db3873b7d452833553469de"; | |
624 | }; |
|
598 | }; | |
625 | meta = { |
|
599 | meta = { | |
626 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.publicDomain pkgs.lib.licenses.gpl1 { fullName = "public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)"; } pkgs.lib.licenses.psfl ]; |
|
600 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.publicDomain pkgs.lib.licenses.gpl1 { fullName = "public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)"; } pkgs.lib.licenses.psfl ]; | |
@@ -783,39 +757,39 b'' | |||||
783 | }; |
|
757 | }; | |
784 | }; |
|
758 | }; | |
785 | gnureadline = super.buildPythonPackage { |
|
759 | gnureadline = super.buildPythonPackage { | |
786 |
name = "gnureadline-6.3. |
|
760 | name = "gnureadline-6.3.8"; | |
787 | buildInputs = with self; []; |
|
761 | buildInputs = with self; []; | |
788 | doCheck = false; |
|
762 | doCheck = false; | |
789 | propagatedBuildInputs = with self; []; |
|
763 | propagatedBuildInputs = with self; []; | |
790 | src = fetchurl { |
|
764 | src = fetchurl { | |
791 | url = "https://pypi.python.org/packages/3a/ee/2c3f568b0a74974791ac590ec742ef6133e2fbd287a074ba72a53fa5e97c/gnureadline-6.3.3.tar.gz"; |
|
765 | url = "https://pypi.python.org/packages/50/64/86085c823cd78f9df9d8e33dce0baa71618016f8860460b82cf6610e1eb3/gnureadline-6.3.8.tar.gz"; | |
792 | md5 = "c4af83c9a3fbeac8f2da9b5a7c60e51c"; |
|
766 | md5 = "ba341f4b907250bd1f47dbc06290604f"; | |
793 | }; |
|
767 | }; | |
794 | meta = { |
|
768 | meta = { | |
795 | license = [ pkgs.lib.licenses.gpl1 ]; |
|
769 | license = [ { fullName = "GNU General Public License v3 (GPLv3)"; } pkgs.lib.licenses.gpl1 ]; | |
796 | }; |
|
770 | }; | |
797 | }; |
|
771 | }; | |
798 | gprof2dot = super.buildPythonPackage { |
|
772 | gprof2dot = super.buildPythonPackage { | |
799 |
name = "gprof2dot-201 |
|
773 | name = "gprof2dot-2017.9.19"; | |
800 | buildInputs = with self; []; |
|
774 | buildInputs = with self; []; | |
801 | doCheck = false; |
|
775 | doCheck = false; | |
802 | propagatedBuildInputs = with self; []; |
|
776 | propagatedBuildInputs = with self; []; | |
803 | src = fetchurl { |
|
777 | src = fetchurl { | |
804 | url = "https://pypi.python.org/packages/a0/e0/73c71baed306f0402a00a94ffc7b2be94ad1296dfcb8b46912655b93154c/gprof2dot-2016.10.13.tar.gz"; |
|
778 | url = "https://pypi.python.org/packages/9d/36/f977122502979f3dfb50704979c9ed70e6b620787942b089bf1af15f5aba/gprof2dot-2017.9.19.tar.gz"; | |
805 | md5 = "0125401f15fd2afe1df686a76c64a4fd"; |
|
779 | md5 = "cda2d552bb0d0b9f16e6824a9aabd225"; | |
806 | }; |
|
780 | }; | |
807 | meta = { |
|
781 | meta = { | |
808 | license = [ { fullName = "LGPL"; } ]; |
|
782 | license = [ { fullName = "GNU Lesser General Public License v3 or later (LGPLv3+)"; } { fullName = "LGPL"; } ]; | |
809 | }; |
|
783 | }; | |
810 | }; |
|
784 | }; | |
811 | graphviz = super.buildPythonPackage { |
|
785 | graphviz = super.buildPythonPackage { | |
812 | name = "graphviz-0.8"; |
|
786 | name = "graphviz-0.8.1"; | |
813 | buildInputs = with self; []; |
|
787 | buildInputs = with self; []; | |
814 | doCheck = false; |
|
788 | doCheck = false; | |
815 | propagatedBuildInputs = with self; []; |
|
789 | propagatedBuildInputs = with self; []; | |
816 | src = fetchurl { |
|
790 | src = fetchurl { | |
817 | url = "https://pypi.python.org/packages/da/84/0e997520323d6b01124eb01c68d5c101814d0aab53083cd62bd75a90f70b/graphviz-0.8.zip"; |
|
791 | url = "https://pypi.python.org/packages/a9/a6/ee6721349489a2da6eedd3dba124f2b5ac15ee1e0a7bd4d3cfdc4fff0327/graphviz-0.8.1.zip"; | |
818 | md5 = "9486a885360a5ee54a81eb2950470c71"; |
|
792 | md5 = "88d8efa88c02a735b3659fe0feaf0b96"; | |
819 | }; |
|
793 | }; | |
820 | meta = { |
|
794 | meta = { | |
821 | license = [ pkgs.lib.licenses.mit ]; |
|
795 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -848,13 +822,13 b'' | |||||
848 | }; |
|
822 | }; | |
849 | }; |
|
823 | }; | |
850 | html5lib = super.buildPythonPackage { |
|
824 | html5lib = super.buildPythonPackage { | |
851 |
name = "html5lib-0 |
|
825 | name = "html5lib-1.0b10"; | |
852 | buildInputs = with self; []; |
|
826 | buildInputs = with self; []; | |
853 | doCheck = false; |
|
827 | doCheck = false; | |
854 | propagatedBuildInputs = with self; [six]; |
|
828 | propagatedBuildInputs = with self; [six webencodings setuptools]; | |
855 | src = fetchurl { |
|
829 | src = fetchurl { | |
856 | url = "https://pypi.python.org/packages/ae/ae/bcb60402c60932b32dfaf19bb53870b29eda2cd17551ba5639219fb5ebf9/html5lib-0.9999999.tar.gz"; |
|
830 | url = "https://pypi.python.org/packages/97/16/982214624095c1420c75f3bd295d9e658794aafb95fc075823de107e0ae4/html5lib-1.0b10.tar.gz"; | |
857 | md5 = "ef43cb05e9e799f25d65d1135838a96f"; |
|
831 | md5 = "5ada1243b7a863624b2f35245b2186e9"; | |
858 | }; |
|
832 | }; | |
859 | meta = { |
|
833 | meta = { | |
860 | license = [ pkgs.lib.licenses.mit ]; |
|
834 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -952,13 +926,13 b'' | |||||
952 | }; |
|
926 | }; | |
953 | }; |
|
927 | }; | |
954 | iso8601 = super.buildPythonPackage { |
|
928 | iso8601 = super.buildPythonPackage { | |
955 |
name = "iso8601-0.1.1 |
|
929 | name = "iso8601-0.1.12"; | |
956 | buildInputs = with self; []; |
|
930 | buildInputs = with self; []; | |
957 | doCheck = false; |
|
931 | doCheck = false; | |
958 | propagatedBuildInputs = with self; []; |
|
932 | propagatedBuildInputs = with self; []; | |
959 | src = fetchurl { |
|
933 | src = fetchurl { | |
960 | url = "https://pypi.python.org/packages/c0/75/c9209ee4d1b5975eb8c2cba4428bde6b61bd55664a98290dd015cdb18e98/iso8601-0.1.11.tar.gz"; |
|
934 | url = "https://pypi.python.org/packages/45/13/3db24895497345fb44c4248c08b16da34a9eb02643cea2754b21b5ed08b0/iso8601-0.1.12.tar.gz"; | |
961 | md5 = "b06d11cd14a64096f907086044f0fe38"; |
|
935 | md5 = "4de940f691c5ea759fb254384c8ddcf6"; | |
962 | }; |
|
936 | }; | |
963 | meta = { |
|
937 | meta = { | |
964 | license = [ pkgs.lib.licenses.mit ]; |
|
938 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1004,26 +978,26 b'' | |||||
1004 | }; |
|
978 | }; | |
1005 | }; |
|
979 | }; | |
1006 | jupyter-core = super.buildPythonPackage { |
|
980 | jupyter-core = super.buildPythonPackage { | |
1007 |
name = "jupyter-core-4. |
|
981 | name = "jupyter-core-4.4.0"; | |
1008 | buildInputs = with self; []; |
|
982 | buildInputs = with self; []; | |
1009 | doCheck = false; |
|
983 | doCheck = false; | |
1010 | propagatedBuildInputs = with self; [traitlets]; |
|
984 | propagatedBuildInputs = with self; [traitlets]; | |
1011 | src = fetchurl { |
|
985 | src = fetchurl { | |
1012 |
url = "https://pypi.python.org/packages/2f |
|
986 | url = "https://pypi.python.org/packages/b6/2d/2804f4de3a95583f65e5dcb4d7c8c7183124882323758996e867f47e72af/jupyter_core-4.4.0.tar.gz"; | |
1013 | md5 = "18819511a809afdeed9a995a9c27bcfb"; |
|
987 | md5 = "7829fc07884ed98459e170f217e2a5ba"; | |
1014 | }; |
|
988 | }; | |
1015 | meta = { |
|
989 | meta = { | |
1016 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
990 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
1017 | }; |
|
991 | }; | |
1018 | }; |
|
992 | }; | |
1019 | kombu = super.buildPythonPackage { |
|
993 | kombu = super.buildPythonPackage { | |
1020 |
name = "kombu-1. |
|
994 | name = "kombu-4.1.0"; | |
1021 | buildInputs = with self; []; |
|
995 | buildInputs = with self; []; | |
1022 | doCheck = false; |
|
996 | doCheck = false; | |
1023 |
propagatedBuildInputs = with self; [ |
|
997 | propagatedBuildInputs = with self; [amqp]; | |
1024 | src = fetchurl { |
|
998 | src = fetchurl { | |
1025 |
url = "https://pypi.python.org/packages/ |
|
999 | url = "https://pypi.python.org/packages/03/5e/1a47d1e543d4943d65330af4e4406049f443878818fb65bfdc651bb93a96/kombu-4.1.0.tar.gz"; | |
1026 | md5 = "50662f3c7e9395b3d0721fb75d100b63"; |
|
1000 | md5 = "2fb2be9fec0e6514231bba23a3779439"; | |
1027 | }; |
|
1001 | }; | |
1028 | meta = { |
|
1002 | meta = { | |
1029 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1003 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1056,13 +1030,13 b'' | |||||
1056 | }; |
|
1030 | }; | |
1057 | }; |
|
1031 | }; | |
1058 | mistune = super.buildPythonPackage { |
|
1032 | mistune = super.buildPythonPackage { | |
1059 |
name = "mistune-0. |
|
1033 | name = "mistune-0.8.3"; | |
1060 | buildInputs = with self; []; |
|
1034 | buildInputs = with self; []; | |
1061 | doCheck = false; |
|
1035 | doCheck = false; | |
1062 | propagatedBuildInputs = with self; []; |
|
1036 | propagatedBuildInputs = with self; []; | |
1063 | src = fetchurl { |
|
1037 | src = fetchurl { | |
1064 |
url = "https://pypi.python.org/packages/ |
|
1038 | url = "https://pypi.python.org/packages/9d/be/e06d4346cc608a01dec6bf770d7d0303a4fd6db588b318ced18f5f257145/mistune-0.8.3.tar.gz"; | |
1065 | md5 = "92d01cb717e9e74429e9bde9d29ac43b"; |
|
1039 | md5 = "a5e4043e93fb8f9082e27f29eeb5e054"; | |
1066 | }; |
|
1040 | }; | |
1067 | meta = { |
|
1041 | meta = { | |
1068 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1042 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1095,52 +1069,39 b'' | |||||
1095 | }; |
|
1069 | }; | |
1096 | }; |
|
1070 | }; | |
1097 | nbconvert = super.buildPythonPackage { |
|
1071 | nbconvert = super.buildPythonPackage { | |
1098 |
name = "nbconvert-5. |
|
1072 | name = "nbconvert-5.3.1"; | |
1099 | buildInputs = with self; []; |
|
1073 | buildInputs = with self; []; | |
1100 | doCheck = false; |
|
1074 | doCheck = false; | |
1101 | propagatedBuildInputs = with self; [mistune Jinja2 Pygments traitlets jupyter-core nbformat entrypoints bleach pandocfilters testpath]; |
|
1075 | propagatedBuildInputs = with self; [mistune Jinja2 Pygments traitlets jupyter-core nbformat entrypoints bleach pandocfilters testpath]; | |
1102 | src = fetchurl { |
|
1076 | src = fetchurl { | |
1103 | url = "https://pypi.python.org/packages/95/58/df1c91f1658ee5df19097f915a1e71c91fc824a708d82d2b2e35f8b80e9a/nbconvert-5.1.1.tar.gz"; |
|
1077 | url = "https://pypi.python.org/packages/b9/a4/d0a0938ad6f5eeb4dea4e73d255c617ef94b0b2849d51194c9bbdb838412/nbconvert-5.3.1.tar.gz"; | |
1104 | md5 = "d0263fb03a44db2f94eea09a608ed813"; |
|
1078 | md5 = "c128d0d93d02f70a85429a383dae96d2"; | |
1105 | }; |
|
1079 | }; | |
1106 | meta = { |
|
1080 | meta = { | |
1107 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1081 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
1108 | }; |
|
1082 | }; | |
1109 | }; |
|
1083 | }; | |
1110 | nbformat = super.buildPythonPackage { |
|
1084 | nbformat = super.buildPythonPackage { | |
1111 |
name = "nbformat-4. |
|
1085 | name = "nbformat-4.4.0"; | |
1112 | buildInputs = with self; []; |
|
1086 | buildInputs = with self; []; | |
1113 | doCheck = false; |
|
1087 | doCheck = false; | |
1114 | propagatedBuildInputs = with self; [ipython-genutils traitlets jsonschema jupyter-core]; |
|
1088 | propagatedBuildInputs = with self; [ipython-genutils traitlets jsonschema jupyter-core]; | |
1115 | src = fetchurl { |
|
1089 | src = fetchurl { | |
1116 |
url = "https://pypi.python.org/packages/ |
|
1090 | url = "https://pypi.python.org/packages/6e/0e/160754f7ae3e984863f585a3743b0ed1702043a81245907c8fae2d537155/nbformat-4.4.0.tar.gz"; | |
1117 | md5 = "9a00d20425914cd5ba5f97769d9963ca"; |
|
1091 | md5 = "2d5f873138d9fbc2a3f9eaaebca3b8a1"; | |
1118 | }; |
|
1092 | }; | |
1119 | meta = { |
|
1093 | meta = { | |
1120 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1094 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
1121 | }; |
|
1095 | }; | |
1122 | }; |
|
1096 | }; | |
1123 | nose = super.buildPythonPackage { |
|
|||
1124 | name = "nose-1.3.6"; |
|
|||
1125 | buildInputs = with self; []; |
|
|||
1126 | doCheck = false; |
|
|||
1127 | propagatedBuildInputs = with self; []; |
|
|||
1128 | src = fetchurl { |
|
|||
1129 | url = "https://pypi.python.org/packages/70/c7/469e68148d17a0d3db5ed49150242fd70a74a8147b8f3f8b87776e028d99/nose-1.3.6.tar.gz"; |
|
|||
1130 | md5 = "0ca546d81ca8309080fc80cb389e7a16"; |
|
|||
1131 | }; |
|
|||
1132 | meta = { |
|
|||
1133 | license = [ { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "GNU LGPL"; } ]; |
|
|||
1134 | }; |
|
|||
1135 | }; |
|
|||
1136 | objgraph = super.buildPythonPackage { |
|
1097 | objgraph = super.buildPythonPackage { | |
1137 |
name = "objgraph-3.1. |
|
1098 | name = "objgraph-3.1.1"; | |
1138 | buildInputs = with self; []; |
|
1099 | buildInputs = with self; []; | |
1139 | doCheck = false; |
|
1100 | doCheck = false; | |
1140 | propagatedBuildInputs = with self; [graphviz]; |
|
1101 | propagatedBuildInputs = with self; [graphviz]; | |
1141 | src = fetchurl { |
|
1102 | src = fetchurl { | |
1142 |
url = "https://pypi.python.org/packages/ |
|
1103 | url = "https://pypi.python.org/packages/be/58/9ca81a20cc837054e94866df1475d899caaa94f3732b8a46006858b015f7/objgraph-3.1.1.tar.gz"; | |
1143 | md5 = "eddbd96039796bfbd13eee403701e64a"; |
|
1104 | md5 = "253af9944763377877c3678d8aaebb8b"; | |
1144 | }; |
|
1105 | }; | |
1145 | meta = { |
|
1106 | meta = { | |
1146 | license = [ pkgs.lib.licenses.mit ]; |
|
1107 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1199,13 +1160,13 b'' | |||||
1199 | }; |
|
1160 | }; | |
1200 | }; |
|
1161 | }; | |
1201 | pexpect = super.buildPythonPackage { |
|
1162 | pexpect = super.buildPythonPackage { | |
1202 |
name = "pexpect-4. |
|
1163 | name = "pexpect-4.3.0"; | |
1203 | buildInputs = with self; []; |
|
1164 | buildInputs = with self; []; | |
1204 | doCheck = false; |
|
1165 | doCheck = false; | |
1205 | propagatedBuildInputs = with self; [ptyprocess]; |
|
1166 | propagatedBuildInputs = with self; [ptyprocess]; | |
1206 | src = fetchurl { |
|
1167 | src = fetchurl { | |
1207 | url = "https://pypi.python.org/packages/e8/13/d0b0599099d6cd23663043a2a0bb7c61e58c6ba359b2656e6fb000ef5b98/pexpect-4.2.1.tar.gz"; |
|
1168 | url = "https://pypi.python.org/packages/f8/44/5466c30e49762bb92e442bbdf4472d6904608d211258eb3198a11f0309a4/pexpect-4.3.0.tar.gz"; | |
1208 | md5 = "3694410001a99dff83f0b500a1ca1c95"; |
|
1169 | md5 = "047a486dcd26134b74f2e67046bb61a0"; | |
1209 | }; |
|
1170 | }; | |
1210 | meta = { |
|
1171 | meta = { | |
1211 | license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ]; |
|
1172 | license = [ pkgs.lib.licenses.isc { fullName = "ISC License (ISCL)"; } ]; | |
@@ -1225,26 +1186,26 b'' | |||||
1225 | }; |
|
1186 | }; | |
1226 | }; |
|
1187 | }; | |
1227 | plaster = super.buildPythonPackage { |
|
1188 | plaster = super.buildPythonPackage { | |
1228 |
name = "plaster-0 |
|
1189 | name = "plaster-1.0"; | |
1229 | buildInputs = with self; []; |
|
1190 | buildInputs = with self; []; | |
1230 | doCheck = false; |
|
1191 | doCheck = false; | |
1231 | propagatedBuildInputs = with self; [setuptools]; |
|
1192 | propagatedBuildInputs = with self; [setuptools]; | |
1232 | src = fetchurl { |
|
1193 | src = fetchurl { | |
1233 | url = "https://pypi.python.org/packages/99/b3/d7ca1fe31d2b56dba68a238721fda6820770f9c2a3de17a582d4b5b2edcc/plaster-0.5.tar.gz"; |
|
1194 | url = "https://pypi.python.org/packages/37/e1/56d04382d718d32751017d32f351214384e529b794084eee20bb52405563/plaster-1.0.tar.gz"; | |
1234 | md5 = "c59345a67a860cfcaa1bd6a81451399d"; |
|
1195 | md5 = "80e6beb4760c16fea31754babcc0576e"; | |
1235 | }; |
|
1196 | }; | |
1236 | meta = { |
|
1197 | meta = { | |
1237 | license = [ pkgs.lib.licenses.mit ]; |
|
1198 | license = [ pkgs.lib.licenses.mit ]; | |
1238 | }; |
|
1199 | }; | |
1239 | }; |
|
1200 | }; | |
1240 | plaster-pastedeploy = super.buildPythonPackage { |
|
1201 | plaster-pastedeploy = super.buildPythonPackage { | |
1241 |
name = "plaster-pastedeploy-0.4. |
|
1202 | name = "plaster-pastedeploy-0.4.2"; | |
1242 | buildInputs = with self; []; |
|
1203 | buildInputs = with self; []; | |
1243 | doCheck = false; |
|
1204 | doCheck = false; | |
1244 | propagatedBuildInputs = with self; [PasteDeploy plaster]; |
|
1205 | propagatedBuildInputs = with self; [PasteDeploy plaster]; | |
1245 | src = fetchurl { |
|
1206 | src = fetchurl { | |
1246 |
url = "https://pypi.python.org/packages/ |
|
1207 | url = "https://pypi.python.org/packages/2c/62/0daf9c0be958e785023e583e51baac15863699e956bfb3d448898d80edd8/plaster_pastedeploy-0.4.2.tar.gz"; | |
1247 | md5 = "f48d5344b922e56c4978eebf1cd2e0d3"; |
|
1208 | md5 = "58fd7852002909378e818c9d5b71e90a"; | |
1248 | }; |
|
1209 | }; | |
1249 | meta = { |
|
1210 | meta = { | |
1250 | license = [ pkgs.lib.licenses.mit ]; |
|
1211 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1264,26 +1225,26 b'' | |||||
1264 | }; |
|
1225 | }; | |
1265 | }; |
|
1226 | }; | |
1266 | psutil = super.buildPythonPackage { |
|
1227 | psutil = super.buildPythonPackage { | |
1267 |
name = "psutil-4. |
|
1228 | name = "psutil-5.4.0"; | |
1268 | buildInputs = with self; []; |
|
1229 | buildInputs = with self; []; | |
1269 | doCheck = false; |
|
1230 | doCheck = false; | |
1270 | propagatedBuildInputs = with self; []; |
|
1231 | propagatedBuildInputs = with self; []; | |
1271 | src = fetchurl { |
|
1232 | src = fetchurl { | |
1272 |
url = "https://pypi.python.org/packages/ |
|
1233 | url = "https://pypi.python.org/packages/8d/96/1fc6468be91521192861966c40bd73fdf8b065eae6d82dd0f870b9825a65/psutil-5.4.0.tar.gz"; | |
1273 | md5 = "199a366dba829c88bddaf5b41d19ddc0"; |
|
1234 | md5 = "01af6219b1e8fcfd53603023967713bf"; | |
1274 | }; |
|
1235 | }; | |
1275 | meta = { |
|
1236 | meta = { | |
1276 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1237 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
1277 | }; |
|
1238 | }; | |
1278 | }; |
|
1239 | }; | |
1279 | psycopg2 = super.buildPythonPackage { |
|
1240 | psycopg2 = super.buildPythonPackage { | |
1280 |
name = "psycopg2-2.7. |
|
1241 | name = "psycopg2-2.7.3.2"; | |
1281 | buildInputs = with self; []; |
|
1242 | buildInputs = with self; []; | |
1282 | doCheck = false; |
|
1243 | doCheck = false; | |
1283 | propagatedBuildInputs = with self; []; |
|
1244 | propagatedBuildInputs = with self; []; | |
1284 | src = fetchurl { |
|
1245 | src = fetchurl { | |
1285 | url = "https://pypi.python.org/packages/f8/e9/5793369ce8a41bf5467623ded8d59a434dfef9c136351aca4e70c2657ba0/psycopg2-2.7.1.tar.gz"; |
|
1246 | url = "https://pypi.python.org/packages/dd/47/000b405d73ca22980684fd7bd3318690cc03cfa3b2ae1c5b7fff8050b28a/psycopg2-2.7.3.2.tar.gz"; | |
1286 | md5 = "67848ac33af88336046802f6ef7081f3"; |
|
1247 | md5 = "8114e672d5f23fa5329874a4314fbd6f"; | |
1287 | }; |
|
1248 | }; | |
1288 | meta = { |
|
1249 | meta = { | |
1289 | license = [ pkgs.lib.licenses.zpt21 { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "LGPL with exceptions or ZPL"; } ]; |
|
1250 | license = [ pkgs.lib.licenses.zpt21 { fullName = "GNU Library or Lesser General Public License (LGPL)"; } { fullName = "LGPL with exceptions or ZPL"; } ]; | |
@@ -1303,13 +1264,13 b'' | |||||
1303 | }; |
|
1264 | }; | |
1304 | }; |
|
1265 | }; | |
1305 | py = super.buildPythonPackage { |
|
1266 | py = super.buildPythonPackage { | |
1306 |
name = "py-1. |
|
1267 | name = "py-1.5.2"; | |
1307 | buildInputs = with self; []; |
|
1268 | buildInputs = with self; []; | |
1308 | doCheck = false; |
|
1269 | doCheck = false; | |
1309 | propagatedBuildInputs = with self; []; |
|
1270 | propagatedBuildInputs = with self; []; | |
1310 | src = fetchurl { |
|
1271 | src = fetchurl { | |
1311 | url = "https://pypi.python.org/packages/68/35/58572278f1c097b403879c1e9369069633d1cbad5239b9057944bb764782/py-1.4.34.tar.gz"; |
|
1272 | url = "https://pypi.python.org/packages/90/e3/e075127d39d35f09a500ebb4a90afd10f9ef0a1d28a6d09abeec0e444fdd/py-1.5.2.tar.gz"; | |
1312 | md5 = "d9c3d8f734b0819ff48e355d77bf1730"; |
|
1273 | md5 = "279ca69c632069e1b71e11b14641ca28"; | |
1313 | }; |
|
1274 | }; | |
1314 | meta = { |
|
1275 | meta = { | |
1315 | license = [ pkgs.lib.licenses.mit ]; |
|
1276 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1334,8 +1295,8 b'' | |||||
1334 | doCheck = false; |
|
1295 | doCheck = false; | |
1335 | propagatedBuildInputs = with self; [setuptools Markdown]; |
|
1296 | propagatedBuildInputs = with self; [setuptools Markdown]; | |
1336 | src = fetchurl { |
|
1297 | src = fetchurl { | |
1337 | url = "https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16"; |
|
1298 | url = "https://pypi.python.org/packages/12/e4/6b3d8678da04f97d7490d8264d8de51c2dc9fb91209ccee9c515c95e14c5/py-gfm-0.1.3.tar.gz"; | |
1338 | md5 = "0d0d5385bfb629eea636a80b9c2bfd16"; |
|
1299 | md5 = "e588d9e69640a241b97e2c59c22527a6"; | |
1339 | }; |
|
1300 | }; | |
1340 | meta = { |
|
1301 | meta = { | |
1341 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1302 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1433,26 +1394,26 b'' | |||||
1433 | }; |
|
1394 | }; | |
1434 | }; |
|
1395 | }; | |
1435 | pyramid-debugtoolbar = super.buildPythonPackage { |
|
1396 | pyramid-debugtoolbar = super.buildPythonPackage { | |
1436 |
name = "pyramid-debugtoolbar-4. |
|
1397 | name = "pyramid-debugtoolbar-4.3"; | |
1437 | buildInputs = with self; []; |
|
1398 | buildInputs = with self; []; | |
1438 | doCheck = false; |
|
1399 | doCheck = false; | |
1439 | propagatedBuildInputs = with self; [pyramid pyramid-mako repoze.lru Pygments ipaddress]; |
|
1400 | propagatedBuildInputs = with self; [pyramid pyramid-mako repoze.lru Pygments ipaddress]; | |
1440 | src = fetchurl { |
|
1401 | src = fetchurl { | |
1441 |
url = "https://pypi.python.org/packages/db |
|
1402 | url = "https://pypi.python.org/packages/a4/40/f09d8800bfc3c09bdb6c95f37bb61c890dc62c19c4e7caa304da7aa77403/pyramid_debugtoolbar-4.3.tar.gz"; | |
1442 | md5 = "3dfaced2fab1644ff5284017be9d92b9"; |
|
1403 | md5 = "9c49029e9f0695130499ef6416ffaaf8"; | |
1443 | }; |
|
1404 | }; | |
1444 | meta = { |
|
1405 | meta = { | |
1445 | license = [ { fullName = "Repoze Public License"; } pkgs.lib.licenses.bsdOriginal ]; |
|
1406 | license = [ { fullName = "Repoze Public License"; } pkgs.lib.licenses.bsdOriginal ]; | |
1446 | }; |
|
1407 | }; | |
1447 | }; |
|
1408 | }; | |
1448 | pyramid-jinja2 = super.buildPythonPackage { |
|
1409 | pyramid-jinja2 = super.buildPythonPackage { | |
1449 |
name = "pyramid-jinja2-2. |
|
1410 | name = "pyramid-jinja2-2.7"; | |
1450 | buildInputs = with self; []; |
|
1411 | buildInputs = with self; []; | |
1451 | doCheck = false; |
|
1412 | doCheck = false; | |
1452 | propagatedBuildInputs = with self; [pyramid zope.deprecation Jinja2 MarkupSafe]; |
|
1413 | propagatedBuildInputs = with self; [pyramid zope.deprecation Jinja2 MarkupSafe]; | |
1453 | src = fetchurl { |
|
1414 | src = fetchurl { | |
1454 |
url = "https://pypi.python.org/packages/ |
|
1415 | url = "https://pypi.python.org/packages/d8/80/d60a7233823de22ce77bd864a8a83736a1fe8b49884b08303a2e68b2c853/pyramid_jinja2-2.7.tar.gz"; | |
1455 | md5 = "07cb6547204ac5e6f0b22a954ccee928"; |
|
1416 | md5 = "c2f8b2cd7b73a6f1d9a311fcfaf4fb92"; | |
1456 | }; |
|
1417 | }; | |
1457 | meta = { |
|
1418 | meta = { | |
1458 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
1419 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
@@ -1485,13 +1446,13 b'' | |||||
1485 | }; |
|
1446 | }; | |
1486 | }; |
|
1447 | }; | |
1487 | pytest = super.buildPythonPackage { |
|
1448 | pytest = super.buildPythonPackage { | |
1488 |
name = "pytest-3. |
|
1449 | name = "pytest-3.2.5"; | |
1489 | buildInputs = with self; []; |
|
1450 | buildInputs = with self; []; | |
1490 | doCheck = false; |
|
1451 | doCheck = false; | |
1491 | propagatedBuildInputs = with self; [py setuptools]; |
|
1452 | propagatedBuildInputs = with self; [py setuptools]; | |
1492 | src = fetchurl { |
|
1453 | src = fetchurl { | |
1493 | url = "https://pypi.python.org/packages/72/2b/2d3155e01f45a5a04427857352ee88220ee39550b2bc078f9db3190aea46/pytest-3.1.2.tar.gz"; |
|
1454 | url = "https://pypi.python.org/packages/1f/f8/8cd74c16952163ce0db0bd95fdd8810cbf093c08be00e6e665ebf0dc3138/pytest-3.2.5.tar.gz"; | |
1494 | md5 = "c4d179f89043cc925e1c169d03128e02"; |
|
1455 | md5 = "6dbe9bb093883f75394a689a1426ac6f"; | |
1495 | }; |
|
1456 | }; | |
1496 | meta = { |
|
1457 | meta = { | |
1497 | license = [ pkgs.lib.licenses.mit ]; |
|
1458 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1524,39 +1485,39 b'' | |||||
1524 | }; |
|
1485 | }; | |
1525 | }; |
|
1486 | }; | |
1526 | pytest-profiling = super.buildPythonPackage { |
|
1487 | pytest-profiling = super.buildPythonPackage { | |
1527 |
name = "pytest-profiling-1.2. |
|
1488 | name = "pytest-profiling-1.2.11"; | |
1528 | buildInputs = with self; []; |
|
1489 | buildInputs = with self; []; | |
1529 | doCheck = false; |
|
1490 | doCheck = false; | |
1530 | propagatedBuildInputs = with self; [six pytest gprof2dot]; |
|
1491 | propagatedBuildInputs = with self; [six pytest gprof2dot]; | |
1531 | src = fetchurl { |
|
1492 | src = fetchurl { | |
1532 | url = "https://pypi.python.org/packages/f9/0d/df67fb9ce16c2cef201693da956321b1bccfbf9a4ead39748b9f9d1d74cb/pytest-profiling-1.2.6.tar.gz"; |
|
1493 | url = "https://pypi.python.org/packages/c0/4a/b4aa786e93c07a86f1f87c581a36bf355a9e06a9da7e00dbd05047626bd2/pytest-profiling-1.2.11.tar.gz"; | |
1533 | md5 = "50eb4c66c3762a2f1a49669bedc0b894"; |
|
1494 | md5 = "9ef6b60248731be5d44477980408e8f7"; | |
1534 | }; |
|
1495 | }; | |
1535 | meta = { |
|
1496 | meta = { | |
1536 | license = [ pkgs.lib.licenses.mit ]; |
|
1497 | license = [ pkgs.lib.licenses.mit ]; | |
1537 | }; |
|
1498 | }; | |
1538 | }; |
|
1499 | }; | |
1539 | pytest-runner = super.buildPythonPackage { |
|
1500 | pytest-runner = super.buildPythonPackage { | |
1540 |
name = "pytest-runner- |
|
1501 | name = "pytest-runner-3.0"; | |
1541 | buildInputs = with self; []; |
|
1502 | buildInputs = with self; []; | |
1542 | doCheck = false; |
|
1503 | doCheck = false; | |
1543 | propagatedBuildInputs = with self; []; |
|
1504 | propagatedBuildInputs = with self; []; | |
1544 | src = fetchurl { |
|
1505 | src = fetchurl { | |
1545 |
url = "https://pypi.python.org/packages/ |
|
1506 | url = "https://pypi.python.org/packages/65/b4/ae89338cd2d81e2cc54bd6db2e962bfe948f612303610d68ab24539ac2d1/pytest-runner-3.0.tar.gz"; | |
1546 | md5 = "bdb73eb18eca2727944a2dcf963c5a81"; |
|
1507 | md5 = "8f8363a52bbabc4cedd5e239beb2ba11"; | |
1547 | }; |
|
1508 | }; | |
1548 | meta = { |
|
1509 | meta = { | |
1549 | license = [ pkgs.lib.licenses.mit ]; |
|
1510 | license = [ pkgs.lib.licenses.mit ]; | |
1550 | }; |
|
1511 | }; | |
1551 | }; |
|
1512 | }; | |
1552 | pytest-sugar = super.buildPythonPackage { |
|
1513 | pytest-sugar = super.buildPythonPackage { | |
1553 |
name = "pytest-sugar-0. |
|
1514 | name = "pytest-sugar-0.9.0"; | |
1554 | buildInputs = with self; []; |
|
1515 | buildInputs = with self; []; | |
1555 | doCheck = false; |
|
1516 | doCheck = false; | |
1556 | propagatedBuildInputs = with self; [pytest termcolor]; |
|
1517 | propagatedBuildInputs = with self; [pytest termcolor]; | |
1557 | src = fetchurl { |
|
1518 | src = fetchurl { | |
1558 |
url = "https://pypi.python.org/packages/a |
|
1519 | url = "https://pypi.python.org/packages/49/d8/c5ff6cca3ce2ebd8b73eec89779bf6b4a7737456a70e8ea4d44c1ff90f71/pytest-sugar-0.9.0.tar.gz"; | |
1559 | md5 = "8cafbdad648068e0e44b8fc5f9faae42"; |
|
1520 | md5 = "89fbff17277fa6a95a560a04b68cb9f9"; | |
1560 | }; |
|
1521 | }; | |
1561 | meta = { |
|
1522 | meta = { | |
1562 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1523 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1576,16 +1537,16 b'' | |||||
1576 | }; |
|
1537 | }; | |
1577 | }; |
|
1538 | }; | |
1578 | python-dateutil = super.buildPythonPackage { |
|
1539 | python-dateutil = super.buildPythonPackage { | |
1579 | name = "python-dateutil-2.1"; |
|
1540 | name = "python-dateutil-2.6.1"; | |
1580 | buildInputs = with self; []; |
|
1541 | buildInputs = with self; []; | |
1581 | doCheck = false; |
|
1542 | doCheck = false; | |
1582 | propagatedBuildInputs = with self; [six]; |
|
1543 | propagatedBuildInputs = with self; [six]; | |
1583 | src = fetchurl { |
|
1544 | src = fetchurl { | |
1584 |
url = "https://pypi.python.org/packages/65 |
|
1545 | url = "https://pypi.python.org/packages/54/bb/f1db86504f7a49e1d9b9301531181b00a1c7325dc85a29160ee3eaa73a54/python-dateutil-2.6.1.tar.gz"; | |
1585 | md5 = "1534bb15cf311f07afaa3aacba1c028b"; |
|
1546 | md5 = "db38f6b4511cefd76014745bb0cc45a4"; | |
1586 | }; |
|
1547 | }; | |
1587 | meta = { |
|
1548 | meta = { | |
1588 | license = [ { fullName = "Simplified BSD"; } ]; |
|
1549 | license = [ pkgs.lib.licenses.bsdOriginal { fullName = "Simplified BSD"; } ]; | |
1589 | }; |
|
1550 | }; | |
1590 | }; |
|
1551 | }; | |
1591 | python-editor = super.buildPythonPackage { |
|
1552 | python-editor = super.buildPythonPackage { | |
@@ -1602,13 +1563,13 b'' | |||||
1602 | }; |
|
1563 | }; | |
1603 | }; |
|
1564 | }; | |
1604 | python-ldap = super.buildPythonPackage { |
|
1565 | python-ldap = super.buildPythonPackage { | |
1605 |
name = "python-ldap-2.4.4 |
|
1566 | name = "python-ldap-2.4.45"; | |
1606 | buildInputs = with self; []; |
|
1567 | buildInputs = with self; []; | |
1607 | doCheck = false; |
|
1568 | doCheck = false; | |
1608 | propagatedBuildInputs = with self; [setuptools]; |
|
1569 | propagatedBuildInputs = with self; [setuptools]; | |
1609 | src = fetchurl { |
|
1570 | src = fetchurl { | |
1610 | url = "https://pypi.python.org/packages/4a/d8/7d70a7469058a3987d224061a81d778951ac2b48220bdcc511e4b1b37176/python-ldap-2.4.40.tar.gz"; |
|
1571 | url = "https://pypi.python.org/packages/ce/52/6b5372d0166820f4a4b0a88ed73dc7504219355049fc1d266d8ccdb7942e/python-ldap-2.4.45.tar.gz"; | |
1611 | md5 = "aea0233f7d39b0c7549fcd310deeb0e5"; |
|
1572 | md5 = "6108e189a44eea8bc7d1cc281c222978"; | |
1612 | }; |
|
1573 | }; | |
1613 | meta = { |
|
1574 | meta = { | |
1614 | license = [ pkgs.lib.licenses.psfl ]; |
|
1575 | license = [ pkgs.lib.licenses.psfl ]; | |
@@ -1641,13 +1602,13 b'' | |||||
1641 | }; |
|
1602 | }; | |
1642 | }; |
|
1603 | }; | |
1643 | pytz = super.buildPythonPackage { |
|
1604 | pytz = super.buildPythonPackage { | |
1644 |
name = "pytz-201 |
|
1605 | name = "pytz-2017.3"; | |
1645 | buildInputs = with self; []; |
|
1606 | buildInputs = with self; []; | |
1646 | doCheck = false; |
|
1607 | doCheck = false; | |
1647 | propagatedBuildInputs = with self; []; |
|
1608 | propagatedBuildInputs = with self; []; | |
1648 | src = fetchurl { |
|
1609 | src = fetchurl { | |
1649 |
url = "https://pypi.python.org/packages/ |
|
1610 | url = "https://pypi.python.org/packages/60/88/d3152c234da4b2a1f7a989f89609ea488225eaea015bc16fbde2b3fdfefa/pytz-2017.3.zip"; | |
1650 | md5 = "233f2a2b370d03f9b5911700cc9ebf3c"; |
|
1611 | md5 = "7006b56c0d68a162d9fe57d4249c3171"; | |
1651 | }; |
|
1612 | }; | |
1652 | meta = { |
|
1613 | meta = { | |
1653 | license = [ pkgs.lib.licenses.mit ]; |
|
1614 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1693,13 +1654,13 b'' | |||||
1693 | }; |
|
1654 | }; | |
1694 | }; |
|
1655 | }; | |
1695 | repoze.lru = super.buildPythonPackage { |
|
1656 | repoze.lru = super.buildPythonPackage { | |
1696 |
name = "repoze.lru-0. |
|
1657 | name = "repoze.lru-0.7"; | |
1697 | buildInputs = with self; []; |
|
1658 | buildInputs = with self; []; | |
1698 | doCheck = false; |
|
1659 | doCheck = false; | |
1699 | propagatedBuildInputs = with self; []; |
|
1660 | propagatedBuildInputs = with self; []; | |
1700 | src = fetchurl { |
|
1661 | src = fetchurl { | |
1701 | url = "https://pypi.python.org/packages/6e/1e/aa15cc90217e086dc8769872c8778b409812ff036bf021b15795638939e4/repoze.lru-0.6.tar.gz"; |
|
1662 | url = "https://pypi.python.org/packages/12/bc/595a77c4b5e204847fdf19268314ef59c85193a9dc9f83630fc459c0fee5/repoze.lru-0.7.tar.gz"; | |
1702 | md5 = "2c3b64b17a8e18b405f55d46173e14dd"; |
|
1663 | md5 = "c08cc030387e0b1fc53c5c7d964b35e2"; | |
1703 | }; |
|
1664 | }; | |
1704 | meta = { |
|
1665 | meta = { | |
1705 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
1666 | license = [ { fullName = "Repoze Public License"; } { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
@@ -1719,49 +1680,49 b'' | |||||
1719 | }; |
|
1680 | }; | |
1720 | }; |
|
1681 | }; | |
1721 | rhodecode-enterprise-ce = super.buildPythonPackage { |
|
1682 | rhodecode-enterprise-ce = super.buildPythonPackage { | |
1722 |
name = "rhodecode-enterprise-ce-4.10 |
|
1683 | name = "rhodecode-enterprise-ce-4.11.0"; | |
1723 | buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj]; |
|
1684 | buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage configobj]; | |
1724 | doCheck = true; |
|
1685 | doCheck = true; | |
1725 | propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic cssselect celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu lxml msgpack-python nbconvert packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client redis repoze.lru requests simplejson sshpubkeys subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt]; |
|
1686 | propagatedBuildInputs = with self; [setuptools-scm amqp authomatic Babel Beaker celery Chameleon channelstream click colander configobj cssselect decorator deform docutils dogpile.cache dogpile.core ecdsa FormEncode future futures gnureadline infrae.cache iso8601 itsdangerous Jinja2 billiard kombu lxml Mako Markdown MarkupSafe msgpack-python MySQL-python objgraph packaging Paste PasteDeploy PasteScript pathlib2 peppercorn psutil psycopg2 py-bcrypt pycrypto pycurl pyflakes pygments-markdown-lexer Pygments pyparsing pyramid-beaker pyramid-debugtoolbar pyramid-jinja2 pyramid-mako pyramid pysqlite python-dateutil python-ldap python-memcached python-pam pytz pyzmq py-gfm recaptcha-client redis repoze.lru requests Routes setproctitle simplejson six SQLAlchemy sshpubkeys subprocess32 supervisor Tempita translationstring trollius urllib3 URLObject venusian WebError WebHelpers2 WebHelpers WebOb Whoosh wsgiref zope.cachedescriptors zope.deprecation zope.event zope.interface nbconvert bleach nbformat jupyter-client alembic invoke bumpversion transifex-client gevent greenlet gunicorn waitress uWSGI ipdb ipython CProfileV bottle rhodecode-tools appenlight-client pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage]; | |
1726 | src = ./.; |
|
1687 | src = ./.; | |
1727 | meta = { |
|
1688 | meta = { | |
1728 | license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ]; |
|
1689 | license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ]; | |
1729 | }; |
|
1690 | }; | |
1730 | }; |
|
1691 | }; | |
1731 | rhodecode-tools = super.buildPythonPackage { |
|
1692 | rhodecode-tools = super.buildPythonPackage { | |
1732 |
name = "rhodecode-tools-0.1 |
|
1693 | name = "rhodecode-tools-0.14.1"; | |
1733 | buildInputs = with self; []; |
|
1694 | buildInputs = with self; []; | |
1734 | doCheck = false; |
|
1695 | doCheck = false; | |
1735 | propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests elasticsearch elasticsearch-dsl urllib3 Whoosh]; |
|
1696 | propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests elasticsearch elasticsearch-dsl urllib3 Whoosh]; | |
1736 | src = fetchurl { |
|
1697 | src = fetchurl { | |
1737 |
url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.1 |
|
1698 | url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.14.1.tar.gz?md5=0b9c2caad160b68889f8172ea54af7b2"; | |
1738 | md5 = "f72add4690c9b341f87127a0a79573ae"; |
|
1699 | md5 = "0b9c2caad160b68889f8172ea54af7b2"; | |
1739 | }; |
|
1700 | }; | |
1740 | meta = { |
|
1701 | meta = { | |
1741 | license = [ { fullName = "AGPLv3 and Proprietary"; } ]; |
|
1702 | license = [ { fullName = "AGPLv3 and Proprietary"; } ]; | |
1742 | }; |
|
1703 | }; | |
1743 | }; |
|
1704 | }; | |
1744 | scandir = super.buildPythonPackage { |
|
1705 | scandir = super.buildPythonPackage { | |
1745 |
name = "scandir-1. |
|
1706 | name = "scandir-1.6"; | |
1746 | buildInputs = with self; []; |
|
1707 | buildInputs = with self; []; | |
1747 | doCheck = false; |
|
1708 | doCheck = false; | |
1748 | propagatedBuildInputs = with self; []; |
|
1709 | propagatedBuildInputs = with self; []; | |
1749 | src = fetchurl { |
|
1710 | src = fetchurl { | |
1750 |
url = "https://pypi.python.org/packages/ |
|
1711 | url = "https://pypi.python.org/packages/77/3f/916f524f50ee65e3f465a280d2851bd63685250fddb3020c212b3977664d/scandir-1.6.tar.gz"; | |
1751 | md5 = "a2713043de681bba6b084be42e7a8a44"; |
|
1712 | md5 = "0180ddb97c96cbb2d4f25d2ae11c64ac"; | |
1752 | }; |
|
1713 | }; | |
1753 | meta = { |
|
1714 | meta = { | |
1754 | license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ]; |
|
1715 | license = [ pkgs.lib.licenses.bsdOriginal { fullName = "New BSD License"; } ]; | |
1755 | }; |
|
1716 | }; | |
1756 | }; |
|
1717 | }; | |
1757 | setproctitle = super.buildPythonPackage { |
|
1718 | setproctitle = super.buildPythonPackage { | |
1758 |
name = "setproctitle-1.1. |
|
1719 | name = "setproctitle-1.1.10"; | |
1759 | buildInputs = with self; []; |
|
1720 | buildInputs = with self; []; | |
1760 | doCheck = false; |
|
1721 | doCheck = false; | |
1761 | propagatedBuildInputs = with self; []; |
|
1722 | propagatedBuildInputs = with self; []; | |
1762 | src = fetchurl { |
|
1723 | src = fetchurl { | |
1763 |
url = "https://pypi.python.org/packages/3 |
|
1724 | url = "https://pypi.python.org/packages/5a/0d/dc0d2234aacba6cf1a729964383e3452c52096dc695581248b548786f2b3/setproctitle-1.1.10.tar.gz"; | |
1764 | md5 = "728f4c8c6031bbe56083a48594027edd"; |
|
1725 | md5 = "2dcdd1b761700a5a13252fea3dfd1977"; | |
1765 | }; |
|
1726 | }; | |
1766 | meta = { |
|
1727 | meta = { | |
1767 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1728 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1781,13 +1742,13 b'' | |||||
1781 | }; |
|
1742 | }; | |
1782 | }; |
|
1743 | }; | |
1783 | setuptools-scm = super.buildPythonPackage { |
|
1744 | setuptools-scm = super.buildPythonPackage { | |
1784 |
name = "setuptools-scm-1.15. |
|
1745 | name = "setuptools-scm-1.15.6"; | |
1785 | buildInputs = with self; []; |
|
1746 | buildInputs = with self; []; | |
1786 | doCheck = false; |
|
1747 | doCheck = false; | |
1787 | propagatedBuildInputs = with self; []; |
|
1748 | propagatedBuildInputs = with self; []; | |
1788 | src = fetchurl { |
|
1749 | src = fetchurl { | |
1789 |
url = "https://pypi.python.org/packages/8 |
|
1750 | url = "https://pypi.python.org/packages/03/6d/aafdd01edd227ee879b691455bf19895091872af7e48192bea1758c82032/setuptools_scm-1.15.6.tar.gz"; | |
1790 | md5 = "b6916c78ed6253d6602444fad4279c5b"; |
|
1751 | md5 = "f17493d53f0d842bb0152f214775640b"; | |
1791 | }; |
|
1752 | }; | |
1792 | meta = { |
|
1753 | meta = { | |
1793 | license = [ pkgs.lib.licenses.mit ]; |
|
1754 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1820,13 +1781,13 b'' | |||||
1820 | }; |
|
1781 | }; | |
1821 | }; |
|
1782 | }; | |
1822 | six = super.buildPythonPackage { |
|
1783 | six = super.buildPythonPackage { | |
1823 |
name = "six-1. |
|
1784 | name = "six-1.11.0"; | |
1824 | buildInputs = with self; []; |
|
1785 | buildInputs = with self; []; | |
1825 | doCheck = false; |
|
1786 | doCheck = false; | |
1826 | propagatedBuildInputs = with self; []; |
|
1787 | propagatedBuildInputs = with self; []; | |
1827 | src = fetchurl { |
|
1788 | src = fetchurl { | |
1828 |
url = "https://pypi.python.org/packages/16/64 |
|
1789 | url = "https://pypi.python.org/packages/16/d8/bc6316cf98419719bd59c91742194c111b6f2e85abac88e496adefaf7afe/six-1.11.0.tar.gz"; | |
1829 | md5 = "476881ef4012262dfc8adc645ee786c4"; |
|
1790 | md5 = "d12789f9baf7e9fb2524c0c64f1773f8"; | |
1830 | }; |
|
1791 | }; | |
1831 | meta = { |
|
1792 | meta = { | |
1832 | license = [ pkgs.lib.licenses.mit ]; |
|
1793 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1911,13 +1872,13 b'' | |||||
1911 | }; |
|
1872 | }; | |
1912 | }; |
|
1873 | }; | |
1913 | transifex-client = super.buildPythonPackage { |
|
1874 | transifex-client = super.buildPythonPackage { | |
1914 |
name = "transifex-client-0.1 |
|
1875 | name = "transifex-client-0.12.5"; | |
1915 | buildInputs = with self; []; |
|
1876 | buildInputs = with self; []; | |
1916 | doCheck = false; |
|
1877 | doCheck = false; | |
1917 | propagatedBuildInputs = with self; []; |
|
1878 | propagatedBuildInputs = with self; [urllib3 six]; | |
1918 | src = fetchurl { |
|
1879 | src = fetchurl { | |
1919 |
url = "https://pypi.python.org/packages/f3 |
|
1880 | url = "https://pypi.python.org/packages/7b/86/60f31a0c9b8d0b1266ce15b6c80b55f88522140c8acfc395d5aec5e23475/transifex-client-0.12.5.tar.gz"; | |
1920 | md5 = "5549538d84b8eede6b254cd81ae024fa"; |
|
1881 | md5 = "e6e278117b23f60702c06e203b7e51ae"; | |
1921 | }; |
|
1882 | }; | |
1922 | meta = { |
|
1883 | meta = { | |
1923 | license = [ pkgs.lib.licenses.gpl2 ]; |
|
1884 | license = [ pkgs.lib.licenses.gpl2 ]; | |
@@ -1988,14 +1949,27 b'' | |||||
1988 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
1949 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
1989 | }; |
|
1950 | }; | |
1990 | }; |
|
1951 | }; | |
1991 |
|
|
1952 | vine = super.buildPythonPackage { | |
1992 |
name = " |
|
1953 | name = "vine-1.1.4"; | |
1993 | buildInputs = with self; []; |
|
1954 | buildInputs = with self; []; | |
1994 | doCheck = false; |
|
1955 | doCheck = false; | |
1995 | propagatedBuildInputs = with self; []; |
|
1956 | propagatedBuildInputs = with self; []; | |
1996 | src = fetchurl { |
|
1957 | src = fetchurl { | |
1997 | url = "https://pypi.python.org/packages/cd/f4/400d00863afa1e03618e31fd7e2092479a71b8c9718b00eb1eeb603746c6/waitress-1.0.2.tar.gz"; |
|
1958 | url = "https://pypi.python.org/packages/32/23/36284986e011f3c130d802c3c66abd8f1aef371eae110ddf80c5ae22e1ff/vine-1.1.4.tar.gz"; | |
1998 | md5 = "b968f39e95d609f6194c6e50425d4bb7"; |
|
1959 | md5 = "9fdb971e7fd15b181b84f3bfcf20d11c"; | |
|
1960 | }; | |||
|
1961 | meta = { | |||
|
1962 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |||
|
1963 | }; | |||
|
1964 | }; | |||
|
1965 | waitress = super.buildPythonPackage { | |||
|
1966 | name = "waitress-1.1.0"; | |||
|
1967 | buildInputs = with self; []; | |||
|
1968 | doCheck = false; | |||
|
1969 | propagatedBuildInputs = with self; []; | |||
|
1970 | src = fetchurl { | |||
|
1971 | url = "https://pypi.python.org/packages/3c/68/1c10dd5c556872ceebe88483b0436140048d39de83a84a06a8baa8136f4f/waitress-1.1.0.tar.gz"; | |||
|
1972 | md5 = "0f1eb7fdfdbf2e6d18decbda1733045c"; | |||
1999 | }; |
|
1973 | }; | |
2000 | meta = { |
|
1974 | meta = { | |
2001 | license = [ pkgs.lib.licenses.zpt21 ]; |
|
1975 | license = [ pkgs.lib.licenses.zpt21 ]; | |
@@ -2014,14 +1988,27 b'' | |||||
2014 | license = [ pkgs.lib.licenses.mit ]; |
|
1988 | license = [ pkgs.lib.licenses.mit ]; | |
2015 | }; |
|
1989 | }; | |
2016 | }; |
|
1990 | }; | |
2017 |
ws |
|
1991 | webencodings = super.buildPythonPackage { | |
2018 |
name = "ws |
|
1992 | name = "webencodings-0.5.1"; | |
2019 | buildInputs = with self; []; |
|
1993 | buildInputs = with self; []; | |
2020 | doCheck = false; |
|
1994 | doCheck = false; | |
2021 | propagatedBuildInputs = with self; []; |
|
1995 | propagatedBuildInputs = with self; []; | |
2022 | src = fetchurl { |
|
1996 | src = fetchurl { | |
2023 | url = "https://pypi.python.org/packages/b6/4f/34af703be86939629479e74d6e650e39f3bd73b3b09212c34e5125764cbc/ws4py-0.3.5.zip"; |
|
1997 | url = "https://pypi.python.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz"; | |
2024 | md5 = "a261b75c20b980e55ce7451a3576a867"; |
|
1998 | md5 = "32f6e261d52e57bf7e1c4d41546d15b8"; | |
|
1999 | }; | |||
|
2000 | meta = { | |||
|
2001 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |||
|
2002 | }; | |||
|
2003 | }; | |||
|
2004 | ws4py = super.buildPythonPackage { | |||
|
2005 | name = "ws4py-0.4.2"; | |||
|
2006 | buildInputs = with self; []; | |||
|
2007 | doCheck = false; | |||
|
2008 | propagatedBuildInputs = with self; []; | |||
|
2009 | src = fetchurl { | |||
|
2010 | url = "https://pypi.python.org/packages/b8/98/a90f1d96ffcb15dfc220af524ce23e0a5881258dafa197673357ce1683dd/ws4py-0.4.2.tar.gz"; | |||
|
2011 | md5 = "f0603ae376707a58d205bd87a67758a2"; | |||
2025 | }; |
|
2012 | }; | |
2026 | meta = { |
|
2013 | meta = { | |
2027 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
2014 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1,12 +1,12 b'' | |||||
1 | [pytest] |
|
1 | [pytest] | |
2 |
testpaths = |
|
2 | testpaths = rhodecode | |
3 | pylons_config = rhodecode/tests/rhodecode.ini |
|
3 | norecursedirs = rhodecode/public rhodecode/templates tests/scripts | |
|
4 | ||||
|
5 | pyramid_config = rhodecode/tests/rhodecode.ini | |||
4 | vcsserver_protocol = http |
|
6 | vcsserver_protocol = http | |
5 | vcsserver_config_http = rhodecode/tests/vcsserver_http.ini |
|
7 | vcsserver_config_http = rhodecode/tests/vcsserver_http.ini | |
6 | norecursedirs = tests/scripts |
|
|||
7 |
|
8 | |||
8 | addopts = |
|
9 | addopts = | |
9 | -k "not _BaseTest" |
|
|||
10 | --pdbcls=IPython.terminal.debugger:TerminalPdb |
|
10 | --pdbcls=IPython.terminal.debugger:TerminalPdb | |
11 |
|
11 | |||
12 | markers = |
|
12 | markers = |
@@ -1,51 +1,49 b'' | |||||
1 | ## core |
|
1 | ## core | |
2 | setuptools==30.1.0 |
|
2 | setuptools==30.1.0 | |
3 |
setuptools-scm==1.15. |
|
3 | setuptools-scm==1.15.6 | |
4 |
|
4 | |||
5 |
amqp |
|
5 | amqp==2.2.2 | |
6 | anyjson==0.3.3 |
|
|||
7 | authomatic==0.1.0.post1 |
|
6 | authomatic==0.1.0.post1 | |
8 | Babel==1.3 |
|
7 | Babel==1.3 | |
9 | Beaker==1.9.0 |
|
8 | Beaker==1.9.0 | |
10 |
celery== |
|
9 | celery==4.1.0 | |
11 | Chameleon==2.24 |
|
10 | Chameleon==2.24 | |
12 | channelstream==0.5.2 |
|
11 | channelstream==0.5.2 | |
13 |
click== |
|
12 | click==6.6 | |
14 |
colander==1. |
|
13 | colander==1.4.0 | |
15 | configobj==5.0.6 |
|
14 | configobj==5.0.6 | |
16 | cssselect==1.0.1 |
|
15 | cssselect==1.0.1 | |
17 |
decorator==4. |
|
16 | decorator==4.1.2 | |
18 | deform==2.0.4 |
|
17 | deform==2.0.4 | |
19 |
docutils==0.1 |
|
18 | docutils==0.14.0 | |
20 | dogpile.cache==0.6.4 |
|
19 | dogpile.cache==0.6.4 | |
21 | dogpile.core==0.4.1 |
|
20 | dogpile.core==0.4.1 | |
22 | ecdsa==0.13 |
|
21 | ecdsa==0.13 | |
23 | FormEncode==1.2.4 |
|
22 | FormEncode==1.2.4 | |
24 | future==0.14.3 |
|
23 | future==0.14.3 | |
25 | futures==3.0.2 |
|
24 | futures==3.0.2 | |
26 |
gnureadline==6.3. |
|
25 | gnureadline==6.3.8 | |
27 | infrae.cache==1.0.1 |
|
26 | infrae.cache==1.0.1 | |
28 |
iso8601==0.1.1 |
|
27 | iso8601==0.1.12 | |
29 | itsdangerous==0.24 |
|
28 | itsdangerous==0.24 | |
30 |
Jinja2==2. |
|
29 | Jinja2==2.9.6 | |
31 | kombu==1.5.1 |
|
30 | billiard==3.5.0.3 | |
|
31 | kombu==4.1.0 | |||
32 | lxml==3.7.3 |
|
32 | lxml==3.7.3 | |
33 | Mako==1.0.7 |
|
33 | Mako==1.0.7 | |
34 |
Markdown==2.6. |
|
34 | Markdown==2.6.9 | |
35 |
MarkupSafe== |
|
35 | MarkupSafe==1.0.0 | |
36 | meld3==1.0.2 |
|
|||
37 | msgpack-python==0.4.8 |
|
36 | msgpack-python==0.4.8 | |
38 | MySQL-python==1.2.5 |
|
37 | MySQL-python==1.2.5 | |
39 | nose==1.3.6 |
|
38 | objgraph==3.1.1 | |
40 | objgraph==3.1.0 |
|
|||
41 | packaging==15.2 |
|
39 | packaging==15.2 | |
42 | Paste==2.0.3 |
|
40 | Paste==2.0.3 | |
43 | PasteDeploy==1.5.2 |
|
41 | PasteDeploy==1.5.2 | |
44 |
PasteScript== |
|
42 | PasteScript==2.0.2 | |
45 | pathlib2==2.3.0 |
|
43 | pathlib2==2.3.0 | |
46 | peppercorn==0.5 |
|
44 | peppercorn==0.5 | |
47 |
psutil== |
|
45 | psutil==5.4.0 | |
48 |
psycopg2==2.7. |
|
46 | psycopg2==2.7.3.2 | |
49 | py-bcrypt==0.4 |
|
47 | py-bcrypt==0.4 | |
50 | pycrypto==2.6.1 |
|
48 | pycrypto==2.6.1 | |
51 | pycurl==7.19.5 |
|
49 | pycurl==7.19.5 | |
@@ -54,27 +52,27 b' pygments-markdown-lexer==0.1.0.dev39' | |||||
54 | Pygments==2.2.0 |
|
52 | Pygments==2.2.0 | |
55 | pyparsing==1.5.7 |
|
53 | pyparsing==1.5.7 | |
56 | pyramid-beaker==0.8 |
|
54 | pyramid-beaker==0.8 | |
57 |
pyramid-debugtoolbar==4. |
|
55 | pyramid-debugtoolbar==4.3.0 | |
58 |
pyramid-jinja2==2. |
|
56 | pyramid-jinja2==2.7 | |
59 | pyramid-mako==1.0.2 |
|
57 | pyramid-mako==1.0.2 | |
60 | pyramid==1.9.1 |
|
58 | pyramid==1.9.1 | |
61 | pysqlite==2.8.3 |
|
59 | pysqlite==2.8.3 | |
62 |
python-dateutil |
|
60 | python-dateutil | |
63 |
python-ldap==2.4.4 |
|
61 | python-ldap==2.4.45 | |
64 | python-memcached==1.58 |
|
62 | python-memcached==1.58 | |
65 | python-pam==1.8.2 |
|
63 | python-pam==1.8.2 | |
66 |
pytz==201 |
|
64 | pytz==2017.3 | |
67 | pyzmq==14.6.0 |
|
65 | pyzmq==14.6.0 | |
|
66 | py-gfm==0.1.3 | |||
68 | recaptcha-client==1.0.6 |
|
67 | recaptcha-client==1.0.6 | |
69 | redis==2.10.6 |
|
68 | redis==2.10.6 | |
70 |
repoze.lru==0. |
|
69 | repoze.lru==0.7 | |
71 | requests==2.9.1 |
|
70 | requests==2.9.1 | |
72 |
Routes== |
|
71 | Routes==2.4.1 | |
73 |
setproctitle==1.1. |
|
72 | setproctitle==1.1.10 | |
74 | simplejson==3.11.1 |
|
73 | simplejson==3.11.1 | |
75 |
six==1. |
|
74 | six==1.11.0 | |
76 | Sphinx==1.2.2 |
|
75 | SQLAlchemy==1.1.15 | |
77 | SQLAlchemy==1.1.11 |
|
|||
78 | sshpubkeys==2.2.0 |
|
76 | sshpubkeys==2.2.0 | |
79 | subprocess32==3.2.7 |
|
77 | subprocess32==3.2.7 | |
80 | supervisor==3.3.3 |
|
78 | supervisor==3.3.3 | |
@@ -95,44 +93,39 b' zope.deprecation==4.1.2' | |||||
95 | zope.event==4.0.3 |
|
93 | zope.event==4.0.3 | |
96 | zope.interface==4.1.3 |
|
94 | zope.interface==4.1.3 | |
97 |
|
95 | |||
98 | ## customized/patched libs |
|
|||
99 | # our patched version of Pylons==1.0.2 |
|
|||
100 | https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f#egg=Pylons==1.0.2.rhodecode-patch-1 |
|
|||
101 | # not released py-gfm==0.1.3 |
|
|||
102 | https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16#egg=py-gfm==0.1.3.rhodecode-upstream1 |
|
|||
103 |
|
96 | |||
104 | # IPYTHON RENDERING |
|
97 | # IPYTHON RENDERING | |
105 | # entrypoints backport, pypi version doesn't support egg installs |
|
98 | # entrypoints backport, pypi version doesn't support egg installs | |
106 | https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1 |
|
99 | https://code.rhodecode.com/upstream/entrypoints/archive/96e6d645684e1af3d7df5b5272f3fe85a546b233.tar.gz?md5=7db37771aea9ac9fefe093e5d6987313#egg=entrypoints==0.2.2.rhodecode-upstream1 | |
107 |
nbconvert==5. |
|
100 | nbconvert==5.3.1 | |
108 |
bleach== |
|
101 | bleach==2.1.1 | |
109 |
nbformat==4. |
|
102 | nbformat==4.4.0 | |
110 | jupyter_client==5.0.0 |
|
103 | jupyter_client==5.0.0 | |
111 |
|
104 | |||
112 | ## cli tools |
|
105 | ## cli tools | |
113 |
alembic==0.9. |
|
106 | alembic==0.9.6 | |
114 | invoke==0.13.0 |
|
107 | invoke==0.13.0 | |
115 | bumpversion==0.5.3 |
|
108 | bumpversion==0.5.3 | |
116 |
transifex-client==0.1 |
|
109 | transifex-client==0.12.5 | |
117 |
|
110 | |||
118 | ## http servers |
|
111 | ## http servers | |
119 | gevent==1.2.2 |
|
112 | gevent==1.2.2 | |
120 | greenlet==0.4.12 |
|
113 | greenlet==0.4.12 | |
121 | gunicorn==19.7.1 |
|
114 | gunicorn==19.7.1 | |
122 |
waitress==1. |
|
115 | waitress==1.1.0 | |
123 | uWSGI==2.0.15 |
|
116 | uWSGI==2.0.15 | |
124 |
|
117 | |||
125 | ## debug |
|
118 | ## debug | |
126 | ipdb==0.10.3 |
|
119 | ipdb==0.10.3 | |
127 | ipython==5.1.0 |
|
120 | ipython==5.1.0 | |
128 | CProfileV==1.0.7 |
|
121 | CProfileV==1.0.7 | |
129 |
bottle==0.12. |
|
122 | bottle==0.12.13 | |
130 |
|
123 | |||
131 | ## rhodecode-tools, special case |
|
124 | ## rhodecode-tools, special case | |
132 |
https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.1 |
|
125 | https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.14.1.tar.gz?md5=0b9c2caad160b68889f8172ea54af7b2#egg=rhodecode-tools==0.14.1 | |
133 |
|
126 | |||
134 | ## appenlight |
|
127 | ## appenlight | |
135 |
appenlight-client==0.6.2 |
|
128 | appenlight-client==0.6.22 | |
136 |
|
129 | |||
137 | ## test related requirements |
|
130 | ## test related requirements | |
138 | -r requirements_test.txt |
|
131 | -r requirements_test.txt |
@@ -1,15 +1,15 b'' | |||||
1 | # test related requirements |
|
1 | # test related requirements | |
2 |
pytest==3. |
|
2 | pytest==3.2.5 | |
3 |
py==1. |
|
3 | py==1.5.2 | |
4 | pytest-cov==2.5.1 |
|
4 | pytest-cov==2.5.1 | |
5 |
pytest-sugar==0. |
|
5 | pytest-sugar==0.9.0 | |
6 |
pytest-runner== |
|
6 | pytest-runner==3.0.0 | |
7 | pytest-catchlog==1.2.2 |
|
7 | pytest-catchlog==1.2.2 | |
8 |
pytest-profiling==1.2. |
|
8 | pytest-profiling==1.2.11 | |
9 |
gprof2dot==201 |
|
9 | gprof2dot==2017.9.19 | |
10 | pytest-timeout==1.2.0 |
|
10 | pytest-timeout==1.2.0 | |
11 |
|
11 | |||
12 | mock==1.0.1 |
|
12 | mock==1.0.1 | |
13 |
WebTest==2.0.2 |
|
13 | WebTest==2.0.29 | |
14 | cov-core==1.15.0 |
|
14 | cov-core==1.15.0 | |
15 | coverage==3.7.1 |
|
15 | coverage==3.7.1 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -40,7 +40,7 b' BACKENDS = {' | |||||
40 | CELERY_ENABLED = False |
|
40 | CELERY_ENABLED = False | |
41 | CELERY_EAGER = False |
|
41 | CELERY_EAGER = False | |
42 |
|
42 | |||
43 |
# link to config for py |
|
43 | # link to config for pyramid | |
44 | CONFIG = {} |
|
44 | CONFIG = {} | |
45 |
|
45 | |||
46 | # Populated with the settings dictionary from application init in |
|
46 | # Populated with the settings dictionary from application init in | |
@@ -51,7 +51,7 b' PYRAMID_SETTINGS = {}' | |||||
51 | EXTENSIONS = {} |
|
51 | EXTENSIONS = {} | |
52 |
|
52 | |||
53 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) |
|
53 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) | |
54 |
__dbversion__ = 8 |
|
54 | __dbversion__ = 85 # defines current db version for migrations | |
55 | __platform__ = platform.system() |
|
55 | __platform__ = platform.system() | |
56 | __license__ = 'AGPLv3, and Commercial License' |
|
56 | __license__ = 'AGPLv3, and Commercial License' | |
57 | __author__ = 'RhodeCode GmbH' |
|
57 | __author__ = 'RhodeCode GmbH' |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -27,7 +27,7 b' from rhodecode.tests import TEST_USER_AD' | |||||
27 |
|
27 | |||
28 |
|
28 | |||
29 | @pytest.fixture(scope="class") |
|
29 | @pytest.fixture(scope="class") | |
30 |
def testuser_api(request, |
|
30 | def testuser_api(request, baseapp): | |
31 | cls = request.cls |
|
31 | cls = request.cls | |
32 |
|
32 | |||
33 | # ADMIN USER |
|
33 | # ADMIN USER |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -86,7 +86,7 b' class TestApi(object):' | |||||
86 | def test_api_non_existing_method_have_similar(self, request): |
|
86 | def test_api_non_existing_method_have_similar(self, request): | |
87 | id_, params = build_data(self.apikey, 'comment', args='xx') |
|
87 | id_, params = build_data(self.apikey, 'comment', args='xx') | |
88 | response = api_call(self.app, params) |
|
88 | response = api_call(self.app, params) | |
89 | expected = 'No such method: comment. Similar methods: changeset_comment, comment_pull_request, comment_commit' |
|
89 | expected = 'No such method: comment. Similar methods: changeset_comment, comment_pull_request, get_pull_request_comments, comment_commit' | |
90 | assert_error(id_, expected, given=response.body) |
|
90 | assert_error(id_, expected, given=response.body) | |
91 |
|
91 | |||
92 | def test_api_disabled_user(self, request): |
|
92 | def test_api_disabled_user(self, request): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -70,10 +70,11 b' class TestClosePullRequest(object):' | |||||
70 | assert_error(id_, expected, given=response.body) |
|
70 | assert_error(id_, expected, given=response.body) | |
71 |
|
71 | |||
72 | @pytest.mark.backends("git", "hg") |
|
72 | @pytest.mark.backends("git", "hg") | |
73 | def test_api_close_pull_request_repo_error(self): |
|
73 | def test_api_close_pull_request_repo_error(self, pr_util): | |
|
74 | pull_request = pr_util.create_pull_request() | |||
74 | id_, params = build_data( |
|
75 | id_, params = build_data( | |
75 | self.apikey, 'close_pull_request', |
|
76 | self.apikey, 'close_pull_request', | |
76 |
repoid=666, pullrequestid= |
|
77 | repoid=666, pullrequestid=pull_request.pull_request_id) | |
77 | response = api_call(self.app, params) |
|
78 | response = api_call(self.app, params) | |
78 |
|
79 | |||
79 | expected = 'repository `666` does not exist' |
|
80 | expected = 'repository `666` does not exist' |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -170,10 +170,11 b' class TestCommentPullRequest(object):' | |||||
170 | assert_error(id_, expected, given=response.body) |
|
170 | assert_error(id_, expected, given=response.body) | |
171 |
|
171 | |||
172 | @pytest.mark.backends("git", "hg") |
|
172 | @pytest.mark.backends("git", "hg") | |
173 | def test_api_comment_pull_request_repo_error(self): |
|
173 | def test_api_comment_pull_request_repo_error(self, pr_util): | |
|
174 | pull_request = pr_util.create_pull_request() | |||
174 | id_, params = build_data( |
|
175 | id_, params = build_data( | |
175 | self.apikey, 'comment_pull_request', |
|
176 | self.apikey, 'comment_pull_request', | |
176 |
repoid=666, pullrequestid= |
|
177 | repoid=666, pullrequestid=pull_request.pull_request_id) | |
177 | response = api_call(self.app, params) |
|
178 | response = api_call(self.app, params) | |
178 |
|
179 | |||
179 | expected = 'repository `666` does not exist' |
|
180 | expected = 'repository `666` does not exist' |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -38,11 +38,12 b' class TestGetMethod(object):' | |||||
38 | response = api_call(self.app, params) |
|
38 | response = api_call(self.app, params) | |
39 |
|
39 | |||
40 | expected = ['changeset_comment', 'comment_pull_request', |
|
40 | expected = ['changeset_comment', 'comment_pull_request', | |
41 | 'comment_commit'] |
|
41 | 'get_pull_request_comments', 'comment_commit'] | |
42 | assert_ok(id_, expected, given=response.body) |
|
42 | assert_ok(id_, expected, given=response.body) | |
43 |
|
43 | |||
44 | def test_get_methods_on_single_match(self): |
|
44 | def test_get_methods_on_single_match(self): | |
45 |
id_, params = build_data(self.apikey, 'get_method', |
|
45 | id_, params = build_data(self.apikey, 'get_method', | |
|
46 | pattern='*comment_commit*') | |||
46 | response = api_call(self.app, params) |
|
47 | response = api_call(self.app, params) | |
47 |
|
48 | |||
48 | expected = ['comment_commit', |
|
49 | expected = ['comment_commit', |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -38,7 +38,6 b' class TestGetPullRequest(object):' | |||||
38 | pull_request = pr_util.create_pull_request(mergeable=True) |
|
38 | pull_request = pr_util.create_pull_request(mergeable=True) | |
39 | id_, params = build_data( |
|
39 | id_, params = build_data( | |
40 | self.apikey, 'get_pull_request', |
|
40 | self.apikey, 'get_pull_request', | |
41 | repoid=pull_request.target_repo.repo_name, |
|
|||
42 | pullrequestid=pull_request.pull_request_id) |
|
41 | pullrequestid=pull_request.pull_request_id) | |
43 |
|
42 | |||
44 | response = api_call(self.app, params) |
|
43 | response = api_call(self.app, params) | |
@@ -109,16 +108,17 b' class TestGetPullRequest(object):' | |||||
109 | 'reasons': reasons, |
|
108 | 'reasons': reasons, | |
110 | 'review_status': st[0][1].status if st else 'not_reviewed', |
|
109 | 'review_status': st[0][1].status if st else 'not_reviewed', | |
111 | } |
|
110 | } | |
112 | for reviewer, reasons, mandatory, st in |
|
111 | for obj, reviewer, reasons, mandatory, st in | |
113 | pull_request.reviewers_statuses() |
|
112 | pull_request.reviewers_statuses() | |
114 | ] |
|
113 | ] | |
115 | } |
|
114 | } | |
116 | assert_ok(id_, expected, response.body) |
|
115 | assert_ok(id_, expected, response.body) | |
117 |
|
116 | |||
118 | def test_api_get_pull_request_repo_error(self): |
|
117 | def test_api_get_pull_request_repo_error(self, pr_util): | |
|
118 | pull_request = pr_util.create_pull_request() | |||
119 | id_, params = build_data( |
|
119 | id_, params = build_data( | |
120 | self.apikey, 'get_pull_request', |
|
120 | self.apikey, 'get_pull_request', | |
121 |
repoid=666, pullrequestid= |
|
121 | repoid=666, pullrequestid=pull_request.pull_request_id) | |
122 | response = api_call(self.app, params) |
|
122 | response = api_call(self.app, params) | |
123 |
|
123 | |||
124 | expected = 'repository `666` does not exist' |
|
124 | expected = 'repository `666` does not exist' | |
@@ -126,9 +126,17 b' class TestGetPullRequest(object):' | |||||
126 |
|
126 | |||
127 | def test_api_get_pull_request_pull_request_error(self): |
|
127 | def test_api_get_pull_request_pull_request_error(self): | |
128 | id_, params = build_data( |
|
128 | id_, params = build_data( | |
129 | self.apikey, 'get_pull_request', |
|
129 | self.apikey, 'get_pull_request', pullrequestid=666) | |
130 | repoid=1, pullrequestid=666) |
|
|||
131 | response = api_call(self.app, params) |
|
130 | response = api_call(self.app, params) | |
132 |
|
131 | |||
133 | expected = 'pull request `666` does not exist' |
|
132 | expected = 'pull request `666` does not exist' | |
134 | assert_error(id_, expected, given=response.body) |
|
133 | assert_error(id_, expected, given=response.body) | |
|
134 | ||||
|
135 | def test_api_get_pull_request_pull_request_error_just_pr_id(self): | |||
|
136 | id_, params = build_data( | |||
|
137 | self.apikey, 'get_pull_request', | |||
|
138 | pullrequestid=666) | |||
|
139 | response = api_call(self.app, params) | |||
|
140 | ||||
|
141 | expected = 'pull request `666` does not exist' | |||
|
142 | assert_error(id_, expected, given=response.body) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -68,7 +68,6 b' class TestGetRepo(object):' | |||||
68 | followers.append(user.user.get_api_data( |
|
68 | followers.append(user.user.get_api_data( | |
69 | include_secrets=expect_secrets)) |
|
69 | include_secrets=expect_secrets)) | |
70 |
|
70 | |||
71 | ret['members'] = permissions |
|
|||
72 | ret['permissions'] = permissions |
|
71 | ret['permissions'] = permissions | |
73 | ret['followers'] = followers |
|
72 | ret['followers'] = followers | |
74 |
|
73 | |||
@@ -106,7 +105,6 b' class TestGetRepo(object):' | |||||
106 | for user in repo.followers: |
|
105 | for user in repo.followers: | |
107 | followers.append(user.user.get_api_data()) |
|
106 | followers.append(user.user.get_api_data()) | |
108 |
|
107 | |||
109 | ret['members'] = permissions |
|
|||
110 | ret['permissions'] = permissions |
|
108 | ret['permissions'] = permissions | |
111 | ret['followers'] = followers |
|
109 | ret['followers'] = followers | |
112 |
|
110 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -41,7 +41,7 b' class TestApiGetRepoGroup(object):' | |||||
41 |
|
41 | |||
42 | permissions = expected_permissions(repo_group) |
|
42 | permissions = expected_permissions(repo_group) | |
43 |
|
43 | |||
44 |
ret[' |
|
44 | ret['permissions'] = permissions | |
45 | expected = ret |
|
45 | expected = ret | |
46 | assert_ok(id_, expected, given=response.body) |
|
46 | assert_ok(id_, expected, given=response.body) | |
47 |
|
47 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -36,7 +36,9 b' class TestGetUser(object):' | |||||
36 |
|
36 | |||
37 | usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) |
|
37 | usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) | |
38 | ret = usr.get_api_data(include_secrets=True) |
|
38 | ret = usr.get_api_data(include_secrets=True) | |
39 |
|
|
39 | permissions = AuthUser(usr.user_id).permissions | |
|
40 | ret['permissions'] = permissions | |||
|
41 | ret['permissions_summary'] = permissions | |||
40 |
|
42 | |||
41 | expected = ret |
|
43 | expected = ret | |
42 | assert_ok(id_, expected, given=response.body) |
|
44 | assert_ok(id_, expected, given=response.body) | |
@@ -54,7 +56,9 b' class TestGetUser(object):' | |||||
54 |
|
56 | |||
55 | usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) |
|
57 | usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) | |
56 | ret = usr.get_api_data(include_secrets=True) |
|
58 | ret = usr.get_api_data(include_secrets=True) | |
57 |
|
|
59 | permissions = AuthUser(usr.user_id).permissions | |
|
60 | ret['permissions'] = permissions | |||
|
61 | ret['permissions_summary'] = permissions | |||
58 |
|
62 | |||
59 | expected = ret |
|
63 | expected = ret | |
60 | assert_ok(id_, expected, given=response.body) |
|
64 | assert_ok(id_, expected, given=response.body) | |
@@ -65,7 +69,9 b' class TestGetUser(object):' | |||||
65 |
|
69 | |||
66 | usr = UserModel().get_by_username(self.TEST_USER_LOGIN) |
|
70 | usr = UserModel().get_by_username(self.TEST_USER_LOGIN) | |
67 | ret = usr.get_api_data(include_secrets=True) |
|
71 | ret = usr.get_api_data(include_secrets=True) | |
68 |
|
|
72 | permissions = AuthUser(usr.user_id).permissions | |
|
73 | ret['permissions'] = permissions | |||
|
74 | ret['permissions_summary'] = permissions | |||
69 |
|
75 | |||
70 | expected = ret |
|
76 | expected = ret | |
71 | assert_ok(id_, expected, given=response.body) |
|
77 | assert_ok(id_, expected, given=response.body) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -38,7 +38,8 b' class TestGetUserGroups(object):' | |||||
38 |
|
38 | |||
39 | permissions = expected_permissions(group) |
|
39 | permissions = expected_permissions(group) | |
40 |
|
40 | |||
41 |
ret[' |
|
41 | ret['permissions'] = permissions | |
|
42 | ret['permissions_summary'] = response.json['result']['permissions_summary'] | |||
42 | expected = ret |
|
43 | expected = ret | |
43 | assert_ok(id_, expected, given=response.body) |
|
44 | assert_ok(id_, expected, given=response.body) | |
44 |
|
45 | |||
@@ -54,7 +55,8 b' class TestGetUserGroups(object):' | |||||
54 |
|
55 | |||
55 | permissions = expected_permissions(group) |
|
56 | permissions = expected_permissions(group) | |
56 |
|
57 | |||
57 |
ret[' |
|
58 | ret['permissions'] = permissions | |
|
59 | ret['permissions_summary'] = response.json['result']['permissions_summary'] | |||
58 | expected = ret |
|
60 | expected = ret | |
59 | assert_ok(id_, expected, given=response.body) |
|
61 | assert_ok(id_, expected, given=response.body) | |
60 |
|
62 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -112,10 +112,11 b' class TestMergePullRequest(object):' | |||||
112 | assert_error(id_, expected, given=response.body) |
|
112 | assert_error(id_, expected, given=response.body) | |
113 |
|
113 | |||
114 | @pytest.mark.backends("git", "hg") |
|
114 | @pytest.mark.backends("git", "hg") | |
115 | def test_api_merge_pull_request_repo_error(self): |
|
115 | def test_api_merge_pull_request_repo_error(self, pr_util): | |
|
116 | pull_request = pr_util.create_pull_request() | |||
116 | id_, params = build_data( |
|
117 | id_, params = build_data( | |
117 | self.apikey, 'merge_pull_request', |
|
118 | self.apikey, 'merge_pull_request', | |
118 |
repoid=666, pullrequestid= |
|
119 | repoid=666, pullrequestid=pull_request.pull_request_id) | |
119 | response = api_call(self.app, params) |
|
120 | response = api_call(self.app, params) | |
120 |
|
121 | |||
121 | expected = 'repository `666` does not exist' |
|
122 | expected = 'repository `666` does not exist' |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -133,7 +133,7 b' class TestUpdatePullRequest(object):' | |||||
133 | removed = [a.username] |
|
133 | removed = [a.username] | |
134 |
|
134 | |||
135 | pull_request = pr_util.create_pull_request( |
|
135 | pull_request = pr_util.create_pull_request( | |
136 | reviewers=[(a.username, ['added via API'], False)]) |
|
136 | reviewers=[(a.username, ['added via API'], False, [])]) | |
137 |
|
137 | |||
138 | id_, params = build_data( |
|
138 | id_, params = build_data( | |
139 | self.apikey, 'update_pull_request', |
|
139 | self.apikey, 'update_pull_request', | |
@@ -168,10 +168,11 b' class TestUpdatePullRequest(object):' | |||||
168 |
|
168 | |||
169 | @pytest.mark.backends("git", "hg") |
|
169 | @pytest.mark.backends("git", "hg") | |
170 | def test_api_update_repo_error(self, pr_util): |
|
170 | def test_api_update_repo_error(self, pr_util): | |
|
171 | pull_request = pr_util.create_pull_request() | |||
171 | id_, params = build_data( |
|
172 | id_, params = build_data( | |
172 | self.apikey, 'update_pull_request', |
|
173 | self.apikey, 'update_pull_request', | |
173 | repoid='fake', |
|
174 | repoid='fake', | |
174 |
pullrequestid= |
|
175 | pullrequestid=pull_request.pull_request_id, | |
175 | reviewers=[{'username': 'bad_name'}]) |
|
176 | reviewers=[{'username': 'bad_name'}]) | |
176 | response = api_call(self.app, params) |
|
177 | response = api_call(self.app, params) | |
177 |
|
178 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2014-201 |
|
3 | # Copyright (C) 2014-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2015-201 |
|
3 | # Copyright (C) 2015-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -43,14 +43,14 b' log = logging.getLogger(__name__)' | |||||
43 |
|
43 | |||
44 |
|
44 | |||
45 | @jsonrpc_method() |
|
45 | @jsonrpc_method() | |
46 |
def get_pull_request(request, apiuser, |
|
46 | def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None)): | |
47 | """ |
|
47 | """ | |
48 | Get a pull request based on the given ID. |
|
48 | Get a pull request based on the given ID. | |
49 |
|
49 | |||
50 | :param apiuser: This is filled automatically from the |authtoken|. |
|
50 | :param apiuser: This is filled automatically from the |authtoken|. | |
51 | :type apiuser: AuthUser |
|
51 | :type apiuser: AuthUser | |
52 |
:param repoid: |
|
52 | :param repoid: Optional, repository name or repository ID from where | |
53 | request was opened. |
|
53 | the pull request was opened. | |
54 | :type repoid: str or int |
|
54 | :type repoid: str or int | |
55 | :param pullrequestid: ID of the requested pull request. |
|
55 | :param pullrequestid: ID of the requested pull request. | |
56 | :type pullrequestid: int |
|
56 | :type pullrequestid: int | |
@@ -121,11 +121,17 b' def get_pull_request(request, apiuser, r' | |||||
121 | }, |
|
121 | }, | |
122 | "error": null |
|
122 | "error": null | |
123 | """ |
|
123 | """ | |
124 | get_repo_or_error(repoid) |
|
124 | ||
125 | pull_request = get_pull_request_or_error(pullrequestid) |
|
125 | pull_request = get_pull_request_or_error(pullrequestid) | |
|
126 | if Optional.extract(repoid): | |||
|
127 | repo = get_repo_or_error(repoid) | |||
|
128 | else: | |||
|
129 | repo = pull_request.target_repo | |||
|
130 | ||||
126 | if not PullRequestModel().check_user_read( |
|
131 | if not PullRequestModel().check_user_read( | |
127 | pull_request, apiuser, api=True): |
|
132 | pull_request, apiuser, api=True): | |
128 |
raise JSONRPCError('repository `%s` |
|
133 | raise JSONRPCError('repository `%s` or pull request `%s` ' | |
|
134 | 'does not exist' % (repoid, pullrequestid)) | |||
129 | data = pull_request.get_api_data() |
|
135 | data = pull_request.get_api_data() | |
130 | return data |
|
136 | return data | |
131 |
|
137 | |||
@@ -137,7 +143,7 b' def get_pull_requests(request, apiuser, ' | |||||
137 |
|
143 | |||
138 | :param apiuser: This is filled automatically from the |authtoken|. |
|
144 | :param apiuser: This is filled automatically from the |authtoken|. | |
139 | :type apiuser: AuthUser |
|
145 | :type apiuser: AuthUser | |
140 |
:param repoid: |
|
146 | :param repoid: Optional repository name or repository ID. | |
141 | :type repoid: str or int |
|
147 | :type repoid: str or int | |
142 | :param status: Only return pull requests with the specified status. |
|
148 | :param status: Only return pull requests with the specified status. | |
143 | Valid options are. |
|
149 | Valid options are. | |
@@ -229,7 +235,7 b' def get_pull_requests(request, apiuser, ' | |||||
229 |
|
235 | |||
230 | @jsonrpc_method() |
|
236 | @jsonrpc_method() | |
231 | def merge_pull_request( |
|
237 | def merge_pull_request( | |
232 |
request, apiuser, |
|
238 | request, apiuser, pullrequestid, repoid=Optional(None), | |
233 | userid=Optional(OAttr('apiuser'))): |
|
239 | userid=Optional(OAttr('apiuser'))): | |
234 | """ |
|
240 | """ | |
235 | Merge the pull request specified by `pullrequestid` into its target |
|
241 | Merge the pull request specified by `pullrequestid` into its target | |
@@ -237,7 +243,7 b' def merge_pull_request(' | |||||
237 |
|
243 | |||
238 | :param apiuser: This is filled automatically from the |authtoken|. |
|
244 | :param apiuser: This is filled automatically from the |authtoken|. | |
239 | :type apiuser: AuthUser |
|
245 | :type apiuser: AuthUser | |
240 |
:param repoid: |
|
246 | :param repoid: Optional, repository name or repository ID of the | |
241 | target repository to which the |pr| is to be merged. |
|
247 | target repository to which the |pr| is to be merged. | |
242 | :type repoid: str or int |
|
248 | :type repoid: str or int | |
243 | :param pullrequestid: ID of the pull request which shall be merged. |
|
249 | :param pullrequestid: ID of the pull request which shall be merged. | |
@@ -263,7 +269,12 b' def merge_pull_request(' | |||||
263 | }, |
|
269 | }, | |
264 | "error": null |
|
270 | "error": null | |
265 | """ |
|
271 | """ | |
266 |
|
|
272 | pull_request = get_pull_request_or_error(pullrequestid) | |
|
273 | if Optional.extract(repoid): | |||
|
274 | repo = get_repo_or_error(repoid) | |||
|
275 | else: | |||
|
276 | repo = pull_request.target_repo | |||
|
277 | ||||
267 | if not isinstance(userid, Optional): |
|
278 | if not isinstance(userid, Optional): | |
268 | if (has_superadmin_permission(apiuser) or |
|
279 | if (has_superadmin_permission(apiuser) or | |
269 | HasRepoPermissionAnyApi('repository.admin')( |
|
280 | HasRepoPermissionAnyApi('repository.admin')( | |
@@ -272,8 +283,6 b' def merge_pull_request(' | |||||
272 | else: |
|
283 | else: | |
273 | raise JSONRPCError('userid is not the same as your user') |
|
284 | raise JSONRPCError('userid is not the same as your user') | |
274 |
|
285 | |||
275 | pull_request = get_pull_request_or_error(pullrequestid) |
|
|||
276 |
|
||||
277 | check = MergeCheck.validate( |
|
286 | check = MergeCheck.validate( | |
278 | pull_request, user=apiuser, translator=request.translate) |
|
287 | pull_request, user=apiuser, translator=request.translate) | |
279 | merge_possible = not check.failed |
|
288 | merge_possible = not check.failed | |
@@ -311,9 +320,112 b' def merge_pull_request(' | |||||
311 |
|
320 | |||
312 |
|
321 | |||
313 | @jsonrpc_method() |
|
322 | @jsonrpc_method() | |
|
323 | def get_pull_request_comments( | |||
|
324 | request, apiuser, pullrequestid, repoid=Optional(None)): | |||
|
325 | """ | |||
|
326 | Get all comments of pull request specified with the `pullrequestid` | |||
|
327 | ||||
|
328 | :param apiuser: This is filled automatically from the |authtoken|. | |||
|
329 | :type apiuser: AuthUser | |||
|
330 | :param repoid: Optional repository name or repository ID. | |||
|
331 | :type repoid: str or int | |||
|
332 | :param pullrequestid: The pull request ID. | |||
|
333 | :type pullrequestid: int | |||
|
334 | ||||
|
335 | Example output: | |||
|
336 | ||||
|
337 | .. code-block:: bash | |||
|
338 | ||||
|
339 | id : <id_given_in_input> | |||
|
340 | result : [ | |||
|
341 | { | |||
|
342 | "comment_author": { | |||
|
343 | "active": true, | |||
|
344 | "full_name_or_username": "Tom Gore", | |||
|
345 | "username": "admin" | |||
|
346 | }, | |||
|
347 | "comment_created_on": "2017-01-02T18:43:45.533", | |||
|
348 | "comment_f_path": null, | |||
|
349 | "comment_id": 25, | |||
|
350 | "comment_lineno": null, | |||
|
351 | "comment_status": { | |||
|
352 | "status": "under_review", | |||
|
353 | "status_lbl": "Under Review" | |||
|
354 | }, | |||
|
355 | "comment_text": "Example text", | |||
|
356 | "comment_type": null, | |||
|
357 | "pull_request_version": null | |||
|
358 | } | |||
|
359 | ], | |||
|
360 | error : null | |||
|
361 | """ | |||
|
362 | ||||
|
363 | pull_request = get_pull_request_or_error(pullrequestid) | |||
|
364 | if Optional.extract(repoid): | |||
|
365 | repo = get_repo_or_error(repoid) | |||
|
366 | else: | |||
|
367 | repo = pull_request.target_repo | |||
|
368 | ||||
|
369 | if not PullRequestModel().check_user_read( | |||
|
370 | pull_request, apiuser, api=True): | |||
|
371 | raise JSONRPCError('repository `%s` or pull request `%s` ' | |||
|
372 | 'does not exist' % (repoid, pullrequestid)) | |||
|
373 | ||||
|
374 | (pull_request_latest, | |||
|
375 | pull_request_at_ver, | |||
|
376 | pull_request_display_obj, | |||
|
377 | at_version) = PullRequestModel().get_pr_version( | |||
|
378 | pull_request.pull_request_id, version=None) | |||
|
379 | ||||
|
380 | versions = pull_request_display_obj.versions() | |||
|
381 | ver_map = { | |||
|
382 | ver.pull_request_version_id: cnt | |||
|
383 | for cnt, ver in enumerate(versions, 1) | |||
|
384 | } | |||
|
385 | ||||
|
386 | # GENERAL COMMENTS with versions # | |||
|
387 | q = CommentsModel()._all_general_comments_of_pull_request(pull_request) | |||
|
388 | q = q.order_by(ChangesetComment.comment_id.asc()) | |||
|
389 | general_comments = q.all() | |||
|
390 | ||||
|
391 | # INLINE COMMENTS with versions # | |||
|
392 | q = CommentsModel()._all_inline_comments_of_pull_request(pull_request) | |||
|
393 | q = q.order_by(ChangesetComment.comment_id.asc()) | |||
|
394 | inline_comments = q.all() | |||
|
395 | ||||
|
396 | data = [] | |||
|
397 | for comment in inline_comments + general_comments: | |||
|
398 | full_data = comment.get_api_data() | |||
|
399 | pr_version_id = None | |||
|
400 | if comment.pull_request_version_id: | |||
|
401 | pr_version_id = 'v{}'.format( | |||
|
402 | ver_map[comment.pull_request_version_id]) | |||
|
403 | ||||
|
404 | # sanitize some entries | |||
|
405 | ||||
|
406 | full_data['pull_request_version'] = pr_version_id | |||
|
407 | full_data['comment_author'] = { | |||
|
408 | 'username': full_data['comment_author'].username, | |||
|
409 | 'full_name_or_username': full_data['comment_author'].full_name_or_username, | |||
|
410 | 'active': full_data['comment_author'].active, | |||
|
411 | } | |||
|
412 | ||||
|
413 | if full_data['comment_status']: | |||
|
414 | full_data['comment_status'] = { | |||
|
415 | 'status': full_data['comment_status'][0].status, | |||
|
416 | 'status_lbl': full_data['comment_status'][0].status_lbl, | |||
|
417 | } | |||
|
418 | else: | |||
|
419 | full_data['comment_status'] = {} | |||
|
420 | ||||
|
421 | data.append(full_data) | |||
|
422 | return data | |||
|
423 | ||||
|
424 | ||||
|
425 | @jsonrpc_method() | |||
314 | def comment_pull_request( |
|
426 | def comment_pull_request( | |
315 |
request, apiuser, |
|
427 | request, apiuser, pullrequestid, repoid=Optional(None), | |
316 | commit_id=Optional(None), status=Optional(None), |
|
428 | message=Optional(None), commit_id=Optional(None), status=Optional(None), | |
317 | comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), |
|
429 | comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), | |
318 | resolves_comment_id=Optional(None), |
|
430 | resolves_comment_id=Optional(None), | |
319 | userid=Optional(OAttr('apiuser'))): |
|
431 | userid=Optional(OAttr('apiuser'))): | |
@@ -324,7 +436,7 b' def comment_pull_request(' | |||||
324 |
|
436 | |||
325 | :param apiuser: This is filled automatically from the |authtoken|. |
|
437 | :param apiuser: This is filled automatically from the |authtoken|. | |
326 | :type apiuser: AuthUser |
|
438 | :type apiuser: AuthUser | |
327 |
:param repoid: |
|
439 | :param repoid: Optional repository name or repository ID. | |
328 | :type repoid: str or int |
|
440 | :type repoid: str or int | |
329 | :param pullrequestid: The pull request ID. |
|
441 | :param pullrequestid: The pull request ID. | |
330 | :type pullrequestid: int |
|
442 | :type pullrequestid: int | |
@@ -356,7 +468,12 b' def comment_pull_request(' | |||||
356 | }, |
|
468 | }, | |
357 | error : null |
|
469 | error : null | |
358 | """ |
|
470 | """ | |
359 |
|
|
471 | pull_request = get_pull_request_or_error(pullrequestid) | |
|
472 | if Optional.extract(repoid): | |||
|
473 | repo = get_repo_or_error(repoid) | |||
|
474 | else: | |||
|
475 | repo = pull_request.target_repo | |||
|
476 | ||||
360 | if not isinstance(userid, Optional): |
|
477 | if not isinstance(userid, Optional): | |
361 | if (has_superadmin_permission(apiuser) or |
|
478 | if (has_superadmin_permission(apiuser) or | |
362 | HasRepoPermissionAnyApi('repository.admin')( |
|
479 | HasRepoPermissionAnyApi('repository.admin')( | |
@@ -365,7 +482,6 b' def comment_pull_request(' | |||||
365 | else: |
|
482 | else: | |
366 | raise JSONRPCError('userid is not the same as your user') |
|
483 | raise JSONRPCError('userid is not the same as your user') | |
367 |
|
484 | |||
368 | pull_request = get_pull_request_or_error(pullrequestid) |
|
|||
369 | if not PullRequestModel().check_user_read( |
|
485 | if not PullRequestModel().check_user_read( | |
370 | pull_request, apiuser, api=True): |
|
486 | pull_request, apiuser, api=True): | |
371 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) |
|
487 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) | |
@@ -573,15 +689,15 b' def create_pull_request(' | |||||
573 |
|
689 | |||
574 | @jsonrpc_method() |
|
690 | @jsonrpc_method() | |
575 | def update_pull_request( |
|
691 | def update_pull_request( | |
576 |
request, apiuser, |
|
692 | request, apiuser, pullrequestid, repoid=Optional(None), | |
577 | description=Optional(''), reviewers=Optional(None), |
|
693 | title=Optional(''), description=Optional(''), reviewers=Optional(None), | |
578 | update_commits=Optional(None)): |
|
694 | update_commits=Optional(None)): | |
579 | """ |
|
695 | """ | |
580 | Updates a pull request. |
|
696 | Updates a pull request. | |
581 |
|
697 | |||
582 | :param apiuser: This is filled automatically from the |authtoken|. |
|
698 | :param apiuser: This is filled automatically from the |authtoken|. | |
583 | :type apiuser: AuthUser |
|
699 | :type apiuser: AuthUser | |
584 |
:param repoid: |
|
700 | :param repoid: Optional repository name or repository ID. | |
585 | :type repoid: str or int |
|
701 | :type repoid: str or int | |
586 | :param pullrequestid: The pull request ID. |
|
702 | :param pullrequestid: The pull request ID. | |
587 | :type pullrequestid: int |
|
703 | :type pullrequestid: int | |
@@ -626,8 +742,12 b' def update_pull_request(' | |||||
626 | error : null |
|
742 | error : null | |
627 | """ |
|
743 | """ | |
628 |
|
744 | |||
629 | repo = get_repo_or_error(repoid) |
|
|||
630 | pull_request = get_pull_request_or_error(pullrequestid) |
|
745 | pull_request = get_pull_request_or_error(pullrequestid) | |
|
746 | if Optional.extract(repoid): | |||
|
747 | repo = get_repo_or_error(repoid) | |||
|
748 | else: | |||
|
749 | repo = pull_request.target_repo | |||
|
750 | ||||
631 | if not PullRequestModel().check_user_update( |
|
751 | if not PullRequestModel().check_user_update( | |
632 | pull_request, apiuser, api=True): |
|
752 | pull_request, apiuser, api=True): | |
633 | raise JSONRPCError( |
|
753 | raise JSONRPCError( | |
@@ -705,7 +825,7 b' def update_pull_request(' | |||||
705 |
|
825 | |||
706 | @jsonrpc_method() |
|
826 | @jsonrpc_method() | |
707 | def close_pull_request( |
|
827 | def close_pull_request( | |
708 |
request, apiuser, |
|
828 | request, apiuser, pullrequestid, repoid=Optional(None), | |
709 | userid=Optional(OAttr('apiuser')), message=Optional('')): |
|
829 | userid=Optional(OAttr('apiuser')), message=Optional('')): | |
710 | """ |
|
830 | """ | |
711 | Close the pull request specified by `pullrequestid`. |
|
831 | Close the pull request specified by `pullrequestid`. | |
@@ -738,7 +858,12 b' def close_pull_request(' | |||||
738 | """ |
|
858 | """ | |
739 | _ = request.translate |
|
859 | _ = request.translate | |
740 |
|
860 | |||
741 |
|
|
861 | pull_request = get_pull_request_or_error(pullrequestid) | |
|
862 | if Optional.extract(repoid): | |||
|
863 | repo = get_repo_or_error(repoid) | |||
|
864 | else: | |||
|
865 | repo = pull_request.target_repo | |||
|
866 | ||||
742 | if not isinstance(userid, Optional): |
|
867 | if not isinstance(userid, Optional): | |
743 | if (has_superadmin_permission(apiuser) or |
|
868 | if (has_superadmin_permission(apiuser) or | |
744 | HasRepoPermissionAnyApi('repository.admin')( |
|
869 | HasRepoPermissionAnyApi('repository.admin')( | |
@@ -747,8 +872,6 b' def close_pull_request(' | |||||
747 | else: |
|
872 | else: | |
748 | raise JSONRPCError('userid is not the same as your user') |
|
873 | raise JSONRPCError('userid is not the same as your user') | |
749 |
|
874 | |||
750 | pull_request = get_pull_request_or_error(pullrequestid) |
|
|||
751 |
|
||||
752 | if pull_request.is_closed(): |
|
875 | if pull_request.is_closed(): | |
753 | raise JSONRPCError( |
|
876 | raise JSONRPCError( | |
754 | 'pull request `%s` is already closed' % (pullrequestid,)) |
|
877 | 'pull request `%s` is already closed' % (pullrequestid,)) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -32,6 +32,7 b' from rhodecode.api.utils import (' | |||||
32 | from rhodecode.lib import audit_logger |
|
32 | from rhodecode.lib import audit_logger | |
33 | from rhodecode.lib import repo_maintenance |
|
33 | from rhodecode.lib import repo_maintenance | |
34 | from rhodecode.lib.auth import HasPermissionAnyApi, HasUserGroupPermissionAnyApi |
|
34 | from rhodecode.lib.auth import HasPermissionAnyApi, HasUserGroupPermissionAnyApi | |
|
35 | from rhodecode.lib.celerylib.utils import get_task_id | |||
35 | from rhodecode.lib.utils2 import str2bool, time_to_datetime |
|
36 | from rhodecode.lib.utils2 import str2bool, time_to_datetime | |
36 | from rhodecode.lib.ext_json import json |
|
37 | from rhodecode.lib.ext_json import json | |
37 | from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError |
|
38 | from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError | |
@@ -126,26 +127,6 b' def get_repo(request, apiuser, repoid, c' | |||||
126 | "lock_reason": null, |
|
127 | "lock_reason": null, | |
127 | "locked_by": null, |
|
128 | "locked_by": null, | |
128 | "locked_date": null, |
|
129 | "locked_date": null, | |
129 | "members": [ |
|
|||
130 | { |
|
|||
131 | "name": "super-admin-name", |
|
|||
132 | "origin": "super-admin", |
|
|||
133 | "permission": "repository.admin", |
|
|||
134 | "type": "user" |
|
|||
135 | }, |
|
|||
136 | { |
|
|||
137 | "name": "owner-name", |
|
|||
138 | "origin": "owner", |
|
|||
139 | "permission": "repository.admin", |
|
|||
140 | "type": "user" |
|
|||
141 | }, |
|
|||
142 | { |
|
|||
143 | "name": "user-group-name", |
|
|||
144 | "origin": "permission", |
|
|||
145 | "permission": "repository.write", |
|
|||
146 | "type": "user_group" |
|
|||
147 | } |
|
|||
148 | ], |
|
|||
149 | "owner": "owner-name", |
|
130 | "owner": "owner-name", | |
150 | "permissions": [ |
|
131 | "permissions": [ | |
151 | { |
|
132 | { | |
@@ -213,7 +194,6 b' def get_repo(request, apiuser, repoid, c' | |||||
213 | if not cache: |
|
194 | if not cache: | |
214 | repo.update_commit_cache() |
|
195 | repo.update_commit_cache() | |
215 | data = repo.get_api_data(include_secrets=include_secrets) |
|
196 | data = repo.get_api_data(include_secrets=include_secrets) | |
216 | data['members'] = permissions # TODO: this should be deprecated soon |
|
|||
217 | data['permissions'] = permissions |
|
197 | data['permissions'] = permissions | |
218 | data['followers'] = following_users |
|
198 | data['followers'] = following_users | |
219 | return data |
|
199 | return data | |
@@ -340,11 +320,7 b' def get_repo_changeset(request, apiuser,' | |||||
340 | _cs_json = cs.__json__() |
|
320 | _cs_json = cs.__json__() | |
341 | _cs_json['diff'] = build_commit_data(cs, changes_details) |
|
321 | _cs_json['diff'] = build_commit_data(cs, changes_details) | |
342 | if changes_details == 'full': |
|
322 | if changes_details == 'full': | |
343 |
_cs_json['refs'] = |
|
323 | _cs_json['refs'] = cs._get_refs() | |
344 | 'branches': [cs.branch], |
|
|||
345 | 'bookmarks': getattr(cs, 'bookmarks', []), |
|
|||
346 | 'tags': cs.tags |
|
|||
347 | } |
|
|||
348 | return _cs_json |
|
324 | return _cs_json | |
349 |
|
325 | |||
350 |
|
326 | |||
@@ -716,10 +692,7 b' def create_repo(' | |||||
716 | } |
|
692 | } | |
717 |
|
693 | |||
718 | task = RepoModel().create(form_data=data, cur_user=owner) |
|
694 | task = RepoModel().create(form_data=data, cur_user=owner) | |
719 | from celery.result import BaseAsyncResult |
|
695 | task_id = get_task_id(task) | |
720 | task_id = None |
|
|||
721 | if isinstance(task, BaseAsyncResult): |
|
|||
722 | task_id = task.task_id |
|
|||
723 | # no commit, it's done in RepoModel, or async via celery |
|
696 | # no commit, it's done in RepoModel, or async via celery | |
724 | return { |
|
697 | return { | |
725 | 'msg': "Created new repository `%s`" % (schema_data['repo_name'],), |
|
698 | 'msg': "Created new repository `%s`" % (schema_data['repo_name'],), | |
@@ -915,7 +888,8 b' def update_repo(' | |||||
915 | repo_enable_downloads=enable_downloads |
|
888 | repo_enable_downloads=enable_downloads | |
916 | if not isinstance(enable_downloads, Optional) else repo.enable_downloads) |
|
889 | if not isinstance(enable_downloads, Optional) else repo.enable_downloads) | |
917 |
|
890 | |||
918 |
ref_choices, _labels = ScmModel().get_repo_landing_revs( |
|
891 | ref_choices, _labels = ScmModel().get_repo_landing_revs( | |
|
892 | request.translate, repo=repo) | |||
919 |
|
893 | |||
920 | old_values = repo.get_api_data() |
|
894 | old_values = repo.get_api_data() | |
921 | schema = repo_schema.RepoSchema().bind( |
|
895 | schema = repo_schema.RepoSchema().bind( | |
@@ -1108,10 +1082,8 b' def fork_repo(request, apiuser, repoid, ' | |||||
1108 |
|
1082 | |||
1109 | task = RepoModel().create_fork(data, cur_user=owner) |
|
1083 | task = RepoModel().create_fork(data, cur_user=owner) | |
1110 | # no commit, it's done in RepoModel, or async via celery |
|
1084 | # no commit, it's done in RepoModel, or async via celery | |
1111 | from celery.result import BaseAsyncResult |
|
1085 | task_id = get_task_id(task) | |
1112 | task_id = None |
|
1086 | ||
1113 | if isinstance(task, BaseAsyncResult): |
|
|||
1114 | task_id = task.task_id |
|
|||
1115 | return { |
|
1087 | return { | |
1116 | 'msg': 'Created fork of `%s` as `%s`' % ( |
|
1088 | 'msg': 'Created fork of `%s` as `%s`' % ( | |
1117 | repo.repo_name, schema_data['repo_name']), |
|
1089 | repo.repo_name, schema_data['repo_name']), |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -63,7 +63,7 b' def get_repo_group(request, apiuser, rep' | |||||
63 | "group_description": "repo group description", |
|
63 | "group_description": "repo group description", | |
64 | "group_id": 14, |
|
64 | "group_id": 14, | |
65 | "group_name": "group name", |
|
65 | "group_name": "group name", | |
66 |
" |
|
66 | "permissions": [ | |
67 | { |
|
67 | { | |
68 | "name": "super-admin-username", |
|
68 | "name": "super-admin-username", | |
69 | "origin": "super-admin", |
|
69 | "origin": "super-admin", | |
@@ -119,7 +119,7 b' def get_repo_group(request, apiuser, rep' | |||||
119 | permissions.append(user_group_data) |
|
119 | permissions.append(user_group_data) | |
120 |
|
120 | |||
121 | data = repo_group.get_api_data() |
|
121 | data = repo_group.get_api_data() | |
122 | data["members"] = permissions # TODO: this should be named permissions |
|
122 | data["permissions"] = permissions | |
123 | return data |
|
123 | return data | |
124 |
|
124 | |||
125 |
|
125 | |||
@@ -221,7 +221,7 b' def create_repo_group(' | |||||
221 | repo_group = RepoGroupModel().create( |
|
221 | repo_group = RepoGroupModel().create( | |
222 | owner=owner, |
|
222 | owner=owner, | |
223 | group_name=validated_group_name, |
|
223 | group_name=validated_group_name, | |
224 |
group_description=schema_data['repo_group_n |
|
224 | group_description=schema_data['repo_group_description'], | |
225 | copy_permissions=schema_data['repo_group_copy_permissions']) |
|
225 | copy_permissions=schema_data['repo_group_copy_permissions']) | |
226 | Session().flush() |
|
226 | Session().flush() | |
227 |
|
227 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -79,7 +79,8 b' def get_user(request, apiuser, userid=Op' | |||||
79 | "last_login": "Timestamp", |
|
79 | "last_login": "Timestamp", | |
80 | "last_activity": "Timestamp", |
|
80 | "last_activity": "Timestamp", | |
81 | "lastname": "surnae", |
|
81 | "lastname": "surnae", | |
82 |
"permissions": |
|
82 | "permissions": <deprecated>, | |
|
83 | "permissions_summary": { | |||
83 | "global": [ |
|
84 | "global": [ | |
84 | "hg.inherit_default_perms.true", |
|
85 | "hg.inherit_default_perms.true", | |
85 | "usergroup.read", |
|
86 | "usergroup.read", | |
@@ -97,7 +98,7 b' def get_user(request, apiuser, userid=Op' | |||||
97 | "repositories": { "username/example": "repository.write"}, |
|
98 | "repositories": { "username/example": "repository.write"}, | |
98 | "repositories_groups": { "user-group/repo": "group.none" }, |
|
99 | "repositories_groups": { "user-group/repo": "group.none" }, | |
99 | "user_groups": { "user_group_name": "usergroup.read" } |
|
100 | "user_groups": { "user_group_name": "usergroup.read" } | |
100 |
} |
|
101 | } | |
101 | "user_id": 32, |
|
102 | "user_id": 32, | |
102 | "username": "username" |
|
103 | "username": "username" | |
103 | } |
|
104 | } | |
@@ -115,7 +116,9 b' def get_user(request, apiuser, userid=Op' | |||||
115 |
|
116 | |||
116 | user = get_user_or_error(userid) |
|
117 | user = get_user_or_error(userid) | |
117 | data = user.get_api_data(include_secrets=True) |
|
118 | data = user.get_api_data(include_secrets=True) | |
118 |
|
|
119 | permissions = AuthUser(user_id=user.user_id).permissions | |
|
120 | data['permissions'] = permissions # TODO(marcink): should be deprecated | |||
|
121 | data['permissions_summary'] = permissions | |||
119 | return data |
|
122 | return data | |
120 |
|
123 | |||
121 |
|
124 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -61,7 +61,7 b' def get_user_group(request, apiuser, use' | |||||
61 | "active": true, |
|
61 | "active": true, | |
62 | "group_description": "group description", |
|
62 | "group_description": "group description", | |
63 | "group_name": "group name", |
|
63 | "group_name": "group name", | |
64 |
" |
|
64 | "permissions": [ | |
65 | { |
|
65 | { | |
66 | "name": "owner-name", |
|
66 | "name": "owner-name", | |
67 | "origin": "owner", |
|
67 | "origin": "owner", | |
@@ -82,6 +82,12 b' def get_user_group(request, apiuser, use' | |||||
82 | "type": "user_group" |
|
82 | "type": "user_group" | |
83 | } |
|
83 | } | |
84 | ], |
|
84 | ], | |
|
85 | "permissions_summary": { | |||
|
86 | "repositories": { | |||
|
87 | "aa-root-level-repo-1": "repository.admin" | |||
|
88 | }, | |||
|
89 | "repositories_groups": {} | |||
|
90 | }, | |||
85 | "owner": "owner name", |
|
91 | "owner": "owner name", | |
86 | "users": [], |
|
92 | "users": [], | |
87 | "users_group_id": 2 |
|
93 | "users_group_id": 2 | |
@@ -119,8 +125,9 b' def get_user_group(request, apiuser, use' | |||||
119 | permissions.append(user_group_data) |
|
125 | permissions.append(user_group_data) | |
120 |
|
126 | |||
121 | data = user_group.get_api_data() |
|
127 | data = user_group.get_api_data() | |
122 |
data[ |
|
128 | data["permissions"] = permissions | |
123 |
|
129 | data["permissions_summary"] = UserGroupModel().get_perms_summary( | ||
|
130 | user_group.users_group_id) | |||
124 | return data |
|
131 | return data | |
125 |
|
132 | |||
126 |
|
133 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -147,46 +147,26 b' class BaseAppView(object):' | |||||
147 | % repo_name) |
|
147 | % repo_name) | |
148 | return msg |
|
148 | return msg | |
149 |
|
149 | |||
150 |
def _get_local_tmpl_context(self, include_app_defaults= |
|
150 | def _get_local_tmpl_context(self, include_app_defaults=True): | |
151 | c = TemplateArgs() |
|
151 | c = TemplateArgs() | |
152 | c.auth_user = self.request.user |
|
152 | c.auth_user = self.request.user | |
153 | # TODO(marcink): migrate the usage of c.rhodecode_user to c.auth_user |
|
153 | # TODO(marcink): migrate the usage of c.rhodecode_user to c.auth_user | |
154 | c.rhodecode_user = self.request.user |
|
154 | c.rhodecode_user = self.request.user | |
155 |
|
155 | |||
156 | if include_app_defaults: |
|
156 | if include_app_defaults: | |
157 | # NOTE(marcink): after full pyramid migration include_app_defaults |
|
|||
158 | # should be turned on by default |
|
|||
159 | from rhodecode.lib.base import attach_context_attributes |
|
157 | from rhodecode.lib.base import attach_context_attributes | |
160 | attach_context_attributes(c, self.request, self.request.user.user_id) |
|
158 | attach_context_attributes(c, self.request, self.request.user.user_id) | |
161 |
|
159 | |||
162 | return c |
|
160 | return c | |
163 |
|
161 | |||
164 |
def _ |
|
162 | def _get_template_context(self, tmpl_args, **kwargs): | |
165 | """ |
|
|||
166 | Registers attributes to pylons global `c` |
|
|||
167 | """ |
|
|||
168 |
|
||||
169 | # TODO(marcink): remove once pyramid migration is finished |
|
|||
170 | from pylons import tmpl_context as c |
|
|||
171 | try: |
|
|||
172 | for k, v in tmpl_args.items(): |
|
|||
173 | setattr(c, k, v) |
|
|||
174 | except TypeError: |
|
|||
175 | log.exception('Failed to register pylons C') |
|
|||
176 | pass |
|
|||
177 |
|
||||
178 | def _get_template_context(self, tmpl_args): |
|
|||
179 | self._register_global_c(tmpl_args) |
|
|||
180 |
|
163 | |||
181 | local_tmpl_args = { |
|
164 | local_tmpl_args = { | |
182 | 'defaults': {}, |
|
165 | 'defaults': {}, | |
183 | 'errors': {}, |
|
166 | 'errors': {}, | |
184 | # register a fake 'c' to be used in templates instead of global |
|
167 | 'c': tmpl_args | |
185 | # pylons c, after migration to pyramid we should rename it to 'c' |
|
|||
186 | # make sure we replace usage of _c in templates too |
|
|||
187 | '_c': tmpl_args |
|
|||
188 | } |
|
168 | } | |
189 |
local_tmpl_args.update( |
|
169 | local_tmpl_args.update(kwargs) | |
190 | return local_tmpl_args |
|
170 | return local_tmpl_args | |
191 |
|
171 | |||
192 | def load_default_context(self): |
|
172 | def load_default_context(self): | |
@@ -196,7 +176,7 b' class BaseAppView(object):' | |||||
196 | def load_default_context(self): |
|
176 | def load_default_context(self): | |
197 | c = self._get_local_tmpl_context() |
|
177 | c = self._get_local_tmpl_context() | |
198 | c.custom_var = 'foobar' |
|
178 | c.custom_var = 'foobar' | |
199 | self._register_global_c(c) |
|
179 | ||
200 | return c |
|
180 | return c | |
201 | """ |
|
181 | """ | |
202 | raise NotImplementedError('Needs implementation in view class') |
|
182 | raise NotImplementedError('Needs implementation in view class') | |
@@ -215,7 +195,7 b' class RepoAppView(BaseAppView):' | |||||
215 | 'Requirements are missing for repository %s: %s', |
|
195 | 'Requirements are missing for repository %s: %s', | |
216 | self.db_repo_name, error.message) |
|
196 | self.db_repo_name, error.message) | |
217 |
|
197 | |||
218 |
def _get_local_tmpl_context(self, include_app_defaults= |
|
198 | def _get_local_tmpl_context(self, include_app_defaults=True): | |
219 | _ = self.request.translate |
|
199 | _ = self.request.translate | |
220 | c = super(RepoAppView, self)._get_local_tmpl_context( |
|
200 | c = super(RepoAppView, self)._get_local_tmpl_context( | |
221 | include_app_defaults=include_app_defaults) |
|
201 | include_app_defaults=include_app_defaults) | |
@@ -338,7 +318,7 b' class BaseReferencesView(RepoAppView):' | |||||
338 | def load_default_context(self): |
|
318 | def load_default_context(self): | |
339 | c = self._get_local_tmpl_context() |
|
319 | c = self._get_local_tmpl_context() | |
340 |
|
320 | |||
341 | self._register_global_c(c) |
|
321 | ||
342 | return c |
|
322 | return c | |
343 |
|
323 | |||
344 | def load_refs_context(self, ref_items, partials_template): |
|
324 | def load_refs_context(self, ref_items, partials_template): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -19,9 +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.admin.navigation import NavigationRegistry |
|
22 | from rhodecode.apps._base import ADMIN_PREFIX | |
23 | from rhodecode.config.routing import ADMIN_PREFIX |
|
|||
24 | from rhodecode.lib.utils2 import str2bool |
|
|||
25 |
|
23 | |||
26 |
|
24 | |||
27 | def admin_routes(config): |
|
25 | def admin_routes(config): | |
@@ -72,8 +70,14 b' def admin_routes(config):' | |||||
72 | name='admin_settings_process_management', |
|
70 | name='admin_settings_process_management', | |
73 | pattern='/settings/process_management') |
|
71 | pattern='/settings/process_management') | |
74 | config.add_route( |
|
72 | config.add_route( | |
|
73 | name='admin_settings_process_management_data', | |||
|
74 | pattern='/settings/process_management/data') | |||
|
75 | config.add_route( | |||
75 | name='admin_settings_process_management_signal', |
|
76 | name='admin_settings_process_management_signal', | |
76 | pattern='/settings/process_management/signal') |
|
77 | pattern='/settings/process_management/signal') | |
|
78 | config.add_route( | |||
|
79 | name='admin_settings_process_management_master_signal', | |||
|
80 | pattern='/settings/process_management/master_signal') | |||
77 |
|
81 | |||
78 | # default settings |
|
82 | # default settings | |
79 | config.add_route( |
|
83 | config.add_route( | |
@@ -83,6 +87,88 b' def admin_routes(config):' | |||||
83 | name='admin_defaults_repositories_update', |
|
87 | name='admin_defaults_repositories_update', | |
84 | pattern='/defaults/repositories/update') |
|
88 | pattern='/defaults/repositories/update') | |
85 |
|
89 | |||
|
90 | # admin settings | |||
|
91 | ||||
|
92 | config.add_route( | |||
|
93 | name='admin_settings', | |||
|
94 | pattern='/settings') | |||
|
95 | config.add_route( | |||
|
96 | name='admin_settings_update', | |||
|
97 | pattern='/settings/update') | |||
|
98 | ||||
|
99 | config.add_route( | |||
|
100 | name='admin_settings_global', | |||
|
101 | pattern='/settings/global') | |||
|
102 | config.add_route( | |||
|
103 | name='admin_settings_global_update', | |||
|
104 | pattern='/settings/global/update') | |||
|
105 | ||||
|
106 | config.add_route( | |||
|
107 | name='admin_settings_vcs', | |||
|
108 | pattern='/settings/vcs') | |||
|
109 | config.add_route( | |||
|
110 | name='admin_settings_vcs_update', | |||
|
111 | pattern='/settings/vcs/update') | |||
|
112 | config.add_route( | |||
|
113 | name='admin_settings_vcs_svn_pattern_delete', | |||
|
114 | pattern='/settings/vcs/svn_pattern_delete') | |||
|
115 | ||||
|
116 | config.add_route( | |||
|
117 | name='admin_settings_mapping', | |||
|
118 | pattern='/settings/mapping') | |||
|
119 | config.add_route( | |||
|
120 | name='admin_settings_mapping_update', | |||
|
121 | pattern='/settings/mapping/update') | |||
|
122 | ||||
|
123 | config.add_route( | |||
|
124 | name='admin_settings_visual', | |||
|
125 | pattern='/settings/visual') | |||
|
126 | config.add_route( | |||
|
127 | name='admin_settings_visual_update', | |||
|
128 | pattern='/settings/visual/update') | |||
|
129 | ||||
|
130 | ||||
|
131 | config.add_route( | |||
|
132 | name='admin_settings_issuetracker', | |||
|
133 | pattern='/settings/issue-tracker') | |||
|
134 | config.add_route( | |||
|
135 | name='admin_settings_issuetracker_update', | |||
|
136 | pattern='/settings/issue-tracker/update') | |||
|
137 | config.add_route( | |||
|
138 | name='admin_settings_issuetracker_test', | |||
|
139 | pattern='/settings/issue-tracker/test') | |||
|
140 | config.add_route( | |||
|
141 | name='admin_settings_issuetracker_delete', | |||
|
142 | pattern='/settings/issue-tracker/delete') | |||
|
143 | ||||
|
144 | config.add_route( | |||
|
145 | name='admin_settings_email', | |||
|
146 | pattern='/settings/email') | |||
|
147 | config.add_route( | |||
|
148 | name='admin_settings_email_update', | |||
|
149 | pattern='/settings/email/update') | |||
|
150 | ||||
|
151 | config.add_route( | |||
|
152 | name='admin_settings_hooks', | |||
|
153 | pattern='/settings/hooks') | |||
|
154 | config.add_route( | |||
|
155 | name='admin_settings_hooks_update', | |||
|
156 | pattern='/settings/hooks/update') | |||
|
157 | config.add_route( | |||
|
158 | name='admin_settings_hooks_delete', | |||
|
159 | pattern='/settings/hooks/delete') | |||
|
160 | ||||
|
161 | config.add_route( | |||
|
162 | name='admin_settings_search', | |||
|
163 | pattern='/settings/search') | |||
|
164 | ||||
|
165 | config.add_route( | |||
|
166 | name='admin_settings_labs', | |||
|
167 | pattern='/settings/labs') | |||
|
168 | config.add_route( | |||
|
169 | name='admin_settings_labs_update', | |||
|
170 | pattern='/settings/labs/update') | |||
|
171 | ||||
86 | # global permissions |
|
172 | # global permissions | |
87 |
|
173 | |||
88 | config.add_route( |
|
174 | config.add_route( | |
@@ -237,7 +323,7 b' def admin_routes(config):' | |||||
237 | config.add_route( |
|
323 | config.add_route( | |
238 | name='edit_user_ips_delete', |
|
324 | name='edit_user_ips_delete', | |
239 | pattern='/users/{user_id:\d+}/edit/ips/delete', |
|
325 | pattern='/users/{user_id:\d+}/edit/ips/delete', | |
240 | user_route_with_default=True) # enabled for default user too |
|
326 | user_route_with_default=True) # enabled for default user too | |
241 |
|
327 | |||
242 | # user perms |
|
328 | # user perms | |
243 | config.add_route( |
|
329 | config.add_route( | |
@@ -310,12 +396,10 b' def admin_routes(config):' | |||||
310 |
|
396 | |||
311 |
|
397 | |||
312 | def includeme(config): |
|
398 | def includeme(config): | |
313 | settings = config.get_settings() |
|
399 | from rhodecode.apps.admin.navigation import includeme as nav_includeme | |
314 |
|
400 | |||
315 | # Create admin navigation registry and add it to the pyramid registry. |
|
401 | # Create admin navigation registry and add it to the pyramid registry. | |
316 | labs_active = str2bool(settings.get('labs_settings_active', False)) |
|
402 | nav_includeme(config) | |
317 | navigation_registry = NavigationRegistry(labs_active=labs_active) |
|
|||
318 | config.registry.registerUtility(navigation_registry) |
|
|||
319 |
|
403 | |||
320 | # main admin routes |
|
404 | # main admin routes | |
321 | config.add_route(name='admin_home', pattern=ADMIN_PREFIX) |
|
405 | config.add_route(name='admin_home', pattern=ADMIN_PREFIX) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -25,13 +25,14 b' import collections' | |||||
25 | from zope.interface import implementer |
|
25 | from zope.interface import implementer | |
26 |
|
26 | |||
27 | from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry |
|
27 | from rhodecode.apps.admin.interfaces import IAdminNavigationRegistry | |
28 |
from rhodecode.lib.utils import |
|
28 | from rhodecode.lib.utils2 import str2bool | |
29 | from rhodecode.translation import _ |
|
29 | from rhodecode.translation import _ | |
30 |
|
30 | |||
31 |
|
31 | |||
32 | log = logging.getLogger(__name__) |
|
32 | log = logging.getLogger(__name__) | |
33 |
|
33 | |||
34 |
NavListEntry = collections.namedtuple( |
|
34 | NavListEntry = collections.namedtuple( | |
|
35 | 'NavListEntry', ['key', 'name', 'url', 'active_list']) | |||
35 |
|
36 | |||
36 |
|
37 | |||
37 | class NavEntry(object): |
|
38 | class NavEntry(object): | |
@@ -41,77 +42,69 b' class NavEntry(object):' | |||||
41 | :param key: Unique identifier used to store reference in an OrderedDict. |
|
42 | :param key: Unique identifier used to store reference in an OrderedDict. | |
42 | :param name: Display name, usually a translation string. |
|
43 | :param name: Display name, usually a translation string. | |
43 | :param view_name: Name of the view, used generate the URL. |
|
44 | :param view_name: Name of the view, used generate the URL. | |
44 | :param pyramid: Indicator to use pyramid for URL generation. This should |
|
45 | :param active_list: list of urls that we select active for this element | |
45 | be removed as soon as we are fully migrated to pyramid. |
|
|||
46 | """ |
|
46 | """ | |
47 |
|
47 | |||
48 |
def __init__(self, key, name, view_name, |
|
48 | def __init__(self, key, name, view_name, active_list=None): | |
49 | self.key = key |
|
49 | self.key = key | |
50 | self.name = name |
|
50 | self.name = name | |
51 | self.view_name = view_name |
|
51 | self.view_name = view_name | |
52 | self.pyramid = pyramid |
|
52 | self._active_list = active_list or [] | |
53 |
|
53 | |||
54 | def generate_url(self, request): |
|
54 | def generate_url(self, request): | |
55 | if self.pyramid: |
|
55 | return request.route_path(self.view_name) | |
56 | if hasattr(request, 'route_path'): |
|
|||
57 | return request.route_path(self.view_name) |
|
|||
58 | else: |
|
|||
59 | # TODO: johbo: Remove this after migrating to pyramid. |
|
|||
60 | # We need the pyramid request here to generate URLs to pyramid |
|
|||
61 | # views from within pylons views. |
|
|||
62 | from pyramid.threadlocal import get_current_request |
|
|||
63 | pyramid_request = get_current_request() |
|
|||
64 | return pyramid_request.route_path(self.view_name) |
|
|||
65 | else: |
|
|||
66 | from pylons import url |
|
|||
67 | return url(self.view_name) |
|
|||
68 |
|
56 | |||
69 | def get_localized_name(self, request): |
|
57 | def get_localized_name(self, request): | |
70 |
|
|
58 | return request.translate(self.name) | |
71 | return request.translate(self.name) |
|
59 | ||
72 | else: |
|
60 | @property | |
73 | # TODO(marcink): Remove this after migrating to pyramid |
|
61 | def active_list(self): | |
74 | from pyramid.threadlocal import get_current_request |
|
62 | active_list = [self.key] | |
75 | pyramid_request = get_current_request() |
|
63 | if self._active_list: | |
76 | return pyramid_request.translate(self.name) |
|
64 | active_list = self._active_list | |
|
65 | return active_list | |||
77 |
|
66 | |||
78 |
|
67 | |||
79 | @implementer(IAdminNavigationRegistry) |
|
68 | @implementer(IAdminNavigationRegistry) | |
80 | class NavigationRegistry(object): |
|
69 | class NavigationRegistry(object): | |
81 |
|
70 | |||
82 | _base_entries = [ |
|
71 | _base_entries = [ | |
83 |
NavEntry('global', _('Global'), |
|
72 | NavEntry('global', _('Global'), | |
84 | NavEntry('vcs', _('VCS'), 'admin_settings_vcs'), |
|
73 | 'admin_settings_global'), | |
85 |
NavEntry('v |
|
74 | NavEntry('vcs', _('VCS'), | |
86 | NavEntry('mapping', _('Remap and Rescan'), 'admin_settings_mapping'), |
|
75 | 'admin_settings_vcs'), | |
|
76 | NavEntry('visual', _('Visual'), | |||
|
77 | 'admin_settings_visual'), | |||
|
78 | NavEntry('mapping', _('Remap and Rescan'), | |||
|
79 | 'admin_settings_mapping'), | |||
87 | NavEntry('issuetracker', _('Issue Tracker'), |
|
80 | NavEntry('issuetracker', _('Issue Tracker'), | |
88 | 'admin_settings_issuetracker'), |
|
81 | 'admin_settings_issuetracker'), | |
89 |
NavEntry('email', _('Email'), |
|
82 | NavEntry('email', _('Email'), | |
90 | NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'), |
|
83 | 'admin_settings_email'), | |
91 | NavEntry('search', _('Full Text Search'), 'admin_settings_search'), |
|
84 | NavEntry('hooks', _('Hooks'), | |
92 |
|
85 | 'admin_settings_hooks'), | ||
|
86 | NavEntry('search', _('Full Text Search'), | |||
|
87 | 'admin_settings_search'), | |||
93 | NavEntry('integrations', _('Integrations'), |
|
88 | NavEntry('integrations', _('Integrations'), | |
94 |
'global_integrations_home' |
|
89 | 'global_integrations_home'), | |
95 | NavEntry('system', _('System Info'), |
|
90 | NavEntry('system', _('System Info'), | |
96 |
'admin_settings_system' |
|
91 | 'admin_settings_system'), | |
97 | NavEntry('process_management', _('Processes'), |
|
92 | NavEntry('process_management', _('Processes'), | |
98 |
'admin_settings_process_management' |
|
93 | 'admin_settings_process_management'), | |
99 | NavEntry('sessions', _('User Sessions'), |
|
94 | NavEntry('sessions', _('User Sessions'), | |
100 |
'admin_settings_sessions' |
|
95 | 'admin_settings_sessions'), | |
101 | NavEntry('open_source', _('Open Source Licenses'), |
|
96 | NavEntry('open_source', _('Open Source Licenses'), | |
102 |
'admin_settings_open_source' |
|
97 | 'admin_settings_open_source'), | |
103 |
|
98 | |||
104 | # TODO: marcink: we disable supervisor now until the supervisor stats |
|
|||
105 | # page is fixed in the nix configuration |
|
|||
106 | # NavEntry('supervisor', _('Supervisor'), 'admin_settings_supervisor'), |
|
|||
107 | ] |
|
99 | ] | |
108 |
|
100 | |||
109 |
_labs_entry = NavEntry('labs', _('Labs'), |
|
101 | _labs_entry = NavEntry('labs', _('Labs'), | |
|
102 | 'admin_settings_labs') | |||
110 |
|
103 | |||
111 | def __init__(self, labs_active=False): |
|
104 | def __init__(self, labs_active=False): | |
112 |
self._registered_entries = collections.OrderedDict( |
|
105 | self._registered_entries = collections.OrderedDict() | |
113 |
|
|
106 | for item in self.__class__._base_entries: | |
114 | ]) |
|
107 | self._registered_entries[item.key] = item | |
115 |
|
108 | |||
116 | if labs_active: |
|
109 | if labs_active: | |
117 | self.add_entry(self._labs_entry) |
|
110 | self.add_entry(self._labs_entry) | |
@@ -121,16 +114,16 b' class NavigationRegistry(object):' | |||||
121 |
|
114 | |||
122 | def get_navlist(self, request): |
|
115 | def get_navlist(self, request): | |
123 | navlist = [NavListEntry(i.key, i.get_localized_name(request), |
|
116 | navlist = [NavListEntry(i.key, i.get_localized_name(request), | |
124 | i.generate_url(request)) |
|
117 | i.generate_url(request), i.active_list) | |
125 | for i in self._registered_entries.values()] |
|
118 | for i in self._registered_entries.values()] | |
126 | return navlist |
|
119 | return navlist | |
127 |
|
120 | |||
128 |
|
121 | |||
129 | def navigation_registry(request): |
|
122 | def navigation_registry(request, registry=None): | |
130 | """ |
|
123 | """ | |
131 | Helper that returns the admin navigation registry. |
|
124 | Helper that returns the admin navigation registry. | |
132 | """ |
|
125 | """ | |
133 |
pyramid_registry = |
|
126 | pyramid_registry = registry or request.registry | |
134 | nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry) |
|
127 | nav_registry = pyramid_registry.queryUtility(IAdminNavigationRegistry) | |
135 | return nav_registry |
|
128 | return nav_registry | |
136 |
|
129 | |||
@@ -140,3 +133,11 b' def navigation_list(request):' | |||||
140 | Helper that returns the admin navigation as list of NavListEntry objects. |
|
133 | Helper that returns the admin navigation as list of NavListEntry objects. | |
141 | """ |
|
134 | """ | |
142 | return navigation_registry(request).get_navlist(request) |
|
135 | return navigation_registry(request).get_navlist(request) | |
|
136 | ||||
|
137 | ||||
|
138 | def includeme(config): | |||
|
139 | # Create admin navigation registry and add it to the pyramid registry. | |||
|
140 | settings = config.get_settings() | |||
|
141 | labs_active = str2bool(settings.get('labs_settings_active', False)) | |||
|
142 | navigation_registry = NavigationRegistry(labs_active=labs_active) | |||
|
143 | config.registry.registerUtility(navigation_registry) No newline at end of file |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -46,10 +46,11 b' def route_path(name, params=None, **kwar' | |||||
46 | return base_url |
|
46 | return base_url | |
47 |
|
47 | |||
48 |
|
48 | |||
49 | class TestAdminController(TestController): |
|
49 | @pytest.mark.usefixtures('app') | |
|
50 | class TestAdminController(object): | |||
50 |
|
51 | |||
51 | @pytest.fixture(scope='class', autouse=True) |
|
52 | @pytest.fixture(scope='class', autouse=True) | |
52 |
def prepare(self, request, |
|
53 | def prepare(self, request, baseapp): | |
53 | UserLog.query().delete() |
|
54 | UserLog.query().delete() | |
54 | Session().commit() |
|
55 | Session().commit() | |
55 |
|
56 | |||
@@ -84,104 +85,87 b' class TestAdminController(TestController' | |||||
84 | UserLog.query().delete() |
|
85 | UserLog.query().delete() | |
85 | Session().commit() |
|
86 | Session().commit() | |
86 |
|
87 | |||
87 | def test_index(self): |
|
88 | def test_index(self, autologin_user): | |
88 | self.log_user() |
|
|||
89 | response = self.app.get(route_path('admin_audit_logs')) |
|
89 | response = self.app.get(route_path('admin_audit_logs')) | |
90 | response.mustcontain('Admin audit logs') |
|
90 | response.mustcontain('Admin audit logs') | |
91 |
|
91 | |||
92 | def test_filter_all_entries(self): |
|
92 | def test_filter_all_entries(self, autologin_user): | |
93 | self.log_user() |
|
|||
94 | response = self.app.get(route_path('admin_audit_logs')) |
|
93 | response = self.app.get(route_path('admin_audit_logs')) | |
95 | all_count = UserLog.query().count() |
|
94 | all_count = UserLog.query().count() | |
96 | response.mustcontain('%s entries' % all_count) |
|
95 | response.mustcontain('%s entries' % all_count) | |
97 |
|
96 | |||
98 | def test_filter_journal_filter_exact_match_on_repository(self): |
|
97 | def test_filter_journal_filter_exact_match_on_repository(self, autologin_user): | |
99 | self.log_user() |
|
|||
100 | response = self.app.get(route_path('admin_audit_logs', |
|
98 | response = self.app.get(route_path('admin_audit_logs', | |
101 | params=dict(filter='repository:rhodecode'))) |
|
99 | params=dict(filter='repository:rhodecode'))) | |
102 | response.mustcontain('3 entries') |
|
100 | response.mustcontain('3 entries') | |
103 |
|
101 | |||
104 | def test_filter_journal_filter_exact_match_on_repository_CamelCase(self): |
|
102 | def test_filter_journal_filter_exact_match_on_repository_CamelCase(self, autologin_user): | |
105 | self.log_user() |
|
|||
106 | response = self.app.get(route_path('admin_audit_logs', |
|
103 | response = self.app.get(route_path('admin_audit_logs', | |
107 | params=dict(filter='repository:RhodeCode'))) |
|
104 | params=dict(filter='repository:RhodeCode'))) | |
108 | response.mustcontain('3 entries') |
|
105 | response.mustcontain('3 entries') | |
109 |
|
106 | |||
110 | def test_filter_journal_filter_wildcard_on_repository(self): |
|
107 | def test_filter_journal_filter_wildcard_on_repository(self, autologin_user): | |
111 | self.log_user() |
|
|||
112 | response = self.app.get(route_path('admin_audit_logs', |
|
108 | response = self.app.get(route_path('admin_audit_logs', | |
113 | params=dict(filter='repository:*test*'))) |
|
109 | params=dict(filter='repository:*test*'))) | |
114 | response.mustcontain('862 entries') |
|
110 | response.mustcontain('862 entries') | |
115 |
|
111 | |||
116 | def test_filter_journal_filter_prefix_on_repository(self): |
|
112 | def test_filter_journal_filter_prefix_on_repository(self, autologin_user): | |
117 | self.log_user() |
|
|||
118 | response = self.app.get(route_path('admin_audit_logs', |
|
113 | response = self.app.get(route_path('admin_audit_logs', | |
119 | params=dict(filter='repository:test*'))) |
|
114 | params=dict(filter='repository:test*'))) | |
120 | response.mustcontain('257 entries') |
|
115 | response.mustcontain('257 entries') | |
121 |
|
116 | |||
122 | def test_filter_journal_filter_prefix_on_repository_CamelCase(self): |
|
117 | def test_filter_journal_filter_prefix_on_repository_CamelCase(self, autologin_user): | |
123 | self.log_user() |
|
|||
124 | response = self.app.get(route_path('admin_audit_logs', |
|
118 | response = self.app.get(route_path('admin_audit_logs', | |
125 | params=dict(filter='repository:Test*'))) |
|
119 | params=dict(filter='repository:Test*'))) | |
126 | response.mustcontain('257 entries') |
|
120 | response.mustcontain('257 entries') | |
127 |
|
121 | |||
128 | def test_filter_journal_filter_prefix_on_repository_and_user(self): |
|
122 | def test_filter_journal_filter_prefix_on_repository_and_user(self, autologin_user): | |
129 | self.log_user() |
|
|||
130 | response = self.app.get(route_path('admin_audit_logs', |
|
123 | response = self.app.get(route_path('admin_audit_logs', | |
131 | params=dict(filter='repository:test* AND username:demo'))) |
|
124 | params=dict(filter='repository:test* AND username:demo'))) | |
132 | response.mustcontain('130 entries') |
|
125 | response.mustcontain('130 entries') | |
133 |
|
126 | |||
134 | def test_filter_journal_filter_prefix_on_repository_or_target_repo(self): |
|
127 | def test_filter_journal_filter_prefix_on_repository_or_target_repo(self, autologin_user): | |
135 | self.log_user() |
|
|||
136 | response = self.app.get(route_path('admin_audit_logs', |
|
128 | response = self.app.get(route_path('admin_audit_logs', | |
137 | params=dict(filter='repository:test* OR repository:rhodecode'))) |
|
129 | params=dict(filter='repository:test* OR repository:rhodecode'))) | |
138 | response.mustcontain('260 entries') # 257 + 3 |
|
130 | response.mustcontain('260 entries') # 257 + 3 | |
139 |
|
131 | |||
140 | def test_filter_journal_filter_exact_match_on_username(self): |
|
132 | def test_filter_journal_filter_exact_match_on_username(self, autologin_user): | |
141 | self.log_user() |
|
|||
142 | response = self.app.get(route_path('admin_audit_logs', |
|
133 | response = self.app.get(route_path('admin_audit_logs', | |
143 | params=dict(filter='username:demo'))) |
|
134 | params=dict(filter='username:demo'))) | |
144 | response.mustcontain('1087 entries') |
|
135 | response.mustcontain('1087 entries') | |
145 |
|
136 | |||
146 | def test_filter_journal_filter_exact_match_on_username_camelCase(self): |
|
137 | def test_filter_journal_filter_exact_match_on_username_camelCase(self, autologin_user): | |
147 | self.log_user() |
|
|||
148 | response = self.app.get(route_path('admin_audit_logs', |
|
138 | response = self.app.get(route_path('admin_audit_logs', | |
149 | params=dict(filter='username:DemO'))) |
|
139 | params=dict(filter='username:DemO'))) | |
150 | response.mustcontain('1087 entries') |
|
140 | response.mustcontain('1087 entries') | |
151 |
|
141 | |||
152 | def test_filter_journal_filter_wildcard_on_username(self): |
|
142 | def test_filter_journal_filter_wildcard_on_username(self, autologin_user): | |
153 | self.log_user() |
|
|||
154 | response = self.app.get(route_path('admin_audit_logs', |
|
143 | response = self.app.get(route_path('admin_audit_logs', | |
155 | params=dict(filter='username:*test*'))) |
|
144 | params=dict(filter='username:*test*'))) | |
156 | entries_count = UserLog.query().filter(UserLog.username.ilike('%test%')).count() |
|
145 | entries_count = UserLog.query().filter(UserLog.username.ilike('%test%')).count() | |
157 | response.mustcontain('{} entries'.format(entries_count)) |
|
146 | response.mustcontain('{} entries'.format(entries_count)) | |
158 |
|
147 | |||
159 | def test_filter_journal_filter_prefix_on_username(self): |
|
148 | def test_filter_journal_filter_prefix_on_username(self, autologin_user): | |
160 | self.log_user() |
|
|||
161 | response = self.app.get(route_path('admin_audit_logs', |
|
149 | response = self.app.get(route_path('admin_audit_logs', | |
162 | params=dict(filter='username:demo*'))) |
|
150 | params=dict(filter='username:demo*'))) | |
163 | response.mustcontain('1101 entries') |
|
151 | response.mustcontain('1101 entries') | |
164 |
|
152 | |||
165 | def test_filter_journal_filter_prefix_on_user_or_other_user(self): |
|
153 | def test_filter_journal_filter_prefix_on_user_or_other_user(self, autologin_user): | |
166 | self.log_user() |
|
|||
167 | response = self.app.get(route_path('admin_audit_logs', |
|
154 | response = self.app.get(route_path('admin_audit_logs', | |
168 | params=dict(filter='username:demo OR username:volcan'))) |
|
155 | params=dict(filter='username:demo OR username:volcan'))) | |
169 | response.mustcontain('1095 entries') # 1087 + 8 |
|
156 | response.mustcontain('1095 entries') # 1087 + 8 | |
170 |
|
157 | |||
171 | def test_filter_journal_filter_wildcard_on_action(self): |
|
158 | def test_filter_journal_filter_wildcard_on_action(self, autologin_user): | |
172 | self.log_user() |
|
|||
173 | response = self.app.get(route_path('admin_audit_logs', |
|
159 | response = self.app.get(route_path('admin_audit_logs', | |
174 | params=dict(filter='action:*pull_request*'))) |
|
160 | params=dict(filter='action:*pull_request*'))) | |
175 | response.mustcontain('187 entries') |
|
161 | response.mustcontain('187 entries') | |
176 |
|
162 | |||
177 | def test_filter_journal_filter_on_date(self): |
|
163 | def test_filter_journal_filter_on_date(self, autologin_user): | |
178 | self.log_user() |
|
|||
179 | response = self.app.get(route_path('admin_audit_logs', |
|
164 | response = self.app.get(route_path('admin_audit_logs', | |
180 | params=dict(filter='date:20121010'))) |
|
165 | params=dict(filter='date:20121010'))) | |
181 | response.mustcontain('47 entries') |
|
166 | response.mustcontain('47 entries') | |
182 |
|
167 | |||
183 | def test_filter_journal_filter_on_date_2(self): |
|
168 | def test_filter_journal_filter_on_date_2(self, autologin_user): | |
184 | self.log_user() |
|
|||
185 | response = self.app.get(route_path('admin_audit_logs', |
|
169 | response = self.app.get(route_path('admin_audit_logs', | |
186 | params=dict(filter='date:20121020'))) |
|
170 | params=dict(filter='date:20121020'))) | |
187 | response.mustcontain('17 entries') |
|
171 | response.mustcontain('17 entries') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -32,7 +32,7 b' def assert_auth_settings_updated(respons' | |||||
32 |
|
32 | |||
33 |
|
33 | |||
34 | @pytest.mark.usefixtures("autologin_user", "app") |
|
34 | @pytest.mark.usefixtures("autologin_user", "app") | |
35 |
class TestAuthSettings |
|
35 | class TestAuthSettingsView(object): | |
36 |
|
36 | |||
37 | def _enable_plugins(self, plugins_list, csrf_token, override=None, |
|
37 | def _enable_plugins(self, plugins_list, csrf_token, override=None, | |
38 | verify_response=False): |
|
38 | verify_response=False): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -22,17 +22,88 b' import mock' | |||||
22 | import pytest |
|
22 | import pytest | |
23 |
|
23 | |||
24 | import rhodecode |
|
24 | import rhodecode | |
25 |
from rhodecode. |
|
25 | from rhodecode.apps._base import ADMIN_PREFIX | |
26 | from rhodecode.lib.utils2 import md5 |
|
26 | from rhodecode.lib.utils2 import md5 | |
27 | from rhodecode.model.db import RhodeCodeUi |
|
27 | from rhodecode.model.db import RhodeCodeUi | |
28 | from rhodecode.model.meta import Session |
|
28 | from rhodecode.model.meta import Session | |
29 | from rhodecode.model.settings import SettingsModel, IssueTrackerSettingsModel |
|
29 | from rhodecode.model.settings import SettingsModel, IssueTrackerSettingsModel | |
30 |
from rhodecode.tests import |
|
30 | from rhodecode.tests import assert_session_flash | |
31 | from rhodecode.tests.utils import AssertResponse |
|
31 | from rhodecode.tests.utils import AssertResponse | |
32 |
|
32 | |||
33 |
|
33 | |||
34 | UPDATE_DATA_QUALNAME = ( |
|
34 | UPDATE_DATA_QUALNAME = 'rhodecode.model.update.UpdateModel.get_update_data' | |
35 | 'rhodecode.apps.admin.views.system_info.AdminSystemInfoSettingsView.get_update_data') |
|
35 | ||
|
36 | ||||
|
37 | def route_path(name, params=None, **kwargs): | |||
|
38 | import urllib | |||
|
39 | from rhodecode.apps._base import ADMIN_PREFIX | |||
|
40 | ||||
|
41 | base_url = { | |||
|
42 | ||||
|
43 | 'admin_settings': | |||
|
44 | ADMIN_PREFIX +'/settings', | |||
|
45 | 'admin_settings_update': | |||
|
46 | ADMIN_PREFIX + '/settings/update', | |||
|
47 | 'admin_settings_global': | |||
|
48 | ADMIN_PREFIX + '/settings/global', | |||
|
49 | 'admin_settings_global_update': | |||
|
50 | ADMIN_PREFIX + '/settings/global/update', | |||
|
51 | 'admin_settings_vcs': | |||
|
52 | ADMIN_PREFIX + '/settings/vcs', | |||
|
53 | 'admin_settings_vcs_update': | |||
|
54 | ADMIN_PREFIX + '/settings/vcs/update', | |||
|
55 | 'admin_settings_vcs_svn_pattern_delete': | |||
|
56 | ADMIN_PREFIX + '/settings/vcs/svn_pattern_delete', | |||
|
57 | 'admin_settings_mapping': | |||
|
58 | ADMIN_PREFIX + '/settings/mapping', | |||
|
59 | 'admin_settings_mapping_update': | |||
|
60 | ADMIN_PREFIX + '/settings/mapping/update', | |||
|
61 | 'admin_settings_visual': | |||
|
62 | ADMIN_PREFIX + '/settings/visual', | |||
|
63 | 'admin_settings_visual_update': | |||
|
64 | ADMIN_PREFIX + '/settings/visual/update', | |||
|
65 | 'admin_settings_issuetracker': | |||
|
66 | ADMIN_PREFIX + '/settings/issue-tracker', | |||
|
67 | 'admin_settings_issuetracker_update': | |||
|
68 | ADMIN_PREFIX + '/settings/issue-tracker/update', | |||
|
69 | 'admin_settings_issuetracker_test': | |||
|
70 | ADMIN_PREFIX + '/settings/issue-tracker/test', | |||
|
71 | 'admin_settings_issuetracker_delete': | |||
|
72 | ADMIN_PREFIX + '/settings/issue-tracker/delete', | |||
|
73 | 'admin_settings_email': | |||
|
74 | ADMIN_PREFIX + '/settings/email', | |||
|
75 | 'admin_settings_email_update': | |||
|
76 | ADMIN_PREFIX + '/settings/email/update', | |||
|
77 | 'admin_settings_hooks': | |||
|
78 | ADMIN_PREFIX + '/settings/hooks', | |||
|
79 | 'admin_settings_hooks_update': | |||
|
80 | ADMIN_PREFIX + '/settings/hooks/update', | |||
|
81 | 'admin_settings_hooks_delete': | |||
|
82 | ADMIN_PREFIX + '/settings/hooks/delete', | |||
|
83 | 'admin_settings_search': | |||
|
84 | ADMIN_PREFIX + '/settings/search', | |||
|
85 | 'admin_settings_labs': | |||
|
86 | ADMIN_PREFIX + '/settings/labs', | |||
|
87 | 'admin_settings_labs_update': | |||
|
88 | ADMIN_PREFIX + '/settings/labs/update', | |||
|
89 | ||||
|
90 | 'admin_settings_sessions': | |||
|
91 | ADMIN_PREFIX + '/settings/sessions', | |||
|
92 | 'admin_settings_sessions_cleanup': | |||
|
93 | ADMIN_PREFIX + '/settings/sessions/cleanup', | |||
|
94 | 'admin_settings_system': | |||
|
95 | ADMIN_PREFIX + '/settings/system', | |||
|
96 | 'admin_settings_system_update': | |||
|
97 | ADMIN_PREFIX + '/settings/system/updates', | |||
|
98 | 'admin_settings_open_source': | |||
|
99 | ADMIN_PREFIX + '/settings/open_source', | |||
|
100 | ||||
|
101 | ||||
|
102 | }[name].format(**kwargs) | |||
|
103 | ||||
|
104 | if params: | |||
|
105 | base_url = '{}?{}'.format(base_url, urllib.urlencode(params)) | |||
|
106 | return base_url | |||
36 |
|
107 | |||
37 |
|
108 | |||
38 | @pytest.mark.usefixtures('autologin_user', 'app') |
|
109 | @pytest.mark.usefixtures('autologin_user', 'app') | |
@@ -47,12 +118,12 b' class TestAdminSettingsController(object' | |||||
47 | 'admin_settings_hooks', |
|
118 | 'admin_settings_hooks', | |
48 | 'admin_settings_search', |
|
119 | 'admin_settings_search', | |
49 | ]) |
|
120 | ]) | |
50 |
def test_simple_get(self, urlname |
|
121 | def test_simple_get(self, urlname): | |
51 |
app.get( |
|
122 | self.app.get(route_path(urlname)) | |
52 |
|
123 | |||
53 | def test_create_custom_hook(self, csrf_token): |
|
124 | def test_create_custom_hook(self, csrf_token): | |
54 | response = self.app.post( |
|
125 | response = self.app.post( | |
55 |
|
|
126 | route_path('admin_settings_hooks_update'), | |
56 | params={ |
|
127 | params={ | |
57 | 'new_hook_ui_key': 'test_hooks_1', |
|
128 | 'new_hook_ui_key': 'test_hooks_1', | |
58 | 'new_hook_ui_value': 'cd /tmp', |
|
129 | 'new_hook_ui_value': 'cd /tmp', | |
@@ -64,7 +135,7 b' class TestAdminSettingsController(object' | |||||
64 |
|
135 | |||
65 | def test_create_custom_hook_delete(self, csrf_token): |
|
136 | def test_create_custom_hook_delete(self, csrf_token): | |
66 | response = self.app.post( |
|
137 | response = self.app.post( | |
67 |
|
|
138 | route_path('admin_settings_hooks_update'), | |
68 | params={ |
|
139 | params={ | |
69 | 'new_hook_ui_key': 'test_hooks_2', |
|
140 | 'new_hook_ui_key': 'test_hooks_2', | |
70 | 'new_hook_ui_value': 'cd /tmp2', |
|
141 | 'new_hook_ui_value': 'cd /tmp2', | |
@@ -78,9 +149,9 b' class TestAdminSettingsController(object' | |||||
78 |
|
149 | |||
79 | # delete |
|
150 | # delete | |
80 | self.app.post( |
|
151 | self.app.post( | |
81 |
|
|
152 | route_path('admin_settings_hooks_delete'), | |
82 | params={'hook_id': hook_id, 'csrf_token': csrf_token}) |
|
153 | params={'hook_id': hook_id, 'csrf_token': csrf_token}) | |
83 |
response = self.app.get( |
|
154 | response = self.app.get(route_path('admin_settings_hooks')) | |
84 | response.mustcontain(no=['test_hooks_2']) |
|
155 | response.mustcontain(no=['test_hooks_2']) | |
85 | response.mustcontain(no=['cd /tmp2']) |
|
156 | response.mustcontain(no=['cd /tmp2']) | |
86 |
|
157 | |||
@@ -135,7 +206,6 b' class TestAdminSettingsGlobal(object):' | |||||
135 |
|
206 | |||
136 | def test_title_change(self, csrf_token): |
|
207 | def test_title_change(self, csrf_token): | |
137 | old_title = 'RhodeCode' |
|
208 | old_title = 'RhodeCode' | |
138 | new_title = old_title + '_changed' |
|
|||
139 |
|
209 | |||
140 | for new_title in ['Changed', 'Żółwik', old_title]: |
|
210 | for new_title in ['Changed', 'Żółwik', old_title]: | |
141 | response = self.post_and_verify_settings({ |
|
211 | response = self.post_and_verify_settings({ | |
@@ -161,7 +231,8 b' class TestAdminSettingsGlobal(object):' | |||||
161 | 'rhodecode_personal_repo_group_pattern': '${username}', |
|
231 | 'rhodecode_personal_repo_group_pattern': '${username}', | |
162 | } |
|
232 | } | |
163 | params.update(settings) |
|
233 | params.update(settings) | |
164 |
response = self.app.post( |
|
234 | response = self.app.post( | |
|
235 | route_path('admin_settings_global_update'), params=params) | |||
165 |
|
236 | |||
166 | assert_session_flash(response, 'Updated application settings') |
|
237 | assert_session_flash(response, 'Updated application settings') | |
167 | app_settings = SettingsModel().get_all_settings() |
|
238 | app_settings = SettingsModel().get_all_settings() | |
@@ -175,8 +246,8 b' class TestAdminSettingsGlobal(object):' | |||||
175 | @pytest.mark.usefixtures('autologin_user', 'app') |
|
246 | @pytest.mark.usefixtures('autologin_user', 'app') | |
176 | class TestAdminSettingsVcs(object): |
|
247 | class TestAdminSettingsVcs(object): | |
177 |
|
248 | |||
178 |
def test_contains_svn_default_patterns(self |
|
249 | def test_contains_svn_default_patterns(self): | |
179 |
response = app.get( |
|
250 | response = self.app.get(route_path('admin_settings_vcs')) | |
180 | expected_patterns = [ |
|
251 | expected_patterns = [ | |
181 | '/trunk', |
|
252 | '/trunk', | |
182 | '/branches/*', |
|
253 | '/branches/*', | |
@@ -186,7 +257,7 b' class TestAdminSettingsVcs(object):' | |||||
186 | response.mustcontain(pattern) |
|
257 | response.mustcontain(pattern) | |
187 |
|
258 | |||
188 | def test_add_new_svn_branch_and_tag_pattern( |
|
259 | def test_add_new_svn_branch_and_tag_pattern( | |
189 |
self |
|
260 | self, backend_svn, form_defaults, disable_sql_cache, | |
190 | csrf_token): |
|
261 | csrf_token): | |
191 | form_defaults.update({ |
|
262 | form_defaults.update({ | |
192 | 'new_svn_branch': '/exp/branches/*', |
|
263 | 'new_svn_branch': '/exp/branches/*', | |
@@ -194,8 +265,9 b' class TestAdminSettingsVcs(object):' | |||||
194 | 'csrf_token': csrf_token, |
|
265 | 'csrf_token': csrf_token, | |
195 | }) |
|
266 | }) | |
196 |
|
267 | |||
197 | response = app.post( |
|
268 | response = self.app.post( | |
198 | url('admin_settings_vcs'), params=form_defaults, status=302) |
|
269 | route_path('admin_settings_vcs_update'), | |
|
270 | params=form_defaults, status=302) | |||
199 | response = response.follow() |
|
271 | response = response.follow() | |
200 |
|
272 | |||
201 | # Expect to find the new values on the page |
|
273 | # Expect to find the new values on the page | |
@@ -208,12 +280,12 b' class TestAdminSettingsVcs(object):' | |||||
208 | assert 'important_tags/v0.5' in repo.tags |
|
280 | assert 'important_tags/v0.5' in repo.tags | |
209 |
|
281 | |||
210 | def test_add_same_svn_value_twice_shows_an_error_message( |
|
282 | def test_add_same_svn_value_twice_shows_an_error_message( | |
211 |
self |
|
283 | self, form_defaults, csrf_token, settings_util): | |
212 | settings_util.create_rhodecode_ui('vcs_svn_branch', '/test') |
|
284 | settings_util.create_rhodecode_ui('vcs_svn_branch', '/test') | |
213 | settings_util.create_rhodecode_ui('vcs_svn_tag', '/test') |
|
285 | settings_util.create_rhodecode_ui('vcs_svn_tag', '/test') | |
214 |
|
286 | |||
215 | response = app.post( |
|
287 | response = self.app.post( | |
216 |
|
|
288 | route_path('admin_settings_vcs_update'), | |
217 | params={ |
|
289 | params={ | |
218 | 'paths_root_path': form_defaults['paths_root_path'], |
|
290 | 'paths_root_path': form_defaults['paths_root_path'], | |
219 | 'new_svn_branch': '/test', |
|
291 | 'new_svn_branch': '/test', | |
@@ -230,14 +302,13 b' class TestAdminSettingsVcs(object):' | |||||
230 | 'vcs_svn_tag', |
|
302 | 'vcs_svn_tag', | |
231 | ]) |
|
303 | ]) | |
232 | def test_delete_svn_patterns( |
|
304 | def test_delete_svn_patterns( | |
233 |
self, section |
|
305 | self, section, csrf_token, settings_util): | |
234 | setting = settings_util.create_rhodecode_ui( |
|
306 | setting = settings_util.create_rhodecode_ui( | |
235 | section, '/test_delete', cleanup=False) |
|
307 | section, '/test_delete', cleanup=False) | |
236 |
|
308 | |||
237 | app.post( |
|
309 | self.app.post( | |
238 |
|
|
310 | route_path('admin_settings_vcs_svn_pattern_delete'), | |
239 | params={ |
|
311 | params={ | |
240 | '_method': 'delete', |
|
|||
241 | 'delete_svn_pattern': setting.ui_id, |
|
312 | 'delete_svn_pattern': setting.ui_id, | |
242 | 'csrf_token': csrf_token}, |
|
313 | 'csrf_token': csrf_token}, | |
243 | headers={'X-REQUESTED-WITH': 'XMLHttpRequest'}) |
|
314 | headers={'X-REQUESTED-WITH': 'XMLHttpRequest'}) | |
@@ -246,25 +317,24 b' class TestAdminSettingsVcs(object):' | |||||
246 | 'vcs_svn_branch', |
|
317 | 'vcs_svn_branch', | |
247 | 'vcs_svn_tag', |
|
318 | 'vcs_svn_tag', | |
248 | ]) |
|
319 | ]) | |
249 |
def test_delete_svn_patterns_raises_40 |
|
320 | def test_delete_svn_patterns_raises_404_when_no_xhr( | |
250 |
self, section |
|
321 | self, section, csrf_token, settings_util): | |
251 | setting = settings_util.create_rhodecode_ui(section, '/test_delete') |
|
322 | setting = settings_util.create_rhodecode_ui(section, '/test_delete') | |
252 |
|
323 | |||
253 | app.post( |
|
324 | self.app.post( | |
254 |
|
|
325 | route_path('admin_settings_vcs_svn_pattern_delete'), | |
255 | params={ |
|
326 | params={ | |
256 | '_method': 'delete', |
|
|||
257 | 'delete_svn_pattern': setting.ui_id, |
|
327 | 'delete_svn_pattern': setting.ui_id, | |
258 | 'csrf_token': csrf_token}, |
|
328 | 'csrf_token': csrf_token}, | |
259 |
status=40 |
|
329 | status=404) | |
260 |
|
330 | |||
261 |
def test_extensions_hgsubversion(self, |
|
331 | def test_extensions_hgsubversion(self, form_defaults, csrf_token): | |
262 | form_defaults.update({ |
|
332 | form_defaults.update({ | |
263 | 'csrf_token': csrf_token, |
|
333 | 'csrf_token': csrf_token, | |
264 | 'extensions_hgsubversion': 'True', |
|
334 | 'extensions_hgsubversion': 'True', | |
265 | }) |
|
335 | }) | |
266 | response = app.post( |
|
336 | response = self.app.post( | |
267 |
|
|
337 | route_path('admin_settings_vcs_update'), | |
268 | params=form_defaults, |
|
338 | params=form_defaults, | |
269 | status=302) |
|
339 | status=302) | |
270 |
|
340 | |||
@@ -275,13 +345,13 b' class TestAdminSettingsVcs(object):' | |||||
275 | 'value="True" checked="checked" />') |
|
345 | 'value="True" checked="checked" />') | |
276 | response.mustcontain(extensions_input) |
|
346 | response.mustcontain(extensions_input) | |
277 |
|
347 | |||
278 |
def test_extensions_hgevolve(self, |
|
348 | def test_extensions_hgevolve(self, form_defaults, csrf_token): | |
279 | form_defaults.update({ |
|
349 | form_defaults.update({ | |
280 | 'csrf_token': csrf_token, |
|
350 | 'csrf_token': csrf_token, | |
281 | 'extensions_evolve': 'True', |
|
351 | 'extensions_evolve': 'True', | |
282 | }) |
|
352 | }) | |
283 | response = app.post( |
|
353 | response = self.app.post( | |
284 |
|
|
354 | route_path('admin_settings_vcs_update'), | |
285 | params=form_defaults, |
|
355 | params=form_defaults, | |
286 | status=302) |
|
356 | status=302) | |
287 |
|
357 | |||
@@ -292,20 +362,19 b' class TestAdminSettingsVcs(object):' | |||||
292 | 'value="True" checked="checked" />') |
|
362 | 'value="True" checked="checked" />') | |
293 | response.mustcontain(extensions_input) |
|
363 | response.mustcontain(extensions_input) | |
294 |
|
364 | |||
295 |
def test_has_a_section_for_pull_request_settings(self |
|
365 | def test_has_a_section_for_pull_request_settings(self): | |
296 |
response = app.get( |
|
366 | response = self.app.get(route_path('admin_settings_vcs')) | |
297 | response.mustcontain('Pull Request Settings') |
|
367 | response.mustcontain('Pull Request Settings') | |
298 |
|
368 | |||
299 | def test_has_an_input_for_invalidation_of_inline_comments( |
|
369 | def test_has_an_input_for_invalidation_of_inline_comments(self): | |
300 | self, app): |
|
370 | response = self.app.get(route_path('admin_settings_vcs')) | |
301 | response = app.get(url('admin_settings_vcs')) |
|
|||
302 | assert_response = AssertResponse(response) |
|
371 | assert_response = AssertResponse(response) | |
303 | assert_response.one_element_exists( |
|
372 | assert_response.one_element_exists( | |
304 | '[name=rhodecode_use_outdated_comments]') |
|
373 | '[name=rhodecode_use_outdated_comments]') | |
305 |
|
374 | |||
306 | @pytest.mark.parametrize('new_value', [True, False]) |
|
375 | @pytest.mark.parametrize('new_value', [True, False]) | |
307 | def test_allows_to_change_invalidation_of_inline_comments( |
|
376 | def test_allows_to_change_invalidation_of_inline_comments( | |
308 |
self |
|
377 | self, form_defaults, csrf_token, new_value): | |
309 | setting_key = 'use_outdated_comments' |
|
378 | setting_key = 'use_outdated_comments' | |
310 | setting = SettingsModel().create_or_update_setting( |
|
379 | setting = SettingsModel().create_or_update_setting( | |
311 | setting_key, not new_value, 'bool') |
|
380 | setting_key, not new_value, 'bool') | |
@@ -316,8 +385,8 b' class TestAdminSettingsVcs(object):' | |||||
316 | 'csrf_token': csrf_token, |
|
385 | 'csrf_token': csrf_token, | |
317 | 'rhodecode_use_outdated_comments': str(new_value), |
|
386 | 'rhodecode_use_outdated_comments': str(new_value), | |
318 | }) |
|
387 | }) | |
319 | response = app.post( |
|
388 | response = self.app.post( | |
320 |
|
|
389 | route_path('admin_settings_vcs_update'), | |
321 | params=form_defaults, |
|
390 | params=form_defaults, | |
322 | status=302) |
|
391 | status=302) | |
323 | response = response.follow() |
|
392 | response = response.follow() | |
@@ -326,7 +395,7 b' class TestAdminSettingsVcs(object):' | |||||
326 |
|
395 | |||
327 | @pytest.mark.parametrize('new_value', [True, False]) |
|
396 | @pytest.mark.parametrize('new_value', [True, False]) | |
328 | def test_allows_to_change_hg_rebase_merge_strategy( |
|
397 | def test_allows_to_change_hg_rebase_merge_strategy( | |
329 |
self |
|
398 | self, form_defaults, csrf_token, new_value): | |
330 | setting_key = 'hg_use_rebase_for_merging' |
|
399 | setting_key = 'hg_use_rebase_for_merging' | |
331 |
|
400 | |||
332 | form_defaults.update({ |
|
401 | form_defaults.update({ | |
@@ -336,8 +405,8 b' class TestAdminSettingsVcs(object):' | |||||
336 |
|
405 | |||
337 | with mock.patch.dict( |
|
406 | with mock.patch.dict( | |
338 | rhodecode.CONFIG, {'labs_settings_active': 'true'}): |
|
407 | rhodecode.CONFIG, {'labs_settings_active': 'true'}): | |
339 | app.post( |
|
408 | self.app.post( | |
340 |
|
|
409 | route_path('admin_settings_vcs_update'), | |
341 | params=form_defaults, |
|
410 | params=form_defaults, | |
342 | status=302) |
|
411 | status=302) | |
343 |
|
412 | |||
@@ -353,14 +422,13 b' class TestAdminSettingsVcs(object):' | |||||
353 |
|
422 | |||
354 | @pytest.fixture |
|
423 | @pytest.fixture | |
355 | def form_defaults(self): |
|
424 | def form_defaults(self): | |
356 |
from rhodecode. |
|
425 | from rhodecode.apps.admin.views.settings import AdminSettingsView | |
357 | controller = SettingsController() |
|
426 | return AdminSettingsView._form_defaults() | |
358 | return controller._form_defaults() |
|
|||
359 |
|
427 | |||
360 | # TODO: johbo: What we really want is to checkpoint before a test run and |
|
428 | # TODO: johbo: What we really want is to checkpoint before a test run and | |
361 | # reset the session afterwards. |
|
429 | # reset the session afterwards. | |
362 | @pytest.fixture(scope='class', autouse=True) |
|
430 | @pytest.fixture(scope='class', autouse=True) | |
363 |
def cleanup_settings(self, request, |
|
431 | def cleanup_settings(self, request, baseapp): | |
364 | ui_id = RhodeCodeUi.ui_id |
|
432 | ui_id = RhodeCodeUi.ui_id | |
365 | original_ids = list( |
|
433 | original_ids = list( | |
366 | r.ui_id for r in RhodeCodeUi.query().values(ui_id)) |
|
434 | r.ui_id for r in RhodeCodeUi.query().values(ui_id)) | |
@@ -374,14 +442,16 b' class TestAdminSettingsVcs(object):' | |||||
374 | @pytest.mark.usefixtures('autologin_user', 'app') |
|
442 | @pytest.mark.usefixtures('autologin_user', 'app') | |
375 | class TestLabsSettings(object): |
|
443 | class TestLabsSettings(object): | |
376 | def test_get_settings_page_disabled(self): |
|
444 | def test_get_settings_page_disabled(self): | |
377 |
with mock.patch.dict( |
|
445 | with mock.patch.dict( | |
378 |
|
|
446 | rhodecode.CONFIG, {'labs_settings_active': 'false'}): | |
379 | response = self.app.get(url('admin_settings_labs'), status=302) |
|
|||
380 |
|
447 | |||
381 | assert response.location.endswith(url('admin_settings')) |
|
448 | response = self.app.get( | |
|
449 | route_path('admin_settings_labs'), status=302) | |||
|
450 | ||||
|
451 | assert response.location.endswith(route_path('admin_settings')) | |||
382 |
|
452 | |||
383 | def test_get_settings_page_enabled(self): |
|
453 | def test_get_settings_page_enabled(self): | |
384 |
from rhodecode. |
|
454 | from rhodecode.apps.admin.views import settings | |
385 | lab_settings = [ |
|
455 | lab_settings = [ | |
386 | settings.LabSetting( |
|
456 | settings.LabSetting( | |
387 | key='rhodecode_bool', |
|
457 | key='rhodecode_bool', | |
@@ -401,7 +471,7 b' class TestLabsSettings(object):' | |||||
401 | with mock.patch.dict(rhodecode.CONFIG, |
|
471 | with mock.patch.dict(rhodecode.CONFIG, | |
402 | {'labs_settings_active': 'true'}): |
|
472 | {'labs_settings_active': 'true'}): | |
403 | with mock.patch.object(settings, '_LAB_SETTINGS', lab_settings): |
|
473 | with mock.patch.object(settings, '_LAB_SETTINGS', lab_settings): | |
404 |
response = self.app.get( |
|
474 | response = self.app.get(route_path('admin_settings_labs')) | |
405 |
|
475 | |||
406 | assert '<label>bool group:</label>' in response |
|
476 | assert '<label>bool group:</label>' in response | |
407 | assert '<label for="rhodecode_bool">bool label</label>' in response |
|
477 | assert '<label for="rhodecode_bool">bool label</label>' in response | |
@@ -417,9 +487,6 b' class TestLabsSettings(object):' | |||||
417 | @pytest.mark.usefixtures('app') |
|
487 | @pytest.mark.usefixtures('app') | |
418 | class TestOpenSourceLicenses(object): |
|
488 | class TestOpenSourceLicenses(object): | |
419 |
|
489 | |||
420 | def _get_url(self): |
|
|||
421 | return ADMIN_PREFIX + '/settings/open_source' |
|
|||
422 |
|
||||
423 | def test_records_are_displayed(self, autologin_user): |
|
490 | def test_records_are_displayed(self, autologin_user): | |
424 | sample_licenses = { |
|
491 | sample_licenses = { | |
425 | "python2.7-pytest-2.7.1": { |
|
492 | "python2.7-pytest-2.7.1": { | |
@@ -433,7 +500,8 b' class TestOpenSourceLicenses(object):' | |||||
433 | 'rhodecode.apps.admin.views.open_source_licenses.read_opensource_licenses', |
|
500 | 'rhodecode.apps.admin.views.open_source_licenses.read_opensource_licenses', | |
434 | return_value=sample_licenses) |
|
501 | return_value=sample_licenses) | |
435 | with read_licenses_patch: |
|
502 | with read_licenses_patch: | |
436 |
response = self.app.get( |
|
503 | response = self.app.get( | |
|
504 | route_path('admin_settings_open_source'), status=200) | |||
437 |
|
505 | |||
438 | assert_response = AssertResponse(response) |
|
506 | assert_response = AssertResponse(response) | |
439 | assert_response.element_contains( |
|
507 | assert_response.element_contains( | |
@@ -444,29 +512,25 b' class TestOpenSourceLicenses(object):' | |||||
444 | assert_response.element_contains('.panel-body', license) |
|
512 | assert_response.element_contains('.panel-body', license) | |
445 |
|
513 | |||
446 | def test_records_can_be_read(self, autologin_user): |
|
514 | def test_records_can_be_read(self, autologin_user): | |
447 |
response = self.app.get( |
|
515 | response = self.app.get( | |
|
516 | route_path('admin_settings_open_source'), status=200) | |||
448 | assert_response = AssertResponse(response) |
|
517 | assert_response = AssertResponse(response) | |
449 | assert_response.element_contains( |
|
518 | assert_response.element_contains( | |
450 | '.panel-heading', 'Licenses of Third Party Packages') |
|
519 | '.panel-heading', 'Licenses of Third Party Packages') | |
451 |
|
520 | |||
452 | def test_forbidden_when_normal_user(self, autologin_regular_user): |
|
521 | def test_forbidden_when_normal_user(self, autologin_regular_user): | |
453 |
self.app.get( |
|
522 | self.app.get( | |
|
523 | route_path('admin_settings_open_source'), status=404) | |||
454 |
|
524 | |||
455 |
|
525 | |||
456 | @pytest.mark.usefixtures('app') |
|
526 | @pytest.mark.usefixtures('app') | |
457 | class TestUserSessions(object): |
|
527 | class TestUserSessions(object): | |
458 |
|
528 | |||
459 | def _get_url(self, name='admin_settings_sessions'): |
|
|||
460 | return { |
|
|||
461 | 'admin_settings_sessions': ADMIN_PREFIX + '/settings/sessions', |
|
|||
462 | 'admin_settings_sessions_cleanup': ADMIN_PREFIX + '/settings/sessions/cleanup' |
|
|||
463 | }[name] |
|
|||
464 |
|
||||
465 | def test_forbidden_when_normal_user(self, autologin_regular_user): |
|
529 | def test_forbidden_when_normal_user(self, autologin_regular_user): | |
466 |
self.app.get( |
|
530 | self.app.get(route_path('admin_settings_sessions'), status=404) | |
467 |
|
531 | |||
468 | def test_show_sessions_page(self, autologin_user): |
|
532 | def test_show_sessions_page(self, autologin_user): | |
469 |
response = self.app.get( |
|
533 | response = self.app.get(route_path('admin_settings_sessions'), status=200) | |
470 | response.mustcontain('file') |
|
534 | response.mustcontain('file') | |
471 |
|
535 | |||
472 | def test_cleanup_old_sessions(self, autologin_user, csrf_token): |
|
536 | def test_cleanup_old_sessions(self, autologin_user, csrf_token): | |
@@ -476,24 +540,19 b' class TestUserSessions(object):' | |||||
476 | 'expire_days': '60' |
|
540 | 'expire_days': '60' | |
477 | } |
|
541 | } | |
478 | response = self.app.post( |
|
542 | response = self.app.post( | |
479 |
|
|
543 | route_path('admin_settings_sessions_cleanup'), params=post_data, | |
480 | status=302) |
|
544 | status=302) | |
481 | assert_session_flash(response, 'Cleaned up old sessions') |
|
545 | assert_session_flash(response, 'Cleaned up old sessions') | |
482 |
|
546 | |||
483 |
|
547 | |||
484 | @pytest.mark.usefixtures('app') |
|
548 | @pytest.mark.usefixtures('app') | |
485 | class TestAdminSystemInfo(object): |
|
549 | class TestAdminSystemInfo(object): | |
486 | def _get_url(self, name='admin_settings_system'): |
|
|||
487 | return { |
|
|||
488 | 'admin_settings_system': ADMIN_PREFIX + '/settings/system', |
|
|||
489 | 'admin_settings_system_update': ADMIN_PREFIX + '/settings/system/updates', |
|
|||
490 | }[name] |
|
|||
491 |
|
550 | |||
492 | def test_forbidden_when_normal_user(self, autologin_regular_user): |
|
551 | def test_forbidden_when_normal_user(self, autologin_regular_user): | |
493 |
self.app.get( |
|
552 | self.app.get(route_path('admin_settings_system'), status=404) | |
494 |
|
553 | |||
495 | def test_system_info_page(self, autologin_user): |
|
554 | def test_system_info_page(self, autologin_user): | |
496 |
response = self.app.get( |
|
555 | response = self.app.get(route_path('admin_settings_system')) | |
497 | response.mustcontain('RhodeCode Community Edition, version {}'.format( |
|
556 | response.mustcontain('RhodeCode Community Edition, version {}'.format( | |
498 | rhodecode.__version__)) |
|
557 | rhodecode.__version__)) | |
499 |
|
558 | |||
@@ -511,7 +570,7 b' class TestAdminSystemInfo(object):' | |||||
511 | ] |
|
570 | ] | |
512 | } |
|
571 | } | |
513 | with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data): |
|
572 | with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data): | |
514 |
response = self.app.get( |
|
573 | response = self.app.get(route_path('admin_settings_system_update')) | |
515 | response.mustcontain('A <b>new version</b> is available') |
|
574 | response.mustcontain('A <b>new version</b> is available') | |
516 |
|
575 | |||
517 | def test_system_update_nothing_new(self, autologin_user): |
|
576 | def test_system_update_nothing_new(self, autologin_user): | |
@@ -524,13 +583,13 b' class TestAdminSystemInfo(object):' | |||||
524 | ] |
|
583 | ] | |
525 | } |
|
584 | } | |
526 | with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data): |
|
585 | with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data): | |
527 |
response = self.app.get( |
|
586 | response = self.app.get(route_path('admin_settings_system_update')) | |
528 | response.mustcontain( |
|
587 | response.mustcontain( | |
529 |
' |
|
588 | 'This instance is already running the <b>latest</b> stable version') | |
530 |
|
589 | |||
531 | def test_system_update_bad_response(self, autologin_user): |
|
590 | def test_system_update_bad_response(self, autologin_user): | |
532 | with mock.patch(UPDATE_DATA_QUALNAME, side_effect=ValueError('foo')): |
|
591 | with mock.patch(UPDATE_DATA_QUALNAME, side_effect=ValueError('foo')): | |
533 |
response = self.app.get( |
|
592 | response = self.app.get(route_path('admin_settings_system_update')) | |
534 | response.mustcontain( |
|
593 | response.mustcontain( | |
535 | 'Bad data sent from update server') |
|
594 | 'Bad data sent from update server') | |
536 |
|
595 | |||
@@ -542,12 +601,12 b' class TestAdminSettingsIssueTracker(obje' | |||||
542 | PATTERN_KEY = RC_PREFIX + SHORT_PATTERN_KEY |
|
601 | PATTERN_KEY = RC_PREFIX + SHORT_PATTERN_KEY | |
543 |
|
602 | |||
544 | def test_issuetracker_index(self, autologin_user): |
|
603 | def test_issuetracker_index(self, autologin_user): | |
545 |
response = self.app.get( |
|
604 | response = self.app.get(route_path('admin_settings_issuetracker')) | |
546 | assert response.status_code == 200 |
|
605 | assert response.status_code == 200 | |
547 |
|
606 | |||
548 | def test_add_empty_issuetracker_pattern( |
|
607 | def test_add_empty_issuetracker_pattern( | |
549 | self, request, autologin_user, csrf_token): |
|
608 | self, request, autologin_user, csrf_token): | |
550 |
post_url = |
|
609 | post_url = route_path('admin_settings_issuetracker_update') | |
551 | post_data = { |
|
610 | post_data = { | |
552 | 'csrf_token': csrf_token |
|
611 | 'csrf_token': csrf_token | |
553 | } |
|
612 | } | |
@@ -557,14 +616,14 b' class TestAdminSettingsIssueTracker(obje' | |||||
557 | self, request, autologin_user, csrf_token): |
|
616 | self, request, autologin_user, csrf_token): | |
558 | pattern = 'issuetracker_pat' |
|
617 | pattern = 'issuetracker_pat' | |
559 | another_pattern = pattern+'1' |
|
618 | another_pattern = pattern+'1' | |
560 |
post_url = |
|
619 | post_url = route_path('admin_settings_issuetracker_update') | |
561 | post_data = { |
|
620 | post_data = { | |
562 | 'new_pattern_pattern_0': pattern, |
|
621 | 'new_pattern_pattern_0': pattern, | |
563 | 'new_pattern_url_0': 'url', |
|
622 | 'new_pattern_url_0': 'http://url', | |
564 | 'new_pattern_prefix_0': 'prefix', |
|
623 | 'new_pattern_prefix_0': 'prefix', | |
565 | 'new_pattern_description_0': 'description', |
|
624 | 'new_pattern_description_0': 'description', | |
566 | 'new_pattern_pattern_1': another_pattern, |
|
625 | 'new_pattern_pattern_1': another_pattern, | |
567 | 'new_pattern_url_1': 'url1', |
|
626 | 'new_pattern_url_1': 'https://url1', | |
568 | 'new_pattern_prefix_1': 'prefix1', |
|
627 | 'new_pattern_prefix_1': 'prefix1', | |
569 | 'new_pattern_description_1': 'description1', |
|
628 | 'new_pattern_description_1': 'description1', | |
570 | 'csrf_token': csrf_token |
|
629 | 'csrf_token': csrf_token | |
@@ -600,10 +659,10 b' class TestAdminSettingsIssueTracker(obje' | |||||
600 | SettingsModel().create_or_update_setting( |
|
659 | SettingsModel().create_or_update_setting( | |
601 | self.SHORT_PATTERN_KEY+old_uid, old_pattern, 'unicode') |
|
660 | self.SHORT_PATTERN_KEY+old_uid, old_pattern, 'unicode') | |
602 |
|
661 | |||
603 |
post_url = |
|
662 | post_url = route_path('admin_settings_issuetracker_update') | |
604 | post_data = { |
|
663 | post_data = { | |
605 | 'new_pattern_pattern_0': pattern, |
|
664 | 'new_pattern_pattern_0': pattern, | |
606 | 'new_pattern_url_0': 'url', |
|
665 | 'new_pattern_url_0': 'https://url', | |
607 | 'new_pattern_prefix_0': 'prefix', |
|
666 | 'new_pattern_prefix_0': 'prefix', | |
608 | 'new_pattern_description_0': 'description', |
|
667 | 'new_pattern_description_0': 'description', | |
609 | 'uid': old_uid, |
|
668 | 'uid': old_uid, | |
@@ -634,10 +693,10 b' class TestAdminSettingsIssueTracker(obje' | |||||
634 | settings_util.create_rhodecode_setting( |
|
693 | settings_util.create_rhodecode_setting( | |
635 | desc_key, 'old description', 'unicode', cleanup=False) |
|
694 | desc_key, 'old description', 'unicode', cleanup=False) | |
636 |
|
695 | |||
637 |
post_url = |
|
696 | post_url = route_path('admin_settings_issuetracker_update') | |
638 | post_data = { |
|
697 | post_data = { | |
639 | 'new_pattern_pattern_0': pattern, |
|
698 | 'new_pattern_pattern_0': pattern, | |
640 | 'new_pattern_url_0': 'url', |
|
699 | 'new_pattern_url_0': 'https://url', | |
641 | 'new_pattern_prefix_0': 'prefix', |
|
700 | 'new_pattern_prefix_0': 'prefix', | |
642 | 'new_pattern_description_0': new_description, |
|
701 | 'new_pattern_description_0': new_description, | |
643 | 'uid': self.uid, |
|
702 | 'uid': self.uid, | |
@@ -659,7 +718,7 b' class TestAdminSettingsIssueTracker(obje' | |||||
659 | settings_util.create_rhodecode_setting( |
|
718 | settings_util.create_rhodecode_setting( | |
660 | self.SHORT_PATTERN_KEY+uid, pattern, 'unicode', cleanup=False) |
|
719 | self.SHORT_PATTERN_KEY+uid, pattern, 'unicode', cleanup=False) | |
661 |
|
720 | |||
662 |
post_url = |
|
721 | post_url = route_path('admin_settings_issuetracker_delete') | |
663 | post_data = { |
|
722 | post_data = { | |
664 | '_method': 'delete', |
|
723 | '_method': 'delete', | |
665 | 'uid': uid, |
|
724 | 'uid': uid, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -23,7 +23,6 b' from sqlalchemy.orm.exc import NoResultF' | |||||
23 |
|
23 | |||
24 | from rhodecode.lib import auth |
|
24 | from rhodecode.lib import auth | |
25 | from rhodecode.lib import helpers as h |
|
25 | from rhodecode.lib import helpers as h | |
26 | from rhodecode.model import validators |
|
|||
27 | from rhodecode.model.db import User, UserApiKeys, UserEmailMap, Repository |
|
26 | from rhodecode.model.db import User, UserApiKeys, UserEmailMap, Repository | |
28 | from rhodecode.model.meta import Session |
|
27 | from rhodecode.model.meta import Session | |
29 | from rhodecode.model.user import UserModel |
|
28 | from rhodecode.model.user import UserModel | |
@@ -386,8 +385,7 b' class TestAdminUsersView(TestController)' | |||||
386 | 'csrf_token': self.csrf_token, |
|
385 | 'csrf_token': self.csrf_token, | |
387 | }) |
|
386 | }) | |
388 |
|
387 | |||
389 | msg = validators.ValidUsername( |
|
388 | msg = u'Username "%(username)s" is forbidden' | |
390 | False, {})._messages['system_invalid_username'] |
|
|||
391 | msg = h.html_escape(msg % {'username': 'new_user'}) |
|
389 | msg = h.html_escape(msg % {'username': 'new_user'}) | |
392 | response.mustcontain('<span class="error-message">%s</span>' % msg) |
|
390 | response.mustcontain('<span class="error-message">%s</span>' % msg) | |
393 | response.mustcontain( |
|
391 | response.mustcontain( |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -36,7 +36,6 b' log = logging.getLogger(__name__)' | |||||
36 | class AdminAuditLogsView(BaseAppView): |
|
36 | class AdminAuditLogsView(BaseAppView): | |
37 | def load_default_context(self): |
|
37 | def load_default_context(self): | |
38 | c = self._get_local_tmpl_context() |
|
38 | c = self._get_local_tmpl_context() | |
39 | self._register_global_c(c) |
|
|||
40 | return c |
|
39 | return c | |
41 |
|
40 | |||
42 | @LoginRequired() |
|
41 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -44,7 +44,7 b' class AdminDefaultSettingsView(BaseAppVi' | |||||
44 | def load_default_context(self): |
|
44 | def load_default_context(self): | |
45 | c = self._get_local_tmpl_context() |
|
45 | c = self._get_local_tmpl_context() | |
46 |
|
46 | |||
47 | self._register_global_c(c) |
|
47 | ||
48 | return c |
|
48 | return c | |
49 |
|
49 | |||
50 | @LoginRequired() |
|
50 | @LoginRequired() | |
@@ -79,7 +79,7 b' class AdminDefaultSettingsView(BaseAppVi' | |||||
79 | _ = self.request.translate |
|
79 | _ = self.request.translate | |
80 | c = self.load_default_context() |
|
80 | c = self.load_default_context() | |
81 | c.active = 'repositories' |
|
81 | c.active = 'repositories' | |
82 | form = DefaultsForm()() |
|
82 | form = DefaultsForm(self.request.translate)() | |
83 |
|
83 | |||
84 | try: |
|
84 | try: | |
85 | form_result = form.to_python(dict(self.request.POST)) |
|
85 | form_result = form.to_python(dict(self.request.POST)) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -35,7 +35,7 b' class OpenSourceLicensesAdminSettingsVie' | |||||
35 |
|
35 | |||
36 | def load_default_context(self): |
|
36 | def load_default_context(self): | |
37 | c = self._get_local_tmpl_context() |
|
37 | c = self._get_local_tmpl_context() | |
38 | self._register_global_c(c) |
|
38 | ||
39 | return c |
|
39 | return c | |
40 |
|
40 | |||
41 | @LoginRequired() |
|
41 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -53,8 +53,6 b' log = logging.getLogger(__name__)' | |||||
53 | class AdminPermissionsView(BaseAppView, DataGridAppView): |
|
53 | class AdminPermissionsView(BaseAppView, DataGridAppView): | |
54 | def load_default_context(self): |
|
54 | def load_default_context(self): | |
55 | c = self._get_local_tmpl_context() |
|
55 | c = self._get_local_tmpl_context() | |
56 |
|
||||
57 | self._register_global_c(c) |
|
|||
58 | PermissionModel().set_global_permission_choices( |
|
56 | PermissionModel().set_global_permission_choices( | |
59 | c, gettext_translator=self.request.translate) |
|
57 | c, gettext_translator=self.request.translate) | |
60 | return c |
|
58 | return c | |
@@ -100,6 +98,7 b' class AdminPermissionsView(BaseAppView, ' | |||||
100 | c.active = 'application' |
|
98 | c.active = 'application' | |
101 |
|
99 | |||
102 | _form = ApplicationPermissionsForm( |
|
100 | _form = ApplicationPermissionsForm( | |
|
101 | self.request.translate, | |||
103 | [x[0] for x in c.register_choices], |
|
102 | [x[0] for x in c.register_choices], | |
104 | [x[0] for x in c.password_reset_choices], |
|
103 | [x[0] for x in c.password_reset_choices], | |
105 | [x[0] for x in c.extern_activate_choices])() |
|
104 | [x[0] for x in c.extern_activate_choices])() | |
@@ -180,6 +179,7 b' class AdminPermissionsView(BaseAppView, ' | |||||
180 | c.active = 'objects' |
|
179 | c.active = 'objects' | |
181 |
|
180 | |||
182 | _form = ObjectPermissionsForm( |
|
181 | _form = ObjectPermissionsForm( | |
|
182 | self.request.translate, | |||
183 | [x[0] for x in c.repo_perms_choices], |
|
183 | [x[0] for x in c.repo_perms_choices], | |
184 | [x[0] for x in c.group_perms_choices], |
|
184 | [x[0] for x in c.group_perms_choices], | |
185 | [x[0] for x in c.user_group_perms_choices])() |
|
185 | [x[0] for x in c.user_group_perms_choices])() | |
@@ -251,6 +251,7 b' class AdminPermissionsView(BaseAppView, ' | |||||
251 | c.active = 'global' |
|
251 | c.active = 'global' | |
252 |
|
252 | |||
253 | _form = UserPermissionsForm( |
|
253 | _form = UserPermissionsForm( | |
|
254 | self.request.translate, | |||
254 | [x[0] for x in c.repo_create_choices], |
|
255 | [x[0] for x in c.repo_create_choices], | |
255 | [x[0] for x in c.repo_create_on_write_choices], |
|
256 | [x[0] for x in c.repo_create_on_write_choices], | |
256 | [x[0] for x in c.repo_group_create_choices], |
|
257 | [x[0] for x in c.repo_group_create_choices], | |
@@ -395,6 +396,7 b' class AdminPermissionsView(BaseAppView, ' | |||||
395 | renderer='json_ext', xhr=True) |
|
396 | renderer='json_ext', xhr=True) | |
396 | def ssh_keys_data(self): |
|
397 | def ssh_keys_data(self): | |
397 | _ = self.request.translate |
|
398 | _ = self.request.translate | |
|
399 | self.load_default_context() | |||
398 | column_map = { |
|
400 | column_map = { | |
399 | 'fingerprint': 'ssh_key_fingerprint', |
|
401 | 'fingerprint': 'ssh_key_fingerprint', | |
400 | 'username': User.username |
|
402 | 'username': User.username |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -21,6 +21,7 b'' | |||||
21 | import logging |
|
21 | import logging | |
22 |
|
22 | |||
23 | import psutil |
|
23 | import psutil | |
|
24 | import signal | |||
24 | from pyramid.view import view_config |
|
25 | from pyramid.view import view_config | |
25 |
|
26 | |||
26 | from rhodecode.apps._base import BaseAppView |
|
27 | from rhodecode.apps._base import BaseAppView | |
@@ -35,7 +36,7 b' log = logging.getLogger(__name__)' | |||||
35 | class AdminProcessManagementView(BaseAppView): |
|
36 | class AdminProcessManagementView(BaseAppView): | |
36 | def load_default_context(self): |
|
37 | def load_default_context(self): | |
37 | c = self._get_local_tmpl_context() |
|
38 | c = self._get_local_tmpl_context() | |
38 | self._register_global_c(c) |
|
39 | ||
39 | return c |
|
40 | return c | |
40 |
|
41 | |||
41 | @LoginRequired() |
|
42 | @LoginRequired() | |
@@ -55,6 +56,18 b' class AdminProcessManagementView(BaseApp' | |||||
55 |
|
56 | |||
56 | @LoginRequired() |
|
57 | @LoginRequired() | |
57 | @HasPermissionAllDecorator('hg.admin') |
|
58 | @HasPermissionAllDecorator('hg.admin') | |
|
59 | @view_config( | |||
|
60 | route_name='admin_settings_process_management_data', request_method='GET', | |||
|
61 | renderer='rhodecode:templates/admin/settings/settings_process_management_data.mako') | |||
|
62 | def process_management_data(self): | |||
|
63 | _ = self.request.translate | |||
|
64 | c = self.load_default_context() | |||
|
65 | c.gunicorn_processes = ( | |||
|
66 | p for p in psutil.process_iter() if 'gunicorn' in p.name()) | |||
|
67 | return self._get_template_context(c) | |||
|
68 | ||||
|
69 | @LoginRequired() | |||
|
70 | @HasPermissionAllDecorator('hg.admin') | |||
58 | @CSRFRequired() |
|
71 | @CSRFRequired() | |
59 | @view_config( |
|
72 | @view_config( | |
60 | route_name='admin_settings_process_management_signal', |
|
73 | route_name='admin_settings_process_management_signal', | |
@@ -89,3 +102,32 b' class AdminProcessManagementView(BaseApp' | |||||
89 | p.kill() |
|
102 | p.kill() | |
90 |
|
103 | |||
91 | return {'result': result} |
|
104 | return {'result': result} | |
|
105 | ||||
|
106 | @LoginRequired() | |||
|
107 | @HasPermissionAllDecorator('hg.admin') | |||
|
108 | @CSRFRequired() | |||
|
109 | @view_config( | |||
|
110 | route_name='admin_settings_process_management_master_signal', | |||
|
111 | request_method='POST', renderer='json_ext') | |||
|
112 | def process_management_master_signal(self): | |||
|
113 | pid_data = self.request.json.get('pid_data', {}) | |||
|
114 | pid = safe_int(pid_data['pid']) | |||
|
115 | action = pid_data['action'] | |||
|
116 | if pid: | |||
|
117 | try: | |||
|
118 | proc = psutil.Process(pid) | |||
|
119 | except psutil.NoSuchProcess: | |||
|
120 | return {'result': 'failure_no_such_process'} | |||
|
121 | ||||
|
122 | children = proc.children(recursive=True) | |||
|
123 | if children: | |||
|
124 | # master process | |||
|
125 | if action == '+' and len(children) <= 20: | |||
|
126 | proc.send_signal(signal.SIGTTIN) | |||
|
127 | elif action == '-' and len(children) >= 2: | |||
|
128 | proc.send_signal(signal.SIGTTOU) | |||
|
129 | else: | |||
|
130 | return {'result': 'failure_wrong_action'} | |||
|
131 | return {'result': 'success'} | |||
|
132 | ||||
|
133 | return {'result': 'failure_not_master'} |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -47,7 +47,7 b' class AdminRepoGroupsView(BaseAppView, D' | |||||
47 |
|
47 | |||
48 | def load_default_context(self): |
|
48 | def load_default_context(self): | |
49 | c = self._get_local_tmpl_context() |
|
49 | c = self._get_local_tmpl_context() | |
50 | self._register_global_c(c) |
|
50 | ||
51 | return c |
|
51 | return c | |
52 |
|
52 | |||
53 | def _load_form_data(self, c): |
|
53 | def _load_form_data(self, c): | |
@@ -150,8 +150,9 b' class AdminRepoGroupsView(BaseAppView, D' | |||||
150 | # permissions for can create group based on parent_id are checked |
|
150 | # permissions for can create group based on parent_id are checked | |
151 | # here in the Form |
|
151 | # here in the Form | |
152 | available_groups = map(lambda k: safe_unicode(k[0]), c.repo_groups) |
|
152 | available_groups = map(lambda k: safe_unicode(k[0]), c.repo_groups) | |
153 |
repo_group_form = RepoGroupForm( |
|
153 | repo_group_form = RepoGroupForm( | |
154 | can_create_in_root=can_create)() |
|
154 | self.request.translate, available_groups=available_groups, | |
|
155 | can_create_in_root=can_create)() | |||
155 |
|
156 | |||
156 | repo_group_name = self.request.POST.get('group_name') |
|
157 | repo_group_name = self.request.POST.get('group_name') | |
157 | try: |
|
158 | try: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -28,6 +28,7 b' from pyramid.renderers import render' | |||||
28 | from pyramid.response import Response |
|
28 | from pyramid.response import Response | |
29 |
|
29 | |||
30 | from rhodecode.apps._base import BaseAppView, DataGridAppView |
|
30 | from rhodecode.apps._base import BaseAppView, DataGridAppView | |
|
31 | from rhodecode.lib.celerylib.utils import get_task_id | |||
31 |
|
32 | |||
32 | from rhodecode.lib.ext_json import json |
|
33 | from rhodecode.lib.ext_json import json | |
33 | from rhodecode.lib.auth import ( |
|
34 | from rhodecode.lib.auth import ( | |
@@ -49,7 +50,7 b' class AdminReposView(BaseAppView, DataGr' | |||||
49 |
|
50 | |||
50 | def load_default_context(self): |
|
51 | def load_default_context(self): | |
51 | c = self._get_local_tmpl_context() |
|
52 | c = self._get_local_tmpl_context() | |
52 | self._register_global_c(c) |
|
53 | ||
53 | return c |
|
54 | return c | |
54 |
|
55 | |||
55 | def _load_form_data(self, c): |
|
56 | def _load_form_data(self, c): | |
@@ -58,7 +59,7 b' class AdminReposView(BaseAppView, DataGr' | |||||
58 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) |
|
59 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) | |
59 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) |
|
60 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) | |
60 | c.landing_revs_choices, c.landing_revs = \ |
|
61 | c.landing_revs_choices, c.landing_revs = \ | |
61 | ScmModel().get_repo_landing_revs() |
|
62 | ScmModel().get_repo_landing_revs(self.request.translate) | |
62 | c.personal_repo_group = self._rhodecode_user.personal_repo_group |
|
63 | c.personal_repo_group = self._rhodecode_user.personal_repo_group | |
63 |
|
64 | |||
64 | @LoginRequired() |
|
65 | @LoginRequired() | |
@@ -143,21 +144,19 b' class AdminReposView(BaseAppView, DataGr' | |||||
143 | c = self.load_default_context() |
|
144 | c = self.load_default_context() | |
144 |
|
145 | |||
145 | form_result = {} |
|
146 | form_result = {} | |
|
147 | self._load_form_data(c) | |||
146 | task_id = None |
|
148 | task_id = None | |
147 | self._load_form_data(c) |
|
|||
148 |
|
||||
149 | try: |
|
149 | try: | |
150 | # CanWriteToGroup validators checks permissions of this POST |
|
150 | # CanWriteToGroup validators checks permissions of this POST | |
151 | form_result = RepoForm(repo_groups=c.repo_groups_choices, |
|
151 | form = RepoForm( | |
152 | landing_revs=c.landing_revs_choices)()\ |
|
152 | self.request.translate, repo_groups=c.repo_groups_choices, | |
153 | .to_python(dict(self.request.POST)) |
|
153 | landing_revs=c.landing_revs_choices)() | |
|
154 | form_result = form.to_python(dict(self.request.POST)) | |||
154 |
|
155 | |||
155 | # create is done sometimes async on celery, db transaction |
|
156 | # create is done sometimes async on celery, db transaction | |
156 | # management is handled there. |
|
157 | # management is handled there. | |
157 | task = RepoModel().create(form_result, self._rhodecode_user.user_id) |
|
158 | task = RepoModel().create(form_result, self._rhodecode_user.user_id) | |
158 | from celery.result import BaseAsyncResult |
|
159 | task_id = get_task_id(task) | |
159 | if isinstance(task, BaseAsyncResult): |
|
|||
160 | task_id = task.task_id |
|
|||
161 | except formencode.Invalid as errors: |
|
160 | except formencode.Invalid as errors: | |
162 | data = render('rhodecode:templates/admin/repos/repo_add.mako', |
|
161 | data = render('rhodecode:templates/admin/repos/repo_add.mako', | |
163 | self._get_template_context(c), self.request) |
|
162 | self._get_template_context(c), self.request) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -30,6 +30,7 b' from rhodecode.lib.auth import (' | |||||
30 | from rhodecode.lib.utils2 import safe_int |
|
30 | from rhodecode.lib.utils2 import safe_int | |
31 | from rhodecode.lib import system_info |
|
31 | from rhodecode.lib import system_info | |
32 | from rhodecode.lib import user_sessions |
|
32 | from rhodecode.lib import user_sessions | |
|
33 | from rhodecode.lib import helpers as h | |||
33 |
|
34 | |||
34 |
|
35 | |||
35 | log = logging.getLogger(__name__) |
|
36 | log = logging.getLogger(__name__) | |
@@ -39,7 +40,7 b' class AdminSessionSettingsView(BaseAppVi' | |||||
39 | def load_default_context(self): |
|
40 | def load_default_context(self): | |
40 | c = self._get_local_tmpl_context() |
|
41 | c = self._get_local_tmpl_context() | |
41 |
|
42 | |||
42 | self._register_global_c(c) |
|
43 | ||
43 | return c |
|
44 | return c | |
44 |
|
45 | |||
45 | @LoginRequired() |
|
46 | @LoginRequired() | |
@@ -88,14 +89,12 b' class AdminSessionSettingsView(BaseAppVi' | |||||
88 | try: |
|
89 | try: | |
89 | session_model.clean_sessions( |
|
90 | session_model.clean_sessions( | |
90 | older_than_seconds=older_than_seconds) |
|
91 | older_than_seconds=older_than_seconds) | |
91 | self.request.session.flash( |
|
92 | h.flash(_('Cleaned up old sessions'), category='success') | |
92 | _('Cleaned up old sessions'), queue='success') |
|
|||
93 | except user_sessions.CleanupCommand as msg: |
|
93 | except user_sessions.CleanupCommand as msg: | |
94 |
|
|
94 | h.flash(msg.message, category='warning') | |
95 | except Exception as e: |
|
95 | except Exception as e: | |
96 | log.exception('Failed session cleanup') |
|
96 | log.exception('Failed session cleanup') | |
97 | self.request.session.flash( |
|
97 | h.flash(_('Failed to cleanup up old sessions'), category='error') | |
98 | _('Failed to cleanup up old sessions'), queue='error') |
|
|||
99 |
|
98 | |||
100 | redirect_to = self.request.resource_path( |
|
99 | redirect_to = self.request.resource_path( | |
101 | self.context, route_name='admin_settings_sessions') |
|
100 | self.context, route_name='admin_settings_sessions') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -20,7 +20,6 b'' | |||||
20 |
|
20 | |||
21 | import logging |
|
21 | import logging | |
22 | import urllib2 |
|
22 | import urllib2 | |
23 | import packaging.version |
|
|||
24 |
|
23 | |||
25 | from pyramid.view import view_config |
|
24 | from pyramid.view import view_config | |
26 |
|
25 | |||
@@ -31,8 +30,7 b' from rhodecode.lib import helpers as h' | |||||
31 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) |
|
30 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) | |
32 | from rhodecode.lib.utils2 import str2bool |
|
31 | from rhodecode.lib.utils2 import str2bool | |
33 | from rhodecode.lib import system_info |
|
32 | from rhodecode.lib import system_info | |
34 |
from rhodecode.l |
|
33 | from rhodecode.model.update import UpdateModel | |
35 | from rhodecode.model.settings import SettingsModel |
|
|||
36 |
|
34 | |||
37 | log = logging.getLogger(__name__) |
|
35 | log = logging.getLogger(__name__) | |
38 |
|
36 | |||
@@ -40,26 +38,8 b' log = logging.getLogger(__name__)' | |||||
40 | class AdminSystemInfoSettingsView(BaseAppView): |
|
38 | class AdminSystemInfoSettingsView(BaseAppView): | |
41 | def load_default_context(self): |
|
39 | def load_default_context(self): | |
42 | c = self._get_local_tmpl_context() |
|
40 | c = self._get_local_tmpl_context() | |
43 | self._register_global_c(c) |
|
|||
44 | return c |
|
41 | return c | |
45 |
|
42 | |||
46 | @staticmethod |
|
|||
47 | def get_update_data(update_url): |
|
|||
48 | """Return the JSON update data.""" |
|
|||
49 | ver = rhodecode.__version__ |
|
|||
50 | log.debug('Checking for upgrade on `%s` server', update_url) |
|
|||
51 | opener = urllib2.build_opener() |
|
|||
52 | opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)] |
|
|||
53 | response = opener.open(update_url) |
|
|||
54 | response_data = response.read() |
|
|||
55 | data = json.loads(response_data) |
|
|||
56 |
|
||||
57 | return data |
|
|||
58 |
|
||||
59 | def get_update_url(self): |
|
|||
60 | settings = SettingsModel().get_all_settings() |
|
|||
61 | return settings.get('rhodecode_update_url') |
|
|||
62 |
|
||||
63 | @LoginRequired() |
|
43 | @LoginRequired() | |
64 | @HasPermissionAllDecorator('hg.admin') |
|
44 | @HasPermissionAllDecorator('hg.admin') | |
65 | @view_config( |
|
45 | @view_config( | |
@@ -77,7 +57,7 b' class AdminSystemInfoSettingsView(BaseAp' | |||||
77 |
|
57 | |||
78 | snapshot = str2bool(self.request.params.get('snapshot')) |
|
58 | snapshot = str2bool(self.request.params.get('snapshot')) | |
79 |
|
59 | |||
80 |
c.rhodecode_update_url = |
|
60 | c.rhodecode_update_url = UpdateModel().get_update_url() | |
81 | server_info = system_info.get_system_info(self.request.environ) |
|
61 | server_info = system_info.get_system_info(self.request.environ) | |
82 |
|
62 | |||
83 | for key, val in server_info.items(): |
|
63 | for key, val in server_info.items(): | |
@@ -97,6 +77,14 b' class AdminSystemInfoSettingsView(BaseAp' | |||||
97 | update_info_msg = _('Note: please make sure this server can ' |
|
77 | update_info_msg = _('Note: please make sure this server can ' | |
98 | 'access `${url}` for the update link to work', |
|
78 | 'access `${url}` for the update link to work', | |
99 | mapping=dict(url=c.rhodecode_update_url)) |
|
79 | mapping=dict(url=c.rhodecode_update_url)) | |
|
80 | version = UpdateModel().get_stored_version() | |||
|
81 | is_outdated = UpdateModel().is_outdated( | |||
|
82 | rhodecode.__version__, version) | |||
|
83 | update_state = { | |||
|
84 | 'type': 'warning', | |||
|
85 | 'message': 'New version available: {}'.format(version) | |||
|
86 | } \ | |||
|
87 | if is_outdated else {} | |||
100 | c.data_items = [ |
|
88 | c.data_items = [ | |
101 | # update info |
|
89 | # update info | |
102 | (_('Update info'), h.literal( |
|
90 | (_('Update info'), h.literal( | |
@@ -107,6 +95,7 b' class AdminSystemInfoSettingsView(BaseAp' | |||||
107 |
|
95 | |||
108 | # RhodeCode specific |
|
96 | # RhodeCode specific | |
109 | (_('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), | |||
110 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), |
|
99 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), | |
111 | (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), |
|
100 | (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), | |
112 | (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), |
|
101 | (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), | |
@@ -166,8 +155,7 b' class AdminSystemInfoSettingsView(BaseAp' | |||||
166 | c.data_items.pop(0) # remove server info |
|
155 | c.data_items.pop(0) # remove server info | |
167 | self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako' |
|
156 | self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako' | |
168 | else: |
|
157 | else: | |
169 | self.request.session.flash( |
|
158 | h.flash('You are not allowed to do this', category='warning') | |
170 | 'You are not allowed to do this', queue='warning') |
|
|||
171 | return self._get_template_context(c) |
|
159 | return self._get_template_context(c) | |
172 |
|
160 | |||
173 | @LoginRequired() |
|
161 | @LoginRequired() | |
@@ -179,11 +167,11 b' class AdminSystemInfoSettingsView(BaseAp' | |||||
179 | _ = self.request.translate |
|
167 | _ = self.request.translate | |
180 | c = self.load_default_context() |
|
168 | c = self.load_default_context() | |
181 |
|
169 | |||
182 |
update_url = |
|
170 | update_url = UpdateModel().get_update_url() | |
183 |
|
171 | |||
184 | _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">{}</div>'.format(s) |
|
172 | _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">{}</div>'.format(s) | |
185 | try: |
|
173 | try: | |
186 |
data = |
|
174 | data = UpdateModel().get_update_data(update_url) | |
187 | except urllib2.URLError as e: |
|
175 | except urllib2.URLError as e: | |
188 | log.exception("Exception contacting upgrade server") |
|
176 | log.exception("Exception contacting upgrade server") | |
189 | self.request.override_renderer = 'string' |
|
177 | self.request.override_renderer = 'string' | |
@@ -201,9 +189,9 b' class AdminSystemInfoSettingsView(BaseAp' | |||||
201 | c.cur_ver = rhodecode.__version__ |
|
189 | c.cur_ver = rhodecode.__version__ | |
202 | c.should_upgrade = False |
|
190 | c.should_upgrade = False | |
203 |
|
191 | |||
204 | if (packaging.version.Version(c.latest_ver) > |
|
192 | is_oudated = UpdateModel().is_outdated(c.cur_ver, c.latest_ver) | |
205 | packaging.version.Version(c.cur_ver)): |
|
193 | if is_oudated: | |
206 | c.should_upgrade = True |
|
194 | c.should_upgrade = True | |
207 | c.important_notices = latest['general'] |
|
195 | c.important_notices = latest['general'] | |
208 |
|
196 | UpdateModel().store_version(latest['version']) | ||
209 | return self._get_template_context(c) |
|
197 | return self._get_template_context(c) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -53,7 +53,6 b' class AdminUserGroupsView(BaseAppView, D' | |||||
53 | PermissionModel().set_global_permission_choices( |
|
53 | PermissionModel().set_global_permission_choices( | |
54 | c, gettext_translator=self.request.translate) |
|
54 | c, gettext_translator=self.request.translate) | |
55 |
|
55 | |||
56 | self._register_global_c(c) |
|
|||
57 | return c |
|
56 | return c | |
58 |
|
57 | |||
59 | # permission check in data loading of |
|
58 | # permission check in data loading of | |
@@ -74,6 +73,7 b' class AdminUserGroupsView(BaseAppView, D' | |||||
74 | route_name='user_groups_data', request_method='GET', |
|
73 | route_name='user_groups_data', request_method='GET', | |
75 | renderer='json_ext', xhr=True) |
|
74 | renderer='json_ext', xhr=True) | |
76 | def user_groups_list_data(self): |
|
75 | def user_groups_list_data(self): | |
|
76 | self.load_default_context() | |||
77 | column_map = { |
|
77 | column_map = { | |
78 | 'active': 'users_group_active', |
|
78 | 'active': 'users_group_active', | |
79 | 'description': 'user_group_description', |
|
79 | 'description': 'user_group_description', | |
@@ -86,7 +86,7 b' class AdminUserGroupsView(BaseAppView, D' | |||||
86 | self.request, column_map=column_map) |
|
86 | self.request, column_map=column_map) | |
87 |
|
87 | |||
88 | _render = self.request.get_partial_renderer( |
|
88 | _render = self.request.get_partial_renderer( | |
89 | 'data_table/_dt_elements.mako') |
|
89 | 'rhodecode:templates/data_table/_dt_elements.mako') | |
90 |
|
90 | |||
91 | def user_group_name(user_group_id, user_group_name): |
|
91 | def user_group_name(user_group_id, user_group_name): | |
92 | return _render("user_group_name", user_group_id, user_group_name) |
|
92 | return _render("user_group_name", user_group_id, user_group_name) | |
@@ -195,7 +195,7 b' class AdminUserGroupsView(BaseAppView, D' | |||||
195 | def user_groups_create(self): |
|
195 | def user_groups_create(self): | |
196 | _ = self.request.translate |
|
196 | _ = self.request.translate | |
197 | c = self.load_default_context() |
|
197 | c = self.load_default_context() | |
198 | users_group_form = UserGroupForm()() |
|
198 | users_group_form = UserGroupForm(self.request.translate)() | |
199 |
|
199 | |||
200 | user_group_name = self.request.POST.get('users_group_name') |
|
200 | user_group_name = self.request.POST.get('users_group_name') | |
201 | try: |
|
201 | try: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -44,7 +44,8 b' from rhodecode.lib import helpers as h' | |||||
44 | from rhodecode.lib.utils2 import safe_int, safe_unicode, AttributeDict |
|
44 | from rhodecode.lib.utils2 import safe_int, safe_unicode, AttributeDict | |
45 | from rhodecode.model.auth_token import AuthTokenModel |
|
45 | from rhodecode.model.auth_token import AuthTokenModel | |
46 | from rhodecode.model.forms import ( |
|
46 | from rhodecode.model.forms import ( | |
47 |
UserForm, UserIndividualPermissionsForm, UserPermissionsForm |
|
47 | UserForm, UserIndividualPermissionsForm, UserPermissionsForm, | |
|
48 | UserExtraEmailForm, UserExtraIpForm) | |||
48 | from rhodecode.model.permission import PermissionModel |
|
49 | from rhodecode.model.permission import PermissionModel | |
49 | from rhodecode.model.repo_group import RepoGroupModel |
|
50 | from rhodecode.model.repo_group import RepoGroupModel | |
50 | from rhodecode.model.ssh_key import SshKeyModel |
|
51 | from rhodecode.model.ssh_key import SshKeyModel | |
@@ -62,7 +63,6 b' class AdminUsersView(BaseAppView, DataGr' | |||||
62 |
|
63 | |||
63 | def load_default_context(self): |
|
64 | def load_default_context(self): | |
64 | c = self._get_local_tmpl_context() |
|
65 | c = self._get_local_tmpl_context() | |
65 | self._register_global_c(c) |
|
|||
66 | return c |
|
66 | return c | |
67 |
|
67 | |||
68 | @LoginRequired() |
|
68 | @LoginRequired() | |
@@ -81,6 +81,7 b' class AdminUsersView(BaseAppView, DataGr' | |||||
81 | route_name='users_data', request_method='GET', |
|
81 | route_name='users_data', request_method='GET', | |
82 | renderer='json_ext', xhr=True) |
|
82 | renderer='json_ext', xhr=True) | |
83 | def users_list_data(self): |
|
83 | def users_list_data(self): | |
|
84 | self.load_default_context() | |||
84 | column_map = { |
|
85 | column_map = { | |
85 | 'first_name': 'name', |
|
86 | 'first_name': 'name', | |
86 | 'last_name': 'lastname', |
|
87 | 'last_name': 'lastname', | |
@@ -90,7 +91,7 b' class AdminUsersView(BaseAppView, DataGr' | |||||
90 | self.request, column_map=column_map) |
|
91 | self.request, column_map=column_map) | |
91 |
|
92 | |||
92 | _render = self.request.get_partial_renderer( |
|
93 | _render = self.request.get_partial_renderer( | |
93 | 'data_table/_dt_elements.mako') |
|
94 | 'rhodecode:templates/data_table/_dt_elements.mako') | |
94 |
|
95 | |||
95 | def user_actions(user_id, username): |
|
96 | def user_actions(user_id, username): | |
96 | return _render("user_actions", user_id, username) |
|
97 | return _render("user_actions", user_id, username) | |
@@ -190,7 +191,7 b' class AdminUsersView(BaseAppView, DataGr' | |||||
190 | c = self.load_default_context() |
|
191 | c = self.load_default_context() | |
191 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name |
|
192 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name | |
192 | user_model = UserModel() |
|
193 | user_model = UserModel() | |
193 | user_form = UserForm()() |
|
194 | user_form = UserForm(self.request.translate)() | |
194 | try: |
|
195 | try: | |
195 | form_result = user_form.to_python(dict(self.request.POST)) |
|
196 | form_result = user_form.to_python(dict(self.request.POST)) | |
196 | user = user_model.create(form_result) |
|
197 | user = user_model.create(form_result) | |
@@ -258,7 +259,6 b' class UsersView(UserAppView):' | |||||
258 | PermissionModel().set_global_permission_choices( |
|
259 | PermissionModel().set_global_permission_choices( | |
259 | c, gettext_translator=req.translate) |
|
260 | c, gettext_translator=req.translate) | |
260 |
|
261 | |||
261 | self._register_global_c(c) |
|
|||
262 | return c |
|
262 | return c | |
263 |
|
263 | |||
264 | @LoginRequired() |
|
264 | @LoginRequired() | |
@@ -279,7 +279,8 b' class UsersView(UserAppView):' | |||||
279 | c.extern_name = c.user.extern_name |
|
279 | c.extern_name = c.user.extern_name | |
280 | c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) |
|
280 | c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) | |
281 | available_languages = [x[0] for x in c.allowed_languages] |
|
281 | available_languages = [x[0] for x in c.allowed_languages] | |
282 | _form = UserForm(edit=True, available_languages=available_languages, |
|
282 | _form = UserForm(self.request.translate, edit=True, | |
|
283 | available_languages=available_languages, | |||
283 | old_data={'user_id': user_id, |
|
284 | old_data={'user_id': user_id, | |
284 | 'email': c.user.email})() |
|
285 | 'email': c.user.email})() | |
285 | form_result = {} |
|
286 | form_result = {} | |
@@ -537,7 +538,7 b' class UsersView(UserAppView):' | |||||
537 | c.active = 'global_perms' |
|
538 | c.active = 'global_perms' | |
538 | try: |
|
539 | try: | |
539 | # first stage that verifies the checkbox |
|
540 | # first stage that verifies the checkbox | |
540 | _form = UserIndividualPermissionsForm() |
|
541 | _form = UserIndividualPermissionsForm(self.request.translate) | |
541 | form_result = _form.to_python(dict(self.request.POST)) |
|
542 | form_result = _form.to_python(dict(self.request.POST)) | |
542 | inherit_perms = form_result['inherit_default_permissions'] |
|
543 | inherit_perms = form_result['inherit_default_permissions'] | |
543 | c.user.inherit_default_permissions = inherit_perms |
|
544 | c.user.inherit_default_permissions = inherit_perms | |
@@ -546,6 +547,7 b' class UsersView(UserAppView):' | |||||
546 | if not inherit_perms: |
|
547 | if not inherit_perms: | |
547 | # only update the individual ones if we un check the flag |
|
548 | # only update the individual ones if we un check the flag | |
548 | _form = UserPermissionsForm( |
|
549 | _form = UserPermissionsForm( | |
|
550 | self.request.translate, | |||
549 | [x[0] for x in c.repo_create_choices], |
|
551 | [x[0] for x in c.repo_create_choices], | |
550 | [x[0] for x in c.repo_create_on_write_choices], |
|
552 | [x[0] for x in c.repo_create_on_write_choices], | |
551 | [x[0] for x in c.repo_group_create_choices], |
|
553 | [x[0] for x in c.repo_group_create_choices], | |
@@ -913,6 +915,11 b' class UsersView(UserAppView):' | |||||
913 | email = self.request.POST.get('new_email') |
|
915 | email = self.request.POST.get('new_email') | |
914 | user_data = c.user.get_api_data() |
|
916 | user_data = c.user.get_api_data() | |
915 | try: |
|
917 | try: | |
|
918 | ||||
|
919 | form = UserExtraEmailForm(self.request.translate)() | |||
|
920 | data = form.to_python({'email': email}) | |||
|
921 | email = data['email'] | |||
|
922 | ||||
916 | UserModel().add_extra_email(c.user.user_id, email) |
|
923 | UserModel().add_extra_email(c.user.user_id, email) | |
917 | audit_logger.store_web( |
|
924 | audit_logger.store_web( | |
918 | 'user.edit.email.add', |
|
925 | 'user.edit.email.add', | |
@@ -1008,6 +1015,10 b' class UsersView(UserAppView):' | |||||
1008 | user_data = c.user.get_api_data() |
|
1015 | user_data = c.user.get_api_data() | |
1009 | for ip in ip_list: |
|
1016 | for ip in ip_list: | |
1010 | try: |
|
1017 | try: | |
|
1018 | form = UserExtraIpForm(self.request.translate)() | |||
|
1019 | data = form.to_python({'ip': ip}) | |||
|
1020 | ip = data['ip'] | |||
|
1021 | ||||
1011 | user_model.add_extra_ip(c.user.user_id, ip, desc) |
|
1022 | user_model.add_extra_ip(c.user.user_id, ip, desc) | |
1012 | audit_logger.store_web( |
|
1023 | audit_logger.store_web( | |
1013 | 'user.edit.ip.add', |
|
1024 | 'user.edit.ip.add', |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -20,9 +20,10 b'' | |||||
20 |
|
20 | |||
21 | import os |
|
21 | import os | |
22 |
|
22 | |||
|
23 | from pyramid.events import ApplicationCreated | |||
23 | from pyramid.settings import asbool |
|
24 | from pyramid.settings import asbool | |
24 |
|
25 | |||
25 |
from rhodecode. |
|
26 | from rhodecode.apps._base import ADMIN_PREFIX | |
26 | from rhodecode.lib.ext_json import json |
|
27 | from rhodecode.lib.ext_json import json | |
27 |
|
28 | |||
28 |
|
29 | |||
@@ -57,6 +58,14 b' PLUGIN_DEFINITION = {' | |||||
57 | } |
|
58 | } | |
58 |
|
59 | |||
59 |
|
60 | |||
|
61 | def maybe_create_history_store(event): | |||
|
62 | # create plugin history location | |||
|
63 | settings = event.app.registry.settings | |||
|
64 | history_dir = settings.get('channelstream.history.location', '') | |||
|
65 | if history_dir and not os.path.exists(history_dir): | |||
|
66 | os.makedirs(history_dir, 0750) | |||
|
67 | ||||
|
68 | ||||
60 | def includeme(config): |
|
69 | def includeme(config): | |
61 | settings = config.registry.settings |
|
70 | settings = config.registry.settings | |
62 | PLUGIN_DEFINITION['config']['enabled'] = asbool( |
|
71 | PLUGIN_DEFINITION['config']['enabled'] = asbool( | |
@@ -71,10 +80,7 b' def includeme(config):' | |||||
71 | PLUGIN_DEFINITION['name'], |
|
80 | PLUGIN_DEFINITION['name'], | |
72 | PLUGIN_DEFINITION['config'] |
|
81 | PLUGIN_DEFINITION['config'] | |
73 | ) |
|
82 | ) | |
74 | # create plugin history location |
|
83 | config.add_subscriber(maybe_create_history_store, ApplicationCreated) | |
75 | history_dir = PLUGIN_DEFINITION['config']['history.location'] |
|
|||
76 | if history_dir and not os.path.exists(history_dir): |
|
|||
77 | os.makedirs(history_dir, 0750) |
|
|||
78 |
|
84 | |||
79 | config.add_route( |
|
85 | config.add_route( | |
80 | name='channelstream_connect', |
|
86 | name='channelstream_connect', |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -24,6 +24,7 b' import uuid' | |||||
24 | from pyramid.view import view_config |
|
24 | from pyramid.view import view_config | |
25 | from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPBadGateway |
|
25 | from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPBadGateway | |
26 |
|
26 | |||
|
27 | from rhodecode.apps._base import BaseAppView | |||
27 | from rhodecode.lib.channelstream import ( |
|
28 | from rhodecode.lib.channelstream import ( | |
28 | channelstream_request, |
|
29 | channelstream_request, | |
29 | ChannelstreamConnectionException, |
|
30 | ChannelstreamConnectionException, | |
@@ -34,28 +35,28 b' from rhodecode.lib.channelstream import ' | |||||
34 | parse_channels_info, |
|
35 | parse_channels_info, | |
35 | update_history_from_logs, |
|
36 | update_history_from_logs, | |
36 | STATE_PUBLIC_KEYS) |
|
37 | STATE_PUBLIC_KEYS) | |
|
38 | ||||
37 | from rhodecode.lib.auth import NotAnonymous |
|
39 | from rhodecode.lib.auth import NotAnonymous | |
38 |
|
40 | |||
39 | log = logging.getLogger(__name__) |
|
41 | log = logging.getLogger(__name__) | |
40 |
|
42 | |||
41 |
|
43 | |||
42 |
class ChannelstreamView( |
|
44 | class ChannelstreamView(BaseAppView): | |
43 | def __init__(self, context, request): |
|
|||
44 | self.context = context |
|
|||
45 | self.request = request |
|
|||
46 |
|
45 | |||
47 | # Some of the decorators rely on this attribute to be present |
|
46 | def load_default_context(self): | |
48 | # on the class of the decorated method. |
|
47 | c = self._get_local_tmpl_context() | |
49 | self._rhodecode_user = request.user |
|
48 | self.channelstream_config = \ | |
50 | registry = request.registry |
|
49 | self.request.registry.rhodecode_plugins['channelstream'] | |
51 | self.channelstream_config = registry.rhodecode_plugins['channelstream'] |
|
|||
52 | if not self.channelstream_config.get('enabled'): |
|
50 | if not self.channelstream_config.get('enabled'): | |
53 | log.error('Channelstream plugin is disabled') |
|
51 | log.error('Channelstream plugin is disabled') | |
54 | raise HTTPBadRequest() |
|
52 | raise HTTPBadRequest() | |
55 |
|
53 | |||
|
54 | return c | |||
|
55 | ||||
56 | @NotAnonymous() |
|
56 | @NotAnonymous() | |
57 | @view_config(route_name='channelstream_connect', renderer='json') |
|
57 | @view_config(route_name='channelstream_connect', renderer='json_ext') | |
58 | def connect(self): |
|
58 | def connect(self): | |
|
59 | self.load_default_context() | |||
59 | """ handle authorization of users trying to connect """ |
|
60 | """ handle authorization of users trying to connect """ | |
60 | try: |
|
61 | try: | |
61 | json_body = self.request.json_body |
|
62 | json_body = self.request.json_body | |
@@ -122,9 +123,10 b' class ChannelstreamView(object):' | |||||
122 | return connect_result |
|
123 | return connect_result | |
123 |
|
124 | |||
124 | @NotAnonymous() |
|
125 | @NotAnonymous() | |
125 | @view_config(route_name='channelstream_subscribe', renderer='json') |
|
126 | @view_config(route_name='channelstream_subscribe', renderer='json_ext') | |
126 | def subscribe(self): |
|
127 | def subscribe(self): | |
127 | """ can be used to subscribe specific connection to other channels """ |
|
128 | """ can be used to subscribe specific connection to other channels """ | |
|
129 | self.load_default_context() | |||
128 | try: |
|
130 | try: | |
129 | json_body = self.request.json_body |
|
131 | json_body = self.request.json_body | |
130 | except Exception: |
|
132 | except Exception: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -31,7 +31,7 b' log = logging.getLogger(__name__)' | |||||
31 | class DebugStyleView(BaseAppView): |
|
31 | class DebugStyleView(BaseAppView): | |
32 | def load_default_context(self): |
|
32 | def load_default_context(self): | |
33 | c = self._get_local_tmpl_context() |
|
33 | c = self._get_local_tmpl_context() | |
34 | self._register_global_c(c) |
|
34 | ||
35 | return c |
|
35 | return c | |
36 |
|
36 | |||
37 | @view_config( |
|
37 | @view_config( |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2013-201 |
|
3 | # Copyright (C) 2013-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -67,7 +67,7 b' class GistView(BaseAppView):' | |||||
67 | (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users")) |
|
67 | (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users")) | |
68 | ] |
|
68 | ] | |
69 |
|
69 | |||
70 | self._register_global_c(c) |
|
70 | ||
71 | return c |
|
71 | return c | |
72 |
|
72 | |||
73 | @LoginRequired() |
|
73 | @LoginRequired() | |
@@ -114,7 +114,7 b' class GistView(BaseAppView):' | |||||
114 | c.active = 'public' |
|
114 | c.active = 'public' | |
115 |
|
115 | |||
116 | _render = self.request.get_partial_renderer( |
|
116 | _render = self.request.get_partial_renderer( | |
117 | 'data_table/_dt_elements.mako') |
|
117 | 'rhodecode:templates/data_table/_dt_elements.mako') | |
118 |
|
118 | |||
119 | data = [] |
|
119 | data = [] | |
120 |
|
120 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -66,7 +66,7 b' class TestGotoSwitcherData(TestControlle' | |||||
66 | ] |
|
66 | ] | |
67 |
|
67 | |||
68 | @pytest.fixture(autouse=True, scope='class') |
|
68 | @pytest.fixture(autouse=True, scope='class') | |
69 |
def prepare(self, request, |
|
69 | def prepare(self, request, baseapp): | |
70 | for repo_and_group in self.required_repos_with_groups: |
|
70 | for repo_and_group in self.required_repos_with_groups: | |
71 | # create structure of groups and return the last group |
|
71 | # create structure of groups and return the last group | |
72 |
|
72 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -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 | # -*- coding: utf-8 -*- |
|
20 | # -*- coding: utf-8 -*- | |
21 |
|
21 | |||
22 |
# Copyright (C) 2016-201 |
|
22 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
23 | # |
|
23 | # | |
24 | # This program is free software: you can redistribute it and/or modify |
|
24 | # This program is free software: you can redistribute it and/or modify | |
25 | # it under the terms of the GNU Affero General Public License, version 3 |
|
25 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -46,7 +46,7 b' class HomeView(BaseAppView):' | |||||
46 | def load_default_context(self): |
|
46 | def load_default_context(self): | |
47 | c = self._get_local_tmpl_context() |
|
47 | c = self._get_local_tmpl_context() | |
48 | c.user = c.auth_user.get_instance() |
|
48 | c.user = c.auth_user.get_instance() | |
49 | self._register_global_c(c) |
|
49 | ||
50 | return c |
|
50 | return c | |
51 |
|
51 | |||
52 | @LoginRequired() |
|
52 | @LoginRequired() | |
@@ -54,6 +54,7 b' class HomeView(BaseAppView):' | |||||
54 | route_name='user_autocomplete_data', request_method='GET', |
|
54 | route_name='user_autocomplete_data', request_method='GET', | |
55 | renderer='json_ext', xhr=True) |
|
55 | renderer='json_ext', xhr=True) | |
56 | def user_autocomplete_data(self): |
|
56 | def user_autocomplete_data(self): | |
|
57 | self.load_default_context() | |||
57 | query = self.request.GET.get('query') |
|
58 | query = self.request.GET.get('query') | |
58 | active = str2bool(self.request.GET.get('active') or True) |
|
59 | active = str2bool(self.request.GET.get('active') or True) | |
59 | include_groups = str2bool(self.request.GET.get('user_groups')) |
|
60 | include_groups = str2bool(self.request.GET.get('user_groups')) | |
@@ -87,6 +88,7 b' class HomeView(BaseAppView):' | |||||
87 | route_name='user_group_autocomplete_data', request_method='GET', |
|
88 | route_name='user_group_autocomplete_data', request_method='GET', | |
88 | renderer='json_ext', xhr=True) |
|
89 | renderer='json_ext', xhr=True) | |
89 | def user_group_autocomplete_data(self): |
|
90 | def user_group_autocomplete_data(self): | |
|
91 | self.load_default_context() | |||
90 | query = self.request.GET.get('query') |
|
92 | query = self.request.GET.get('query') | |
91 | active = str2bool(self.request.GET.get('active') or True) |
|
93 | active = str2bool(self.request.GET.get('active') or True) | |
92 | expand_groups = str2bool(self.request.GET.get('user_groups_expand')) |
|
94 | expand_groups = str2bool(self.request.GET.get('user_groups_expand')) | |
@@ -202,6 +204,7 b' class HomeView(BaseAppView):' | |||||
202 | renderer='json_ext', xhr=True) |
|
204 | renderer='json_ext', xhr=True) | |
203 | def repo_list_data(self): |
|
205 | def repo_list_data(self): | |
204 | _ = self.request.translate |
|
206 | _ = self.request.translate | |
|
207 | self.load_default_context() | |||
205 |
|
208 | |||
206 | query = self.request.GET.get('query') |
|
209 | query = self.request.GET.get('query') | |
207 | repo_type = self.request.GET.get('repo_type') |
|
210 | repo_type = self.request.GET.get('repo_type') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -47,7 +47,7 b' class JournalView(BaseAppView):' | |||||
47 |
|
47 | |||
48 | def load_default_context(self): |
|
48 | def load_default_context(self): | |
49 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
49 | c = self._get_local_tmpl_context(include_app_defaults=True) | |
50 | self._register_global_c(c) |
|
50 | ||
51 | self._load_defaults(c.rhodecode_name) |
|
51 | self._load_defaults(c.rhodecode_name) | |
52 |
|
52 | |||
53 | # TODO(marcink): what is this, why we need a global register ? |
|
53 | # TODO(marcink): what is this, why we need a global register ? | |
@@ -146,7 +146,8 b' class JournalView(BaseAppView):' | |||||
146 | user = AttributeDict({'short_contact': entry.username, |
|
146 | user = AttributeDict({'short_contact': entry.username, | |
147 | 'email': '', |
|
147 | 'email': '', | |
148 | 'full_contact': ''}) |
|
148 | 'full_contact': ''}) | |
149 |
action, action_extra, ico = h.action_parser( |
|
149 | action, action_extra, ico = h.action_parser( | |
|
150 | self.request, entry, feed=True) | |||
150 | title = "%s - %s %s" % (user.short_contact, action(), |
|
151 | title = "%s - %s %s" % (user.short_contact, action(), | |
151 | entry.repository.repo_name) |
|
152 | entry.repository.repo_name) | |
152 | desc = action_extra() |
|
153 | desc = action_extra() | |
@@ -191,7 +192,8 b' class JournalView(BaseAppView):' | |||||
191 | user = AttributeDict({'short_contact': entry.username, |
|
192 | user = AttributeDict({'short_contact': entry.username, | |
192 | 'email': '', |
|
193 | 'email': '', | |
193 | 'full_contact': ''}) |
|
194 | 'full_contact': ''}) | |
194 |
action, action_extra, ico = h.action_parser( |
|
195 | action, action_extra, ico = h.action_parser( | |
|
196 | self.request, entry, feed=True) | |||
195 | title = "%s - %s %s" % (user.short_contact, action(), |
|
197 | title = "%s - %s %s" % (user.short_contact, action(), | |
196 | entry.repository.repo_name) |
|
198 | entry.repository.repo_name) | |
197 | desc = action_extra() |
|
199 | desc = action_extra() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -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. |
|
22 | from rhodecode.apps._base import ADMIN_PREFIX | |
23 |
|
23 | |||
24 |
|
24 | |||
25 | def includeme(config): |
|
25 | def includeme(config): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -30,7 +30,6 b' from rhodecode.tests.fixture import Fixt' | |||||
30 | from rhodecode.lib.auth import check_password |
|
30 | from rhodecode.lib.auth import check_password | |
31 | from rhodecode.lib import helpers as h |
|
31 | from rhodecode.lib import helpers as h | |
32 | from rhodecode.model.auth_token import AuthTokenModel |
|
32 | from rhodecode.model.auth_token import AuthTokenModel | |
33 | from rhodecode.model import validators |
|
|||
34 | from rhodecode.model.db import User, Notification, UserApiKeys |
|
33 | from rhodecode.model.db import User, Notification, UserApiKeys | |
35 | from rhodecode.model.meta import Session |
|
34 | from rhodecode.model.meta import Session | |
36 |
|
35 | |||
@@ -89,32 +88,31 b' class TestLoginController(object):' | |||||
89 | def test_login_admin_ok(self): |
|
88 | def test_login_admin_ok(self): | |
90 | response = self.app.post(route_path('login'), |
|
89 | response = self.app.post(route_path('login'), | |
91 | {'username': 'test_admin', |
|
90 | {'username': 'test_admin', | |
92 | 'password': 'test12'}) |
|
91 | 'password': 'test12'}, status=302) | |
93 | assert response.status == '302 Found' |
|
92 | response = response.follow() | |
94 | session = response.get_session_from_response() |
|
93 | session = response.get_session_from_response() | |
95 | username = session['rhodecode_user'].get('username') |
|
94 | username = session['rhodecode_user'].get('username') | |
96 | assert username == 'test_admin' |
|
95 | assert username == 'test_admin' | |
97 | response = response.follow() |
|
|||
98 | response.mustcontain('/%s' % HG_REPO) |
|
96 | response.mustcontain('/%s' % HG_REPO) | |
99 |
|
97 | |||
100 | def test_login_regular_ok(self): |
|
98 | def test_login_regular_ok(self): | |
101 | response = self.app.post(route_path('login'), |
|
99 | response = self.app.post(route_path('login'), | |
102 | {'username': 'test_regular', |
|
100 | {'username': 'test_regular', | |
103 | 'password': 'test12'}) |
|
101 | 'password': 'test12'}, status=302) | |
104 |
|
102 | |||
105 | assert response.status == '302 Found' |
|
103 | response = response.follow() | |
106 | session = response.get_session_from_response() |
|
104 | session = response.get_session_from_response() | |
107 | username = session['rhodecode_user'].get('username') |
|
105 | username = session['rhodecode_user'].get('username') | |
108 | assert username == 'test_regular' |
|
106 | assert username == 'test_regular' | |
109 | response = response.follow() |
|
107 | ||
110 | response.mustcontain('/%s' % HG_REPO) |
|
108 | response.mustcontain('/%s' % HG_REPO) | |
111 |
|
109 | |||
112 | def test_login_ok_came_from(self): |
|
110 | def test_login_ok_came_from(self): | |
113 | test_came_from = '/_admin/users?branch=stable' |
|
111 | test_came_from = '/_admin/users?branch=stable' | |
114 | _url = '{}?came_from={}'.format(route_path('login'), test_came_from) |
|
112 | _url = '{}?came_from={}'.format(route_path('login'), test_came_from) | |
115 | response = self.app.post( |
|
113 | response = self.app.post( | |
116 | _url, {'username': 'test_admin', 'password': 'test12'}) |
|
114 | _url, {'username': 'test_admin', 'password': 'test12'}, status=302) | |
117 | assert response.status == '302 Found' |
|
115 | ||
118 | assert 'branch=stable' in response.location |
|
116 | assert 'branch=stable' in response.location | |
119 | response = response.follow() |
|
117 | response = response.follow() | |
120 |
|
118 | |||
@@ -125,8 +123,8 b' class TestLoginController(object):' | |||||
125 | with fixture.anon_access(False): |
|
123 | with fixture.anon_access(False): | |
126 | kwargs = {'branch': 'stable'} |
|
124 | kwargs = {'branch': 'stable'} | |
127 | response = self.app.get( |
|
125 | response = self.app.get( | |
128 |
h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs) |
|
126 | h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs), | |
129 |
|
|
127 | status=302) | |
130 |
|
128 | |||
131 | response_query = urlparse.parse_qsl(response.location) |
|
129 | response_query = urlparse.parse_qsl(response.location) | |
132 | assert 'branch=stable' in response_query[0][1] |
|
130 | assert 'branch=stable' in response_query[0][1] | |
@@ -201,13 +199,12 b' class TestLoginController(object):' | |||||
201 | self.destroy_users.add(temp_user) |
|
199 | self.destroy_users.add(temp_user) | |
202 | response = self.app.post(route_path('login'), |
|
200 | response = self.app.post(route_path('login'), | |
203 | {'username': temp_user, |
|
201 | {'username': temp_user, | |
204 | 'password': 'test123'}) |
|
202 | 'password': 'test123'}, status=302) | |
205 |
|
203 | |||
206 | assert response.status == '302 Found' |
|
204 | response = response.follow() | |
207 | session = response.get_session_from_response() |
|
205 | session = response.get_session_from_response() | |
208 | username = session['rhodecode_user'].get('username') |
|
206 | username = session['rhodecode_user'].get('username') | |
209 | assert username == temp_user |
|
207 | assert username == temp_user | |
210 | response = response.follow() |
|
|||
211 | response.mustcontain('/%s' % HG_REPO) |
|
208 | response.mustcontain('/%s' % HG_REPO) | |
212 |
|
209 | |||
213 | # new password should be bcrypted, after log-in and transfer |
|
210 | # new password should be bcrypted, after log-in and transfer | |
@@ -234,7 +231,7 b' class TestLoginController(object):' | |||||
234 | ) |
|
231 | ) | |
235 |
|
232 | |||
236 | assertr = response.assert_response() |
|
233 | assertr = response.assert_response() | |
237 |
msg = |
|
234 | msg = 'Username "%(username)s" already exists' | |
238 | msg = msg % {'username': uname} |
|
235 | msg = msg % {'username': uname} | |
239 | assertr.element_contains('#username+.error-message', msg) |
|
236 | assertr.element_contains('#username+.error-message', msg) | |
240 |
|
237 | |||
@@ -252,7 +249,7 b' class TestLoginController(object):' | |||||
252 | ) |
|
249 | ) | |
253 |
|
250 | |||
254 | assertr = response.assert_response() |
|
251 | assertr = response.assert_response() | |
255 | msg = validators.UniqSystemEmail()()._messages['email_taken'] |
|
252 | msg = u'This e-mail address is already taken' | |
256 | assertr.element_contains('#email+.error-message', msg) |
|
253 | assertr.element_contains('#email+.error-message', msg) | |
257 |
|
254 | |||
258 | def test_register_err_same_email_case_sensitive(self): |
|
255 | def test_register_err_same_email_case_sensitive(self): | |
@@ -268,7 +265,7 b' class TestLoginController(object):' | |||||
268 | } |
|
265 | } | |
269 | ) |
|
266 | ) | |
270 | assertr = response.assert_response() |
|
267 | assertr = response.assert_response() | |
271 | msg = validators.UniqSystemEmail()()._messages['email_taken'] |
|
268 | msg = u'This e-mail address is already taken' | |
272 | assertr.element_contains('#email+.error-message', msg) |
|
269 | assertr.element_contains('#email+.error-message', msg) | |
273 |
|
270 | |||
274 | def test_register_err_wrong_data(self): |
|
271 | def test_register_err_wrong_data(self): | |
@@ -322,7 +319,7 b' class TestLoginController(object):' | |||||
322 | ) |
|
319 | ) | |
323 |
|
320 | |||
324 | assertr = response.assert_response() |
|
321 | assertr = response.assert_response() | |
325 |
msg = |
|
322 | msg = u'Username "%(username)s" already exists' | |
326 | msg = msg % {'username': usr} |
|
323 | msg = msg % {'username': usr} | |
327 | assertr.element_contains('#username+.error-message', msg) |
|
324 | assertr.element_contains('#username+.error-message', msg) | |
328 |
|
325 | |||
@@ -339,7 +336,7 b' class TestLoginController(object):' | |||||
339 | } |
|
336 | } | |
340 | ) |
|
337 | ) | |
341 |
|
338 | |||
342 | msg = validators.ValidPassword()._messages['invalid_password'] |
|
339 | msg = u'Invalid characters (non-ascii) in password' | |
343 | response.mustcontain(msg) |
|
340 | response.mustcontain(msg) | |
344 |
|
341 | |||
345 | def test_register_password_mismatch(self): |
|
342 | def test_register_password_mismatch(self): | |
@@ -354,7 +351,7 b' class TestLoginController(object):' | |||||
354 | 'lastname': 'test' |
|
351 | 'lastname': 'test' | |
355 | } |
|
352 | } | |
356 | ) |
|
353 | ) | |
357 | msg = validators.ValidPasswordsMatch()._messages['password_mismatch'] |
|
354 | msg = u'Passwords do not match' | |
358 | response.mustcontain(msg) |
|
355 | response.mustcontain(msg) | |
359 |
|
356 | |||
360 | def test_register_ok(self): |
|
357 | def test_register_ok(self): | |
@@ -364,6 +361,11 b' class TestLoginController(object):' | |||||
364 | name = 'testname' |
|
361 | name = 'testname' | |
365 | lastname = 'testlastname' |
|
362 | lastname = 'testlastname' | |
366 |
|
363 | |||
|
364 | # this initializes a session | |||
|
365 | response = self.app.get(route_path('register')) | |||
|
366 | response.mustcontain('Create an Account') | |||
|
367 | ||||
|
368 | ||||
367 | response = self.app.post( |
|
369 | response = self.app.post( | |
368 | route_path('register'), |
|
370 | route_path('register'), | |
369 | { |
|
371 | { | |
@@ -374,9 +376,10 b' class TestLoginController(object):' | |||||
374 | 'firstname': name, |
|
376 | 'firstname': name, | |
375 | 'lastname': lastname, |
|
377 | 'lastname': lastname, | |
376 | 'admin': True |
|
378 | 'admin': True | |
377 | } |
|
379 | }, | |
378 | ) # This should be overriden |
|
380 | status=302 | |
379 | assert response.status == '302 Found' |
|
381 | ) # This should be overridden | |
|
382 | ||||
380 | assert_session_flash( |
|
383 | assert_session_flash( | |
381 | response, 'You have successfully registered with RhodeCode') |
|
384 | response, 'You have successfully registered with RhodeCode') | |
382 |
|
385 | |||
@@ -392,6 +395,9 b' class TestLoginController(object):' | |||||
392 |
|
395 | |||
393 | def test_forgot_password_wrong_mail(self): |
|
396 | def test_forgot_password_wrong_mail(self): | |
394 | bad_email = 'marcin@wrongmail.org' |
|
397 | bad_email = 'marcin@wrongmail.org' | |
|
398 | # this initializes a session | |||
|
399 | self.app.get(route_path('reset_password')) | |||
|
400 | ||||
395 | response = self.app.post( |
|
401 | response = self.app.post( | |
396 | route_path('reset_password'), {'email': bad_email, } |
|
402 | route_path('reset_password'), {'email': bad_email, } | |
397 | ) |
|
403 | ) | |
@@ -399,8 +405,8 b' class TestLoginController(object):' | |||||
399 | 'If such email exists, a password reset link was sent to it.') |
|
405 | 'If such email exists, a password reset link was sent to it.') | |
400 |
|
406 | |||
401 | def test_forgot_password(self, user_util): |
|
407 | def test_forgot_password(self, user_util): | |
402 | response = self.app.get(route_path('reset_password')) |
|
408 | # this initializes a session | |
403 | assert response.status == '200 OK' |
|
409 | self.app.get(route_path('reset_password')) | |
404 |
|
410 | |||
405 | user = user_util.create_user() |
|
411 | user = user_util.create_user() | |
406 | user_id = user.user_id |
|
412 | user_id = user.user_id | |
@@ -413,8 +419,7 b' class TestLoginController(object):' | |||||
413 |
|
419 | |||
414 | # BAD KEY |
|
420 | # BAD KEY | |
415 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey') |
|
421 | confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), 'badkey') | |
416 | response = self.app.get(confirm_url) |
|
422 | response = self.app.get(confirm_url, status=302) | |
417 | assert response.status == '302 Found' |
|
|||
418 | assert response.location.endswith(route_path('reset_password')) |
|
423 | assert response.location.endswith(route_path('reset_password')) | |
419 | assert_session_flash(response, 'Given reset token is invalid') |
|
424 | assert_session_flash(response, 'Given reset token is invalid') | |
420 |
|
425 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -22,10 +22,10 b'' | |||||
22 | import mock |
|
22 | import mock | |
23 | import pytest |
|
23 | import pytest | |
24 |
|
24 | |||
|
25 | from rhodecode.apps._base import ADMIN_PREFIX | |||
25 | from rhodecode.apps.login.views import LoginView, CaptchaData |
|
26 | from rhodecode.apps.login.views import LoginView, CaptchaData | |
26 |
from rhodecode. |
|
27 | from rhodecode.model.settings import SettingsModel | |
27 | from rhodecode.lib.utils2 import AttributeDict |
|
28 | from rhodecode.lib.utils2 import AttributeDict | |
28 | from rhodecode.model.settings import SettingsModel |
|
|||
29 | from rhodecode.tests.utils import AssertResponse |
|
29 | from rhodecode.tests.utils import AssertResponse | |
30 |
|
30 | |||
31 |
|
31 | |||
@@ -58,7 +58,7 b' class TestRegisterCaptcha(object):' | |||||
58 | ('privkey', '', CaptchaData(True, 'privkey', '')), |
|
58 | ('privkey', '', CaptchaData(True, 'privkey', '')), | |
59 | ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')), |
|
59 | ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')), | |
60 | ]) |
|
60 | ]) | |
61 |
def test_get_captcha_data(self, private_key, public_key, expected, |
|
61 | def test_get_captcha_data(self, private_key, public_key, expected, | |
62 | request_stub, user_util): |
|
62 | request_stub, user_util): | |
63 | request_stub.user = user_util.create_user().AuthUser() |
|
63 | request_stub.user = user_util.create_user().AuthUser() | |
64 | request_stub.matched_route = AttributeDict({'name': 'login'}) |
|
64 | request_stub.matched_route = AttributeDict({'name': 'login'}) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -32,7 +32,7 b' from recaptcha.client.captcha import sub' | |||||
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.events import UserRegistered |
|
35 | from rhodecode.events import UserRegistered, trigger | |
36 | from rhodecode.lib import helpers as h |
|
36 | from rhodecode.lib import helpers as h | |
37 | from rhodecode.lib import audit_logger |
|
37 | from rhodecode.lib import audit_logger | |
38 | from rhodecode.lib.auth import ( |
|
38 | from rhodecode.lib.auth import ( | |
@@ -113,7 +113,7 b' class LoginView(BaseAppView):' | |||||
113 | def load_default_context(self): |
|
113 | def load_default_context(self): | |
114 | c = self._get_local_tmpl_context() |
|
114 | c = self._get_local_tmpl_context() | |
115 | c.came_from = get_came_from(self.request) |
|
115 | c.came_from = get_came_from(self.request) | |
116 | self._register_global_c(c) |
|
116 | ||
117 | return c |
|
117 | return c | |
118 |
|
118 | |||
119 | def _get_captcha_data(self): |
|
119 | def _get_captcha_data(self): | |
@@ -147,7 +147,7 b' class LoginView(BaseAppView):' | |||||
147 | raise HTTPFound(c.came_from, headers=headers) |
|
147 | raise HTTPFound(c.came_from, headers=headers) | |
148 | except UserCreationError as e: |
|
148 | except UserCreationError as e: | |
149 | log.error(e) |
|
149 | log.error(e) | |
150 |
|
|
150 | h.flash(e, category='error') | |
151 |
|
151 | |||
152 | return self._get_template_context(c) |
|
152 | return self._get_template_context(c) | |
153 |
|
153 | |||
@@ -157,7 +157,7 b' class LoginView(BaseAppView):' | |||||
157 | def login_post(self): |
|
157 | def login_post(self): | |
158 | c = self.load_default_context() |
|
158 | c = self.load_default_context() | |
159 |
|
159 | |||
160 | login_form = LoginForm()() |
|
160 | login_form = LoginForm(self.request.translate)() | |
161 |
|
161 | |||
162 | try: |
|
162 | try: | |
163 | self.session.invalidate() |
|
163 | self.session.invalidate() | |
@@ -182,11 +182,10 b' class LoginView(BaseAppView):' | |||||
182 | defaults = errors.value |
|
182 | defaults = errors.value | |
183 | # remove password from filling in form again |
|
183 | # remove password from filling in form again | |
184 | defaults.pop('password', None) |
|
184 | defaults.pop('password', None) | |
185 |
render_ctx = |
|
185 | render_ctx = { | |
186 | render_ctx.update({ |
|
|||
187 | 'errors': errors.error_dict, |
|
186 | 'errors': errors.error_dict, | |
188 | 'defaults': defaults, |
|
187 | 'defaults': defaults, | |
189 |
} |
|
188 | } | |
190 |
|
189 | |||
191 | audit_user = audit_logger.UserWrap( |
|
190 | audit_user = audit_logger.UserWrap( | |
192 | username=self.request.POST.get('username'), |
|
191 | username=self.request.POST.get('username'), | |
@@ -195,14 +194,14 b' class LoginView(BaseAppView):' | |||||
195 | audit_logger.store_web( |
|
194 | audit_logger.store_web( | |
196 | 'user.login.failure', action_data=action_data, |
|
195 | 'user.login.failure', action_data=action_data, | |
197 | user=audit_user, commit=True) |
|
196 | user=audit_user, commit=True) | |
198 | return render_ctx |
|
197 | return self._get_template_context(c, **render_ctx) | |
199 |
|
198 | |||
200 | except UserCreationError as e: |
|
199 | except UserCreationError as e: | |
201 | # headers auth or other auth functions that create users on |
|
200 | # headers auth or other auth functions that create users on | |
202 | # the fly can throw this exception signaling that there's issue |
|
201 | # the fly can throw this exception signaling that there's issue | |
203 | # with user creation, explanation should be provided in |
|
202 | # with user creation, explanation should be provided in | |
204 | # Exception itself |
|
203 | # Exception itself | |
205 |
|
|
204 | h.flash(e, category='error') | |
206 | return self._get_template_context(c) |
|
205 | return self._get_template_context(c) | |
207 |
|
206 | |||
208 | @CSRFRequired() |
|
207 | @CSRFRequired() | |
@@ -251,11 +250,12 b' class LoginView(BaseAppView):' | |||||
251 | route_name='register', request_method='POST', |
|
250 | route_name='register', request_method='POST', | |
252 | renderer='rhodecode:templates/register.mako') |
|
251 | renderer='rhodecode:templates/register.mako') | |
253 | def register_post(self): |
|
252 | def register_post(self): | |
|
253 | self.load_default_context() | |||
254 | captcha = self._get_captcha_data() |
|
254 | captcha = self._get_captcha_data() | |
255 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ |
|
255 | auto_active = 'hg.register.auto_activate' in User.get_default_user()\ | |
256 | .AuthUser().permissions['global'] |
|
256 | .AuthUser().permissions['global'] | |
257 |
|
257 | |||
258 | register_form = RegisterForm()() |
|
258 | register_form = RegisterForm(self.request.translate)() | |
259 | try: |
|
259 | try: | |
260 |
|
260 | |||
261 | form_result = register_form.to_python(self.request.POST) |
|
261 | form_result = register_form.to_python(self.request.POST) | |
@@ -275,11 +275,18 b' class LoginView(BaseAppView):' | |||||
275 | error_dict=error_dict) |
|
275 | error_dict=error_dict) | |
276 |
|
276 | |||
277 | new_user = UserModel().create_registration(form_result) |
|
277 | new_user = UserModel().create_registration(form_result) | |
|
278 | ||||
|
279 | action_data = {'data': new_user.get_api_data(), | |||
|
280 | 'user_agent': self.request.user_agent} | |||
|
281 | audit_logger.store_web( | |||
|
282 | 'user.register', action_data=action_data, | |||
|
283 | user=new_user) | |||
|
284 | ||||
278 | event = UserRegistered(user=new_user, session=self.session) |
|
285 | event = UserRegistered(user=new_user, session=self.session) | |
279 |
|
|
286 | trigger(event) | |
280 |
|
|
287 | h.flash( | |
281 | _('You have successfully registered with RhodeCode'), |
|
288 | _('You have successfully registered with RhodeCode'), | |
282 |
|
|
289 | category='success') | |
283 | Session().commit() |
|
290 | Session().commit() | |
284 |
|
291 | |||
285 | redirect_ro = self.request.route_path('login') |
|
292 | redirect_ro = self.request.route_path('login') | |
@@ -296,16 +303,17 b' class LoginView(BaseAppView):' | |||||
296 | # the fly can throw this exception signaling that there's issue |
|
303 | # the fly can throw this exception signaling that there's issue | |
297 | # with user creation, explanation should be provided in |
|
304 | # with user creation, explanation should be provided in | |
298 | # Exception itself |
|
305 | # Exception itself | |
299 |
|
|
306 | h.flash(e, category='error') | |
300 | return self.register() |
|
307 | return self.register() | |
301 |
|
308 | |||
302 | @view_config( |
|
309 | @view_config( | |
303 | route_name='reset_password', request_method=('GET', 'POST'), |
|
310 | route_name='reset_password', request_method=('GET', 'POST'), | |
304 | renderer='rhodecode:templates/password_reset.mako') |
|
311 | renderer='rhodecode:templates/password_reset.mako') | |
305 | def password_reset(self): |
|
312 | def password_reset(self): | |
|
313 | c = self.load_default_context() | |||
306 | captcha = self._get_captcha_data() |
|
314 | captcha = self._get_captcha_data() | |
307 |
|
315 | |||
308 |
|
|
316 | template_context = { | |
309 | 'captcha_active': captcha.active, |
|
317 | 'captcha_active': captcha.active, | |
310 | 'captcha_public_key': captcha.public_key, |
|
318 | 'captcha_public_key': captcha.public_key, | |
311 | 'defaults': {}, |
|
319 | 'defaults': {}, | |
@@ -320,11 +328,11 b' class LoginView(BaseAppView):' | |||||
320 | if h.HasPermissionAny('hg.password_reset.disabled')(): |
|
328 | if h.HasPermissionAny('hg.password_reset.disabled')(): | |
321 | _email = self.request.POST.get('email', '') |
|
329 | _email = self.request.POST.get('email', '') | |
322 | log.error('Failed attempt to reset password for `%s`.', _email) |
|
330 | log.error('Failed attempt to reset password for `%s`.', _email) | |
323 |
|
|
331 | h.flash(_('Password reset has been disabled.'), | |
324 |
|
|
332 | category='error') | |
325 | return HTTPFound(self.request.route_path('reset_password')) |
|
333 | return HTTPFound(self.request.route_path('reset_password')) | |
326 |
|
334 | |||
327 | password_reset_form = PasswordResetForm()() |
|
335 | password_reset_form = PasswordResetForm(self.request.translate)() | |
328 | try: |
|
336 | try: | |
329 | form_result = password_reset_form.to_python( |
|
337 | form_result = password_reset_form.to_python( | |
330 | self.request.POST) |
|
338 | self.request.POST) | |
@@ -362,7 +370,7 b' class LoginView(BaseAppView):' | |||||
362 | UserModel().reset_password_link( |
|
370 | UserModel().reset_password_link( | |
363 | form_result, password_reset_url) |
|
371 | form_result, password_reset_url) | |
364 | # Display success message and redirect. |
|
372 | # Display success message and redirect. | |
365 |
|
|
373 | h.flash(msg, category='success') | |
366 |
|
374 | |||
367 | action_data = {'email': user_email, |
|
375 | action_data = {'email': user_email, | |
368 | 'user_agent': self.request.user_agent} |
|
376 | 'user_agent': self.request.user_agent} | |
@@ -372,30 +380,30 b' class LoginView(BaseAppView):' | |||||
372 | return HTTPFound(self.request.route_path('reset_password')) |
|
380 | return HTTPFound(self.request.route_path('reset_password')) | |
373 |
|
381 | |||
374 | except formencode.Invalid as errors: |
|
382 | except formencode.Invalid as errors: | |
375 |
|
|
383 | template_context.update({ | |
376 | 'defaults': errors.value, |
|
384 | 'defaults': errors.value, | |
377 | 'errors': errors.error_dict, |
|
385 | 'errors': errors.error_dict, | |
378 | }) |
|
386 | }) | |
379 | if not self.request.POST.get('email'): |
|
387 | if not self.request.POST.get('email'): | |
380 | # case of empty email, we want to report that |
|
388 | # case of empty email, we want to report that | |
381 | return render_ctx |
|
389 | return self._get_template_context(c, **template_context) | |
382 |
|
390 | |||
383 | if 'recaptcha_field' in errors.error_dict: |
|
391 | if 'recaptcha_field' in errors.error_dict: | |
384 | # case of failed captcha |
|
392 | # case of failed captcha | |
385 | return render_ctx |
|
393 | return self._get_template_context(c, **template_context) | |
386 |
|
394 | |||
387 | log.debug('faking response on invalid password reset') |
|
395 | log.debug('faking response on invalid password reset') | |
388 | # make this take 2s, to prevent brute forcing. |
|
396 | # make this take 2s, to prevent brute forcing. | |
389 | time.sleep(2) |
|
397 | time.sleep(2) | |
390 |
|
|
398 | h.flash(msg, category='success') | |
391 | return HTTPFound(self.request.route_path('reset_password')) |
|
399 | return HTTPFound(self.request.route_path('reset_password')) | |
392 |
|
400 | |||
393 | return render_ctx |
|
401 | return self._get_template_context(c, **template_context) | |
394 |
|
402 | |||
395 | @view_config(route_name='reset_password_confirmation', |
|
403 | @view_config(route_name='reset_password_confirmation', | |
396 | request_method='GET') |
|
404 | request_method='GET') | |
397 | def password_reset_confirmation(self): |
|
405 | def password_reset_confirmation(self): | |
398 |
|
406 | self.load_default_context() | ||
399 | if self.request.GET and self.request.GET.get('key'): |
|
407 | if self.request.GET and self.request.GET.get('key'): | |
400 | # make this take 2s, to prevent brute forcing. |
|
408 | # make this take 2s, to prevent brute forcing. | |
401 | time.sleep(2) |
|
409 | time.sleep(2) | |
@@ -408,18 +416,18 b' class LoginView(BaseAppView):' | |||||
408 | log.debug('Got token with role:%s expected is %s', |
|
416 | log.debug('Got token with role:%s expected is %s', | |
409 | getattr(token, 'role', 'EMPTY_TOKEN'), |
|
417 | getattr(token, 'role', 'EMPTY_TOKEN'), | |
410 | UserApiKeys.ROLE_PASSWORD_RESET) |
|
418 | UserApiKeys.ROLE_PASSWORD_RESET) | |
411 |
|
|
419 | h.flash( | |
412 |
_('Given reset token is invalid'), |
|
420 | _('Given reset token is invalid'), category='error') | |
413 | return HTTPFound(self.request.route_path('reset_password')) |
|
421 | return HTTPFound(self.request.route_path('reset_password')) | |
414 |
|
422 | |||
415 | try: |
|
423 | try: | |
416 | owner = token.user |
|
424 | owner = token.user | |
417 | data = {'email': owner.email, 'token': token.api_key} |
|
425 | data = {'email': owner.email, 'token': token.api_key} | |
418 | UserModel().reset_password(data) |
|
426 | UserModel().reset_password(data) | |
419 |
|
|
427 | h.flash( | |
420 | _('Your password reset was successful, ' |
|
428 | _('Your password reset was successful, ' | |
421 | 'a new password has been sent to your email'), |
|
429 | 'a new password has been sent to your email'), | |
422 |
|
|
430 | category='success') | |
423 | except Exception as e: |
|
431 | except Exception as e: | |
424 | log.error(e) |
|
432 | log.error(e) | |
425 | return HTTPFound(self.request.route_path('reset_password')) |
|
433 | return HTTPFound(self.request.route_path('reset_password')) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -70,6 +70,11 b' def includeme(config):' | |||||
70 | name='my_account_ssh_keys_delete', |
|
70 | name='my_account_ssh_keys_delete', | |
71 | pattern=ADMIN_PREFIX + '/my_account/ssh_keys/delete') |
|
71 | pattern=ADMIN_PREFIX + '/my_account/ssh_keys/delete') | |
72 |
|
72 | |||
|
73 | # my account user group membership | |||
|
74 | config.add_route( | |||
|
75 | name='my_account_user_group_membership', | |||
|
76 | pattern=ADMIN_PREFIX + '/my_account/user_group_membership') | |||
|
77 | ||||
73 | # my account emails |
|
78 | # my account emails | |
74 | config.add_route( |
|
79 | config.add_route( | |
75 | name='my_account_emails', |
|
80 | name='my_account_emails', |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -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 | # -*- coding: utf-8 -*- |
|
20 | # -*- coding: utf-8 -*- | |
21 |
|
21 | |||
22 |
# Copyright (C) 2016-201 |
|
22 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
23 | # |
|
23 | # | |
24 | # This program is free software: you can redistribute it and/or modify |
|
24 | # This program is free software: you can redistribute it and/or modify | |
25 | # it under the terms of the GNU Affero General Public License, version 3 |
|
25 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -198,8 +198,6 b' class TestMyAccountEdit(TestController):' | |||||
198 | params=params) |
|
198 | params=params) | |
199 |
|
199 | |||
200 | response.mustcontain('An email address must contain a single @') |
|
200 | response.mustcontain('An email address must contain a single @') | |
201 | from rhodecode.model import validators |
|
201 | msg = u'Username "%(username)s" already exists' | |
202 | msg = validators.ValidUsername( |
|
|||
203 | edit=False, old_data={})._messages['username_exists'] |
|
|||
204 | msg = h.html_escape(msg % {'username': 'test_admin'}) |
|
202 | msg = h.html_escape(msg % {'username': 'test_admin'}) | |
205 | response.mustcontain(u"%s" % msg) |
|
203 | response.mustcontain(u"%s" % msg) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -42,12 +42,13 b' from rhodecode.model.comment import Comm' | |||||
42 | from rhodecode.model.db import ( |
|
42 | from rhodecode.model.db import ( | |
43 | Repository, UserEmailMap, UserApiKeys, UserFollowing, joinedload, |
|
43 | Repository, UserEmailMap, UserApiKeys, UserFollowing, joinedload, | |
44 | PullRequest) |
|
44 | PullRequest) | |
45 | from rhodecode.model.forms import UserForm |
|
45 | from rhodecode.model.forms import UserForm, UserExtraEmailForm | |
46 | from rhodecode.model.meta import Session |
|
46 | from rhodecode.model.meta import Session | |
47 | from rhodecode.model.pull_request import PullRequestModel |
|
47 | from rhodecode.model.pull_request import PullRequestModel | |
48 | from rhodecode.model.scm import RepoList |
|
48 | from rhodecode.model.scm import RepoList | |
49 | from rhodecode.model.user import UserModel |
|
49 | from rhodecode.model.user import UserModel | |
50 | from rhodecode.model.repo import RepoModel |
|
50 | from rhodecode.model.repo import RepoModel | |
|
51 | from rhodecode.model.user_group import UserGroupModel | |||
51 | from rhodecode.model.validation_schema.schemas import user_schema |
|
52 | from rhodecode.model.validation_schema.schemas import user_schema | |
52 |
|
53 | |||
53 | log = logging.getLogger(__name__) |
|
54 | log = logging.getLogger(__name__) | |
@@ -64,7 +65,7 b' class MyAccountView(BaseAppView, DataGri' | |||||
64 | c = self._get_local_tmpl_context() |
|
65 | c = self._get_local_tmpl_context() | |
65 | c.user = c.auth_user.get_instance() |
|
66 | c.user = c.auth_user.get_instance() | |
66 | c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS |
|
67 | c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS | |
67 | self._register_global_c(c) |
|
68 | ||
68 | return c |
|
69 | return c | |
69 |
|
70 | |||
70 | @LoginRequired() |
|
71 | @LoginRequired() | |
@@ -245,6 +246,10 b' class MyAccountView(BaseAppView, DataGri' | |||||
245 | email = self.request.POST.get('new_email') |
|
246 | email = self.request.POST.get('new_email') | |
246 |
|
247 | |||
247 | try: |
|
248 | try: | |
|
249 | form = UserExtraEmailForm(self.request.translate)() | |||
|
250 | data = form.to_python({'email': email}) | |||
|
251 | email = data['email'] | |||
|
252 | ||||
248 | UserModel().add_extra_email(c.user.user_id, email) |
|
253 | UserModel().add_extra_email(c.user.user_id, email) | |
249 | audit_logger.store_web( |
|
254 | audit_logger.store_web( | |
250 | 'user.edit.email.add', action_data={ |
|
255 | 'user.edit.email.add', action_data={ | |
@@ -442,7 +447,7 b' class MyAccountView(BaseAppView, DataGri' | |||||
442 | c.extern_type = c.user.extern_type |
|
447 | c.extern_type = c.user.extern_type | |
443 | c.extern_name = c.user.extern_name |
|
448 | c.extern_name = c.user.extern_name | |
444 |
|
449 | |||
445 | _form = UserForm(edit=True, |
|
450 | _form = UserForm(self.request.translate, edit=True, | |
446 | old_data={'user_id': self._rhodecode_user.user_id, |
|
451 | old_data={'user_id': self._rhodecode_user.user_id, | |
447 | 'email': self._rhodecode_user.email})() |
|
452 | 'email': self._rhodecode_user.email})() | |
448 | form_result = {} |
|
453 | form_result = {} | |
@@ -492,7 +497,7 b' class MyAccountView(BaseAppView, DataGri' | |||||
492 | draw, start, limit = self._extract_chunk(self.request) |
|
497 | draw, start, limit = self._extract_chunk(self.request) | |
493 | search_q, order_by, order_dir = self._extract_ordering(self.request) |
|
498 | search_q, order_by, order_dir = self._extract_ordering(self.request) | |
494 | _render = self.request.get_partial_renderer( |
|
499 | _render = self.request.get_partial_renderer( | |
495 | 'data_table/_dt_elements.mako') |
|
500 | 'rhodecode:templates/data_table/_dt_elements.mako') | |
496 |
|
501 | |||
497 | pull_requests = PullRequestModel().get_im_participating_in( |
|
502 | pull_requests = PullRequestModel().get_im_participating_in( | |
498 | user_id=self._rhodecode_user.user_id, |
|
503 | user_id=self._rhodecode_user.user_id, | |
@@ -568,6 +573,7 b' class MyAccountView(BaseAppView, DataGri' | |||||
568 | route_name='my_account_pullrequests_data', |
|
573 | route_name='my_account_pullrequests_data', | |
569 | request_method='GET', renderer='json_ext') |
|
574 | request_method='GET', renderer='json_ext') | |
570 | def my_account_pullrequests_data(self): |
|
575 | def my_account_pullrequests_data(self): | |
|
576 | self.load_default_context() | |||
571 | req_get = self.request.GET |
|
577 | req_get = self.request.GET | |
572 | closed = str2bool(req_get.get('closed')) |
|
578 | closed = str2bool(req_get.get('closed')) | |
573 |
|
579 | |||
@@ -578,3 +584,16 b' class MyAccountView(BaseAppView, DataGri' | |||||
578 | data = self._get_pull_requests_list(statuses=statuses) |
|
584 | data = self._get_pull_requests_list(statuses=statuses) | |
579 | return data |
|
585 | return data | |
580 |
|
586 | |||
|
587 | @LoginRequired() | |||
|
588 | @NotAnonymous() | |||
|
589 | @view_config( | |||
|
590 | route_name='my_account_user_group_membership', | |||
|
591 | request_method='GET', | |||
|
592 | renderer='rhodecode:templates/admin/my_account/my_account.mako') | |||
|
593 | def my_account_user_group_membership(self): | |||
|
594 | c = self.load_default_context() | |||
|
595 | c.active = 'user_group_membership' | |||
|
596 | groups = [UserGroupModel.get_user_groups_as_dict(group.users_group) | |||
|
597 | for group in self._rhodecode_db_user.group_member] | |||
|
598 | c.user_groups = json.dumps(groups) | |||
|
599 | return self._get_template_context(c) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -43,7 +43,7 b' class MyAccountNotificationsView(BaseApp' | |||||
43 | def load_default_context(self): |
|
43 | def load_default_context(self): | |
44 | c = self._get_local_tmpl_context() |
|
44 | c = self._get_local_tmpl_context() | |
45 | c.user = c.auth_user.get_instance() |
|
45 | c.user = c.auth_user.get_instance() | |
46 | self._register_global_c(c) |
|
46 | ||
47 | return c |
|
47 | return c | |
48 |
|
48 | |||
49 | def _has_permissions(self, notification): |
|
49 | def _has_permissions(self, notification): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -44,7 +44,7 b' class MyAccountSshKeysView(BaseAppView, ' | |||||
44 |
|
44 | |||
45 | c.ssh_enabled = self.request.registry.settings.get( |
|
45 | c.ssh_enabled = self.request.registry.settings.get( | |
46 | 'ssh.generate_authorized_keyfile') |
|
46 | 'ssh.generate_authorized_keyfile') | |
47 | self._register_global_c(c) |
|
47 | ||
48 | return c |
|
48 | return c | |
49 |
|
49 | |||
50 | @LoginRequired() |
|
50 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -18,7 +18,7 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 |
from rhodecode. |
|
21 | from rhodecode.apps._base import ADMIN_PREFIX | |
22 |
|
22 | |||
23 |
|
23 | |||
24 | def admin_routes(config): |
|
24 | def admin_routes(config): | |
@@ -36,7 +36,7 b' def admin_routes(config):' | |||||
36 | def includeme(config): |
|
36 | def includeme(config): | |
37 |
|
37 | |||
38 | config.include(admin_routes, route_prefix=ADMIN_PREFIX + '/ops') |
|
38 | config.include(admin_routes, route_prefix=ADMIN_PREFIX + '/ops') | |
39 |
# make OLD entries from |
|
39 | # make OLD entries from <4.10.0 work | |
40 | config.add_route( |
|
40 | config.add_route( | |
41 | name='ops_ping_legacy', pattern=ADMIN_PREFIX + '/ping') |
|
41 | name='ops_ping_legacy', pattern=ADMIN_PREFIX + '/ping') | |
42 | config.add_route( |
|
42 | config.add_route( |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -35,7 +35,7 b' class OpsView(BaseAppView):' | |||||
35 | def load_default_context(self): |
|
35 | def load_default_context(self): | |
36 | c = self._get_local_tmpl_context() |
|
36 | c = self._get_local_tmpl_context() | |
37 | c.user = c.auth_user.get_instance() |
|
37 | c.user = c.auth_user.get_instance() | |
38 | self._register_global_c(c) |
|
38 | ||
39 | return c |
|
39 | return c | |
40 |
|
40 | |||
41 | @view_config( |
|
41 | @view_config( |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -37,7 +37,7 b' log = logging.getLogger(__name__)' | |||||
37 | class RepoGroupSettingsView(RepoGroupAppView): |
|
37 | class RepoGroupSettingsView(RepoGroupAppView): | |
38 | def load_default_context(self): |
|
38 | def load_default_context(self): | |
39 | c = self._get_local_tmpl_context() |
|
39 | c = self._get_local_tmpl_context() | |
40 | self._register_global_c(c) |
|
40 | ||
41 | return c |
|
41 | return c | |
42 |
|
42 | |||
43 | @LoginRequired() |
|
43 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -38,7 +38,7 b' log = logging.getLogger(__name__)' | |||||
38 | class RepoGroupPermissionsView(RepoGroupAppView): |
|
38 | class RepoGroupPermissionsView(RepoGroupAppView): | |
39 | def load_default_context(self): |
|
39 | def load_default_context(self): | |
40 | c = self._get_local_tmpl_context() |
|
40 | c = self._get_local_tmpl_context() | |
41 | self._register_global_c(c) |
|
41 | ||
42 | return c |
|
42 | return c | |
43 |
|
43 | |||
44 | @LoginRequired() |
|
44 | @LoginRequired() | |
@@ -65,7 +65,7 b' class RepoGroupPermissionsView(RepoGroup' | |||||
65 | c.repo_group = self.db_repo_group |
|
65 | c.repo_group = self.db_repo_group | |
66 |
|
66 | |||
67 | valid_recursive_choices = ['none', 'repos', 'groups', 'all'] |
|
67 | valid_recursive_choices = ['none', 'repos', 'groups', 'all'] | |
68 | form = RepoGroupPermsForm(valid_recursive_choices)()\ |
|
68 | form = RepoGroupPermsForm(self.request.translate, valid_recursive_choices)()\ | |
69 | .to_python(self.request.POST) |
|
69 | .to_python(self.request.POST) | |
70 |
|
70 | |||
71 | if not c.rhodecode_user.is_admin: |
|
71 | if not c.rhodecode_user.is_admin: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -73,7 +73,7 b' class RepoGroupSettingsView(RepoGroupApp' | |||||
73 | c.repo_groups_choices.append(parent_group.group_id) |
|
73 | c.repo_groups_choices.append(parent_group.group_id) | |
74 | c.repo_groups.append(RepoGroup._generate_choice(parent_group)) |
|
74 | c.repo_groups.append(RepoGroup._generate_choice(parent_group)) | |
75 |
|
75 | |||
76 | self._register_global_c(c) |
|
76 | ||
77 | return c |
|
77 | return c | |
78 |
|
78 | |||
79 | def _can_create_repo_group(self, parent_group_id=None): |
|
79 | def _can_create_repo_group(self, parent_group_id=None): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -47,7 +47,7 b' def route_path(name, params=None, **kwar' | |||||
47 | class TestRepoCommitCommentsView(TestController): |
|
47 | class TestRepoCommitCommentsView(TestController): | |
48 |
|
48 | |||
49 | @pytest.fixture(autouse=True) |
|
49 | @pytest.fixture(autouse=True) | |
50 |
def prepare(self, request, |
|
50 | def prepare(self, request, baseapp): | |
51 | for x in ChangesetComment.query().all(): |
|
51 | for x in ChangesetComment.query().all(): | |
52 | Session().delete(x) |
|
52 | Session().delete(x) | |
53 | Session().commit() |
|
53 | Session().commit() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -48,6 +48,7 b' def route_path(name, params=None, **kwar' | |||||
48 | import urllib |
|
48 | import urllib | |
49 |
|
49 | |||
50 | base_url = { |
|
50 | base_url = { | |
|
51 | 'repo_summary': '/{repo_name}', | |||
51 | 'repo_archivefile': '/{repo_name}/archive/{fname}', |
|
52 | 'repo_archivefile': '/{repo_name}/archive/{fname}', | |
52 | 'repo_files_diff': '/{repo_name}/diff/{f_path}', |
|
53 | 'repo_files_diff': '/{repo_name}/diff/{f_path}', | |
53 | 'repo_files_diff_2way_redirect': '/{repo_name}/diff-2way/{f_path}', |
|
54 | 'repo_files_diff_2way_redirect': '/{repo_name}/diff-2way/{f_path}', | |
@@ -999,8 +1000,11 b' class TestFilesViewOtherCases(object):' | |||||
999 | .format(repo_file_add_url)) |
|
1000 | .format(repo_file_add_url)) | |
1000 |
|
1001 | |||
1001 | def test_access_empty_repo_redirect_to_summary_with_alert_no_write_perms( |
|
1002 | def test_access_empty_repo_redirect_to_summary_with_alert_no_write_perms( | |
1002 |
self, backend_stub, |
|
1003 | self, backend_stub, autologin_regular_user): | |
1003 | repo = backend_stub.create_repo() |
|
1004 | repo = backend_stub.create_repo() | |
|
1005 | # init session for anon user | |||
|
1006 | route_path('repo_summary', repo_name=repo.repo_name) | |||
|
1007 | ||||
1004 | repo_file_add_url = route_path( |
|
1008 | repo_file_add_url = route_path( | |
1005 | 'repo_files_add_file', |
|
1009 | 'repo_files_add_file', | |
1006 | repo_name=repo.repo_name, |
|
1010 | repo_name=repo.repo_name, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -58,11 +58,11 b' class TestRepoIssueTracker(object):' | |||||
58 | 'edit_repo_issuetracker_update', repo_name=backend.repo.repo_name) |
|
58 | 'edit_repo_issuetracker_update', repo_name=backend.repo.repo_name) | |
59 | post_data = { |
|
59 | post_data = { | |
60 | 'new_pattern_pattern_0': pattern, |
|
60 | 'new_pattern_pattern_0': pattern, | |
61 | 'new_pattern_url_0': 'url', |
|
61 | 'new_pattern_url_0': 'http://url', | |
62 | 'new_pattern_prefix_0': 'prefix', |
|
62 | 'new_pattern_prefix_0': 'prefix', | |
63 | 'new_pattern_description_0': 'description', |
|
63 | 'new_pattern_description_0': 'description', | |
64 | 'new_pattern_pattern_1': another_pattern, |
|
64 | 'new_pattern_pattern_1': another_pattern, | |
65 | 'new_pattern_url_1': 'url1', |
|
65 | 'new_pattern_url_1': '/url1', | |
66 | 'new_pattern_prefix_1': 'prefix1', |
|
66 | 'new_pattern_prefix_1': 'prefix1', | |
67 | 'new_pattern_description_1': 'description1', |
|
67 | 'new_pattern_description_1': 'description1', | |
68 | 'csrf_token': csrf_token |
|
68 | 'csrf_token': csrf_token | |
@@ -84,7 +84,7 b' class TestRepoIssueTracker(object):' | |||||
84 | extra_environ=xhr_header, params=data) |
|
84 | extra_environ=xhr_header, params=data) | |
85 |
|
85 | |||
86 | assert response.body == \ |
|
86 | assert response.body == \ | |
87 | 'example of <a class="issue-tracker-link" href="url">prefix</a> replacement' |
|
87 | 'example of <a class="issue-tracker-link" href="http://url">prefix</a> replacement' | |
88 |
|
88 | |||
89 | @request.addfinalizer |
|
89 | @request.addfinalizer | |
90 | def cleanup(): |
|
90 | def cleanup(): | |
@@ -106,7 +106,7 b' class TestRepoIssueTracker(object):' | |||||
106 | 'edit_repo_issuetracker_update', repo_name=backend.repo.repo_name) |
|
106 | 'edit_repo_issuetracker_update', repo_name=backend.repo.repo_name) | |
107 | post_data = { |
|
107 | post_data = { | |
108 | 'new_pattern_pattern_0': pattern, |
|
108 | 'new_pattern_pattern_0': pattern, | |
109 | 'new_pattern_url_0': 'url', |
|
109 | 'new_pattern_url_0': '/url', | |
110 | 'new_pattern_prefix_0': 'prefix', |
|
110 | 'new_pattern_prefix_0': 'prefix', | |
111 | 'new_pattern_description_0': 'description', |
|
111 | 'new_pattern_description_0': 'description', | |
112 | 'uid': old_uid, |
|
112 | 'uid': old_uid, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -199,18 +199,17 b' class TestPullrequestsView(object):' | |||||
199 | def test_edit_title_description_closed(self, pr_util, csrf_token): |
|
199 | def test_edit_title_description_closed(self, pr_util, csrf_token): | |
200 | pull_request = pr_util.create_pull_request() |
|
200 | pull_request = pr_util.create_pull_request() | |
201 | pull_request_id = pull_request.pull_request_id |
|
201 | pull_request_id = pull_request.pull_request_id | |
|
202 | repo_name = pull_request.target_repo.repo_name | |||
202 | pr_util.close() |
|
203 | pr_util.close() | |
203 |
|
204 | |||
204 | response = self.app.post( |
|
205 | response = self.app.post( | |
205 | route_path('pullrequest_update', |
|
206 | route_path('pullrequest_update', | |
206 |
repo_name= |
|
207 | repo_name=repo_name, pull_request_id=pull_request_id), | |
207 | pull_request_id=pull_request_id), |
|
|||
208 | params={ |
|
208 | params={ | |
209 | 'edit_pull_request': 'true', |
|
209 | 'edit_pull_request': 'true', | |
210 | 'title': 'New title', |
|
210 | 'title': 'New title', | |
211 | 'description': 'New description', |
|
211 | 'description': 'New description', | |
212 | 'csrf_token': csrf_token}) |
|
212 | 'csrf_token': csrf_token}, status=200) | |
213 |
|
||||
214 | assert_session_flash( |
|
213 | assert_session_flash( | |
215 | response, u'Cannot update closed pull requests.', |
|
214 | response, u'Cannot update closed pull requests.', | |
216 | category='error') |
|
215 | category='error') | |
@@ -300,7 +299,7 b' class TestPullrequestsView(object):' | |||||
300 | pull_request = pr_util.create_pull_request() |
|
299 | pull_request = pr_util.create_pull_request() | |
301 | pull_request_id = pull_request.pull_request_id |
|
300 | pull_request_id = pull_request.pull_request_id | |
302 | PullRequestModel().update_reviewers( |
|
301 | PullRequestModel().update_reviewers( | |
303 | pull_request_id, [(1, ['reason'], False), (2, ['reason2'], False)], |
|
302 | pull_request_id, [(1, ['reason'], False, []), (2, ['reason2'], False, [])], | |
304 | pull_request.author) |
|
303 | pull_request.author) | |
305 | author = pull_request.user_id |
|
304 | author = pull_request.user_id | |
306 | repo = pull_request.target_repo.repo_id |
|
305 | repo = pull_request.target_repo.repo_id | |
@@ -377,6 +376,8 b' class TestPullrequestsView(object):' | |||||
377 | ('__start__', 'reasons:sequence'), |
|
376 | ('__start__', 'reasons:sequence'), | |
378 | ('reason', 'Some reason'), |
|
377 | ('reason', 'Some reason'), | |
379 | ('__end__', 'reasons:sequence'), |
|
378 | ('__end__', 'reasons:sequence'), | |
|
379 | ('__start__', 'rules:sequence'), | |||
|
380 | ('__end__', 'rules:sequence'), | |||
380 | ('mandatory', 'False'), |
|
381 | ('mandatory', 'False'), | |
381 | ('__end__', 'reviewer:mapping'), |
|
382 | ('__end__', 'reviewer:mapping'), | |
382 | ('__end__', 'review_members:sequence'), |
|
383 | ('__end__', 'review_members:sequence'), | |
@@ -434,6 +435,8 b' class TestPullrequestsView(object):' | |||||
434 | ('__start__', 'reasons:sequence'), |
|
435 | ('__start__', 'reasons:sequence'), | |
435 | ('reason', 'Some reason'), |
|
436 | ('reason', 'Some reason'), | |
436 | ('__end__', 'reasons:sequence'), |
|
437 | ('__end__', 'reasons:sequence'), | |
|
438 | ('__start__', 'rules:sequence'), | |||
|
439 | ('__end__', 'rules:sequence'), | |||
437 | ('mandatory', 'False'), |
|
440 | ('mandatory', 'False'), | |
438 | ('__end__', 'reviewer:mapping'), |
|
441 | ('__end__', 'reviewer:mapping'), | |
439 | ('__end__', 'review_members:sequence'), |
|
442 | ('__end__', 'review_members:sequence'), | |
@@ -461,7 +464,7 b' class TestPullrequestsView(object):' | |||||
461 |
|
464 | |||
462 | # Change reviewers and check that a notification was made |
|
465 | # Change reviewers and check that a notification was made | |
463 | PullRequestModel().update_reviewers( |
|
466 | PullRequestModel().update_reviewers( | |
464 | pull_request.pull_request_id, [(1, [], False)], |
|
467 | pull_request.pull_request_id, [(1, [], False, [])], | |
465 | pull_request.author) |
|
468 | pull_request.author) | |
466 | assert len(notifications.all()) == 2 |
|
469 | assert len(notifications.all()) == 2 | |
467 |
|
470 | |||
@@ -498,6 +501,8 b' class TestPullrequestsView(object):' | |||||
498 | ('__start__', 'reasons:sequence'), |
|
501 | ('__start__', 'reasons:sequence'), | |
499 | ('reason', 'Some reason'), |
|
502 | ('reason', 'Some reason'), | |
500 | ('__end__', 'reasons:sequence'), |
|
503 | ('__end__', 'reasons:sequence'), | |
|
504 | ('__start__', 'rules:sequence'), | |||
|
505 | ('__end__', 'rules:sequence'), | |||
501 | ('mandatory', 'False'), |
|
506 | ('mandatory', 'False'), | |
502 | ('__end__', 'reviewer:mapping'), |
|
507 | ('__end__', 'reviewer:mapping'), | |
503 | ('__end__', 'review_members:sequence'), |
|
508 | ('__end__', 'review_members:sequence'), |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -56,6 +56,16 b' def route_path(name, params=None, **kwar' | |||||
56 | return base_url |
|
56 | return base_url | |
57 |
|
57 | |||
58 |
|
58 | |||
|
59 | def assert_clone_url(response, server, repo, disabled=False): | |||
|
60 | ||||
|
61 | response.mustcontain( | |||
|
62 | '<input type="text" class="input-monospace clone_url_input" ' | |||
|
63 | '{disabled}readonly="readonly" ' | |||
|
64 | 'value="http://test_admin@{server}/{repo}"/>'.format( | |||
|
65 | server=server, repo=repo, disabled='disabled ' if disabled else ' ') | |||
|
66 | ) | |||
|
67 | ||||
|
68 | ||||
59 | @pytest.mark.usefixtures('app') |
|
69 | @pytest.mark.usefixtures('app') | |
60 | class TestSummaryView(object): |
|
70 | class TestSummaryView(object): | |
61 | def test_index(self, autologin_user, backend, http_host_only_stub): |
|
71 | def test_index(self, autologin_user, backend, http_host_only_stub): | |
@@ -76,12 +86,8 b' class TestSummaryView(object):' | |||||
76 | ) |
|
86 | ) | |
77 |
|
87 | |||
78 | # clone url... |
|
88 | # clone url... | |
79 | response.mustcontain( |
|
89 | assert_clone_url(response, http_host_only_stub, repo_name) | |
80 | 'id="clone_url" readonly="readonly"' |
|
90 | assert_clone_url(response, http_host_only_stub, '_{}'.format(repo_id)) | |
81 | ' value="http://test_admin@%s/%s"' % (http_host_only_stub, repo_name, )) |
|
|||
82 | response.mustcontain( |
|
|||
83 | 'id="clone_url_id" readonly="readonly"' |
|
|||
84 | ' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, )) |
|
|||
85 |
|
91 | |||
86 | def test_index_svn_without_proxy( |
|
92 | def test_index_svn_without_proxy( | |
87 | self, autologin_user, backend_svn, http_host_only_stub): |
|
93 | self, autologin_user, backend_svn, http_host_only_stub): | |
@@ -89,12 +95,9 b' class TestSummaryView(object):' | |||||
89 | repo_name = backend_svn.repo_name |
|
95 | repo_name = backend_svn.repo_name | |
90 | response = self.app.get(route_path('repo_summary', repo_name=repo_name)) |
|
96 | response = self.app.get(route_path('repo_summary', repo_name=repo_name)) | |
91 | # clone url... |
|
97 | # clone url... | |
92 | response.mustcontain( |
|
98 | ||
93 | 'id="clone_url" disabled' |
|
99 | assert_clone_url(response, http_host_only_stub, repo_name, disabled=True) | |
94 | ' value="http://test_admin@%s/%s"' % (http_host_only_stub, repo_name, )) |
|
100 | assert_clone_url(response, http_host_only_stub, '_{}'.format(repo_id), disabled=True) | |
95 | response.mustcontain( |
|
|||
96 | 'id="clone_url_id" disabled' |
|
|||
97 | ' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, )) |
|
|||
98 |
|
101 | |||
99 | def test_index_with_trailing_slash( |
|
102 | def test_index_with_trailing_slash( | |
100 | self, autologin_user, backend, http_host_only_stub): |
|
103 | self, autologin_user, backend, http_host_only_stub): | |
@@ -108,12 +111,8 b' class TestSummaryView(object):' | |||||
108 | status=200) |
|
111 | status=200) | |
109 |
|
112 | |||
110 | # clone url... |
|
113 | # clone url... | |
111 | response.mustcontain( |
|
114 | assert_clone_url(response, http_host_only_stub, repo_name) | |
112 | 'id="clone_url" readonly="readonly"' |
|
115 | assert_clone_url(response, http_host_only_stub, '_{}'.format(repo_id)) | |
113 | ' value="http://test_admin@%s/%s"' % (http_host_only_stub, repo_name, )) |
|
|||
114 | response.mustcontain( |
|
|||
115 | 'id="clone_url_id" readonly="readonly"' |
|
|||
116 | ' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, )) |
|
|||
117 |
|
116 | |||
118 | def test_index_by_id(self, autologin_user, backend): |
|
117 | def test_index_by_id(self, autologin_user, backend): | |
119 | repo_id = backend.repo.repo_id |
|
118 | repo_id = backend.repo.repo_id |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -22,7 +22,7 b' from rhodecode.lib import helpers as h' | |||||
22 | from rhodecode.lib.utils2 import safe_int |
|
22 | from rhodecode.lib.utils2 import safe_int | |
23 |
|
23 | |||
24 |
|
24 | |||
25 | def reviewer_as_json(user, reasons=None, mandatory=False): |
|
25 | def reviewer_as_json(user, reasons=None, mandatory=False, rules=None, user_group=None): | |
26 | """ |
|
26 | """ | |
27 | Returns json struct of a reviewer for frontend |
|
27 | Returns json struct of a reviewer for frontend | |
28 |
|
28 | |||
@@ -34,10 +34,13 b' def reviewer_as_json(user, reasons=None,' | |||||
34 | return { |
|
34 | return { | |
35 | 'user_id': user.user_id, |
|
35 | 'user_id': user.user_id, | |
36 | 'reasons': reasons or [], |
|
36 | 'reasons': reasons or [], | |
|
37 | 'rules': rules or [], | |||
37 | 'mandatory': mandatory, |
|
38 | 'mandatory': mandatory, | |
|
39 | 'user_group': user_group, | |||
38 | 'username': user.username, |
|
40 | 'username': user.username, | |
39 | 'first_name': user.first_name, |
|
41 | 'first_name': user.first_name, | |
40 | 'last_name': user.last_name, |
|
42 | 'last_name': user.last_name, | |
|
43 | 'user_link': h.link_to_user(user), | |||
41 | 'gravatar_link': h.gravatar_url(user.email, 14), |
|
44 | 'gravatar_link': h.gravatar_url(user.email, 14), | |
42 | } |
|
45 | } | |
43 |
|
46 | |||
@@ -68,7 +71,7 b' def validate_default_reviewers(review_me' | |||||
68 | reviewer_by_id = {} |
|
71 | reviewer_by_id = {} | |
69 | for r in review_members: |
|
72 | for r in review_members: | |
70 | reviewer_user_id = safe_int(r['user_id']) |
|
73 | reviewer_user_id = safe_int(r['user_id']) | |
71 | entry = (reviewer_user_id, r['reasons'], r['mandatory']) |
|
74 | entry = (reviewer_user_id, r['reasons'], r['mandatory'], r['rules']) | |
72 |
|
75 | |||
73 | reviewer_by_id[reviewer_user_id] = entry |
|
76 | reviewer_by_id[reviewer_user_id] = entry | |
74 | reviewers.append(entry) |
|
77 | reviewers.append(entry) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -34,7 +34,7 b' class AuditLogsView(RepoAppView):' | |||||
34 | def load_default_context(self): |
|
34 | def load_default_context(self): | |
35 | c = self._get_local_tmpl_context() |
|
35 | c = self._get_local_tmpl_context() | |
36 |
|
36 | |||
37 | self._register_global_c(c) |
|
37 | ||
38 | return c |
|
38 | return c | |
39 |
|
39 | |||
40 | @LoginRequired() |
|
40 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -37,7 +37,7 b' class RepoCachesView(RepoAppView):' | |||||
37 | def load_default_context(self): |
|
37 | def load_default_context(self): | |
38 | c = self._get_local_tmpl_context() |
|
38 | c = self._get_local_tmpl_context() | |
39 |
|
39 | |||
40 | self._register_global_c(c) |
|
40 | ||
41 | return c |
|
41 | return c | |
42 |
|
42 | |||
43 | @LoginRequired() |
|
43 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -159,7 +159,7 b' class RepoChangelogView(RepoAppView):' | |||||
159 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
159 | c = self._get_local_tmpl_context(include_app_defaults=True) | |
160 |
|
160 | |||
161 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
161 | c.rhodecode_repo = self.rhodecode_vcs_repo | |
162 | self._register_global_c(c) |
|
162 | ||
163 | return c |
|
163 | return c | |
164 |
|
164 | |||
165 | def _get_preload_attrs(self): |
|
165 | def _get_preload_attrs(self): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -34,7 +34,7 b' log = logging.getLogger(__name__)' | |||||
34 | class RepoChecksView(BaseAppView): |
|
34 | class RepoChecksView(BaseAppView): | |
35 | def load_default_context(self): |
|
35 | def load_default_context(self): | |
36 | c = self._get_local_tmpl_context() |
|
36 | c = self._get_local_tmpl_context() | |
37 | self._register_global_c(c) |
|
37 | ||
38 | return c |
|
38 | return c | |
39 |
|
39 | |||
40 | @NotAnonymous() |
|
40 | @NotAnonymous() | |
@@ -78,10 +78,15 b' class RepoChecksView(BaseAppView):' | |||||
78 |
|
78 | |||
79 | if task_id and task_id not in ['None']: |
|
79 | if task_id and task_id not in ['None']: | |
80 | import rhodecode |
|
80 | import rhodecode | |
81 | from celery.result import AsyncResult |
|
81 | from rhodecode.lib.celerylib.loader import celery_app, exceptions | |
82 | if rhodecode.CELERY_ENABLED: |
|
82 | if rhodecode.CELERY_ENABLED: | |
83 | task = AsyncResult(task_id) |
|
83 | log.debug('celery: checking result for task:%s', task_id) | |
84 | if task.failed(): |
|
84 | task = celery_app.AsyncResult(task_id) | |
|
85 | try: | |||
|
86 | task.get(timeout=10) | |||
|
87 | except exceptions.TimeoutError: | |||
|
88 | task = None | |||
|
89 | if task and task.failed(): | |||
85 | msg = self._log_creation_exception(task.result, repo_name) |
|
90 | msg = self._log_creation_exception(task.result, repo_name) | |
86 | h.flash(msg, category='error') |
|
91 | h.flash(msg, category='error') | |
87 | raise HTTPFound(h.route_path('home'), code=501) |
|
92 | raise HTTPFound(h.route_path('home'), code=501) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -150,7 +150,6 b' class RepoCommitsView(RepoAppView):' | |||||
150 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
150 | c = self._get_local_tmpl_context(include_app_defaults=True) | |
151 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
151 | c.rhodecode_repo = self.rhodecode_vcs_repo | |
152 |
|
152 | |||
153 | self._register_global_c(c) |
|
|||
154 | return c |
|
153 | return c | |
155 |
|
154 | |||
156 | def _commit(self, commit_id_range, method): |
|
155 | def _commit(self, commit_id_range, method): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -47,7 +47,7 b' class RepoCompareView(RepoAppView):' | |||||
47 |
|
47 | |||
48 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
48 | c.rhodecode_repo = self.rhodecode_vcs_repo | |
49 |
|
49 | |||
50 | self._register_global_c(c) |
|
50 | ||
51 | return c |
|
51 | return c | |
52 |
|
52 | |||
53 | def _get_commit_or_redirect( |
|
53 | def _get_commit_or_redirect( |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -42,7 +42,7 b' class RepoFeedView(RepoAppView):' | |||||
42 | def load_default_context(self): |
|
42 | def load_default_context(self): | |
43 | c = self._get_local_tmpl_context() |
|
43 | c = self._get_local_tmpl_context() | |
44 |
|
44 | |||
45 | self._register_global_c(c) |
|
45 | ||
46 | self._load_defaults() |
|
46 | self._load_defaults() | |
47 | return c |
|
47 | return c | |
48 |
|
48 | |||
@@ -81,21 +81,22 b' class RepoFeedView(RepoAppView):' | |||||
81 | _parsed = diff_processor.prepare(inline_diff=False) |
|
81 | _parsed = diff_processor.prepare(inline_diff=False) | |
82 | limited_diff = isinstance(_parsed, LimitedDiffContainer) |
|
82 | limited_diff = isinstance(_parsed, LimitedDiffContainer) | |
83 |
|
83 | |||
84 | return _parsed, limited_diff |
|
84 | return diff_processor, _parsed, limited_diff | |
85 |
|
85 | |||
86 | def _get_title(self, commit): |
|
86 | def _get_title(self, commit): | |
87 | return h.shorter(commit.message, 160) |
|
87 | return h.shorter(commit.message, 160) | |
88 |
|
88 | |||
89 | def _get_description(self, commit): |
|
89 | def _get_description(self, commit): | |
90 | _renderer = self.request.get_partial_renderer( |
|
90 | _renderer = self.request.get_partial_renderer( | |
91 | 'feed/atom_feed_entry.mako') |
|
91 | 'rhodecode:templates/feed/atom_feed_entry.mako') | |
92 | parsed_diff, limited_diff = self._changes(commit) |
|
92 | diff_processor, parsed_diff, limited_diff = self._changes(commit) | |
93 | return _renderer( |
|
93 | return _renderer( | |
94 | 'body', |
|
94 | 'body', | |
95 | commit=commit, |
|
95 | commit=commit, | |
96 | parsed_diff=parsed_diff, |
|
96 | parsed_diff=parsed_diff, | |
97 | limited_diff=limited_diff, |
|
97 | limited_diff=limited_diff, | |
98 | feed_include_diff=self.feed_include_diff, |
|
98 | feed_include_diff=self.feed_include_diff, | |
|
99 | diff_processor=diff_processor, | |||
99 | ) |
|
100 | ) | |
100 |
|
101 | |||
101 | def _set_timezone(self, date, tzinfo=pytz.utc): |
|
102 | def _set_timezone(self, date, tzinfo=pytz.utc): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -83,7 +83,7 b' class RepoFilesView(RepoAppView):' | |||||
83 |
|
83 | |||
84 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
84 | c.rhodecode_repo = self.rhodecode_vcs_repo | |
85 |
|
85 | |||
86 | self._register_global_c(c) |
|
86 | ||
87 | return c |
|
87 | return c | |
88 |
|
88 | |||
89 | def _ensure_not_locked(self): |
|
89 | def _ensure_not_locked(self): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -33,6 +33,7 b' from rhodecode.lib.auth import (' | |||||
33 | LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, |
|
33 | LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, | |
34 | HasRepoPermissionAny, HasPermissionAnyDecorator, CSRFRequired) |
|
34 | HasRepoPermissionAny, HasPermissionAnyDecorator, CSRFRequired) | |
35 | import rhodecode.lib.helpers as h |
|
35 | import rhodecode.lib.helpers as h | |
|
36 | from rhodecode.lib.celerylib.utils import get_task_id | |||
36 | from rhodecode.model.db import coalesce, or_, Repository, RepoGroup |
|
37 | from rhodecode.model.db import coalesce, or_, Repository, RepoGroup | |
37 | from rhodecode.model.repo import RepoModel |
|
38 | from rhodecode.model.repo import RepoModel | |
38 | from rhodecode.model.forms import RepoForkForm |
|
39 | from rhodecode.model.forms import RepoForkForm | |
@@ -53,11 +54,11 b' class RepoForksView(RepoAppView, DataGri' | |||||
53 | perm_set=['group.write', 'group.admin']) |
|
54 | perm_set=['group.write', 'group.admin']) | |
54 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) |
|
55 | c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) | |
55 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) |
|
56 | c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups) | |
56 |
choices, c.landing_revs = ScmModel().get_repo_landing_revs( |
|
57 | choices, c.landing_revs = ScmModel().get_repo_landing_revs( | |
|
58 | self.request.translate) | |||
57 | c.landing_revs_choices = choices |
|
59 | c.landing_revs_choices = choices | |
58 | c.personal_repo_group = c.rhodecode_user.personal_repo_group |
|
60 | c.personal_repo_group = c.rhodecode_user.personal_repo_group | |
59 |
|
61 | |||
60 | self._register_global_c(c) |
|
|||
61 | return c |
|
62 | return c | |
62 |
|
63 | |||
63 | @LoginRequired() |
|
64 | @LoginRequired() | |
@@ -78,6 +79,7 b' class RepoForksView(RepoAppView, DataGri' | |||||
78 | renderer='json_ext', xhr=True) |
|
79 | renderer='json_ext', xhr=True) | |
79 | def repo_forks_data(self): |
|
80 | def repo_forks_data(self): | |
80 | _ = self.request.translate |
|
81 | _ = self.request.translate | |
|
82 | self.load_default_context() | |||
81 | column_map = { |
|
83 | column_map = { | |
82 | 'fork_name': 'repo_name', |
|
84 | 'fork_name': 'repo_name', | |
83 | 'fork_date': 'created_on', |
|
85 | 'fork_date': 'created_on', | |
@@ -209,7 +211,7 b' class RepoForksView(RepoAppView, DataGri' | |||||
209 | _ = self.request.translate |
|
211 | _ = self.request.translate | |
210 | c = self.load_default_context() |
|
212 | c = self.load_default_context() | |
211 |
|
213 | |||
212 | _form = RepoForkForm(old_data={'repo_type': self.db_repo.repo_type}, |
|
214 | _form = RepoForkForm(self.request.translate, old_data={'repo_type': self.db_repo.repo_type}, | |
213 | repo_groups=c.repo_groups_choices, |
|
215 | repo_groups=c.repo_groups_choices, | |
214 | landing_revs=c.landing_revs_choices)() |
|
216 | landing_revs=c.landing_revs_choices)() | |
215 | post_data = dict(self.request.POST) |
|
217 | post_data = dict(self.request.POST) | |
@@ -225,9 +227,8 b' class RepoForksView(RepoAppView, DataGri' | |||||
225 | # management is handled there. |
|
227 | # management is handled there. | |
226 | task = RepoModel().create_fork( |
|
228 | task = RepoModel().create_fork( | |
227 | form_result, c.rhodecode_user.user_id) |
|
229 | form_result, c.rhodecode_user.user_id) | |
228 | from celery.result import BaseAsyncResult |
|
230 | ||
229 | if isinstance(task, BaseAsyncResult): |
|
231 | task_id = get_task_id(task) | |
230 | task_id = task.task_id |
|
|||
231 | except formencode.Invalid as errors: |
|
232 | except formencode.Invalid as errors: | |
232 | c.rhodecode_db_repo = self.db_repo |
|
233 | c.rhodecode_db_repo = self.db_repo | |
233 |
|
234 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -33,7 +33,7 b' class RepoMaintenanceView(RepoAppView):' | |||||
33 | def load_default_context(self): |
|
33 | def load_default_context(self): | |
34 | c = self._get_local_tmpl_context() |
|
34 | c = self._get_local_tmpl_context() | |
35 |
|
35 | |||
36 | self._register_global_c(c) |
|
36 | ||
37 | return c |
|
37 | return c | |
38 |
|
38 | |||
39 | @LoginRequired() |
|
39 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -40,7 +40,7 b' class RepoSettingsPermissionsView(RepoAp' | |||||
40 | def load_default_context(self): |
|
40 | def load_default_context(self): | |
41 | c = self._get_local_tmpl_context() |
|
41 | c = self._get_local_tmpl_context() | |
42 |
|
42 | |||
43 | self._register_global_c(c) |
|
43 | ||
44 | return c |
|
44 | return c | |
45 |
|
45 | |||
46 | @LoginRequired() |
|
46 | @LoginRequired() | |
@@ -68,7 +68,7 b' class RepoSettingsPermissionsView(RepoAp' | |||||
68 | # default user permissions, prevents submission of FAKE post data |
|
68 | # default user permissions, prevents submission of FAKE post data | |
69 | # into the form for private repos |
|
69 | # into the form for private repos | |
70 | data['repo_private'] = self.db_repo.private |
|
70 | data['repo_private'] = self.db_repo.private | |
71 | form = RepoPermsForm()().to_python(data) |
|
71 | form = RepoPermsForm(self.request.translate)().to_python(data) | |
72 | changes = RepoModel().update_permissions( |
|
72 | changes = RepoModel().update_permissions( | |
73 | self.db_repo_name, form['perm_additions'], form['perm_updates'], |
|
73 | self.db_repo_name, form['perm_additions'], form['perm_updates'], | |
74 | form['perm_deletions']) |
|
74 | form['perm_deletions']) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -60,7 +60,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
60 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
60 | c = self._get_local_tmpl_context(include_app_defaults=True) | |
61 | c.REVIEW_STATUS_APPROVED = ChangesetStatus.STATUS_APPROVED |
|
61 | c.REVIEW_STATUS_APPROVED = ChangesetStatus.STATUS_APPROVED | |
62 | c.REVIEW_STATUS_REJECTED = ChangesetStatus.STATUS_REJECTED |
|
62 | c.REVIEW_STATUS_REJECTED = ChangesetStatus.STATUS_REJECTED | |
63 | self._register_global_c(c) |
|
63 | ||
64 | return c |
|
64 | return c | |
65 |
|
65 | |||
66 | def _get_pull_requests_list( |
|
66 | def _get_pull_requests_list( | |
@@ -69,7 +69,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
69 | draw, start, limit = self._extract_chunk(self.request) |
|
69 | draw, start, limit = self._extract_chunk(self.request) | |
70 | search_q, order_by, order_dir = self._extract_ordering(self.request) |
|
70 | search_q, order_by, order_dir = self._extract_ordering(self.request) | |
71 | _render = self.request.get_partial_renderer( |
|
71 | _render = self.request.get_partial_renderer( | |
72 | 'data_table/_dt_elements.mako') |
|
72 | 'rhodecode:templates/data_table/_dt_elements.mako') | |
73 |
|
73 | |||
74 | # pagination |
|
74 | # pagination | |
75 |
|
75 | |||
@@ -173,6 +173,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
173 | route_name='pullrequest_show_all_data', request_method='GET', |
|
173 | route_name='pullrequest_show_all_data', request_method='GET', | |
174 | renderer='json_ext', xhr=True) |
|
174 | renderer='json_ext', xhr=True) | |
175 | def pull_request_list_data(self): |
|
175 | def pull_request_list_data(self): | |
|
176 | self.load_default_context() | |||
176 |
|
177 | |||
177 | # additional filters |
|
178 | # additional filters | |
178 | req_get = self.request.GET |
|
179 | req_get = self.request.GET | |
@@ -200,29 +201,6 b' class RepoPullRequestsView(RepoAppView, ' | |||||
200 |
|
201 | |||
201 | return data |
|
202 | return data | |
202 |
|
203 | |||
203 | def _get_pr_version(self, pull_request_id, version=None): |
|
|||
204 | at_version = None |
|
|||
205 |
|
||||
206 | if version and version == 'latest': |
|
|||
207 | pull_request_ver = PullRequest.get(pull_request_id) |
|
|||
208 | pull_request_obj = pull_request_ver |
|
|||
209 | _org_pull_request_obj = pull_request_obj |
|
|||
210 | at_version = 'latest' |
|
|||
211 | elif version: |
|
|||
212 | pull_request_ver = PullRequestVersion.get_or_404(version) |
|
|||
213 | pull_request_obj = pull_request_ver |
|
|||
214 | _org_pull_request_obj = pull_request_ver.pull_request |
|
|||
215 | at_version = pull_request_ver.pull_request_version_id |
|
|||
216 | else: |
|
|||
217 | _org_pull_request_obj = pull_request_obj = PullRequest.get_or_404( |
|
|||
218 | pull_request_id) |
|
|||
219 |
|
||||
220 | pull_request_display_obj = PullRequest.get_pr_display_object( |
|
|||
221 | pull_request_obj, _org_pull_request_obj) |
|
|||
222 |
|
||||
223 | return _org_pull_request_obj, pull_request_obj, \ |
|
|||
224 | pull_request_display_obj, at_version |
|
|||
225 |
|
||||
226 | def _get_diffset(self, source_repo_name, source_repo, |
|
204 | def _get_diffset(self, source_repo_name, source_repo, | |
227 | source_ref_id, target_ref_id, |
|
205 | source_ref_id, target_ref_id, | |
228 | target_commit, source_commit, diff_limit, fulldiff, |
|
206 | target_commit, source_commit, diff_limit, fulldiff, | |
@@ -277,7 +255,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
277 | (pull_request_latest, |
|
255 | (pull_request_latest, | |
278 | pull_request_at_ver, |
|
256 | pull_request_at_ver, | |
279 | pull_request_display_obj, |
|
257 | pull_request_display_obj, | |
280 |
at_version) = |
|
258 | at_version) = PullRequestModel().get_pr_version( | |
281 | pull_request_id, version=version) |
|
259 | pull_request_id, version=version) | |
282 | pr_closed = pull_request_latest.is_closed() |
|
260 | pr_closed = pull_request_latest.is_closed() | |
283 |
|
261 | |||
@@ -299,7 +277,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
299 | (prev_pull_request_latest, |
|
277 | (prev_pull_request_latest, | |
300 | prev_pull_request_at_ver, |
|
278 | prev_pull_request_at_ver, | |
301 | prev_pull_request_display_obj, |
|
279 | prev_pull_request_display_obj, | |
302 |
prev_at_version) = |
|
280 | prev_at_version) = PullRequestModel().get_pr_version( | |
303 | pull_request_id, version=from_version) |
|
281 | pull_request_id, version=from_version) | |
304 |
|
282 | |||
305 | c.from_version = prev_at_version |
|
283 | c.from_version = prev_at_version | |
@@ -630,7 +608,8 b' class RepoPullRequestsView(RepoAppView, ' | |||||
630 | try: |
|
608 | try: | |
631 | source_repo_data = PullRequestModel().generate_repo_data( |
|
609 | source_repo_data = PullRequestModel().generate_repo_data( | |
632 | source_repo, commit_id=commit_id, |
|
610 | source_repo, commit_id=commit_id, | |
633 |
branch=branch_ref, bookmark=bookmark_ref, |
|
611 | branch=branch_ref, bookmark=bookmark_ref, | |
|
612 | translator=self.request.translate) | |||
634 | except CommitDoesNotExistError as e: |
|
613 | except CommitDoesNotExistError as e: | |
635 | log.exception(e) |
|
614 | log.exception(e) | |
636 | h.flash(_('Commit does not exist'), 'error') |
|
615 | h.flash(_('Commit does not exist'), 'error') | |
@@ -649,8 +628,9 b' class RepoPullRequestsView(RepoAppView, ' | |||||
649 | default_target_repo, translator=self.request.translate) |
|
628 | default_target_repo, translator=self.request.translate) | |
650 |
|
629 | |||
651 | selected_source_ref = source_repo_data['refs']['selected_ref'] |
|
630 | selected_source_ref = source_repo_data['refs']['selected_ref'] | |
652 |
|
631 | title_source_ref = '' | ||
653 |
|
|
632 | if selected_source_ref: | |
|
633 | title_source_ref = selected_source_ref.split(':', 2)[1] | |||
654 | c.default_title = PullRequestModel().generate_pullrequest_title( |
|
634 | c.default_title = PullRequestModel().generate_pullrequest_title( | |
655 | source=source_repo.repo_name, |
|
635 | source=source_repo.repo_name, | |
656 | source_ref=title_source_ref, |
|
636 | source_ref=title_source_ref, | |
@@ -675,6 +655,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
675 | route_name='pullrequest_repo_refs', request_method='GET', |
|
655 | route_name='pullrequest_repo_refs', request_method='GET', | |
676 | renderer='json_ext', xhr=True) |
|
656 | renderer='json_ext', xhr=True) | |
677 | def pull_request_repo_refs(self): |
|
657 | def pull_request_repo_refs(self): | |
|
658 | self.load_default_context() | |||
678 | target_repo_name = self.request.matchdict['target_repo_name'] |
|
659 | target_repo_name = self.request.matchdict['target_repo_name'] | |
679 | repo = Repository.get_by_repo_name(target_repo_name) |
|
660 | repo = Repository.get_by_repo_name(target_repo_name) | |
680 | if not repo: |
|
661 | if not repo: | |
@@ -752,16 +733,19 b' class RepoPullRequestsView(RepoAppView, ' | |||||
752 | def pull_request_create(self): |
|
733 | def pull_request_create(self): | |
753 | _ = self.request.translate |
|
734 | _ = self.request.translate | |
754 | self.assure_not_empty_repo() |
|
735 | self.assure_not_empty_repo() | |
|
736 | self.load_default_context() | |||
755 |
|
737 | |||
756 | controls = peppercorn.parse(self.request.POST.items()) |
|
738 | controls = peppercorn.parse(self.request.POST.items()) | |
757 |
|
739 | |||
758 | try: |
|
740 | try: | |
759 |
|
|
741 | form = PullRequestForm( | |
|
742 | self.request.translate, self.db_repo.repo_id)() | |||
|
743 | _form = form.to_python(controls) | |||
760 | except formencode.Invalid as errors: |
|
744 | except formencode.Invalid as errors: | |
761 | if errors.error_dict.get('revisions'): |
|
745 | if errors.error_dict.get('revisions'): | |
762 | msg = 'Revisions: %s' % errors.error_dict['revisions'] |
|
746 | msg = 'Revisions: %s' % errors.error_dict['revisions'] | |
763 | elif errors.error_dict.get('pullrequest_title'): |
|
747 | elif errors.error_dict.get('pullrequest_title'): | |
764 |
msg = _(' |
|
748 | msg = errors.error_dict.get('pullrequest_title') | |
765 | else: |
|
749 | else: | |
766 | msg = _('Error creating pull request: {}').format(errors) |
|
750 | msg = _('Error creating pull request: {}').format(errors) | |
767 | log.exception(msg) |
|
751 | log.exception(msg) | |
@@ -882,6 +866,15 b' class RepoPullRequestsView(RepoAppView, ' | |||||
882 | def pull_request_update(self): |
|
866 | def pull_request_update(self): | |
883 | pull_request = PullRequest.get_or_404( |
|
867 | pull_request = PullRequest.get_or_404( | |
884 | self.request.matchdict['pull_request_id']) |
|
868 | self.request.matchdict['pull_request_id']) | |
|
869 | _ = self.request.translate | |||
|
870 | ||||
|
871 | self.load_default_context() | |||
|
872 | ||||
|
873 | if pull_request.is_closed(): | |||
|
874 | log.debug('update: forbidden because pull request is closed') | |||
|
875 | msg = _(u'Cannot update closed pull requests.') | |||
|
876 | h.flash(msg, category='error') | |||
|
877 | return True | |||
885 |
|
878 | |||
886 | # only owner or admin can update it |
|
879 | # only owner or admin can update it | |
887 | allowed_to_update = PullRequestModel().check_user_update( |
|
880 | allowed_to_update = PullRequestModel().check_user_update( | |
@@ -981,6 +974,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
981 | pull_request = PullRequest.get_or_404( |
|
974 | pull_request = PullRequest.get_or_404( | |
982 | self.request.matchdict['pull_request_id']) |
|
975 | self.request.matchdict['pull_request_id']) | |
983 |
|
976 | |||
|
977 | self.load_default_context() | |||
984 | check = MergeCheck.validate(pull_request, self._rhodecode_db_user, |
|
978 | check = MergeCheck.validate(pull_request, self._rhodecode_db_user, | |
985 | translator=self.request.translate) |
|
979 | translator=self.request.translate) | |
986 | merge_possible = not check.failed |
|
980 | merge_possible = not check.failed | |
@@ -1053,6 +1047,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1053 |
|
1047 | |||
1054 | pull_request = PullRequest.get_or_404( |
|
1048 | pull_request = PullRequest.get_or_404( | |
1055 | self.request.matchdict['pull_request_id']) |
|
1049 | self.request.matchdict['pull_request_id']) | |
|
1050 | self.load_default_context() | |||
1056 |
|
1051 | |||
1057 | pr_closed = pull_request.is_closed() |
|
1052 | pr_closed = pull_request.is_closed() | |
1058 | allowed_to_delete = PullRequestModel().check_user_delete( |
|
1053 | allowed_to_delete = PullRequestModel().check_user_delete( | |
@@ -1166,6 +1161,10 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1166 | ) |
|
1161 | ) | |
1167 |
|
1162 | |||
1168 | Session().flush() |
|
1163 | Session().flush() | |
|
1164 | # this is somehow required to get access to some relationship | |||
|
1165 | # loaded on comment | |||
|
1166 | Session().refresh(comment) | |||
|
1167 | ||||
1169 | events.trigger( |
|
1168 | events.trigger( | |
1170 | events.PullRequestCommentEvent(pull_request, comment)) |
|
1169 | events.PullRequestCommentEvent(pull_request, comment)) | |
1171 |
|
1170 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -32,8 +32,6 b' log = logging.getLogger(__name__)' | |||||
32 | class RepoReviewRulesView(RepoAppView): |
|
32 | class RepoReviewRulesView(RepoAppView): | |
33 | def load_default_context(self): |
|
33 | def load_default_context(self): | |
34 | c = self._get_local_tmpl_context() |
|
34 | c = self._get_local_tmpl_context() | |
35 |
|
||||
36 | self._register_global_c(c) |
|
|||
37 | return c |
|
35 | return c | |
38 |
|
36 | |||
39 | @LoginRequired() |
|
37 | @LoginRequired() | |
@@ -54,6 +52,7 b' class RepoReviewRulesView(RepoAppView):' | |||||
54 | route_name='repo_default_reviewers_data', request_method='GET', |
|
52 | route_name='repo_default_reviewers_data', request_method='GET', | |
55 | renderer='json_ext') |
|
53 | renderer='json_ext') | |
56 | def repo_default_reviewers_data(self): |
|
54 | def repo_default_reviewers_data(self): | |
|
55 | self.load_default_context() | |||
57 | review_data = get_default_reviewers_data( |
|
56 | review_data = get_default_reviewers_data( | |
58 | self.db_repo.user, None, None, None, None) |
|
57 | self.db_repo.user, None, None, None, None) | |
59 | return review_data |
|
58 | return review_data |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -62,16 +62,17 b' class RepoSettingsView(RepoAppView):' | |||||
62 | # we might be in missing requirement state, so we load things |
|
62 | # we might be in missing requirement state, so we load things | |
63 | # without touching scm_instance() |
|
63 | # without touching scm_instance() | |
64 | c.landing_revs_choices, c.landing_revs = \ |
|
64 | c.landing_revs_choices, c.landing_revs = \ | |
65 | ScmModel().get_repo_landing_revs() |
|
65 | ScmModel().get_repo_landing_revs(self.request.translate) | |
66 | else: |
|
66 | else: | |
67 | c.landing_revs_choices, c.landing_revs = \ |
|
67 | c.landing_revs_choices, c.landing_revs = \ | |
68 |
ScmModel().get_repo_landing_revs( |
|
68 | ScmModel().get_repo_landing_revs( | |
|
69 | self.request.translate, self.db_repo) | |||
69 |
|
70 | |||
70 | c.personal_repo_group = c.auth_user.personal_repo_group |
|
71 | c.personal_repo_group = c.auth_user.personal_repo_group | |
71 | c.repo_fields = RepositoryField.query()\ |
|
72 | c.repo_fields = RepositoryField.query()\ | |
72 | .filter(RepositoryField.repository == self.db_repo).all() |
|
73 | .filter(RepositoryField.repository == self.db_repo).all() | |
73 |
|
74 | |||
74 | self._register_global_c(c) |
|
75 | ||
75 | return c |
|
76 | return c | |
76 |
|
77 | |||
77 | def _get_schema(self, c, old_values=None): |
|
78 | def _get_schema(self, c, old_values=None): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -44,7 +44,7 b' class RepoSettingsView(RepoAppView):' | |||||
44 | def load_default_context(self): |
|
44 | def load_default_context(self): | |
45 | c = self._get_local_tmpl_context() |
|
45 | c = self._get_local_tmpl_context() | |
46 |
|
46 | |||
47 | self._register_global_c(c) |
|
47 | ||
48 | return c |
|
48 | return c | |
49 |
|
49 | |||
50 | @LoginRequired() |
|
50 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -43,7 +43,7 b' class RepoSettingsFieldsView(RepoAppView' | |||||
43 | def load_default_context(self): |
|
43 | def load_default_context(self): | |
44 | c = self._get_local_tmpl_context() |
|
44 | c = self._get_local_tmpl_context() | |
45 |
|
45 | |||
46 | self._register_global_c(c) |
|
46 | ||
47 | return c |
|
47 | return c | |
48 |
|
48 | |||
49 | @LoginRequired() |
|
49 | @LoginRequired() | |
@@ -70,7 +70,8 b' class RepoSettingsFieldsView(RepoAppView' | |||||
70 | _ = self.request.translate |
|
70 | _ = self.request.translate | |
71 |
|
71 | |||
72 | try: |
|
72 | try: | |
73 |
form |
|
73 | form = RepoFieldForm(self.request.translate)() | |
|
74 | form_result = form.to_python(dict(self.request.POST)) | |||
74 | RepoModel().add_repo_field( |
|
75 | RepoModel().add_repo_field( | |
75 | self.db_repo_name, |
|
76 | self.db_repo_name, | |
76 | form_result['new_field_key'], |
|
77 | form_result['new_field_key'], |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -22,6 +22,7 b' import logging' | |||||
22 |
|
22 | |||
23 | from pyramid.httpexceptions import HTTPFound |
|
23 | from pyramid.httpexceptions import HTTPFound | |
24 | from pyramid.view import view_config |
|
24 | from pyramid.view import view_config | |
|
25 | import formencode | |||
25 |
|
26 | |||
26 | from rhodecode.apps._base import RepoAppView |
|
27 | from rhodecode.apps._base import RepoAppView | |
27 | from rhodecode.lib import audit_logger |
|
28 | from rhodecode.lib import audit_logger | |
@@ -39,7 +40,7 b' class RepoSettingsIssueTrackersView(Repo' | |||||
39 | def load_default_context(self): |
|
40 | def load_default_context(self): | |
40 | c = self._get_local_tmpl_context() |
|
41 | c = self._get_local_tmpl_context() | |
41 |
|
42 | |||
42 | self._register_global_c(c) |
|
43 | ||
43 | return c |
|
44 | return c | |
44 |
|
45 | |||
45 | @LoginRequired() |
|
46 | @LoginRequired() | |
@@ -116,7 +117,17 b' class RepoSettingsIssueTrackersView(Repo' | |||||
116 | repo_settings.inherit_global_settings = inherited |
|
117 | repo_settings.inherit_global_settings = inherited | |
117 | Session().commit() |
|
118 | Session().commit() | |
118 |
|
119 | |||
119 | form = IssueTrackerPatternsForm()().to_python(self.request.POST) |
|
120 | try: | |
|
121 | form = IssueTrackerPatternsForm(self.request.translate)().to_python(self.request.POST) | |||
|
122 | except formencode.Invalid as errors: | |||
|
123 | log.exception('Failed to add new pattern') | |||
|
124 | error = errors | |||
|
125 | h.flash(_('Invalid issue tracker pattern: {}'.format(error)), | |||
|
126 | category='error') | |||
|
127 | raise HTTPFound( | |||
|
128 | h.route_path('edit_repo_issuetracker', | |||
|
129 | repo_name=self.db_repo_name)) | |||
|
130 | ||||
120 | if form: |
|
131 | if form: | |
121 | self._update_patterns(form, repo_settings) |
|
132 | self._update_patterns(form, repo_settings) | |
122 |
|
133 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -36,7 +36,7 b' class RepoSettingsRemoteView(RepoAppView' | |||||
36 | def load_default_context(self): |
|
36 | def load_default_context(self): | |
37 | c = self._get_local_tmpl_context() |
|
37 | c = self._get_local_tmpl_context() | |
38 |
|
38 | |||
39 | self._register_global_c(c) |
|
39 | ||
40 | return c |
|
40 | return c | |
41 |
|
41 | |||
42 | @LoginRequired() |
|
42 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -43,7 +43,7 b' class RepoSettingsVcsView(RepoAppView):' | |||||
43 | def load_default_context(self): |
|
43 | def load_default_context(self): | |
44 | c = self._get_local_tmpl_context() |
|
44 | c = self._get_local_tmpl_context() | |
45 |
|
45 | |||
46 | self._register_global_c(c) |
|
46 | ||
47 | return c |
|
47 | return c | |
48 |
|
48 | |||
49 | def _vcs_form_defaults(self, repo_name): |
|
49 | def _vcs_form_defaults(self, repo_name): | |
@@ -117,7 +117,7 b' class RepoSettingsVcsView(RepoAppView):' | |||||
117 | defaults = self._vcs_form_defaults(self.db_repo_name) |
|
117 | defaults = self._vcs_form_defaults(self.db_repo_name) | |
118 | c.inherit_global_settings = defaults['inherit_global_settings'] |
|
118 | c.inherit_global_settings = defaults['inherit_global_settings'] | |
119 |
|
119 | |||
120 | application_form = RepoVcsSettingsForm(self.db_repo_name)() |
|
120 | application_form = RepoVcsSettingsForm(self.request.translate, self.db_repo_name)() | |
121 | try: |
|
121 | try: | |
122 | form_result = application_form.to_python(dict(self.request.POST)) |
|
122 | form_result = application_form.to_python(dict(self.request.POST)) | |
123 | except formencode.Invalid as errors: |
|
123 | except formencode.Invalid as errors: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2017-201 |
|
3 | # Copyright (C) 2017-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -35,7 +35,7 b' class StripView(RepoAppView):' | |||||
35 | def load_default_context(self): |
|
35 | def load_default_context(self): | |
36 | c = self._get_local_tmpl_context() |
|
36 | c = self._get_local_tmpl_context() | |
37 |
|
37 | |||
38 | self._register_global_c(c) |
|
38 | ||
39 | return c |
|
39 | return c | |
40 |
|
40 | |||
41 | @LoginRequired() |
|
41 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -48,12 +48,9 b' class RepoSummaryView(RepoAppView):' | |||||
48 |
|
48 | |||
49 | def load_default_context(self): |
|
49 | def load_default_context(self): | |
50 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
50 | c = self._get_local_tmpl_context(include_app_defaults=True) | |
51 |
|
||||
52 | c.rhodecode_repo = None |
|
51 | c.rhodecode_repo = None | |
53 | if not c.repository_requirements_missing: |
|
52 | if not c.repository_requirements_missing: | |
54 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
53 | c.rhodecode_repo = self.rhodecode_vcs_repo | |
55 |
|
||||
56 | self._register_global_c(c) |
|
|||
57 | return c |
|
54 | return c | |
58 |
|
55 | |||
59 | def _get_readme_data(self, db_repo, default_renderer): |
|
56 | def _get_readme_data(self, db_repo, default_renderer): | |
@@ -174,18 +171,22 b' class RepoSummaryView(RepoAppView):' | |||||
174 | if self._rhodecode_user.username != User.DEFAULT_USER: |
|
171 | if self._rhodecode_user.username != User.DEFAULT_USER: | |
175 | username = safe_str(self._rhodecode_user.username) |
|
172 | username = safe_str(self._rhodecode_user.username) | |
176 |
|
173 | |||
177 |
_def_clone_uri = _def_clone_uri_ |
|
174 | _def_clone_uri = _def_clone_uri_id = c.clone_uri_tmpl | |
|
175 | _def_clone_uri_ssh = c.clone_uri_ssh_tmpl | |||
|
176 | ||||
178 | if '{repo}' in _def_clone_uri: |
|
177 | if '{repo}' in _def_clone_uri: | |
179 |
_def_clone_uri_ |
|
178 | _def_clone_uri_id = _def_clone_uri.replace( | |
180 | '{repo}', '_{repoid}') |
|
179 | '{repo}', '_{repoid}') | |
181 | elif '{repoid}' in _def_clone_uri: |
|
180 | elif '{repoid}' in _def_clone_uri: | |
182 |
_def_clone_uri_ |
|
181 | _def_clone_uri_id = _def_clone_uri.replace( | |
183 | '_{repoid}', '{repo}') |
|
182 | '_{repoid}', '{repo}') | |
184 |
|
183 | |||
185 | c.clone_repo_url = self.db_repo.clone_url( |
|
184 | c.clone_repo_url = self.db_repo.clone_url( | |
186 | user=username, uri_tmpl=_def_clone_uri) |
|
185 | user=username, uri_tmpl=_def_clone_uri) | |
187 | c.clone_repo_url_id = self.db_repo.clone_url( |
|
186 | c.clone_repo_url_id = self.db_repo.clone_url( | |
188 |
user=username, uri_tmpl=_def_clone_uri_ |
|
187 | user=username, uri_tmpl=_def_clone_uri_id) | |
|
188 | c.clone_repo_url_ssh = self.db_repo.clone_url( | |||
|
189 | uri_tmpl=_def_clone_uri_ssh, ssh=True) | |||
189 |
|
190 | |||
190 | # If enabled, get statistics data |
|
191 | # If enabled, get statistics data | |
191 |
|
192 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -25,7 +25,7 b' import pytest' | |||||
25 | from whoosh import query |
|
25 | from whoosh import query | |
26 |
|
26 | |||
27 | from rhodecode.tests import ( |
|
27 | from rhodecode.tests import ( | |
28 |
TestController, |
|
28 | TestController, HG_REPO, | |
29 | TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) |
|
29 | TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) | |
30 | from rhodecode.tests.utils import AssertResponse |
|
30 | from rhodecode.tests.utils import AssertResponse | |
31 |
|
31 | |||
@@ -51,7 +51,7 b' class TestSearchController(TestControlle' | |||||
51 |
|
51 | |||
52 | def test_search_files_empty_search(self): |
|
52 | def test_search_files_empty_search(self): | |
53 | if os.path.isdir(self.index_location): |
|
53 | if os.path.isdir(self.index_location): | |
54 |
|
|
54 | pytest.skip('skipped due to existing index') | |
55 | else: |
|
55 | else: | |
56 | self.log_user() |
|
56 | self.log_user() | |
57 | response = self.app.get(route_path('search'), |
|
57 | response = self.app.get(route_path('search'), |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -103,7 +103,7 b' def search(request, tmpl_context, repo_n' | |||||
103 | class SearchView(BaseAppView): |
|
103 | class SearchView(BaseAppView): | |
104 | def load_default_context(self): |
|
104 | def load_default_context(self): | |
105 | c = self._get_local_tmpl_context() |
|
105 | c = self._get_local_tmpl_context() | |
106 | self._register_global_c(c) |
|
106 | ||
107 | return c |
|
107 | return c | |
108 |
|
108 | |||
109 | @LoginRequired() |
|
109 | @LoginRequired() | |
@@ -119,7 +119,7 b' class SearchView(BaseAppView):' | |||||
119 | class SearchRepoView(RepoAppView): |
|
119 | class SearchRepoView(RepoAppView): | |
120 | def load_default_context(self): |
|
120 | def load_default_context(self): | |
121 | c = self._get_local_tmpl_context() |
|
121 | c = self._get_local_tmpl_context() | |
122 | self._register_global_c(c) |
|
122 | ||
123 | return c |
|
123 | return c | |
124 |
|
124 | |||
125 | @LoginRequired() |
|
125 | @LoginRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -22,7 +22,7 b' import os' | |||||
22 | import re |
|
22 | import re | |
23 | import logging |
|
23 | import logging | |
24 | import datetime |
|
24 | import datetime | |
25 | import ConfigParser |
|
25 | from pyramid.compat import configparser | |
26 |
|
26 | |||
27 | from rhodecode.model.db import Session, User, UserSshKeys |
|
27 | from rhodecode.model.db import Session, User, UserSshKeys | |
28 | from rhodecode.model.scm import ScmModel |
|
28 | from rhodecode.model.scm import ScmModel | |
@@ -51,7 +51,7 b' class SshWrapper(object):' | |||||
51 | self.server_impl = None |
|
51 | self.server_impl = None | |
52 |
|
52 | |||
53 | def parse_config(self, config_path): |
|
53 | def parse_config(self, config_path): | |
54 |
parser = |
|
54 | parser = configparser.ConfigParser() | |
55 | parser.read(config_path) |
|
55 | parser.read(config_path) | |
56 | return parser |
|
56 | return parser | |
57 |
|
57 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -93,6 +93,7 b' class VcsServer(object):' | |||||
93 | scm_data = { |
|
93 | scm_data = { | |
94 | 'ip': os.environ['SSH_CLIENT'].split()[0], |
|
94 | 'ip': os.environ['SSH_CLIENT'].split()[0], | |
95 | 'username': self.user.username, |
|
95 | 'username': self.user.username, | |
|
96 | 'user_id': self.user.user_id, | |||
96 | 'action': action, |
|
97 | 'action': action, | |
97 | 'repository': self.repo_name, |
|
98 | 'repository': self.repo_name, | |
98 | 'scm': self.backend, |
|
99 | 'scm': self.backend, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -20,7 +20,7 b'' | |||||
20 |
|
20 | |||
21 | import os |
|
21 | import os | |
22 | import pytest |
|
22 | import pytest | |
23 | import ConfigParser |
|
23 | from pyramid.compat import configparser | |
24 |
|
24 | |||
25 | from rhodecode.apps.ssh_support.lib.ssh_wrapper import SshWrapper |
|
25 | from rhodecode.apps.ssh_support.lib.ssh_wrapper import SshWrapper | |
26 | from rhodecode.lib.utils2 import AttributeDict |
|
26 | from rhodecode.lib.utils2 import AttributeDict | |
@@ -28,7 +28,7 b' from rhodecode.lib.utils2 import Attribu' | |||||
28 |
|
28 | |||
29 | @pytest.fixture |
|
29 | @pytest.fixture | |
30 | def dummy_conf_file(tmpdir): |
|
30 | def dummy_conf_file(tmpdir): | |
31 |
conf = |
|
31 | conf = configparser.ConfigParser() | |
32 | conf.add_section('app:main') |
|
32 | conf.add_section('app:main') | |
33 | conf.set('app:main', 'ssh.executable.hg', '/usr/bin/hg') |
|
33 | conf.set('app:main', 'ssh.executable.hg', '/usr/bin/hg') | |
34 | conf.set('app:main', 'ssh.executable.git', '/usr/bin/git') |
|
34 | conf.set('app:main', 'ssh.executable.git', '/usr/bin/git') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -127,6 +127,7 b' class TestGitServer(object):' | |||||
127 |
|
127 | |||
128 | expected_data = { |
|
128 | expected_data = { | |
129 | 'username': git_server.user.username, |
|
129 | 'username': git_server.user.username, | |
|
130 | 'user_id': git_server.user.user_id, | |||
130 | 'scm': 'git', |
|
131 | 'scm': 'git', | |
131 | 'repository': git_server.repo_name, |
|
132 | 'repository': git_server.repo_name, | |
132 | 'make_lock': None, |
|
133 | 'make_lock': None, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -23,19 +23,14 b' import os' | |||||
23 | import mock |
|
23 | import mock | |
24 | import pytest |
|
24 | import pytest | |
25 |
|
25 | |||
26 | from pyramid import testing |
|
|||
27 |
|
||||
28 | from rhodecode.apps.svn_support import utils |
|
26 | from rhodecode.apps.svn_support import utils | |
29 |
|
27 | |||
30 |
|
28 | |||
|
29 | @pytest.mark.usefixtures('config_stub') | |||
31 | class TestModDavSvnConfig(object): |
|
30 | class TestModDavSvnConfig(object): | |
32 |
|
31 | |||
33 | @classmethod |
|
32 | @classmethod | |
34 | def setup_class(cls): |
|
33 | def setup_class(cls): | |
35 | # Make mako renderer available in tests. |
|
|||
36 | config = testing.setUp() |
|
|||
37 | config.include('pyramid_mako') |
|
|||
38 |
|
||||
39 | cls.location_root = u'/location/root/çµäö' |
|
34 | cls.location_root = u'/location/root/çµäö' | |
40 | cls.parent_path_root = u'/parent/path/çµäö' |
|
35 | cls.parent_path_root = u'/parent/path/çµäö' | |
41 | cls.realm = u'Dummy Realm (äöüçµ)' |
|
36 | cls.realm = u'Dummy Realm (äöüçµ)' |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -20,7 +20,7 b'' | |||||
20 |
|
20 | |||
21 |
|
21 | |||
22 | from rhodecode.apps.admin.navigation import NavigationRegistry |
|
22 | from rhodecode.apps.admin.navigation import NavigationRegistry | |
23 |
from rhodecode. |
|
23 | from rhodecode.apps._base import ADMIN_PREFIX | |
24 | from rhodecode.lib.utils2 import str2bool |
|
24 | from rhodecode.lib.utils2 import str2bool | |
25 |
|
25 | |||
26 |
|
26 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -40,8 +40,7 b' from rhodecode.lib.auth import (' | |||||
40 | LoginRequired, HasUserGroupPermissionAnyDecorator, CSRFRequired) |
|
40 | LoginRequired, HasUserGroupPermissionAnyDecorator, CSRFRequired) | |
41 | from rhodecode.lib import helpers as h, audit_logger |
|
41 | from rhodecode.lib import helpers as h, audit_logger | |
42 | from rhodecode.lib.utils2 import str2bool |
|
42 | from rhodecode.lib.utils2 import str2bool | |
43 |
from rhodecode.model.db import |
|
43 | from rhodecode.model.db import User | |
44 | joinedload, User, UserGroupRepoToPerm, UserGroupRepoGroupToPerm) |
|
|||
45 | from rhodecode.model.meta import Session |
|
44 | from rhodecode.model.meta import Session | |
46 | from rhodecode.model.user_group import UserGroupModel |
|
45 | from rhodecode.model.user_group import UserGroupModel | |
47 |
|
46 | |||
@@ -56,35 +55,8 b' class UserGroupsView(UserGroupAppView):' | |||||
56 | PermissionModel().set_global_permission_choices( |
|
55 | PermissionModel().set_global_permission_choices( | |
57 | c, gettext_translator=self.request.translate) |
|
56 | c, gettext_translator=self.request.translate) | |
58 |
|
57 | |||
59 | self._register_global_c(c) |
|
|||
60 | return c |
|
58 | return c | |
61 |
|
59 | |||
62 | def _get_perms_summary(self, user_group_id): |
|
|||
63 | permissions = { |
|
|||
64 | 'repositories': {}, |
|
|||
65 | 'repositories_groups': {}, |
|
|||
66 | } |
|
|||
67 | ugroup_repo_perms = UserGroupRepoToPerm.query()\ |
|
|||
68 | .options(joinedload(UserGroupRepoToPerm.permission))\ |
|
|||
69 | .options(joinedload(UserGroupRepoToPerm.repository))\ |
|
|||
70 | .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\ |
|
|||
71 | .all() |
|
|||
72 |
|
||||
73 | for gr in ugroup_repo_perms: |
|
|||
74 | permissions['repositories'][gr.repository.repo_name] \ |
|
|||
75 | = gr.permission.permission_name |
|
|||
76 |
|
||||
77 | ugroup_group_perms = UserGroupRepoGroupToPerm.query()\ |
|
|||
78 | .options(joinedload(UserGroupRepoGroupToPerm.permission))\ |
|
|||
79 | .options(joinedload(UserGroupRepoGroupToPerm.group))\ |
|
|||
80 | .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\ |
|
|||
81 | .all() |
|
|||
82 |
|
||||
83 | for gr in ugroup_group_perms: |
|
|||
84 | permissions['repositories_groups'][gr.group.group_name] \ |
|
|||
85 | = gr.permission.permission_name |
|
|||
86 | return permissions |
|
|||
87 |
|
||||
88 | @LoginRequired() |
|
60 | @LoginRequired() | |
89 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') |
|
61 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
90 | @view_config( |
|
62 | @view_config( | |
@@ -94,6 +66,7 b' class UserGroupsView(UserGroupAppView):' | |||||
94 | """ |
|
66 | """ | |
95 | Return members of given user group |
|
67 | Return members of given user group | |
96 | """ |
|
68 | """ | |
|
69 | self.load_default_context() | |||
97 | user_group = self.db_user_group |
|
70 | user_group = self.db_user_group | |
98 | group_members_obj = sorted((x.user for x in user_group.members), |
|
71 | group_members_obj = sorted((x.user for x in user_group.members), | |
99 | key=lambda u: u.username.lower()) |
|
72 | key=lambda u: u.username.lower()) | |
@@ -126,7 +99,8 b' class UserGroupsView(UserGroupAppView):' | |||||
126 | c = self.load_default_context() |
|
99 | c = self.load_default_context() | |
127 | c.user_group = self.db_user_group |
|
100 | c.user_group = self.db_user_group | |
128 | c.active = 'perms_summary' |
|
101 | c.active = 'perms_summary' | |
129 |
c.permissions = |
|
102 | c.permissions = UserGroupModel().get_perms_summary( | |
|
103 | c.user_group.users_group_id) | |||
130 | return self._get_template_context(c) |
|
104 | return self._get_template_context(c) | |
131 |
|
105 | |||
132 | @LoginRequired() |
|
106 | @LoginRequired() | |
@@ -137,7 +111,7 b' class UserGroupsView(UserGroupAppView):' | |||||
137 | def user_group_perms_summary_json(self): |
|
111 | def user_group_perms_summary_json(self): | |
138 | self.load_default_context() |
|
112 | self.load_default_context() | |
139 | user_group = self.db_user_group |
|
113 | user_group = self.db_user_group | |
140 |
return |
|
114 | return UserGroupModel().get_perms_summary(user_group.users_group_id) | |
141 |
|
115 | |||
142 | def _revoke_perms_on_yourself(self, form_result): |
|
116 | def _revoke_perms_on_yourself(self, form_result): | |
143 | _updates = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), |
|
117 | _updates = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), | |
@@ -173,7 +147,8 b' class UserGroupsView(UserGroupAppView):' | |||||
173 | c.active = 'settings' |
|
147 | c.active = 'settings' | |
174 |
|
148 | |||
175 | users_group_form = UserGroupForm( |
|
149 | users_group_form = UserGroupForm( | |
176 | edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)() |
|
150 | self.request.translate, edit=True, | |
|
151 | old_data=c.user_group.get_dict(), allow_disabled=True)() | |||
177 |
|
152 | |||
178 | old_values = c.user_group.get_api_data() |
|
153 | old_values = c.user_group.get_api_data() | |
179 | user_group_name = self.request.POST.get('users_group_name') |
|
154 | user_group_name = self.request.POST.get('users_group_name') | |
@@ -346,7 +321,7 b' class UserGroupsView(UserGroupAppView):' | |||||
346 | user_group_id = user_group.users_group_id |
|
321 | user_group_id = user_group.users_group_id | |
347 | c = self.load_default_context() |
|
322 | c = self.load_default_context() | |
348 | c.user_group = user_group |
|
323 | c.user_group = user_group | |
349 | form = UserGroupPermsForm()().to_python(self.request.POST) |
|
324 | form = UserGroupPermsForm(self.request.translate)().to_python(self.request.POST) | |
350 |
|
325 | |||
351 | if not self._rhodecode_user.is_admin: |
|
326 | if not self._rhodecode_user.is_admin: | |
352 | if self._revoke_perms_on_yourself(form): |
|
327 | if self._revoke_perms_on_yourself(form): | |
@@ -426,7 +401,7 b' class UserGroupsView(UserGroupAppView):' | |||||
426 |
|
401 | |||
427 | try: |
|
402 | try: | |
428 | # first stage that verifies the checkbox |
|
403 | # first stage that verifies the checkbox | |
429 | _form = UserIndividualPermissionsForm() |
|
404 | _form = UserIndividualPermissionsForm(self.request.translate) | |
430 | form_result = _form.to_python(dict(self.request.POST)) |
|
405 | form_result = _form.to_python(dict(self.request.POST)) | |
431 | inherit_perms = form_result['inherit_default_permissions'] |
|
406 | inherit_perms = form_result['inherit_default_permissions'] | |
432 | user_group.inherit_default_permissions = inherit_perms |
|
407 | user_group.inherit_default_permissions = inherit_perms | |
@@ -435,6 +410,7 b' class UserGroupsView(UserGroupAppView):' | |||||
435 | if not inherit_perms: |
|
410 | if not inherit_perms: | |
436 | # only update the individual ones if we un check the flag |
|
411 | # only update the individual ones if we un check the flag | |
437 | _form = UserPermissionsForm( |
|
412 | _form = UserPermissionsForm( | |
|
413 | self.request.translate, | |||
438 | [x[0] for x in c.repo_create_choices], |
|
414 | [x[0] for x in c.repo_create_choices], | |
439 | [x[0] for x in c.repo_create_on_write_choices], |
|
415 | [x[0] for x in c.repo_create_on_write_choices], | |
440 | [x[0] for x in c.repo_group_create_choices], |
|
416 | [x[0] for x in c.repo_group_create_choices], |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -27,7 +27,7 b' from pyramid.authentication import Sessi' | |||||
27 | from rhodecode.authentication.registry import AuthenticationPluginRegistry |
|
27 | from rhodecode.authentication.registry import AuthenticationPluginRegistry | |
28 | from rhodecode.authentication.routes import root_factory |
|
28 | from rhodecode.authentication.routes import root_factory | |
29 | from rhodecode.authentication.routes import AuthnRootResource |
|
29 | from rhodecode.authentication.routes import AuthnRootResource | |
30 |
from rhodecode. |
|
30 | from rhodecode.apps._base import ADMIN_PREFIX | |
31 | from rhodecode.model.settings import SettingsModel |
|
31 | from rhodecode.model.settings import SettingsModel | |
32 |
|
32 | |||
33 |
|
33 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -77,7 +77,6 b' class hybrid_property(object):' | |||||
77 | self.fdel(instance) |
|
77 | self.fdel(instance) | |
78 |
|
78 | |||
79 |
|
79 | |||
80 |
|
||||
81 | class LazyFormencode(object): |
|
80 | class LazyFormencode(object): | |
82 | def __init__(self, formencode_obj, *args, **kwargs): |
|
81 | def __init__(self, formencode_obj, *args, **kwargs): | |
83 | self.formencode_obj = formencode_obj |
|
82 | self.formencode_obj = formencode_obj | |
@@ -106,6 +105,8 b' class RhodeCodeAuthPluginBase(object):' | |||||
106 | "lastname": "last name", |
|
105 | "lastname": "last name", | |
107 | "email": "email address", |
|
106 | "email": "email address", | |
108 | "groups": '["list", "of", "groups"]', |
|
107 | "groups": '["list", "of", "groups"]', | |
|
108 | "user_group_sync": | |||
|
109 | 'True|False defines if returned user groups should be synced', | |||
109 | "extern_name": "name in external source of record", |
|
110 | "extern_name": "name in external source of record", | |
110 | "extern_type": "type of external source of record", |
|
111 | "extern_type": "type of external source of record", | |
111 | "admin": 'True|False defines if user should be RhodeCode super admin', |
|
112 | "admin": 'True|False defines if user should be RhodeCode super admin', | |
@@ -114,6 +115,7 b' class RhodeCodeAuthPluginBase(object):' | |||||
114 | "active_from_extern": |
|
115 | "active_from_extern": | |
115 | "True|False\None, active state from the external auth, " |
|
116 | "True|False\None, active state from the external auth, " | |
116 | "None means use definition from RhodeCode extern_type active value" |
|
117 | "None means use definition from RhodeCode extern_type active value" | |
|
118 | ||||
117 | } |
|
119 | } | |
118 | # set on authenticate() method and via set_auth_type func. |
|
120 | # set on authenticate() method and via set_auth_type func. | |
119 | auth_type = None |
|
121 | auth_type = None | |
@@ -252,29 +254,6 b' class RhodeCodeAuthPluginBase(object):' | |||||
252 | del settings_copy[k] |
|
254 | del settings_copy[k] | |
253 | return settings_copy |
|
255 | return settings_copy | |
254 |
|
256 | |||
255 | @property |
|
|||
256 | def validators(self): |
|
|||
257 | """ |
|
|||
258 | Exposes RhodeCode validators modules |
|
|||
259 | """ |
|
|||
260 | # this is a hack to overcome issues with pylons threadlocals and |
|
|||
261 | # translator object _() not being registered properly. |
|
|||
262 | class LazyCaller(object): |
|
|||
263 | def __init__(self, name): |
|
|||
264 | self.validator_name = name |
|
|||
265 |
|
||||
266 | def __call__(self, *args, **kwargs): |
|
|||
267 | from rhodecode.model import validators as v |
|
|||
268 | obj = getattr(v, self.validator_name) |
|
|||
269 | # log.debug('Initializing lazy formencode object: %s', obj) |
|
|||
270 | return LazyFormencode(obj, *args, **kwargs) |
|
|||
271 |
|
||||
272 | class ProxyGet(object): |
|
|||
273 | def __getattribute__(self, name): |
|
|||
274 | return LazyCaller(name) |
|
|||
275 |
|
||||
276 | return ProxyGet() |
|
|||
277 |
|
||||
278 | @hybrid_property |
|
257 | @hybrid_property | |
279 | def name(self): |
|
258 | def name(self): | |
280 | """ |
|
259 | """ | |
@@ -435,8 +414,9 b' class RhodeCodeAuthPluginBase(object):' | |||||
435 | new_hash = auth.get('_hash_migrate') |
|
414 | new_hash = auth.get('_hash_migrate') | |
436 | if new_hash: |
|
415 | if new_hash: | |
437 | self._migrate_hash_to_bcrypt(username, passwd, new_hash) |
|
416 | self._migrate_hash_to_bcrypt(username, passwd, new_hash) | |
|
417 | if 'user_group_sync' not in auth: | |||
|
418 | auth['user_group_sync'] = False | |||
438 | return self._validate_auth_return(auth) |
|
419 | return self._validate_auth_return(auth) | |
439 |
|
||||
440 | return auth |
|
420 | return auth | |
441 |
|
421 | |||
442 | def _migrate_hash_to_bcrypt(self, username, password, new_hash): |
|
422 | def _migrate_hash_to_bcrypt(self, username, password, new_hash): | |
@@ -561,16 +541,19 b' class RhodeCodeExternalAuthPlugin(RhodeC' | |||||
561 | # enforce user is just in given groups, all of them has to be ones |
|
541 | # enforce user is just in given groups, all of them has to be ones | |
562 | # created from plugins. We store this info in _group_data JSON |
|
542 | # created from plugins. We store this info in _group_data JSON | |
563 | # field |
|
543 | # field | |
564 | try: |
|
544 | ||
565 |
|
|
545 | if auth['user_group_sync']: | |
566 |
|
|
546 | try: | |
567 | 'Performing user_group sync based on set `%s` ' |
|
547 | groups = auth['groups'] or [] | |
568 | 'returned by this plugin', groups) |
|
548 | log.debug( | |
569 | UserGroupModel().enforce_groups(user, groups, self.name) |
|
549 | 'Performing user_group sync based on set `%s` ' | |
570 | except Exception: |
|
550 | 'returned by `%s` plugin', groups, self.name) | |
571 | # for any reason group syncing fails, we should |
|
551 | UserGroupModel().enforce_groups(user, groups, self.name) | |
572 |
|
|
552 | except Exception: | |
573 | log.error(traceback.format_exc()) |
|
553 | # for any reason group syncing fails, we should | |
|
554 | # proceed with login | |||
|
555 | log.error(traceback.format_exc()) | |||
|
556 | ||||
574 | Session().commit() |
|
557 | Session().commit() | |
575 | return auth |
|
558 | return auth | |
576 |
|
559 | |||
@@ -694,7 +677,7 b' def authenticate(username, password, env' | |||||
694 | environ=environ or {}) |
|
677 | environ=environ or {}) | |
695 |
|
678 | |||
696 | if plugin_cache_active: |
|
679 | if plugin_cache_active: | |
697 | log.debug('Trying to fetch cached auth by %s', _password_hash[:6]) |
|
680 | log.debug('Trying to fetch cached auth by `...%s`', _password_hash[:6]) | |
698 | plugin_user = cache_manager.get( |
|
681 | plugin_user = cache_manager.get( | |
699 | _password_hash, createfunc=auth_func) |
|
682 | _password_hash, createfunc=auth_func) | |
700 | else: |
|
683 | else: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -267,6 +267,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
267 | 'firstname': crowd_user["first-name"] or firstname, |
|
267 | 'firstname': crowd_user["first-name"] or firstname, | |
268 | 'lastname': crowd_user["last-name"] or lastname, |
|
268 | 'lastname': crowd_user["last-name"] or lastname, | |
269 | 'groups': crowd_user["groups"], |
|
269 | 'groups': crowd_user["groups"], | |
|
270 | 'user_group_sync': True, | |||
270 | 'email': crowd_user["email"] or email, |
|
271 | 'email': crowd_user["email"] or email, | |
271 | 'admin': admin, |
|
272 | 'admin': admin, | |
272 | 'active': active, |
|
273 | 'active': active, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -212,6 +212,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
212 | 'firstname': safe_unicode(firstname or username), |
|
212 | 'firstname': safe_unicode(firstname or username), | |
213 | 'lastname': safe_unicode(lastname or ''), |
|
213 | 'lastname': safe_unicode(lastname or ''), | |
214 | 'groups': [], |
|
214 | 'groups': [], | |
|
215 | 'user_group_sync': False, | |||
215 | 'email': email or '', |
|
216 | 'email': email or '', | |
216 | 'admin': admin or False, |
|
217 | 'admin': admin or False, | |
217 | 'active': active, |
|
218 | 'active': active, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -154,6 +154,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
154 | 'firstname': safe_unicode(firstname or username), |
|
154 | 'firstname': safe_unicode(firstname or username), | |
155 | 'lastname': safe_unicode(lastname or ''), |
|
155 | 'lastname': safe_unicode(lastname or ''), | |
156 | 'groups': [], |
|
156 | 'groups': [], | |
|
157 | 'user_group_sync': False, | |||
157 | 'email': email or '', |
|
158 | 'email': email or '', | |
158 | 'admin': admin or False, |
|
159 | 'admin': admin or False, | |
159 | 'active': active, |
|
160 | 'active': active, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -460,6 +460,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
460 | 'lastname': safe_unicode( |
|
460 | 'lastname': safe_unicode( | |
461 | get_ldap_attr('attr_lastname') or lastname), |
|
461 | get_ldap_attr('attr_lastname') or lastname), | |
462 | 'groups': groups, |
|
462 | 'groups': groups, | |
|
463 | 'user_group_sync': False, | |||
463 | 'email': get_ldap_attr('attr_email') or email, |
|
464 | 'email': get_ldap_attr('attr_email') or email, | |
464 | 'admin': admin, |
|
465 | 'admin': admin, | |
465 | 'active': active, |
|
466 | 'active': active, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -136,6 +136,7 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
136 | 'lastname': lastname, |
|
136 | 'lastname': lastname, | |
137 | 'groups': [g.gr_name for g in grp.getgrall() |
|
137 | 'groups': [g.gr_name for g in grp.getgrall() | |
138 | if username in g.gr_mem], |
|
138 | if username in g.gr_mem], | |
|
139 | 'user_group_sync': True, | |||
139 | 'email': email, |
|
140 | 'email': email, | |
140 | 'admin': admin, |
|
141 | 'admin': admin, | |
141 | 'active': active, |
|
142 | 'active': active, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -100,6 +100,7 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
100 | "firstname": userobj.firstname, |
|
100 | "firstname": userobj.firstname, | |
101 | "lastname": userobj.lastname, |
|
101 | "lastname": userobj.lastname, | |
102 | "groups": [], |
|
102 | "groups": [], | |
|
103 | 'user_group_sync': False, | |||
103 | "email": userobj.email, |
|
104 | "email": userobj.email, | |
104 | "admin": userobj.admin, |
|
105 | "admin": userobj.admin, | |
105 | "active": userobj.active, |
|
106 | "active": userobj.active, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -111,6 +111,7 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
111 | "firstname": userobj.firstname, |
|
111 | "firstname": userobj.firstname, | |
112 | "lastname": userobj.lastname, |
|
112 | "lastname": userobj.lastname, | |
113 | "groups": [], |
|
113 | "groups": [], | |
|
114 | 'user_group_sync': False, | |||
114 | "email": userobj.email, |
|
115 | "email": userobj.email, | |
115 | "admin": userobj.admin, |
|
116 | "admin": userobj.admin, | |
116 | "active": userobj.active, |
|
117 | "active": userobj.active, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -22,7 +22,7 b'' | |||||
22 | import pytest |
|
22 | import pytest | |
23 |
|
23 | |||
24 |
|
24 | |||
25 | class EnabledAuthPlugin(): |
|
25 | class EnabledAuthPlugin(object): | |
26 | """ |
|
26 | """ | |
27 | Context manager that updates the 'auth_plugins' setting in DB to enable |
|
27 | Context manager that updates the 'auth_plugins' setting in DB to enable | |
28 | a plugin. Previous setting is restored on exit. The rhodecode auth plugin |
|
28 | a plugin. Previous setting is restored on exit. The rhodecode auth plugin |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -23,7 +23,7 b' import pytest' | |||||
23 |
|
23 | |||
24 | from rhodecode.authentication.tests.conftest import ( |
|
24 | from rhodecode.authentication.tests.conftest import ( | |
25 | EnabledAuthPlugin, DisabledAuthPlugin) |
|
25 | EnabledAuthPlugin, DisabledAuthPlugin) | |
26 |
from rhodecode. |
|
26 | from rhodecode.apps._base import ADMIN_PREFIX | |
27 |
|
27 | |||
28 |
|
28 | |||
29 | @pytest.mark.usefixtures('autologin_user', 'app') |
|
29 | @pytest.mark.usefixtures('autologin_user', 'app') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -26,25 +26,25 b' from pyramid.httpexceptions import HTTPF' | |||||
26 | from pyramid.renderers import render |
|
26 | from pyramid.renderers import render | |
27 | from pyramid.response import Response |
|
27 | from pyramid.response import Response | |
28 |
|
28 | |||
|
29 | from rhodecode.apps._base import BaseAppView | |||
29 | from rhodecode.authentication.base import ( |
|
30 | from rhodecode.authentication.base import ( | |
30 | get_auth_cache_manager, get_perms_cache_manager, get_authn_registry) |
|
31 | get_auth_cache_manager, get_perms_cache_manager, get_authn_registry) | |
31 |
from rhodecode.lib import |
|
32 | from rhodecode.lib import helpers as h | |
32 |
from rhodecode.lib.auth import |
|
33 | from rhodecode.lib.auth import ( | |
|
34 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |||
33 | from rhodecode.model.forms import AuthSettingsForm |
|
35 | from rhodecode.model.forms import AuthSettingsForm | |
34 | from rhodecode.model.meta import Session |
|
36 | from rhodecode.model.meta import Session | |
35 | from rhodecode.model.settings import SettingsModel |
|
37 | from rhodecode.model.settings import SettingsModel | |
36 | from rhodecode.translation import _ |
|
|||
37 |
|
38 | |||
38 | log = logging.getLogger(__name__) |
|
39 | log = logging.getLogger(__name__) | |
39 |
|
40 | |||
40 |
|
41 | |||
41 |
class AuthnPluginViewBase( |
|
42 | class AuthnPluginViewBase(BaseAppView): | |
42 |
|
43 | |||
43 | def __init__(self, context, request): |
|
44 | def load_default_context(self): | |
44 | self.request = request |
|
45 | c = self._get_local_tmpl_context() | |
45 | self.context = context |
|
46 | self.plugin = self.context.plugin | |
46 | self.plugin = context.plugin |
|
47 | return c | |
47 | self._rhodecode_user = request.user |
|
|||
48 |
|
48 | |||
49 | @LoginRequired() |
|
49 | @LoginRequired() | |
50 | @HasPermissionAllDecorator('hg.admin') |
|
50 | @HasPermissionAllDecorator('hg.admin') | |
@@ -52,6 +52,7 b' class AuthnPluginViewBase(object):' | |||||
52 | """ |
|
52 | """ | |
53 | View that displays the plugin settings as a form. |
|
53 | View that displays the plugin settings as a form. | |
54 | """ |
|
54 | """ | |
|
55 | c = self.load_default_context() | |||
55 | defaults = defaults or {} |
|
56 | defaults = defaults or {} | |
56 | errors = errors or {} |
|
57 | errors = errors or {} | |
57 | schema = self.plugin.get_settings_schema() |
|
58 | schema = self.plugin.get_settings_schema() | |
@@ -70,15 +71,17 b' class AuthnPluginViewBase(object):' | |||||
70 | 'resource': self.context, |
|
71 | 'resource': self.context, | |
71 | } |
|
72 | } | |
72 |
|
73 | |||
73 | return template_context |
|
74 | return self._get_template_context(c, **template_context) | |
74 |
|
75 | |||
75 | @LoginRequired() |
|
76 | @LoginRequired() | |
76 | @HasPermissionAllDecorator('hg.admin') |
|
77 | @HasPermissionAllDecorator('hg.admin') | |
77 |
@ |
|
78 | @CSRFRequired() | |
78 | def settings_post(self): |
|
79 | def settings_post(self): | |
79 | """ |
|
80 | """ | |
80 | View that validates and stores the plugin settings. |
|
81 | View that validates and stores the plugin settings. | |
81 | """ |
|
82 | """ | |
|
83 | _ = self.request.translate | |||
|
84 | self.load_default_context() | |||
82 | schema = self.plugin.get_settings_schema() |
|
85 | schema = self.plugin.get_settings_schema() | |
83 | data = self.request.params |
|
86 | data = self.request.params | |
84 |
|
87 | |||
@@ -86,10 +89,10 b' class AuthnPluginViewBase(object):' | |||||
86 | valid_data = schema.deserialize(data) |
|
89 | valid_data = schema.deserialize(data) | |
87 | except colander.Invalid as e: |
|
90 | except colander.Invalid as e: | |
88 | # Display error message and display form again. |
|
91 | # Display error message and display form again. | |
89 |
|
|
92 | h.flash( | |
90 | _('Errors exist when saving plugin settings. ' |
|
93 | _('Errors exist when saving plugin settings. ' | |
91 | 'Please check the form inputs.'), |
|
94 | 'Please check the form inputs.'), | |
92 |
|
|
95 | category='error') | |
93 | defaults = {key: data[key] for key in data if key in schema} |
|
96 | defaults = {key: data[key] for key in data if key in schema} | |
94 | return self.settings_get(errors=e.asdict(), defaults=defaults) |
|
97 | return self.settings_get(errors=e.asdict(), defaults=defaults) | |
95 |
|
98 | |||
@@ -99,31 +102,22 b' class AuthnPluginViewBase(object):' | |||||
99 | Session().commit() |
|
102 | Session().commit() | |
100 |
|
103 | |||
101 | # Display success message and redirect. |
|
104 | # Display success message and redirect. | |
102 | self.request.session.flash( |
|
105 | h.flash(_('Auth settings updated successfully.'), category='success') | |
103 | _('Auth settings updated successfully.'), |
|
|||
104 | queue='success') |
|
|||
105 | redirect_to = self.request.resource_path( |
|
106 | redirect_to = self.request.resource_path( | |
106 | self.context, route_name='auth_home') |
|
107 | self.context, route_name='auth_home') | |
107 | return HTTPFound(redirect_to) |
|
108 | return HTTPFound(redirect_to) | |
108 |
|
109 | |||
109 |
|
110 | |||
110 | # TODO: Ongoing migration in these views. |
|
111 | class AuthSettingsView(BaseAppView): | |
111 | # - Maybe we should also use a colander schema for these views. |
|
112 | def load_default_context(self): | |
112 | class AuthSettingsView(object): |
|
113 | c = self._get_local_tmpl_context() | |
113 | def __init__(self, context, request): |
|
114 | return c | |
114 | self.context = context |
|
|||
115 | self.request = request |
|
|||
116 |
|
||||
117 | # TODO: Move this into a utility function. It is needed in all view |
|
|||
118 | # classes during migration. Maybe a mixin? |
|
|||
119 |
|
||||
120 | # Some of the decorators rely on this attribute to be present on the |
|
|||
121 | # class of the decorated method. |
|
|||
122 | self._rhodecode_user = request.user |
|
|||
123 |
|
115 | |||
124 | @LoginRequired() |
|
116 | @LoginRequired() | |
125 | @HasPermissionAllDecorator('hg.admin') |
|
117 | @HasPermissionAllDecorator('hg.admin') | |
126 | def index(self, defaults=None, errors=None, prefix_error=False): |
|
118 | def index(self, defaults=None, errors=None, prefix_error=False): | |
|
119 | c = self.load_default_context() | |||
|
120 | ||||
127 | defaults = defaults or {} |
|
121 | defaults = defaults or {} | |
128 | authn_registry = get_authn_registry(self.request.registry) |
|
122 | authn_registry = get_authn_registry(self.request.registry) | |
129 | enabled_plugins = SettingsModel().get_auth_plugins() |
|
123 | enabled_plugins = SettingsModel().get_auth_plugins() | |
@@ -135,8 +129,8 b' class AuthSettingsView(object):' | |||||
135 | 'enabled_plugins': enabled_plugins, |
|
129 | 'enabled_plugins': enabled_plugins, | |
136 | } |
|
130 | } | |
137 | html = render('rhodecode:templates/admin/auth/auth_settings.mako', |
|
131 | html = render('rhodecode:templates/admin/auth/auth_settings.mako', | |
138 | template_context, |
|
132 | self._get_template_context(c, **template_context), | |
139 |
|
|
133 | self.request) | |
140 |
|
134 | |||
141 | # Create form default values and fill the form. |
|
135 | # Create form default values and fill the form. | |
142 | form_defaults = { |
|
136 | form_defaults = { | |
@@ -155,11 +149,12 b' class AuthSettingsView(object):' | |||||
155 |
|
149 | |||
156 | @LoginRequired() |
|
150 | @LoginRequired() | |
157 | @HasPermissionAllDecorator('hg.admin') |
|
151 | @HasPermissionAllDecorator('hg.admin') | |
158 |
@ |
|
152 | @CSRFRequired() | |
159 | def auth_settings(self): |
|
153 | def auth_settings(self): | |
|
154 | _ = self.request.translate | |||
160 | try: |
|
155 | try: | |
161 | form = AuthSettingsForm()() |
|
156 | form = AuthSettingsForm(self.request.translate)() | |
162 |
form_result = form.to_python(self.request. |
|
157 | form_result = form.to_python(self.request.POST) | |
163 | plugins = ','.join(form_result['auth_plugins']) |
|
158 | plugins = ','.join(form_result['auth_plugins']) | |
164 | setting = SettingsModel().create_or_update_setting( |
|
159 | setting = SettingsModel().create_or_update_setting( | |
165 | 'auth_plugins', plugins) |
|
160 | 'auth_plugins', plugins) | |
@@ -172,24 +167,19 b' class AuthSettingsView(object):' | |||||
172 | cache_manager = get_perms_cache_manager() |
|
167 | cache_manager = get_perms_cache_manager() | |
173 | cache_manager.clear() |
|
168 | cache_manager.clear() | |
174 |
|
169 | |||
175 | self.request.session.flash( |
|
170 | h.flash(_('Auth settings updated successfully.'), category='success') | |
176 | _('Auth settings updated successfully.'), |
|
|||
177 | queue='success') |
|
|||
178 | except formencode.Invalid as errors: |
|
171 | except formencode.Invalid as errors: | |
179 | e = errors.error_dict or {} |
|
172 | e = errors.error_dict or {} | |
180 | self.request.session.flash( |
|
173 | h.flash(_('Errors exist when saving plugin setting. ' | |
181 | _('Errors exist when saving plugin setting. ' |
|
174 | 'Please check the form inputs.'), category='error') | |
182 | 'Please check the form inputs.'), |
|
|||
183 | queue='error') |
|
|||
184 | return self.index( |
|
175 | return self.index( | |
185 | defaults=errors.value, |
|
176 | defaults=errors.value, | |
186 | errors=e, |
|
177 | errors=e, | |
187 | prefix_error=False) |
|
178 | prefix_error=False) | |
188 | except Exception: |
|
179 | except Exception: | |
189 | log.exception('Exception in auth_settings') |
|
180 | log.exception('Exception in auth_settings') | |
190 | self.request.session.flash( |
|
181 | h.flash(_('Error occurred during update of auth settings.'), | |
191 | _('Error occurred during update of auth settings.'), |
|
182 | category='error') | |
192 | queue='error') |
|
|||
193 |
|
183 | |||
194 | redirect_to = self.request.resource_path( |
|
184 | redirect_to = self.request.resource_path( | |
195 | self.context, route_name='auth_home') |
|
185 | self.context, route_name='auth_home') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2013-201 |
|
3 | # Copyright (C) 2013-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -18,121 +18,19 b'' | |||||
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | """ |
|
|||
22 | Pylons environment configuration |
|
|||
23 | """ |
|
|||
24 |
|
21 | |||
25 | import os |
|
22 | import os | |
26 | import logging |
|
23 | import logging | |
27 | import rhodecode |
|
24 | import rhodecode | |
28 | import platform |
|
|||
29 | import re |
|
|||
30 | import io |
|
|||
31 |
|
||||
32 | from mako.lookup import TemplateLookup |
|
|||
33 | from pylons.configuration import PylonsConfig |
|
|||
34 | from pylons.error import handle_mako_error |
|
|||
35 | from pyramid.settings import asbool |
|
|||
36 |
|
||||
37 | # ------------------------------------------------------------------------------ |
|
|||
38 | # CELERY magic until refactor - issue #4163 - import order matters here: |
|
|||
39 | from rhodecode.lib import celerypylons # this must be first, celerypylons |
|
|||
40 | # sets config settings upon import |
|
|||
41 |
|
||||
42 | import rhodecode.integrations # any modules using celery task |
|
|||
43 | # decorators should be added afterwards: |
|
|||
44 | # ------------------------------------------------------------------------------ |
|
|||
45 |
|
||||
46 | from rhodecode.lib import app_globals |
|
|||
47 | from rhodecode.config import utils |
|
|||
48 | from rhodecode.config.routing import make_map |
|
|||
49 | from rhodecode.config.jsroutes import generate_jsroutes_content |
|
|||
50 |
|
||||
51 | from rhodecode.lib import helpers |
|
|||
52 | from rhodecode.lib.auth import set_available_permissions |
|
|||
53 | from rhodecode.lib.utils import ( |
|
|||
54 | repo2db_mapper, make_db_config, set_rhodecode_config, |
|
|||
55 | load_rcextensions) |
|
|||
56 | from rhodecode.lib.utils2 import str2bool, aslist |
|
|||
57 | from rhodecode.lib.vcs import connect_vcs, start_vcs_server |
|
|||
58 | from rhodecode.model.scm import ScmModel |
|
|||
59 |
|
||||
60 | log = logging.getLogger(__name__) |
|
|||
61 |
|
||||
62 | def load_environment(global_conf, app_conf, initial=False, |
|
|||
63 | test_env=None, test_index=None): |
|
|||
64 | """ |
|
|||
65 | Configure the Pylons environment via the ``pylons.config`` |
|
|||
66 | object |
|
|||
67 | """ |
|
|||
68 | config = PylonsConfig() |
|
|||
69 |
|
25 | |||
70 |
|
26 | |||
71 | # Pylons paths |
|
27 | from rhodecode.config import utils | |
72 | root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
|
|||
73 | paths = { |
|
|||
74 | 'root': root, |
|
|||
75 | 'controllers': os.path.join(root, 'controllers'), |
|
|||
76 | 'static_files': os.path.join(root, 'public'), |
|
|||
77 | 'templates': [os.path.join(root, 'templates')], |
|
|||
78 | } |
|
|||
79 |
|
||||
80 | # Initialize config with the basic options |
|
|||
81 | config.init_app(global_conf, app_conf, package='rhodecode', paths=paths) |
|
|||
82 |
|
||||
83 | # store some globals into rhodecode |
|
|||
84 | rhodecode.CELERY_ENABLED = str2bool(config['app_conf'].get('use_celery')) |
|
|||
85 | rhodecode.CELERY_EAGER = str2bool( |
|
|||
86 | config['app_conf'].get('celery.always.eager')) |
|
|||
87 |
|
||||
88 | config['routes.map'] = make_map(config) |
|
|||
89 |
|
||||
90 | config['pylons.app_globals'] = app_globals.Globals(config) |
|
|||
91 | config['pylons.h'] = helpers |
|
|||
92 | rhodecode.CONFIG = config |
|
|||
93 |
|
||||
94 | load_rcextensions(root_path=config['here']) |
|
|||
95 |
|
||||
96 | # Setup cache object as early as possible |
|
|||
97 | import pylons |
|
|||
98 | pylons.cache._push_object(config['pylons.app_globals'].cache) |
|
|||
99 |
|
28 | |||
100 | # Create the Mako TemplateLookup, with the default auto-escaping |
|
29 | from rhodecode.lib.utils import load_rcextensions | |
101 | config['pylons.app_globals'].mako_lookup = TemplateLookup( |
|
30 | from rhodecode.lib.utils2 import str2bool | |
102 | directories=paths['templates'], |
|
31 | from rhodecode.lib.vcs import connect_vcs | |
103 | error_handler=handle_mako_error, |
|
|||
104 | module_directory=os.path.join(app_conf['cache_dir'], 'templates'), |
|
|||
105 | input_encoding='utf-8', default_filters=['escape'], |
|
|||
106 | imports=['from webhelpers.html import escape']) |
|
|||
107 |
|
||||
108 | # sets the c attribute access when don't existing attribute are accessed |
|
|||
109 | config['pylons.strict_tmpl_context'] = True |
|
|||
110 |
|
||||
111 | # configure channelstream |
|
|||
112 | config['channelstream_config'] = { |
|
|||
113 | 'enabled': asbool(config.get('channelstream.enabled', False)), |
|
|||
114 | 'server': config.get('channelstream.server'), |
|
|||
115 | 'secret': config.get('channelstream.secret') |
|
|||
116 | } |
|
|||
117 |
|
32 | |||
118 | db_cfg = make_db_config(clear_session=True) |
|
33 | log = logging.getLogger(__name__) | |
119 |
|
||||
120 | repos_path = list(db_cfg.items('paths'))[0][1] |
|
|||
121 | config['base_path'] = repos_path |
|
|||
122 |
|
||||
123 | # store db config also in main global CONFIG |
|
|||
124 | set_rhodecode_config(config) |
|
|||
125 |
|
||||
126 | # configure instance id |
|
|||
127 | utils.set_instance_id(config) |
|
|||
128 |
|
||||
129 | # CONFIGURATION OPTIONS HERE (note: all config options will override |
|
|||
130 | # any Pylons config options) |
|
|||
131 |
|
||||
132 | # store config reference into our module to skip import magic of pylons |
|
|||
133 | rhodecode.CONFIG.update(config) |
|
|||
134 |
|
||||
135 | return config |
|
|||
136 |
|
34 | |||
137 |
|
35 | |||
138 | def load_pyramid_environment(global_config, settings): |
|
36 | def load_pyramid_environment(global_config, settings): | |
@@ -140,10 +38,13 b' def load_pyramid_environment(global_conf' | |||||
140 | settings_merged = global_config.copy() |
|
38 | settings_merged = global_config.copy() | |
141 | settings_merged.update(settings) |
|
39 | settings_merged.update(settings) | |
142 |
|
40 | |||
143 | # Store the settings to make them available to other modules. |
|
41 | # TODO(marcink): probably not required anymore | |
144 | rhodecode.PYRAMID_SETTINGS = settings_merged |
|
42 | # configure channelstream, | |
145 | # NOTE(marcink): needs to be enabled after full port to pyramid |
|
43 | settings_merged['channelstream_config'] = { | |
146 | # rhodecode.CONFIG = config |
|
44 | 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)), | |
|
45 | 'server': settings_merged.get('channelstream.server'), | |||
|
46 | 'secret': settings_merged.get('channelstream.secret') | |||
|
47 | } | |||
147 |
|
48 | |||
148 | # If this is a test run we prepare the test environment like |
|
49 | # If this is a test run we prepare the test environment like | |
149 | # creating a test database, test search index and test repositories. |
|
50 | # creating a test database, test search index and test repositories. | |
@@ -157,6 +58,8 b' def load_pyramid_environment(global_conf' | |||||
157 | # Initialize the database connection. |
|
58 | # Initialize the database connection. | |
158 | utils.initialize_database(settings_merged) |
|
59 | utils.initialize_database(settings_merged) | |
159 |
|
60 | |||
|
61 | load_rcextensions(root_path=settings_merged['here']) | |||
|
62 | ||||
160 | # Limit backends to `vcs.backends` from configuration |
|
63 | # Limit backends to `vcs.backends` from configuration | |
161 | for alias in rhodecode.BACKENDS.keys(): |
|
64 | for alias in rhodecode.BACKENDS.keys(): | |
162 | if alias not in settings['vcs.backends']: |
|
65 | if alias not in settings['vcs.backends']: | |
@@ -166,17 +69,13 b' def load_pyramid_environment(global_conf' | |||||
166 | # initialize vcs client and optionally run the server if enabled |
|
69 | # initialize vcs client and optionally run the server if enabled | |
167 | vcs_server_uri = settings['vcs.server'] |
|
70 | vcs_server_uri = settings['vcs.server'] | |
168 | vcs_server_enabled = settings['vcs.server.enable'] |
|
71 | vcs_server_enabled = settings['vcs.server.enable'] | |
169 | start_server = ( |
|
|||
170 | settings['vcs.start_server'] and |
|
|||
171 | not int(os.environ.get('RC_VCSSERVER_TEST_DISABLE', '0'))) |
|
|||
172 |
|
||||
173 | if vcs_server_enabled and start_server: |
|
|||
174 | log.info("Starting vcsserver") |
|
|||
175 | start_vcs_server(server_and_port=vcs_server_uri, |
|
|||
176 | protocol=utils.get_vcs_server_protocol(settings), |
|
|||
177 | log_level=settings['vcs.server.log_level']) |
|
|||
178 |
|
72 | |||
179 | utils.configure_vcs(settings) |
|
73 | utils.configure_vcs(settings) | |
180 |
|
74 | |||
|
75 | # Store the settings to make them available to other modules. | |||
|
76 | ||||
|
77 | rhodecode.PYRAMID_SETTINGS = settings_merged | |||
|
78 | rhodecode.CONFIG = settings_merged | |||
|
79 | ||||
181 | if vcs_server_enabled: |
|
80 | if vcs_server_enabled: | |
182 | connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings)) |
|
81 | connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings)) |
@@ -16,7 +16,7 b" RC_HOOK_VER = '_TMPL_'" | |||||
16 |
|
16 | |||
17 | def main(): |
|
17 | def main(): | |
18 | if hooks is None: |
|
18 | if hooks is None: | |
19 |
# exit with success if we cannot import |
|
19 | # exit with success if we cannot import vcsserver.hooks !! | |
20 | # this allows simply push to this repo even without rhodecode |
|
20 | # this allows simply push to this repo even without rhodecode | |
21 | sys.exit(0) |
|
21 | sys.exit(0) | |
22 |
|
22 |
@@ -16,7 +16,7 b" RC_HOOK_VER = '_TMPL_'" | |||||
16 |
|
16 | |||
17 | def main(): |
|
17 | def main(): | |
18 | if hooks is None: |
|
18 | if hooks is None: | |
19 |
# exit with success if we cannot import |
|
19 | # exit with success if we cannot import vcsserver.hooks !! | |
20 | # this allows simply push to this repo even without rhodecode |
|
20 | # this allows simply push to this repo even without rhodecode | |
21 | sys.exit(0) |
|
21 | sys.exit(0) | |
22 |
|
22 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -43,10 +43,7 b'' | |||||
43 | }, |
|
43 | }, | |
44 | "python2.7-Pygments-2.2.0": { |
|
44 | "python2.7-Pygments-2.2.0": { | |
45 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
45 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" | |
46 |
}, |
|
46 | }, | |
47 | "python2.7-Pylons-1.0.2.rhodecode-patch1": { |
|
|||
48 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
|||
49 | }, |
|
|||
50 | "python2.7-Routes-1.13": { |
|
47 | "python2.7-Routes-1.13": { | |
51 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
48 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" | |
52 | }, |
|
49 | }, | |
@@ -77,13 +74,7 b'' | |||||
77 | }, |
|
74 | }, | |
78 | "python2.7-alembic-0.8.4": { |
|
75 | "python2.7-alembic-0.8.4": { | |
79 | "MIT License": "http://spdx.org/licenses/MIT" |
|
76 | "MIT License": "http://spdx.org/licenses/MIT" | |
80 |
}, |
|
77 | }, | |
81 | "python2.7-amqplib-1.0.2": { |
|
|||
82 | "GNU Lesser General Public License v3.0 only": "http://spdx.org/licenses/LGPL-3.0" |
|
|||
83 | }, |
|
|||
84 | "python2.7-anyjson-0.3.3": { |
|
|||
85 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
|||
86 | }, |
|
|||
87 | "python2.7-appenlight-client-0.6.14": { |
|
78 | "python2.7-appenlight-client-0.6.14": { | |
88 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
79 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" | |
89 | }, |
|
80 | }, | |
@@ -195,7 +186,7 b'' | |||||
195 | "python2.7-jupyter-core-4.3.0": { |
|
186 | "python2.7-jupyter-core-4.3.0": { | |
196 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
187 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" | |
197 | }, |
|
188 | }, | |
198 |
"python2.7-kombu- |
|
189 | "python2.7-kombu-4.1.0": { | |
199 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" |
|
190 | "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause" | |
200 | }, |
|
191 | }, | |
201 | "python2.7-mistune-0.7.4": { |
|
192 | "python2.7-mistune-0.7.4": { | |
@@ -327,7 +318,7 b'' | |||||
327 | "Python Software Foundation License version 2": "http://spdx.org/licenses/Python-2.0", |
|
318 | "Python Software Foundation License version 2": "http://spdx.org/licenses/Python-2.0", | |
328 | "Zope Public License 2.0": "http://spdx.org/licenses/ZPL-2.0" |
|
319 | "Zope Public License 2.0": "http://spdx.org/licenses/ZPL-2.0" | |
329 | }, |
|
320 | }, | |
330 |
"python2.7-setuptools-scm-1.15. |
|
321 | "python2.7-setuptools-scm-1.15.6": { | |
331 | "MIT License": "http://spdx.org/licenses/MIT" |
|
322 | "MIT License": "http://spdx.org/licenses/MIT" | |
332 | }, |
|
323 | }, | |
333 | "python2.7-simplegeneric-0.8.1": { |
|
324 | "python2.7-simplegeneric-0.8.1": { |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -18,41 +18,31 b'' | |||||
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | """ |
|
|||
22 | Pylons middleware initialization |
|
|||
23 | """ |
|
|||
24 | import logging |
|
21 | import logging | |
25 | import traceback |
|
22 | import traceback | |
26 | from collections import OrderedDict |
|
23 | import collections | |
27 |
|
24 | |||
28 | from paste.registry import RegistryManager |
|
|||
29 | from paste.gzipper import make_gzip_middleware |
|
25 | from paste.gzipper import make_gzip_middleware | |
30 |
from py |
|
26 | from pyramid.wsgi import wsgiapp | |
31 | from pyramid.authorization import ACLAuthorizationPolicy |
|
27 | from pyramid.authorization import ACLAuthorizationPolicy | |
32 | from pyramid.config import Configurator |
|
28 | from pyramid.config import Configurator | |
33 | from pyramid.settings import asbool, aslist |
|
29 | from pyramid.settings import asbool, aslist | |
34 | from pyramid.wsgi import wsgiapp |
|
|||
35 | from pyramid.httpexceptions import ( |
|
30 | from pyramid.httpexceptions import ( | |
36 | HTTPException, HTTPError, HTTPInternalServerError, HTTPFound) |
|
31 | HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound) | |
37 | from pyramid.events import ApplicationCreated |
|
32 | from pyramid.events import ApplicationCreated | |
38 | from pyramid.renderers import render_to_response |
|
33 | from pyramid.renderers import render_to_response | |
39 | from routes.middleware import RoutesMiddleware |
|
|||
40 | import rhodecode |
|
|||
41 |
|
34 | |||
42 | from rhodecode.model import meta |
|
35 | from rhodecode.model import meta | |
43 | from rhodecode.config import patches |
|
36 | from rhodecode.config import patches | |
44 | from rhodecode.config import utils as config_utils |
|
37 | from rhodecode.config import utils as config_utils | |
45 | from rhodecode.config.routing import STATIC_FILE_PREFIX |
|
38 | from rhodecode.config.environment import load_pyramid_environment | |
46 | from rhodecode.config.environment import ( |
|
|||
47 | load_environment, load_pyramid_environment) |
|
|||
48 |
|
39 | |||
|
40 | from rhodecode.lib.middleware.vcs import VCSMiddleware | |||
49 | from rhodecode.lib.vcs import VCSCommunicationError |
|
41 | from rhodecode.lib.vcs import VCSCommunicationError | |
50 | from rhodecode.lib.exceptions import VCSServerUnavailable |
|
42 | from rhodecode.lib.exceptions import VCSServerUnavailable | |
51 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled |
|
43 | from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled | |
52 | from rhodecode.lib.middleware.error_handling import ( |
|
|||
53 | PylonsErrorHandlingMiddleware) |
|
|||
54 | from rhodecode.lib.middleware.https_fixup import HttpsFixup |
|
44 | from rhodecode.lib.middleware.https_fixup import HttpsFixup | |
55 |
from rhodecode.lib. |
|
45 | from rhodecode.lib.celerylib.loader import configure_celery | |
56 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin |
|
46 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin | |
57 | from rhodecode.lib.utils2 import aslist as rhodecode_aslist, AttributeDict |
|
47 | from rhodecode.lib.utils2 import aslist as rhodecode_aslist, AttributeDict | |
58 | from rhodecode.subscribers import ( |
|
48 | from rhodecode.subscribers import ( | |
@@ -63,157 +53,67 b' from rhodecode.subscribers import (' | |||||
63 | log = logging.getLogger(__name__) |
|
53 | log = logging.getLogger(__name__) | |
64 |
|
54 | |||
65 |
|
55 | |||
66 | # this is used to avoid avoid the route lookup overhead in routesmiddleware |
|
56 | def is_http_error(response): | |
67 | # for certain routes which won't go to pylons to - eg. static files, debugger |
|
57 | # error which should have traceback | |
68 | # it is only needed for the pylons migration and can be removed once complete |
|
58 | return response.status_code > 499 | |
69 | class SkippableRoutesMiddleware(RoutesMiddleware): |
|
|||
70 | """ Routes middleware that allows you to skip prefixes """ |
|
|||
71 |
|
||||
72 | def __init__(self, *args, **kw): |
|
|||
73 | self.skip_prefixes = kw.pop('skip_prefixes', []) |
|
|||
74 | super(SkippableRoutesMiddleware, self).__init__(*args, **kw) |
|
|||
75 |
|
||||
76 | def __call__(self, environ, start_response): |
|
|||
77 | for prefix in self.skip_prefixes: |
|
|||
78 | if environ['PATH_INFO'].startswith(prefix): |
|
|||
79 | # added to avoid the case when a missing /_static route falls |
|
|||
80 | # through to pylons and causes an exception as pylons is |
|
|||
81 | # expecting wsgiorg.routingargs to be set in the environ |
|
|||
82 | # by RoutesMiddleware. |
|
|||
83 | if 'wsgiorg.routing_args' not in environ: |
|
|||
84 | environ['wsgiorg.routing_args'] = (None, {}) |
|
|||
85 | return self.app(environ, start_response) |
|
|||
86 |
|
||||
87 | return super(SkippableRoutesMiddleware, self).__call__( |
|
|||
88 | environ, start_response) |
|
|||
89 |
|
||||
90 |
|
||||
91 | def make_app(global_conf, static_files=True, **app_conf): |
|
|||
92 | """Create a Pylons WSGI application and return it |
|
|||
93 |
|
||||
94 | ``global_conf`` |
|
|||
95 | The inherited configuration for this application. Normally from |
|
|||
96 | the [DEFAULT] section of the Paste ini file. |
|
|||
97 |
|
||||
98 | ``app_conf`` |
|
|||
99 | The application's local configuration. Normally specified in |
|
|||
100 | the [app:<name>] section of the Paste ini file (where <name> |
|
|||
101 | defaults to main). |
|
|||
102 |
|
||||
103 | """ |
|
|||
104 | # Apply compatibility patches |
|
|||
105 | patches.kombu_1_5_1_python_2_7_11() |
|
|||
106 | patches.inspect_getargspec() |
|
|||
107 |
|
||||
108 | # Configure the Pylons environment |
|
|||
109 | config = load_environment(global_conf, app_conf) |
|
|||
110 |
|
||||
111 | # The Pylons WSGI app |
|
|||
112 | app = PylonsApp(config=config) |
|
|||
113 |
|
||||
114 | # Establish the Registry for this application |
|
|||
115 | app = RegistryManager(app) |
|
|||
116 |
|
||||
117 | app.config = config |
|
|||
118 |
|
||||
119 | return app |
|
|||
120 |
|
59 | |||
121 |
|
60 | |||
122 | def make_pyramid_app(global_config, **settings): |
|
61 | def make_pyramid_app(global_config, **settings): | |
123 | """ |
|
62 | """ | |
124 |
Constructs the WSGI application based on Pyramid |
|
63 | Constructs the WSGI application based on Pyramid. | |
125 | application. |
|
|||
126 |
|
64 | |||
127 | Specials: |
|
65 | Specials: | |
128 |
|
66 | |||
129 | * We migrate from Pylons to Pyramid. While doing this, we keep both |
|
|||
130 | frameworks functional. This involves moving some WSGI middlewares around |
|
|||
131 | and providing access to some data internals, so that the old code is |
|
|||
132 | still functional. |
|
|||
133 |
|
||||
134 | * The application can also be integrated like a plugin via the call to |
|
67 | * The application can also be integrated like a plugin via the call to | |
135 | `includeme`. This is accompanied with the other utility functions which |
|
68 | `includeme`. This is accompanied with the other utility functions which | |
136 | are called. Changing this should be done with great care to not break |
|
69 | are called. Changing this should be done with great care to not break | |
137 | cases when these fragments are assembled from another place. |
|
70 | cases when these fragments are assembled from another place. | |
138 |
|
71 | |||
139 | """ |
|
72 | """ | |
140 | # The edition string should be available in pylons too, so we add it here |
|
|||
141 | # before copying the settings. |
|
|||
142 | settings.setdefault('rhodecode.edition', 'Community Edition') |
|
|||
143 |
|
||||
144 | # As long as our Pylons application does expect "unprepared" settings, make |
|
|||
145 | # sure that we keep an unmodified copy. This avoids unintentional change of |
|
|||
146 | # behavior in the old application. |
|
|||
147 | settings_pylons = settings.copy() |
|
|||
148 |
|
||||
149 | sanitize_settings_and_apply_defaults(settings) |
|
73 | sanitize_settings_and_apply_defaults(settings) | |
150 |
|
74 | |||
151 | config = Configurator(settings=settings) |
|
75 | config = Configurator(settings=settings) | |
|
76 | ||||
|
77 | # Apply compatibility patches | |||
|
78 | patches.inspect_getargspec() | |||
|
79 | ||||
152 | load_pyramid_environment(global_config, settings) |
|
80 | load_pyramid_environment(global_config, settings) | |
153 |
|
81 | |||
154 | add_pylons_compat_data(config.registry, global_config, settings_pylons) |
|
82 | # Static file view comes first | |
|
83 | includeme_first(config) | |||
155 |
|
84 | |||
156 | includeme_first(config) |
|
|||
157 | includeme(config) |
|
85 | includeme(config) | |
158 |
|
86 | |||
159 | pyramid_app = config.make_wsgi_app() |
|
87 | pyramid_app = config.make_wsgi_app() | |
160 | pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config) |
|
88 | pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config) | |
161 | pyramid_app.config = config |
|
89 | pyramid_app.config = config | |
162 |
|
90 | |||
|
91 | config.configure_celery(global_config['__file__']) | |||
163 | # creating the app uses a connection - return it after we are done |
|
92 | # creating the app uses a connection - return it after we are done | |
164 | meta.Session.remove() |
|
93 | meta.Session.remove() | |
165 |
|
94 | |||
|
95 | log.info('Pyramid app %s created and configured.', pyramid_app) | |||
166 | return pyramid_app |
|
96 | return pyramid_app | |
167 |
|
97 | |||
168 |
|
98 | |||
169 |
def |
|
99 | def not_found_view(request): | |
170 | """ |
|
100 | """ | |
171 | This creates the view which should be registered as not-found-view to |
|
101 | This creates the view which should be registered as not-found-view to | |
172 | pyramid. Basically it contains of the old pylons app, converted to a view. |
|
102 | pyramid. | |
173 | Additionally it is wrapped by some other middlewares. |
|
|||
174 | """ |
|
103 | """ | |
175 | settings = config.registry.settings |
|
|||
176 | vcs_server_enabled = settings['vcs.server.enable'] |
|
|||
177 |
|
104 | |||
178 | # Make pylons app from unprepared settings. |
|
105 | if not getattr(request, 'vcs_call', None): | |
179 | pylons_app = make_app( |
|
106 | # handle like regular case with our error_handler | |
180 | config.registry._pylons_compat_global_config, |
|
107 | return error_handler(HTTPNotFound(), request) | |
181 | **config.registry._pylons_compat_settings) |
|
|||
182 | config.registry._pylons_compat_config = pylons_app.config |
|
|||
183 |
|
||||
184 | # Appenlight monitoring. |
|
|||
185 | pylons_app, appenlight_client = wrap_in_appenlight_if_enabled( |
|
|||
186 | pylons_app, settings) |
|
|||
187 |
|
108 | |||
188 | # The pylons app is executed inside of the pyramid 404 exception handler. |
|
109 | # handle not found view as a vcs call | |
189 | # Exceptions which are raised inside of it are not handled by pyramid |
|
110 | settings = request.registry.settings | |
190 | # again. Therefore we add a middleware that invokes the error handler in |
|
111 | ae_client = getattr(request, 'ae_client', None) | |
191 | # case of an exception or error response. This way we return proper error |
|
112 | vcs_app = VCSMiddleware( | |
192 | # HTML pages in case of an error. |
|
113 | HTTPNotFound(), request.registry, settings, | |
193 | reraise = (settings.get('debugtoolbar.enabled', False) or |
|
114 | appenlight_client=ae_client) | |
194 | rhodecode.disable_error_handler) |
|
|||
195 | pylons_app = PylonsErrorHandlingMiddleware( |
|
|||
196 | pylons_app, error_handler, reraise) |
|
|||
197 |
|
115 | |||
198 | # The VCSMiddleware shall operate like a fallback if pyramid doesn't find a |
|
116 | return wsgiapp(vcs_app)(None, request) | |
199 | # view to handle the request. Therefore it is wrapped around the pylons |
|
|||
200 | # app. It has to be outside of the error handling otherwise error responses |
|
|||
201 | # from the vcsserver are converted to HTML error pages. This confuses the |
|
|||
202 | # command line tools and the user won't get a meaningful error message. |
|
|||
203 | if vcs_server_enabled: |
|
|||
204 | pylons_app = VCSMiddleware( |
|
|||
205 | pylons_app, settings, appenlight_client, registry=config.registry) |
|
|||
206 |
|
||||
207 | # Convert WSGI app to pyramid view and return it. |
|
|||
208 | return wsgiapp(pylons_app) |
|
|||
209 |
|
||||
210 |
|
||||
211 | def add_pylons_compat_data(registry, global_config, settings): |
|
|||
212 | """ |
|
|||
213 | Attach data to the registry to support the Pylons integration. |
|
|||
214 | """ |
|
|||
215 | registry._pylons_compat_global_config = global_config |
|
|||
216 | registry._pylons_compat_settings = settings |
|
|||
217 |
|
117 | |||
218 |
|
118 | |||
219 | def error_handler(exception, request): |
|
119 | def error_handler(exception, request): | |
@@ -229,10 +129,6 b' def error_handler(exception, request):' | |||||
229 | elif isinstance(exception, VCSCommunicationError): |
|
129 | elif isinstance(exception, VCSCommunicationError): | |
230 | base_response = VCSServerUnavailable() |
|
130 | base_response = VCSServerUnavailable() | |
231 |
|
131 | |||
232 | def is_http_error(response): |
|
|||
233 | # error which should have traceback |
|
|||
234 | return response.status_code > 499 |
|
|||
235 |
|
||||
236 | if is_http_error(base_response): |
|
132 | if is_http_error(base_response): | |
237 | log.exception( |
|
133 | log.exception( | |
238 | 'error occurred handling this request for path: %s', request.path) |
|
134 | 'error occurred handling this request for path: %s', request.path) | |
@@ -272,26 +168,46 b' def error_handler(exception, request):' | |||||
272 | return response |
|
168 | return response | |
273 |
|
169 | |||
274 |
|
170 | |||
|
171 | def includeme_first(config): | |||
|
172 | # redirect automatic browser favicon.ico requests to correct place | |||
|
173 | def favicon_redirect(context, request): | |||
|
174 | return HTTPFound( | |||
|
175 | request.static_path('rhodecode:public/images/favicon.ico')) | |||
|
176 | ||||
|
177 | config.add_view(favicon_redirect, route_name='favicon') | |||
|
178 | config.add_route('favicon', '/favicon.ico') | |||
|
179 | ||||
|
180 | def robots_redirect(context, request): | |||
|
181 | return HTTPFound( | |||
|
182 | request.static_path('rhodecode:public/robots.txt')) | |||
|
183 | ||||
|
184 | config.add_view(robots_redirect, route_name='robots') | |||
|
185 | config.add_route('robots', '/robots.txt') | |||
|
186 | ||||
|
187 | config.add_static_view( | |||
|
188 | '_static/deform', 'deform:static') | |||
|
189 | config.add_static_view( | |||
|
190 | '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24) | |||
|
191 | ||||
|
192 | ||||
275 | def includeme(config): |
|
193 | def includeme(config): | |
276 | settings = config.registry.settings |
|
194 | settings = config.registry.settings | |
277 |
|
195 | |||
278 | # plugin information |
|
196 | # plugin information | |
279 | config.registry.rhodecode_plugins = OrderedDict() |
|
197 | config.registry.rhodecode_plugins = collections.OrderedDict() | |
280 |
|
198 | |||
281 | config.add_directive( |
|
199 | config.add_directive( | |
282 | 'register_rhodecode_plugin', register_rhodecode_plugin) |
|
200 | 'register_rhodecode_plugin', register_rhodecode_plugin) | |
283 |
|
201 | |||
|
202 | config.add_directive('configure_celery', configure_celery) | |||
|
203 | ||||
284 | if asbool(settings.get('appenlight', 'false')): |
|
204 | if asbool(settings.get('appenlight', 'false')): | |
285 | config.include('appenlight_client.ext.pyramid_tween') |
|
205 | config.include('appenlight_client.ext.pyramid_tween') | |
286 |
|
206 | |||
287 | if 'mako.default_filters' not in settings: |
|
|||
288 | # set custom default filters if we don't have it defined |
|
|||
289 | settings['mako.imports'] = 'from rhodecode.lib.base import h_filter' |
|
|||
290 | settings['mako.default_filters'] = 'h_filter' |
|
|||
291 |
|
||||
292 | # Includes which are required. The application would fail without them. |
|
207 | # Includes which are required. The application would fail without them. | |
293 | config.include('pyramid_mako') |
|
208 | config.include('pyramid_mako') | |
294 | config.include('pyramid_beaker') |
|
209 | config.include('pyramid_beaker') | |
|
210 | config.include('rhodecode.lib.caches') | |||
295 |
|
211 | |||
296 | config.include('rhodecode.authentication') |
|
212 | config.include('rhodecode.authentication') | |
297 | config.include('rhodecode.integrations') |
|
213 | config.include('rhodecode.integrations') | |
@@ -331,16 +247,17 b' def includeme(config):' | |||||
331 | config.add_subscriber(write_metadata_if_needed, ApplicationCreated) |
|
247 | config.add_subscriber(write_metadata_if_needed, ApplicationCreated) | |
332 | config.add_subscriber(write_js_routes_if_enabled, ApplicationCreated) |
|
248 | config.add_subscriber(write_js_routes_if_enabled, ApplicationCreated) | |
333 |
|
249 | |||
334 | config.add_request_method( |
|
|||
335 | 'rhodecode.lib.partial_renderer.get_partial_renderer', |
|
|||
336 | 'get_partial_renderer') |
|
|||
337 |
|
||||
338 | # events |
|
250 | # events | |
339 | # TODO(marcink): this should be done when pyramid migration is finished |
|
251 | # TODO(marcink): this should be done when pyramid migration is finished | |
340 | # config.add_subscriber( |
|
252 | # config.add_subscriber( | |
341 | # 'rhodecode.integrations.integrations_event_handler', |
|
253 | # 'rhodecode.integrations.integrations_event_handler', | |
342 | # 'rhodecode.events.RhodecodeEvent') |
|
254 | # 'rhodecode.events.RhodecodeEvent') | |
343 |
|
255 | |||
|
256 | # request custom methods | |||
|
257 | config.add_request_method( | |||
|
258 | 'rhodecode.lib.partial_renderer.get_partial_renderer', | |||
|
259 | 'get_partial_renderer') | |||
|
260 | ||||
344 | # Set the authorization policy. |
|
261 | # Set the authorization policy. | |
345 | authz_policy = ACLAuthorizationPolicy() |
|
262 | authz_policy = ACLAuthorizationPolicy() | |
346 | config.set_authorization_policy(authz_policy) |
|
263 | config.set_authorization_policy(authz_policy) | |
@@ -357,65 +274,29 b' def includeme(config):' | |||||
357 | for inc in includes: |
|
274 | for inc in includes: | |
358 | config.include(inc) |
|
275 | config.include(inc) | |
359 |
|
276 | |||
360 | # This is the glue which allows us to migrate in chunks. By registering the |
|
277 | # custom not found view, if our pyramid app doesn't know how to handle | |
361 | # pylons based application as the "Not Found" view in Pyramid, we will |
|
278 | # the request pass it to potential VCS handling ap | |
362 | # fallback to the old application each time the new one does not yet know |
|
279 | config.add_notfound_view(not_found_view) | |
363 | # how to handle a request. |
|
|||
364 | config.add_notfound_view(make_not_found_view(config)) |
|
|||
365 |
|
||||
366 | if not settings.get('debugtoolbar.enabled', False): |
|
280 | if not settings.get('debugtoolbar.enabled', False): | |
367 | # disabled debugtoolbar handle all exceptions via the error_handlers |
|
281 | # disabled debugtoolbar handle all exceptions via the error_handlers | |
368 | config.add_view(error_handler, context=Exception) |
|
282 | config.add_view(error_handler, context=Exception) | |
369 |
|
283 | |||
|
284 | # all errors including 403/404/50X | |||
370 | config.add_view(error_handler, context=HTTPError) |
|
285 | config.add_view(error_handler, context=HTTPError) | |
371 |
|
286 | |||
372 |
|
287 | |||
373 | def includeme_first(config): |
|
|||
374 | # redirect automatic browser favicon.ico requests to correct place |
|
|||
375 | def favicon_redirect(context, request): |
|
|||
376 | return HTTPFound( |
|
|||
377 | request.static_path('rhodecode:public/images/favicon.ico')) |
|
|||
378 |
|
||||
379 | config.add_view(favicon_redirect, route_name='favicon') |
|
|||
380 | config.add_route('favicon', '/favicon.ico') |
|
|||
381 |
|
||||
382 | def robots_redirect(context, request): |
|
|||
383 | return HTTPFound( |
|
|||
384 | request.static_path('rhodecode:public/robots.txt')) |
|
|||
385 |
|
||||
386 | config.add_view(robots_redirect, route_name='robots') |
|
|||
387 | config.add_route('robots', '/robots.txt') |
|
|||
388 |
|
||||
389 | config.add_static_view( |
|
|||
390 | '_static/deform', 'deform:static') |
|
|||
391 | config.add_static_view( |
|
|||
392 | '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24) |
|
|||
393 |
|
||||
394 |
|
||||
395 | def wrap_app_in_wsgi_middlewares(pyramid_app, config): |
|
288 | def wrap_app_in_wsgi_middlewares(pyramid_app, config): | |
396 | """ |
|
289 | """ | |
397 | Apply outer WSGI middlewares around the application. |
|
290 | Apply outer WSGI middlewares around the application. | |
398 |
|
||||
399 | Part of this has been moved up from the Pylons layer, so that the |
|
|||
400 | data is also available if old Pylons code is hit through an already ported |
|
|||
401 | view. |
|
|||
402 | """ |
|
291 | """ | |
403 | settings = config.registry.settings |
|
292 | settings = config.registry.settings | |
404 |
|
293 | |||
405 | # enable https redirects based on HTTP_X_URL_SCHEME set by proxy |
|
294 | # enable https redirects based on HTTP_X_URL_SCHEME set by proxy | |
406 | pyramid_app = HttpsFixup(pyramid_app, settings) |
|
295 | pyramid_app = HttpsFixup(pyramid_app, settings) | |
407 |
|
296 | |||
408 | # Add RoutesMiddleware to support the pylons compatibility tween during |
|
297 | pyramid_app, _ae_client = wrap_in_appenlight_if_enabled( | |
409 | # migration to pyramid. |
|
298 | pyramid_app, settings) | |
410 |
|
299 | config.registry.ae_client = _ae_client | ||
411 | # TODO(marcink): remove after migration to pyramid |
|
|||
412 | if hasattr(config.registry, '_pylons_compat_config'): |
|
|||
413 | routes_map = config.registry._pylons_compat_config['routes.map'] |
|
|||
414 | pyramid_app = SkippableRoutesMiddleware( |
|
|||
415 | pyramid_app, routes_map, |
|
|||
416 | skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar')) |
|
|||
417 |
|
||||
418 | pyramid_app, _ = wrap_in_appenlight_if_enabled(pyramid_app, settings) |
|
|||
419 |
|
300 | |||
420 | if settings['gzip_responses']: |
|
301 | if settings['gzip_responses']: | |
421 | pyramid_app = make_gzip_middleware( |
|
302 | pyramid_app = make_gzip_middleware( | |
@@ -452,16 +333,21 b' def sanitize_settings_and_apply_defaults' | |||||
452 | function. |
|
333 | function. | |
453 | """ |
|
334 | """ | |
454 |
|
335 | |||
455 | # Pyramid's mako renderer has to search in the templates folder so that the |
|
336 | settings.setdefault('rhodecode.edition', 'Community Edition') | |
456 | # old templates still work. Ported and new templates are expected to use |
|
337 | ||
457 | # real asset specifications for the includes. |
|
338 | if 'mako.default_filters' not in settings: | |
458 | mako_directories = settings.setdefault('mako.directories', [ |
|
339 | # set custom default filters if we don't have it defined | |
459 | # Base templates of the original Pylons application |
|
340 | settings['mako.imports'] = 'from rhodecode.lib.base import h_filter' | |
460 | 'rhodecode:templates', |
|
341 | settings['mako.default_filters'] = 'h_filter' | |
461 | ]) |
|
342 | ||
462 | log.debug( |
|
343 | if 'mako.directories' not in settings: | |
463 | "Using the following Mako template directories: %s", |
|
344 | mako_directories = settings.setdefault('mako.directories', [ | |
464 | mako_directories) |
|
345 | # Base templates of the original application | |
|
346 | 'rhodecode:templates', | |||
|
347 | ]) | |||
|
348 | log.debug( | |||
|
349 | "Using the following Mako template directories: %s", | |||
|
350 | mako_directories) | |||
465 |
|
351 | |||
466 | # Default includes, possible to change as a user |
|
352 | # Default includes, possible to change as a user | |
467 | pyramid_includes = settings.setdefault('pyramid.includes', [ |
|
353 | pyramid_includes = settings.setdefault('pyramid.includes', [ | |
@@ -526,10 +412,10 b' def _int_setting(settings, name, default' | |||||
526 |
|
412 | |||
527 |
|
413 | |||
528 | def _bool_setting(settings, name, default): |
|
414 | def _bool_setting(settings, name, default): | |
529 | input = settings.get(name, default) |
|
415 | input_val = settings.get(name, default) | |
530 | if isinstance(input, unicode): |
|
416 | if isinstance(input_val, unicode): | |
531 | input = input.encode('utf8') |
|
417 | input_val = input_val.encode('utf8') | |
532 | settings[name] = asbool(input) |
|
418 | settings[name] = asbool(input_val) | |
533 |
|
419 | |||
534 |
|
420 | |||
535 | def _list_setting(settings, name, default): |
|
421 | def _list_setting(settings, name, default): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -32,26 +32,10 b' Please keep the following principles in ' | |||||
32 | """ |
|
32 | """ | |
33 |
|
33 | |||
34 |
|
34 | |||
35 | def kombu_1_5_1_python_2_7_11(): |
|
|||
36 | """ |
|
|||
37 | Kombu 1.5.1 relies on a private method which got removed in Python 2.7.11. |
|
|||
38 |
|
||||
39 | This patch adds the symbol to the module :mod:`uuid` and assigns the value |
|
|||
40 | ``None`` to it. This causes kombu to fall back to the public API of |
|
|||
41 | :mod:`uuid`. |
|
|||
42 |
|
||||
43 | This patch can most probably be removed once celery and kombu are updated |
|
|||
44 | to more recent versions. |
|
|||
45 | """ |
|
|||
46 | import uuid |
|
|||
47 |
|
||||
48 | if not hasattr(uuid, '_uuid_generate_random'): |
|
|||
49 | uuid._uuid_generate_random = None |
|
|||
50 |
|
||||
51 |
|
35 | |||
52 | def inspect_getargspec(): |
|
36 | def inspect_getargspec(): | |
53 | """ |
|
37 | """ | |
54 |
Pyramid |
|
38 | Pyramid rely on inspect.getargspec to lookup the signature of | |
55 | view functions. This is not compatible with cython, therefore we replace |
|
39 | view functions. This is not compatible with cython, therefore we replace | |
56 | getargspec with a custom version. |
|
40 | getargspec with a custom version. | |
57 | Code is inspired by the inspect module from Python-3.4 |
|
41 | Code is inspired by the inspect module from Python-3.4 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2018 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/lib/paster_commands/setup_rhodecode.py to rhodecode/lib/paster_commands/deprecated/setup_rhodecode.py |
|
NO CONTENT: file renamed from rhodecode/lib/paster_commands/setup_rhodecode.py to rhodecode/lib/paster_commands/deprecated/setup_rhodecode.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/__init__.py to rhodecode/tests/vcs_operations/__init__.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/__init__.py to rhodecode/tests/vcs_operations/__init__.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/conftest.py to rhodecode/tests/vcs_operations/conftest.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/conftest.py to rhodecode/tests/vcs_operations/conftest.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_calls_custom_auth_code_403.py to rhodecode/tests/vcs_operations/test_vcs_calls_custom_auth_code_403.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_calls_custom_auth_code_403.py to rhodecode/tests/vcs_operations/test_vcs_calls_custom_auth_code_403.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_calls_custom_auth_code_404.py to rhodecode/tests/vcs_operations/test_vcs_calls_custom_auth_code_404.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_calls_custom_auth_code_404.py to rhodecode/tests/vcs_operations/test_vcs_calls_custom_auth_code_404.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_calls_custom_auth_code_bad_code.py to rhodecode/tests/vcs_operations/test_vcs_calls_custom_auth_code_bad_code.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_calls_custom_auth_code_bad_code.py to rhodecode/tests/vcs_operations/test_vcs_calls_custom_auth_code_bad_code.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_operations.py to rhodecode/tests/vcs_operations/test_vcs_operations.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_operations.py to rhodecode/tests/vcs_operations/test_vcs_operations.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_operations_locking.py to rhodecode/tests/vcs_operations/test_vcs_operations_locking.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_operations_locking.py to rhodecode/tests/vcs_operations/test_vcs_operations_locking.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_operations_locking_custom_code.py to rhodecode/tests/vcs_operations/test_vcs_operations_locking_custom_code.py |
|
NO CONTENT: file renamed from rhodecode/tests/other/vcs_operations/test_vcs_operations_locking_custom_code.py to rhodecode/tests/vcs_operations/test_vcs_operations_locking_custom_code.py | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
General Comments 0
You need to be logged in to leave comments.
Login now