Skip to content

Commit 2b1c1e8

Browse files
committed
issue2550837 - New option for web auth (also http header passing)
Implement experimental support to allow tracker to use an alternate authentication variable replacing ROUNDUP_USER. Also add -I option to roundup-server to whitelist HTTP headers that should be passed through to the tracker.
1 parent 1e8c94e commit 2b1c1e8

File tree

6 files changed

+114
-6
lines changed

6 files changed

+114
-6
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ Features:
178178
translations from https://sourceforge.net/p/roundup/code/merge-requests/3/
179179
(John Rouillard. DE translations by Tobias Herp.)
180180
- send_message now allows setting authid to set source of email. (John Rouillard)
181+
- issue2550837 - New option for web auth (also http header passing).
182+
Allow admin to configure authentication header replacing the default
183+
REMOTE_USER. Also allow arbitrary headers to be passed to the
184+
tracker when using roundup-serverbhind a proxy.
181185

182186
2020-07-13 2.0.0
183187

doc/admin_guide.txt

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ Roundup identifies users in a number of ways:
208208
Authentication or cookie authentication. If you are running the web
209209
server (roundup-server) through another HTTP server (eg. apache or IIS)
210210
then that server may require HTTP Basic Authentication, and it will pass
211-
the ``REMOTE_USER`` variable through to Roundup. If this variable is not
211+
the ``REMOTE_USER`` variable (or variable defined using
212+
http_auth_header) through to Roundup. If this variable is not
212213
present, then Roundup defaults to using its own cookie-based login
213214
mechanism.
214215
2. In email messages handled by roundup-mailgw, users are identified by the
@@ -228,6 +229,47 @@ Email Registration
228229
More information about how to customise your tracker's security settings
229230
may be found in the `customisation documentation`_.
230231

232+
Configuring Authentication Header/Variable
233+
------------------------------------------
234+
235+
The front end server running roundup can perform the user
236+
authentication. It pass the authenticated username to the backend in a
237+
variable. By default roundup looks for the ``REMOTE_USER`` variable
238+
This can be changed by setting the parameter ``http_auth_header`` in the
239+
``[web]`` section of the tracker's ``config.ini`` file. If the value
240+
is unset (the default) the REMOTE_USER variable is used.
241+
242+
If you are running roundup using ``roundup-server`` behind a proxy
243+
that authenticates the user you need to configure ``roundup-server`` to
244+
pass the proper header to the tracker. By default ``roundup-server``
245+
looks for the ``REMOTE_USER`` header for the authenticated user. You
246+
can copy an arbitrary header variable to the tracker using the ``-I``
247+
option to roundup-server (or the equivalent option in the
248+
roundup-server config file).
249+
250+
For example to use the ``uid_variable`` header, two configuration
251+
changes are needed: First configure ``roundup-server`` to pass the
252+
header to the tracker using::
253+
254+
roundup-server -I uid_variable ....
255+
256+
note that the header is passed exactly as supplied by the upstream
257+
server. It is **not** prefixed with ``HTTP_`` like other headers since
258+
you are explicitly whitelisting the header. Multiple comma separated
259+
headers can be passed to the ``-I`` option. These could be used in a
260+
detector or other tracker extensions, but only one header can be used
261+
by the tracker as an authentication header.
262+
263+
To make the tracker honor the new variable changing the tracker
264+
``config.ini`` to read::
265+
266+
[web]
267+
...
268+
http_auth_header = uid_variable
269+
270+
At the time this is written, support is experimental. If you use it
271+
you should notify the roundup maintainers using the roundup-users
272+
mailing list.
231273

232274
Tasks
233275
=====

doc/upgrading.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,47 @@ install setuptools. Use the version packgaged by your OS vendor. If
109109
your OS vendor doesn't supply setuptools use ``pip install
110110
setuptools``. (You may need pip3 rather than pip if using python3.)
111111

112+
Define Authentication Header
113+
----------------------------
114+
115+
The front end server running roundup can perform the user
116+
authentication. It pass the authenticated username to the backend in a
117+
variable. By default roundup looks for the ``REMOTE_USER`` variable
118+
This can be changed by setting the parameter ``http_auth_header`` in the
119+
``[web]`` section of the tracker's ``config.ini`` file. If the value
120+
is unset (the default) the REMOTE_USER variable is used.
121+
122+
If you are running roundup using ``roundup-server`` behind a proxy
123+
that authenticates the user you need to configure ``roundup-server`` to
124+
pass the proper header to the tracker. By default ``roundup-server``
125+
looks for the ``REMOTE_USER`` header for the authenticated user. You
126+
can copy an arbitrary header variable to the tracker using the ``-I``
127+
option to roundup-server (or the equivalent option in the
128+
roundup-server config file).
129+
130+
For example to use the ``uid_variable`` header, two configuration
131+
changes are needed: First configure ``roundup-server`` to pass the
132+
header to the tracker using::
133+
134+
roundup-server -I uid_variable ....
135+
136+
note that the header is passed exactly as supplied by the upstream
137+
server. It is **not** prefixed with ``HTTP_`` like other headers since
138+
you are explicitly whitelisting the header. Multiple comma separated
139+
headers can be passed to the ``-I`` option. These could be used in a
140+
detector or other tracker extensions, but only one header can be used
141+
by the tracker as an authentication header.
142+
143+
To make the tracker honor the new variable changing the tracker
144+
``config.ini`` to read::
145+
146+
[web]
147+
...
148+
http_auth_header = uid_variable
149+
150+
At the time this is written, support is experimental. If you use it
151+
you should notify the roundup maintainers using the roundup-users
152+
mailing list.
112153

