Skip to content

Commit 9c71a9c

Browse files
authored
Merge pull request #2634 from sebix/fix-http-auth
http mixin: only send auth when strings not empty
2 parents d7f9409 + fc242ac commit 9c71a9c

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Please refer to the [NEWS](NEWS.md) for a list of changes which have an affect o
2222
- `intelmq.lib.mixins.sql` Add Support for MySQL (PR#2625 by Karl-Johan Karlsson).
2323
- New parameter `stop_retry_limit` to gracefully handle stopping bots which take longer to shutdown (PR#2598 by Lukas Heindl, fixes #2595).
2424
- `intelmq.lib.datatypes`: Remove unneeded Dict39 alias (PR#2639 by Nakul Rajpal, fixes #2635)
25+
- `intelmq.lib.mixins.http`: Only set HTTP header 'Authorization' if username or password are set and are not both empty string as they are by default in the Manager (fixes #2590, PR#2634 by Sebastian Wagner).
2526

2627
### Development
2728

docs/user/bots.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,11 +4520,11 @@ Using 'intelmq' as the `elastic_index`, the following are examples of the genera
45204520

45214521
**`http_username`**
45224522

4523-
(optional, string) HTTP basic authentication username.
4523+
(optional, string) HTTP basic authentication username. Also set `http_password`.
45244524

45254525
**`http_password`**
45264526

4527-
(optional, string) HTTP basic authentication password.
4527+
(optional, string) HTTP basic authentication password. Also set `http_username`.
45284528

45294529
**`use_ssl`**
45304530

intelmq/lib/mixins/http.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ def setup(self):
6565
# tls certificate settings
6666
if self.ssl_client_cert is not None:
6767
self.__session.cert = self.ssl_client_cert
68-
# auth settings
69-
if self.http_username is not None:
68+
# auth settings. username or password must exist (if only one, then this is likely an error, but we should try without auth) and not be an empty string
69+
if self.http_username and self.http_password:
7070
self.__auth = (self.http_username, self.http_password)
71+
elif self.http_username or self.http_password:
72+
# only one, but not both are given
73+
self.logger.warning("Either 'http_username' or 'http_password' are given, but for HTTP Authentication, both must be set.")
7174
self.__session.auth = self.__auth
7275
# headers settings
7376
if self.http_header is not None:

intelmq/tests/bots/collectors/http/test_collector.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,66 @@ def test_debug_request_response_log(self, mocker):
196196
self.assertLogMatches("Response body: 'Should be in logs'.", 'DEBUG')
197197

198198

199+
@requests_mock.Mocker()
200+
class TestHTTPCollectorBotAuthentication(test.BotTestCase, unittest.TestCase):
201+
"""
202+
HttpMixin setup is called a initialization
203+
"""
204+
205+
@classmethod
206+
def set_bot(cls):
207+
cls.bot_reference = HTTPCollectorBot
208+
cls.sysconfig = {'http_url': 'http://localhost/foobar',
209+
'name': 'Example feed',
210+
'http_username': '',
211+
'http_password': '',
212+
'logging_level': 'DEBUG'
213+
}
214+
215+
def test_empty_auth(self, mocker):
216+
"""
217+
Test that no Authorization is set when username and password are empty strings.
218+
"""
219+
def check_authorization_header(request):
220+
print(f'check_authorization_header: {request.headers}') # show the erroneos headers when the test fails
221+
return 'Authorization' not in request.headers
222+
# generates a mock address if the Authorization header is empty, otherwise the test fails
223+
captured = mocker.register_uri('GET', self.sysconfig['http_url'],
224+
text='Foo Bar',
225+
additional_matcher=check_authorization_header)
226+
self.run_bot()
227+
228+
def test_auth_only_username_or_password(self, mocker):
229+
"""
230+
Test that no Authorization is set only the username is given and password is missing
231+
"""
232+
def check_authorization_header(request):
233+
print(f'check_authorization_header: {request.headers}') # show the erroneos headers when the test fails
234+
return 'Authorization' not in request.headers
235+
# generates a mock address if the Authorization header is empty, otherwise the test fails
236+
captured = mocker.register_uri('GET', self.sysconfig['http_url'],
237+
text='Foo Bar',
238+
additional_matcher=check_authorization_header)
239+
log_line = "Either 'http_username' or 'http_password' are given, but for HTTP Authentication, both must be set\."
240+
self.run_bot(parameters={'http_username': 'username'}, allowed_warning_count=1)
241+
self.assertLogMatches(log_line, 'WARNING')
242+
self.run_bot(parameters={'http_password': 'password'}, allowed_warning_count=1)
243+
self.assertLogMatches(log_line, 'WARNING')
244+
245+
def test_auth(self, mocker):
246+
"""
247+
Test the Authorization header when username and password are set.
248+
"""
249+
def check_authorization_header(request):
250+
print(f'check_authorization_header: {request.headers}') # show the erroneos headers when the test fails
251+
return request.headers['Authorization'] == 'Basic dXNlcjpwYXNzd29yZA=='
252+
# generates a mock address if the Authorization header is correct, otherwise the test fails
253+
captured = mocker.register_uri('GET', self.sysconfig['http_url'],
254+
text='Foo Bar',
255+
additional_matcher=check_authorization_header)
256+
self.run_bot(parameters={'http_username': 'user',
257+
'http_password': 'password'})
258+
259+
199260
if __name__ == '__main__': # pragma: no cover
200261
unittest.main()

0 commit comments

Comments
 (0)