annotate roundup/cgi/actions.py @ 8408:e882a5d52ae5

refactor: move RateLimitExceeded to roundup.cgi.exceptions RateLimitExceeded is an HTTP exception that raises code 429. Move it to roundup.cgi.exceptions where all the other exceptions that result in http status codes are located. Also make it inherit from HTTPException since it is one. Also add docstrings for all HTTP exceptions and order HTTPExceptions by status code. BREAKING CHANGE: if somebody is importing RateLimitExceeded they will need to change their import. I consider it unlikely anybody is using RateLimitExceeded. Detectors and extensions are unlikely to raise RateLimitExceeded. So I am leaving it out of the upgrading doc. Just doc in change log.
author John Rouillard <rouilj@ieee.org>
date Sun, 10 Aug 2025 21:27:06 -0400
parents a81a3cd067fa
children ef1ea918b07a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1 import codecs
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
2 import csv
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
3 import re
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
4 import sys
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
5 from datetime import timedelta
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
6
7178
db06d4aeb978 unshadow stdlib token from roundup's token.
John Rouillard <rouilj@ieee.org>
parents: 7165
diff changeset
7 from roundup import hyperdb, token_r, date, password
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
8 from roundup.actions import Action as BaseAction
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
9 from roundup.anypy import urllib_
7582
978285986b2c fix: issue2551193 - Fix roundup for removal of cgi and cgitb ...
John Rouillard <rouilj@ieee.org>
parents: 7556
diff changeset
10 from roundup.anypy.cgi_ import cgi
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
11 from roundup.anypy.html import html_escape
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
12 from roundup.anypy.strings import StringIO
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
13 from roundup.cgi import exceptions, templating
8408
e882a5d52ae5 refactor: move RateLimitExceeded to roundup.cgi.exceptions
John Rouillard <rouilj@ieee.org>
parents: 8305
diff changeset
14 from roundup.cgi.exceptions import RateLimitExceeded
5973
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
15 from roundup.cgi.timestamp import Timestamped
8408
e882a5d52ae5 refactor: move RateLimitExceeded to roundup.cgi.exceptions
John Rouillard <rouilj@ieee.org>
parents: 8305
diff changeset
16 from roundup.exceptions import Reject, RejectRaw
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
17 from roundup.i18n import _
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
18 from roundup.mailgw import uidFromAddress
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
19 from roundup.rate_limit import Gcra, RateLimit
5717
cad18de2b988 issue2550949: Rate limit password guesses/login attempts.
John Rouillard <rouilj@ieee.org>
parents: 5652
diff changeset
20
5119
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
21 # Also add action to client.py::Client.actions property
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
22 __all__ = ['Action', 'ShowAction', 'RetireAction', 'RestoreAction',
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
23 'SearchAction',
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
24 'EditCSVAction', 'EditItemAction', 'PassResetAction',
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
25 'ConfRegoAction', 'RegisterAction', 'LoginAction', 'LogoutAction',
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
26 'NewItemAction', 'ExportCSVAction', 'ExportCSVWithIdAction']
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
27
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
28
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
29 class Action:
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
30 loginLimit = None
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
31
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
32 def __init__(self, client):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
33 self.client = client
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
34 self.form = client.form
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
35 self.db = client.db
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
36 self.nodeid = client.nodeid
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
37 self.template = client.template
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
38 self.classname = client.classname
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
39 self.userid = client.userid
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
40 self.base = client.base
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
41 self.user = client.user
2391
3a0a248289dd action objects got 'context' attribute containing dictionary...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2372
diff changeset
42 self.context = templating.context(client)
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
43
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
44 def handle(self):
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
45 """Action handler procedure"""
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
46 raise NotImplementedError
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
47
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
48 def execute(self):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
49 """Execute the action specified by this object."""
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
50 self.permission()
2163
791c66a3b738 fixed CSV export and CGI actions returning results
Richard Jones <richard@users.sourceforge.net>
parents: 2160
diff changeset
51 return self.handle()
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
52
5162
3ee79a2d95d4 rename clean_url method to examine_url. the method doesn't realy clean anything, it throws a ValueError if it finds a problem
John Rouillard <rouilj@ieee.org>
parents: 5161
diff changeset
53 def examine_url(self, url):
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
54 '''Return URL validated to be under self.base and properly escaped
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
55
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
56 If url not properly escaped or validation fails raise ValueError.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
57
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
58 To try to prevent XSS attacks, validate that the url that is
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
59 passed in is under self.base for the tracker. This is used to
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
60 clean up "__came_from" and "__redirect_to" form variables used
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
61 by the LoginAction and NewItemAction actions.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
62
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
63 The url that is passed in must be a properly url quoted
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
64 argument. I.E. all characters that are not valid according to
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
65 RFC3986 must be % encoded. Schema should be lower case.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
66
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
67 It parses the passed url into components.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
68
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
69 It verifies that the scheme is http or https (so a redirect can
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
70 force https even if normal access to the tracker is via http).
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
71 Validates that the network component is the same as in self.base.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
72 Validates that the path component in the base url starts the url's
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
73 path component. It not it raises ValueError. If everything
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
74 validates:
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
75
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
76 For each component, Appendix A of RFC 3986 says the following
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
77 are allowed:
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
78
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
79 pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
80 query = *( pchar / "/" / "?" )
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
81 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
82 pct-encoded = "%" HEXDIG HEXDIG
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
83 sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
84 / "*" / "+" / "," / ";" / "="
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
85
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
86 Checks all parts with a regexp that matches any run of 0 or
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
87 more allowed characters. If the component doesn't validate,
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
88 raise ValueError. Don't attempt to urllib_.quote it. Either
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
89 it's correct as it comes in or it's a ValueError.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
90
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
91 Finally paste the whole thing together and return the new url.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
92 '''
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
93
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
94 parsed_url_tuple = urllib_.urlparse(url)
5164
114d9628fd77 Fixed a couple of failing tests for *LoginRedirect in test_actions.py after url validation. Also raise ValueError from examine_url if base url is None.
John Rouillard <rouilj@ieee.org>
parents: 5162
diff changeset
95 if self.base:
114d9628fd77 Fixed a couple of failing tests for *LoginRedirect in test_actions.py after url validation. Also raise ValueError from examine_url if base url is None.
John Rouillard <rouilj@ieee.org>
parents: 5162
diff changeset
96 parsed_base_url_tuple = urllib_.urlparse(self.base)
114d9628fd77 Fixed a couple of failing tests for *LoginRedirect in test_actions.py after url validation. Also raise ValueError from examine_url if base url is None.
John Rouillard <rouilj@ieee.org>
parents: 5162
diff changeset
97 else:
114d9628fd77 Fixed a couple of failing tests for *LoginRedirect in test_actions.py after url validation. Also raise ValueError from examine_url if base url is None.
John Rouillard <rouilj@ieee.org>
parents: 5162
diff changeset
98 raise ValueError(self._("Base url not set. Check configuration."))
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
99
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
100 info = {'url': url,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
101 'base_url': self.base,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
102 'base_scheme': parsed_base_url_tuple.scheme,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
103 'base_netloc': parsed_base_url_tuple.netloc,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
104 'base_path': parsed_base_url_tuple.path,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
105 'url_scheme': parsed_url_tuple.scheme,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
106 'url_netloc': parsed_url_tuple.netloc,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
107 'url_path': parsed_url_tuple.path,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
108 'url_params': parsed_url_tuple.params,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
109 'url_query': parsed_url_tuple.query,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
110 'url_fragment': parsed_url_tuple.fragment}
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
111
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
112 if parsed_base_url_tuple.scheme == "https":
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
113 if parsed_url_tuple.scheme != "https":
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
114 raise ValueError(self._("Base url %(base_url)s requires https."
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
115 " Redirect url %(url)s uses http.") %
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
116 info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
117 else:
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
118 if parsed_url_tuple.scheme not in ('http', 'https'):
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
119 raise ValueError(self._("Unrecognized scheme in %(url)s") %
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
120 info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
121
5382
1556b39fde7c Python 3 preparation: use != instead of <>.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
122 if parsed_url_tuple.netloc != parsed_base_url_tuple.netloc:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
123 raise ValueError(self._("Net location in %(url)s does not match "
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
124 "base: %(base_netloc)s") % info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
125
5382
1556b39fde7c Python 3 preparation: use != instead of <>.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
126 if parsed_url_tuple.path.find(parsed_base_url_tuple.path) != 0:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
127 raise ValueError(self._("Base path %(base_path)s is not a "
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
128 "prefix for url %(url)s") % info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
129
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
130 # I am not sure if this has to be language sensitive.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
131 # Do ranges depend on the LANG of the user??
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
132 # Is there a newer spec for URI's than what I am referencing?
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
133
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
134 # Also it really should be % HEXDIG HEXDIG that's allowed
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
135 # If %%% passes, the roundup server should be able to ignore/
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
136 # quote it so it doesn't do anything bad otherwise we have a
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
137 # different vector to handle.
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
138 allowed_pattern = re.compile(r'''^[A-Za-z0-9@:/?._~%!$&'()*+,;=-]*$''')
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
139
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
140 if not allowed_pattern.match(parsed_url_tuple.path):
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
141 raise ValueError(self._("Path component (%(url_path)s) in %(url)s "
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
142 "is not properly escaped") % info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
143
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
144 if not allowed_pattern.match(parsed_url_tuple.params):
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
145 raise ValueError(self._("Params component (%(url_params)s) in %(url)s is not properly escaped") % info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
146
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
147 if not allowed_pattern.match(parsed_url_tuple.query):
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
148 raise ValueError(self._("Query component (%(url_query)s) in %(url)s is not properly escaped") % info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
149
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
150 if not allowed_pattern.match(parsed_url_tuple.fragment):
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
151 raise ValueError(self._("Fragment component (%(url_fragment)s) in %(url)s is not properly escaped") % info)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
152
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
153 return urllib_.urlunparse(parsed_url_tuple)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
154
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
155 name = ''
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
156 permissionType = None
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
157
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
158 def permission(self):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
159 """Check whether the user has permission to execute this action.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
160
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
161 True by default. If the permissionType attribute is a string containing
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
162 a simple permission, check whether the user has that permission.
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
163 Subclasses must also define the name attribute if they define
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
164 permissionType.
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
165
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
166 Despite having this permission, users may still be unauthorised to
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
167 perform parts of actions. It is up to the subclasses to detect this.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
168 """
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
169 if (self.permissionType and
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
170 not self.hasPermission(self.permissionType)):
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
171 info = {'action': self.name, 'classname': self.classname}
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
172 raise exceptions.Unauthorised(self._(
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
173 'You do not have permission to '
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
174 '%(action)s the %(classname)s class.') % info)
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
175
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
176 _marker = []
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
177
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
178 def hasPermission(self, permission, classname=_marker, itemid=None,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
179 property=None):
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
180 """Check whether the user has 'permission' on the current class."""
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
181 if classname is self._marker:
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
182 classname = self.client.classname
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
183 return self.db.security.hasPermission(permission, self.client.userid,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
184 classname=classname,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
185 itemid=itemid, property=property)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
186
2391
3a0a248289dd action objects got 'context' attribute containing dictionary...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2372
diff changeset
187 def gettext(self, msgid):
3a0a248289dd action objects got 'context' attribute containing dictionary...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2372
diff changeset
188 """Return the localized translation of msgid"""
2563
420d5c2a49d9 use client.translator instead of static translationService;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2553
diff changeset
189 return self.client.translator.gettext(msgid)
2391
3a0a248289dd action objects got 'context' attribute containing dictionary...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2372
diff changeset
190
3a0a248289dd action objects got 'context' attribute containing dictionary...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2372
diff changeset
191 _ = gettext
3a0a248289dd action objects got 'context' attribute containing dictionary...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2372
diff changeset
192
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
193
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
194 class ShowAction(Action):
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
195
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
196 typere = re.compile('[@:]type')
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
197 numre = re.compile('[@:]number')
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
198
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
199 def handle(self):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
200 """Show a node of a particular class/id."""
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
201 t = n = ''
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
202 for key in self.form:
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
203 if self.typere.match(key):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
204 t = self.form[key].value.strip()
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
205 elif self.numre.match(key):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
206 n = self.form[key].value.strip()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
207 if not t:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
208 raise ValueError(self._('No type specified'))
2052
78e6a1e4984e forward-port from maint branch
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
209 if not n:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
210 raise exceptions.SeriousError(self._('No ID entered'))
2052
78e6a1e4984e forward-port from maint branch
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
211 try:
78e6a1e4984e forward-port from maint branch
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
212 int(n)
78e6a1e4984e forward-port from maint branch
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
213 except ValueError:
78e6a1e4984e forward-port from maint branch
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
214 d = {'input': n, 'classname': t}
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
215 raise exceptions.SeriousError(self._(
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
216 '"%(input)s" is not an ID (%(classname)s ID required)') % d)
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
217 url = '%s%s%s' % (self.base, t, n)
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
218 raise exceptions.Redirect(url)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
219
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
220
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
221 class RetireAction(Action):
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
222 name = 'retire'
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
223 permissionType = 'Edit'
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
224
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
225 def handle(self):
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
226 """Retire the context item."""
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
227 # ensure modification comes via POST
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
228 if self.client.env['REQUEST_METHOD'] != 'POST':
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
229 raise Reject(self._('Invalid request'))
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
230
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
231 # if we want to view the index template now, then unset the itemid
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
232 # context info (a special-case for retire actions on the index page)
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
233 itemid = self.nodeid
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
234 if self.template == 'index':
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
235 self.client.nodeid = None
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
236
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
237 # make sure we don't try to retire admin or anonymous
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
238 if self.classname == 'user' and \
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
239 self.db.user.get(itemid, 'username') in ('admin', 'anonymous'):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
240 raise ValueError(self._(
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
241 'You may not retire the admin or anonymous user'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
242
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
243 # check permission
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
244 if not self.hasPermission('Retire', classname=self.classname,
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
245 itemid=itemid):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
246 raise exceptions.Unauthorised(self._(
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
247 'You do not have permission to retire %(class)s'
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
248 ) % {'class': self.classname})
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
249
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
250 # do the retire
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
251 self.db.getclass(self.classname).retire(itemid)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
252 self.db.commit()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
253
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
254 self.client.add_ok_message(
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
255 self._('%(classname)s %(itemid)s has been retired') % {
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
256 'classname': self.classname.capitalize(), 'itemid': itemid})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
257
3473
370bb8f3c4d1 fix permission check on RetireAction [SF#1407342]
Richard Jones <richard@users.sourceforge.net>
parents: 3469
diff changeset
258
5119
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
259 class RestoreAction(Action):
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
260 name = 'restore'
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
261 permissionType = 'Edit'
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
262
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
263 def handle(self):
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
264 """Restore the context item."""
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
265 # ensure modification comes via POST
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
266 if self.client.env['REQUEST_METHOD'] != 'POST':
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
267 raise Reject(self._('Invalid request'))
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
268
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
269 # if we want to view the index template now, then unset the itemid
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
270 # context info (a special-case for retire actions on the index page)
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
271 itemid = self.nodeid
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
272 if self.template == 'index':
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
273 self.client.nodeid = None
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
274
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
275 # check permission
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
276 if not self.hasPermission('Restore', classname=self.classname,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
277 itemid=itemid):
5119
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
278 raise exceptions.Unauthorised(self._(
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
279 'You do not have permission to restore %(class)s'
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
280 ) % {'class': self.classname})
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
281
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
282 # do the restore
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
283 self.db.getclass(self.classname).restore(itemid)
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
284 self.db.commit()
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
285
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
286 self.client.add_ok_message(
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
287 self._('%(classname)s %(itemid)s has been restored') % {
5119
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
288 'classname': self.classname.capitalize(), 'itemid': itemid})
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
289
748ba87e1aca Added a new cgi action restore. The opposite of (and a clone of) the existing retire action.
John Rouillard <rouilj@ieee.org>
parents: 5097
diff changeset
290
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
291 class SearchAction(Action):
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
292 name = 'search'
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
293 permissionType = 'View'
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
294
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
295 def handle(self):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
296 """Mangle some of the form variables.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
297
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
298 Set the form ":filter" variable based on the values of the filter
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
299 variables - if they're set to anything other than "dontcare" then add
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
300 them to :filter.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
301
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
302 Handle the ":queryname" variable and save off the query to the user's
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
303 query list.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
304
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
305 Split any String query values on whitespace and comma.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
306
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
307 """
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
308 self.fakeFilterVars()
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
309 queryname = self.getQueryName()
3913
00896a2acaa5 clean up query display of "Private to you" items
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3855
diff changeset
310
3518
7fb8cfe3c737 enable editing of public queries [SF#966144]
Richard Jones <richard@users.sourceforge.net>
parents: 3499
diff changeset
311 # editing existing query name?
3804
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
312 old_queryname = self.getFromForm('old-queryname')
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
313
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
314 # handle saving the query params
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
315 if queryname:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
316 # parse the environment and figure what the query _is_
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
317 req = templating.HTMLRequest(self.client)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
318
3804
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
319 url = self.getCurrentURL(req)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
320
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
321 key = self.db.query.getkey()
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
322 if key:
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
323 # edit the old way, only one query per name
5192
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
324 # Note that use of queryname as key will automatically
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
325 # raise an error if there are duplicate names.
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
326 try:
3518
7fb8cfe3c737 enable editing of public queries [SF#966144]
Richard Jones <richard@users.sourceforge.net>
parents: 3499
diff changeset
327 qid = self.db.query.lookup(old_queryname)
3073
7fefb1e29ed0 fix permission lookup in query editing
Richard Jones <richard@users.sourceforge.net>
parents: 3012
diff changeset
328 if not self.hasPermission('Edit', 'query', itemid=qid):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
329 raise exceptions.Unauthorised(self._(
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
330 "You do not have permission to edit queries"))
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
331 self.db.query.set(qid, klass=self.classname, url=url)
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
332 except KeyError:
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
333 # create a query
3073
7fefb1e29ed0 fix permission lookup in query editing
Richard Jones <richard@users.sourceforge.net>
parents: 3012
diff changeset
334 if not self.hasPermission('Create', 'query'):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
335 raise exceptions.Unauthorised(self._(
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
336 "You do not have permission to store queries"))
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
337 qid = self.db.query.create(name=queryname,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
338 klass=self.classname, url=url)
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
339 else:
5192
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
340 uid = self.db.getuid()
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
341
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
342 # if the queryname is being changed from the old
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
343 # (original) value, make sure new queryname is not
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
344 # already in use by user.
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
345 # if in use, return to edit/search screen and let
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
346 # user change it.
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
347
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
348 if old_queryname != queryname:
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
349 # we have a name change
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
350 qids = self.db.query.filter(None, {'name': queryname,
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
351 'creator': uid})
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
352 for qid in qids:
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
353 # require an exact name match
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
354 if queryname != self.db.query.get(qid, 'name'):
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
355 continue
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
356 # whoops we found a duplicate; report error and return
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
357 message = _(
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
358 "You already own a query named '%s'. "
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
359 "Please choose another name.") % (queryname)
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
360
5192
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
361 self.client.add_error_message(message)
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
362 return
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
363
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
364 # edit the new way, query name not a key any more
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
365 # see if we match an existing private query
3518
7fb8cfe3c737 enable editing of public queries [SF#966144]
Richard Jones <richard@users.sourceforge.net>
parents: 3499
diff changeset
366 qids = self.db.query.filter(None, {'name': old_queryname,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
367 'private_for': uid})
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
368 if not qids:
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
369 # ok, so there's not a private query for the current user
3518
7fb8cfe3c737 enable editing of public queries [SF#966144]
Richard Jones <richard@users.sourceforge.net>
parents: 3499
diff changeset
370 # - see if there's one created by them
7fb8cfe3c737 enable editing of public queries [SF#966144]
Richard Jones <richard@users.sourceforge.net>
parents: 3499
diff changeset
371 qids = self.db.query.filter(None, {'name': old_queryname,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
372 'creator': uid})
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
373
3581
d10008f756a4 fix saving of queries [SF#1436169]
Richard Jones <richard@users.sourceforge.net>
parents: 3549
diff changeset
374 if qids and old_queryname:
2362
10fc45eea226 fix SearchAction use of Class.filter(), and clarify API docs for same
Richard Jones <richard@users.sourceforge.net>
parents: 2291
diff changeset
375 # edit query - make sure we get an exact match on the name
10fc45eea226 fix SearchAction use of Class.filter(), and clarify API docs for same
Richard Jones <richard@users.sourceforge.net>
parents: 2291
diff changeset
376 for qid in qids:
3518
7fb8cfe3c737 enable editing of public queries [SF#966144]
Richard Jones <richard@users.sourceforge.net>
parents: 3499
diff changeset
377 if old_queryname != self.db.query.get(qid, 'name'):
2362
10fc45eea226 fix SearchAction use of Class.filter(), and clarify API docs for same
Richard Jones <richard@users.sourceforge.net>
parents: 2291
diff changeset
378 continue
3073
7fefb1e29ed0 fix permission lookup in query editing
Richard Jones <richard@users.sourceforge.net>
parents: 3012
diff changeset
379 if not self.hasPermission('Edit', 'query', itemid=qid):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
380 raise exceptions.Unauthorised(self._(
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
381 "You do not have permission to edit queries"))
3518
7fb8cfe3c737 enable editing of public queries [SF#966144]
Richard Jones <richard@users.sourceforge.net>
parents: 3499
diff changeset
382 self.db.query.set(qid, klass=self.classname,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
383 url=url, name=queryname)
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
384 else:
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
385 # create a query
3073
7fefb1e29ed0 fix permission lookup in query editing
Richard Jones <richard@users.sourceforge.net>
parents: 3012
diff changeset
386 if not self.hasPermission('Create', 'query'):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
387 raise exceptions.Unauthorised(self._(
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
388 "You do not have permission to store queries"))
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
389 qid = self.db.query.create(name=queryname,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
390 klass=self.classname, url=url,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
391 private_for=uid)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
392
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
393 # and add it to the user's query multilink
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
394 queries = self.db.user.get(self.userid, 'queries')
2061
0eeecaac008a query saving fix
Richard Jones <richard@users.sourceforge.net>
parents: 2052
diff changeset
395 if qid not in queries:
0eeecaac008a query saving fix
Richard Jones <richard@users.sourceforge.net>
parents: 2052
diff changeset
396 queries.append(qid)
0eeecaac008a query saving fix
Richard Jones <richard@users.sourceforge.net>
parents: 2052
diff changeset
397 self.db.user.set(self.userid, queries=queries)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
398
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
399 # commit the query change to the database
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
400 self.db.commit()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
401
5192
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
402 # This redirects to the index page. Add the @dispname
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
403 # url param to the request so that the query name
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
404 # is displayed.
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
405 req.form.list.append(
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
406 cgi.MiniFieldStorage(
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
407 "@dispname", queryname
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
408 )
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
409 )
302e3a1a7190 Three sets of changes:
rouilj@uland
parents: 5173
diff changeset
410
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
411 def fakeFilterVars(self):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
412 """Add a faked :filter form variable for each filtering prop."""
3635
53987aa153d2 Transitive-property support.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3604
diff changeset
413 cls = self.db.classes[self.classname]
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
414 for key in self.form:
3635
53987aa153d2 Transitive-property support.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3604
diff changeset
415 prop = cls.get_transitive_prop(key)
53987aa153d2 Transitive-property support.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3604
diff changeset
416 if not prop:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
417 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
418 if isinstance(self.form[key], type([])):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
419 # search for at least one entry which is not empty
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
420 for minifield in self.form[key]:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
421 if minifield.value:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
422 break
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
423 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
424 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
425 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
426 if not self.form[key].value:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
427 continue
3635
53987aa153d2 Transitive-property support.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3604
diff changeset
428 if isinstance(prop, hyperdb.String):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
429 v = self.form[key].value
5245
bc16d91b7a50 Fix token_split() so its one error throws ValueError w/out extra arg.
Eric S. Raymond <esr@thyrsus.com>
parents: 5217
diff changeset
430 # If this ever has unbalanced quotes, hilarity will ensue
7178
db06d4aeb978 unshadow stdlib token from roundup's token.
John Rouillard <rouilj@ieee.org>
parents: 7165
diff changeset
431 tokens = token_r.token_split(v)
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
432 if len(tokens) != 1 or tokens[0] != v:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
433 self.form.value.remove(self.form[key])
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
434 # replace the single value with the split list
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
435 for v in tokens:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
436 self.form.value.append(cgi.MiniFieldStorage(key, v))
5097
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
437 elif isinstance(prop, hyperdb.Number):
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
438 try:
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
439 float(self.form[key].value)
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
440 except ValueError:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
441 raise exceptions.FormError(_("Invalid number: ") +
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
442 self.form[key].value)
5097
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
443 elif isinstance(prop, hyperdb.Integer):
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
444 try:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
445 val = self.form[key].value
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
446 if (str(int(val)) == val):
5097
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
447 pass
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
448 else:
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
449 raise ValueError
156cbc1d182c Validate values for Integer and Numeric type filter parameters rather than
John Rouillard <rouilj@ieee.org>
parents: 5093
diff changeset
450 except ValueError:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
451 raise exceptions.FormError(_("Invalid integer: ") +
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
452 val)
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
453
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
454 self.form.value.append(cgi.MiniFieldStorage('@filter', key))
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
455
3804
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
456 def getCurrentURL(self, req):
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
457 """Get current URL for storing as a query.
3805
f86d9531c8db comment update
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3804
diff changeset
458
f86d9531c8db comment update
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3804
diff changeset
459 Note: We are removing the first character from the current URL,
f86d9531c8db comment update
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3804
diff changeset
460 because the leading '?' is not part of the query string.
f86d9531c8db comment update
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3804
diff changeset
461
f86d9531c8db comment update
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3804
diff changeset
462 Implementation note:
5173
4f99aad7e8e8 Store template name with saved query
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
463 We now store the template with the query if the template name is
4f99aad7e8e8 Store template name with saved query
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
464 different from 'index'
4f99aad7e8e8 Store template name with saved query
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5165
diff changeset
465 """
3804
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
466 template = self.getFromForm('template')
6574
20d4ca71d458 Fix unwanted redirect from search index to edit on login error
John Rouillard <rouilj@ieee.org>
parents: 6468
diff changeset
467 if template and template not in ['index', 'index|search']:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
468 return req.indexargs_url('', {'@template': template})[1:]
3804
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
469 return req.indexargs_url('', {})[1:]
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
470
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
471 def getFromForm(self, name):
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
472 for key in ('@' + name, ':' + name):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
473 if key in self.form:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
474 return self.form[key].value.strip()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
475 return ''
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
476
3804
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
477 def getQueryName(self):
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
478 return self.getFromForm('queryname')
5445ff8c442b factor getCurrentURL into its own method:
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3673
diff changeset
479
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
480
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
481 class EditCSVAction(Action):
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
482 name = 'edit'
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
483 permissionType = 'Edit'
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
484
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
485 def handle(self):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
486 """Performs an edit of all of a class' items in one go.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
487
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
488 The "rows" CGI var defines the CSV-formatted entries for the class. New
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
489 nodes are identified by the ID 'X' (or any other non-existent ID) and
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
490 removed lines are retired.
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
491 """
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
492 # ensure modification comes via POST
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
493 if self.client.env['REQUEST_METHOD'] != 'POST':
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
494 raise Reject(self._('Invalid request'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
495
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
496 # figure the properties list for the class
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
497 cl = self.db.classes[self.classname]
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
498 props_without_id = list(cl.getprops(protected=0))
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
499
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
500 # the incoming CSV data will always have the properties in colums
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
501 # sorted and starting with the "id" column
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
502 props_without_id.sort()
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
503 props = ['id'] + props_without_id
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
504
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
505 # do the edit
5452
b50a4c85c270 fixed incorrect usage of BytesIO
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5395
diff changeset
506 rows = StringIO(self.form['rows'].value)
3179
88dbe6b3d891 merge removal of rcsv
Richard Jones <richard@users.sourceforge.net>
parents: 3145
diff changeset
507 reader = csv.reader(rows)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
508 found = {}
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
509 line = 0
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
510 for values in reader:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
511 line += 1
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
512 if line == 1: continue # noqa: E701
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
513 # skip property names header
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
514 if values == props:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
515 continue
6435
ada96db8ec62 Ignore blank lines when editing class via CSV
John Rouillard <rouilj@ieee.org>
parents: 6375
diff changeset
516 # skip blank lines. Can be in the middle
ada96db8ec62 Ignore blank lines when editing class via CSV
John Rouillard <rouilj@ieee.org>
parents: 6375
diff changeset
517 # of the data or a newline at end of file.
ada96db8ec62 Ignore blank lines when editing class via CSV
John Rouillard <rouilj@ieee.org>
parents: 6375
diff changeset
518 if len(values) == 0:
ada96db8ec62 Ignore blank lines when editing class via CSV
John Rouillard <rouilj@ieee.org>
parents: 6375
diff changeset
519 continue
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
520
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
521 # extract the itemid
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
522 itemid, values = values[0], values[1:]
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
523 found[itemid] = 1
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
524
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
525 # see if the node exists
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
526 if itemid in ('x', 'X') or not cl.hasnode(itemid):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
527 exists = 0
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
528
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
529 # check permission to create this item
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
530 if not self.hasPermission('Create', classname=self.classname):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
531 raise exceptions.Unauthorised(self._(
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
532 'You do not have permission to create %(class)s'
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
533 ) % {'class': self.classname})
4293
9b9ab6109254 Generic class editor may now restore retired items (thanks Ralf Hemmecke)
Richard Jones <richard@users.sourceforge.net>
parents: 4146
diff changeset
534 elif cl.hasnode(itemid) and cl.is_retired(itemid):
9b9ab6109254 Generic class editor may now restore retired items (thanks Ralf Hemmecke)
Richard Jones <richard@users.sourceforge.net>
parents: 4146
diff changeset
535 # If a CSV line just mentions an id and the corresponding
9b9ab6109254 Generic class editor may now restore retired items (thanks Ralf Hemmecke)
Richard Jones <richard@users.sourceforge.net>
parents: 4146
diff changeset
536 # item is retired, then the item is restored.
9b9ab6109254 Generic class editor may now restore retired items (thanks Ralf Hemmecke)
Richard Jones <richard@users.sourceforge.net>
parents: 4146
diff changeset
537 cl.restore(itemid)
5515
cd0ceb2afdb8 fixed issue2550993 and added test case
Christof Meerwald <cmeerw@cmeerw.org>
parents: 5503
diff changeset
538 exists = 1
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
539 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
540 exists = 1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
541
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
542 # confirm correct weight
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
543 if len(props_without_id) != len(values):
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
544 self.client.add_error_message(
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
545 self._('Not enough values on line %(line)s') % {
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
546 'line': line})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
547 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
548
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
549 # extract the new values
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
550 d = {}
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
551 for name, value in zip(props_without_id, values):
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
552 # check permission to edit this property on this item
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
553 if exists and not self.hasPermission('Edit', itemid=itemid,
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
554 classname=self.classname,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
555 property=name):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
556 raise exceptions.Unauthorised(self._(
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
557 'You do not have permission to edit %(class)s'
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
558 ) % {'class': self.classname})
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
559
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
560 prop = cl.properties[name]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
561 value = value.strip()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
562 # only add the property if it has a value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
563 if value:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
564 # if it's a multilink, split it
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
565 if isinstance(prop, hyperdb.Multilink):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
566 value = value.split(':')
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
567 elif isinstance(prop, hyperdb.Password):
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4484
diff changeset
568 value = password.Password(value, config=self.db.config)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
569 elif isinstance(prop, hyperdb.Interval):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
570 value = date.Interval(value)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
571 elif isinstance(prop, hyperdb.Date):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
572 value = date.Date(value)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
573 elif isinstance(prop, hyperdb.Boolean):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
574 value = value.lower() in ('yes', 'true', 'on', '1')
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
575 elif isinstance(prop, hyperdb.Number):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
576 value = float(value)
5067
e424987d294a Add support for an integer type to join the existing number type.
John Rouillard <rouilj@ieee.org>
parents: 5044
diff changeset
577 elif isinstance(prop, hyperdb.Integer):
e424987d294a Add support for an integer type to join the existing number type.
John Rouillard <rouilj@ieee.org>
parents: 5044
diff changeset
578 value = int(value)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
579 d[name] = value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
580 elif exists:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
581 # nuke the existing value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
582 if isinstance(prop, hyperdb.Multilink):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
583 d[name] = []
5814
bd6d41f21a5a More extensive EditCSV testing.
John Rouillard <rouilj@ieee.org>
parents: 5800
diff changeset
584 elif isinstance(prop, hyperdb.Password):
bd6d41f21a5a More extensive EditCSV testing.
John Rouillard <rouilj@ieee.org>
parents: 5800
diff changeset
585 # create empty password entry
bd6d41f21a5a More extensive EditCSV testing.
John Rouillard <rouilj@ieee.org>
parents: 5800
diff changeset
586 d[name] = password.Password("", config=self.db.config)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
587 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
588 d[name] = None
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
589
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
590 # perform the edit
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
591 if exists:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
592 # edit existing
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
593 cl.set(itemid, **d)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
594 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
595 # new node
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
596 found[cl.create(**d)] = 1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
597
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
598 # retire the removed entries
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
599 for itemid in cl.list():
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
600 if itemid not in found:
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
601 # check permission to retire this item
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
602 if not self.hasPermission('Retire', itemid=itemid,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
603 classname=self.classname):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
604 raise exceptions.Unauthorised(self._(
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
605 'You do not have permission to retire %(class)s'
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
606 ) % {'class': self.classname})
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
607 cl.retire(itemid)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
608
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
609 # all OK
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
610 self.db.commit()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
611
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
612 self.client.add_ok_message(self._('Items edited OK'))
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
613
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
614
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
615 class EditCommon(Action):
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
616 '''Utility methods for editing.'''
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
617
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
618 def _editnodes(self, all_props, all_links):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
619 ''' Use the props in all_props to perform edit and creation, then
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
620 use the link specs in all_links to do linking.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
621 '''
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
622 # figure dependencies and re-work links
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
623 deps = {}
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
624 links = {}
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
625 for cn, nodeid, propname, vlist in all_links:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
626 numeric_id = int(nodeid or 0)
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
627 if not (numeric_id > 0 or (cn, nodeid) in all_props):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
628 # link item to link to doesn't (and won't) exist
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
629 continue
3850
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
630
3852
0dd05c9e5fff New test for linking of non-existing and existing properties via a form.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3851
diff changeset
631 for value in vlist:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
632 if value not in all_props:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
633 # link item to link to doesn't (and won't) exist
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
634 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
635 deps.setdefault((cn, nodeid), []).append(value)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
636 links.setdefault(value, []).append((cn, nodeid, propname))
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
637
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
638 # figure chained dependencies ordering
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
639 order = []
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
640 done = {}
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
641 # loop detection
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
642 change = 0
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
643 while len(all_props) != len(done):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
644 for needed in all_props:
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
645 if needed in done:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
646 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
647 tlist = deps.get(needed, [])
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
648 for target in tlist:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
649 if target not in done:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
650 break
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
651 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
652 done[needed] = 1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
653 order.append(needed)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
654 change = 1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
655 if not change:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
656 raise ValueError('linking must not loop!')
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
657
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
658 # now, edit / create
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
659 m = []
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
660 for needed in order:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
661 props = all_props[needed]
3851
5fe1f30f7f30 Bug-fix: In case we have a @link@ to an existing node...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3850
diff changeset
662 cn, nodeid = needed
3850
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
663 if props:
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
664 if nodeid is not None and int(nodeid) > 0:
8305
a81a3cd067fa Generate savepoint only if necessary
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8128
diff changeset
665 # make changes to the node, if an error occurs the
a81a3cd067fa Generate savepoint only if necessary
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8128
diff changeset
666 # db may be in a state that needs rollback
a81a3cd067fa Generate savepoint only if necessary
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8128
diff changeset
667 try:
a81a3cd067fa Generate savepoint only if necessary
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8128
diff changeset
668 props = self._changenode(cn, nodeid, props)
a81a3cd067fa Generate savepoint only if necessary
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8128
diff changeset
669 except (IndexError, ValueError):
a81a3cd067fa Generate savepoint only if necessary
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8128
diff changeset
670 self.db.rollback ()
a81a3cd067fa Generate savepoint only if necessary
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8128
diff changeset
671 raise
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
672
3850
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
673 # and some nice feedback for the user
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
674 if props:
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
675 info = ', '.join(map(self._, props))
3850
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
676 m.append(
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
677 self._('%(class)s %(id)s %(properties)s edited ok')
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
678 % {'class': cn, 'id': nodeid, 'properties': info})
3850
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
679 else:
5251
35b30ce991d0 Suppress the "... - nothing changed" status banner presented when a
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
680 # this used to produce a message like:
35b30ce991d0 Suppress the "... - nothing changed" status banner presented when a
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
681 # issue34 - nothing changed
35b30ce991d0 Suppress the "... - nothing changed" status banner presented when a
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
682 # which is confusing if only quiet properties
35b30ce991d0 Suppress the "... - nothing changed" status banner presented when a
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
683 # changed for the class/id. So don't report
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
684 # anything if the user didn't explicitly change
5251
35b30ce991d0 Suppress the "... - nothing changed" status banner presented when a
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
685 # a visible (non-quiet) property.
35b30ce991d0 Suppress the "... - nothing changed" status banner presented when a
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
686 pass
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
687 else:
3850
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
688 # make a new node
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
689 newid = self._createnode(cn, props)
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
690 if nodeid is None:
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
691 self.nodeid = newid
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
692 nodeid = newid
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
693
3850
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
694 # and some nice feedback for the user
326269886c32 Fix form handling of editing existing hyperdb items from a new item page.
Richard Jones <richard@users.sourceforge.net>
parents: 3847
diff changeset
695 m.append(self._('%(class)s %(id)s created')
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
696 % {'class': cn, 'id': newid})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
697
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
698 # fill in new ids in links
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
699 if needed in links:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
700 for linkcn, linkid, linkprop in links[needed]:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
701 props = all_props[(linkcn, linkid)]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
702 cl = self.db.classes[linkcn]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
703 propdef = cl.getprops()[linkprop]
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
704 if linkprop not in props:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
705 if linkid is None or linkid.startswith('-'):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
706 # linking to a new item
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
707 if isinstance(propdef, hyperdb.Multilink):
4304
df7a4400c2ce Fix linking of an existing item to a newly created item...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4293
diff changeset
708 props[linkprop] = [nodeid]
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
709 else:
4304
df7a4400c2ce Fix linking of an existing item to a newly created item...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4293
diff changeset
710 props[linkprop] = nodeid
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
711 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
712 # linking to an existing item
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
713 if isinstance(propdef, hyperdb.Multilink):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
714 existing = cl.get(linkid, linkprop)[:]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
715 existing.append(nodeid)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
716 props[linkprop] = existing
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
717 else:
4304
df7a4400c2ce Fix linking of an existing item to a newly created item...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4293
diff changeset
718 props[linkprop] = nodeid
4992
b562df8a5056 Fix form-parsing for multilinks
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4880
diff changeset
719 elif isinstance(propdef, hyperdb.Multilink):
b562df8a5056 Fix form-parsing for multilinks
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4880
diff changeset
720 props[linkprop].append(nodeid)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
721
4623
4f9c3858b671 Fix another XSS with the ok- and error message, see issue2550724.
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4521
diff changeset
722 return '\n'.join(m)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
723
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
724 def _changenode(self, cn, nodeid, props):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
725 """Change the node based on the contents of the form."""
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
726 # check for permission
3468
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
727 if not self.editItemPermission(props, classname=cn, itemid=nodeid):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
728 raise exceptions.Unauthorised(self._(
2531
f8c6a09ef485 translate web ui messages in _EditAction, PassResetAction
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2391
diff changeset
729 'You do not have permission to edit %(class)s'
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
730 ) % {'class': cn})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
731
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
732 # make the changes
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
733 cl = self.db.classes[cn]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
734 return cl.set(nodeid, **props)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
735
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
736 def _createnode(self, cn, props):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
737 """Create a node based on the contents of the form."""
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
738 # check for permission
3468
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
739 if not self.newItemPermission(props, classname=cn):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
740 raise exceptions.Unauthorised(self._(
2531
f8c6a09ef485 translate web ui messages in _EditAction, PassResetAction
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2391
diff changeset
741 'You do not have permission to create %(class)s'
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
742 ) % {'class': cn})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
743
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
744 # create the node and return its id
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
745 cl = self.db.classes[cn]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
746 return cl.create(**props)
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
747
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
748 def isEditingSelf(self):
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
749 """Check whether a user is editing his/her own details."""
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
750 return (self.nodeid == self.userid
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
751 and self.db.user.get(self.nodeid, 'username') != 'anonymous')
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
752
3468
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
753 _cn_marker = []
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
754
3468
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
755 def editItemPermission(self, props, classname=_cn_marker, itemid=None):
4030
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
756 """Determine whether the user has permission to edit this item."""
3468
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
757 if itemid is None:
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
758 itemid = self.nodeid
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
759 if classname is self._cn_marker:
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
760 classname = self.classname
4030
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
761 # The user must have permission to edit each of the properties
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
762 # being changed.
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
763 for p in props:
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
764 if not self.hasPermission('Edit', itemid=itemid,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
765 classname=classname, property=p):
4030
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
766 return 0
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
767 # Since the user has permission to edit all of the properties,
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
768 # the edit is OK.
b140d76c1cc8 fix issue2550502
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
769 return 1
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
770
3468
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
771 def newItemPermission(self, props, classname=None):
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
772 """Determine whether the user has permission to create this item.
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
773
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
774 Base behaviour is to check the user can edit this class. No additional
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
775 property checks are made.
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
776 """
4126
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
777
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
778 if not classname:
3468
6f3b30925975 fix permission checks in cgi interface [SF#1289557]
Richard Jones <richard@users.sourceforge.net>
parents: 3466
diff changeset
779 classname = self.client.classname
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
780
4126
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
781 if not self.hasPermission('Create', classname=classname):
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
782 return 0
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
783
4310
8e0d350ce644 Proper handling of 'Create' permissions in both mail gateway...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4304
diff changeset
784 # Check Create permission for each property, to avoid being able
4126
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
785 # to set restricted ones on new item creation
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
786 for key in props:
4310
8e0d350ce644 Proper handling of 'Create' permissions in both mail gateway...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4304
diff changeset
787 if not self.hasPermission('Create', classname=classname,
4126
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
788 property=key):
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
789 return 0
e67379669e11 Make sure user has edit permission on all properties when creating items.
Stefan Seefeld <stefan@seefeld.name>
parents: 4118
diff changeset
790 return 1
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
791
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
792
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
793 class EditItemAction(EditCommon):
2143
b29323f75718 wow, I broke that good
Richard Jones <richard@users.sourceforge.net>
parents: 2136
diff changeset
794 def lastUserActivity(self):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
795 if ':lastactivity' in self.form:
2260
46d9cc1e4fc4 collision detection only at second granularity
Richard Jones <richard@users.sourceforge.net>
parents: 2248
diff changeset
796 d = date.Date(self.form[':lastactivity'].value)
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
797 elif '@lastactivity' in self.form:
2260
46d9cc1e4fc4 collision detection only at second granularity
Richard Jones <richard@users.sourceforge.net>
parents: 2248
diff changeset
798 d = date.Date(self.form['@lastactivity'].value)
2014
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
799 else:
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
800 return None
2260
46d9cc1e4fc4 collision detection only at second granularity
Richard Jones <richard@users.sourceforge.net>
parents: 2248
diff changeset
801 d.second = int(d.second)
2264
9b34f41507ed *** empty log message ***
Richard Jones <richard@users.sourceforge.net>
parents: 2260
diff changeset
802 return d
2014
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
803
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
804 def lastNodeActivity(self):
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
805 cl = getattr(self.client.db, self.classname)
2260
46d9cc1e4fc4 collision detection only at second granularity
Richard Jones <richard@users.sourceforge.net>
parents: 2248
diff changeset
806 activity = cl.get(self.nodeid, 'activity').local(0)
46d9cc1e4fc4 collision detection only at second granularity
Richard Jones <richard@users.sourceforge.net>
parents: 2248
diff changeset
807 activity.second = int(activity.second)
46d9cc1e4fc4 collision detection only at second granularity
Richard Jones <richard@users.sourceforge.net>
parents: 2248
diff changeset
808 return activity
2014
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
809
2143
b29323f75718 wow, I broke that good
Richard Jones <richard@users.sourceforge.net>
parents: 2136
diff changeset
810 def detectCollision(self, user_activity, node_activity):
3145
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
811 '''Check for a collision and return the list of props we edited
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
812 that conflict.'''
3188
7faae85e1e33 merge from branch
Richard Jones <richard@users.sourceforge.net>
parents: 3179
diff changeset
813 if user_activity and user_activity < node_activity:
3145
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
814 props, links = self.client.parsePropsFromForm()
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
815 key = (self.classname, self.nodeid)
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
816 # we really only collide for direct prop edit conflicts
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
817 return list(props[key])
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
818 else:
3145
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
819 return []
2014
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
820
3145
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
821 def handleCollision(self, props):
6301
45ba6b71f1cf actions.py translation. Using mapping rather than tuple for args.
John Rouillard <rouilj@ieee.org>
parents: 6190
diff changeset
822 message = self._(
45ba6b71f1cf actions.py translation. Using mapping rather than tuple for args.
John Rouillard <rouilj@ieee.org>
parents: 6190
diff changeset
823 'Edit Error: someone else has edited this %(klass)s (%(props)s). '
45ba6b71f1cf actions.py translation. Using mapping rather than tuple for args.
John Rouillard <rouilj@ieee.org>
parents: 6190
diff changeset
824 'View <a target="_blank" href="%(klass)s%(id)s">their changes</a> '
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
825 'in a new window.') % {"klass": self.classname,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
826 "props": ', '.join(props),
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
827 "id": self.nodeid}
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
828 self.client.add_error_message(message, escape=False)
3145
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
829 return
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
830
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
831 def handle(self):
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
832 """Perform an edit of an item in the database.
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
833
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
834 See parsePropsFromForm and _editnodes for special variables.
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
835
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
836 """
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
837 # ensure modification comes via POST
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
838 if self.client.env['REQUEST_METHOD'] != 'POST':
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
839 raise Reject(self._('Invalid request'))
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
840
2148
2490d26c88df Line 485, lastUserActivity misspelled as lastUserActvity.
Brian Kelley <wc2so1@users.sourceforge.net>
parents: 2143
diff changeset
841 user_activity = self.lastUserActivity()
3145
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
842 if user_activity:
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
843 props = self.detectCollision(user_activity, self.lastNodeActivity())
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
844 if props:
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
845 self.handleCollision(props)
9aa9436a81e0 better edit conflict handling
Richard Jones <richard@users.sourceforge.net>
parents: 3130
diff changeset
846 return
2014
366d3bbce982 Simple version of collision detection...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2012
diff changeset
847
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
848 props, links = self.client.parsePropsFromForm()
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
849
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
850 # handle the props
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
851 try:
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
852 message = self._editnodes(props, links)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
853 except (ValueError, KeyError, IndexError, Reject) as message:
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
854 escape = not isinstance(message, RejectRaw)
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
855 self.client.add_error_message(
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
856 self._('Edit Error: %s') % str(message), escape=escape)
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
857 return
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
858
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
859 # commit now that all the tricky stuff is done
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
860 self.db.commit()
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
861
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
862 # redirect to the item's edit page
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
863 # redirect to finish off
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
864 url = self.base + self.classname
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
865 # note that this action might have been called by an index page, so
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
866 # we will want to include index-page args in this URL too
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
867 if self.nodeid is not None:
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
868 url += self.nodeid
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
869 url += '?@ok_message=%s&@template=%s' % (urllib_.quote(message),
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
870 urllib_.quote(self.template))
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
871 if self.nodeid is None:
2136
ee3cf6a44f29 queries on a per-user basis, and public queries [SF#891798] :)
Richard Jones <richard@users.sourceforge.net>
parents: 2130
diff changeset
872 req = templating.HTMLRequest(self.client)
3130
7308c3c5a943 docs editing from Jean Jordaan
Richard Jones <richard@users.sourceforge.net>
parents: 3073
diff changeset
873 url += '&' + req.indexargs_url('', {})[1:]
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
874 raise exceptions.Redirect(url)
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
875
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
876
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
877 class NewItemAction(EditCommon):
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
878 def handle(self):
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
879 ''' Add a new item to the database.
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
880
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
881 This follows the same form as the EditItemAction, with the same
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
882 special form values.
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
883 '''
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
884 # ensure modification comes via POST
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
885 if self.client.env['REQUEST_METHOD'] != 'POST':
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
886 raise Reject(self._('Invalid request'))
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
887
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
888 # parse the props from the form
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
889 try:
2107
b7404a96b58a minor pre-release / test fixes
Richard Jones <richard@users.sourceforge.net>
parents: 2082
diff changeset
890 props, links = self.client.parsePropsFromForm(create=1)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
891 except (ValueError, KeyError) as message:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
892 self.client.add_error_message(self._('Error: %s')
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
893 % str(message))
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
894 return
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
895
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
896 # handle the props - edit or create
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
897 try:
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
898 # when it hits the None element, it'll set self.nodeid
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
899 messages = self._editnodes(props, links)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
900 except (ValueError, KeyError, IndexError, Reject) as message:
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
901 escape = not isinstance(message, RejectRaw)
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
902 # these errors might just be indicative of user dumbness
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
903 self.client.add_error_message(_('Error: %s') % str(message),
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
904 escape=escape)
2012
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
905 return
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
906
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
907 # commit now that all the tricky stuff is done
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
908 self.db.commit()
9cc7b7d0ca3f Fix last commit to make editing/creating items work again.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2010
diff changeset
909
5158
63294ed25e84 issue1842687: Keywords: After creating, stay in "Create New" mode.
John Rouillard <rouilj@ieee.org>
parents: 5121
diff changeset
910 # Allow an option to stay on the page to create new things
63294ed25e84 issue1842687: Keywords: After creating, stay in "Create New" mode.
John Rouillard <rouilj@ieee.org>
parents: 5121
diff changeset
911 if '__redirect_to' in self.form:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
912 raise exceptions.Redirect('%s&@ok_message=%s' % (
5162
3ee79a2d95d4 rename clean_url method to examine_url. the method doesn't realy clean anything, it throws a ValueError if it finds a problem
John Rouillard <rouilj@ieee.org>
parents: 5161
diff changeset
913 self.examine_url(self.form['__redirect_to'].value),
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
914 urllib_.quote(messages)))
5158
63294ed25e84 issue1842687: Keywords: After creating, stay in "Create New" mode.
John Rouillard <rouilj@ieee.org>
parents: 5121
diff changeset
915
63294ed25e84 issue1842687: Keywords: After creating, stay in "Create New" mode.
John Rouillard <rouilj@ieee.org>
parents: 5121
diff changeset
916 # otherwise redirect to the new item's page
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
917 raise exceptions.Redirect('%s%s%s?@ok_message=%s&@template=%s' % (
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
918 self.base, self.classname, self.nodeid, urllib_.quote(messages),
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
919 urllib_.quote(self.template)))
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
920
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
921
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
922 class PassResetAction(Action):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
923 def handle(self):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
924 """Handle password reset requests.
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
925
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
926 Presence of either "name" or "address" generates email. Presence of
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
927 "otk" performs the reset.
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
928
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
929 """
2291
90cca653ef3d otks manager missing [SF#952931]
Richard Jones <richard@users.sourceforge.net>
parents: 2264
diff changeset
930 otks = self.db.getOTKManager()
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
931 if 'otk' in self.form:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
932 # pull the rego information out of the otk database
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
933 otk = self.form['otk'].value
3673
94b905502d26 removed traceback with OTK is used multiple times [SF#1240539]
Richard Jones <richard@users.sourceforge.net>
parents: 3635
diff changeset
934 uid = otks.get(otk, 'uid', default=None)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
935 if uid is None:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
936 self.client.add_error_message(
2531
f8c6a09ef485 translate web ui messages in _EditAction, PassResetAction
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2391
diff changeset
937 self._("Invalid One Time Key!\n"
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
938 "(a Mozilla bug may cause this message "
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
939 "to show up erroneously, please check your email)"))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
940 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
941
5092
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
942 # pull the additional email address if exist
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
943 uaddress = otks.get(otk, 'uaddress', default=None)
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
944
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
945 # re-open the database as "admin"
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
946 if self.user != 'admin':
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
947 self.client.opendb('admin')
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
948 self.db = self.client.db
2372
c26bb78d2f0c couple of bugfixes
Richard Jones <richard@users.sourceforge.net>
parents: 2362
diff changeset
949 otks = self.db.getOTKManager()
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
950
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
951 # change the password
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
952 newpw = password.generatePassword()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
953
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
954 cl = self.db.user
2082
c091cacdc505 Finished implementation of session and one-time-key stores for RDBMS backends.
Richard Jones <richard@users.sourceforge.net>
parents: 2061
diff changeset
955 # XXX we need to make the "default" page be able to display errors!
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
956 try:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
957 # set the password
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
958 cl.set(uid, password=password.Password(newpw,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
959 config=self.db.config))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
960 # clear the props from the otk database
2082
c091cacdc505 Finished implementation of session and one-time-key stores for RDBMS backends.
Richard Jones <richard@users.sourceforge.net>
parents: 2061
diff changeset
961 otks.destroy(otk)
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5256
diff changeset
962 otks.commit()
5340
ed6153d3ee6a Fix password reset
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5322
diff changeset
963 # commit the password change
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
964 self.db.commit()
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
965 except (ValueError, KeyError) as message:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
966 self.client.add_error_message(str(message))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
967 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
968
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
969 # user info
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
970 name = self.db.user.get(uid, 'username')
5092
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
971 if uaddress is None:
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
972 address = self.db.user.get(uid, 'address')
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
973 else:
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
974 address = uaddress
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
975
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
976 # send the email
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
977 tracker_name = self.db.config.TRACKER_NAME
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
978 subject = self._('Password reset for %s') % tracker_name
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
979 body = self._('''
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
980 The password has been reset for username "%(name)s".
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
981
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
982 Your password is now: %(password)s
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
983 ''') % {'name': name, 'password': newpw}
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
984 if not self.client.standard_message([address], subject, body):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
985 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
986
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
987 self.client.add_ok_message(
2531
f8c6a09ef485 translate web ui messages in _EditAction, PassResetAction
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2391
diff changeset
988 self._('Password reset and email sent to %s') % address)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
989 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
990
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
991 # no OTK, so now figure the user
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
992 if 'username' in self.form:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
993 name = self.form['username'].value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
994 try:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
995 uid = self.db.user.lookup(name)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
996 except KeyError:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
997 self.client.add_error_message(self._('Unknown username'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
998 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
999 address = self.db.user.get(uid, 'address')
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1000 elif 'address' in self.form:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1001 address = self.form['address'].value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1002 uid = uidFromAddress(self.db, ('', address), create=0)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1003 if not uid:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1004 self.client.add_error_message(
2531
f8c6a09ef485 translate web ui messages in _EditAction, PassResetAction
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2391
diff changeset
1005 self._('Unknown email address'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1006 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1007 name = self.db.user.get(uid, 'username')
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1008 else:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1009 self.client.add_error_message(
2531
f8c6a09ef485 translate web ui messages in _EditAction, PassResetAction
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2391
diff changeset
1010 self._('You need to specify a username or address'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1011 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1012
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1013 # generate the one-time-key and store the props for later
6823
fe0091279f50 Refactor session db logging and key generation for sessions/otks
John Rouillard <rouilj@ieee.org>
parents: 6814
diff changeset
1014 otk = otks.getUniqueKey(length=32)
fe0091279f50 Refactor session db logging and key generation for sessions/otks
John Rouillard <rouilj@ieee.org>
parents: 6814
diff changeset
1015
5092
fc03c1381690 issue564 from meta tracker
Chau Nguyen <dangchau1991@gmail.com>
parents: 4880
diff changeset
1016 otks.set(otk, uid=uid, uaddress=address)
5319
62de601bdf6f Fix commits although a Reject exception is raised
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5256
diff changeset
1017 otks.commit()
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1018
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1019 # send the email
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1020 tracker_name = self.db.config.TRACKER_NAME
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1021 subject = self._('Confirm reset of password for %s') % tracker_name
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1022 body = self._('''
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1023 Someone, perhaps you, has requested that the password be changed for your
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1024 username, "%(name)s". If you wish to proceed with the change, please follow
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1025 the link below:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1026
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1027 %(url)suser?@template=forgotten&@action=passrst&otk=%(otk)s
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1028
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1029 You should then receive another email with the new password.
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1030 ''') % {'name': name, 'tracker': tracker_name, 'url': self.base, 'otk': otk}
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1031 if not self.client.standard_message([address], subject, body):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1032 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1033
5253
2d61e39b89c8 Issue2550716 Email address displayed after password reset request (fix)
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
1034 if 'username' in self.form:
2d61e39b89c8 Issue2550716 Email address displayed after password reset request (fix)
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
1035 self.client.add_ok_message(self._('Email sent to primary notification address for %s.') % name)
2d61e39b89c8 Issue2550716 Email address displayed after password reset request (fix)
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
1036 else:
2d61e39b89c8 Issue2550716 Email address displayed after password reset request (fix)
John Rouillard <rouilj@ieee.org>
parents: 5217
diff changeset
1037 self.client.add_ok_message(self._('Email sent to %s.') % address)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1038
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1039
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
1040 class RegoCommon(Action):
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1041 def finishRego(self):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1042 # log the new user in
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1043 self.client.userid = self.userid
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1044 user = self.client.user = self.db.user.get(self.userid, 'username')
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1045 # re-open the database for real, using the user
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1046 self.client.opendb(user)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1047
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1048 # update session data
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1049 self.client.session_api.set(user=user)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1050
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1051 # nice message
2391
3a0a248289dd action objects got 'context' attribute containing dictionary...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2372
diff changeset
1052 message = self._('You are now registered, welcome!')
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1053 url = '%suser%s?@ok_message=%s' % (self.base, self.userid,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1054 urllib_.quote(message))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1055
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1056 # redirect to the user's page (but not 302, as some email clients seem
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1057 # to want to reload the page, or something)
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1058 return '''<html><head><title>%s</title></head>
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1059 <body><p><a href="%s">%s</a></p>
5217
17b213eab274 Add nonce to embedded script references.
John Rouillard <rouilj@ieee.org>
parents: 5201
diff changeset
1060 <script nonce="%s" type="text/javascript">
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1061 window.setTimeout('window.location = "%s"', 1000);
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1062 </script>''' % (message, url, message,
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1063 self.client.client_nonce, url)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1064
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1065
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
1066 class ConfRegoAction(RegoCommon):
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1067 def handle(self):
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1068 """Grab the OTK, use it to load up the new user details."""
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1069 try:
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1070 # pull the rego information out of the otk database
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1071 self.userid = self.db.confirm_registration(self.form['otk'].value)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
1072 except (ValueError, KeyError) as message:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1073 self.client.add_error_message(str(message))
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1074 return
3847
1a44e4bb2b54 Fix missing return value.
Stefan Seefeld <stefan@seefeld.name>
parents: 3805
diff changeset
1075 return self.finishRego()
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1076
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1077
5973
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1078 class RegisterAction(RegoCommon, EditCommon, Timestamped):
2018
96a1bf48efdd Remove duplication in permission handling:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2014
diff changeset
1079 name = 'register'
4146
42331c201b02 Fix issue2550553.
Stefan Seefeld <stefan@seefeld.name>
parents: 4127
diff changeset
1080 permissionType = 'Register'
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
1081
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1082 def handle(self):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1083 """Attempt to create a new user based on the contents of the form
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1084 and then remember it in session.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1085
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1086 Return 1 on successful login.
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2031
diff changeset
1087 """
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1088 # ensure modification comes via POST
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1089 if self.client.env['REQUEST_METHOD'] != 'POST':
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
1090 raise Reject(self._('Invalid request'))
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1091
5973
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1092 # try to make sure user is not a bot by checking the
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1093 # hidden field opaqueregister to make sure it's at least
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1094 # WEB_REGISTRATION_DELAY seconds. If set to 0,
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1095 # disable the check.
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1096 delaytime = self.db.config['WEB_REGISTRATION_DELAY']
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1097
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1098 if delaytime > 0:
fe334430ca07 issue2550919 - Anti-bot signup using 4 second delay
John Rouillard <rouilj@ieee.org>
parents: 5937
diff changeset
1099 self.timecheck('opaqueregister', delaytime)
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1100
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1101 # parse the props from the form
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1102 try:
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1103 props, links = self.client.parsePropsFromForm(create=1)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
1104 except (ValueError, KeyError) as message:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1105 self.client.add_error_message(self._('Error: %s')
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1106 % str(message))
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1107 return
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1108
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1109 # skip the confirmation step?
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1110 if self.db.config['INSTANT_REGISTRATION']:
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1111 # handle the create now
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1112 try:
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1113 # when it hits the None element, it'll set self.nodeid
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1114 # execute for side effect
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1115 messages = self._editnodes(props, links) # noqa: F841
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
1116 except (ValueError, KeyError, IndexError, Reject) as message:
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
1117 escape = not isinstance(message, RejectRaw)
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1118 # these errors might just be indicative of user dumbness
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
1119 self.client.add_error_message(_('Error: %s') % str(message),
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
1120 escape=escape)
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1121 return
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1122
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1123 # fix up the initial roles
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1124 self.db.user.set(self.nodeid,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1125 roles=self.db.config['NEW_WEB_USER_ROLES'])
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1126
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1127 # commit now that all the tricky stuff is done
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1128 self.db.commit()
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1129
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1130 # finish off by logging the user in
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1131 self.userid = self.nodeid
3466
0ecd0062abfb fix redirect after instant registration [SF#1381676]
Richard Jones <richard@users.sourceforge.net>
parents: 3418
diff changeset
1132 return self.finishRego()
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1133
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1134 # generate the one-time-key and store the props for later
4334
1aef7a4e4e39 fix non-instant rego
Richard Jones <richard@users.sourceforge.net>
parents: 4329
diff changeset
1135 user_props = props[('user', None)]
5976
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1136 # check that admin has requested username available check
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1137 check_user = self.db.config['WEB_REGISTRATION_PREVALIDATE_USERNAME']
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1138 if check_user:
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1139 try:
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1140 # verify user exists
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1141 user_found = self.db.user.lookup(user_props['username']) \
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1142 # noqa: F841
5976
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1143 # if user is found reject the request.
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1144 raise Reject(
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1145 _("Username '%s' is already used.") % user_props['username'])
5976
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1146 except KeyError:
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1147 # user not found this is what we want.
71c68961d9f4 - issue2550920 - Optionally detect duplicate username at registration.
John Rouillard <rouilj@ieee.org>
parents: 5973
diff changeset
1148 pass
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1149
5395
23b8e6067f7c Python 3 preparation: update calls to dict methods.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5382
diff changeset
1150 for propname, proptype in self.db.user.getprops().items():
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1151 value = user_props.get(propname, None)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1152 if value is None:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1153 pass
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1154 elif isinstance(proptype, hyperdb.Date):
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1155 user_props[propname] = str(value)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1156 elif isinstance(proptype, hyperdb.Interval):
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1157 user_props[propname] = str(value)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1158 elif isinstance(proptype, hyperdb.Password):
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1159 user_props[propname] = str(value)
2082
c091cacdc505 Finished implementation of session and one-time-key stores for RDBMS backends.
Richard Jones <richard@users.sourceforge.net>
parents: 2061
diff changeset
1160 otks = self.db.getOTKManager()
6823
fe0091279f50 Refactor session db logging and key generation for sessions/otks
John Rouillard <rouilj@ieee.org>
parents: 6814
diff changeset
1161 otk = otks.getUniqueKey(length=32)
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1162 otks.set(otk, **user_props)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1163
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1164 # send the email
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1165 tracker_name = self.db.config.TRACKER_NAME
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1166 tracker_email = self.db.config.TRACKER_EMAIL
3469
d3b02352484f enable registration confirmation by web only [SF#1381675]
Richard Jones <richard@users.sourceforge.net>
parents: 3468
diff changeset
1167 if self.db.config['EMAIL_REGISTRATION_CONFIRMATION']:
7057
9fe29682dca2 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6938
diff changeset
1168 subject = _(
9fe29682dca2 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6938
diff changeset
1169 'Complete your registration to %(tracker_name)s -- key %(key)s') % {
9fe29682dca2 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6938
diff changeset
1170 'tracker_name': tracker_name,
9fe29682dca2 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6938
diff changeset
1171 'key': otk}
9fe29682dca2 Fix internationalized strings with multiple unlabeled % replacements.
John Rouillard <rouilj@ieee.org>
parents: 6938
diff changeset
1172
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1173 body = _("""To complete your registration of the user "%(name)s" with
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1174 %(tracker)s, please do one of the following:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1175
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1176 - send a reply to %(tracker_email)s and maintain the subject line as is (the
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1177 reply's additional "Re:" is ok),
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1178
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1179 - or visit the following URL:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1180
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1181 %(url)s?@action=confrego&otk=%(otk)s
2108
54815ca493a5 add line to rego email to help URL detection [SF#906247]
Richard Jones <richard@users.sourceforge.net>
parents: 2107
diff changeset
1182
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1183 """) % {'name': user_props['username'], 'tracker': tracker_name,
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1184 'url': self.base, 'otk': otk, 'tracker_email': tracker_email} \
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1185 # noqa: E122
3469
d3b02352484f enable registration confirmation by web only [SF#1381675]
Richard Jones <richard@users.sourceforge.net>
parents: 3468
diff changeset
1186 else:
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1187 subject = _('Complete your registration to %s') % (tracker_name)
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1188 body = _("""To complete your registration of the user "%(name)s" with
3469
d3b02352484f enable registration confirmation by web only [SF#1381675]
Richard Jones <richard@users.sourceforge.net>
parents: 3468
diff changeset
1189 %(tracker)s, please visit the following URL:
d3b02352484f enable registration confirmation by web only [SF#1381675]
Richard Jones <richard@users.sourceforge.net>
parents: 3468
diff changeset
1190
d3b02352484f enable registration confirmation by web only [SF#1381675]
Richard Jones <richard@users.sourceforge.net>
parents: 3468
diff changeset
1191 %(url)s?@action=confrego&otk=%(otk)s
d3b02352484f enable registration confirmation by web only [SF#1381675]
Richard Jones <richard@users.sourceforge.net>
parents: 3468
diff changeset
1192
6676
b336cc98d9d2 Mark strings for password reset and registration for translation
John Rouillard <rouilj@ieee.org>
parents: 6593
diff changeset
1193 """) % {'name': user_props['username'], 'tracker': tracker_name,
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1194 'url': self.base, 'otk': otk} # noqa: E122
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1195 if not self.client.standard_message([user_props['address']], subject,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1196 body,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1197 (tracker_name, tracker_email)):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1198 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1199
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1200 # commit changes to the database
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1201 self.db.commit()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1202
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1203 # redirect to the "you're almost there" page
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1204 raise exceptions.Redirect('%suser?@template=rego_progress' % self.base)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1205
4329
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1206 def newItemPermission(self, props, classname=None):
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1207 """Just check the "Register" permission.
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1208 """
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1209 # registration isn't allowed to supply roles
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1210 if 'roles' in props:
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1211 raise exceptions.Unauthorised(self._(
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1212 "It is not permitted to supply roles at registration."))
4329
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1213
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1214 # technically already checked, but here for clarity
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1215 return self.hasPermission('Register', classname=classname)
58b7ba47af87 fixes to make registration work again
Richard Jones <richard@users.sourceforge.net>
parents: 4310
diff changeset
1216
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1217
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1218 class LogoutAction(Action):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1219 def handle(self):
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1220 """Make us really anonymous - nuke the session too."""
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1221 # log us out
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1222 self.client.make_user_anonymous()
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1223 self.client.session_api.destroy()
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1224
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1225 # Let the user know what's going on
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1226 self.client.add_ok_message(self._('You are logged out'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1227
3264
6fc18923f837 LogoutAction: reset client context to render tracker home page...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3188
diff changeset
1228 # reset client context to render tracker home page
6fc18923f837 LogoutAction: reset client context to render tracker home page...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3188
diff changeset
1229 # instead of last viewed page (may be inaccessibe for anonymous)
6fc18923f837 LogoutAction: reset client context to render tracker home page...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3188
diff changeset
1230 self.client.classname = None
6fc18923f837 LogoutAction: reset client context to render tracker home page...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3188
diff changeset
1231 self.client.nodeid = None
6fc18923f837 LogoutAction: reset client context to render tracker home page...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3188
diff changeset
1232 self.client.template = None
6fc18923f837 LogoutAction: reset client context to render tracker home page...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3188
diff changeset
1233
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5192
diff changeset
1234 # Redirect to a new page on logout. This regenerates
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5192
diff changeset
1235 # CSRF tokens so they are associated with the
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5192
diff changeset
1236 # anonymous user and not the user who logged out. If
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5192
diff changeset
1237 # we don't the user gets an invalid CSRF token error
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5192
diff changeset
1238 # As above choose the home page since everybody can
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5192
diff changeset
1239 # see that.
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5356
diff changeset
1240 raise exceptions.Redirect(self.base)
5201
a9ace22e0a2f issue 2550690 - Adding anti-csrf measures to roundup following
John Rouillard <rouilj@ieee.org>
parents: 5192
diff changeset
1241
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1242
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1243 class LoginAction(Action):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1244 def handle(self):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1245 """Attempt to log a user in.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1246
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1247 Sets up a session for the user which contains the login credentials.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1248
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1249 """
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1250 # ensure modification comes via POST
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1251 if self.client.env['REQUEST_METHOD'] != 'POST':
5004
494d255043c9 Display errors containing HTML with RejectRaw (issue2550847)
John Kristensen <john@jerrykan.com>
parents: 4992
diff changeset
1252 raise Reject(self._('Invalid request'))
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1253
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1254 # we need the username at a minimum
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1255 if '__login_name' not in self.form:
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1256 self.client.add_error_message(self._('Username required'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1257 return
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1258
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1259 # get the login info
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1260 self.client.user = self.form['__login_name'].value
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1261 if '__login_password' in self.form:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1262 password = self.form['__login_password'].value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1263 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1264 password = ''
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1265
5121
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1266 if '__came_from' in self.form:
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1267 # On valid or invalid login, redirect the user back to the page
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1268 # the started on. Searches, issue and other pages
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1269 # are all preserved in __came_from. Clean out any old feedback
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1270 # @error_message, @ok_message from the __came_from url.
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1271 #
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1272 # 1. Split the url into components.
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1273 # 2. Split the query string into parts.
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1274 # 3. Delete @error_message and @ok_message if present.
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1275 # 4. Define a new redirect_url missing the @...message entries.
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1276 # This will be redefined if there is a login error to include
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1277 # a new error message
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
1278
5162
3ee79a2d95d4 rename clean_url method to examine_url. the method doesn't realy clean anything, it throws a ValueError if it finds a problem
John Rouillard <rouilj@ieee.org>
parents: 5161
diff changeset
1279 clean_url = self.examine_url(self.form['__came_from'].value)
5161
12190efa30d4 I realized that the __came_from and __redirect_to url parameters I
John Rouillard <rouilj@ieee.org>
parents: 5158
diff changeset
1280 redirect_url_tuple = urllib_.urlparse(clean_url)
5121
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1281 # now I have a tuple form for the __came_from url
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1282 try:
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1283 query = urllib_.parse_qs(redirect_url_tuple.query)
5121
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1284 if "@error_message" in query:
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1285 del query["@error_message"]
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1286 if "@ok_message" in query:
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1287 del query["@ok_message"]
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1288 if "@action" in query:
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1289 # also remove the logout action from the redirect
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1290 # there is only ever one @action value.
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1291 if query['@action'] == ["logout"]:
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1292 del query["@action"]
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1293 except AttributeError:
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1294 # no query param so nothing to remove. Just define.
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1295 query = {}
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1296 pass
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1297
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1298 redirect_url = urllib_.urlunparse(
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1299 (redirect_url_tuple.scheme,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1300 redirect_url_tuple.netloc,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1301 redirect_url_tuple.path,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1302 redirect_url_tuple.params,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1303 urllib_.urlencode(list(sorted(query.items())), doseq=True),
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1304 redirect_url_tuple.fragment))
5121
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1305
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1306 try:
5772
8dbe307bdb57 Finish up login rate limit code. Set config item to 0 disables, make
John Rouillard <rouilj@ieee.org>
parents: 5722
diff changeset
1307 self.verifyLogin(self.client.user, password)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5245
diff changeset
1308 except exceptions.LoginError as err:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1309 self.client.make_user_anonymous()
4880
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1310 for arg in err.args:
ca692423e401 Different approach to fix XSS in issue2550817
Ralf Schlatterbeck <rsc@runtux.com>
parents: 4624
diff changeset
1311 self.client.add_error_message(arg)
5121
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1312
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1313 if '__came_from' in self.form:
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1314 # set a new error
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1315 query['@error_message'] = err.args
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1316 redirect_url = urllib_.urlunparse(
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1317 (redirect_url_tuple.scheme,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1318 redirect_url_tuple.netloc,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1319 redirect_url_tuple.path,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1320 redirect_url_tuple.params,
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1321 urllib_.urlencode(list(sorted(query.items())), doseq=True),
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1322 redirect_url_tuple.fragment))
5121
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1323 raise exceptions.Redirect(redirect_url)
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1324 # if no __came_from, send back to base url with error
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1325 return
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1326 except RateLimitExceeded as err:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1327 self.client.make_user_anonymous()
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1328 for arg in err.args:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1329 self.client.add_error_message(arg)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1330
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1331 if '__came_from' in self.form:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1332 # usually web only. If API uses this they will get
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1333 # confused as the 429 isn't returned. Without this
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1334 # a web user will get redirected back to the home
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1335 # page rather than stay on the page where they tried
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1336 # to login.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1337 # set a new error message
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1338 query['@error_message'] = err.args
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1339 redirect_url = urllib_.urlunparse(
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1340 (redirect_url_tuple.scheme,
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1341 redirect_url_tuple.netloc,
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1342 redirect_url_tuple.path,
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1343 redirect_url_tuple.params,
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1344 urllib_.urlencode(list(sorted(query.items())), doseq=True),
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1345 redirect_url_tuple.fragment))
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1346 raise exceptions.Redirect(redirect_url)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1347 raise
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1348
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1349 # now we're OK, re-open the database for real, using the user
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1350 self.client.opendb(self.client.user)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1351
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1352 # save user in session
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1353 self.client.session_api.set(user=self.client.user)
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1354 if 'remember' in self.form:
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3987
diff changeset
1355 self.client.session_api.update(set_cookie=True, expire=24*3600*365)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1356
3418
9b8019f28158 remember where we came from when logging in (patch [SF#1312889])
Richard Jones <richard@users.sourceforge.net>
parents: 3382
diff changeset
1357 # If we came from someplace, go back there
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1358 if '__came_from' in self.form:
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1359 # add welcome message to user when logged in
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1360 query['@ok_message'] = _("Welcome %(username)s!") % {
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1361 "username": self.client.user, }
6468
37b57da3374f issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login.
aburke
parents: 6435
diff changeset
1362 redirect_url = urllib_.urlunparse((redirect_url_tuple.scheme,
37b57da3374f issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login.
aburke
parents: 6435
diff changeset
1363 redirect_url_tuple.netloc,
37b57da3374f issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login.
aburke
parents: 6435
diff changeset
1364 redirect_url_tuple.path,
37b57da3374f issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login.
aburke
parents: 6435
diff changeset
1365 redirect_url_tuple.params,
37b57da3374f issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login.
aburke
parents: 6435
diff changeset
1366 urllib_.urlencode(list(sorted(query.items())), doseq=True),
37b57da3374f issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login.
aburke
parents: 6435
diff changeset
1367 redirect_url_tuple.fragment))
37b57da3374f issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login.
aburke
parents: 6435
diff changeset
1368
5121
894aa07be6cb issue2550785: Using login from search (or logout) fails. when
John Rouillard <rouilj@ieee.org>
parents: 5119
diff changeset
1369 raise exceptions.Redirect(redirect_url)
3418
9b8019f28158 remember where we came from when logging in (patch [SF#1312889])
Richard Jones <richard@users.sourceforge.net>
parents: 3382
diff changeset
1370
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1371 def rateLimitLogin(self, username, is_api=False, update=True):
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1372 """Implement rate limiting of logins by login name.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1373
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1374 username - username attempting to log in. May or may not
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1375 be valid.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1376 is_api - set to False for login via html page
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1377 set to "xmlrpc" for xmlrpc api
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1378 set to "rest" for rest api
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1379 update - if False will raise RateLimitExceeded without
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1380 updating the stored value. Default is True
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1381 which updates stored value. Used to deny access
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1382 when user successfully logs in but the user
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1383 doesn't have a valid attempt available.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1384
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1385 Login rates for a user are split based on html vs api
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1386 login.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1387
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1388 Set self.client.db.config.WEB_LOGIN_ATTEMPTS_MIN to 0
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1389 to disable for web interface. Set
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1390 self.client.db.config.API_LOGIN_ATTEMPTS to 0
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1391 to disable for web interface.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1392
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1393 By setting LoginAction.limitLogin, the admin can override
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1394 the HTML web page rate limiter if they need to change the
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1395 interval from 1 minute.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1396 """
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1397 config = self.client.db.config
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1398
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1399 if not is_api:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1400 # HTML web login. Period is fixed at 1 minute.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1401 # Override by setting self.loginLimit. Yech.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1402 allowed_attempts = config.WEB_LOGIN_ATTEMPTS_MIN
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1403 per_period = 60
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1404 rlkey = "LOGIN-" + username
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1405 else:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1406 # api login. Both Rest and XMLRPC use this.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1407 allowed_attempts = config.WEB_API_FAILED_LOGIN_LIMIT
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1408 per_period = config.WEB_API_FAILED_LOGIN_INTERVAL_IN_SEC
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1409 rlkey = "LOGIN-API" + username
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1410
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1411 if not allowed_attempts: # if allowed_attempt == 0 - off
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1412 return
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1413
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1414 if self.loginLimit and not is_api:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1415 # provide a way for user (via interfaces.py) to
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1416 # change the interval on the html login limit.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1417 limit = self.loginLimit
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1418 else:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1419 limit = RateLimit(allowed_attempts,
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1420 timedelta(seconds=per_period))
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1421
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1422 gcra = Gcra()
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1423 otk = self.client.db.Otk
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1424
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1425 try:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1426 val = otk.getall(rlkey)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1427 gcra.set_tat_as_string(rlkey, val['tat'])
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1428 except KeyError:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1429 # ignore if tat not set, tat is 1970-1-1 by default.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1430 pass
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1431
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1432 # see if rate limit exceeded and we need to reject
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1433 # the attempt
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1434 reject = gcra.update(rlkey, limit)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1435
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1436 # Calculate a timestamp that will make OTK expire the
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1437 # unused entry in twice the period defined for the
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1438 # rate limiter.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1439 if update:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1440 ts = otk.lifetime(per_period*2)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1441 otk.set(rlkey, tat=gcra.get_tat_as_string(rlkey),
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1442 __timestamp=ts)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1443 otk.commit()
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1444
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1445 # User exceeded limits: find out how long to wait
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1446 limitStatus = gcra.status(rlkey, limit)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1447
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1448 if not reject:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1449 return
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1450
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1451 for header, value in limitStatus.items():
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1452 self.client.setHeader(header, value)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1453
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1454 # User exceeded limits: tell humans how long to wait
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1455 # Headers above will do the right thing for api
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1456 # aware clients.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1457 try:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1458 retry_after = limitStatus['Retry-After']
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1459 except KeyError:
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1460 # handle race condition. If the time between
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1461 # the call to grca.update and grca.status
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1462 # is sufficient to reload the bucket by 1
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1463 # item, Retry-After will be missing from
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1464 # limitStatus. So report a 1 second delay back
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1465 # to the client. We treat update as sole
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1466 # source of truth for exceeded rate limits.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1467 retry_after = 1
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1468 self.client.setHeader('Retry-After', '1')
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1469
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1470 # make rate limiting headers available to javascript
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1471 # even for non-api calls.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1472 self.client.setHeader(
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1473 "Access-Control-Expose-Headers",
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1474 ", ".join([
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1475 "X-RateLimit-Limit",
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1476 "X-RateLimit-Remaining",
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1477 "X-RateLimit-Reset",
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1478 "X-RateLimit-Limit-Period",
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1479 "Retry-After"
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1480 ])
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1481 )
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1482
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1483 raise RateLimitExceeded(_("Logins occurring too fast. Please wait: %s seconds.") % retry_after)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1484
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1485 def verifyLogin(self, username, password, is_api=False):
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1486 """Authenticate the user with rate limits.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1487
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1488 All logins (valid and failing) from a web page calling the
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1489 LoginAction method are rate limited to the config.ini
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1490 configured value in 1 minute. (Interval can be changed see
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1491 rateLimitLogin method.)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1492
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1493 API logins are only rate limited if they fail. Successful
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1494 api logins are rate limited using the
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1495 api_calls_per_interval and api_interval_in_sec settings in
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1496 config.ini.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1497
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1498 Once a user receives a rate limit notice, they must
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1499 wait the recommended time to try again as the account is
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1500 locked out for the recommended time. If a user tries to
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1501 log in while locked out, they will get a 429 rejection
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1502 even if the username and password are correct.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1503 """
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1504 # make sure the user exists
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1505 try:
7179
804cc66692ac Add comment. lookup on a username doesn't return retired users.
John Rouillard <rouilj@ieee.org>
parents: 7178
diff changeset
1506 # Note: lookup only searches non-retired items.
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1507 self.client.userid = self.db.user.lookup(username)
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1508 except KeyError:
6375
c4371ec7d1c0 Call verifyPassword even if user does not exist.
John Rouillard <rouilj@ieee.org>
parents: 6301
diff changeset
1509 # Perform password check against anonymous user.
c4371ec7d1c0 Call verifyPassword even if user does not exist.
John Rouillard <rouilj@ieee.org>
parents: 6301
diff changeset
1510 # Prevents guessing of valid usernames by detecting
c4371ec7d1c0 Call verifyPassword even if user does not exist.
John Rouillard <rouilj@ieee.org>
parents: 6301
diff changeset
1511 # delay caused by checking password only on valid
c4371ec7d1c0 Call verifyPassword even if user does not exist.
John Rouillard <rouilj@ieee.org>
parents: 6301
diff changeset
1512 # users.
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1513 _discard = self.verifyPassword("2", password) # noqa: F841
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1514
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1515 # limit logins to an acceptable rate. Do it for
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1516 # invalid usernames so attempts to break
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1517 # an invalid user will also be rate limited.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1518 self.rateLimitLogin(username, is_api=is_api)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1519
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1520 # this is not hit if rate limit is exceeded
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1521 raise exceptions.LoginError(self._('Invalid login'))
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1522
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1523 # if we are rate limited and the user tries again,
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1524 # reject the login. update=false so we don't count
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1525 # a potentially valid login.
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1526 self.rateLimitLogin(username, is_api=is_api, update=False)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1527
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1528 # verify the password
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1529 if not self.verifyPassword(self.client.userid, password):
7556
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1530 self.rateLimitLogin(username, is_api=is_api)
273c8c2b5042 fix(api): - issue2551063 - Rest/Xmlrpc interfaces needs failed login protection.
John Rouillard <rouilj@ieee.org>
parents: 7179
diff changeset
1531 # this is not hit if rate limit is exceeded
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1532 raise exceptions.LoginError(self._('Invalid login'))
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1533
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1534 # Determine whether the user has permission to log in.
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1535 # Base behaviour is to check the user has "Web Access".
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1536 if not self.hasPermission("Web Access"):
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1537 raise exceptions.LoginError(self._(
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1538 "You do not have permission to login"))
2927
9ecca789544f applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2657
diff changeset
1539
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1540 def verifyPassword(self, userid, givenpw):
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1541 '''Verify the password that the user has supplied.
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1542 Optionally migrate to new password scheme if configured
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1543 '''
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1544 db = self.db
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1545 stored = db.user.get(userid, 'password')
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1546 if givenpw == stored:
7165
970cd6d2b8ea issue2551251 - migrate pbkdf2 passwords if more rounds configured
John Rouillard <rouilj@ieee.org>
parents: 7163
diff changeset
1547 if (db.config.WEB_MIGRATE_PASSWORDS and
970cd6d2b8ea issue2551251 - migrate pbkdf2 passwords if more rounds configured
John Rouillard <rouilj@ieee.org>
parents: 7163
diff changeset
1548 stored.needs_migration(config=db.config)):
4486
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4484
diff changeset
1549 newpw = password.Password(givenpw, config=db.config)
693c75d56ebe Add new config-option 'password_pbkdf2_default_rounds'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4484
diff changeset
1550 db.user.set(userid, password=newpw)
4484
52e13bf0bb40 Add new config-option 'migrate_passwords' in section 'web'...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4416
diff changeset
1551 db.commit()
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1552 return 1
6684
9ca5cbffa0c4 Switch off using blank passwords for login
John Rouillard <rouilj@ieee.org>
parents: 6676
diff changeset
1553 # allow blank password
9ca5cbffa0c4 Switch off using blank passwords for login
John Rouillard <rouilj@ieee.org>
parents: 6676
diff changeset
1554 if db.config.WEB_LOGIN_EMPTY_PASSWORDS and not givenpw and not stored:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1555 return 1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1556 return 0
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1557
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1558
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1559 class ExportCSVAction(Action):
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1560 name = 'export'
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1561 permissionType = 'View'
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1562 list_sep = ';' # Separator for list types
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1563
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1564 def handle(self):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1565 ''' Export the specified search query as CSV. '''
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1566 # figure the request
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1567 request = templating.HTMLRequest(self.client)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1568 filterspec = request.filterspec
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1569 sort = request.sort
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1570 group = request.group
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1571 columns = request.columns
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1572 klass = self.db.getclass(request.classname)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1573
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1574 # check if all columns exist on class
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1575 # the exception must be raised before sending header
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1576 props = klass.getprops()
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1577 for cname in columns:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1578 if cname not in props:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1579 # use error code 400: Bad Request. Do not use
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1580 # error code 404: Not Found.
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1581 self.client.response_code = 400
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1582 raise exceptions.NotFound(
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1583 self._('Column "%(column)s" not found in %(class)s')
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1584 % {'column': html_escape(cname),
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1585 'class': request.classname})
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1586
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1587 # full-text search
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1588 if request.search_text:
6593
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1589 indexer = self.db.indexer
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1590 if self.db.indexer.query_language:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1591 try:
6593
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1592 matches = indexer.search(
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1593 [request.search_text], klass)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1594 except Exception as e:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1595 error = " ".join(e.args)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1596 self.client.add_error_message(error)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1597 self.client.response_code = 400
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1598 # trigger error reporting. NotFound isn't right but...
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1599 raise exceptions.NotFound(error)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1600 else:
6593
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1601 matches = indexer.search(
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1602 re.findall(r'\b\w{%s,%s}\b' % (indexer.minlength,
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1603 indexer.maxlength),
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1604 request.search_text), klass)
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1605 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1606 matches = None
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1607
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1608 header = self.client.additional_headers
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1609 header['Content-Type'] = 'text/csv; charset=%s' % self.client.charset
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1610 # some browsers will honor the filename here...
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1611 header['Content-Disposition'] = 'inline; filename=query.csv'
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1612
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1613 self.client.header()
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1615 if self.client.env['REQUEST_METHOD'] == 'HEAD':
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1616 # all done, return a dummy string
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1617 return 'dummy'
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1618
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1619 wfile = self.client.request.wfile
6083
f74d078cfd9a issue2551019 needs to be handled in the action code itself, not the WSGI handler
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6066
diff changeset
1620 if sys.version_info[0] > 2:
f74d078cfd9a issue2551019 needs to be handled in the action code itself, not the WSGI handler
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6066
diff changeset
1621 wfile = codecs.getwriter(self.client.charset)(wfile, 'replace')
f74d078cfd9a issue2551019 needs to be handled in the action code itself, not the WSGI handler
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6066
diff changeset
1622 elif self.client.charset != self.client.STORAGE_CHARSET:
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1623 wfile = codecs.EncodedFile(wfile,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1624 self.client.STORAGE_CHARSET,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1625 self.client.charset, 'replace')
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1626
6190
15fd91fd3c4c Quote all exported CSV data
John Rouillard <rouilj@ieee.org>
parents: 6083
diff changeset
1627 writer = csv.writer(wfile, quoting=csv.QUOTE_NONNUMERIC)
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1628
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1629 # handle different types of columns.
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1630 def repr_no_right(cls, col):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1631 """User doesn't have the right to see the value of col."""
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1632 def fct(arg):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1633 return "[hidden]"
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1634 return fct
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1635
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1636 def repr_link(cls, col):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1637 """Generate a function which returns the string representation of
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1638 a link depending on `cls` and `col`."""
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1639 def fct(arg):
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1640 if arg is None:
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1641 return ""
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1642 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1643 return str(cls.get(arg, col))
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1644 return fct
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1645
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1646 def repr_list(cls, col):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1647 def fct(arg):
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1648 if arg is None:
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1649 return ""
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1650 elif type(arg) is list:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1651 seq = [str(cls.get(val, col)) for val in arg]
5652
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1652 # python2/python 3 have different order in lists
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1653 # sort to not break tests
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1654 seq.sort()
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1655 return self.list_sep.join(seq)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1656 return fct
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1657
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1658 def repr_date():
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1659 def fct(arg):
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1660 if arg is None:
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1661 return ""
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1662 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1663 if (arg.local(self.db.getUserTimezone()).pretty('%H:%M') ==
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1664 '00:00'):
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1665 fmt = '%Y-%m-%d'
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1666 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1667 fmt = '%Y-%m-%d %H:%M'
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1668 return arg.local(self.db.getUserTimezone()).pretty(fmt)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1669 return fct
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1670
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1671 def repr_val():
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1672 def fct(arg):
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1673 if arg is None:
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1674 return ""
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1675 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1676 return str(arg)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1677 return fct
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1678
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1679 props = klass.getprops()
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1680
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1681 # Determine translation map.
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1682 ncols = []
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1683 represent = {}
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1684 for col in columns:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1685 ncols.append(col)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1686 represent[col] = repr_val()
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1687 if isinstance(props[col], hyperdb.Multilink):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1688 cname = props[col].classname
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1689 cclass = self.db.getclass(cname)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1690 represent[col] = repr_list(cclass, 'name')
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1691 if not self.hasPermission(self.permissionType, classname=cname):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1692 represent[col] = repr_no_right(cclass, 'name')
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1693 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1694 if 'name' in cclass.getprops():
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1695 represent[col] = repr_list(cclass, 'name')
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1696 elif cname == 'user':
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1697 represent[col] = repr_list(cclass, 'realname')
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1698 if isinstance(props[col], hyperdb.Link):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1699 cname = props[col].classname
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1700 cclass = self.db.getclass(cname)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1701 if not self.hasPermission(self.permissionType, classname=cname):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1702 represent[col] = repr_no_right(cclass, 'name')
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1703 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1704 if 'name' in cclass.getprops():
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1705 represent[col] = repr_link(cclass, 'name')
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1706 elif cname == 'user':
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1707 represent[col] = repr_link(cclass, 'realname')
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1708 if isinstance(props[col], hyperdb.Date):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1709 represent[col] = repr_date()
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1710
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1711 columns = ncols
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1712 # generate the CSV output
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1713 self.client._socket_op(writer.writerow, columns)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1714 # and search
8128
261438b9c91c Use new filtering for csv export variants
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8040
diff changeset
1715 filter = klass.filter_with_permissions
261438b9c91c Use new filtering for csv export variants
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8040
diff changeset
1716 for itemid in filter(matches, filterspec, sort, group):
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1717 row = []
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1718 for name in columns:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1719 # check permission for this property on this item
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1720 # TODO: Permission filter doesn't work for the 'user' class
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1721 if not self.hasPermission(self.permissionType, itemid=itemid,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1722 classname=request.classname,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1723 property=name):
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1724 repr_function = repr_no_right(request.classname, name)
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1725 else:
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1726 repr_function = represent[name]
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1727 row.append(repr_function(klass.get(itemid, name)))
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1728 self.client._socket_op(writer.writerow, row)
8040
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1729
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1730 # force close of connection since we can't send a
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1731 # Content-Length header.
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1732 self.client.request.close_connection = True
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1733
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1734 return '\n'
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1735
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1736
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1737 class ExportCSVWithIdAction(Action):
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1738 ''' A variation of ExportCSVAction that returns ID number rather than
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1739 names. This is the original csv export function.
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1740 '''
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1741 name = 'export'
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1742 permissionType = 'View'
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1743
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1744 def handle(self):
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1745 ''' Export the specified search query as CSV. '''
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1746 # figure the request
2163
791c66a3b738 fixed CSV export and CGI actions returning results
Richard Jones <richard@users.sourceforge.net>
parents: 2160
diff changeset
1747 request = templating.HTMLRequest(self.client)
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1748 filterspec = request.filterspec
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1749 sort = request.sort
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1750 group = request.group
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1751 columns = request.columns
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1752 klass = self.db.getclass(request.classname)
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1753
4624
21705126dafa Committed edited fix for issue2550712 by Cedric Krier.
Bernhard Reiter <bernhard@intevation.de>
parents: 4623
diff changeset
1754 # check if all columns exist on class
21705126dafa Committed edited fix for issue2550712 by Cedric Krier.
Bernhard Reiter <bernhard@intevation.de>
parents: 4623
diff changeset
1755 # the exception must be raised before sending header
21705126dafa Committed edited fix for issue2550712 by Cedric Krier.
Bernhard Reiter <bernhard@intevation.de>
parents: 4623
diff changeset
1756 props = klass.getprops()
21705126dafa Committed edited fix for issue2550712 by Cedric Krier.
Bernhard Reiter <bernhard@intevation.de>
parents: 4623
diff changeset
1757 for cname in columns:
21705126dafa Committed edited fix for issue2550712 by Cedric Krier.
Bernhard Reiter <bernhard@intevation.de>
parents: 4623
diff changeset
1758 if cname not in props:
5165
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5164
diff changeset
1759 # use error code 400: Bad Request. Do not use
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5164
diff changeset
1760 # error code 404: Not Found.
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5164
diff changeset
1761 self.client.response_code = 400
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5164
diff changeset
1762 raise exceptions.NotFound(
a86860224d80 issue2550755: exceptions.NotFound(msg) msg is not reported to user in cgi.
John Rouillard <rouilj@ieee.org>
parents: 5164
diff changeset
1763 self._('Column "%(column)s" not found in %(class)s')
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1764 % {'column': html_escape(cname),
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1765 'class': request.classname})
4624
21705126dafa Committed edited fix for issue2550712 by Cedric Krier.
Bernhard Reiter <bernhard@intevation.de>
parents: 4623
diff changeset
1766
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1767 # full-text search
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1768 if request.search_text:
6593
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1769 indexer = self.db.indexer
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1770 if indexer.query_language:
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1771 try:
6593
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1772 matches = indexer.search(
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1773 [request.search_text], klass)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1774 except Exception as e:
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1775 error = " ".join(e.args)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1776 self.client.add_error_message(error)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1777 self.client.response_code = 400
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1778 # trigger error reporting. NotFound isn't right but...
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1779 raise exceptions.NotFound(error)
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1780 else:
6593
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1781 matches = indexer.search(
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1782 re.findall(r'\b\w{%s,%s}\b' % (indexer.minlength,
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1783 indexer.maxlength),
e70e2789bc2c issue2551189 - increase text search maxlength
John Rouillard <rouilj@ieee.org>
parents: 6588
diff changeset
1784 request.search_text),
6588
91ab3e0ffcd0 Summary: Add test cases for sqlite fts
John Rouillard <rouilj@ieee.org>
parents: 6574
diff changeset
1785 klass)
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1786 else:
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1787 matches = None
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1788
2163
791c66a3b738 fixed CSV export and CGI actions returning results
Richard Jones <richard@users.sourceforge.net>
parents: 2160
diff changeset
1789 h = self.client.additional_headers
3499
230fb5d49c19 CSV encoding support [SF#1240848]
Richard Jones <richard@users.sourceforge.net>
parents: 3484
diff changeset
1790 h['Content-Type'] = 'text/csv; charset=%s' % self.client.charset
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1791 # some browsers will honor the filename here...
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1792 h['Content-Disposition'] = 'inline; filename=query.csv'
2592
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2563
diff changeset
1793
2163
791c66a3b738 fixed CSV export and CGI actions returning results
Richard Jones <richard@users.sourceforge.net>
parents: 2160
diff changeset
1794 self.client.header()
2592
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2563
diff changeset
1795
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2563
diff changeset
1796 if self.client.env['REQUEST_METHOD'] == 'HEAD':
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2563
diff changeset
1797 # all done, return a dummy string
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2563
diff changeset
1798 return 'dummy'
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2563
diff changeset
1799
3499
230fb5d49c19 CSV encoding support [SF#1240848]
Richard Jones <richard@users.sourceforge.net>
parents: 3484
diff changeset
1800 wfile = self.client.request.wfile
6083
f74d078cfd9a issue2551019 needs to be handled in the action code itself, not the WSGI handler
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6066
diff changeset
1801 if sys.version_info[0] > 2:
f74d078cfd9a issue2551019 needs to be handled in the action code itself, not the WSGI handler
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6066
diff changeset
1802 wfile = codecs.getwriter(self.client.charset)(wfile, 'replace')
f74d078cfd9a issue2551019 needs to be handled in the action code itself, not the WSGI handler
Christof Meerwald <cmeerw@cmeerw.org>
parents: 6066
diff changeset
1803 elif self.client.charset != self.client.STORAGE_CHARSET:
3499
230fb5d49c19 CSV encoding support [SF#1240848]
Richard Jones <richard@users.sourceforge.net>
parents: 3484
diff changeset
1804 wfile = codecs.EncodedFile(wfile,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1805 self.client.STORAGE_CHARSET,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1806 self.client.charset, 'replace')
3499
230fb5d49c19 CSV encoding support [SF#1240848]
Richard Jones <richard@users.sourceforge.net>
parents: 3484
diff changeset
1807
6190
15fd91fd3c4c Quote all exported CSV data
John Rouillard <rouilj@ieee.org>
parents: 6083
diff changeset
1808 writer = csv.writer(wfile, quoting=csv.QUOTE_NONNUMERIC)
3987
c4f7b3817d3d Prevent broken pipe errors in csv export (patch [SF#911449)
Richard Jones <richard@users.sourceforge.net>
parents: 3913
diff changeset
1809 self.client._socket_op(writer.writerow, columns)
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1810
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1811 # and search
8128
261438b9c91c Use new filtering for csv export variants
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8040
diff changeset
1812 filter = klass.filter_with_permissions
261438b9c91c Use new filtering for csv export variants
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8040
diff changeset
1813 for itemid in filter(matches, filterspec, sort, group):
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1814 row = []
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1815 for name in columns:
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1816 # check permission to view this property on this item
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1817 if not self.hasPermission(self.permissionType, itemid=itemid,
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1818 classname=request.classname,
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1819 property=name):
5614
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1820 # FIXME: is this correct, or should we just
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1821 # emit a '[hidden]' string. Note that this may
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1822 # allow an attacker to figure out hidden schema
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1823 # properties.
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1824 # A bad property name will result in an exception.
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1825 # A valid property results in a column of '[hidden]'
be99aa02c616 issue2550833 enhance the export csv action to include the keys for
John Rouillard <rouilj@ieee.org>
parents: 5515
diff changeset
1826 # values.
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1827 raise exceptions.Unauthorised(self._(
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1828 'You do not have permission to view %(class)s'
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1829 ) % {'class': request.classname})
5652
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1830 value = klass.get(itemid, name)
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1831 try:
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1832 # python2/python 3 have different order in lists
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1833 # sort to not break tests
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1834 value.sort()
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1835 except AttributeError:
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1836 pass # value is not sortable, probably str
9689d1bf9bb0 python2/python3 normalization. When exporting CSV, sort lists as they
John Rouillard <rouilj@ieee.org>
parents: 5614
diff changeset
1837 row.append(str(value))
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
1838 self.client._socket_op(writer.writerow, row)
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1839
8040
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1840 # force close of connection since we can't send a
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1841 # Content-Length header.
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1842 self.client.request.close_connection = True
19cef1e285b0 fix: remove delay when using csv export actions.
John Rouillard <rouilj@ieee.org>
parents: 7582
diff changeset
1843
2112
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1844 return '\n'
b86f0627b07c added CSV download of index / search results
Richard Jones <richard@users.sourceforge.net>
parents: 2108
diff changeset
1845
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1846
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1847 class Bridge(BaseAction):
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1848 """Make roundup.actions.Action executable via CGI request.
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1849
6066
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1850 Using this allows users to write actions executable from multiple
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1851 frontends. CGI Form content is translated into a dictionary, which
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1852 then is passed as argument to 'handle()'. XMLRPC requests have to
b011e5ac06d5 Flake8 whitespace; add translate; change use 'is None' not =
John Rouillard <rouilj@ieee.org>
parents: 5999
diff changeset
1853 pass this dictionary directly.
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1854 """
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1855
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1856 def __init__(self, *args):
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1857
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1858 # As this constructor is callable from multiple frontends, each with
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1859 # different Action interfaces, we have to look at the arguments to
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1860 # figure out how to complete construction.
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1861 if (len(args) == 1 and
6938
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1862 hasattr(args[0], '__class__') and
075d8c6626b0 flake8 fixes
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
1863 args[0].__class__.__name__ == 'Client'):
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1864 self.cgi = True
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1865 self.execute = self.execute_cgi
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1866 self.client = args[0]
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1867 self.form = self.client.form
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1868 else:
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1869 self.cgi = False
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1870
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1871 def execute_cgi(self):
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1872 args = {}
4362
74476eaac38a more modernisation
Richard Jones <richard@users.sourceforge.net>
parents: 4334
diff changeset
1873 for key in self.form:
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1874 args[key] = self.form.getvalue(key)
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1875 self.permission(args)
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1876 return self.handle(args)
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1877
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1878 def permission(self, args):
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1879 """Raise Unauthorised if the current user is not allowed to execute
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1880 this action. Users may override this method."""
4118
878767b75e1d fix the fix for ensuring POST
Richard Jones <richard@users.sourceforge.net>
parents: 4112
diff changeset
1881
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1882 pass
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1883
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1884 def handle(self, args):
4118
878767b75e1d fix the fix for ensuring POST
Richard Jones <richard@users.sourceforge.net>
parents: 4112
diff changeset
1885
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1886 raise NotImplementedError
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4037
diff changeset
1887
2934
c8ee5907f1e2 pychecker cleanup
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2927
diff changeset
1888 # vim: set filetype=python sts=4 sw=4 et si :

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