113154
Classname Format Enforced
114155
-------------------------

roundup/cgi/client.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -997,17 +997,18 @@ def determine_user(self):
997997
user = None
998998
# first up, try http authorization if enabled
999999
cfg = self.instance.config
1000+
remote_user_header = cfg.WEB_HTTP_AUTH_HEADER or 'REMOTE_USER'
10001001
if cfg.WEB_COOKIE_TAKES_PRECEDENCE:
10011002
user = self.session_api.get('user')
10021003
if user:
10031004
# update session lifetime datestamp
10041005
self.session_api.update()
1005-
if 'REMOTE_USER' in self.env:
1006-
del self.env['REMOTE_USER']
1006+
if remote_user_header in self.env:
1007+
del self.env[remote_user_header]
10071008
if not user and cfg.WEB_HTTP_AUTH:
1008-
if 'REMOTE_USER' in self.env:
1009+
if remote_user_header in self.env:
10091010
# we have external auth (e.g. by Apache)
1010-
user = self.env['REMOTE_USER']
1011+
user = self.env[remote_user_header]
10111012
if cfg.WEB_HTTP_AUTH_CONVERT_REALM_TO_LOWERCASE and '@' in user:
10121013
u, d = user.split ('@', 1)
10131014
user = '@'.join ((u, d.lower()))

roundup/configuration.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,10 +836,16 @@ def str2value(self, value):
836836
"trust *all* users uploading content to your tracker."),
837837
(BooleanOption, 'http_auth', "yes",
838838
"Whether to use HTTP Basic Authentication, if present.\n"
839-
"Roundup will use either the REMOTE_USER or HTTP_AUTHORIZATION\n"
839+
"Roundup will use either the REMOTE_USER (the value set \n"
840+
"by http_auth_header) or HTTP_AUTHORIZATION\n"
840841
"variables supplied by your web server (in that order).\n"
841842
"Set this option to 'no' if you do not wish to use HTTP Basic\n"
842843
"Authentication in your web interface."),
844+
(Option, "http_auth_header", "",
845+
"The HTTP header that holds the user authentication information.\n"
846+
"If empty (default) the REMOTE_USER header is used.\n"
847+
"This is used when the upstream HTTP server authenticates\n"
848+
"the user and passes the username using this HTTP header."),
843849
(BooleanOption, 'http_auth_convert_realm_to_lowercase', "no",
844850
"If usernames consist of a name and a domain/realm part of\n"
845851
"the form user@realm and we're using REMOTE_USER for\n"

roundup/scripts/roundup_server.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ def inner_run_cgi(self):
406406
if co:
407407
env['HTTP_COOKIE'] = ', '.join(co)
408408
env['HTTP_AUTHORIZATION'] = self.headers.get('authorization')
409+
# self.CONFIG['INCLUDE_HEADERS'] is a list.
410+
for h in self.CONFIG['INCLUDE_HEADERS']:
411+
env[h] = self.headers.get(h, None)
412+
# if header is MISSING
413+
if env[h] is None:
414+
del(env[h])
409415
env['SCRIPT_NAME'] = ''
410416
env['SERVER_NAME'] = self.server.server_name
411417
env['SERVER_PORT'] = str(self.server.server_port)
@@ -626,6 +632,12 @@ class ServerConfig(configuration.Config):
626632
(configuration.NullableFilePathOption, "pem", "",
627633
"PEM file used for SSL. A temporary self-signed certificate\n"
628634
"will be used if left blank."),
635+
(configuration.WordListOption, "include_headers", "",
636+
"Comma separated list of extra headers that should\n"
637+
"be copied into the CGI environment.\n"
638+
"E.G. if you want to acces the REMOTE_USER and\n"
639+
"X-Proxy-User headers in the back end,\n"
640+
"set to the value REMOTE_USER,X-Proxy-User."),
629641
)),
630642
("trackers", (), "Roundup trackers to serve.\n"
631643
"Each option in this section defines single Roundup tracker.\n"
@@ -650,6 +662,7 @@ class ServerConfig(configuration.Config):
650662
"loghttpvialogger": 'L',
651663
"ssl": "s",
652664
"pem": "e:",
665+
"include_headers": "I:",
653666
}
654667

655668
def __init__(self, config_file=None):
@@ -864,6 +877,7 @@ def usage(message=''):
864877
connections, defaults to localhost, use 0.0.0.0 to bind
865878
to all network interfaces
866879
-p <port> set the port to listen on (default: %(port)s)
880+
-I <header1[,header2]*> list of headers to pass to the backend
867881
-l <fname> log to the file indicated by fname instead of stderr/stdout
868882
-N log client machine names instead of IP addresses (much slower)
869883
-i <fname> set tracker index template

0 commit comments

Comments
 (0)