##// END OF EJS Templates
fix(svn): fixed svn tests and pass-in the Auth headers back to the svn server
super-admin -
r5224:a16f5a87 default
parent child Browse files
Show More
@@ -139,14 +139,19 b' class SimpleSvnApp(object):'
139
139
140 def _get_request_headers(self, environ):
140 def _get_request_headers(self, environ):
141 headers = {}
141 headers = {}
142
142 whitelist = {
143 'Authorization': {}
144 }
143 for key in environ:
145 for key in environ:
144 if not key.startswith('HTTP_'):
146 if key in whitelist:
147 headers[key] = environ[key]
148 elif not key.startswith('HTTP_'):
145 continue
149 continue
146 new_key = key.split('_')
150 else:
147 new_key = [k.capitalize() for k in new_key[1:]]
151 new_key = key.split('_')
148 new_key = '-'.join(new_key)
152 new_key = [k.capitalize() for k in new_key[1:]]
149 headers[new_key] = environ[key]
153 new_key = '-'.join(new_key)
154 headers[new_key] = environ[key]
150
155
151 if 'CONTENT_TYPE' in environ:
156 if 'CONTENT_TYPE' in environ:
152 headers['Content-Type'] = environ['CONTENT_TYPE']
157 headers['Content-Type'] = environ['CONTENT_TYPE']
@@ -17,12 +17,14 b''
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 import io
19 import io
20 from base64 import b64encode
20
21
21 import pytest
22 import pytest
22 from mock import patch, Mock
23 from unittest.mock import patch, Mock, MagicMock
23
24
24 from rhodecode.lib.middleware.simplesvn import SimpleSvn, SimpleSvnApp
25 from rhodecode.lib.middleware.simplesvn import SimpleSvn, SimpleSvnApp
25 from rhodecode.lib.utils import get_rhodecode_base_path
26 from rhodecode.lib.utils import get_rhodecode_base_path
27 from rhodecode.tests import SVN_REPO, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS
26
28
27
29
28 class TestSimpleSvn(object):
30 class TestSimpleSvn(object):
@@ -99,24 +101,31 b' class TestSimpleSvn(object):'
99 assert wsgi_app == wsgi_app_mock()
101 assert wsgi_app == wsgi_app_mock()
100
102
101
103
104 def basic_auth(username, password):
105 token = b64encode(f"{username}:{password}".encode('utf-8')).decode("ascii")
106 return f'Basic {token}'
107
108
102 class TestSimpleSvnApp(object):
109 class TestSimpleSvnApp(object):
103 data = b'<xml></xml>'
110 data = b'<xml></xml>'
104 path = '/group/my-repo'
111 path = SVN_REPO
105 wsgi_input = io.BytesIO(data)
112 wsgi_input = io.BytesIO(data)
106 environment = {
113 environment = {
107 'HTTP_DAV': (
114 'HTTP_DAV': (
108 'http://subversion.tigris.org/xmlns/dav/svn/depth,'
115 'http://subversion.tigris.org/xmlns/dav/svn/depth, '
109 ' http://subversion.tigris.org/xmlns/dav/svn/mergeinfo'),
116 'http://subversion.tigris.org/xmlns/dav/svn/mergeinfo'),
110 'HTTP_USER_AGENT': 'SVN/1.8.11 (x86_64-linux) serf/1.3.8',
117 'HTTP_USER_AGENT': 'SVN/1.14.1 (x86_64-linux) serf/1.3.8',
111 'REQUEST_METHOD': 'OPTIONS',
118 'REQUEST_METHOD': 'OPTIONS',
112 'PATH_INFO': path,
119 'PATH_INFO': path,
113 'wsgi.input': wsgi_input,
120 'wsgi.input': wsgi_input,
114 'CONTENT_TYPE': 'text/xml',
121 'CONTENT_TYPE': 'text/xml',
115 'CONTENT_LENGTH': '130'
122 'CONTENT_LENGTH': '130',
123 'Authorization': basic_auth(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS)
116 }
124 }
117
125
118 def setup_method(self, method):
126 def setup_method(self, method):
119 self.host = 'http://localhost/'
127 # note(marcink): this is hostname from docker compose used for testing...
128 self.host = 'http://svn:8090'
120 base_path = get_rhodecode_base_path()
129 base_path = get_rhodecode_base_path()
121 self.app = SimpleSvnApp(
130 self.app = SimpleSvnApp(
122 config={'subversion_http_server_url': self.host,
131 config={'subversion_http_server_url': self.host,
@@ -127,7 +136,8 b' class TestSimpleSvnApp(object):'
127 'Dav': self.environment['HTTP_DAV'],
136 'Dav': self.environment['HTTP_DAV'],
128 'User-Agent': self.environment['HTTP_USER_AGENT'],
137 'User-Agent': self.environment['HTTP_USER_AGENT'],
129 'Content-Type': self.environment['CONTENT_TYPE'],
138 'Content-Type': self.environment['CONTENT_TYPE'],
130 'Content-Length': self.environment['CONTENT_LENGTH']
139 'Content-Length': self.environment['CONTENT_LENGTH'],
140 'Authorization': self.environment['Authorization']
131 }
141 }
132 headers = self.app._get_request_headers(self.environment)
142 headers = self.app._get_request_headers(self.environment)
133 assert headers == expected_headers
143 assert headers == expected_headers
@@ -139,6 +149,7 b' class TestSimpleSvnApp(object):'
139 'Dav': environment['HTTP_DAV'],
149 'Dav': environment['HTTP_DAV'],
140 'Content-Length': self.environment['CONTENT_LENGTH'],
150 'Content-Length': self.environment['CONTENT_LENGTH'],
141 'User-Agent': environment['HTTP_USER_AGENT'],
151 'User-Agent': environment['HTTP_USER_AGENT'],
152 'Authorization': self.environment['Authorization']
142 }
153 }
143 request_headers = self.app._get_request_headers(environment)
154 request_headers = self.app._get_request_headers(environment)
144 assert request_headers == expected_headers
155 assert request_headers == expected_headers
@@ -180,28 +191,42 b' class TestSimpleSvnApp(object):'
180 'MS-Author-Via': 'DAV',
191 'MS-Author-Via': 'DAV',
181 'SVN-Supported-Posts': 'create-txn-with-props'
192 'SVN-Supported-Posts': 'create-txn-with-props'
182 }
193 }
183 response_mock.status_code = 200
194
184 response_mock.reason = 'OK'
195 from rhodecode.lib.middleware.simplesvn import requests
185 with patch('rhodecode.lib.middleware.simplesvn.requests.request') as (
196 original_request = requests.Session.request
186 request_mock):
197
187 request_mock.return_value = response_mock
198 with patch('rhodecode.lib.middleware.simplesvn.requests.Session.request', autospec=True) as request_mock:
199 # Use side_effect to call the original method
200 request_mock.side_effect = original_request
188 self.app(self.environment, start_response)
201 self.app(self.environment, start_response)
189
202
190 expected_url = f'{self.host.strip("/")}{self.path}'
203 expected_url = f'{self.host.strip("/")}/{self.path}'
191 expected_request_headers = {
204 expected_request_headers = {
192 'Dav': self.environment['HTTP_DAV'],
205 'Dav': self.environment['HTTP_DAV'],
193 'User-Agent': self.environment['HTTP_USER_AGENT'],
206 'User-Agent': self.environment['HTTP_USER_AGENT'],
207 'Authorization': self.environment['Authorization'],
194 'Content-Type': self.environment['CONTENT_TYPE'],
208 'Content-Type': self.environment['CONTENT_TYPE'],
195 'Content-Length': self.environment['CONTENT_LENGTH']
209 'Content-Length': self.environment['CONTENT_LENGTH'],
196 }
210 }
211
212 # Check if the method was called
213 assert request_mock.called
214 assert request_mock.call_count == 1
215
216 # Extract the session instance from the first call
217 called_with_session = request_mock.call_args[0][0]
218
219 request_mock.assert_called_once_with(
220 called_with_session,
221 self.environment['REQUEST_METHOD'], expected_url,
222 data=self.data, headers=expected_request_headers, stream=False)
223
197 expected_response_headers = [
224 expected_response_headers = [
198 ('SVN-Supported-Posts', 'create-txn-with-props'),
225 ('SVN-Supported-Posts', 'create-txn-with-props'),
199 ('MS-Author-Via', 'DAV'),
226 ('MS-Author-Via', 'DAV'),
200 ]
227 ]
201 request_mock.assert_called_once_with(
228
202 self.environment['REQUEST_METHOD'], expected_url,
229 # TODO: the svn doesn't have a repo for testing
203 data=self.data, headers=expected_request_headers, stream=False)
230 #args, _ = start_response.call_args
204 response_mock.iter_content.assert_called_once_with(chunk_size=1024)
231 #assert args[0] == '200 OK'
205 args, _ = start_response.call_args
232 #assert sorted(args[1]) == sorted(expected_response_headers)
206 assert args[0] == '200 OK'
207 assert sorted(args[1]) == sorted(expected_response_headers)
General Comments 0
You need to be logged in to leave comments. Login now