annotate roundup/cgi/client.py @ 8575:b1024bf0d9f7

feature: add nonceless/tokenless CSRF protection Add tokenless CSRF protection following: https://words.filippo.io/csrf/ Must be enabled using use_tokenless_csrf_protection in config.ini. By default it's off. If enabled the older csrf_* settings are ignored. The allowed_api_origins setting is still used for Origin comparisons. This should also improve performance as a nonce isn't required so generating random nonce and saving it to the otks database is eliminated. doc/admin_guide.txt, doc/reference.txt doc/upgrading.txt doc updates. roundup/configuration.py add use_tokenless_csrf_protection setting. move allowed_api_origins directly after use_tokenless_csrf_protection and before the older csrf_* settings. It's used by both of them. Rewrite description of allowed_api_origins as its applied to all URLs with tokenless protection, not just API URLs. roundup/anypy/urllib_.py import urlsplit, it is used in new code. urlparse() is less efficient and splits params out of the path component. Since Roundup doesn't require that params be split from the path. I expect future patch will replace urlparse() with urlsplit() globally and not need urlparse(). roundup/cgi/client.py add handle_csrf_tokenless() and call from handle_csrf() if use_tokenless_csrf_protection is enabled. refactor code that expires csrf tokens when used with the wrong methods (i.e. GET) into expire_exposed_keys(). Call same from handle_csrf and handle_csrf_tokenless. Also improve logging if this happens including both Referer and Origin headers if available. Arguably we dont care about CSRF tokens exposed via GET/HEAD/OPTIONS in the tokenless case, but this cleans them up in case the admin has to switch back. At some future date we can delete all the nonce based CSRF from 2018. Update handle_csrf() docstring about calling/returning handle_csrf_tokenless() when enabled. Call expire_exposed_keys(method) if token is supplied with wrong method. roundup/cgi/templating.py disable nonce generation/save and always return "0" when use_tokenless_csrf_protection enabled.
author John Rouillard <rouilj@ieee.org>
date Sun, 19 Apr 2026 20:50:07 -0400
parents 5fbf6451a782
children ed1465c5963e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1 """WWW request handler (also used in the stand-alone server).
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 """
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
3 __docformat__ = 'restructuredtext'
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
5 import base64
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
6 import binascii
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
7 import codecs
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
8 import email.utils
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
9 import errno
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
10 import logging
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
11 import mimetypes
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
12 import os
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
13 import re
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
14 import socket
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
15 import stat
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
16 import sys
8555
98fb176224fc bug(perf): move import tempfile to top of file
John Rouillard <rouilj@ieee.org>
parents: 8554
diff changeset
17 import tempfile
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
18 import time
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
19 from email.mime.multipart import MIMEMultipart
4543
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
20 from traceback import format_exc
7813
928c20d4344b chore(ruff): sort imports; tuples for import not supported in python2.
John Rouillard <rouilj@ieee.org>
parents: 7809
diff changeset
21
4638
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
22 try:
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
23 from OpenSSL.SSL import SysCallError
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
24 except ImportError:
5429
daa19de102a2 Python 3 preparation: make fallback SysCallError an actual exception class.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5422
diff changeset
25 class SysCallError(Exception):
daa19de102a2 Python 3 preparation: make fallback SysCallError an actual exception class.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5422
diff changeset
26 pass
4638
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
27
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
28 import roundup.anypy.email_ # noqa: F401 -- patches for email library code
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
29 from roundup import hyperdb, rest, xmlrpc
8104
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
30
7813
928c20d4344b chore(ruff): sort imports; tuples for import not supported in python2.
John Rouillard <rouilj@ieee.org>
parents: 7809
diff changeset
31 # quality of random checked below
928c20d4344b chore(ruff): sort imports; tuples for import not supported in python2.
John Rouillard <rouilj@ieee.org>
parents: 7809
diff changeset
32 from roundup.anypy import http_, random_, urllib_, xmlrpc_
928c20d4344b chore(ruff): sort imports; tuples for import not supported in python2.
John Rouillard <rouilj@ieee.org>
parents: 7809
diff changeset
33 from roundup.anypy.cgi_ import cgi
928c20d4344b chore(ruff): sort imports; tuples for import not supported in python2.
John Rouillard <rouilj@ieee.org>
parents: 7809
diff changeset
34 from roundup.anypy.cookie_ import BaseCookie, CookieError, SimpleCookie, get_cookie_date
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
35 from roundup.anypy.html import html_escape
7813
928c20d4344b chore(ruff): sort imports; tuples for import not supported in python2.
John Rouillard <rouilj@ieee.org>
parents: 7809
diff changeset
36 from roundup.anypy.strings import b2s, bs2b, is_us, s2b, uchr
928c20d4344b chore(ruff): sort imports; tuples for import not supported in python2.
John Rouillard <rouilj@ieee.org>
parents: 7809
diff changeset
37 from roundup.cgi import TranslationService, accept_language, actions, cgitb, templating
8104
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
38 from roundup.cgi.exceptions import (
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
39 DetectorError,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
40 FormError,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
41 IndexerQueryError,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
42 NotFound,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
43 NotModified,
8408
e882a5d52ae5 refactor: move RateLimitExceeded to roundup.cgi.exceptions
John Rouillard <rouilj@ieee.org>
parents: 8386
diff changeset
44 RateLimitExceeded,
8411
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
45 Reauth,
8104
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
46 Redirect,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
47 SendFile,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
48 SendStaticFile,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
49 SeriousError,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
50 )
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
51 from roundup.cgi.form_parser import FormParser
8104
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
52 from roundup.exceptions import (
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
53 LoginError,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
54 Reject,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
55 RejectRaw,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
56 Unauthorised,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
57 UsageError,
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
58 )
8241
741ea8a86012 fix: issue2551374. Error handling for filter expressions.
John Rouillard <rouilj@ieee.org>
parents: 8237
diff changeset
59
8446
14c7c07b32d8 feature: add thread local trace_id and trace_reason to logging.
John Rouillard <rouilj@ieee.org>
parents: 8412
diff changeset
60 from roundup.logcontext import gen_trace_id, store_trace_reason
14c7c07b32d8 feature: add thread local trace_id and trace_reason to logging.
John Rouillard <rouilj@ieee.org>
parents: 8412
diff changeset
61 from roundup.mailer import Mailer, MessageSendError
8241
741ea8a86012 fix: issue2551374. Error handling for filter expressions.
John Rouillard <rouilj@ieee.org>
parents: 8237
diff changeset
62 from roundup.mlink_expr import ExpressionError
741ea8a86012 fix: issue2551374. Error handling for filter expressions.
John Rouillard <rouilj@ieee.org>
parents: 8237
diff changeset
63
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
64 logger = logging.getLogger('roundup')
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
66 if not random_.is_weak:
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
67 logger.debug("Importing good random generator")
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
68 else:
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
69 logger.warning("**SystemRandom not available. Using poor random generator")
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
70
8104
0e01299414a8 chore(lint): format imports and add/remove blank lines.
John Rouillard <rouilj@ieee.org>
parents: 8062
diff changeset
71
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 def initialiseSecurity(security):
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
73 '''Create some Permissions and Roles on the security object
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
75 This function is directly invoked by security.Security.__init__()
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
76 as a part of the Security object instantiation.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77 '''
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
78 p = security.addPermission(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
79 name="Web Access",
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 description="User may access the web interface")
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 security.addPermissionToRole('Admin', p)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
83 p = security.addPermission(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
84 name="Rest Access",
5879
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
85 description="User may access the rest interface")
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
86 security.addPermissionToRole('Admin', p)
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
87
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
88 p = security.addPermission(
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
89 name="Xmlrpc Access",
5879
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
90 description="User may access the xmlrpc interface")
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
91 security.addPermissionToRole('Admin', p)
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
92
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 # doing Role stuff through the web - make sure Admin can
3276
3124e578db02 Email fixes:
Richard Jones <richard@users.sourceforge.net>
parents: 3069
diff changeset
94 # TODO: deprecate this and use a property-based control
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
95 p = security.addPermission(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
96 name="Web Roles",
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 description="User may manipulate user Roles through the web")
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 security.addPermissionToRole('Admin', p)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
100
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
101 def add_message(msg_list, msg, escape=True):
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
102 if escape:
5804
8f50e00532e7 html.escape(string, quote=...) sets quote to True not False by
John Rouillard <rouilj@ieee.org>
parents: 5802
diff changeset
103 msg = html_escape(msg, quote=False).replace('\n', '<br />\n')
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
104 else:
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
105 msg = msg.replace('\n', '<br />\n')
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
106 msg_list.append(msg)
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
107 return msg_list # for unittests
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
108
8502
dfecb240bc34 chore: ruff whitespace fixes.
John Rouillard <rouilj@ieee.org>
parents: 8500
diff changeset
109
8237
57325fea9982 issue2551116 - Replace xmlrpclib (xmlrpc.client) with defusedxml.
John Rouillard <rouilj@ieee.org>
parents: 8209
diff changeset
110 # if set to False via interfaces.py do not log a warning when
57325fea9982 issue2551116 - Replace xmlrpclib (xmlrpc.client) with defusedxml.
John Rouillard <rouilj@ieee.org>
parents: 8209
diff changeset
111 # xmlrpc is used and defusedxml is not installed.
57325fea9982 issue2551116 - Replace xmlrpclib (xmlrpc.client) with defusedxml.
John Rouillard <rouilj@ieee.org>
parents: 8209
diff changeset
112 WARN_FOR_MISSING_DEFUSEDXML = True
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
113
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
114 default_err_msg = ''"""<html><head><title>An error has occurred</title></head>
3554
5e70726a86dd fixed schema migration problem when Class keys were removed
Richard Jones <richard@users.sourceforge.net>
parents: 3551
diff changeset
115 <body><h1>An error has occurred</h1>
3551
3c70ab03c917 translate error message shown instead of tracebacks, add page title
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3548
diff changeset
116 <p>A problem was encountered processing your request.
3c70ab03c917 translate error message shown instead of tracebacks, add page title
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3548
diff changeset
117 The tracker maintainers have been notified of the problem.</p>
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
118 </body></html>"""
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
119
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
120
5356
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
121 def seed_pseudorandom():
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
122 '''A function to seed the default pseudorandom random number generator
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
123 which is used to (at minimum):
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
124 * generate part of email message-id
5356
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
125 * generate OTK for password reset
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
126 * generate the temp recovery password
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
127
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
128 This function limits the scope of the 'import random' call
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
129 as the random identifier is used throughout the code and
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
130 can refer to SystemRandom.
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
131 '''
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
132 import random
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
133 random.seed()
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
134
8558
5fbf6451a782 bug: harden header/environment values for roundup-server and cgi
John Rouillard <rouilj@ieee.org>
parents: 8557
diff changeset
135 _safe_char_set = {chr(x) for x in range(32,127)}
5fbf6451a782 bug: harden header/environment values for roundup-server and cgi
John Rouillard <rouilj@ieee.org>
parents: 8557
diff changeset
136 def are_header_values_safe(header_list):
5fbf6451a782 bug: harden header/environment values for roundup-server and cgi
John Rouillard <rouilj@ieee.org>
parents: 8557
diff changeset
137 for header, value in header_list.items():
5fbf6451a782 bug: harden header/environment values for roundup-server and cgi
John Rouillard <rouilj@ieee.org>
parents: 8557
diff changeset
138 if (set(value) - _safe_char_set):
5fbf6451a782 bug: harden header/environment values for roundup-server and cgi
John Rouillard <rouilj@ieee.org>
parents: 8557
diff changeset
139 return header, value
5fbf6451a782 bug: harden header/environment values for roundup-server and cgi
John Rouillard <rouilj@ieee.org>
parents: 8557
diff changeset
140 return None
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
141
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
142 class LiberalCookie(SimpleCookie):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
143 """ Python's SimpleCookie throws an exception if the cookie uses invalid
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
144 syntax. Other applications on the same server may have done precisely
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
145 this, preventing roundup from working through no fault of roundup.
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
146 Numerous other python apps have run into the same problem:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
147
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
148 trac: http://trac.edgewall.org/ticket/2256
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
149 mailman: http://bugs.python.org/issue472646
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
150
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
151 This particular implementation comes from trac's solution to the
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
152 problem. Unfortunately it requires some hackery in SimpleCookie's
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
153 internals to provide a more liberal __set method.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
154 """
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
155 def load(self, rawdata, ignore_parse_errors=True):
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
156 if ignore_parse_errors:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
157 self.bad_cookies = []
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
158 self._BaseCookie__set = self._loose_set
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
159 SimpleCookie.load(self, rawdata)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
160 if ignore_parse_errors:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
161 self._BaseCookie__set = self._strict_set
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
162 for key in self.bad_cookies:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
163 del self[key]
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
164
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
165 _strict_set = BaseCookie._BaseCookie__set
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
166
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
167 def _loose_set(self, key, real_value, coded_value):
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
168 try:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
169 self._strict_set(key, real_value, coded_value)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
170 except CookieError:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
171 self.bad_cookies.append(key)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
172 dict.__setitem__(self, key, None)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
173
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
174
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
175 class Session:
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
176 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
177 Needs DB to be already opened by client
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
178
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
179 Session attributes at instantiation:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
180
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
181 - "client" - reference to client for add_cookie function
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
182 - "session_db" - session DB manager
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
183 - "cookie_name" - name of the cookie with session id
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
184 - "_sid" - session id for current user
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
185 - "_data" - session data cache
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
186
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
187 session = Session(client)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
188 session.set(name=value)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
189 value = session.get(name)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
190
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
191 session.destroy() # delete current session
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
192 session.clean_up() # clean up session table
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
193
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
194 session.update(set_cookie=True, expire=3600*24*365)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
195 # refresh session expiration time, setting persistent
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
196 # cookie if needed to last for 'expire' seconds
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
197
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
198 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
199
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
200 def __init__(self, client):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
201 self._data = {}
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
202 self._sid = None
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
203
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
204 self.client = client
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
205 self.session_db = client.db.getSessionManager()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
206
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
207 # parse cookies for session id
8168
3f0f4746dc7e issue2551370 - prefix session cookie with __Secure- over https
John Rouillard <rouilj@ieee.org>
parents: 8104
diff changeset
208 if self.client.secure:
3f0f4746dc7e issue2551370 - prefix session cookie with __Secure- over https
John Rouillard <rouilj@ieee.org>
parents: 8104
diff changeset
209 cookie_template = '__Secure-roundup_session_%s'
3f0f4746dc7e issue2551370 - prefix session cookie with __Secure- over https
John Rouillard <rouilj@ieee.org>
parents: 8104
diff changeset
210 else:
3f0f4746dc7e issue2551370 - prefix session cookie with __Secure- over https
John Rouillard <rouilj@ieee.org>
parents: 8104
diff changeset
211 cookie_template = 'roundup_session_%s'
3f0f4746dc7e issue2551370 - prefix session cookie with __Secure- over https
John Rouillard <rouilj@ieee.org>
parents: 8104
diff changeset
212 self.cookie_name = cookie_template % \
3f0f4746dc7e issue2551370 - prefix session cookie with __Secure- over https
John Rouillard <rouilj@ieee.org>
parents: 8104
diff changeset
213 re.sub('[^a-zA-Z]', '', client.instance.config.TRACKER_NAME)
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
214 cookies = LiberalCookie(client.env.get('HTTP_COOKIE', ''))
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
215 if self.cookie_name in cookies:
6813
6b636fb29740 Refactor client.py session cookie code. Remove session db access.
John Rouillard <rouilj@ieee.org>
parents: 6693
diff changeset
216 try:
6b636fb29740 Refactor client.py session cookie code. Remove session db access.
John Rouillard <rouilj@ieee.org>
parents: 6693
diff changeset
217 self._sid = cookies[self.cookie_name].value
6b636fb29740 Refactor client.py session cookie code. Remove session db access.
John Rouillard <rouilj@ieee.org>
parents: 6693
diff changeset
218 self._data = self.session_db.getall(self._sid)
6b636fb29740 Refactor client.py session cookie code. Remove session db access.
John Rouillard <rouilj@ieee.org>
parents: 6693
diff changeset
219 except KeyError:
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
220 self._sid = None
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
221 # remove old cookie
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
222 self.client.add_cookie(self.cookie_name, None)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
223
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
224 def _gen_sid(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
225 """ generate a unique session key """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
226 while 1:
6082
a3221c686736 changing the sid after checking for collisions defeats the purpose
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6053
diff changeset
227 s = b2s(binascii.b2a_base64(random_.token_bytes(32)).strip()).rstrip('=')
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
228 if not self.session_db.exists(s):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
229 break
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
230
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
231 return s
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
232
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
233 def clean_up(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
234 """Remove expired sessions"""
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
235 self.session_db.clean()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
236
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
237 def destroy(self):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
238 self.client.add_cookie(self.cookie_name, None)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
239 self._data = {}
6147
f35ca71c9f2e fixed logout action when there is no session
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6082
diff changeset
240 if self._sid:
f35ca71c9f2e fixed logout action when there is no session
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6082
diff changeset
241 self.session_db.destroy(self._sid)
f35ca71c9f2e fixed logout action when there is no session
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6082
diff changeset
242 self.session_db.commit()
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
243
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
244 def get(self, name, default=None):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
245 return self._data.get(name, default)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
246
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
247 def set(self, **kwargs):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
248 self._data.update(kwargs)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
249 if not self._sid:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
250 self._sid = self._gen_sid()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
251 self.session_db.set(self._sid, **self._data)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
252 # add session cookie
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
253 self.update(set_cookie=True)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
254
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
255 # XXX added when patching 1.4.4 for backward compatibility
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
256 # XXX remove
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
257 self.client.session = self._sid
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
258 else:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
259 self.session_db.set(self._sid, **self._data)
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
260 self.session_db.commit()
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
261
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
262 def update(self, set_cookie=False, expire=None):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
263 """ update timestamp in db to avoid expiration
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
264
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
265 if 'set_cookie' is True, set cookie with 'expire' seconds lifetime
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
266 if 'expire' is None - session will be closed with the browser
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
267
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
268 XXX the session can be purged within a week even if a cookie
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
269 lifetime is longer
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
270 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
271 self.session_db.updateTimestamp(self._sid)
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
272 self.session_db.commit()
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
273
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
274 if set_cookie:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
275 self.client.add_cookie(self.cookie_name, self._sid, expire=expire)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
276
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
277
5775
17e110426ad7 issue2551046: Attempts to attach file or create large message fail
John Rouillard <rouilj@ieee.org>
parents: 5696
diff changeset
278 # import from object as well so it's a new style object and I can use super()
17e110426ad7 issue2551046: Attempts to attach file or create large message fail
John Rouillard <rouilj@ieee.org>
parents: 5696
diff changeset
279 class BinaryFieldStorage(cgi.FieldStorage, object):
5656
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
280 '''This class works around the bug https://bugs.python.org/issue27777.
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
281
5656
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
282 cgi.FieldStorage must save all data as binary/bytes. This is
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
283 needed for handling json and xml data blobs under python
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
284 3. Under python 2, str and binary are interchangable, not so
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
285 under 3.
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
286 '''
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
287 def make_file(self, mode=None):
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
288 ''' work around https://bugs.python.org/issue27777 '''
5671
f60c44563c3a Adjust make_file override to use binary files only when needed.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5666
diff changeset
289 if self.length >= 0:
f60c44563c3a Adjust make_file override to use binary files only when needed.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5666
diff changeset
290 return tempfile.TemporaryFile("wb+")
5775
17e110426ad7 issue2551046: Attempts to attach file or create large message fail
John Rouillard <rouilj@ieee.org>
parents: 5696
diff changeset
291 return super(BinaryFieldStorage, self).make_file()
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
292
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
293
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 class Client:
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
295 """Instantiate to handle one CGI request.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
297 See inner_main for request processing.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
298
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
299 Client attributes at instantiation:
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
300
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
301 - "path" is the PATH_INFO inside the instance (with no leading '/')
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
302 - "base" is the base URL for the instance
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
303 - "form" is the cgi form, an instance of FieldStorage from the standard
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
304 cgi module
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
305 - "additional_headers" is a dictionary of additional HTTP headers that
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
306 should be sent to the client
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
307 - "response_code" is the HTTP response code to send to the client
2557
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
308 - "translator" is TranslationService instance
8386
4e2ffa4151cb doc: formatting fix. Don't trigger description list.
John Rouillard <rouilj@ieee.org>
parents: 8320
diff changeset
309 - "clientnonce" is a unique value for this client connection. Can be
4e2ffa4151cb doc: formatting fix. Don't trigger description list.
John Rouillard <rouilj@ieee.org>
parents: 8320
diff changeset
310 used as a nonce for CSP headers and to sign javascript code
4e2ffa4151cb doc: formatting fix. Don't trigger description list.
John Rouillard <rouilj@ieee.org>
parents: 8320
diff changeset
311 presented to the browser. This is different from the CSRF nonces
4e2ffa4151cb doc: formatting fix. Don't trigger description list.
John Rouillard <rouilj@ieee.org>
parents: 8320
diff changeset
312 and can not be used for anti-csrf measures.
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
313
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
314 During the processing of a request, the following attributes are used:
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
315
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
316 - "db"
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
317 - "_error_message" holds a list of error messages
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
318 - "_ok_message" holds a list of OK messages
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
319 - "session" is deprecated in favor of session_api (XXX remove)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
320 - "session_api" is the interface to store data in session
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
321 - "user" is the current user's name
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
322 - "userid" is the current user's id
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
323 - "template" is the current :template context
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
324 - "classname" is the current class context name
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
325 - "nodeid" is the current context item id
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
326
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
327 Note: _error_message and _ok_message should not be modified
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
328 directly, use add_ok_message and add_error_message, these, by
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
329 default, escape the message added to avoid XSS security issues.
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
330
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
331 User Identification:
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
332 Users that are absent in session data are anonymous and are logged
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
333 in as that user. This typically gives them all Permissions assigned
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
334 to the Anonymous Role.
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
335
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
336 Every user is assigned a session. "session_api" is the interface
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
337 to work with session data.
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
338
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
339 Special form variables:
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
340 Note that in various places throughout this code, special form
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
341 variables of the form :<name> are used. The colon (":") part may
1436
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
342 actually be one of either ":" or "@".
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
343 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
344
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
345 # charset used for data storage and form templates
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
346 # Note: must be in lower case for comparisons!
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
347 # XXX take this from instance.config?
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
348 STORAGE_CHARSET = 'utf-8'
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
349
1421
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
350 #
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
351 # special form variables
1421
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
352 #
1436
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
353 FV_TEMPLATE = re.compile(r'[@:]template')
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
354 FV_OK_MESSAGE = re.compile(r'[@:]ok_message')
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
355 FV_ERROR_MESSAGE = re.compile(r'[@:]error_message')
1421
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
356
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
357 # Note: index page stuff doesn't appear here:
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
358 # columns, sort, sortdir, filter, group, groupdir, search_text,
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
359 # pagesize, startwith
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
360
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
361 # list of network error codes that shouldn't be reported to tracker admin
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
362 # (error descriptions from FreeBSD intro(2))
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
363 IGNORE_NET_ERRORS = (
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
364 # A write on a pipe, socket or FIFO for which there is
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
365 # no process to read the data.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
366 errno.EPIPE,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
367 # A connection was forcibly closed by a peer.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
368 # This normally results from a loss of the connection
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
369 # on the remote socket due to a timeout or a reboot.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
370 errno.ECONNRESET,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
371 # Software caused connection abort. A connection abort
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
372 # was caused internal to your host machine.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
373 errno.ECONNABORTED,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
374 # A connect or send request failed because the connected party
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
375 # did not properly respond after a period of time.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
376 errno.ETIMEDOUT,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
377 )
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
378
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
379 # Cache_Control[key] = Cache-Control header value
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
380 # Key can be explicitly file basename - value applied to just that file
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
381 # takes precedence over mime type.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
382 # Key can be mime type - all files of that mimetype will get the value
6546
c58c7cd31243 issue2550991 - Some mechanism to set expiration header or max age for static resources
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
383 Cache_Control = {
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
384 'application/javascript': "public, max-age=1209600", # 2 weeks
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
385 'text/javascript': "public, max-age=1209600", # 2 weeks
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
386 'text/css': "public, max-age=4838400", # 8 weeks/2 mnths
6546
c58c7cd31243 issue2550991 - Some mechanism to set expiration header or max age for static resources
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
387 }
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
388
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
389 # list of valid http compression (Content-Encoding) algorithms
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
390 # we have available
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
391 compressors = []
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
392 try:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
393 # Only one provided by standard library
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
394 import gzip
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
395 compressors.append('gzip')
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
396 except ImportError:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
397 pass
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
398 try:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
399 import brotli
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
400 compressors.append('br')
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
401 except ImportError:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
402 pass
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
403 try:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
404 import zstd
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
405 compressors.append('zstd')
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
406 except ImportError:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
407 pass
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
408
8039
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
409 # everything not here is served as 'application/octet-stream'
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
410 # Moved to class so it can be modified from interfaces.py
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
411 # Adding:
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
412 # from roundup.cgi.client import Client
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
413 # Client.mime_type_allowlist.append('application/pdf')
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
414 # will permit pdf files to be displayed in the browser rather than
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
415 # downloaded to a file.
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
416
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
417 mime_type_allowlist = [
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
418 'text/plain',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
419 'text/x-csrc', # .c
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
420 'text/x-chdr', # .h
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
421 'text/x-patch', # .patch and .diff
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
422 'text/x-python', # .py
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
423 'text/xml',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
424 'text/csv',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
425 'text/css',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
426 'image/gif',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
427 'image/jpeg',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
428 'image/png',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
429 'image/svg+xml',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
430 'image/webp',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
431 'audio/ogg',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
432 'video/webm',
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
433 ]
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
434
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
435 # mime types of files that are already compressed and should not be
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
436 # compressed on the fly. Can be extended/reduced using interfaces.py.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
437 # This excludes types from being compressed. Should we have a list
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
438 # of mime types we should compress? write_html() calls compress_encode
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
439 # which uses this without a content-type so that's an issue.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
440 # Also for text based data, might have charset too so need to parse
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
441 # content-type.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
442 precompressed_mime_types = ["image/png", "image/jpeg"]
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
443
8446
14c7c07b32d8 feature: add thread local trace_id and trace_reason to logging.
John Rouillard <rouilj@ieee.org>
parents: 8412
diff changeset
444 @gen_trace_id()
8557
f80c566f5726 feat: improve store_trace_reason with extract parameter
John Rouillard <rouilj@ieee.org>
parents: 8556
diff changeset
445 @store_trace_reason('client', extract="args[3]['PATH_INFO']")
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
446 def __init__(self, instance, request, env, form=None, translator=None):
5356
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
447 # re-seed the random number generator. Is this is an instance of
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
448 # random.SystemRandom it has no effect.
5488
52cb53eedf77 reworked random number use
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5475
diff changeset
449 random_.seed()
5356
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
450 # So we also seed the pseudorandom random source obtained from
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
451 # import random
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
452 # to make sure that every forked copy of the client will return
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
453 # new random numbers.
91954be46a66 A real fix for the problem where:
John Rouillard <rouilj@ieee.org>
parents: 5350
diff changeset
454 seed_pseudorandom()
2230
ca2664e095be disable forking server when os.fork() not available [SF#938586]
Richard Jones <richard@users.sourceforge.net>
parents: 2183
diff changeset
455 self.start = time.time()
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
456 self.instance = instance
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
457 self.request = request
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
458 self.env = env
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
459 if translator is not None:
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
460 self.setTranslator(translator)
8508
9caa03d7e091 set self.language attribute when translator passed into Client()
John Rouillard <rouilj@ieee.org>
parents: 8506
diff changeset
461 # set self.language to "translator"'s language
9caa03d7e091 set self.language attribute when translator passed into Client()
John Rouillard <rouilj@ieee.org>
parents: 8506
diff changeset
462 try:
9caa03d7e091 set self.language attribute when translator passed into Client()
John Rouillard <rouilj@ieee.org>
parents: 8506
diff changeset
463 self.language = translator.info()["language"]
9caa03d7e091 set self.language attribute when translator passed into Client()
John Rouillard <rouilj@ieee.org>
parents: 8506
diff changeset
464 except (AttributeError, KeyError):
9caa03d7e091 set self.language attribute when translator passed into Client()
John Rouillard <rouilj@ieee.org>
parents: 8506
diff changeset
465 # info() missing or no language key
9caa03d7e091 set self.language attribute when translator passed into Client()
John Rouillard <rouilj@ieee.org>
parents: 8506
diff changeset
466 self.language = ""
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
467 else:
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
468 self.setTranslator(TranslationService.NullTranslationService())
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
469 self.language = "" # as is the default from determine_language
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
470
1799
071ea6fc803f Extracted duplicated mail-sending code...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1798
diff changeset
471 self.mailer = Mailer(instance.config)
5166
232c74973a56 issue1408570: fix that form values are lost
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
472 # If True the form contents wins over the database contents when
232c74973a56 issue1408570: fix that form values are lost
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
473 # rendering html properties. This is set when an error occurs so
232c74973a56 issue1408570: fix that form values are lost
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
474 # that we don't lose submitted form contents.
232c74973a56 issue1408570: fix that form values are lost
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
475 self.form_wins = False
1004
5f12d3259f31 logout works better now
Richard Jones <richard@users.sourceforge.net>
parents: 1003
diff changeset
476
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
477 # save off the path
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
478 self.path = env['PATH_INFO']
1004
5f12d3259f31 logout works better now
Richard Jones <richard@users.sourceforge.net>
parents: 1003
diff changeset
479
1398
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
480 # this is the base URL for this tracker
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
481 self.base = self.instance.config.TRACKER_WEB
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
482
4586
b21bb66de6ff Mark cookies HttpOnly and -- if https is used -- secure.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4578
diff changeset
483 # should cookies be secure?
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
484 self.secure = self.base.startswith('https')
4586
b21bb66de6ff Mark cookies HttpOnly and -- if https is used -- secure.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4578
diff changeset
485
6249
3b62c35e824d client.py fix comment typo
John Rouillard <rouilj@ieee.org>
parents: 6211
diff changeset
486 # check the tracker_web setting
2183
ac24a9c74cca be paranoid about TRACKER_WEB
Richard Jones <richard@users.sourceforge.net>
parents: 2137
diff changeset
487 if not self.base.endswith('/'):
ac24a9c74cca be paranoid about TRACKER_WEB
Richard Jones <richard@users.sourceforge.net>
parents: 2137
diff changeset
488 self.base = self.base + '/'
ac24a9c74cca be paranoid about TRACKER_WEB
Richard Jones <richard@users.sourceforge.net>
parents: 2137
diff changeset
489
1398
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
490 # this is the "cookie path" for this tracker (ie. the path part of
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
491 # the "base" url)
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
492 self.cookie_path = urllib_.urlparse(self.base)[2]
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
493 # cookies to set in http responce
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
494 # {(path, name): (value, expire)}
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
495 self._cookies = {}
1398
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
496
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
497 # define a unique nonce. Can be used for Content Security Policy
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
498 # nonces for scripts.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
499 self.client_nonce = self._gen_nonce()
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
500
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
501 # see if we need to re-parse the environment for the form (eg Zope)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
502 if form is None:
5608
5df309febe49 Path to support OPTIONS verb when using rest interface via
John Rouillard <rouilj@ieee.org>
parents: 5603
diff changeset
503 # cgi.FieldStorage doesn't special case OPTIONS, DELETE or
5df309febe49 Path to support OPTIONS verb when using rest interface via
John Rouillard <rouilj@ieee.org>
parents: 5603
diff changeset
504 # PATCH verbs. They are processed like POST. So FieldStorage
5df309febe49 Path to support OPTIONS verb when using rest interface via
John Rouillard <rouilj@ieee.org>
parents: 5603
diff changeset
505 # hangs on these verbs trying to read posted data that
5df309febe49 Path to support OPTIONS verb when using rest interface via
John Rouillard <rouilj@ieee.org>
parents: 5603
diff changeset
506 # will never arrive.
5df309febe49 Path to support OPTIONS verb when using rest interface via
John Rouillard <rouilj@ieee.org>
parents: 5603
diff changeset
507 # If not defined, set CONTENT_LENGTH to 0 so it doesn't
5df309febe49 Path to support OPTIONS verb when using rest interface via
John Rouillard <rouilj@ieee.org>
parents: 5603
diff changeset
508 # hang reading the data.
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
509 if self.env['REQUEST_METHOD'] in ['OPTIONS', 'DELETE', 'PATCH'] \
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
510 and 'CONTENT_LENGTH' not in self.env:
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
511 self.env['CONTENT_LENGTH'] = 0
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
512 logger.debug("Setting CONTENT_LENGTH to 0 for method: %s",
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
513 self.env['REQUEST_METHOD'])
5608
5df309febe49 Path to support OPTIONS verb when using rest interface via
John Rouillard <rouilj@ieee.org>
parents: 5603
diff changeset
514
5653
ba67e397f063 Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents: 5624
diff changeset
515 # cgi.FieldStorage must save all data as
5656
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
516 # binary/bytes. Subclass BinaryFieldStorage does this.
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
517 # It's a workaround for a bug in cgi.FieldStorage. See class
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
518 # def for details.
d26d2590cd8c Implement different workaround for https://bugs.python.org/issue27777
John Rouillard <rouilj@ieee.org>
parents: 5655
diff changeset
519 self.form = BinaryFieldStorage(fp=request.rfile, environ=env)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
520 else:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
521 self.form = form
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
522
8268
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
523 # When the CONTENT-TYPE is not 'application/x-www-form-urlencoded':
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
524 # or multipart/*, cgi.(Mini)FieldStorage sets the list property to
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
525 # None. Initialize an empty list property in this case so we can
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
526 # query the list in all cases.
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
527 try:
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
528 if (self.form.list is None):
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
529 self.form.list = []
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
530 except AttributeError:
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
531 # self.form should always be some type of
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
532 # FieldStorage. If we get an AttributeError,
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
533 # print what the form is.
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
534 # FIXME: plan on removing this in 2028 to improve
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
535 # performance if there are no reports of it being triggered.
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
536 logger.error(("Invalid self.form found (please report "
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
537 "to the roundup-users mailing list): %s") % self.form)
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
538 raise
05d8806b25ad fix: issue2551387 - TypeError: not indexable.
John Rouillard <rouilj@ieee.org>
parents: 8267
diff changeset
539
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
540 # turn debugging on/off
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
541 try:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
542 self.debug = int(env.get("ROUNDUP_DEBUG", 0))
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
543 except ValueError:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
544 # someone gave us a non-int debug level, turn it off
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
545 self.debug = 0
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
546
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
547 # flag to indicate that the HTTP headers have been sent
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
548 self.headers_done = 0
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
549
7106
64e1058051f3 pylint: fix first reference to properties outside of __init__
John Rouillard <rouilj@ieee.org>
parents: 7079
diff changeset
550 # record of headers sent for debugging
64e1058051f3 pylint: fix first reference to properties outside of __init__
John Rouillard <rouilj@ieee.org>
parents: 7079
diff changeset
551 self.headers_sent = []
64e1058051f3 pylint: fix first reference to properties outside of __init__
John Rouillard <rouilj@ieee.org>
parents: 7079
diff changeset
552
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
553 # additional headers to send with the request - must be registered
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
554 # before the first write
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
555 self.additional_headers = {}
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
556 self.response_code = 200
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
557
2947
e611be5ee6c4 initialize self.charset early to enable html output for tracebacks...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2946
diff changeset
558 # default character set
e611be5ee6c4 initialize self.charset early to enable html output for tracebacks...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2946
diff changeset
559 self.charset = self.STORAGE_CHARSET
e611be5ee6c4 initialize self.charset early to enable html output for tracebacks...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2946
diff changeset
560
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
561 # parse cookies (used for charset lookups)
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
562 # use our own LiberalCookie to handle bad apps on the same
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
563 # server that have set cookies that are out of spec
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
564 self.cookie = LiberalCookie(self.env.get('HTTP_COOKIE', ''))
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
565
2928
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
566 self.user = None
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
567 self.userid = None
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
568 self.nodeid = None
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
569 self.classname = None
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
570 self.template = None
7106
64e1058051f3 pylint: fix first reference to properties outside of __init__
John Rouillard <rouilj@ieee.org>
parents: 7079
diff changeset
571 self._ok_message = []
64e1058051f3 pylint: fix first reference to properties outside of __init__
John Rouillard <rouilj@ieee.org>
parents: 7079
diff changeset
572 self._error_message = []
2928
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
573
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
574 def _gen_nonce(self):
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
575 """ generate a unique nonce """
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
576 return b2s(base64.b32encode(random_.token_bytes(40)))
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
577
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
578 def setTranslator(self, translator=None):
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
579 """Replace the translation engine
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
580
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
581 'translator'
2557
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
582 is TranslationService instance.
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
583 It must define methods 'translate' (TAL-compatible i18n),
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
584 'gettext' and 'ngettext' (gettext-compatible i18n).
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
585
2557
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
586 If omitted, create default TranslationService.
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
587 """
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
588 if translator is None:
2808
18c28d22b3b5 pass tracker home directory to get_translation()
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2800
diff changeset
589 translator = TranslationService.get_translation(
2923
29563959c026 language defaults to config option TRACKER_LANGUAGE
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2906
diff changeset
590 language=self.instance.config["TRACKER_LANGUAGE"],
2808
18c28d22b3b5 pass tracker home directory to get_translation()
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2800
diff changeset
591 tracker_home=self.instance.config["TRACKER_HOME"])
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
592 self.translator = translator
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
593 self._ = self.gettext = translator.gettext
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
594 self.ngettext = translator.ngettext
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
595
8446
14c7c07b32d8 feature: add thread local trace_id and trace_reason to logging.
John Rouillard <rouilj@ieee.org>
parents: 8412
diff changeset
596 @gen_trace_id()
8557
f80c566f5726 feat: improve store_trace_reason with extract parameter
John Rouillard <rouilj@ieee.org>
parents: 8556
diff changeset
597 @store_trace_reason('client_main', extract="args[0].env['PATH_INFO']")
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
598 def main(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
599 """ Wrap the real main in a try/finally so we always close off the db.
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
600 """
5924
b40059d7036f issue2550925 strip HTTP_PROXY environment variable
John Rouillard <rouilj@ieee.org>
parents: 5881
diff changeset
601
b40059d7036f issue2550925 strip HTTP_PROXY environment variable
John Rouillard <rouilj@ieee.org>
parents: 5881
diff changeset
602 # strip HTTP_PROXY issue2550925 in case
b40059d7036f issue2550925 strip HTTP_PROXY environment variable
John Rouillard <rouilj@ieee.org>
parents: 5881
diff changeset
603 # PROXY header is set.
b40059d7036f issue2550925 strip HTTP_PROXY environment variable
John Rouillard <rouilj@ieee.org>
parents: 5881
diff changeset
604 if 'HTTP_PROXY' in self.env:
7571
f8b07ffd0226 flake8: add space between return, del and (
John Rouillard <rouilj@ieee.org>
parents: 7556
diff changeset
605 del (self.env['HTTP_PROXY'])
5924
b40059d7036f issue2550925 strip HTTP_PROXY environment variable
John Rouillard <rouilj@ieee.org>
parents: 5881
diff changeset
606 if 'HTTP_PROXY' in os.environ:
7571
f8b07ffd0226 flake8: add space between return, del and (
John Rouillard <rouilj@ieee.org>
parents: 7556
diff changeset
607 del (os.environ['HTTP_PROXY'])
5924
b40059d7036f issue2550925 strip HTTP_PROXY environment variable
John Rouillard <rouilj@ieee.org>
parents: 5881
diff changeset
608
5603
79da1ca2f94b Make xmlrpc and rest APIs configurable
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5568
diff changeset
609 xmlrpc_enabled = self.instance.config.WEB_ENABLE_XMLRPC
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
610 rest_enabled = self.instance.config.WEB_ENABLE_REST
1133
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
611 try:
5603
79da1ca2f94b Make xmlrpc and rest APIs configurable
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5568
diff changeset
612 if xmlrpc_enabled and self.path == 'xmlrpc':
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
613 self.handle_xmlrpc()
5603
79da1ca2f94b Make xmlrpc and rest APIs configurable
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5568
diff changeset
614 elif rest_enabled and (self.path == 'rest' or
79da1ca2f94b Make xmlrpc and rest APIs configurable
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5568
diff changeset
615 self.path[:5] == 'rest/'):
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
616 self.handle_rest()
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
617 else:
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
618 self.inner_main()
1133
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
619 finally:
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
620 if hasattr(self, 'db'):
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
621 self.db.close()
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
622
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
623 def handle_xmlrpc(self):
4919
24209344b507 Link /xmlrpc to docs if accessed with browser
anatoly techtonik <techtonik@gmail.com>
parents: 4903
diff changeset
624 if self.env.get('CONTENT_TYPE') != 'text/xml':
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
625 self.write(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
5456
0fb04e717de0 fix encoding in handle_xmlrpc
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5441
diff changeset
628 b"XML-RPC interface</a>.")
4919
24209344b507 Link /xmlrpc to docs if accessed with browser
anatoly techtonik <techtonik@gmail.com>
parents: 4903
diff changeset
629 return
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
630
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
631 # Pull the raw XML out of the form. The "value" attribute
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
632 # will be the raw content of the POST request.
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
633 assert self.form.file
8187
5c506c778893 chore(ruff): new name for input variable which doesn't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8186
diff changeset
634 input_data = self.form.value
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
635 # So that the rest of Roundup can query the form in the
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
636 # usual way, we create an empty list of fields.
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
637 self.form.list = []
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
638
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
639 # Set the charset and language, since other parts of
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
640 # Roundup may depend upon that.
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
641 self.determine_charset()
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
642 if self.instance.config["WEB_TRANSLATE_XMLRPC"]:
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
643 self.determine_language()
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
644 # Open the database as the correct user.
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
645 try:
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
646 self.determine_user(is_api="xmlrpc")
5881
9938c40e03bc Add "rest" and "xmlrpc" values for database tx_Source property
John Rouillard <rouilj@ieee.org>
parents: 5879
diff changeset
647 self.db.tx_Source = "xmlrpc"
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
648 self.db.i18n = self.translator
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
649 except LoginError as msg:
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
650 output = xmlrpc_.client.dumps(
5879
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
651 xmlrpc_.client.Fault(401, "%s" % msg),
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
652 allow_none=True)
5879
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
653 self.setHeader("Content-Type", "text/xml")
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
654 self.setHeader("Content-Length", str(len(output)))
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
655 self.write(s2b(output))
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
656 return
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
657 except RateLimitExceeded as msg:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
658 output = xmlrpc_.client.dumps(
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
659 xmlrpc_.client.Fault(429, "%s" % msg),
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
660 allow_none=True)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
661 self.setHeader("Content-Type", "text/xml")
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
662 self.setHeader("Content-Length", str(len(output)))
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
663 self.write(s2b(output))
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
664 return
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
665
5879
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
666 if not self.db.security.hasPermission('Xmlrpc Access', self.userid):
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
667 output = xmlrpc_.client.dumps(
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
668 xmlrpc_.client.Fault(403, "Forbidden"),
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
669 allow_none=True)
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
670 self.setHeader("Content-Type", "text/xml")
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
671 self.setHeader("Content-Length", str(len(output)))
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
672 self.write(s2b(output))
94a7669677ae add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents: 5878
diff changeset
673 return
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
674
4327
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
675 self.check_anonymous_access()
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
676
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
677 try:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
678 # coverting from function returning true/false to
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
679 # raising exceptions
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
680 # Call csrf with xmlrpc checks enabled.
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
681 # It will return True if everything is ok,
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
682 # raises exception on check failure.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
683 csrf_ok = self.handle_csrf(api=True)
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
684 except (Unauthorised, UsageError):
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
685 # report exception back to server
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
686 exc_type, exc_value, exc_tb = sys.exc_info()
5408
e46ce04d5bbc Python 3 preparation: update xmlrpclib / SimpleXMLRPCServer imports.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5395
diff changeset
687 output = xmlrpc_.client.dumps(
e46ce04d5bbc Python 3 preparation: update xmlrpclib / SimpleXMLRPCServer imports.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5395
diff changeset
688 xmlrpc_.client.Fault(1, "%s:%s" % (exc_type, exc_value)),
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
689 allow_none=True)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
690 csrf_ok = False # we had an error, failed check
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
691
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
692 if csrf_ok is True:
8237
57325fea9982 issue2551116 - Replace xmlrpclib (xmlrpc.client) with defusedxml.
John Rouillard <rouilj@ieee.org>
parents: 8209
diff changeset
693 if WARN_FOR_MISSING_DEFUSEDXML and (not xmlrpc_.client.defusedxml):
57325fea9982 issue2551116 - Replace xmlrpclib (xmlrpc.client) with defusedxml.
John Rouillard <rouilj@ieee.org>
parents: 8209
diff changeset
694 logger.warning(self._("XMLRPC endpoint is not using defusedxml. Improve security by installing defusedxml."))
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
695 handler = xmlrpc.RoundupDispatcher(self.db,
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
696 self.instance.actions,
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
697 self.translator,
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
698 allow_none=True)
8187
5c506c778893 chore(ruff): new name for input variable which doesn't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8186
diff changeset
699 output = handler.dispatch(input_data)
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
700
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
701 self.setHeader("Content-Type", "text/xml")
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
702 self.setHeader("Content-Length", str(len(output)))
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
703 self.write(output)
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
704
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
705 def is_cors_preflight(self):
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
706 return (
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
707 self.env['REQUEST_METHOD'] == "OPTIONS"
8265
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
708 and self.request.headers.get("Access-Control-Request-Method")
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
709 # technically Access-Control-Request-Headers (ACRH) is
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
710 # optional, but we require the header x-requested-with,
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
711 # so ACRH will be present.
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
712 and self.request.headers.get("Access-Control-Request-Headers")
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
713 and self.request.headers.get("Origin"))
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
714
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
715 def handle_preflight(self):
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
716 # Call rest library to handle the pre-flight request
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
717 handler = rest.RestfulInstance(self, self.db)
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
718 output = handler.dispatch(self.env['REQUEST_METHOD'],
7228
07ce4e4110f5 flake8 fixes: whitespace, remove unused imports
John Rouillard <rouilj@ieee.org>
parents: 7159
diff changeset
719 self.path, self.form)
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
720
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
721 if self.response_code == 204:
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
722 self.write("")
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
723 else:
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
724 self.setHeader("Content-Length", str(len(output)))
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
725 self.write(output)
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
726
7153
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
727 def reject_request(self, message, message_type="text/plain",
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
728 status=http_.client.UNAUTHORIZED):
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
729 self.response_code = status
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
730 self.setHeader("Content-Length", str(len(message)))
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
731 self.setHeader("Content-Type", message_type)
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
732 self.write(message)
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
733
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
734 def handle_rest(self):
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
735 # Set the charset and language
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
736 self.determine_charset()
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
737 if self.instance.config["WEB_TRANSLATE_REST"]:
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
738 self.determine_language()
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
739 # Open the database as the correct user.
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
740 # TODO: add everything to RestfulDispatcher
5666
d660d1c1ba63 Handle LoginError in rest code. Stop standard "an error occurred check
John Rouillard <rouilj@ieee.org>
parents: 5657
diff changeset
741 try:
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
742 self.determine_user(is_api="rest")
5881
9938c40e03bc Add "rest" and "xmlrpc" values for database tx_Source property
John Rouillard <rouilj@ieee.org>
parents: 5879
diff changeset
743 self.db.tx_Source = "rest"
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
744 self.db.i18n = self.translator
5666
d660d1c1ba63 Handle LoginError in rest code. Stop standard "an error occurred check
John Rouillard <rouilj@ieee.org>
parents: 5657
diff changeset
745 except LoginError as err:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
746 output = s2b("Invalid Login - %s" % str(err))
7153
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
747 self.reject_request(output, status=http_.client.UNAUTHORIZED)
5666
d660d1c1ba63 Handle LoginError in rest code. Stop standard "an error occurred check
John Rouillard <rouilj@ieee.org>
parents: 5657
diff changeset
748 return
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
749 except RateLimitExceeded as err:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
750 output = s2b("%s" % str(err))
8209
9d2ad7386627 chore(ruff): use names not magic numbers.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
751 self.reject_request(output,
9d2ad7386627 chore(ruff): use names not magic numbers.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
752 status=http_.client.TOO_MANY_REQUESTS)
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
753 return
5666
d660d1c1ba63 Handle LoginError in rest code. Stop standard "an error occurred check
John Rouillard <rouilj@ieee.org>
parents: 5657
diff changeset
754
8265
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
755 # Handle CORS preflight request. We know rest is enabled
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
756 # because handle_rest is called. Preflight requests
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
757 # are unauthenticated, so no need to check permissions.
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
758 if (self.is_cors_preflight()):
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
759 # Origin header must be defined to get here
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
760 if self.is_origin_header_ok(api=True):
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
761 self.handle_preflight()
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
762 else:
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
763 # origin is not authorized for REST
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
764 msg = self._("Client is not allowed to use Rest Interface.")
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
765 output = s2b(
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
766 '{ "error": { "status": 400, "msg": "%s" } }' % msg)
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
767 self.reject_request(output,
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
768 message_type="application/json",
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
769 status=400)
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
770 return
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
771
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
772 if not self.db.security.hasPermission('Rest Access', self.userid):
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
773 output = s2b('{ "error": { "status": 403, "msg": "Forbidden." } }')
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
774 self.reject_request(output,
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
775 message_type="application/json",
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
776 status=403)
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
777 return
35beff316883 fix(api): issue2551384. Verify REST authorization earlier
John Rouillard <rouilj@ieee.org>
parents: 8261
diff changeset
778
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
779 # verify Origin is allowed on all requests including GET.
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
780 # If a GET, missing origin is allowed (i.e. same site GET request)
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
781 if not self.is_origin_header_ok(api=True):
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
782 if 'HTTP_ORIGIN' not in self.env:
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
783 msg = self._("Required Header Missing")
8247
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
784 err = "REST request missing 'Origin' header by user %(user)s."
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
785 else:
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
786 msg = self._("Client is not allowed to use Rest Interface.")
8247
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
787 err = "REST request 'Origin' (%(origin)s) unauthorized by user %(user)s."
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
788
7153
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
789 # Use code 400. Codes 401 and 403 imply that authentication
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
790 # is needed or authenticated person is not authorized.
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
791 output = s2b(
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
792 '{ "error": { "status": 400, "msg": "%s" } }' % msg)
7153
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
793 self.reject_request(output,
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
794 message_type="application/json",
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
795 status=400)
8247
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
796 # Would be nice to log the original source address here to
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
797 # allow firewalling in case of abuse/attack. Especially if
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
798 # anonymous is allowed REST access. However,
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
799 # self.request.connection.getpeername()
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
800 # only gets us 127.0.0.1 when a proxy is used. I think the
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
801 # same is true of wsgi mode (but it might be a UNIX domain
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
802 # socket address). The upstream server needs to supply the
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
803 # real IP as it sees it and we need to consume it. There
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
804 # is no method for this that handles all the ways roundup
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
805 # can be run AFAIK. So no IP address, just user.
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
806 logger.error(err, {"user": self.user,
6747051fef79 feat: issue2551372 - REST-API CSRF protection should document mandatory Origin header
John Rouillard <rouilj@ieee.org>
parents: 8241
diff changeset
807 "origin": self.env.get('HTTP_ORIGIN', None)})
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
808 return
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
809
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
810 self.check_anonymous_access()
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
811
5696
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
812 try:
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
813 # Call csrf with api (xmlrpc, rest) checks enabled.
5696
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
814 # It will return True if everything is ok,
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
815 # raises exception on check failure.
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
816 # Note this returns true for a GET request.
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
817 # Must check supplied Origin header for bad value first.
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
818 csrf_ok = self.handle_csrf(api=True)
5696
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
819 except (Unauthorised, UsageError) as msg:
7153
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
820 # FIXME should format return value according to
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
821 # client's accept header, so application/xml, text/plain etc..
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
822 output = s2b('{ "error": { "status": 400, "msg": "%s"}}' %
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
823 str(msg))
7153
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
824 self.reject_request(output,
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
825 message_type="application/json",
1181157d7cec Refactor rejecting requests; update tests, xfail test
John Rouillard <rouilj@ieee.org>
parents: 7150
diff changeset
826 status=400)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
827 csrf_ok = False # we had an error, failed check
5696
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
828 return
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
829
5696
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
830 # With the return above the if will never be false,
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
831 # Keeping the if so we can remove return to pass
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
832 # output though and format output according to accept
5696
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
833 # header.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
834 if csrf_ok is True:
5696
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
835 # Call rest library to handle the request
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
836 handler = rest.RestfulInstance(self, self.db)
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
837 output = handler.dispatch(self.env['REQUEST_METHOD'],
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
838 self.path, self.form)
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
839
b67636bc87d0 Add CSRF protection to rest code path. Follow same model as for
John Rouillard <rouilj@ieee.org>
parents: 5671
diff changeset
840 # type header set by rest handler
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
841 # self.setHeader("Content-Type", "text/xml")
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
842 if self.response_code == 204: # no body with 204
6509
1fc765ef6379 Fix 204 responses, hangs and crashes with REST.
John Rouillard <rouilj@ieee.org>
parents: 6504
diff changeset
843 self.write("")
1fc765ef6379 Fix 204 responses, hangs and crashes with REST.
John Rouillard <rouilj@ieee.org>
parents: 6504
diff changeset
844 else:
1fc765ef6379 Fix 204 responses, hangs and crashes with REST.
John Rouillard <rouilj@ieee.org>
parents: 6504
diff changeset
845 self.setHeader("Content-Length", str(len(output)))
1fc765ef6379 Fix 204 responses, hangs and crashes with REST.
John Rouillard <rouilj@ieee.org>
parents: 6504
diff changeset
846 self.write(output)
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5555
diff changeset
847
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
848 def add_ok_message(self, msg, escape=True):
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
849 add_message(self._ok_message, msg, escape)
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
850
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
851 def add_error_message(self, msg, escape=True):
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
852 add_message(self._error_message, msg, escape)
5166
232c74973a56 issue1408570: fix that form values are lost
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
853 # Want to interpret form values when rendering when an error
232c74973a56 issue1408570: fix that form values are lost
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
854 # occurred:
232c74973a56 issue1408570: fix that form values are lost
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
855 self.form_wins = True
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
856
1133
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
857 def inner_main(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
858 """Process a request.
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
859
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
860 The most common requests are handled like so:
1054
3d8ea16347aa more explanatory docstring
Richard Jones <richard@users.sourceforge.net>
parents: 1053
diff changeset
861
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
862 1. look for charset and language preferences, set up user locale
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
863 see determine_charset, determine_language
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
864 2. figure out who we are, defaulting to the "anonymous" user
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
865 see determine_user
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
866 3. figure out what the request is for - the context
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
867 see determine_context
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
868 4. handle any requested action (item edit, search, ...)
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
869 see handle_action
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
870 5. render a template, resulting in HTML output
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
871
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
872 In some situations, exceptions occur:
1054
3d8ea16347aa more explanatory docstring
Richard Jones <richard@users.sourceforge.net>
parents: 1053
diff changeset
873
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
874 - HTTP Redirect (generally raised by an action)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
875 - SendFile (generally raised by determine_context)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
876 serve up a FileClass "content" property
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
877 - SendStaticFile (generally raised by determine_context)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
878 serve up a file from the tracker "html" directory
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
879 - Unauthorised (generally raised by an action)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
880 the action is cancelled, the request is rendered and an error
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
881 message is displayed indicating that permission was not
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
882 granted for the action to take place
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
883 - templating.Unauthorised (templating action not permitted)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
884 raised by an attempted rendering of a template when the user
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
885 doesn't have permission
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
886 - NotFound (raised wherever it needs to be)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
887 percolates up to the CGI interface that called the client
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
888 """
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
889 self._ok_message = []
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
890 self._error_message = []
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
891 try:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
892 self.determine_charset()
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
893
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
894 try:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
895 # make sure we're identified (even anonymously)
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
896 self.determine_user()
2938
463902a0fbbb determine user before context:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2937
diff changeset
897
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
898 # figure out the context and desired content template
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
899 self.determine_context()
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
900
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
901 self.determine_language()
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
902 self.db.i18n = self.translator
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
903
4326
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
904 # if we've made it this far the context is to a bit of
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
905 # Roundup's real web interface (not a file being served up)
7079
b34d1808b0aa Fix typo in comment.
John Rouillard <rouilj@ieee.org>
parents: 7074
diff changeset
906 # so do the Anonymous Web Access check now
4327
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
907 self.check_anonymous_access()
4326
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
908
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
909 # check for a valid csrf token identifying the right user
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
910 csrf_ok = True
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
911 try:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
912 # coverting from function returning true/false to
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
913 # raising exceptions
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
914 csrf_ok = self.handle_csrf()
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
915 except (UsageError, Unauthorised) as msg:
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
916 csrf_ok = False
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
917 self.form_wins = True
8062
28aa76443f58 fix(security): fix CVE-2024-39124, CVE-2024-39124, and CVE-2024-39125
John Rouillard <rouilj@ieee.org>
parents: 8039
diff changeset
918 self.add_error_message(' '.join(msg.args))
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
919
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
920 # If csrf checks pass. Run actions etc.
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
921 # handle_action() may handle a form submit action.
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
922 # It can change self.classname and self.template,
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
923 # and may also append error/ok_messages.
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
924 html = self.handle_action() if csrf_ok else None
1697
c9f67f2f7ba7 don't open the database for static files
Richard Jones <richard@users.sourceforge.net>
parents: 1692
diff changeset
925
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
926 if html:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
927 self.write_html(html)
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
928 return
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
929
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
930 # now render the page
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
931 # we don't want clients caching our dynamic pages
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
932 self.additional_headers['Cache-Control'] = 'no-cache'
1579
07a6b8587bc2 removed Pragma: no-cache...
Richard Jones <richard@users.sourceforge.net>
parents: 1562
diff changeset
933
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
934 # pages with messages added expire right now
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
935 # simple views may be cached for a small amount of time
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
936 # TODO? make page expire time configurable
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
937 # <rj> always expire pages, as IE just doesn't seem to do the
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
938 # right thing here :(
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
939 date = time.time() - 1
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
940 # if self._error_message or self._ok_message:
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
941 # date = time.time() - 1
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
942 # else:
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
943 # date = time.time() + 5
4980
13f8f88ad984 Replace rfc822 imports with email package (issue2550870)
John Kristensen <john@jerrykan.com>
parents: 4979
diff changeset
944 self.additional_headers['Expires'] = \
13f8f88ad984 Replace rfc822 imports with email package (issue2550870)
John Kristensen <john@jerrykan.com>
parents: 4979
diff changeset
945 email.utils.formatdate(date, usegmt=True)
1552
68ef6deefcf1 cgi fixes
Richard Jones <richard@users.sourceforge.net>
parents: 1538
diff changeset
946
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
947 # render the content
3896
fca0365521fc ignore client shutdown exceptions when sending responses
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3867
diff changeset
948 self.write_html(self.renderContext())
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
949 except SendFile as designator:
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
950 # The call to serve_file may result in an Unauthorised
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
951 # exception or a NotModified exception. Those
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
952 # exceptions will be handled by the outermost set of
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
953 # exception handlers.
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
954 self.determine_language()
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
955 self.db.i18n = self.translator
8062
28aa76443f58 fix(security): fix CVE-2024-39124, CVE-2024-39124, and CVE-2024-39125
John Rouillard <rouilj@ieee.org>
parents: 8039
diff changeset
956 # prevent application/octet-stream mime type in header
28aa76443f58 fix(security): fix CVE-2024-39124, CVE-2024-39124, and CVE-2024-39125
John Rouillard <rouilj@ieee.org>
parents: 8039
diff changeset
957 # from being changed to some other type by the browser
28aa76443f58 fix(security): fix CVE-2024-39124, CVE-2024-39124, and CVE-2024-39125
John Rouillard <rouilj@ieee.org>
parents: 8039
diff changeset
958 # when mime sniffing.
7159
765222ef4cec - issue2551257: add 'X-Content-Type-Options: nosniff' header for file download
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
959 self.setHeader("X-Content-Type-Options", "nosniff")
8062
28aa76443f58 fix(security): fix CVE-2024-39124, CVE-2024-39124, and CVE-2024-39125
John Rouillard <rouilj@ieee.org>
parents: 8039
diff changeset
960 # prevent script execution in downloaded SVG, XML files
28aa76443f58 fix(security): fix CVE-2024-39124, CVE-2024-39124, and CVE-2024-39125
John Rouillard <rouilj@ieee.org>
parents: 8039
diff changeset
961 # (or HTML files if enabled).
28aa76443f58 fix(security): fix CVE-2024-39124, CVE-2024-39124, and CVE-2024-39125
John Rouillard <rouilj@ieee.org>
parents: 8039
diff changeset
962 self.setHeader("Content-Security-Policy", "script-src 'none'")
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
963 self.serve_file(designator)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
964 except SendStaticFile as file:
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
965 self.serve_static_file(str(file))
3896
fca0365521fc ignore client shutdown exceptions when sending responses
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3867
diff changeset
966 except IOError:
3900
182ba3207899 wrap comment to less than 75 chars
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3898
diff changeset
967 # IOErrors here are due to the client disconnecting before
4638
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
968 # receiving the reply.
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
969 pass
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
970 except SysCallError:
1ebc5f16aeda Ignore OpenSSL.SSL.SysCallError similar to IOError.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4623
diff changeset
971 # OpenSSL.SSL.SysCallError is similar to IOError above
3896
fca0365521fc ignore client shutdown exceptions when sending responses
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3867
diff changeset
972 pass
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
973 except RateLimitExceeded:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
974 raise
2230
ca2664e095be disable forking server when os.fork() not available [SF#938586]
Richard Jones <richard@users.sourceforge.net>
parents: 2183
diff changeset
975
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
976 except SeriousError as message:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
977 self.write_html(str(message))
8411
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
978 except Reauth as e:
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
979 self.reauth(e)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
980 except Redirect as url:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
981 # let's redirect - if the url isn't None, then we need to do
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
982 # the headers, otherwise the headers have been set before the
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
983 # exception was raised
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
984 if url:
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
985 self.additional_headers['Location'] = str(url)
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
986 self.response_code = 302
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
987 self.write_html('Redirecting to <a href="%s">%s</a>' % (url, url))
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
988 except LoginError as message:
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
989 # The user tried to log in, but did not provide a valid
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
990 # username and password. If we support HTTP
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
991 # authorization, send back a response that will cause the
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
992 # browser to prompt the user again.
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
993 if self.instance.config.WEB_HTTP_AUTH:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
994 self.response_code = http_.client.UNAUTHORIZED
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
995 realm = self.instance.config.TRACKER_NAME
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
996 self.setHeader("WWW-Authenticate",
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
997 'Basic realm="%s"' % realm)
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
998 else:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
999 self.response_code = http_.client.FORBIDDEN
4898
850551a1568b Fix issue2550843 (AttributeError: 'Unauthorised' object has no attribute 'replace')
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4880
diff changeset
1000 self.renderFrontPage(str(message))
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
1001 except Unauthorised as message:
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
1002 # users may always see the front page
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1003 self.response_code = 403
4898
850551a1568b Fix issue2550843 (AttributeError: 'Unauthorised' object has no attribute 'replace')
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4880
diff changeset
1004 self.renderFrontPage(str(message))
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
1005 except NotModified:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
1006 # send the 304 response
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
1007 self.response_code = 304
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
1008 self.header()
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
1009 except NotFound as e:
5165
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1010 if self.response_code == 400:
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1011 # We can't find a parameter (e.g. property name
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1012 # incorrect). Tell the user what was raised.
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1013 # Do not change to the 404 template since the
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1014 # base url is valid just query args are not.
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1015 # copy the page format from SeriousError _str_ exception.
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1016 error_page = """
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1017 <html><head><title>Roundup issue tracker: An error has occurred</title>
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1018 <link rel="stylesheet" type="text/css" href="@@file/style.css">
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1019 </head>
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1020 <body class="body" marginwidth="0" marginheight="0">
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1021 <p class="error-message">%s</p>
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1022 </body></html>
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1023 """
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1024 self.write_html(error_page % str(e))
5165
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1025 else:
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1026 self.response_code = 404
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1027 self.template = '404'
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1028 try:
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
1029 # generates keyerror if class does not exist
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
1030 self.db.getclass(self.classname)
5165
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1031 self.write_html(self.renderContext())
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1032 except KeyError:
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1033 # we can't map the URL to a class we know about
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1034 # reraise the NotFound and let roundup_server
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1035 # handle it
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5154
diff changeset
1036 raise NotFound(e)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
1037 except FormError as e:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
1038 self.add_error_message(self._('Form Error: ') + str(e))
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1039 self.write_html(self.renderContext())
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
1040 except RateLimitExceeded as e:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
1041 self.add_error_message(str(e))
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
1042 self.write_html(self.renderContext())
4640
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1043 except IOError:
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1044 # IOErrors here are due to the client disconnecting before
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1045 # receiving the reply.
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1046 # may happen during write_html and serve_file, too.
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1047 pass
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1048 except SysCallError:
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1049 # OpenSSL.SSL.SysCallError is similar to IOError above
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1050 # may happen during write_html and serve_file, too.
70b1cb9034c3 Ignore IOError and SysCallError also in outer try/except.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4638
diff changeset
1051 pass
5079
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1052 except DetectorError as e:
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1053 if not self.instance.config.WEB_DEBUG:
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1054 # run when we are not in debug mode, so errors
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1055 # go to admin too.
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1056 self.send_error_to_admin(e.subject, e.html, e.txt)
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1057 self.write_html(e.html)
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1058 else:
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1059 # in debug mode, only write error to screen.
65fef7858606 issue2550826 IOError in detector causes apache 'premature end of script headers' error
John Rouillard <rouilj@ieee.org>
parents: 5073
diff changeset
1060 self.write_html(e.html)
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
1061 except Exception as e: # noqa: F841
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1062 # Something has gone badly wrong. Therefore, we should
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1063 # make sure that the response code indicates failure.
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
1064 if self.response_code == http_.client.OK:
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
1065 self.response_code = http_.client.INTERNAL_SERVER_ERROR
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1066 # Help the administrator work out what went wrong.
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1067 html = ("<h1>Traceback</h1>"
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1068 + cgitb.html(i18n=self.translator)
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1069 + ("<h1>Environment Variables</h1><table>%s</table>"
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1070 % cgitb.niceDict("", self.env)))
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1071 if not self.instance.config.WEB_DEBUG:
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1072 exc_info = sys.exc_info()
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1073 subject = "Error: %s" % exc_info[1]
4543
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
1074 self.send_error_to_admin(subject, html, format_exc())
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
1075 self.write_html(self._(default_err_msg))
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
1076 else:
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1077 self.write_html(html)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1078
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
1079 def clean_sessions(self):
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1080 """Deprecated
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1081 XXX remove
1937
4c850112895b Some reformatting and fixing docstrings for emacs.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1936
diff changeset
1082 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1083 self.clean_up()
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
1084
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1085 def clean_up(self):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1086 """Remove expired sessions and One Time Keys.
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1087
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1088 Do it only once an hour.
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1089 """
8189
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
1090 hour = 60 * 60
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
1091 now = time.time()
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1092
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1093 # XXX: hack - use OTK table to store last_clean time information
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1094 # 'last_clean' string is used instead of otk key
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
1095 otks = self.db.getOTKManager()
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
1096 last_clean = otks.get('last_clean', 'last_use', 0)
2046
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
1097 if now - last_clean < hour:
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
1098 return
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
1099
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1100 self.session_api.clean_up()
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
1101 otks.clean()
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
1102 otks.set('last_clean', last_use=now)
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
1103 otks.commit()
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
1104
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1105 def determine_charset(self):
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1106 """Look for client charset in the form parameters or browser cookie.
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1107
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1108 If no charset requested by client, use storage charset (utf-8).
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1109
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1110 If the charset is found, and differs from the storage charset,
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1111 recode all form fields of type 'text/plain'
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1112 """
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1113 # look for client charset
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1114 charset_parameter = 0
4799
b474adb17fda Fix case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4781
diff changeset
1115 # Python 2.6 form may raise a TypeError if list in form is None
b474adb17fda Fix case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4781
diff changeset
1116 charset = None
4800
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1117 try:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1118 charset = self.form['@charset'].value
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1119 if charset.lower() == "none":
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1120 charset = ""
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1121 charset_parameter = 1
4799
b474adb17fda Fix case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4781
diff changeset
1122 except (KeyError, TypeError):
b474adb17fda Fix case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4781
diff changeset
1123 pass
b474adb17fda Fix case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4781
diff changeset
1124 if charset is None and 'roundup_charset' in self.cookie:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1125 charset = self.cookie['roundup_charset'].value
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1126 if charset:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1127 # make sure the charset is recognized
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1128 try:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1129 codecs.lookup(charset)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1130 except LookupError:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1131 self.add_error_message(self._('Unrecognized charset: %r') %
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
1132 charset)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1133
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1134 charset_parameter = 0
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1135 else:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1136 self.charset = charset.lower()
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1137 # If we've got a character set in request parameters,
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1138 # set the browser cookie to keep the preference.
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1139 # This is done after codecs.lookup to make sure
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1140 # that we aren't keeping a wrong value.
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1141 if charset_parameter:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1142 self.add_cookie('roundup_charset', charset)
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1143
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1144 # if client charset is different from the storage charset,
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1145 # recode form fields
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1146 # XXX this requires FieldStorage from Python library.
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1147 # mod_python FieldStorage is not supported!
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1148 if self.charset != self.STORAGE_CHARSET:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1149 decoder = codecs.getdecoder(self.charset)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1150 encoder = codecs.getencoder(self.STORAGE_CHARSET)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1151 re_charref = re.compile('&#([0-9]+|x[0-9a-f]+);', re.IGNORECASE)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1152
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1153 def _decode_charref(matchobj):
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1154 num = matchobj.group(1)
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1155 uc = int(num[1:], 16) if num[0].lower() == 'x' else int(num)
5417
c749d6795bc2 Python 3 preparation: unichr.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5408
diff changeset
1156 return uchr(uc)
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1157
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
1158 for field_name in self.form:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1159 field = self.form[field_name]
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1160 if (field.type == 'text/plain') and not field.filename:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1161 try:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1162 value = decoder(field.value)[0]
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1163 except UnicodeError:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1164 continue
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1165 value = re_charref.sub(_decode_charref, value)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1166 field.value = encoder(value)[0]
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1167
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1168 def determine_language(self):
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1169 """Determine the language"""
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1170 # look for language parameter
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1171 # then for language cookie
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1172 # last for the Accept-Language header
4800
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1173 # Python 2.6 form may raise a TypeError if list in form is None
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1174 language = None
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1175 try:
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1176 language = self.form["@language"].value
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1177 if language.lower() == "none":
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1178 language = ""
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1179 self.add_cookie("roundup_language", language)
4800
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1180 except (KeyError, TypeError):
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1181 pass
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1182 if language is None:
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1183 if "roundup_language" in self.cookie:
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1184 language = self.cookie["roundup_language"].value
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1185 elif self.instance.config["WEB_USE_BROWSER_LANGUAGE"]:
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1186 hal = self.env.get('HTTP_ACCEPT_LANGUAGE')
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1187 language = accept_language.parse(hal)
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1188 else:
3961b2b91568 2nd case where querying form returns a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4799
diff changeset
1189 language = ""
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1190
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1191 if not language:
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1192 # default to tracker language
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1193 language = self.instance.config["TRACKER_LANGUAGE"]
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1194
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1195 # this maybe is not correct, as get_translation could not
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1196 # find desired locale and switch back to "en" but we set
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1197 # self.language to the desired language !
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1198 self.language = language
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1199
8506
b6c6891754e9 bug: fix mis-commit of perf tests and crash fix for setTranslation
John Rouillard <rouilj@ieee.org>
parents: 8505
diff changeset
1200 self.setTranslator(TranslationService.get_translation(
6658
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1201 language,
408fd477761f Add i18n object to roundupdb.Database
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6656
diff changeset
1202 tracker_home=self.instance.config["TRACKER_HOME"]))
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1203
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1204 def authenticate_bearer_token(self, challenge):
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1205 ''' authenticate the bearer token. Refactored from determine_user()
7474
1cf1ffa65522 Fix mispellings in comments.
John Rouillard <rouilj@ieee.org>
parents: 7258
diff changeset
1206 to allow it to be overridden if needed.
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1207 '''
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1208 try: # will jwt import?
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1209 import jwt
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1210 except ImportError:
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1211 # no support for jwt, this is fine.
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1212 self.setHeader("WWW-Authenticate", "Basic")
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1213 raise LoginError('Support for jwt disabled.')
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1214
7809
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1215 # If first ',' separated token is < 32, jwt is disabled.
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1216 # If second or later tokens are < 32 chars, the config system
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1217 # stops the tracker from starting so insecure tokens can not
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1218 # be used.
8209
9d2ad7386627 chore(ruff): use names not magic numbers.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
1219 CHARS_FOR_256_BIT_KEY = 32
9d2ad7386627 chore(ruff): use names not magic numbers.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
1220 if len(self.db.config.WEB_JWT_SECRET[0]) < CHARS_FOR_256_BIT_KEY:
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1221 # no support for jwt, this is fine.
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1222 self.setHeader("WWW-Authenticate", "Basic")
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1223 raise LoginError('Support for jwt disabled by admin.')
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1224
7809
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1225 last_error = "Unknown error validating bearer token."
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1226
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1227 for secret in self.db.config.WEB_JWT_SECRET:
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1228 try: # handle jwt exceptions
8202
276164647db5 chore(ruff): clean trailing whitespace
John Rouillard <rouilj@ieee.org>
parents: 8200
diff changeset
1229 return jwt.decode(challenge, secret,
276164647db5 chore(ruff): clean trailing whitespace
John Rouillard <rouilj@ieee.org>
parents: 8200
diff changeset
1230 algorithms=['HS256'],
276164647db5 chore(ruff): clean trailing whitespace
John Rouillard <rouilj@ieee.org>
parents: 8200
diff changeset
1231 audience=self.db.config.TRACKER_WEB,
276164647db5 chore(ruff): clean trailing whitespace
John Rouillard <rouilj@ieee.org>
parents: 8200
diff changeset
1232 issuer=self.db.config.TRACKER_WEB)
7809
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1233
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1234 except jwt.exceptions.InvalidSignatureError as err:
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1235 # Try more signatures.
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1236 # If all signatures generate InvalidSignatureError,
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1237 # we exhaust the loop and last_error is used to
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1238 # report the final (but not only) InvalidSignatureError
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1239 last_error = str(err) # preserve for end of loop
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1240 except jwt.exceptions.InvalidTokenError as err:
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1241 self.setHeader("WWW-Authenticate", "Basic, Bearer")
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1242 self.make_user_anonymous()
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1243 raise LoginError(str(err))
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1244
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1245 # reach here only if no valid signature was found
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1246 self.setHeader("WWW-Authenticate", "Basic, Bearer")
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1247 self.make_user_anonymous()
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1248 raise LoginError(last_error)
be6cb2e0d471 feat: add support for rotating jwt keys
John Rouillard <rouilj@ieee.org>
parents: 7805
diff changeset
1249
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
1250 def determine_user(self, is_api=False):
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1251 """Determine who the user is"""
1724
bc4f0aec594e oops, we really do need a database
Richard Jones <richard@users.sourceforge.net>
parents: 1719
diff changeset
1252 self.opendb('admin')
bc4f0aec594e oops, we really do need a database
Richard Jones <richard@users.sourceforge.net>
parents: 1719
diff changeset
1253
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1254 # if we get a jwt, it includes the roles to be used for this session
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1255 # so we define a new function to encpsulate and return the jwt roles
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1256 # and not take the roles from the database.
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1257 override_get_roles = None
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1258
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1259 # get session data from db
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1260 # XXX: rename
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1261 self.session_api = Session(self)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1262
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1263 # take the opportunity to cleanup expired sessions and otks
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1264 self.clean_up()
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1265
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1266 user = None
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1267 # first up, try http authorization if enabled
6053
380dec305c28 Add config option 'http_auth_convert_realm_to_lowercase'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6014
diff changeset
1268 cfg = self.instance.config
6436
1f2f7c0b8968 issue2550837 - New option for web auth (also http header passing)
John Rouillard <rouilj@ieee.org>
parents: 6382
diff changeset
1269 remote_user_header = cfg.WEB_HTTP_AUTH_HEADER or 'REMOTE_USER'
6211
50960479f627 New config-option 'cookie_takes_precedence'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6147
diff changeset
1270 if cfg.WEB_COOKIE_TAKES_PRECEDENCE:
50960479f627 New config-option 'cookie_takes_precedence'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6147
diff changeset
1271 user = self.session_api.get('user')
50960479f627 New config-option 'cookie_takes_precedence'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6147
diff changeset
1272 if user:
50960479f627 New config-option 'cookie_takes_precedence'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6147
diff changeset
1273 # update session lifetime datestamp
50960479f627 New config-option 'cookie_takes_precedence'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6147
diff changeset
1274 self.session_api.update()
6436
1f2f7c0b8968 issue2550837 - New option for web auth (also http header passing)
John Rouillard <rouilj@ieee.org>
parents: 6382
diff changeset
1275 if remote_user_header in self.env:
1f2f7c0b8968 issue2550837 - New option for web auth (also http header passing)
John Rouillard <rouilj@ieee.org>
parents: 6382
diff changeset
1276 del self.env[remote_user_header]
6211
50960479f627 New config-option 'cookie_takes_precedence'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6147
diff changeset
1277 if not user and cfg.WEB_HTTP_AUTH:
6436
1f2f7c0b8968 issue2550837 - New option for web auth (also http header passing)
John Rouillard <rouilj@ieee.org>
parents: 6382
diff changeset
1278 if remote_user_header in self.env:
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1279 # we have external auth (e.g. by Apache)
6436
1f2f7c0b8968 issue2550837 - New option for web auth (also http header passing)
John Rouillard <rouilj@ieee.org>
parents: 6382
diff changeset
1280 user = self.env[remote_user_header]
6053
380dec305c28 Add config option 'http_auth_convert_realm_to_lowercase'
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6014
diff changeset
1281 if cfg.WEB_HTTP_AUTH_CONVERT_REALM_TO_LOWERCASE and '@' in user:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1282 u, d = user.split('@', 1)
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1283 user = '@'.join((u, d.lower()))
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1284 elif self.env.get('HTTP_AUTHORIZATION', ''):
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1285 # try handling Basic Auth ourselves
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1286 auth = self.env['HTTP_AUTHORIZATION']
5549
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1287 try:
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1288 scheme, challenge = auth.split(' ', 1)
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1289 except ValueError:
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1290 # Invalid header.
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1291 scheme = ''
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1292 challenge = ''
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1293 if scheme.lower() == 'basic':
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1294 try:
5474
4c9192393cd9 encoding fixes
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5456
diff changeset
1295 decoded = b2s(base64.b64decode(challenge))
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1296 except TypeError:
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1297 # invalid challenge
5474
4c9192393cd9 encoding fixes
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5456
diff changeset
1298 decoded = ''
5549
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1299 try:
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1300 username, password = decoded.split(':', 1)
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1301 except ValueError:
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1302 # Invalid challenge.
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1303 username = ''
901d7ba146ad Avoid errors from invalid Authorization headers (issue2550992).
Joseph Myers <jsm@polyomino.org.uk>
parents: 5524
diff changeset
1304 password = ''
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1305 try:
4669
d7ac6c7bc371 Fix basic authentication.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4649
diff changeset
1306 # Current user may not be None, otherwise
d7ac6c7bc371 Fix basic authentication.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4649
diff changeset
1307 # instatiation of the login action will fail.
d7ac6c7bc371 Fix basic authentication.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4649
diff changeset
1308 # So we set the user to anonymous first.
d7ac6c7bc371 Fix basic authentication.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4649
diff changeset
1309 self.make_user_anonymous()
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1310 login = self.get_action_class('login')(self)
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
1311 login.verifyLogin(username, password, is_api=is_api)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7474
diff changeset
1312 except (LoginError, RateLimitExceeded):
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1313 self.make_user_anonymous()
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
1314 raise
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
1315 user = username
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1316 # try to seed with something harder to guess than
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1317 # just the time. If random is SystemRandom,
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1318 # this is a no-op.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1319 random_.seed("%s%s" % (password, time.time()))
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1320 elif scheme.lower() == 'bearer':
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1321 token = self.authenticate_bearer_token(challenge)
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1322
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1323 from roundup.hyperdb import iter_roles
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1324
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1325 # if we got here token is valid, use the role
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1326 # and sub claims.
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1327 try:
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1328 # make sure to str(token['sub']) the
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1329 # subject. As decoded by json, it is unicode
7474
1cf1ffa65522 Fix mispellings in comments.
John Rouillard <rouilj@ieee.org>
parents: 7258
diff changeset
1330 # which throws an error when used with 'nodeid
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1331 # in db' down the call chain.
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1332 user = self.db.user.get(str(token['sub']), 'username')
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1333 except IndexError:
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1334 raise LoginError("Token subject is invalid.")
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1335
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1336 # validate roles
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1337 all_rolenames = [role[0] for role in self.db.security.role.items()]
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1338 for r in token['roles']:
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1339 if r.lower() not in all_rolenames:
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1340 raise LoginError("Token roles are invalid.")
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1341
5934
db9bd45d50ad Refactor jwt auth into authenticate_bearer_token() method on Client
John Rouillard <rouilj@ieee.org>
parents: 5924
diff changeset
1342 # will be used later to override the get_roles method
6977
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1343 # having it defined as truthy allows it to be used.
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1344 override_get_roles = lambda self: iter_roles( # noqa: ARG005
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1345 ','.join(token['roles']))
2928
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
1346
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1347 # if user was not set by http authorization, try session lookup
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1348 if not user:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1349 user = self.session_api.get('user')
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1350 if user:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1351 # update session lifetime datestamp
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1352 self.session_api.update()
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1353
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1354 # if no user name set by http authorization or session lookup
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1355 # the user is anonymous
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1356 if not user:
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1357 user = 'anonymous'
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1358
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1359 # sanity check on the user still being valid,
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
1360 # getting the userid at the same time
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1361 try:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1362 self.userid = self.db.user.lookup(user)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1363 except (KeyError, TypeError):
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1364 user = 'anonymous'
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1365
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1366 # make sure the anonymous user is valid if we're using it
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1367 if user == 'anonymous':
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1368 self.make_user_anonymous()
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1369 else:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1370 self.user = user
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1371
1003
f89b8d32291b Hack hack hack...
Richard Jones <richard@users.sourceforge.net>
parents: 1002
diff changeset
1372 # reopen the database as the correct user
f89b8d32291b Hack hack hack...
Richard Jones <richard@users.sourceforge.net>
parents: 1002
diff changeset
1373 self.opendb(self.user)
5878
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1374 if override_get_roles:
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1375 # opendb destroys and re-opens the db if instance.optimize
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1376 # is not true. This deletes an override of get_roles. So
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1377 # assign get_roles override from the jwt if needed at this
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1378 # point.
1b57d8f3eb97 Add rudimentery experiment JSON Web Token (jwt) support
John Rouillard <rouilj@ieee.org>
parents: 5847
diff changeset
1379 self.db.user.get_roles = override_get_roles
1003
f89b8d32291b Hack hack hack...
Richard Jones <richard@users.sourceforge.net>
parents: 1002
diff changeset
1380
4327
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
1381 def check_anonymous_access(self):
4326
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
1382 """Check that the Anonymous user is actually allowed to use the web
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
1383 interface and short-circuit all further processing if they're not.
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
1384 """
4327
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
1385 # allow Anonymous to use the "login" and "register" actions (noting
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
1386 # that "register" has its own "Register" permission check)
4367
fa5587802af9 Handle multiple @action values from broken trackers
Richard Jones <richard@users.sourceforge.net>
parents: 4362
diff changeset
1387
4802
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1388 action = ''
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1389 try:
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1390 if ':action' in self.form:
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1391 action = self.form[':action']
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1392 elif '@action' in self.form:
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1393 action = self.form['@action']
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1394 except TypeError:
e1ffab417c28 Yet another instance of a TypeError fixed
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4801
diff changeset
1395 pass
4367
fa5587802af9 Handle multiple @action values from broken trackers
Richard Jones <richard@users.sourceforge.net>
parents: 4362
diff changeset
1396 if isinstance(action, list):
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1397 raise SeriousError(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1398 self._('broken form: multiple @action values submitted'))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1399 if action != '':
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1400 # '' is value when no action parameter was found so run
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1401 # this to extract action string value when action found.
4367
fa5587802af9 Handle multiple @action values from broken trackers
Richard Jones <richard@users.sourceforge.net>
parents: 4362
diff changeset
1402 action = action.value.lower()
4327
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
1403 if action in ('login', 'register'):
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
1404 return
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
1405
4329
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4327
diff changeset
1406 # allow Anonymous to view the "user" "register" template if they're
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4327
diff changeset
1407 # allowed to register
8505
299edbd03ddf bug: rearrange test condition to optimize test w/ most likely to fail first and expensive permission check last
John Rouillard <rouilj@ieee.org>
parents: 8502
diff changeset
1408 if (self.template == 'register' and self.classname == 'user'
299edbd03ddf bug: rearrange test condition to optimize test w/ most likely to fail first and expensive permission check last
John Rouillard <rouilj@ieee.org>
parents: 8502
diff changeset
1409 and self.db.security.hasPermission('Register',
299edbd03ddf bug: rearrange test condition to optimize test w/ most likely to fail first and expensive permission check last
John Rouillard <rouilj@ieee.org>
parents: 8502
diff changeset
1410 self.userid, 'user')):
4329
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4327
diff changeset
1411 return
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4327
diff changeset
1412
4327
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
1413 # otherwise for everything else
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1414 if self.user == 'anonymous' and \
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1415 not self.db.security.hasPermission('Web Access', self.userid):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
1416 raise Unauthorised(self._("Anonymous users are not "
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1417 "allowed to use the web interface"))
4326
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
1418
7155
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1419 def is_origin_header_ok(self, api=False, credentials=False):
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
1420 """Determine if origin is valid for the context
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
1421
7155
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1422 Header is ok (return True) if ORIGIN is missing and it is a GET.
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1423 Header is ok if ORIGIN matches the base url.
8412
0663a7bcef6c feat: finish reauth docs, enhance code.
John Rouillard <rouilj@ieee.org>
parents: 8411
diff changeset
1424 If this is an API call:
0663a7bcef6c feat: finish reauth docs, enhance code.
John Rouillard <rouilj@ieee.org>
parents: 8411
diff changeset
1425
0663a7bcef6c feat: finish reauth docs, enhance code.
John Rouillard <rouilj@ieee.org>
parents: 8411
diff changeset
1426 * Header is ok if ORIGIN matches an element of allowed_api_origins.
0663a7bcef6c feat: finish reauth docs, enhance code.
John Rouillard <rouilj@ieee.org>
parents: 8411
diff changeset
1427 * Header is ok if allowed_api_origins includes '*' as first
0663a7bcef6c feat: finish reauth docs, enhance code.
John Rouillard <rouilj@ieee.org>
parents: 8411
diff changeset
1428 element and credentials is False.
0663a7bcef6c feat: finish reauth docs, enhance code.
John Rouillard <rouilj@ieee.org>
parents: 8411
diff changeset
1429
7155
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1430 Otherwise header is not ok.
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1431
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1432 In a credentials context, if we match * we will return
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1433 header is not ok. All credentialed requests must be
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1434 explicitly matched.
7150
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
1435 """
72a54826ff4f better rest Origin check; refactor CORS preflight code.
John Rouillard <rouilj@ieee.org>
parents: 7113
diff changeset
1436
7113
5c6dd791d638 bug: handle exception when origin header is missing
John Rouillard <rouilj@ieee.org>
parents: 7106
diff changeset
1437 try:
5c6dd791d638 bug: handle exception when origin header is missing
John Rouillard <rouilj@ieee.org>
parents: 7106
diff changeset
1438 origin = self.env['HTTP_ORIGIN']
5c6dd791d638 bug: handle exception when origin header is missing
John Rouillard <rouilj@ieee.org>
parents: 7106
diff changeset
1439 except KeyError:
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1440 return self.env['REQUEST_METHOD'] == 'GET'
7113
5c6dd791d638 bug: handle exception when origin header is missing
John Rouillard <rouilj@ieee.org>
parents: 7106
diff changeset
1441
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1442 # note base https://host/... ends host with with a /,
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1443 # so add it to origin.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1444 foundat = self.base.find(origin + '/')
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1445 if foundat == 0:
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1446 return True
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1447
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1448 if not api:
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1449 return False
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1450
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1451 allowed_origins = self.db.config['WEB_ALLOWED_API_ORIGINS']
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1452 # find a match for other possible origins
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1453 # Original spec says origin is case sensitive match.
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1454 # Living spec doesn't address Origin value's case or
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1455 # how to compare it. So implement case sensitive....
7155
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1456 if origin in allowed_origins:
7228
07ce4e4110f5 flake8 fixes: whitespace, remove unused imports
John Rouillard <rouilj@ieee.org>
parents: 7159
diff changeset
1457 return True
7155
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1458 # Block use of * when origin match is used for
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1459 # allowing credentials. See:
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1460 # https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 7153
diff changeset
1461 # under Credentials Requests and Wildcards
8192
b4d7f9358ba6 chore(ruff): return/suppress boolen directly
John Rouillard <rouilj@ieee.org>
parents: 8189
diff changeset
1462 return (allowed_origins and allowed_origins[0] == '*'
b4d7f9358ba6 chore(ruff): return/suppress boolen directly
John Rouillard <rouilj@ieee.org>
parents: 8189
diff changeset
1463 and not credentials)
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1464
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1465 def is_referer_header_ok(self, api=False):
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1466 referer = self.env['HTTP_REFERER']
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1467 # parse referer and create an origin
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1468 referer_comp = urllib_.urlparse(referer)
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1469
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1470 # self.base always has trailing /, so add trailing / to referer_origin
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1471 referer_origin = "%s://%s/" % (referer_comp[0], referer_comp[1])
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1472 foundat = self.base.find(referer_origin)
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1473 if foundat == 0:
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1474 return True
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1475
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1476 if not api:
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1477 return False
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1478
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1479 allowed_origins = self.db.config['WEB_ALLOWED_API_ORIGINS']
7074
ec8be5bd8bd6 bug: fix crash unguarded reference allowed_origins[0]
John Rouillard <rouilj@ieee.org>
parents: 7068
diff changeset
1480 if allowed_origins and allowed_origins[0] == '*':
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1481 return True
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1482
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1483 # For referer, loop over allowed_api_origins and
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1484 # see if any of them are a prefix to referer, case sensitive.
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1485 # Append / to each origin so that:
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1486 # an allowed_origin of https://my.host does not match
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1487 # a referer of https://my.host.com/my/path
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1488 for allowed_origin in allowed_origins:
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1489 foundat = referer_origin.find(allowed_origin + '/')
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1490 if foundat == 0:
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1491 return True
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1492 return False
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1493
8575
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1494 def expire_exposed_keys(self, method):
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1495 """A nonce is used with a method it should not be. If the
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1496 nonce exists, report to admin so they can fix the nonce
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1497 leakage and destroy it. (Nonces used in a get are more
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1498 exposed than those used in a post.) If nonce exists in the
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1499 database, report the referer and origin headers to try to
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1500 find where this comes from so it can be fixed. If nonce
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1501 doesn't exist just ignore it. If we reported invalid
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1502 nonces, somebody could spam us with a ton of invalid keys
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1503 and fill up the logs.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1504
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1505 Use ?@csrf=key in a GET, HEAD, or OPTIONS request to
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1506 test this code. Python's http server library will not parse
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1507 Content sent via one of these methods. So smuggle it
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1508 via a query string when testing.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1509 """
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1510 came_from = []
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1511 otks = self.db.getOTKManager()
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1512
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1513 if 'HTTP_REFERER' in self.env:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1514 came_from.append("Referer(%s)" % self.env['HTTP_REFERER'])
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1515 if 'HTTP_ORIGIN' in self.env:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1516 came_from.append("Origin(%s)" % self.env['HTTP_ORIGIN'])
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1517 if not came_from:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1518 came_from.append(self._("Request source headers not available."))
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1519 key = self.form['@csrf'].value
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1520 if otks.exists(key):
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1521 logger.error(
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1522 self._("csrf key used with method %(method)s from: %(source)s"),
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1523 {"method": method, "source": ", ".join(came_from)})
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1524 otks.destroy(key)
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1525 otks.commit()
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1526
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1527 def handle_csrf_tokenless(self):
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1528 '''Modern way to handle csrf prevention quoted from:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1529
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1530 https://words.filippo.io/csrf/
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1531
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1532 and is reformatted with added commentary in []'s:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1533
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1534 "In summary, to protect against CSRF applications (or,
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1535 rather, libraries and frameworks) should reject
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1536 cross-origin non-safe browser requests. The most
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1537 developer-friendly way to do so is using primarily Fetch
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1538 metadata, which requires no extra instrumentation or
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1539 configuration.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1540
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1541 1. Allow all GET, HEAD, or OPTIONS requests. These are
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1542 safe methods, and are assumed not to change state at
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1543 various layers of the stack already.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1544
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1545 2. If the Origin header matches an allow-list [see \*1 below]
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1546 of trusted origins, allow the request.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1547
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1548 Trusted origins should be configured as full origins
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1549 (e.g. https://example.com) and compared by simple
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1550 equality with the header value.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1551
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1552 3. If the Sec-Fetch-Site header is present: if its value is
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1553 same-origin or none, allow the request; otherwise,
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1554 reject the request.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1555
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1556 This secures all major up-to-date browsers for sites
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1557 hosted on trustworthy (HTTPS or localhost) origins.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1558
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1559 4. If neither the Sec-Fetch-Site nor the Origin headers are
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1560 present, allow the request.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1561
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1562 These requests are not from (post-2020) browsers, and
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1563 can't be affected by CSRF.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1564
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1565 5. If the Origin header's host (including the port) matches
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1566 the Host header, allow the request, otherwise reject it.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1567
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1568 This is either a request to an HTTP origin, or by an
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1569 out-of-date browser.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1570
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1571 The only false positives (unnecessary blocking) of this
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1572 algorithm are requests to non-trustworthy (plain HTTP)
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1573 origins that go through a reverse proxy that changes the
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1574 Host header. That edge case can be worked around by adding
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1575 the origin [see \*2 below] to the allow-list.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1576
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1577 There are no false negatives in modern browsers, but
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1578 pre-2023 browsers will be vulnerable to HTTP→HTTPS
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1579 requests, because the Origin fallback is
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1580 scheme-agnostic. HSTS can be used to mitigate that (in
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1581 post-2020 browsers), but note that out-of-date browsers
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1582 are likely to have more pressing security issues."
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1583
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1584 \*1. The allow list of trusted origins is obtained from
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1585 the tracker's config.ini file in two places:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1586
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1587 1. the web setting of the tracker section
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1588 2. the allowed_api_origins setting in the web section
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1589
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1590 \*2. I am not sure what is meant in this section. If the
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1591 reverse proxy changes the ORIGIN header, then setting
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1592 allowed_api_origins is a remedy. However the HOST header
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1593 is only used in step 5 and is compared to the ORIGIN
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1594 header not to a list of possible origins so....
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1595
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1596 The GET/HEAD/OPTIONS requests are scanned for @csrf
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1597 tokens. If any are found, they are removed from the
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1598 database. The @csrf token removal code can be deleted when
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1599 @csrf token support is removed.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1600 '''
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1601 found_origin = found_fetch = False
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1602
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1603 method = self.env['REQUEST_METHOD']
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1604 if method in {'GET', 'OPTIONS', 'HEAD'}:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1605 if (self.form.list is not None) and ("@csrf" in self.form):
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1606 self.expire_exposed_keys(method)
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1607 # do return here. Keys have been obsoleted.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1608 # we didn't do a expire cycle of session keys,
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1609 # but that's ok.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1610 return True
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1611
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1612 # local addition to fail fast if invalid method.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1613 if method not in {'POST', 'PUT', 'DELETE', 'PATCH'}:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1614 raise UsageError("Bad Request: %s" % method)
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1615
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1616 if 'HTTP_ORIGIN' in self.env:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1617 found_origin = True
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1618 origin = self.env['HTTP_ORIGIN']
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1619
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1620 tracker_web = self.db.config['TRACKER_WEB']
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1621 allowed_api_origins = self.db.config['WEB_ALLOWED_API_ORIGINS']
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1622
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1623 # tracker_web always ends with a /, so include it in
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1624 # the find.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1625 if tracker_web.find(origin + '/') == 0:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1626 return True
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1627 if origin in allowed_api_origins:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1628 return True
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1629
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1630 if 'HTTP_SEC_FETCH_SITE' in self.env:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1631 if self.env['HTTP_SEC_FETCH_SITE'] in ['same-origin', 'none']:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1632 return True
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1633
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1634 raise UsageError(self._("Unable to authorize request"))
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1635
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1636 if not (found_origin or found_fetch):
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1637 # not a browser request so not a CSRF by definition
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1638 return True
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1639
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1640 parsed_origin = urllib_.urlsplit(self.env['HTTP_ORIGIN'])
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1641 if self.env['HTTP_HOST'] == parsed_origin.netloc:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1642 return True
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1643
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1644 raise UsageError(self._("Unable to authorize request"))
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1645
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1646 def handle_csrf(self, api=False):
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1647 '''Handle csrf token lookup and validate current user and session
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1648
8575
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1649 If the config.ini setting:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1650 WEB_USE_TOKENLESS_CSRF_PROTECTION is enabled, this routine
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1651 returns the result from handle_csrf_tokenless()
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1652 and doesn't use Nonces at all.
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1653
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1654 This implements (or tries to implement) the
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1655 Session-Dependent Nonce from
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1656 https://seclab.stanford.edu/websec/csrf/csrf.pdf.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1657
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1658 Changing this to an HMAC(sessionid,secret) will
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1659 remove the need for saving a fair amount of
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1660 state on the server (one nonce per form per
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1661 page). If you have multiple forms/page this can
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1662 lead to abandoned csrf tokens that have to time
5946
1b50c2c5619a Fix crash bug where looking for @csrf in a form failed.
John Rouillard <rouilj@ieee.org>
parents: 5934
diff changeset
1663 out and get cleaned up. But you lose per form
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1664 tokens which may be an advantage. Also the HMAC
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1665 is constant for the session, so provides more
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1666 occasions for it to be exposed.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1667
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1668 This only runs on post (or put and delete for
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1669 future use). Nobody should be changing data
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1670 with a get.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1671
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1672 A session token lifetime is settable in
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1673 config.ini. A future enhancement to the
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1674 creation routines should allow for the requester
5946
1b50c2c5619a Fix crash bug where looking for @csrf in a form failed.
John Rouillard <rouilj@ieee.org>
parents: 5934
diff changeset
1675 of the token to set the lifetime.
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1676
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1677 The unique session key and user id is stored
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1678 with the token. The token is valid if the stored
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1679 values match the current client's userid and
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1680 session.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1681
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1682 If a user logs out, the csrf keys are
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1683 invalidated since no other connection should
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1684 have the same session id.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1685
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1686 At least to start I am reporting anti-csrf to
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1687 the user. If it's an attacker who can see the
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1688 site, they can see the @csrf fields and can
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1689 probably figure out that he needs to supply
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1690 valid headers. Or they can just read this code
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1691 8-). So hiding it doesn't seem to help but it
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1692 does arguably show the enforcement settings, but
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1693 given the newness of this code notifying the
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1694 user and having them notify the admins for
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1695 debugging seems to be an advantage.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1696
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1697 '''
8575
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1698
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1699 if self.db.config['WEB_USE_TOKENLESS_CSRF_PROTECTION']:
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1700 return self.handle_csrf_tokenless()
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1701
5210
7da56980754d Remove csrf keys used with get
John Rouillard <rouilj@ieee.org>
parents: 5202
diff changeset
1702 # Create the otks handle here as we need it almost immediately.
7da56980754d Remove csrf keys used with get
John Rouillard <rouilj@ieee.org>
parents: 5202
diff changeset
1703 # If this is perf issue, set to None here and check below
7da56980754d Remove csrf keys used with get
John Rouillard <rouilj@ieee.org>
parents: 5202
diff changeset
1704 # once all header checks have passed if it needs to be opened.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1705 otks = self.db.getOTKManager()
5210
7da56980754d Remove csrf keys used with get
John Rouillard <rouilj@ieee.org>
parents: 5202
diff changeset
1706
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1707 # Assume: never allow changes via GET
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1708 if self.env['REQUEST_METHOD'] not in ['POST', 'PUT', 'DELETE']:
5946
1b50c2c5619a Fix crash bug where looking for @csrf in a form failed.
John Rouillard <rouilj@ieee.org>
parents: 5934
diff changeset
1709 if (self.form.list is not None) and ("@csrf" in self.form):
8575
b1024bf0d9f7 feature: add nonceless/tokenless CSRF protection
John Rouillard <rouilj@ieee.org>
parents: 8558
diff changeset
1710 self.expire_exposed_keys(method)
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1711 # do return here. Keys have been obsoleted.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1712 # we didn't do a expire cycle of session keys,
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1713 # but that's ok.
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1714 return True
5210
7da56980754d Remove csrf keys used with get
John Rouillard <rouilj@ieee.org>
parents: 5202
diff changeset
1715
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1716 config = self.instance.config
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1717 current_user = self.db.getuid()
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1718
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1719 # List HTTP headers we check. Note that the xmlrpc header is
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1720 # missing. Its enforcement is different (yes/required are the
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1721 # same for example) so we don't include here.
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1722 header_names = [
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1723 "ORIGIN",
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1724 "REFERER",
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1725 "X-FORWARDED-HOST",
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1726 "HOST",
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1727 ]
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1728
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1729 header_pass = 0 # count of passing header checks
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1730
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1731 # If required headers are missing, raise an error
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1732 for header in header_names:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1733 if (config["WEB_CSRF_ENFORCE_HEADER_%s" % header] == 'required'
5624
b3618882f906 issue2551023: Fix CSRF headers for use with wsgi and cgi. The
John Rouillard <rouilj@ieee.org>
parents: 5615
diff changeset
1734 and "HTTP_%s" % header.replace('-', '_') not in self.env):
7058
7259ce224d65 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6977
diff changeset
1735 logger.error(self._(
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1736 ''"csrf header %(header)s required but missing "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1737 ''"for user%(userid)s.") % {
7058
7259ce224d65 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6977
diff changeset
1738 'header': header,
7259ce224d65 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6977
diff changeset
1739 'userid': current_user})
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1740 raise Unauthorised(self._("Missing header: %s") % header)
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1741
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1742 # self.base always matches: ^https?://hostname
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1743 enforce = config['WEB_CSRF_ENFORCE_HEADER_REFERER']
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1744 if 'HTTP_REFERER' in self.env and enforce != "no":
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1745 if not self.is_referer_header_ok(api=api):
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6681
diff changeset
1746 referer = self.env['HTTP_REFERER']
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1747 logmsg = self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1748 ''"csrf Referer header check failed for user%(userid)s. "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1749 ''"Value=%(referer)s") % {'userid': current_user,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1750 'referer': referer}
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1751 if enforce in ('required', 'yes'):
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1752 logger.error(logmsg)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1753 raise Unauthorised(self._("Invalid Referer: %s") % (
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1754 referer))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1755 if enforce == 'logfailure':
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1756 logger.warning(logmsg)
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1757 else:
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1758 header_pass += 1
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1759
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1760 # if you change these make sure to consider what
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1761 # happens if header variable exists but is empty.
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1762 # self.base.find("") returns 0 for example not -1
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1763 enforce = config['WEB_CSRF_ENFORCE_HEADER_ORIGIN']
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1764 if 'HTTP_ORIGIN' in self.env and enforce != "no":
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1765 if not self.is_origin_header_ok(api=api):
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1766 origin = self.env['HTTP_ORIGIN']
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1767 logmsg = self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1768 ''"csrf Origin header check failed for user%(userid)s. "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1769 ''"Value=%(origin)s") % {
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1770 'userid': current_user, 'origin': origin}
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1771 if enforce in ('required', 'yes'):
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1772 logger.error(logmsg)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1773 raise Unauthorised(self._("Invalid Origin %s" % origin))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1774 if enforce == 'logfailure':
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1775 logger.warning(logmsg)
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1776 else:
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1777 header_pass += 1
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1778
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1779 enforce = config['WEB_CSRF_ENFORCE_HEADER_X-FORWARDED-HOST']
5624
b3618882f906 issue2551023: Fix CSRF headers for use with wsgi and cgi. The
John Rouillard <rouilj@ieee.org>
parents: 5615
diff changeset
1780 if 'HTTP_X_FORWARDED_HOST' in self.env:
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1781 if enforce != "no":
5624
b3618882f906 issue2551023: Fix CSRF headers for use with wsgi and cgi. The
John Rouillard <rouilj@ieee.org>
parents: 5615
diff changeset
1782 host = self.env['HTTP_X_FORWARDED_HOST']
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1783 foundat = self.base.find('://' + host + '/')
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1784 # 4 means self.base has http:/ prefix, 5 means https:/ prefix
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1785 if foundat not in [4, 5]:
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1786 logmsg = self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1787 ''"csrf X-FORWARDED-HOST header check failed "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1788 ''"for user%(userid)s. Value=%(host)s") % {
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1789 'userid': current_user, 'host': host}
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1790 if enforce in ('required', 'yes'):
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1791 logger.error(logmsg)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1792 raise Unauthorised(self._(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1793 "Invalid X-FORWARDED-HOST %s") % host)
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1794 if enforce == 'logfailure':
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1795 logger.warning(logmsg)
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1796 else:
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1797 header_pass += 1
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1798 else:
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1799 # https://seclab.stanford.edu/websec/csrf/csrf.pdf
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1800 # recommends checking HTTP HOST header as well.
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1801 # If there is an X-FORWARDED-HOST header, check
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1802 # that only. The proxy setting X-F-H has probably set
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1803 # the host header to a local hostname that is
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1804 # internal name of system not name supplied by user.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1805 enforce = config['WEB_CSRF_ENFORCE_HEADER_HOST']
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1806 if 'HTTP_HOST' in self.env and enforce != "no":
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1807 host = self.env['HTTP_HOST']
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1808 foundat = self.base.find('://' + host + '/')
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1809 # 4 means http:// prefix, 5 means https:// prefix
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1810 if foundat not in [4, 5]:
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1811 logmsg = self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1812 ''"csrf HOST header check failed for "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1813 ''"user%(userid)s. Value=%(host)s") % {
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1814 'userid': current_user, 'host': host}
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1815 if enforce in ('required', 'yes'):
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1816 logger.error(logmsg)
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1817 raise Unauthorised(self._("Invalid HOST %s") % host)
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1818 if enforce == 'logfailure':
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1819 logger.warning(logmsg)
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1820 else:
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1821 header_pass += 1
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1822
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1823 enforce = config['WEB_CSRF_HEADER_MIN_COUNT']
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1824 if header_pass < enforce:
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1825 logger.error(self._("Csrf: unable to verify sufficient headers"))
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
1826 raise UsageError(self._("Unable to verify sufficient headers"))
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1827
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1828 enforce = config['WEB_CSRF_ENFORCE_HEADER_X-REQUESTED-WITH']
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1829 if api and enforce in ['required', 'yes']:
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1830 # if we get here we have usually passed at least one
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1831 # header check. We check for presence of this custom
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1832 # header for xmlrpc/rest calls only.
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1833 # E.G. X-Requested-With: XMLHttpRequest
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1834 # Note we do not use CSRF nonces for xmlrpc/rest requests.
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1835 #
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1836 # see: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Protecting_REST_Services:_Use_of_Custom_Request_Headers
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1837 if 'HTTP_X_REQUESTED_WITH' not in self.env:
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1838 logger.error(self._(
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1839 ''"csrf X-REQUESTED-WITH xmlrpc required header "
8279
80105cd30368 refactor: translator hint that 'user%s' should not be 'user %s'
John Rouillard <rouilj@ieee.org>
parents: 8268
diff changeset
1840 ''"check failed for user%(userid)s."),
80105cd30368 refactor: translator hint that 'user%s' should not be 'user %s'
John Rouillard <rouilj@ieee.org>
parents: 8268
diff changeset
1841 {"userid": current_user})
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1842 raise UsageError(self._("Required Header Missing"))
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1843
5211
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1844 # Expire old csrf tokens now so we don't use them. These will
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1845 # be committed after the otks.destroy below. Note that the
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1846 # self.clean_up run as part of determine_user() will run only
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1847 # once an hour. If we have short lived (e.g. 5 minute) keys
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1848 # they will live too long if we depend on clean_up. So we do
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1849 # our own.
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1850 otks.clean()
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1851
6681
ab2ed11c021e issue2551205: Add support for specifying valid origins for api: xmlrpc/rest
John Rouillard <rouilj@ieee.org>
parents: 6658
diff changeset
1852 if api:
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1853 # Save removal of expired keys from database.
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
1854 otks.commit()
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1855 # Return from here since we have done housekeeping
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1856 # and don't use csrf tokens for xmlrpc.
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1857 return True
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1858
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1859 # process @csrf tokens past this point.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1860 key = None
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1861 nonce_user = None
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1862 nonce_session = None
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1863
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1864 if '@csrf' in self.form:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1865 key = self.form['@csrf'].value
5210
7da56980754d Remove csrf keys used with get
John Rouillard <rouilj@ieee.org>
parents: 5202
diff changeset
1866
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1867 nonce_user = otks.get(key, 'uid', default=None)
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1868 nonce_session = otks.get(key, 'sid', default=None)
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1869 # The key has been used or compromised.
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1870 # Delete it to prevent replay.
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1871 otks.destroy(key)
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1872
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1873 # commit the deletion/expiration of all keys
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5248
diff changeset
1874 otks.commit()
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1875
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1876 enforce = config['WEB_CSRF_ENFORCE_TOKEN']
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1877 if key is None: # we do not have an @csrf token
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1878 if enforce == 'required':
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1879 logger.error(self._(
8279
80105cd30368 refactor: translator hint that 'user%s' should not be 'user %s'
John Rouillard <rouilj@ieee.org>
parents: 8268
diff changeset
1880 "Required csrf field missing for user%(userid)s"),
80105cd30368 refactor: translator hint that 'user%s' should not be 'user %s'
John Rouillard <rouilj@ieee.org>
parents: 8268
diff changeset
1881 {"userid": current_user})
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1882 raise UsageError(self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1883 ''"We can't validate your session (csrf failure). "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1884 ''"Re-enter any unsaved data and try again."))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1885 if enforce == 'logfailure':
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
1886 # FIXME include url
8279
80105cd30368 refactor: translator hint that 'user%s' should not be 'user %s'
John Rouillard <rouilj@ieee.org>
parents: 8268
diff changeset
1887 logger.warning(self._(
80105cd30368 refactor: translator hint that 'user%s' should not be 'user %s'
John Rouillard <rouilj@ieee.org>
parents: 8268
diff changeset
1888 "csrf field not supplied by user%(userid)s"),
80105cd30368 refactor: translator hint that 'user%s' should not be 'user %s'
John Rouillard <rouilj@ieee.org>
parents: 8268
diff changeset
1889 {"userid": current_user})
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1890 else:
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1891 # enforce is either yes or no. Both permit change if token is
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1892 # missing
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1893 return True
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1894
5211
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1895 current_session = self.session_api._sid
f4b6a2a3e605 Fix expiration dates and expire csrf tokens properly
John Rouillard <rouilj@ieee.org>
parents: 5210
diff changeset
1896
5210
7da56980754d Remove csrf keys used with get
John Rouillard <rouilj@ieee.org>
parents: 5202
diff changeset
1897 # validate against user and session
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1898 if current_user != nonce_user:
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1899 logmsg = self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1900 ''"Csrf mismatch user: current user %(user)s != stored "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1901 ''"user %(stored)s, current session, stored session: "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1902 ''"%(cur_sess)s,%(stor_sess)s for key %(key)s.") % {
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1903 'user': current_user,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1904 'stored': nonce_user,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1905 'cur_sess': current_session,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1906 'stor_sess': nonce_session,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1907 'key': key}
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1908 if enforce in ('required', 'yes'):
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1909 logger.error(logmsg)
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1910 raise UsageError(self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1911 ''"We can't validate your session (csrf failure). "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1912 ''"Re-enter any unsaved data and try again."))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1913 if enforce == 'logfailure':
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1914 logger.warning(logmsg)
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1915
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1916 if current_session != nonce_session:
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1917 logmsg = self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1918 ''"Csrf mismatch user: current session %(curr_sess)s "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1919 ''"!= stored session %(stor_sess)s, current user/stored "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1920 ''"user is: %(user)s for key %(key)s.") % {
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1921 'curr_sess': current_session,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1922 'stor_sess': nonce_session,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1923 'user': current_user,
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1924 'key': key}
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1925 if enforce in ('required', 'yes'):
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1926 logger.error(logmsg)
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1927 raise UsageError(self._(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1928 ''"We can't validate your session (csrf failure). "
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1929 ''"Re-enter any unsaved data and try again."))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
1930 if enforce == 'logfailure':
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
1931 logger.warning(logmsg)
7058
7259ce224d65 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6977
diff changeset
1932
5220
14d8f61e6ef2 Reimplemented anti-csrf measures by raising exceptions rather than
John Rouillard <rouilj@ieee.org>
parents: 5218
diff changeset
1933 # we are done and the change can occur.
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1934 return True
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5188
diff changeset
1935
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1936 def opendb(self, username):
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1937 """Open the database and set the current user.
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1938
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1939 Opens a database once. On subsequent calls only the user is set on
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1940 the database object the instance.optimize is set. If we are in
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1941 "Development Mode" (cf. roundup_server) then the database is always
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1942 re-opened.
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
1943 """
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1944 # don't do anything if the db is open and the user has not changed
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1945 if hasattr(self, 'db') and self.db.isCurrentUser(username):
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1946 return
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1947
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1948 # open the database or only set the user
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1949 if not hasattr(self, 'db'):
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1950 self.db = self.instance.open(username)
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1951 elif self.instance.optimize:
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
1952 self.db.setCurrentUser(username)
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1953 else:
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1954 self.db.close()
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1955 self.db = self.instance.open(username)
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1956 # The old session API refers to the closed database;
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1957 # we can no longer use it.
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
1958 self.session_api = Session(self)
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
1959
7815
f11c982f01c8 chore(refactor): extract setting of db.tx_source out of if tree
John Rouillard <rouilj@ieee.org>
parents: 7814
diff changeset
1960 self.db.tx_Source = "web"
f11c982f01c8 chore(refactor): extract setting of db.tx_source out of if tree
John Rouillard <rouilj@ieee.org>
parents: 7814
diff changeset
1961
6977
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1962 # match designator in URL stripping leading 0's. So:
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1963 # https://issues.roundup-tracker.org/issue002551190 is the same as
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1964 # https://issues.roundup-tracker.org/issue2551190
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1965 # Note: id's are strings not numbers so "02" != "2" but 02 == 2
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1966 dre_url = re.compile(r'([^\d]+)0*(\d+)')
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1967
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
1968 def determine_context(self, dre=dre_url):
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1969 """Determine the context of this page from the URL:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1970
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1971 The URL path after the instance identifier is examined. The path
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1972 is generally only one entry long.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1973
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1974 - if there is no path, then we are in the "home" context.
8556
dd0445649244 bug(perf): put legacy '_file' last in tuple to speed up match
John Rouillard <rouilj@ieee.org>
parents: 8555
diff changeset
1975 - if the path is "@@file" (or "_file", then the additional
dd0445649244 bug(perf): put legacy '_file' last in tuple to speed up match
John Rouillard <rouilj@ieee.org>
parents: 8555
diff changeset
1976 path entry specifies the filename of a static file we're to
dd0445649244 bug(perf): put legacy '_file' last in tuple to speed up match
John Rouillard <rouilj@ieee.org>
parents: 8555
diff changeset
1977 serve up from the instance "html" directory. Raises a
dd0445649244 bug(perf): put legacy '_file' last in tuple to speed up match
John Rouillard <rouilj@ieee.org>
parents: 8555
diff changeset
1978 SendStaticFile exception.(*)
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1979 - if there is something in the path (eg "issue"), it identifies
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1980 the tracker class we're to display.
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1981 - if the path is an item designator (eg "issue123"), then we're
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1982 to display a specific item.
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1983 - if the path starts with an item designator and is longer than
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1984 one entry, then we're assumed to be handling an item of a
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1985 FileClass, and the extra path information gives the filename
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1986 that the client is going to label the download with (ie
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1987 "file123/image.png" is nicer to download than "file123"). This
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1988 raises a SendFile exception.(*)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1989
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1990 Both of the "*" types of contexts stop before we bother to
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1991 determine the template we're going to use. That's because they
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1992 don't actually use templates.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1993
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1994 The template used is specified by the :template CGI variable,
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1995 which defaults to:
1053
b28393def972 more explanatory docsting
Richard Jones <richard@users.sourceforge.net>
parents: 1051
diff changeset
1996
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1997 - only classname suplied: "index"
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1998 - full item designator supplied: "item"
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1999
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
2000 We set:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2001
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
2002 self.classname - the class to display, can be None
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
2003
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
2004 self.template - the template to render the current context with
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
2005
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
2006 self.nodeid - the nodeid of the class we're displaying
1937
4c850112895b Some reformatting and fixing docstrings for emacs.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1936
diff changeset
2007 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2008 # default the optional variables
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2009 self.classname = None
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2010 self.nodeid = None
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2011
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2012 # see if a template or messages are specified
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2013 template_override = ok_message = error_message = None
4801
bff9e4145f70 Fix another instance of a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4800
diff changeset
2014 try:
bff9e4145f70 Fix another instance of a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4800
diff changeset
2015 keys = self.form.keys()
bff9e4145f70 Fix another instance of a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4800
diff changeset
2016 except TypeError:
bff9e4145f70 Fix another instance of a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4800
diff changeset
2017 keys = ()
bff9e4145f70 Fix another instance of a TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4800
diff changeset
2018 for key in keys:
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2019 if self.FV_TEMPLATE.match(key):
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2020 template_override = self.form[key].value
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2021 elif self.FV_OK_MESSAGE.match(key):
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2022 ok_message = self.form[key].value
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2023 elif self.FV_ERROR_MESSAGE.match(key):
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2024 error_message = self.form[key].value
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2025
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
2026 # see if we were passed in a message
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
2027 if ok_message:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2028 self.add_ok_message(ok_message)
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
2029 if error_message:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2030 self.add_error_message(error_message)
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
2031
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2032 # determine the classname and possibly nodeid
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
2033 path = self.path.split('/')
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2034 if not path or path[0] in ('', 'home', 'index'):
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2035 if template_override is not None:
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2036 self.template = template_override
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2037 else:
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
2038 self.template = ''
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2039 return
8556
dd0445649244 bug(perf): put legacy '_file' last in tuple to speed up match
John Rouillard <rouilj@ieee.org>
parents: 8555
diff changeset
2040 if path[0] in ('@@file', '_file'):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2041 raise SendStaticFile(os.path.join(*path[1:]))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2042
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2043 self.classname = path[0]
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2044 if len(path) > 1:
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2045 # send the file identified by the designator in path[0]
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2046 raise SendFile(path[0])
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2047
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2048 # see if we got a designator
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2049 m = dre.match(self.classname)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2050 if m:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2051 self.classname = m.group(1)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2052 self.nodeid = m.group(2)
3494
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
2053 try:
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
2054 klass = self.db.getclass(self.classname)
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
2055 except KeyError:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2056 raise NotFound('%s/%s' % (self.classname, self.nodeid))
5555
7b663b588292 Don't pass huge itemids into the backend.
martin.v.loewis <martin.v.loewis>
parents: 5554
diff changeset
2057 if int(self.nodeid) > 2**31:
7b663b588292 Don't pass huge itemids into the backend.
martin.v.loewis <martin.v.loewis>
parents: 5554
diff changeset
2058 # Postgres will complain with a ProgrammingError
7b663b588292 Don't pass huge itemids into the backend.
martin.v.loewis <martin.v.loewis>
parents: 5554
diff changeset
2059 # if we try to pass in numbers that are too large
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2060 raise NotFound('%s/%s' % (self.classname, self.nodeid))
3494
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
2061 if not klass.hasnode(self.nodeid):
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2062 raise NotFound('%s/%s' % (self.classname, self.nodeid))
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2063 # with a designator, we default to item view
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
2064 self.template = 'item'
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2065 else:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2066 # with only a class, we default to index view
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
2067 self.template = 'index'
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2068
1288
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
2069 # make sure the classname is valid
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
2070 try:
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
2071 self.db.getclass(self.classname)
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
2072 except KeyError:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2073 raise NotFound(self.classname)
1288
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
2074
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2075 # see if we have a template override
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2076 if template_override is not None:
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
2077 self.template = template_override
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2078
8411
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2079 def reauth(self, exception):
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2080 """Processing for a Reauth exception raised from an auditor.
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2081
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2082 Can be overridden by code in tracker's interfaces.py.
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2083 """
8502
dfecb240bc34 chore: ruff whitespace fixes.
John Rouillard <rouilj@ieee.org>
parents: 8500
diff changeset
2084
8500
b03160d46e9d bug: don't reference vendored outside of anypy modules
John Rouillard <rouilj@ieee.org>
parents: 8446
diff changeset
2085 from roundup.anypy.cgi_ import MiniFieldStorage
8411
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2086
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2087 original_action = self.form['@action'].value if '@action' \
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2088 in self.form else ""
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2089 original_template = self.template
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2090
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2091 self.template = 'reauth'
8502
dfecb240bc34 chore: ruff whitespace fixes.
John Rouillard <rouilj@ieee.org>
parents: 8500
diff changeset
2092 self.form.list = [x for x in self.form.list
dfecb240bc34 chore: ruff whitespace fixes.
John Rouillard <rouilj@ieee.org>
parents: 8500
diff changeset
2093 if x.name not in ('@action',
dfecb240bc34 chore: ruff whitespace fixes.
John Rouillard <rouilj@ieee.org>
parents: 8500
diff changeset
2094 '@csrf',
dfecb240bc34 chore: ruff whitespace fixes.
John Rouillard <rouilj@ieee.org>
parents: 8500
diff changeset
2095 '@template'
dfecb240bc34 chore: ruff whitespace fixes.
John Rouillard <rouilj@ieee.org>
parents: 8500
diff changeset
2096 )]
8411
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2097
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2098 # save the action and template used when the Reauth as
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2099 # triggered. Will be used to resolve the change by the reauth
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2100 # action when when reauth password verified.
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2101 if '@next_action' not in self.form.list:
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2102 self.form.list.append(MiniFieldStorage('@next_action',
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2103 original_action))
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2104 if '@next_template' not in self.form.list:
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2105 self.form.list.append(MiniFieldStorage('@next_template',
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2106 original_template))
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2107
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2108 if exception.args and "@reauth_message" not in self.form.list:
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2109 self.form.list.append(
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2110 MiniFieldStorage('@reauth_message',
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2111 html_escape(exception.args[0])
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2112 )
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2113 )
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2114
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2115 self.write_html(self.renderContext())
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2116
6977
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2117 # re for splitting designator, see also dre_url above this one
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2118 # doesn't strip leading 0's from the id. Why not??
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2119 dre = re.compile(r'([^\d]+)(\d+)')
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2120
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2121 def serve_file(self, designator, dre=dre):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2122 """ Serve the file from the content property of the designated item.
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2123 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2124 m = dre.match(str(designator))
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2125 if not m:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2126 raise NotFound(str(designator))
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2127 classname, nodeid = m.group(1), m.group(2)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2128
4263
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
2129 try:
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
2130 klass = self.db.getclass(classname)
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
2131 except KeyError:
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
2132 # The classname was not valid.
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2133 raise NotFound(str(designator))
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
2134
4326
d51a9c498dc4 Fix "Web Access" permission check to allow serving of static files to Anonymous again
Richard Jones <richard@users.sourceforge.net>
parents: 4291
diff changeset
2135 # perform the Anonymous user access check
4327
095d92109cc7 allow Anonymous users to log in, and register
Richard Jones <richard@users.sourceforge.net>
parents: 4326
diff changeset
2136 self.check_anonymous_access()
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2137
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
2138 # make sure we have the appropriate properties
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
2139 props = klass.getprops()
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2140 if 'type' not in props:
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2141 raise NotFound(designator)
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2142 if 'content' not in props:
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2143 raise NotFound(designator)
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
2144
2870
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
2145 # make sure we have permission
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
2146 if not self.db.security.hasPermission('View', self.userid,
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2147 classname, 'content', nodeid):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2148 raise Unauthorised(self._("You are not allowed to view "
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2149 "this file."))
4962
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2150
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2151 # --- mime-type security
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2152 # mime type detection is performed in cgi.form_parser
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2153
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2154 if self.instance.config['WEB_ALLOW_HTML_FILE']:
8039
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
2155 self.mime_type_allowlist.append('text/html')
4962
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2156
4530
c1c395058dee issue2550715: IndexError when requesting non-existing file via http.
Bernhard Reiter <Bernhard.Reiter@intevation.de>
parents: 4523
diff changeset
2157 try:
c1c395058dee issue2550715: IndexError when requesting non-existing file via http.
Bernhard Reiter <Bernhard.Reiter@intevation.de>
parents: 4523
diff changeset
2158 mime_type = klass.get(nodeid, 'type')
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
2159 except IndexError as e:
4530
c1c395058dee issue2550715: IndexError when requesting non-existing file via http.
Bernhard Reiter <Bernhard.Reiter@intevation.de>
parents: 4523
diff changeset
2160 raise NotFound(e)
4291
b1772fdb09d0 Fix traceback on .../msgN/ url...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4265
diff changeset
2161 # Can happen for msg class:
b1772fdb09d0 Fix traceback on .../msgN/ url...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4265
diff changeset
2162 if not mime_type:
b1772fdb09d0 Fix traceback on .../msgN/ url...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4265
diff changeset
2163 mime_type = 'text/plain'
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2164
8039
e1cff9745fb4 refactor: make mime_type_allowlist class prop to configure from interfaces.py
John Rouillard <rouilj@ieee.org>
parents: 8021
diff changeset
2165 if mime_type not in self.mime_type_allowlist:
4962
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2166 mime_type = 'application/octet-stream'
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2167
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2168 # --/ mime-type security
63c31b18b955 Fix issue 2550848: HTML attachments should not be served as text/html
anatoly techtonik <techtonik@gmail.com>
parents: 4919
diff changeset
2169
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2170 # If this object is a file (i.e., an instance of FileClass),
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2171 # see if we can find it in the filesystem. If so, we may be
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2172 # able to use the more-efficient request.sendfile method of
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2173 # sending the file. If not, just get the "content" property
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2174 # in the usual way, and use that.
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2175 content = None
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2176 filename = None
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2177 if isinstance(klass, hyperdb.FileClass):
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2178 try:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2179 filename = self.db.filename(classname, nodeid)
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2180 except AttributeError:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2181 # The database doesn't store files in the filesystem
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2182 # and therefore doesn't provide the "filename" method.
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2183 pass
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2184 except IOError:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2185 # The file does not exist.
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2186 pass
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2187 if not filename:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2188 content = klass.get(nodeid, 'content')
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
2189
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
2190 lmt = klass.get(nodeid, 'activity').timestamp()
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2191
8185
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2192 self._serve_file(lmt, None, mime_type, content, filename)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2193
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2194 def serve_static_file(self, file):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2195 """ Serve up the file named from the templates dir
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2196 """
2864
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
2197 # figure the filename - try STATIC_FILES, then TEMPLATES dir
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
2198 for dir_option in ('STATIC_FILES', 'TEMPLATES'):
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
2199 prefix = self.instance.config[dir_option]
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
2200 if not prefix:
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
2201 continue
5613
0a8f0fddc2ae Support non-ASCII prefixes in instance config for finding static files (issue2551022).
Cédric Krier <cedric.krier@b2ck.com>
parents: 5608
diff changeset
2202 if is_us(prefix):
5231
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2203 # prefix can be a string or list depending on
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2204 # option. Make it a list to iterate over.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2205 prefix = [prefix]
5231
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2206
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2207 for p in prefix:
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2208 # if last element of STATIC_FILES ends with '/-',
7905
f47b186a2ad9 fix use of '-' directory in static files
John Rouillard <rouilj@ieee.org>
parents: 7815
diff changeset
2209 # or \- on windows, we failed to find the file
f47b186a2ad9 fix use of '-' directory in static files
John Rouillard <rouilj@ieee.org>
parents: 7815
diff changeset
2210 # and should not look in TEMPLATES. So raise exception.
f47b186a2ad9 fix use of '-' directory in static files
John Rouillard <rouilj@ieee.org>
parents: 7815
diff changeset
2211 if (dir_option == 'STATIC_FILES' and p[-1:] == '-' and
f47b186a2ad9 fix use of '-' directory in static files
John Rouillard <rouilj@ieee.org>
parents: 7815
diff changeset
2212 p[-2:-1] in ('/', '\\')):
5231
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2213 raise NotFound(file)
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2214
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2215 # ensure the load doesn't try to poke outside
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2216 # of the static files directory
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2217 p = os.path.normpath(p)
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2218 filename = os.path.normpath(os.path.join(p, file))
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2219 if os.path.isfile(filename) and filename.startswith(p):
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2220 break # inner loop over list of directories
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2221
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2222 # reset filename to None as sentinel for use below.
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2223 filename = None
5231
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2224
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2225 # break out of outer loop over options
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2226 if filename:
2864
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
2227 break
5231
8743b7226dc7 Fix issue with retreiving raw template files using the @@file mechanism.
John Rouillard <rouilj@ieee.org>
parents: 5220
diff changeset
2228
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2229 if filename is None: # we didn't find a filename
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2230 raise NotFound(file)
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2231
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2232 # detemine meta-type
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2233 file = str(file)
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2234 mime_type = mimetypes.guess_type(file)[0]
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2235 if not mime_type:
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
2236 mime_type = 'text/css' if file.endswith('.css') else 'text/plain'
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
2237
5980
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2238 # get filename: given a/b/c.js extract c.js
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2239 fn = file.rpartition("/")[2]
5980
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2240 if fn in self.Cache_Control:
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2241 # if filename matches, don't use cache control
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2242 # for mime type.
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2243 self.additional_headers['Cache-Control'] = \
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2244 self.Cache_Control[fn]
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2245 elif mime_type in self.Cache_Control:
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2246 self.additional_headers['Cache-Control'] = \
54d0080769f9 Support setting cache-control headers for static files
John Rouillard <rouilj@ieee.org>
parents: 5946
diff changeset
2247 self.Cache_Control[mime_type]
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2248
8185
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2249 self._serve_file(None, None, mime_type, '', filename)
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2250
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2251 def _serve_file(self, lmt, etag, mime_type, content=None, filename=None):
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2252 """guts of serve_file() and serve_static_file()
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2253
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2254 if lmt or etag are None, derive them from file filename.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2255
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2256 Handles if-modified-since and if-none-match etag
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2257 conditional gets.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2258
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2259 It produces an raw etag header without encoding suffix.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2260 But it adds Accept-Encoding to the vary header.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2261
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2262 """
8185
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2263 if filename:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2264 stat_info = os.stat(filename)
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2265
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2266 if lmt is None:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2267 # last-modified time
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2268 lmt = stat_info[stat.ST_MTIME]
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2269 if etag is None:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2270 # FIXME: maybe etag should depend on encoding.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2271 # it is an apache compatible etag without encoding.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2272 etag = '"%x-%x-%x"' % (stat_info[stat.ST_INO],
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2273 stat_info[stat.ST_SIZE],
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2274 stat_info[stat.ST_MTIME])
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2275
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2276 # spit out headers for conditional request
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2277 self.setHeader("ETag", etag)
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2278 self.additional_headers['Last-Modified'] = \
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2279 email.utils.formatdate(lmt, usegmt=True)
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2280
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2281 inm = None
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2282 # ETag is a more strict check than modified date. Use etag
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2283 # check if available. Skip testing modified data.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2284 if hasattr(self.request, 'headers'):
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2285 inm = self.request.headers.get('if-none-match')
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2286 elif 'HTTP_IF_NONE_MATCH' in self.env:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2287 # maybe the cgi will put the header in the env var
8186
b938fd5223ae fix(web): issue2551356. Add etag header ... fix env variable name
John Rouillard <rouilj@ieee.org>
parents: 8185
diff changeset
2288 inm = self.env['HTTP_IF_NONE_MATCH']
8185
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2289 if inm and etag == inm:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2290 # because we can compress, always set Accept-Encoding
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2291 # value. Otherwise caches can serve up the wrong info
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2292 # if their cached copy has no compression.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2293 self.setVary("Accept-Encoding")
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2294 '''
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2295 to solve issue2551356 I may need to determine
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2296 the content encoding.
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2297 if (self.determine_content_encoding()):
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2298 '''
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2299 raise NotModified
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2300
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2301 if self.if_not_modified_since(lmt):
8021
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2302 # because we can compress, always set Accept-Encoding
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2303 # value. Otherwise caches can serve up the wrong info
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2304 # if their cached copy has no compression.
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2305 self.setVary("Accept-Encoding")
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2306 '''
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2307 to solve issue2551356 I may need to determine
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2308 the content encoding.
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2309 if (self.determine_content_encoding()):
98429efb80cb fix: Send vary header for if-modified-since conditional returning 304
John Rouillard <rouilj@ieee.org>
parents: 8020
diff changeset
2310 '''
1469
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
2311 raise NotModified
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
2312
6548
de5f5f9c02f2 Fix spurious content-ty on 304; xfail css Cache-Control
John Rouillard <rouilj@ieee.org>
parents: 6546
diff changeset
2313 # don't set until we are sure we are sending a response body.
de5f5f9c02f2 Fix spurious content-ty on 304; xfail css Cache-Control
John Rouillard <rouilj@ieee.org>
parents: 6546
diff changeset
2314 self.additional_headers['Content-Type'] = mime_type
de5f5f9c02f2 Fix spurious content-ty on 304; xfail css Cache-Control
John Rouillard <rouilj@ieee.org>
parents: 6546
diff changeset
2315
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
2316 if filename:
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2317 self.write_file(filename)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2318 else:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2319 self.additional_headers['Content-Length'] = str(len(content))
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2320 self.write(content)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2321
8185
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2322 def if_not_modified_since(self, lmt):
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2323 ims = None
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2324 # see if there's an if-modified-since...
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2325 if hasattr(self.request, 'headers'):
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2326 ims = self.request.headers.get('if-modified-since')
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2327 elif 'HTTP_IF_MODIFIED_SINCE' in self.env:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2328 # cgi will put the header in the env var
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2329 ims = self.env['HTTP_IF_MODIFIED_SINCE']
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2330
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2331 if ims:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2332 datestamp = email.utils.parsedate(ims)
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2333 if datestamp is not None:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2334 ims = datestamp[:6]
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2335 else:
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2336 # set to beginning of time so whole file will be sent
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2337 ims = (0, 0, 0, 0, 0, 0)
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2338 lmtt = time.gmtime(lmt)[:6]
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2339 return lmtt <= ims
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2340
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2341 return False
e84d4585b16d fix(web): issue2551356. Add etag header for not-modified (304) request.
John Rouillard <rouilj@ieee.org>
parents: 8175
diff changeset
2342
4543
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2343 def send_error_to_admin(self, subject, html, txt):
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2344 """Send traceback information to admin via email.
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2345 We send both, the formatted html (with more information) and
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2346 the text version of the traceback. We use
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2347 multipart/alternative so the receiver can chose which version
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2348 to display.
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2349 """
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
2350 to = [self.mailer.config.ADMIN_EMAIL]
4543
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2351 message = MIMEMultipart('alternative')
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2352 self.mailer.set_message_attributes(message, to, subject)
5518
db3a95f28b3c fixed typos in send_error_to_admin
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5493
diff changeset
2353 part = self.mailer.get_text_message('utf-8', 'html')
5493
725266c03eab updated mailgw to no longer use mimetools based on jerrykan's patch
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5488
diff changeset
2354 part.set_payload(html, part.get_charset())
4543
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2355 message.attach(part)
5518
db3a95f28b3c fixed typos in send_error_to_admin
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5493
diff changeset
2356 part = self.mailer.get_text_message()
db3a95f28b3c fixed typos in send_error_to_admin
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5493
diff changeset
2357 part.set_payload(txt, part.get_charset())
4543
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2358 message.attach(part)
4523
a03646a02f68 Fix issue2550691 where a Unix From-Header was sometimes inserted...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4384
diff changeset
2359 self.mailer.smtp_send(to, message.as_string())
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
2360
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
2361 def renderFrontPage(self, message):
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
2362 """Return the front page of the tracker."""
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
2363
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
2364 self.classname = self.nodeid = None
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
2365 self.template = ''
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2366 self.add_error_message(message)
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
2367 self.write_html(self.renderContext())
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
2368
4740
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2369 def selectTemplate(self, name, view):
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2370 """ Choose existing template for the given combination of
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2371 classname (name parameter) and template request variable
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2372 (view parameter) and return its name.
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2373
5185
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2374 View can be a single template or two templates separated
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2375 by a vbar '|' character. If the Client object has a
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2376 non-empty _error_message attribute, the right hand
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2377 template (error template) will be used. If the
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2378 _error_message is empty, the left hand template (ok
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2379 template) will be used.
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2380
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2381 In most cases the name will be "classname.view", but
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2382 if "view" is None, then template name "classname" will
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2383 be returned.
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2384
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2385 If "classname.view" template doesn't exist, the
4740
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2386 "_generic.view" is used as a fallback.
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2387
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2388 [ ] cover with tests
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2389 """
5185
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2390
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2391 # determine if view is oktmpl|errortmpl. If so assign the
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2392 # right one to the view parameter. If we don't have alternate
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2393 # templates, just leave view alone.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2394 if (view and view.find('|') != -1):
5185
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2395 # we have alternate templates, parse them apart.
8320
b07165add61b fix(web): issue2551406 - dont crash when handed invalid @template=a|b|c
John Rouillard <rouilj@ieee.org>
parents: 8279
diff changeset
2396 (oktmpl, errortmpl) = view.split("|", 1)
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
2397
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
2398 # Choose the right template
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
2399 view = errortmpl if self._error_message else oktmpl
5185
349bef975367 Make @template support two alternate templates for error and ok cases.
John Rouillard <rouilj@ieee.org>
parents: 5166
diff changeset
2400
4739
94be76e04140 templating: Move template selection logic from the template loaders
anatoly techtonik <techtonik@gmail.com>
parents: 4728
diff changeset
2401 loader = self.instance.templates
94be76e04140 templating: Move template selection logic from the template loaders
anatoly techtonik <techtonik@gmail.com>
parents: 4728
diff changeset
2402
94be76e04140 templating: Move template selection logic from the template loaders
anatoly techtonik <techtonik@gmail.com>
parents: 4728
diff changeset
2403 # if classname is not set, use "home" template
94be76e04140 templating: Move template selection logic from the template loaders
anatoly techtonik <techtonik@gmail.com>
parents: 4728
diff changeset
2404 if name is None:
94be76e04140 templating: Move template selection logic from the template loaders
anatoly techtonik <techtonik@gmail.com>
parents: 4728
diff changeset
2405 name = 'home'
94be76e04140 templating: Move template selection logic from the template loaders
anatoly techtonik <techtonik@gmail.com>
parents: 4728
diff changeset
2406
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2407 tplname = name
4740
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2408 if view:
5154
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2409 # Support subdirectories for templates. Value is path/to/VIEW
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2410 # or just VIEW if the template is in the html directory of
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2411 # the tracker.
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2412 slash_loc = view.rfind("/")
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2413 if slash_loc == -1:
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2414 # try plain class.view
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2415 tplname = '%s.%s' % (name, view)
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2416 else:
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2417 # try path/class.view
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2418 tplname = '%s/%s.%s' % (
8189
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2419 view[:slash_loc], name, view[slash_loc + 1:])
4740
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2420
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2421 if loader.check(tplname):
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2422 return tplname
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2423
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2424 # rendering class/context with generic template for this view.
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2425 # with no view it's impossible to choose which generic template to use
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2426 if not view:
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2427 raise templating.NoTemplate('Template "%s" doesn\'t exist' % name)
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2428
5154
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2429 if slash_loc == -1:
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2430 generic = '_generic.%s' % view
f608eeecf638 issue2550891: Allow subdir in template value. Anthony (antmail)
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
2431 else:
8189
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2432 generic = '%s/_generic.%s' % (view[:slash_loc], view[slash_loc + 1:])
4740
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2433 if loader.check(generic):
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2434 return generic
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2435
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2436 raise templating.NoTemplate(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2437 'No template file exists for templating '
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2438 '"%s" with template "%s" (neither "%s" nor "%s")' % (
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2439 name, view, tplname, generic))
4739
94be76e04140 templating: Move template selection logic from the template loaders
anatoly techtonik <techtonik@gmail.com>
parents: 4728
diff changeset
2440
1204
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
2441 def renderContext(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2442 """ Return a PageTemplate for the named page
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2443 """
6382
b35a50d02890 Fix issue2551129 - Template not found return 500 and traceback
John Rouillard <rouilj@ieee.org>
parents: 6267
diff changeset
2444 try:
b35a50d02890 Fix issue2551129 - Template not found return 500 and traceback
John Rouillard <rouilj@ieee.org>
parents: 6267
diff changeset
2445 tplname = self.selectTemplate(self.classname, self.template)
1204
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
2446
6382
b35a50d02890 Fix issue2551129 - Template not found return 500 and traceback
John Rouillard <rouilj@ieee.org>
parents: 6267
diff changeset
2447 # catch errors so we can handle PT rendering errors more nicely
b35a50d02890 Fix issue2551129 - Template not found return 500 and traceback
John Rouillard <rouilj@ieee.org>
parents: 6267
diff changeset
2448 args = {
b35a50d02890 Fix issue2551129 - Template not found return 500 and traceback
John Rouillard <rouilj@ieee.org>
parents: 6267
diff changeset
2449 'ok_message': self._ok_message,
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
2450 'error_message': self._error_message,
6382
b35a50d02890 Fix issue2551129 - Template not found return 500 and traceback
John Rouillard <rouilj@ieee.org>
parents: 6267
diff changeset
2451 }
4740
fe9568a6cbd6 Untangle template selection logic from template loading functionality.
anatoly techtonik <techtonik@gmail.com>
parents: 4739
diff changeset
2452 pt = self.instance.templates.load(tplname)
1016
d6c13142e7b9 Keep a cache of compiled PageTemplates.
Richard Jones <richard@users.sourceforge.net>
parents: 1008
diff changeset
2453 # let the template render figure stuff out
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2454 try:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2455 result = pt.render(self, None, None, **args)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2456 except IndexerQueryError as e:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2457 result = self.renderError(e.args[0])
8241
741ea8a86012 fix: issue2551374. Error handling for filter expressions.
John Rouillard <rouilj@ieee.org>
parents: 8237
diff changeset
2458 except ExpressionError as e:
741ea8a86012 fix: issue2551374. Error handling for filter expressions.
John Rouillard <rouilj@ieee.org>
parents: 8237
diff changeset
2459 self.add_error_message(str(e))
8253
cae1bbf2536b fix: issue2551374 - Add error handling for filter expressions. Fix UI
John Rouillard <rouilj@ieee.org>
parents: 8247
diff changeset
2460 self.template = "search"
8261
28c5030757d3 fix: cae1bbf2536b - expression errors not setting result properly
John Rouillard <rouilj@ieee.org>
parents: 8253
diff changeset
2461 result = self.renderContext()
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2462
7805
cc4b11ab2f22 fix: if Content-Type header defined, don't overwrite with default
John Rouillard <rouilj@ieee.org>
parents: 7614
diff changeset
2463 if 'Content-Type' not in self.additional_headers:
cc4b11ab2f22 fix: if Content-Type header defined, don't overwrite with default
John Rouillard <rouilj@ieee.org>
parents: 7614
diff changeset
2464 self.additional_headers['Content-Type'] = pt.content_type
2942
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
2465 if self.env.get('CGI_SHOW_TIMING', ''):
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
2466 if self.env['CGI_SHOW_TIMING'].upper() == 'COMMENT':
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
2467 timings = {'starttag': '<!-- ', 'endtag': ' -->'}
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
2468 else:
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
2469 timings = {'starttag': '<p>', 'endtag': '</p>'}
8189
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2470 timings['seconds'] = time.time() - self.start
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2471 s = self._(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2472 '%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n'
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2473 ) % timings
2237
f624fc20f8fe added capturing of stats
Richard Jones <richard@users.sourceforge.net>
parents: 2233
diff changeset
2474 if hasattr(self.db, 'stats'):
2942
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
2475 timings.update(self.db.stats)
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
2476 s += self._("%(starttag)sCache hits: %(cache_hits)d,"
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2477 " misses %(cache_misses)d."
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2478 " Loading items: %(get_items)f secs."
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2479 " Filtering: %(filtering)f secs."
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2480 "%(endtag)s\n") % timings
2237
f624fc20f8fe added capturing of stats
Richard Jones <richard@users.sourceforge.net>
parents: 2233
diff changeset
2481 s += '</body>'
2230
ca2664e095be disable forking server when os.fork() not available [SF#938586]
Richard Jones <richard@users.sourceforge.net>
parents: 2183
diff changeset
2482 result = result.replace('</body>', s)
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
2483 return result
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
2484 except templating.NoTemplate as message:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2485 self.response_code = 400
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2486 return '<strong>%s</strong>' % html_escape(str(message))
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
2487 except templating.Unauthorised as message:
5802
0e6d45413e88 catching last couple of cgi.escape references.
John Rouillard <rouilj@ieee.org>
parents: 5775
diff changeset
2488 raise Unauthorised(html_escape(str(message)))
6976
3917ae82fb24 flake8 - bare exceptions
John Rouillard <rouilj@ieee.org>
parents: 6975
diff changeset
2489 except Exception:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2490 # everything else
4045
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2491 if self.instance.config.WEB_DEBUG:
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2492 return cgitb.pt_html(i18n=self.translator)
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2493 exc_info = sys.exc_info()
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2494 try:
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2495 # If possible, send the HTML page template traceback
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2496 # to the administrator.
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2497 subject = "Templating Error: %s" % exc_info[1]
4543
d16d9bf655d8 - fix handling of traceback mails to the roundup admin
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4530
diff changeset
2498 self.send_error_to_admin(subject, cgitb.pt_html(), format_exc())
4045
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2499 # Now report the error to the user.
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
2500 return self._(default_err_msg)
6976
3917ae82fb24 flake8 - bare exceptions
John Rouillard <rouilj@ieee.org>
parents: 6975
diff changeset
2501 except Exception:
4045
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2502 # Reraise the original exception. The user will
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2503 # receive an error message, and the adminstrator will
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2504 # receive a traceback, albeit with less information
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
2505 # than the one we tried to generate above.
8554
92aecf6c5c09 bug: remove exec that re-raises exception for python 2 (hexora)
John Rouillard <rouilj@ieee.org>
parents: 8508
diff changeset
2506 raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2507
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2508 def renderError(self, error, response_code=400, use_template=True):
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2509 self.response_code = response_code
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2510
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2511 # see if error message already logged add if not
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2512 if error not in self._error_message:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2513 self.add_error_message(error, escape=True)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2514
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2515 # allow use of template for a specific code
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2516 trial_templates = []
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2517 if use_template:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2518 if response_code == 400:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2519 trial_templates = ["400"]
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2520 else:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2521 trial_templates = [str(response_code), "400"]
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2522
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2523 tplname = None
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2524 for rcode in trial_templates:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2525 try:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2526 tplname = self.selectTemplate(self.classname, rcode)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2527 break
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2528 except templating.NoTemplate:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2529 pass
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2530
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2531 if not tplname:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2532 # call string of serious error to get basic html
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2533 # response.
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2534 return str(SeriousError(error))
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2535
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2536 args = {
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2537 'ok_message': self._ok_message,
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
2538 'error_message': self._error_message,
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2539 }
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2540
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2541 try:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2542 pt = self.instance.templates.load(tplname)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2543 return pt.render(self, None, None, **args)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2544 except Exception:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2545 # report original error
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2546 return str(SeriousError(error))
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6550
diff changeset
2547
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2548 # these are the actions that are available
2904
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
2549 actions = (
8189
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2550 ('edit', actions.EditItemAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2551 ('editcsv', actions.EditCSVAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2552 ('new', actions.NewItemAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2553 ('register', actions.RegisterAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2554 ('confrego', actions.ConfRegoAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2555 ('passrst', actions.PassResetAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2556 ('login', actions.LoginAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2557 ('logout', actions.LogoutAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2558 ('search', actions.SearchAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2559 ('restore', actions.RestoreAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2560 ('retire', actions.RetireAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2561 ('show', actions.ShowAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2562 ('export_csv', actions.ExportCSVAction), # noqa: E241
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
2563 ('export_csv_id', actions.ExportCSVWithIdAction), # noqa: E241
8411
ef1ea918b07a feat(security): Add user confirmation/reauth for sensitive changes
John Rouillard <rouilj@ieee.org>
parents: 8408
diff changeset
2564 ('reauth', actions.ReauthAction), # noqa: E241
2904
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
2565 )
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2566
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2567 def handle_action(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2568 """ Determine whether there should be an Action called.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2569
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2570 The action is defined by the form variable :action which
1477
ed725179953d Added password reset facility for forgotten passwords.
Richard Jones <richard@users.sourceforge.net>
parents: 1472
diff changeset
2571 identifies the method on this object to call. The actions
2904
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
2572 are defined in the "actions" sequence on this class.
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
2573
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
2574 Actions may return a page (by default HTML) to return to the
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
2575 user, bypassing the usual template rendering.
3388
0c66acaea802 present Reject exception messages to web users [SF#1237685]
Richard Jones <richard@users.sourceforge.net>
parents: 3356
diff changeset
2576
0c66acaea802 present Reject exception messages to web users [SF#1237685]
Richard Jones <richard@users.sourceforge.net>
parents: 3356
diff changeset
2577 We explicitly catch Reject and ValueError exceptions and
0c66acaea802 present Reject exception messages to web users [SF#1237685]
Richard Jones <richard@users.sourceforge.net>
parents: 3356
diff changeset
2578 present their messages to the user.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
2579 """
4804
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2580 action = None
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2581 try:
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2582 if ':action' in self.form:
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2583 action = self.form[':action']
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2584 elif '@action' in self.form:
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2585 action = self.form['@action']
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2586 except TypeError:
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2587 pass
bc4144417861 More fixes for form TypeError
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4802
diff changeset
2588 if action is None:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2589 return None
2638
18e86941c950 Load up extensions in the tracker "extensions" directory.
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
2590
4367
fa5587802af9 Handle multiple @action values from broken trackers
Richard Jones <richard@users.sourceforge.net>
parents: 4362
diff changeset
2591 if isinstance(action, list):
7067
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
2592 raise SeriousError(
da58c2b28802 refactor: consolidate sets of identical log messages, flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 7059
diff changeset
2593 self._('broken form: multiple @action values submitted'))
8206
8656bd1cf1f1 chore(ruff): clean whitespace and remove unrecognized noqa directive.
John Rouillard <rouilj@ieee.org>
parents: 8203
diff changeset
2594
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2595 action = action.value.lower()
4367
fa5587802af9 Handle multiple @action values from broken trackers
Richard Jones <richard@users.sourceforge.net>
parents: 4362
diff changeset
2596
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2597 try:
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2598 action_klass = self.get_action_class(action)
2019
8fab5d394f22 Call actions in a different way so we won't hide any bad TypeErrors.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2018
diff changeset
2599
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2600 # call the mapped action
2019
8fab5d394f22 Call actions in a different way so we won't hide any bad TypeErrors.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2018
diff changeset
2601 if isinstance(action_klass, type('')):
8fab5d394f22 Call actions in a different way so we won't hide any bad TypeErrors.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2018
diff changeset
2602 # old way of specifying actions
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
2603 return getattr(self, action_klass)()
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2604
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2605 return action_klass(self).execute()
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
2606 except (ValueError, Reject) as err:
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4980
diff changeset
2607 escape = not isinstance(err, RejectRaw)
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4980
diff changeset
2608 self.add_error_message(str(err), escape=escape)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2609
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2610 def get_action_class(self, action_name):
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2611 if (hasattr(self.instance, 'cgi_actions') and
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2612 action_name in self.instance.cgi_actions):
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2613 # tracker-defined action
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2614 action_klass = self.instance.cgi_actions[action_name]
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2615 else:
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
2616 # go with a default, action_klass used after end of loop
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
2617 for name, action_klass in self.actions: # noqa: B007
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2618 if name == action_name:
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2619 break
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2620 else:
6975
fe4a6ba98bfe flake8 - remove unused imports, unused vars, whitespace fixes
John Rouillard <rouilj@ieee.org>
parents: 6974
diff changeset
2621 raise ValueError('No such action "%s"' %
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2622 html_escape(action_name))
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2623 return action_klass
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
2624
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2625 def _socket_op(self, call, *args, **kwargs):
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2626 """Execute socket-related operation, catch common network errors
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2627
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2628 Parameters:
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2629 call: a callable to execute
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2630 args, kwargs: call arguments
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2631
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2632 """
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2633 try:
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2634 call(*args, **kwargs)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
2635 except socket.error as err:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2636 err_errno = getattr(err, 'errno', None)
3808
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
2637 if err_errno is None:
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
2638 try:
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
2639 err_errno = err[0]
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
2640 except TypeError:
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
2641 pass
3807
c27aafab067d Band-aid over handling of netework errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3800
diff changeset
2642 if err_errno not in self.IGNORE_NET_ERRORS:
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2643 raise
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2644 except IOError:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2645 # Apache's mod_python will raise IOError -- without an
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2646 # accompanying errno -- when a write to the client fails.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2647 # A common case is that the client has closed the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2648 # connection. There's no way to be certain that this is
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2649 # the situation that has occurred here, but that is the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2650 # most likely case.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2651 pass
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2652
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2653 def determine_content_encoding(self, list_all=False, precompressed=False):
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2654
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2655 encoding_list = []
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2656
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2657 # FIXME: Should parse for q= values and properly order
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2658 # the request encodings. Also should handle identity coding.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2659 # Then return first acceptable by q value.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2660 # This code always uses order: zstd, br, gzip. It will send identity
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2661 # even if identity excluded rather than returning 406.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2662 accept_encoding = self.request.headers.get('accept-encoding') or []
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2663
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2664 if accept_encoding:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2665 for enc in ['zstd', 'br', 'gzip']:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2666 if ((enc in self.compressors) or precompressed) and \
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2667 (enc in accept_encoding):
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2668 if not list_all:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2669 return enc
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2670
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2671 encoding_list.append(enc)
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2672
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2673 # Return value must evaluate to false in boolean context if no
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2674 # acceptable encoding is found. If an (non-identity) encoding
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2675 # is found the Vary header will include accept-encoding.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2676 # What to return if the identity encoding is unacceptable?
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2677 # Maybe raise a 406 from here?
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2678 if not list_all:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2679 return None
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8202
diff changeset
2680 return encoding_list
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2681
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2682 def setVary(self, header):
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2683 '''Vary header will include the new header. This will append
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2684 if Vary exists.'''
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2685
8202
276164647db5 chore(ruff): clean trailing whitespace
John Rouillard <rouilj@ieee.org>
parents: 8200
diff changeset
2686 if ('Vary' in self.additional_headers and
8019
16cc72cd9c17 fix: Send Vary: Accept-Encoding on any data that could be compressed
John Rouillard <rouilj@ieee.org>
parents: 8018
diff changeset
2687 header not in self.additional_headers['Vary']):
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2688 self.additional_headers['Vary'] += ", %s" % header
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2689 else:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2690 self.additional_headers['Vary'] = header
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2691
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2692 def compress_encode(self, byte_content, quality=4):
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2693
6467
679ec82798e9 Fix typo referencing config.
John Rouillard <rouilj@ieee.org>
parents: 6458
diff changeset
2694 if not self.instance.config.WEB_DYNAMIC_COMPRESSION:
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2695 # dynamic compression disabled.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2696 return byte_content
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2697
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2698 # don't compress small content
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2699 if len(byte_content) < 100:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2700 return byte_content
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2701
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2702 # abort if already encoded (e.g. served from
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2703 # precompressed file or cache on disk)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2704 if ('Content-Encoding' in self.additional_headers):
8019
16cc72cd9c17 fix: Send Vary: Accept-Encoding on any data that could be compressed
John Rouillard <rouilj@ieee.org>
parents: 8018
diff changeset
2705 # Vary: 'Accept-Encoding' is set when Content-encoding set
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2706 return byte_content
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2707
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2708 # abort if file-type already compressed
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2709 if ('Content-Type' in self.additional_headers) and \
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2710 (self.additional_headers['Content-Type'] in
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2711 self.precompressed_mime_types):
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2712 return byte_content
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2713
8019
16cc72cd9c17 fix: Send Vary: Accept-Encoding on any data that could be compressed
John Rouillard <rouilj@ieee.org>
parents: 8018
diff changeset
2714 self.setVary('Accept-Encoding')
16cc72cd9c17 fix: Send Vary: Accept-Encoding on any data that could be compressed
John Rouillard <rouilj@ieee.org>
parents: 8018
diff changeset
2715
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2716 encoder = None
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2717 # return same content if unable to compress
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2718 new_content = byte_content
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2719
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2720 encoder = self.determine_content_encoding()
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2721
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2722 if encoder == 'zstd':
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2723 new_content = self.zstd.ZSTD_compress(byte_content, 3)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2724 elif encoder == 'br':
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2725 # lgblock=0 sets value from quality
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2726 new_content = self.brotli.compress(byte_content,
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2727 quality=quality,
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2728 mode=1,
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2729 lgblock=0)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2730 elif encoder == 'gzip':
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2731 try:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2732 new_content = self.gzip.compress(byte_content, compresslevel=5)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2733 except AttributeError:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2734 try:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2735 from StringIO import cStringIO as IOBuff
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2736 except ImportError:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2737 # python 3
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2738 # however this code should not be needed under python3
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2739 # since py3 gzip library has compress() method.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2740 from io import BytesIO as IOBuff
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2741
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2742 out = IOBuff()
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2743 # handle under python2
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2744 f = self.gzip.GzipFile(fileobj=out, mode='w', compresslevel=5)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2745 f.write(byte_content)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2746 f.close()
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2747 new_content = out.getvalue()
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2748
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2749 if encoder:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2750 # we changed the data, change existing content-length header
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2751 # and add Content-Encoding and Vary header.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2752 self.additional_headers['Content-Length'] = str(len(new_content))
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2753 self.additional_headers['Content-Encoding'] = encoder
6539
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2754 try:
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2755 current_etag = self.additional_headers['ETag']
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2756 except KeyError:
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2757 pass # etag not set for non-rest endpoints
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2758 else:
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2759 etag_end = current_etag.rindex('"')
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2760 self.additional_headers['ETag'] = (
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2761 current_etag[:etag_end] +
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2762 '-' + encoder + current_etag[etag_end:])
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2763
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2764 return new_content
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2765
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2766 def write(self, content):
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2767 if not self.headers_done and self.env['REQUEST_METHOD'] != 'HEAD':
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2768 # compress_encode modifies headers, must run before self.header()
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2769 content = self.compress_encode(bs2b(content))
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2770
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2771 if not self.headers_done:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2772 self.header()
2592
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
2773 if self.env['REQUEST_METHOD'] != 'HEAD':
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2774 self._socket_op(self.request.wfile.write, content)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2775
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
2776 def write_html(self, content):
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2777 if sys.version_info[0] > 2:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2778 # An action setting appropriate headers for a non-HTML
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2779 # response may return a bytes object directly.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2780 if not isinstance(content, bytes):
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2781 content = content.encode(self.charset, 'xmlcharrefreplace')
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2782 elif self.charset != self.STORAGE_CHARSET:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2783 # recode output
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2784 content = content.decode(self.STORAGE_CHARSET, 'replace')
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2785 content = content.encode(self.charset, 'xmlcharrefreplace')
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2786
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2787 if self.env['REQUEST_METHOD'] != 'HEAD' and not self.headers_done:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2788 # compress_encode modifies headers, must run before self.header()
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2789 content = self.compress_encode(bs2b(content))
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2790
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
2791 if not self.headers_done:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
2792 # at this point, we are sure about Content-Type
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2793 if 'Content-Type' not in self.additional_headers:
3867
2563ddf71cd7 Enabled over-riding of content-type in web interface (thanks John Mitchell)
Richard Jones <richard@users.sourceforge.net>
parents: 3808
diff changeset
2794 self.additional_headers['Content-Type'] = \
2563ddf71cd7 Enabled over-riding of content-type in web interface (thanks John Mitchell)
Richard Jones <richard@users.sourceforge.net>
parents: 3808
diff changeset
2795 'text/html; charset=%s' % self.charset
6509
1fc765ef6379 Fix 204 responses, hangs and crashes with REST.
John Rouillard <rouilj@ieee.org>
parents: 6504
diff changeset
2796 if 'Content-Length' not in self.additional_headers:
6550
15ae655c2014 header values should always be strings (at least "flup" cares)
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6548
diff changeset
2797 self.additional_headers['Content-Length'] = str(len(content))
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
2798 self.header()
2592
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
2799
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
2800 if self.env['REQUEST_METHOD'] == 'HEAD':
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
2801 # client doesn't care about content
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
2802 return
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
2803
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
2804 # and write
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
2805 self._socket_op(self.request.wfile.write, content)
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
2806
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2807 def http_strip(self, content):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2808 """Remove HTTP Linear White Space from 'content'.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2809
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2810 'content' -- A string.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2811
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2812 returns -- 'content', with all leading and trailing LWS
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2813 removed."""
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2814
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2815 # RFC 2616 2.2: Basic Rules
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2816 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2817 # LWS = [CRLF] 1*( SP | HT )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2818 return content.strip(" \r\n\t")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2819
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2820 def http_split(self, content):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2821 """Split an HTTP list.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2822
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2823 'content' -- A string, giving a list of items.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2824
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2825 returns -- A sequence of strings, containing the elements of
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2826 the list."""
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2827
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2828 # RFC 2616 2.1: Augmented BNF
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2829 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2830 # Grammar productions of the form "#rule" indicate a
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2831 # comma-separated list of elements matching "rule". LWS
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2832 # is then removed from each element, and empty elements
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2833 # removed.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2834
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2835 # Split at commas.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2836 elements = content.split(",")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2837 # Remove linear whitespace at either end of the string.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2838 elements = [self.http_strip(e) for e in elements]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2839 # Remove any now-empty elements.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2840 return [e for e in elements if e]
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
2841
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2842 def handle_range_header(self, length, etag):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2843 """Handle the 'Range' and 'If-Range' headers.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2844
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2845 'length' -- the length of the content available for the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2846 resource.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2847
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2848 'etag' -- the entity tag for this resources.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2849
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2850 returns -- If the request headers (including 'Range' and
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2851 'If-Range') indicate that only a portion of the entity should
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2852 be returned, then the return value is a pair '(offfset,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2853 length)' indicating the first byte and number of bytes of the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2854 content that should be returned to the client. In addition,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2855 this method will set 'self.response_code' to indicate Partial
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2856 Content. In all other cases, the return value is 'None'. If
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2857 appropriate, 'self.response_code' will be
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2858 set to indicate 'REQUESTED_RANGE_NOT_SATISFIABLE'. In that
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2859 case, the caller should not send any data to the client."""
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2860
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2861 # RFC 2616 14.35: Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2862 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2863 # See if the Range header is present.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2864 ranges_specifier = self.env.get("HTTP_RANGE")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2865 if ranges_specifier is None:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2866 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2867 # RFC 2616 14.27: If-Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2868 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2869 # Check to see if there is an If-Range header.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2870 # Because the specification says:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2871 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2872 # The If-Range header ... MUST be ignored if the request
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2873 # does not include a Range header, we check for If-Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2874 # after checking for Range.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2875 if_range = self.env.get("HTTP_IF_RANGE")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2876 if if_range:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2877 # The grammar for the If-Range header is:
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
2878 #
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2879 # If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2880 # entity-tag = [ weak ] opaque-tag
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2881 # weak = "W/"
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2882 # opaque-tag = quoted-string
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2883 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2884 # We only support strong entity tags.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2885 if_range = self.http_strip(if_range)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2886 if (not if_range.startswith('"')
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2887 or not if_range.endswith('"')):
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2888 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2889 # If the condition doesn't match the entity tag, then we
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2890 # must send the client the entire file.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2891 if if_range != etag:
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
2892 return None
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2893 # The grammar for the Range header value is:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2894 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2895 # ranges-specifier = byte-ranges-specifier
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2896 # byte-ranges-specifier = bytes-unit "=" byte-range-set
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2897 # byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2898 # byte-range-spec = first-byte-pos "-" [last-byte-pos]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2899 # first-byte-pos = 1*DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2900 # last-byte-pos = 1*DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2901 # suffix-byte-range-spec = "-" suffix-length
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2902 # suffix-length = 1*DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2903 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2904 # Look for the "=" separating the units from the range set.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2905 specs = ranges_specifier.split("=", 1)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2906 if len(specs) != 2:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2907 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2908 # Check that the bytes-unit is in fact "bytes". If it is not,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2909 # we do not know how to process this range.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2910 bytes_unit = self.http_strip(specs[0])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2911 if bytes_unit != "bytes":
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2912 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2913 # Seperate the range-set into range-specs.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2914 byte_range_set = self.http_strip(specs[1])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2915 byte_range_specs = self.http_split(byte_range_set)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2916 # We only handle exactly one range at this time.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2917 if len(byte_range_specs) != 1:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2918 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2919 # Parse the spec.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2920 byte_range_spec = byte_range_specs[0]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2921 pos = byte_range_spec.split("-", 1)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2922 if len(pos) != 2:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2923 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2924 # Get the first and last bytes.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2925 first = self.http_strip(pos[0])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2926 last = self.http_strip(pos[1])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2927 # We do not handle suffix ranges.
6977
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2928 # Note this also captures atempts to make first
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2929 # element of range a negative number.
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2930 if not first:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2931 return None
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
2932 # Convert the first and last positions to integers.
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2933 try:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2934 first = int(first)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2935 if last:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2936 last = int(last)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2937 else:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2938 last = length - 1
6976
3917ae82fb24 flake8 - bare exceptions
John Rouillard <rouilj@ieee.org>
parents: 6975
diff changeset
2939 except ValueError:
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2940 # The positions could not be parsed as integers.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2941 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2942 # Check that the range makes sense.
6977
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2943 # Note, if range is -1-10, first = '', so this code will never
ff2c8b430738 flake8 - remove re.compile from method arg + test + doc
John Rouillard <rouilj@ieee.org>
parents: 6976
diff changeset
2944 # be reached. if range = 1--10, this code is reached.
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2945 if (first < 0 or last < 0 or last < first):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2946 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2947 if last >= length:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2948 # RFC 2616 10.4.17: 416 Requested Range Not Satisfiable
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2949 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2950 # If there is an If-Range header, RFC 2616 says that we
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2951 # should just ignore the invalid Range header.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2952 if if_range:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2953 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2954 # Return code 416 with a Content-Range header giving the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2955 # allowable range.
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2956 self.response_code = http_.client.REQUESTED_RANGE_NOT_SATISFIABLE
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2957 self.setHeader("Content-Range", "bytes */%d" % length)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2958 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2959 # RFC 2616 10.2.7: 206 Partial Content
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2960 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2961 # Tell the client that we are honoring the Range request by
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2962 # indicating that we are providing partial content.
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
2963 self.response_code = http_.client.PARTIAL_CONTENT
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2964 # RFC 2616 14.16: Content-Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2965 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2966 # Tell the client what data we are providing.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2967 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2968 # content-range-spec = byte-content-range-spec
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2969 # byte-content-range-spec = bytes-unit SP
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2970 # byte-range-resp-spec "/"
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2971 # ( instance-length | "*" )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2972 # byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2973 # | "*"
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2974 # instance-length = 1 * DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2975 self.setHeader("Content-Range",
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2976 "bytes %d-%d/%d" % (first, last, length))
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2977 return (first, last - first + 1)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2978
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2979 def write_file(self, filename):
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2980 """Send the contents of 'filename' to the user.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2981 Send an acceptable pre-compressed version of the
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2982 file if it is newer than the uncompressed version.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2983 """
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2984
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2985 # Assume we will return the entire file.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2986 offset = 0
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2987
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2988 # initalize length from uncompressed file
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2989 stat_info = os.stat(filename)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
2990 length = stat_info[stat.ST_SIZE]
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2991
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2992 # Determine if we are sending a range. If so, compress
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2993 # on the fly. Otherwise see if we have a suitable
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2994 # pre-compressed/encoded file we can send.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2995 if not self.env.get("HTTP_RANGE"):
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2996 # no range, search for file in list ordered
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2997 # from best to worst alternative
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2998 encoding_list = self.determine_content_encoding(list_all=True,
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
2999 precompressed=True)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3000 if encoding_list and self.db.config.WEB_USE_PRECOMPRESSED_FILES:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3001 # do we need to search through list? If best is not
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3002 # precompressed, on the fly compress with best?
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3003 # by searching list we will respond with precompressed
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3004 # 2nd best or worse.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3005 for encoder in encoding_list:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3006 try:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3007 trial_filename = '%s.%s' % (filename, encoder)
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3008 trial_stat_info = os.stat(trial_filename)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3009 if stat_info[stat.ST_MTIME] > \
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3010 trial_stat_info[stat.ST_MTIME]:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3011 # compressed file is obsolete
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3012 # don't use it
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3013 logger.warning(self._(
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3014 "Cache failure: "
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3015 "compressed file %(compressed)s is "
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3016 "older than its source file "
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3017 "%(filename)s" % {
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3018 'filename': filename,
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3019 'compressed': trial_filename}))
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3020
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3021 continue
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3022 filename = trial_filename
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3023 length = trial_stat_info[stat.ST_SIZE]
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3024 self.setHeader('Content-Encoding', encoder)
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3025 self.setVary('Accept-Encoding')
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3026 break
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3027 # except FileNotFoundError: py2/py3
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3028 # compatible version
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3029 except EnvironmentError as e:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3030 if e.errno != errno.ENOENT:
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3031 raise
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3032
4648
e645820e8556 Clean up whitespace in client.py
Ezio Melotti <ezio.melotti@gmail.com>
parents: 4640
diff changeset
3033 # If the headers have not already been finalized,
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3034 if not self.headers_done:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3035 # RFC 2616 14.19: ETag
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3036 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3037 # Compute the entity tag, in a format similar to that
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3038 # used by Apache.
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3039 #
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3040 # Tag does *not* change with Content-Encoding.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3041 # Header 'Vary: Accept-Encoding' is returned with response.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3042 # RFC2616 section 13.32 discusses etag and references
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3043 # section 14.44 (Vary header) as being applicable to etag.
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3044 # Hence the intermediate proxy should/must match
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3045 # Accept-Encoding and ETag to determine whether to return
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3046 # a 304 or report cache miss and fetch from origin server.
8020
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3047 #
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3048 # RFC 9110 8.8.3.3 shows a different strong entity tag
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3049 # generated for gzip and non gzip replies.
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3050 etag = '"%x-%x-%x"' % (stat_info[stat.ST_INO],
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3051 length,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3052 stat_info[stat.ST_MTIME])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3053 self.setHeader("ETag", etag)
8020
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3054
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3055 inm = self.request.headers.get('If-None-Match')
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3056 if (inm):
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3057 inm_etags = inm.split(',')
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3058 inm_etags = [tag.strip() for tag in inm_etags]
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3059 if etag in inm_etags:
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3060 self.setHeader('ETag', etag)
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3061 self.setVary('Accept-Encoding')
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3062 raise NotModified
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3063
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3064 # need to check for etag-compression_code:
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3065 # a41932-8b5-664ce93d-zstd or a41932-8b5-664ce93d-gzip
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3066 tag_prefix = etag[:-1] + '-'
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3067 for inm_etag in inm_etags:
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3068 if inm_etag.startswith(tag_prefix):
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3069 self.setHeader('ETag', inm_etag)
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3070 self.setVary('Accept-Encoding')
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3071 raise NotModified
60c98a8a23bd fix: make If-None-Match work for static file (@@file) case
John Rouillard <rouilj@ieee.org>
parents: 8019
diff changeset
3072
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3073 # RFC 2616 14.5: Accept-Ranges
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3074 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3075 # Let the client know that we will accept range requests.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3076 self.setHeader("Accept-Ranges", "bytes")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3077 # RFC 2616 14.35: Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3078 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3079 # If there is a Range header, we may be able to avoid
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3080 # sending the entire file.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3081 content_range = self.handle_range_header(length, etag)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3082 if content_range:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3083 offset, length = content_range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3084 # RFC 2616 14.13: Content-Length
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3085 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3086 # Tell the client how much data we are providing.
4145
c15fcee3d8a1 Fix issue2550552.
Stefan Seefeld <stefan@seefeld.name>
parents: 4114
diff changeset
3087 self.setHeader("Content-Length", str(length))
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3088 # If the client doesn't actually want the body, or if we are
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3089 # indicating an invalid range.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3090 if (self.env['REQUEST_METHOD'] == 'HEAD'
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3091 or self.response_code ==
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3092 http_.client.REQUESTED_RANGE_NOT_SATISFIABLE):
6656
b83b90d57846 Fix header value. needs to be string not integer.
John Rouillard <rouilj@ieee.org>
parents: 6649
diff changeset
3093 self.setHeader("Content-Length", "0")
6649
33616bc80baf Fix hang in unsatisfyable range or HEAD request for static file
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
3094 self.header()
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3095 return
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3096 # Use the optimized "sendfile" operation, if possible.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3097 if hasattr(self.request, "sendfile"):
6458
8f1b91756457 issue2551147 - Enable compression of http responses in roundup.
John Rouillard <rouilj@ieee.org>
parents: 6447
diff changeset
3098 self.header()
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3099 self._socket_op(self.request.sendfile, filename, offset, length)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3100 return
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3101 # Fallback to the "write" operation.
7814
9adf37c63b56 chore(refactor): use with open, consolidate/un-nest if ...
John Rouillard <rouilj@ieee.org>
parents: 7813
diff changeset
3102 with open(filename, 'rb') as f:
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3103 if offset:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3104 f.seek(offset)
4077
7d19ed05baa6 Fix issue2550517
Stefan Seefeld <stefan@seefeld.name>
parents: 4065
diff changeset
3105 content = f.read(length)
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
3106 self.write(content)
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
3107
2046
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
3108 def setHeader(self, header, value):
6544
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6539
diff changeset
3109 """Override or delete a header to be returned to the user's browser.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
3110 """
6544
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6539
diff changeset
3111 if value is None:
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6539
diff changeset
3112 try:
7571
f8b07ffd0226 flake8: add space between return, del and (
John Rouillard <rouilj@ieee.org>
parents: 7556
diff changeset
3113 del (self.additional_headers[header])
6544
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6539
diff changeset
3114 except KeyError:
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6539
diff changeset
3115 pass
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6539
diff changeset
3116 else:
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6539
diff changeset
3117 self.additional_headers[header] = value
2046
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
3118
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
3119 def header(self, headers=None, response=None):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
3120 """Put up the appropriate header.
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
3121 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3122 if headers is None:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3123 headers = {'Content-Type': 'text/html; charset=utf-8'}
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
3124 if response is None:
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
3125 response = self.response_code
1130
89bd02ffe4af tell clients/caches not to cache our dynamic bits
Richard Jones <richard@users.sourceforge.net>
parents: 1129
diff changeset
3126
89bd02ffe4af tell clients/caches not to cache our dynamic bits
Richard Jones <richard@users.sourceforge.net>
parents: 1129
diff changeset
3127 # update with additional info
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
3128 headers.update(self.additional_headers)
1130
89bd02ffe4af tell clients/caches not to cache our dynamic bits
Richard Jones <richard@users.sourceforge.net>
parents: 1129
diff changeset
3129
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
3130 if headers.get('Content-Type', 'text/html') == 'text/html':
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
3131 headers['Content-Type'] = 'text/html; charset=utf-8'
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
3132
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3133 if response in [204, 304]: # has no body so no content-type
7571
f8b07ffd0226 flake8: add space between return, del and (
John Rouillard <rouilj@ieee.org>
parents: 7556
diff changeset
3134 del (headers['Content-Type'])
6509
1fc765ef6379 Fix 204 responses, hangs and crashes with REST.
John Rouillard <rouilj@ieee.org>
parents: 6504
diff changeset
3135
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4344
diff changeset
3136 headers = list(headers.items())
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
3137
5395
23b8e6067f7c Python 3 preparation: update calls to dict methods.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
3138 for ((path, name), (value, expire)) in self._cookies.items():
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3139 cookie = "%s=%s; Path=%s;" % (name, value, path)
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
3140 if expire is not None:
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3141 cookie += " expires=%s;" % get_cookie_date(expire)
4586
b21bb66de6ff Mark cookies HttpOnly and -- if https is used -- secure.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4578
diff changeset
3142 # mark as secure if https, see issue2550689
b21bb66de6ff Mark cookies HttpOnly and -- if https is used -- secure.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4578
diff changeset
3143 if self.secure:
b21bb66de6ff Mark cookies HttpOnly and -- if https is used -- secure.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4578
diff changeset
3144 cookie += " secure;"
5212
d4cc71beb102 Added support for SameSite cookie option for CSRF prevention
John Rouillard <rouilj@ieee.org>
parents: 5211
diff changeset
3145 ssc = self.db.config['WEB_SAMESITE_COOKIE_SETTING']
d4cc71beb102 Added support for SameSite cookie option for CSRF prevention
John Rouillard <rouilj@ieee.org>
parents: 5211
diff changeset
3146 if ssc != "None":
6974
178c80c77ca4 flake8 whitespace fixes plus X == True -> X is True
John Rouillard <rouilj@ieee.org>
parents: 6897
diff changeset
3147 cookie += " SameSite=%s;" % ssc
4586
b21bb66de6ff Mark cookies HttpOnly and -- if https is used -- secure.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4578
diff changeset
3148 # prevent theft of session cookie, see issue2550689
b21bb66de6ff Mark cookies HttpOnly and -- if https is used -- secure.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4578
diff changeset
3149 cookie += " HttpOnly;"
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
3150 headers.append(('Set-Cookie', cookie))
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
3151
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
3152 self._socket_op(self.request.start_response, headers, response)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
3153
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3154 self.headers_done = 1
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3155 if self.debug:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3156 self.headers_sent = headers
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3157
8189
04c10e2189a5 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8187
diff changeset
3158 def add_cookie(self, name, value, expire=86400 * 365, path=None):
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3159 """Set a cookie value to be sent in HTTP headers
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3160
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3161 Parameters:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3162 name:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3163 cookie name
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3164 value:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3165 cookie value
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3166 expire:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3167 cookie expiration time (seconds).
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3168 If value is empty (meaning "delete cookie"),
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3169 expiration time is forced in the past
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3170 and this argument is ignored.
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
3171 If None, the cookie will expire at end-of-session.
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3172 If omitted, the cookie will be kept for a year.
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3173 path:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3174 cookie path (optional)
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3175
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3176 """
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3177 if path is None:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3178 path = self.cookie_path
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3179 if not value:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3180 expire = -1
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
3181 self._cookies[(path, name)] = (value, expire)
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
3182
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3183 def make_user_anonymous(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
3184 """ Make us anonymous
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3185
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3186 This method used to handle non-existence of the 'anonymous'
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3187 user, but that user is mandatory now.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
3188 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3189 self.userid = self.db.user.lookup('anonymous')
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3190 self.user = 'anonymous'
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3191
1801
9f9d35f3d8f7 Change the message asking for confirmation of registration...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1799
diff changeset
3192 def standard_message(self, to, subject, body, author=None):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
3193 """Send a standard email message from Roundup.
2248
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3194
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3195 "to" - recipients list
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3196 "subject" - Subject
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3197 "body" - Message
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3198 "author" - (name, address) tuple or None for admin email
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3199
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3200 Arguments are passed to the Mailer.standard_message code.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
3201 """
1799
071ea6fc803f Extracted duplicated mail-sending code...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1798
diff changeset
3202 try:
1801
9f9d35f3d8f7 Change the message asking for confirmation of registration...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1799
diff changeset
3203 self.mailer.standard_message(to, subject, body, author)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5231
diff changeset
3204 except MessageSendError as e:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4851
diff changeset
3205 self.add_error_message(str(e))
2248
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3206 return 0
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
3207 return 1
1467
378081f066cc registration is now a two-step process with confirmation from the
Richard Jones <richard@users.sourceforge.net>
parents: 1456
diff changeset
3208
2107
b7404a96b58a minor pre-release / test fixes
Richard Jones <richard@users.sourceforge.net>
parents: 2082
diff changeset
3209 def parsePropsFromForm(self, create=0):
2010
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
3210 return FormParser(self).parse(create=create)
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
3211
2799
9605965569b0 disallow caching of pages with error and/or ok messages.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2724
diff changeset
3212 # vim: set et sts=4 sw=4 :

Roundup Issue Tracker: http://roundup-tracker.org/