annotate roundup/rest.py @ 8534:1f8492d68aca

bug: using 'null' value for attributes causes error. In rest.py, filter out any attributes that are set to 'None'. GET on an endpoint can return 'null' values when the attribute is unset. E.G. for a user: { "address": "baddy@example.com", "alternate_addresses": null, "last_login": "2026-03-18.05:57:09", "organisation": null, "password": null, "phone": null, "queries": [], "realname": "Fred Jones", "roles": "User", "timezone": null, "username": "badeggs" } But this json can not be submitted to a PUT or POST endpoint. The validators for passwords, strings, integers etc. don't expect a None value. This change handles attributes with "null" (None) values in json objects by filtering them from the python object before processing. The null value can't be used to unset an attribute via PUT or POST. The 'remove' action using the PATCH verb can unset the value. Also there appears to be some missing checks in the back_anydbm and rdbms_common files for the password type. All the other types have a check: value is not None and not isinstance(.....) but passwords only have the 'not isinstance(....)' part. Not sure why this was the case. Looking at commit history didn't make me think it was intentional.
author John Rouillard <rouilj@ieee.org>
date Wed, 18 Mar 2026 17:24:14 -0400
parents 36be91f671d0
children 5800afdebded
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5557
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
1 """
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
2 Restful API for Roundup
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
3
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
4 This module is free software, you may redistribute it
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
5 and/or modify under the same terms as Python.
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
6 """
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
7
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
8 from __future__ import print_function
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
9
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
10 import hmac
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
11 import json
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
12 import logging
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
13 import os
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
14 import re
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
15 import sys
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
16 import time
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
17 import traceback
8207
894eabf95385 chore(ruff): sort imports.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
18 from datetime import timedelta
894eabf95385 chore(ruff): sort imports.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
19 from hashlib import md5
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
20
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
21 try:
8220
818751637b77 fix: make rest.py still load on python2, do not test bad json
John Rouillard <rouilj@ieee.org>
parents: 8218
diff changeset
22 from json import JSONDecodeError
818751637b77 fix: make rest.py still load on python2, do not test bad json
John Rouillard <rouilj@ieee.org>
parents: 8218
diff changeset
23 except ImportError:
818751637b77 fix: make rest.py still load on python2, do not test bad json
John Rouillard <rouilj@ieee.org>
parents: 8218
diff changeset
24 JSONDecodeError = ValueError
818751637b77 fix: make rest.py still load on python2, do not test bad json
John Rouillard <rouilj@ieee.org>
parents: 8218
diff changeset
25
818751637b77 fix: make rest.py still load on python2, do not test bad json
John Rouillard <rouilj@ieee.org>
parents: 8218
diff changeset
26 try:
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
27 from urllib.parse import urlparse
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
28 except ImportError:
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
29 from urlparse import urlparse
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
30
8207
894eabf95385 chore(ruff): sort imports.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
31 from roundup import actions, date, hyperdb
894eabf95385 chore(ruff): sort imports.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
32 from roundup.anypy.strings import b2s, bs2b, is_us, u2s
894eabf95385 chore(ruff): sort imports.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
33 from roundup.cgi.exceptions import NotFound, PreconditionFailed, Unauthorised
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
34 from roundup.exceptions import Reject, UsageError
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
35 from roundup.i18n import _
8207
894eabf95385 chore(ruff): sort imports.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
36 from roundup.rate_limit import Gcra, RateLimit
8534
1f8492d68aca bug: using 'null' value for attributes causes error.
John Rouillard <rouilj@ieee.org>
parents: 8530
diff changeset
37 from roundup.timer import timer
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
38
6824
9811073b289e replace accidently removed logger setup.
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
39 logger = logging.getLogger('roundup.rest')
9811073b289e replace accidently removed logger setup.
John Rouillard <rouilj@ieee.org>
parents: 6823
diff changeset
40
5631
a5c890d308c3 Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents: 5630
diff changeset
41 try:
8319
5e6ff4e9cacb build: issue2551397: remove support for python 3.6
John Rouillard <rouilj@ieee.org>
parents: 8275
diff changeset
42 # if dicttoxml2
7684
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
43 # is installed in roundup directory, use it
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
44 from roundup.dicttoxml2 import dicttoxml
5631
a5c890d308c3 Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents: 5630
diff changeset
45 except ImportError:
5653
ba67e397f063 Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents: 5646
diff changeset
46 try:
ba67e397f063 Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents: 5646
diff changeset
47 # else look in sys.path
7684
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
48 from dicttoxml2 import dicttoxml
5653
ba67e397f063 Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents: 5646
diff changeset
49 except ImportError:
7684
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
50 try:
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
51 from roundup.dicttoxml import dicttoxml
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
52 except ImportError:
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
53 try:
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
54 # else look in sys.path
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
55 from dicttoxml import dicttoxml
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
56 except ImportError:
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
57 # else not supported
3eca3462ba0c fix: add support for dicttoxml2.py
John Rouillard <rouilj@ieee.org>
parents: 7683
diff changeset
58 dicttoxml = None
5631
a5c890d308c3 Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents: 5630
diff changeset
59
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
60 # Py3 compatible basestring
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
61 try:
8191
30818cc18058 chore(ruff): suppress py2/py3 compatibility code thought useless
John Rouillard <rouilj@ieee.org>
parents: 8190
diff changeset
62 basestring # noqa: B018
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
63 except NameError:
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
64 basestring = str
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
65 unicode = str
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
66
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
67
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
68 def _data_decorator(func):
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
69 """Wrap the returned data into an object."""
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
70 def format_object(self, *args, **kwargs):
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
71 # get the data / error from function
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
72 try:
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
73 code, data = func(self, *args, **kwargs)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
74 except NotFound as msg:
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
75 code = 404
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
76 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
77 except IndexError as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
78 code = 404
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
79 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
80 except Unauthorised as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
81 code = 403
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
82 data = msg
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
83 except (UsageError, KeyError) as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
84 code = 400
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
85 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
86 except (AttributeError, Reject) as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
87 code = 405
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
88 data = msg
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
89 except ValueError as msg:
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
90 code = 409
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
91 data = msg
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
92 except PreconditionFailed as msg:
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
93 code = 412
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
94 data = msg
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
95 except NotImplementedError:
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
96 code = 402 # nothing to pay, just a mark for debugging purpose
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
97 data = 'Method under development'
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
98 except: # noqa: E722
8226
54afcb9149eb chore(lint): mark unused variables in assignment with leading _
John Rouillard <rouilj@ieee.org>
parents: 8220
diff changeset
99 _exc, val, _tb = sys.exc_info()
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
100 code = 400
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
101 ts = time.ctime()
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
102 if getattr(self.client.request, 'DEBUG_MODE', None):
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
103 data = val
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
104 else:
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
105 data = '%s: An error occurred. Please check the server log' \
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
106 ' for more information.' % ts
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
107 # out to the logfile
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
108 print('EXCEPTION AT', ts)
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
109 traceback.print_exc()
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
110
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
111 # decorate it
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
112 self.client.response_code = code
8229
c24b02266077 chore(ruff): handle magic number warnings.
John Rouillard <rouilj@ieee.org>
parents: 8227
diff changeset
113 ERROR_CODE_LOWER_BOUND = 400
c24b02266077 chore(ruff): handle magic number warnings.
John Rouillard <rouilj@ieee.org>
parents: 8227
diff changeset
114 if code >= ERROR_CODE_LOWER_BOUND: # any error require error format
7726
6f66d74d37f3 Add configurable logging for REST
Ralf Schlatterbeck <rsc@runtux.com>
parents: 7684
diff changeset
115 logmethod = getattr(logger, self.db.config.WEB_REST_LOGGING, None)
6f66d74d37f3 Add configurable logging for REST
Ralf Schlatterbeck <rsc@runtux.com>
parents: 7684
diff changeset
116 if logmethod:
6f66d74d37f3 Add configurable logging for REST
Ralf Schlatterbeck <rsc@runtux.com>
parents: 7684
diff changeset
117 logmethod("statuscode: %s" % code)
6f66d74d37f3 Add configurable logging for REST
Ralf Schlatterbeck <rsc@runtux.com>
parents: 7684
diff changeset
118 logmethod('message: "%s"' % data)
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
119 result = {
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
120 'error': {
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
121 'status': code,
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
122 'msg': data
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
123 }
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
124 }
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
125 else:
6185
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
126 if hasattr(self.db, 'stats') and self.report_stats:
8190
569aff540a21 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8188
diff changeset
127 self.db.stats['elapsed'] = time.time() - self.start
6185
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
128 data['@stats'] = self.db.stats
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
129 result = {
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
130 'data': data
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
131 }
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
132 return result
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
133
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
134 format_object.wrapped_func = func
5588
6b3a9655a7d9 Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5587
diff changeset
135 return format_object
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
136
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
137
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
138 def openapi_doc(d):
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
139 """Annotate rest routes with openapi data. Takes a dict
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
140 for the openapi spec. It can be used standalone
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
141 as the openapi spec paths.<path>.<method> =
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
142
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
143 {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
144 "summary": "this path gets a value",
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
145 "description": "a longer description",
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
146 "responses": {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
147 "200": {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
148 "description": "normal response",
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
149 "content": {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
150 "application/json": {},
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
151 "application/xml": {}
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
152 }
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
153 },
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
154 "406": {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
155 "description": "Unable to provide requested content type",
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
156 "content": {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
157 "application/json": {}
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
158 }
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
159 }
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
160 },
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
161 "parameters": [
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
162 {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
163 "$ref": "#components/parameters/generic_.stats"
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
164 },
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
165 {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
166 "$ref": "#components/parameters/generic_.apiver"
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
167 },
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
168 {
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
169 "$ref": "#components/parameters/generic_.verbose"
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
170 }
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
171 ]
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
172 }
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
173 """
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
174
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
175 def wrapper(f):
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
176 f.openapi_doc = d
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
177 return f
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
178 return wrapper
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
179
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
180
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
181 def calculate_etag(node, key, classname="Missing", node_id="0",
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
182 repr_format="json"):
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
183 '''given a hyperdb node generate a hashed representation of it to be
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
184 used as an etag.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
185
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
186 This code needs a __repr__ function in the Password class. This
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
187 replaces the repr(items) which would be:
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
188
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
189 <roundup.password.Password instance at 0x7f3442406170>
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
190
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
191 with the string representation:
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
192
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
193 {PBKDF2}10000$k4d74EDgxlbH...A
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
194
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
195 This makes the representation repeatable as the location of the
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
196 password instance is not static and we need a constant value to
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
197 calculate the etag.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
198
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
199 Note that repr() is chosen for the node rather than str() since
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
200 repr is meant to be an unambiguous representation.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
201
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
202 classname and node_id are used for logging only.
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
203 '''
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
204
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
205 items = node.items(protected=True) # include every item
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
206 etag = hmac.new(bs2b(key), bs2b(repr_format +
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
207 repr(sorted(items))), md5).hexdigest()
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
208 logger.debug("object=%s%s; tag=%s; repr=%s", classname, node_id,
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
209 etag, repr(node.items(protected=True)))
5674
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
210 # Quotes are part of ETag spec, normal headers don't have quotes
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
211 return '"%s"' % etag
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
212
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
213
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
214 def check_etag(node, key, etags, classname="Missing", node_id="0",
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
215 repr_format="json"):
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
216 '''Take a list of etags and compare to the etag for the given node.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
217
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
218 Iterate over all supplied etags,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
219 If a tag fails to match, return False.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
220 If at least one etag matches, return True.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
221 If all etags are None, return False.
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
222
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
223 '''
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
224 have_etag_match = False
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
225
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
226 node_etag = calculate_etag(node, key, classname, node_id,
5729
9ea2ce9d10cf A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents: 5727
diff changeset
227 repr_format=repr_format)
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
228
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
229 for etag in etags:
6539
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
230 # etag includes doublequotes around tag:
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
231 # '"a46a5572190e4fad63958c135f3746fa"'
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
232 # but can include content-encoding suffix like:
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
233 # '"a46a5572190e4fad63958c135f3746fa-gzip"'
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
234 # turn the latter into the former as we don't care what
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
235 # encoding was used to send the body with the etag.
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
236 try:
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
237 suffix_start = etag.rindex('-')
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
238 clean_etag = etag[:suffix_start] + '"'
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
239 except (ValueError, AttributeError):
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
240 # - not in etag or etag is None
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
241 clean_etag = etag
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
242 if clean_etag is not None:
f8df7fed18f6 issue2551175 - Make ETag content-encoding aware.
John Rouillard <rouilj@ieee.org>
parents: 6525
diff changeset
243 if clean_etag != node_etag:
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
244 return False
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
245 have_etag_match = True
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
246
8192
b4d7f9358ba6 chore(ruff): return/suppress boolen directly
John Rouillard <rouilj@ieee.org>
parents: 8191
diff changeset
247 if have_etag_match: # noqa: SIM103 leave for coverage reports
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
248 return True
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
249 return False
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
250
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
251
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
252 def obtain_etags(headers, input_payload):
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
253 '''Get ETags value from headers or payload data
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
254 Only supports one etag value not list.
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
255 '''
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
256 etags = []
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
257 if '@etag' in input_payload:
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
258 etags.append(input_payload['@etag'].value)
5674
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
259 etags.append(headers.get("If-Match", None))
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
260 return etags
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
261
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
262
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
263 def parse_accept_header(accept):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
264 """
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
265 Parse the Accept header *accept*, returning a list with 3-tuples of
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
266 [(str(media_type), dict(params), float(q_value)),] ordered by q values.
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
267
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
268 If the accept header includes vendor-specific types like::
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
269 application/vnd.yourcompany.yourproduct-v1.1+json
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
270
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
271 It will actually convert the vendor and version into parameters and
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
272 convert the content type into `application/json` so appropriate content
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
273 negotiation decisions can be made.
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
274
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
275 Default `q` for values that are not specified is 1.0
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
276
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
277 If q value > 1.0, it is parsed as a very small value.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
278
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
279 # Based on https://gist.github.com/samuraisam/2714195
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
280 # Also, based on a snipped found in this project:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
281 # https://github.com/martinblech/mimerender
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
282 """
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
283 result = []
5731
058ef18af5fd Prevent crash when clients do not set accept header. Use
John Rouillard <rouilj@ieee.org>
parents: 5730
diff changeset
284 if not accept:
058ef18af5fd Prevent crash when clients do not set accept header. Use
John Rouillard <rouilj@ieee.org>
parents: 5730
diff changeset
285 return result
058ef18af5fd Prevent crash when clients do not set accept header. Use
John Rouillard <rouilj@ieee.org>
parents: 5730
diff changeset
286
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
287 for media_range in accept.split(","):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
288 parts = media_range.split(";")
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
289 media_type = parts.pop(0).strip()
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
290 media_params = []
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
291 # convert vendor-specific content types into something useful (see
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
292 # docstring)
6311
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
293 try:
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
294 typ, subtyp = media_type.split('/')
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
295 except ValueError:
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
296 raise UsageError("Invalid media type: %s" % media_type)
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
297 # check for a + in the sub-type
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
298 if '+' in subtyp:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
299 # if it exists, determine if the subtype is a vendor-specific type
8226
54afcb9149eb chore(lint): mark unused variables in assignment with leading _
John Rouillard <rouilj@ieee.org>
parents: 8220
diff changeset
300 vnd, _sep, extra = subtyp.partition('+')
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
301 if vnd.startswith('vnd'):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
302 # and then... if it ends in something like "-v1.1" parse the
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
303 # version out
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
304 if '-v' in vnd:
8226
54afcb9149eb chore(lint): mark unused variables in assignment with leading _
John Rouillard <rouilj@ieee.org>
parents: 8220
diff changeset
305 vnd, _sep, rest = vnd.rpartition('-v')
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
306 if len(rest):
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
307 # add the version as a media param
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
308 try:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
309 media_params.append(('version', rest))
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
310 except ValueError:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
311 pass # return no version value; use rest default
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
312 # add the vendor code as a media param
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
313 media_params.append(('vendor', vnd))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
314 # and re-write media_type to something like application/json so
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
315 # it can be used usefully when looking up emitters
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
316 media_type = '{}/{}'.format(typ, extra)
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
317 q = 1.0
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
318 for part in parts:
6311
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
319 try:
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
320 (key, value) = part.lstrip().split("=", 1)
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
321 except ValueError:
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
322 raise UsageError("Invalid param: %s" % part.lstrip())
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
323 key = key.strip()
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
324 value = value.strip()
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
325 if key == "q":
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
326 q = float(value)
5744
d4de45cde106 Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents: 5740
diff changeset
327 if q > 1.0:
d4de45cde106 Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents: 5740
diff changeset
328 # Not sure what to do here. Can't find spec
d4de45cde106 Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents: 5740
diff changeset
329 # about how to handle q > 1.0. Since invalid
d4de45cde106 Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents: 5740
diff changeset
330 # I choose to make it lowest in priority.
d4de45cde106 Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents: 5740
diff changeset
331 q = 0.0001
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
332 else:
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
333 media_params.append((key, value))
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
334 result.append((media_type, dict(media_params), q))
5653
ba67e397f063 Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents: 5646
diff changeset
335 result.sort(key=lambda x: x[2], reverse=True)
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
336 return result
5567
1af57f9d5bf7 Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5566
diff changeset
337
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
338
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
339 class Routing(object):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
340 __route_map = {}
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
341 __var_to_regex = re.compile(r"<:(\w+)>")
5715
d9a3f6957731 issue2551042 - add extra \ to \w in raw string url_to_regex. Not sure
John Rouillard <rouilj@ieee.org>
parents: 5711
diff changeset
342 url_to_regex = r"([\\w.\-~!$&'()*+,;=:\%%]+)"
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
343
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
344 @classmethod
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
345 def route(cls, rule, methods='GET'):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
346 """A decorator that is used to register a view function for a
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
347 given URL rule:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
348 @self.route('/')
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
349 def index():
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
350 return 'Hello World'
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
351
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
352 rest/ will be added to the beginning of the url string
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
353
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
354 Args:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
355 rule (string): the URL rule
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
356 methods (string or tuple or list): the http method
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
357 """
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
358 # strip the '/' character from rule string
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
359 rule = rule.strip('/')
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
360
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
361 # add 'rest/' to the rule string
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
362 if not rule.startswith('rest/'):
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
363 rule = '^rest/' + rule + '$'
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
364
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
365 if isinstance(methods, basestring): # convert string to tuple
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
366 methods = (methods,)
8193
d06a140eab4d chore(ruff): replace set(generator) with {set comprehension}
John Rouillard <rouilj@ieee.org>
parents: 8192
diff changeset
367 methods = {item.upper() for item in methods}
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
368
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
369 # convert a rule to a compiled regex object
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
370 # so /data/<:class>/<:id> will become
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
371 # /data/([charset]+)/([charset]+)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
372 # and extract the variable names to a list [(class), (id)]
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
373 func_vars = cls.__var_to_regex.findall(rule)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
374 rule = re.compile(cls.__var_to_regex.sub(cls.url_to_regex, rule))
5851
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
375 # Save pattern to represent regex in route_map dictionary
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
376 # The entries consist of a 2-tuple of the (rule, dictionary)
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
377 # where rule is the compiled regex and dictionary contains the
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
378 # func_obj dict indexed by method.
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
379 pattern = rule.pattern
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
380
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
381 # then we decorate it:
5851
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
382 # route_map[pattern] = (rule, func_dict)
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
383 # where func_dict is a dictionary of func_obj (see below)
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
384 # indexed by method name
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
385 def decorator(func):
5851
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
386 rule_route = cls.__route_map.get(pattern, (rule, {}))
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
387 rule_dict = rule_route[1]
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
388 func_obj = {
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
389 'func': func,
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
390 'vars': func_vars
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
391 }
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
392 for method in methods:
5851
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
393 rule_dict[method] = func_obj
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
394 cls.__route_map[pattern] = rule_route
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
395 return func
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
396 return decorator
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
397
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
398 @classmethod
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
399 def execute(cls, instance, path, method, input_payload):
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
400 # format the input_payload, note that we may not lowercase the path
5679
df9eb574b717 REST: Bug-fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5678
diff changeset
401 # here, URL parameters are case-sensitive
df9eb574b717 REST: Bug-fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5678
diff changeset
402 path = path.strip('/')
5622
2a7d23a098ca Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents: 5621
diff changeset
403 if path == 'rest':
2a7d23a098ca Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents: 5621
diff changeset
404 # allow handler to be called for /rest/
2a7d23a098ca Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents: 5621
diff changeset
405 path = 'rest/'
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
406 method = method.upper()
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
407
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
408 # find the rule match the path
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
409 # then get handler match the method
5851
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
410 for path_regex, funcs in cls.__route_map.values():
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
411 # use compiled regex to find rule
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
412 match_obj = path_regex.match(path)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
413 if match_obj:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
414 try:
5851
167ef847fcdf issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5842
diff changeset
415 func_obj = funcs[method]
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
416 except KeyError:
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
417 valid_methods = ', '.join(sorted(funcs.keys()))
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
418 raise Reject(_('Method %(m)s not allowed. '
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
419 'Allowed: %(a)s') % {
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
420 'm': method,
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
421 'a': valid_methods
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
422 },
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
423 valid_methods)
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
424
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
425 # retrieve the vars list and the function caller
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
426 list_vars = func_obj['vars']
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
427 func = func_obj['func']
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
428
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
429 # zip the varlist into a dictionary, and pass it to the caller
8472
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
430 # FIXME: 3.10 is min version- add strict=True to zip
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
431 # also wrap with try/except ValueError if different number of
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
432 # items (which should never happen).
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
433 args = dict(zip(list_vars, match_obj.groups()))
8196
94999f850fd6 fix: missed on input -> input_payload on e5362f8e1808
John Rouillard <rouilj@ieee.org>
parents: 8195
diff changeset
434 args['input_payload'] = input_payload
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
435 return func(instance, **args)
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
436 raise NotFound('Nothing matches the given URI')
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
437
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
438
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
439 class RestfulInstance(object):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
440 """The RestfulInstance performs REST request from the client"""
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
441
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
442 __default_patch_op = "replace" # default operator for PATCH method
5594
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
443 __accepted_content_type = {
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
444 "application/json": "json",
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
445 }
864cf6cb5790 Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5593
diff changeset
446 __default_accept_type = "json"
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
447
5685
4b4885f0c6ad Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents: 5682
diff changeset
448 __default_api_version = 1
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
449 __supported_api_versions = [1]
5687
83037aaf3b9d Move definition/initialization of api_version into the class and out
John Rouillard <rouilj@ieee.org>
parents: 5686
diff changeset
450
83037aaf3b9d Move definition/initialization of api_version into the class and out
John Rouillard <rouilj@ieee.org>
parents: 5686
diff changeset
451 api_version = None
83037aaf3b9d Move definition/initialization of api_version into the class and out
John Rouillard <rouilj@ieee.org>
parents: 5686
diff changeset
452
7853
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
453 # allow 10M row response - can change using interfaces.py
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
454 # limit is 1 less than this size.
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
455 max_response_row_size = 10000001
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
456
5568
edab9daa8015 Make objects returned by REST follow the standard
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5567
diff changeset
457 def __init__(self, client, db):
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
458 self.client = client
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
459 self.db = db
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
460 self.translator = client.translator
6185
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
461 # record start time for statistics reporting
7683
b04e222501b8 fix: rest - set self.start from client.start
John Rouillard <rouilj@ieee.org>
parents: 7605
diff changeset
462 self.start = client.start
6185
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
463 # disable stat reporting by default enable with @stats=True
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
464 # query param
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
465 self.report_stats = False
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
466 # This used to be initialized from client.instance.actions which
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
467 # would include too many actions that do not make sense in the
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
468 # REST-API context, so for now we only permit the retire and
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
469 # restore actions.
8201
d5ad7fcb9bf6 chore(ruff): replace dict(...) with equivalent {...}
John Rouillard <rouilj@ieee.org>
parents: 8199
diff changeset
470 self.actions = {"retire": actions.Retire, "restore": actions.Restore}
5556
d75aa88c2a99 Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff changeset
471
5616
aa4c271514ae Original code generated url's using a harcoded protocol and took the
John Rouillard <rouilj@ieee.org>
parents: 5604
diff changeset
472 # note TRACKER_WEB ends in a /
aa4c271514ae Original code generated url's using a harcoded protocol and took the
John Rouillard <rouilj@ieee.org>
parents: 5604
diff changeset
473 self.base_path = '%srest' % (self.db.config.TRACKER_WEB)
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
474 self.data_path = self.base_path + '/data'
5569
2718aeb55ffa Add base_path to generate uri
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5568
diff changeset
475
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
476 if dicttoxml: # add xml if supported
5744
d4de45cde106 Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents: 5740
diff changeset
477 self.__accepted_content_type["application/xml"] = "xml"
d4de45cde106 Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents: 5740
diff changeset
478
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
479 def props_from_args(self, cl, args, itemid=None, skip_protected=True):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
480 """Construct a list of properties from the given arguments,
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
481 and return them after validation.
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
482
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
483 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
484 cl (string): class object of the resource
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
485 args (list): the submitted form of the user
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
486 itemid (string, optional): itemid of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
487
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
488 Returns:
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
489 dict: dictionary of validated properties excluding
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
490 protected properties if strip_protected=True.
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
491
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
492 Raises: UsageError if property does not exist and is not
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
493 prefixed with @ indicating it's a meta variable.
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
494
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
495
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
496 """
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
497 unprotected_class_props = cl.properties.keys()
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
498 protected_class_props = [p for p in
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
499 list(cl.getprops(protected=True))
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
500 if p not in unprotected_class_props]
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
501 props = {}
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
502 # props = dict.fromkeys(class_props, None)
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
503
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
504 if not args:
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
505 raise UsageError("No properties found.")
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
506
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
507 for arg in args:
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
508 key = arg.name
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
509 value = arg.value
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
510 if key.startswith('@'):
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
511 # meta setting, not db property setting/reference
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
512 continue
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
513 if key in protected_class_props:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
514 # Skip protected props as a convenience.
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
515 # Allows user to get object with all props,
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
516 # change one prop, submit entire object
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
517 # without having to remove any protected props
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
518 # FIXME: Enhancement: raise error if value of prop
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
519 # doesn't match db entry. In this case assume user
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
520 # is really trying to set value. Another possibility is
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
521 # they have an old copy of the data and it has been
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
522 # updated. In the update case, we want etag validation
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
523 # to generate the exception to reduce confusion. I think
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
524 # etag validation occurs before this function is called but
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
525 # I am not positive.
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
526 if skip_protected:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
527 continue
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
528 elif key not in unprotected_class_props:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
529 # report bad props as this is an error.
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
530 raise UsageError("Property %s not found in class %s" % (key,
8206
8656bd1cf1f1 chore(ruff): clean whitespace and remove unrecognized noqa directive.
John Rouillard <rouilj@ieee.org>
parents: 8205
diff changeset
531 cl.classname))
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
532 props[key] = self.prop_from_arg(cl, key, value, itemid)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
533
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
534 return props
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
535
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
536 def prop_from_arg(self, cl, key, value, itemid=None):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
537 """Construct a property from the given argument,
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
538 and return them after validation.
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
539
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
540 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
541 cl (string): class object of the resource
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
542 key (string): attribute key
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
543 value (string): attribute value
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
544 itemid (string, optional): itemid of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
545
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
546 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
547 value: value of validated properties
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
548
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
549 """
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
550 prop = None
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
551 if isinstance(key, unicode):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
552 try:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
553 key.encode('ascii') # Check to see if it can be encoded
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
554 except UnicodeEncodeError:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
555 raise UsageError(
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
556 'argument %r is not a valid ascii keyword' % key
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
557 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
558 if value:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
559 try:
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
560 prop = hyperdb.rawToHyperdb(self.db, cl, itemid, key, value)
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
561 except hyperdb.HyperdbValueError as msg:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
562 raise UsageError(msg)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
563
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
564 return prop
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
565
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
566 def transitive_props(self, class_name, props):
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
567 """Construct a list of transitive properties from the given
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
568 argument, and return it after permission check. Raises
6111
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
569 Unauthorised if no permission. Permission is checked by
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
570 checking View permission on each component. We do not allow to
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
571 traverse multilinks -- the last item of an expansion *may* be a
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
572 multilink but in the middle of a transitive prop.
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
573 """
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
574 checked_props = []
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
575 uid = self.db.getuid()
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
576 for p in props:
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
577 pn = p
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
578 cn = class_name
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
579 if '.' in p:
6111
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
580 prop = None
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
581 for pn in p.split('.'):
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
582 # Tried to dereference a non-Link property
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
583 if cn is None:
8190
569aff540a21 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8188
diff changeset
584 raise UsageError("Property %(base)s can not be dereferenced in %(p)s." % {"base": p[:-(len(pn) + 1)], "p": p})
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
585 cls = self.db.getclass(cn)
6111
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
586 # This raises a KeyError for unknown prop:
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
587 try:
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
588 prop = cls.getprops(protected=True)[pn]
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
589 except KeyError:
6554
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
590 raise KeyError("Unknown property: %s" % p)
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
591 if isinstance(prop, hyperdb.Multilink):
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
592 raise UsageError(
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
593 'Multilink Traversal not allowed: %s' % p)
6111
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
594 # Now we have the classname in cn and the prop name in pn.
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
595 if not self.db.security.hasPermission('View', uid, cn, pn):
7569
940f06dac1b4 flake8: add space between raise and (
John Rouillard <rouilj@ieee.org>
parents: 7552
diff changeset
596 raise (Unauthorised
6111
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
597 ('User does not have permission on "%s.%s"'
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
598 % (cn, pn)))
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
599 try:
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
600 cn = prop.classname
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
601 except AttributeError:
2a513a057691 Fix transitive property check in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6091
diff changeset
602 cn = None
6554
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
603 else:
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
604 cls = self.db.getclass(cn)
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
605 # This raises a KeyError for unknown prop:
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
606 try:
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
607 prop = cls.getprops(protected=True)[pn]
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
608 except KeyError:
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
609 raise KeyError("Unknown property: %s" % pn)
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
610 checked_props.append(p)
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
611 return checked_props
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
612
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
613 def error_obj(self, status, msg, source=None):
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
614 """Return an error object"""
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
615 self.client.response_code = status
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
616 result = {
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
617 'error': {
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
618 'status': status,
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
619 'msg': msg
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
620 }
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
621 }
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
622 if source is not None:
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
623 result['error']['source'] = source
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
624
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
625 return result
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
626
5595
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
627 def patch_data(self, op, old_val, new_val):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
628 """Perform patch operation based on old_val and new_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
629
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
630 Args:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
631 op (string): PATCH operation: add, replace, remove
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
632 old_val: old value of the property
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
633 new_val: new value of the property
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
634
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
635 Returns:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
636 result (string): value after performed the operation
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
637 """
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
638 # add operation: If neither of the value is None, use the other one
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
639 # Otherwise, concat those 2 value
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
640 if op == 'add':
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
641 if old_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
642 result = new_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
643 elif new_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
644 result = old_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
645 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
646 result = old_val + new_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
647 # Replace operation: new value is returned
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
648 elif op == 'replace':
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
649 result = new_val
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
650 # Remove operation:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
651 # if old_val is not a list/dict, change it to None
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
652 # if old_val is a list/dict, but the parameter is empty,
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
653 # change it to none
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
654 # if old_val is a list/dict, and parameter is not empty
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
655 # proceed to remove the values from parameter from the list/dict
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
656 elif op == 'remove':
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
657 if isinstance(old_val, list):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
658 if new_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
659 result = []
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
660 elif isinstance(new_val, list):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
661 result = [x for x in old_val if x not in new_val]
8198
de6b02c23ee9 chore(ruff): replace 'else: if bool_exp:' with 'elif bool_exp:'
John Rouillard <rouilj@ieee.org>
parents: 8197
diff changeset
662 elif new_val in old_val:
de6b02c23ee9 chore(ruff): replace 'else: if bool_exp:' with 'elif bool_exp:'
John Rouillard <rouilj@ieee.org>
parents: 8197
diff changeset
663 old_val.remove(new_val)
5595
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
664 elif isinstance(old_val, dict):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
665 if new_val is None:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
666 result = {}
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
667 elif isinstance(new_val, dict):
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
668 for x in new_val:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
669 old_val.pop(x, None)
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
670 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
671 old_val.pop(new_val, None)
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
672 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
673 result = None
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
674 else:
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
675 raise UsageError('PATCH Operation %s is not allowed' % op)
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
676
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
677 return result
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
678
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
679 def raise_if_no_etag(self, class_name, item_id, input_payload,
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
680 repr_format="json"):
5674
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
681 class_obj = self.db.getclass(class_name)
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
682 if not check_etag(class_obj.getnode(item_id),
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
683 self.db.config.WEB_SECRET_KEY,
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
684 obtain_etags(self.client.request.headers,
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
685 input_payload), class_name, item_id,
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
686 repr_format=repr_format):
5674
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
687 raise PreconditionFailed(
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
688 "If-Match is missing or does not match."
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
689 " Retrieve asset and retry modification if valid.")
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
690
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
691 def format_item(self, node, item_id, props=None, verbose=1):
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
692 ''' display class obj as requested by verbose and
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
693 props.
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
694 '''
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
695 uid = self.db.getuid()
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
696 class_name = node.cl.classname
5685
4b4885f0c6ad Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents: 5682
diff changeset
697
5740
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
698 # version never gets used since we only
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
699 # support version 1 at this time. Set it as
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
700 # placeholder for later use.
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
701 if self.api_version is None:
8230
eb45feb1d01e chore(ruff): remove unused noqa comments.
John Rouillard <rouilj@ieee.org>
parents: 8229
diff changeset
702 version = self.__default_api_version
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
703 else:
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
704 version = self.api_version # noqa: F841
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
705
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
706 result = {}
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
707 try:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
708 # pn = propname
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
709 for pn in sorted(props):
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
710 ok = False
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
711 working_id = item_id
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
712 nd = node
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
713 cn = class_name
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
714 for p in pn.split('.'):
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
715 if not self.db.security.hasPermission(
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
716 'View', uid, cn, p, working_id
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
717 ):
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
718 break
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
719 cl = self.db.getclass(cn)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
720 nd = cl.getnode(working_id)
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
721 working_id = v = getattr(nd, p)
6254
5b66c480f71f Handle empty Link for transitive property
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6185
diff changeset
722 # Handle transitive properties where something on
5b66c480f71f Handle empty Link for transitive property
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6185
diff changeset
723 # the road is None (empty Link property)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
724 if working_id is None:
6254
5b66c480f71f Handle empty Link for transitive property
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6185
diff changeset
725 prop = None
5b66c480f71f Handle empty Link for transitive property
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6185
diff changeset
726 ok = True
5b66c480f71f Handle empty Link for transitive property
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6185
diff changeset
727 break
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
728 prop = cl.getprops(protected=True)[p]
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
729 cn = getattr(prop, 'classname', None)
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
730 else:
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
731 ok = True
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
732 if not ok:
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
733 continue
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
734 if isinstance(prop, (hyperdb.Link, hyperdb.Multilink)):
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
735 linkcls = self.db.getclass(prop.classname)
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
736 cp = '%s/%s/' % (self.data_path, prop.classname)
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
737 if verbose and v:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
738 if isinstance(v, type([])):
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
739 r = []
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
740 for working_id in v:
8201
d5ad7fcb9bf6 chore(ruff): replace dict(...) with equivalent {...}
John Rouillard <rouilj@ieee.org>
parents: 8199
diff changeset
741 d = {"id": working_id,
d5ad7fcb9bf6 chore(ruff): replace dict(...) with equivalent {...}
John Rouillard <rouilj@ieee.org>
parents: 8199
diff changeset
742 "link": cp + working_id}
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
743 if verbose > 1:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
744 label = linkcls.labelprop()
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
745 d[label] = linkcls.get(working_id, label)
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
746 r.append(d)
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
747 result[pn] = r
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
748 else:
8201
d5ad7fcb9bf6 chore(ruff): replace dict(...) with equivalent {...}
John Rouillard <rouilj@ieee.org>
parents: 8199
diff changeset
749 result[pn] = {"id": v, "link": cp + v}
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
750 if verbose > 1:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
751 label = linkcls.labelprop()
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
752 result[pn][label] = linkcls.get(v, label)
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
753 else:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
754 result[pn] = v
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
755 elif isinstance(prop, hyperdb.String) and pn == 'content':
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
756 # Do not show the (possibly HUGE) content prop
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
757 # unless very verbose, we display the standard
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
758 # download link instead
8229
c24b02266077 chore(ruff): handle magic number warnings.
John Rouillard <rouilj@ieee.org>
parents: 8227
diff changeset
759 MIN_VERBOSE_LEVEL_SHOW_CONTENT = 3
c24b02266077 chore(ruff): handle magic number warnings.
John Rouillard <rouilj@ieee.org>
parents: 8227
diff changeset
760 if verbose < MIN_VERBOSE_LEVEL_SHOW_CONTENT:
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
761 u = self.db.config.TRACKER_WEB
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
762 p = u + '%s%s/' % (class_name, node.id)
8201
d5ad7fcb9bf6 chore(ruff): replace dict(...) with equivalent {...}
John Rouillard <rouilj@ieee.org>
parents: 8199
diff changeset
763 result[pn] = {"link": p}
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
764 else:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
765 result[pn] = v
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
766 elif isinstance(prop, hyperdb.Password):
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
767 if v is not None: # locked users like anonymous have None
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
768 result[pn] = "[password hidden scheme %s]" % v.scheme
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
769 else:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
770 # Don't divulge it's a locked account. Choose most
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
771 # secure as default.
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
772 result[pn] = "[password hidden scheme PBKDF2]"
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
773 else:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
774 result[pn] = v
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
775 except KeyError as msg:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
776 raise UsageError("%s field not valid" % msg)
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
777
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
778 return result
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
779
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
780 @Routing.route("/data/<:class_name>", 'GET')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
781 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
782 def get_collection(self, class_name, input_payload):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
783 """GET resource from class URI.
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
784
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
785 This function returns only items have View permission
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
786 class_name should be valid already
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
787
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
788 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
789 class_name (string): class name of the resource (Ex: issue, msg)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
790 input_payload (list): the submitted form of the user
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
791
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
792 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
793 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
794 list: list of reference item in the class
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
795 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
796 link: path to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
797 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
798 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
799 raise NotFound('Class %s not found' % class_name)
5677
1fa59181ce58 Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents: 5674
diff changeset
800
1fa59181ce58 Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents: 5674
diff changeset
801 uid = self.db.getuid()
1fa59181ce58 Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents: 5674
diff changeset
802
5864
5e8e160fe2a0 Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5851
diff changeset
803 if not self.db.security.hasPermission('View', uid, class_name):
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
804 raise Unauthorised('Permission to view %s denied' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
805
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
806 class_obj = self.db.getclass(class_name)
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
807 class_path = '%s/%s/' % (self.data_path, class_name)
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
808
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
809 # Handle filtering and pagination
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
810 filter_props = {}
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
811 exact_props = {}
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
812 page = {
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
813 'size': None,
7853
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
814 'index': 1, # setting just size starts at page 1
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
815 }
5677
1fa59181ce58 Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents: 5674
diff changeset
816 verbose = 1
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
817 display_props = set()
5865
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
818 sort = []
7854
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
819 group = []
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
820 for form_field in input_payload.value:
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
821 key = form_field.name
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
822 value = form_field.value
5659
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
823 if key.startswith("@page_"): # serve the paging purpose
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
824 key = key[6:]
8213
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
825 try:
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
826 value = int(value)
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
827 except ValueError as e:
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
828 raise UsageError("When using @page_%s: %s" %
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
829 (key, e.args[0]))
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
830 page[key] = value
5677
1fa59181ce58 Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents: 5674
diff changeset
831 elif key == "@verbose":
8213
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
832 try:
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
833 verbose = int(value)
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
834 except ValueError as e:
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
835 raise UsageError("When using @verbose: %s" %
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
836 (e.args[0]))
8197
5b8d1cb290cb chore(ruff): replace 'x == y or x == z' with 'x in [y,z]'
John Rouillard <rouilj@ieee.org>
parents: 8196
diff changeset
837 elif key in ["@fields", "@attrs"]:
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
838 f = value.split(",")
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
839 if len(f) == 1:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
840 f = value.split(":")
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
841 display_props.update(self.transitive_props(class_name, f))
5865
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
842 elif key == "@sort":
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
843 f = value.split(",")
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
844 for p in f:
5865
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
845 if not p:
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
846 raise UsageError("Empty property "
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
847 "for class %s." % (class_name))
5865
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
848 if p[0] in ('-', '+'):
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
849 pn = p[1:]
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
850 ss = p[0]
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
851 else:
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
852 ss = '+'
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
853 pn = p
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
854 # Only include properties where we have search permission
5872
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
855 # Note that hasSearchPermission already returns 0 for
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
856 # non-existing properties.
5865
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
857 if self.db.security.hasSearchPermission(
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
858 uid, class_name, pn
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
859 ):
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
860 sort.append((ss, pn))
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
861 else:
6088
00a24243887c Remove redundant permission check
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6086
diff changeset
862 raise (Unauthorised(
6086
c172bd18fa94 REST API: 403 on non-searchable properties
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6009
diff changeset
863 'User does not have search permission on "%s.%s"'
c172bd18fa94 REST API: 403 on non-searchable properties
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6009
diff changeset
864 % (class_name, pn)))
7854
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
865 elif key == "@group":
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
866 f = value.split(",")
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
867 for p in f:
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
868 if not p:
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
869 raise UsageError("Empty property "
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
870 "for class %s." % (class_name))
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
871 if p[0] in ('-', '+'):
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
872 pn = p[1:]
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
873 ss = p[0]
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
874 else:
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
875 ss = '+'
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
876 pn = p
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
877 # Only include properties where we have search permission
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
878 # Note that hasSearchPermission already returns 0 for
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
879 # non-existing properties.
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
880 if self.db.security.hasSearchPermission(
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
881 uid, class_name, pn
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
882 ):
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
883 group.append((ss, pn))
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
884 else:
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
885 raise (Unauthorised(
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
886 'User does not have search permission on "%s.%s"'
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
887 % (class_name, pn)))
5691
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
888 elif key.startswith("@"):
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
889 # ignore any unsupported/previously handled control key
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
890 # like @apiver
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
891 pass
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
892 else: # serve the filter purpose
5874
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
893 exact = False
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
894 if key.endswith(':'):
5874
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
895 exact = True
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
896 key = key[:-1]
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
897 elif key.endswith('~'):
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
898 key = key[:-1]
5872
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
899 p = key.split('.', 1)[0]
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
900 try:
5872
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
901 prop = class_obj.getprops()[p]
5691
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
902 except KeyError:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
903 raise UsageError("Field %s is not valid for %s class." %
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
904 (p, class_name))
6554
576d630fc908 Fix error status for invalid props
John Rouillard <rouilj@ieee.org>
parents: 6544
diff changeset
905 # Call this for the side effect of validating the key
6559
178705fbeaa8 Change _ = to _discard = as _ is the translation service global
John Rouillard <rouilj@ieee.org>
parents: 6554
diff changeset
906 # use _discard as _ is apparently a global for the translation
178705fbeaa8 Change _ = to _discard = as _ is the translation service global
John Rouillard <rouilj@ieee.org>
parents: 6554
diff changeset
907 # service.
8230
eb45feb1d01e chore(ruff): remove unused noqa comments.
John Rouillard <rouilj@ieee.org>
parents: 8229
diff changeset
908 _discard = self.transitive_props(class_name, [key])
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
909
5659
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
910 # We drop properties without search permission silently
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
911 # This reflects the current behavior of other roundup
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
912 # interfaces
5872
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
913 # Note that hasSearchPermission already returns 0 for
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
914 # non-existing properties.
5659
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
915 if not self.db.security.hasSearchPermission(
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
916 uid, class_name, key
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
917 ):
6088
00a24243887c Remove redundant permission check
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6086
diff changeset
918 raise (Unauthorised(
6086
c172bd18fa94 REST API: 403 on non-searchable properties
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6009
diff changeset
919 'User does not have search permission on "%s.%s"'
c172bd18fa94 REST API: 403 on non-searchable properties
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6009
diff changeset
920 % (class_name, key)))
5872
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
921
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
922 linkcls = class_obj
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
923 for p in key.split('.'):
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
924 prop = linkcls.getprops(protected=True)[p]
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
925 linkcls = getattr(prop, 'classname', None)
5872
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
926 if linkcls:
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
927 linkcls = self.db.getclass(linkcls)
1b91e3df3fd0 Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5870
diff changeset
928
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
929 if isinstance(prop, (hyperdb.Link, hyperdb.Multilink)):
5842
9c6617857032 Support use of duplicate rest filters keys. So URL's like:
John Rouillard <rouilj@ieee.org>
parents: 5824
diff changeset
930 if key in filter_props:
9c6617857032 Support use of duplicate rest filters keys. So URL's like:
John Rouillard <rouilj@ieee.org>
parents: 5824
diff changeset
931 vals = filter_props[key]
9c6617857032 Support use of duplicate rest filters keys. So URL's like:
John Rouillard <rouilj@ieee.org>
parents: 5824
diff changeset
932 else:
9c6617857032 Support use of duplicate rest filters keys. So URL's like:
John Rouillard <rouilj@ieee.org>
parents: 5824
diff changeset
933 vals = []
5659
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
934 for p in value.split(","):
8195
beab1ba70d34 chore(ruff): parenthesize "a and b or ..." to enforce/clarify precedence
John Rouillard <rouilj@ieee.org>
parents: 8194
diff changeset
935 dig = (p and p.isdigit()) or \
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
936 (p[0] in ('-', '+') and p[1:].isdigit())
5904
2b78e21d7047 Fix lookup of negative ids
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5874
diff changeset
937 if prop.try_id_parsing and dig:
5659
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
938 vals.append(p)
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
939 else:
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
940 vals.append(linkcls.lookup(p))
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
941 filter_props[key] = vals
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
942 else:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
943 if not isinstance(prop, hyperdb.String):
5874
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
944 exact = False
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
945 props = filter_props
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
946 if exact:
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
947 props = exact_props
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
948 if key in props:
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
949 if isinstance(props[key], list):
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
950 props[key].append(value)
5842
9c6617857032 Support use of duplicate rest filters keys. So URL's like:
John Rouillard <rouilj@ieee.org>
parents: 5824
diff changeset
951 else:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
952 props[key] = [props[key], value]
5842
9c6617857032 Support use of duplicate rest filters keys. So URL's like:
John Rouillard <rouilj@ieee.org>
parents: 5824
diff changeset
953 else:
5874
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
954 props[key] = value
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
955 l = [filter_props] # noqa: E741
5870
5ae426616576 Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5865
diff changeset
956 kw = {}
5865
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
957 if sort:
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
958 l.append(sort)
7854
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
959 if group:
171ff2e487df Add @group for grouping in rest interface.
John Rouillard <rouilj@ieee.org>
parents: 7853
diff changeset
960 l.append(group)
5874
6630baff5f68 Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5873
diff changeset
961 if exact_props:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
962 kw['exact_match_spec'] = exact_props
7853
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
963 if page['size'] is None:
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
964 kw['limit'] = self.max_response_row_size
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
965 elif page['size'] > 0:
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
966 if page['size'] >= self.max_response_row_size:
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
967 raise UsageError(_(
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
968 "Page size %(page_size)s must be less than admin "
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
969 "limit on query result size: %(max_size)s.") % {
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
970 "page_size": page['size'],
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
971 "max_size": self.max_response_row_size,
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
972 })
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
973 kw['limit'] = self.max_response_row_size
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
974 if page['index'] is not None and page['index'] > 1:
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
975 kw['offset'] = (page['index'] - 1) * page['size']
8126
f7bd22bdef9d Move permission check code to hyperdb
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8094
diff changeset
976 obj_list = class_obj.filter_with_permissions(None, *l, **kw)
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
977
7853
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
978 # Have we hit the max number of returned rows?
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
979 # If so there may be more data that the client
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
980 # has to explicitly page through using offset/@page_index.
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
981 overflow = len(obj_list) == self.max_response_row_size
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
982
5865
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
983 # Note: We don't sort explicitly in python. The filter implementation
04deafac71ab Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5864
diff changeset
984 # of the DB already sorts by ID if no sort option was given.
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
985
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
986 # add verbose elements. 2 and above get identifying label.
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
987 if verbose > 1:
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
988 lp = class_obj.labelprop()
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
989 display_props.add(lp)
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
990
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
991 # extract result from data
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
992 result = {}
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
993 result['collection'] = []
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
994 for item_id in obj_list:
5864
5e8e160fe2a0 Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5851
diff changeset
995 r = {}
8126
f7bd22bdef9d Move permission check code to hyperdb
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8094
diff changeset
996 # No need to check permission on id here, as we have only
f7bd22bdef9d Move permission check code to hyperdb
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8094
diff changeset
997 # security-checked results
f7bd22bdef9d Move permission check code to hyperdb
Ralf Schlatterbeck <rsc@runtux.com>
parents: 8094
diff changeset
998 r = {'id': item_id, 'link': class_path + item_id}
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
999 if display_props:
6088
00a24243887c Remove redundant permission check
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6086
diff changeset
1000 # format_item does the permission checks
00a24243887c Remove redundant permission check
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6086
diff changeset
1001 r.update(self.format_item(class_obj.getnode(item_id),
00a24243887c Remove redundant permission check
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6086
diff changeset
1002 item_id, props=display_props, verbose=verbose))
5864
5e8e160fe2a0 Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5851
diff changeset
1003 if r:
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1004 result['collection'].append(r)
5677
1fa59181ce58 Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents: 5674
diff changeset
1005
5639
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1006 result_len = len(result['collection'])
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
1007
7853
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1008 if not overflow: # noqa: SIM108 - no nested ternary
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1009 # add back the number of items in the offset.
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1010 total_len = kw['offset'] + result_len if 'offset' in kw \
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1011 else result_len
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1012 else:
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1013 # we have hit the max number of rows configured to be
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1014 # returned. We hae no idea how many rows can match. We
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1015 # could use 0 as the sentinel, but a filter could match 0
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1016 # rows. So return -1 indicating we exceeded the result
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1017 # max size on this query.
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1018 total_len = -1
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1019
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1020 # truncate result['collection'] to page size
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1021 if page['size'] is not None and page['size'] > 0:
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1022 result['collection'] = result['collection'][:page['size']]
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1023
5639
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1024 # pagination - page_index from 1...N
5870
5ae426616576 Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5865
diff changeset
1025 if page['size'] is not None and page['size'] > 0:
5639
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1026 result['@links'] = {}
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1027 for rel in ('next', 'prev', 'self'):
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1028 if rel == 'next':
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1029 # if current index includes all data, continue
7853
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1030 if page['size'] >= result_len: continue # noqa: E701
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1031 index = page['index'] + 1
5639
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1032 if rel == 'prev':
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1033 if page['index'] <= 1: continue # noqa: E701
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1034 index = page['index'] - 1
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1035 if rel == 'self': index = page['index'] # noqa: E701
5591
a25d79e874cb Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5590
diff changeset
1036
5639
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1037 result['@links'][rel] = []
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1038 result['@links'][rel].append({
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1039 'rel': rel,
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1040 'uri': "%s/%s?@page_index=%s&" % (self.data_path,
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1041 class_name, index) +
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1042 '&'.join(["%s=%s" % (field.name, field.value)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1043 for field in input_payload.value
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1044 if field.name != "@page_index"])})
5639
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
1045
7853
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1046 result['@total_size'] = total_len
03c1b7ae3a68 issue2551328/issue2551264 unneeded next link and total_count incorrect
John Rouillard <rouilj@ieee.org>
parents: 7750
diff changeset
1047 self.client.setHeader("X-Count-Total", str(total_len))
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1048 self.client.setHeader("Allow", "OPTIONS, GET, POST")
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
1049 return 200, result
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1050
7971
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1051 @Routing.route("/data/user/roles", 'GET')
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1052 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1053 def get_roles(self, input_payload):
7971
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1054 """Return all defined roles for users with Admin role.
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1055 The User class property roles is a string but simulate
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1056 it as a MultiLink to an actual Roles class.
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1057 """
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1058 if not self.client.db.user.has_role(self.client.db.getuid(), "Admin"):
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1059 raise Unauthorised(
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1060 'User does not have permission on "user.roles"')
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1061
7983
dd229bbdd32d issue 2551353 - add roundup-classhelper
John Rouillard <rouilj@ieee.org>
parents: 7971
diff changeset
1062 self.client.setHeader(
dd229bbdd32d issue 2551353 - add roundup-classhelper
John Rouillard <rouilj@ieee.org>
parents: 7971
diff changeset
1063 "Allow",
dd229bbdd32d issue 2551353 - add roundup-classhelper
John Rouillard <rouilj@ieee.org>
parents: 7971
diff changeset
1064 "GET"
dd229bbdd32d issue 2551353 - add roundup-classhelper
John Rouillard <rouilj@ieee.org>
parents: 7971
diff changeset
1065 )
dd229bbdd32d issue 2551353 - add roundup-classhelper
John Rouillard <rouilj@ieee.org>
parents: 7971
diff changeset
1066
7971
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1067 return 200, {"collection":
8190
569aff540a21 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8188
diff changeset
1068 [{"id": rolename, "name": rolename}
7971
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1069 for rolename in list(self.db.security.role.keys())]}
fe0348bbe45b issue2551353 - Add roundup-classhelper for 2.4.0 release
John Rouillard <rouilj@ieee.org>
parents: 7854
diff changeset
1070
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1071 @Routing.route("/data/<:class_name>/<:item_id>", 'GET')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1072 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1073 def get_element(self, class_name, item_id, input_payload):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1074 """GET resource from object URI.
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1075
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1076 This function returns only properties have View permission
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1077 class_name and item_id should be valid already
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1078
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1079 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1080 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1081 item_id (string): id of the resource (Ex: 12, 15)
5678
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1082 or (if the class has a key property) this can also be
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1083 the key name, e.g. class_name = status, item_id = 'open'
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1084 input_payload (list): the submitted form of the user
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1085
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1086 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1087 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1088 dict: a dictionary represents the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1089 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1090 type: class name of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1091 link: link to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1092 attributes: a dictionary represent the attributes of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1093 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1094 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1095 raise NotFound('Class %s not found' % class_name)
5678
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1096 class_obj = self.db.getclass(class_name)
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1097 uid = self.db.getuid()
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1098 # If it's not numeric it is a key
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1099 if item_id.isdigit():
5679
df9eb574b717 REST: Bug-fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5678
diff changeset
1100 itemid = item_id
5678
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1101 else:
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1102 keyprop = class_obj.getkey()
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1103 try:
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1104 k, v = item_id.split('=', 1)
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1105 if k != keyprop:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1106 raise UsageError("Field %s is not key property" % k)
5678
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1107 except ValueError:
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1108 v = item_id
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1109 if not self.db.security.hasPermission(
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1110 'View', uid, class_name, itemid=item_id, property=keyprop
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1111 ):
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1112 raise Unauthorised(
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1113 'Permission to view %s%s.%s denied'
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1114 % (class_name, item_id, keyprop)
b8e8b1b3ec77 REST: Add key lookup
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5677
diff changeset
1115 )
7372
886a5c767d7e Invalid REST item spec returns 404 rather than 400.
John Rouillard <rouilj@ieee.org>
parents: 7173
diff changeset
1116 try:
886a5c767d7e Invalid REST item spec returns 404 rather than 400.
John Rouillard <rouilj@ieee.org>
parents: 7173
diff changeset
1117 itemid = class_obj.lookup(v)
886a5c767d7e Invalid REST item spec returns 404 rather than 400.
John Rouillard <rouilj@ieee.org>
parents: 7173
diff changeset
1118 except TypeError:
886a5c767d7e Invalid REST item spec returns 404 rather than 400.
John Rouillard <rouilj@ieee.org>
parents: 7173
diff changeset
1119 raise NotFound("Item '%s' not found" % v)
886a5c767d7e Invalid REST item spec returns 404 rather than 400.
John Rouillard <rouilj@ieee.org>
parents: 7173
diff changeset
1120
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1121 if not self.db.security.hasPermission(
5679
df9eb574b717 REST: Bug-fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5678
diff changeset
1122 'View', uid, class_name, itemid=itemid
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1123 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1124 raise Unauthorised(
5679
df9eb574b717 REST: Bug-fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5678
diff changeset
1125 'Permission to view %s%s denied' % (class_name, itemid)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1126 )
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1127
5679
df9eb574b717 REST: Bug-fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5678
diff changeset
1128 node = class_obj.getnode(itemid)
5726
e199d0ae4a25 issue2551033: prevent reverse engineering hidden data by using etags
John Rouillard <rouilj@ieee.org>
parents: 5715
diff changeset
1129 etag = calculate_etag(node, self.db.config.WEB_SECRET_KEY,
5729
9ea2ce9d10cf A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents: 5727
diff changeset
1130 class_name, itemid, repr_format="json")
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
1131 props = None
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1132 protected = False
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1133 verbose = 1
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1134 for form_field in input_payload.value:
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
1135 key = form_field.name
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
1136 value = form_field.value
8197
5b8d1cb290cb chore(ruff): replace 'x == y or x == z' with 'x in [y,z]'
John Rouillard <rouilj@ieee.org>
parents: 8196
diff changeset
1137 if key in ["@fields", "@attrs"]:
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1138 if props is None:
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
1139 props = set()
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1140 # support , or : separated elements
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1141 f = value.split(",")
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1142 if len(f) == 1:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1143 f = value.split(":")
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
1144 props.update(self.transitive_props(class_name, f))
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1145 elif key == "@protected":
5638
7e3cceec3f4f Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents: 5636
diff changeset
1146 # allow client to request read only
7e3cceec3f4f Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents: 5636
diff changeset
1147 # properties like creator, activity etc.
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1148 # used only if no @fields/@attrs
5638
7e3cceec3f4f Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents: 5636
diff changeset
1149 protected = value.lower() == "true"
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1150 elif key == "@verbose":
8213
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
1151 try:
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
1152 verbose = int(value)
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
1153 except ValueError as e:
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
1154 raise UsageError("When using @verbose: %s" %
14e92a595828 fix(web) issue2551382 - 409 not 400 errors returned
John Rouillard <rouilj@ieee.org>
parents: 8208
diff changeset
1155 (e.args[0]))
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
1156
5661
b08a308c273b Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5660
diff changeset
1157 result = {}
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
1158 if props is None:
6090
e097ff5064b8 Allow transitive properties in @fields in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 6088
diff changeset
1159 props = set(class_obj.getprops(protected=protected))
8198
de6b02c23ee9 chore(ruff): replace 'else: if bool_exp:' with 'elif bool_exp:'
John Rouillard <rouilj@ieee.org>
parents: 8197
diff changeset
1160 elif verbose > 1:
8199
622e7bc2db69 chore(ruff): fix indentation level on de6b02c23ee9
John Rouillard <rouilj@ieee.org>
parents: 8198
diff changeset
1161 lp = class_obj.labelprop()
622e7bc2db69 chore(ruff): fix indentation level on de6b02c23ee9
John Rouillard <rouilj@ieee.org>
parents: 8198
diff changeset
1162 props.add(lp)
5598
be81e8cca38c Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5597
diff changeset
1163
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1164 result = {
5679
df9eb574b717 REST: Bug-fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5678
diff changeset
1165 'id': itemid,
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1166 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1167 'link': '%s/%s/%s' % (self.data_path, class_name, item_id),
5680
f77209ddd579 Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents: 5679
diff changeset
1168 'attributes': self.format_item(node, itemid, props=props,
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1169 verbose=verbose),
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1170 '@etag': etag
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1171 }
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1172
5674
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
1173 self.client.setHeader("ETag", etag)
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
1174 return 200, result
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
1175
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1176 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'GET')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1177 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1178 def get_attribute(self, class_name, item_id, attr_name, input_payload):
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1179 """GET resource from attribute URI.
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1180
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1181 This function returns only attribute has View permission
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1182 class_name should be valid already
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1183
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1184 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1185 class_name (string): class name of the resource (Ex: issue, msg)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1186 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1187 attr_name (string): attribute of the resource (Ex: title, nosy)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1188 input_payload (list): the submitted form of the user
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1189
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1190 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1191 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1192 list: a dictionary represents the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1193 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1194 type: class name of the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1195 link: link to the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1196 data: data of the requested attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1197 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1198 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1199 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1200 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1201 'View', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1202 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1203 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1204 'Permission to view %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1205 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1206 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1207
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1208 class_obj = self.db.getclass(class_name)
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1209 node = class_obj.getnode(item_id)
5726
e199d0ae4a25 issue2551033: prevent reverse engineering hidden data by using etags
John Rouillard <rouilj@ieee.org>
parents: 5715
diff changeset
1210 etag = calculate_etag(node, self.db.config.WEB_SECRET_KEY,
8190
569aff540a21 chore(ruff): whatespace fixes/silence linting
John Rouillard <rouilj@ieee.org>
parents: 8188
diff changeset
1211 class_name, item_id, repr_format="json")
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1212 try:
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1213 data = node.__getattr__(attr_name)
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1214 except AttributeError:
7750
216662fbaaee fix(i18n): fix incorrect lookup of some translations
John Rouillard <rouilj@ieee.org>
parents: 7726
diff changeset
1215 raise UsageError(_("Invalid attribute %s") % attr_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1216 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1217 'id': item_id,
5631
a5c890d308c3 Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents: 5630
diff changeset
1218 'type': str(type(data)),
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1219 'link': "%s/%s/%s/%s" %
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1220 (self.data_path, class_name, item_id, attr_name),
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1221 'data': data,
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1222 '@etag': etag
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1223 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1224
5674
6dc4dba1c225 REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5669
diff changeset
1225 self.client.setHeader("ETag", etag)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1226 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1227
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1228 @Routing.route("/data/<:class_name>", 'POST')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1229 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1230 def post_collection(self, class_name, input_payload):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1231 """POST a new object to a class
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1232
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1233 If the item is successfully created, the "Location" header will also
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1234 contain the link to the created object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1235
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1236 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1237 class_name (string): class name of the resource (Ex: issue, msg)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1238 input_payload (list): the submitted form of the user
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1239
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1240 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1241 int: http status code 201 (Created)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1242 dict: a reference item to the created object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1243 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1244 link: path to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1245 """
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1246 return self.post_collection_inner(class_name, input_payload)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1247
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1248 @Routing.route("/data/<:class_name>/@poe", 'POST')
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1249 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1250 def get_post_once_exactly(self, class_name, input_payload):
6349
c1a672b1ad85 Document post once functions.
John Rouillard <rouilj@ieee.org>
parents: 6311
diff changeset
1251 """Get the Post Once Exactly token to create a new instance of class
c1a672b1ad85 Document post once functions.
John Rouillard <rouilj@ieee.org>
parents: 6311
diff changeset
1252 See https://tools.ietf.org/html/draft-nottingham-http-poe-00"""
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1253 otks = self.db.Otk
6823
fe0091279f50 Refactor session db logging and key generation for sessions/otks
John Rouillard <rouilj@ieee.org>
parents: 6814
diff changeset
1254 poe_key = otks.getUniqueKey()
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1255
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1256 try:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1257 lifetime = int(input_payload['lifetime'].value)
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1258 except KeyError:
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1259 lifetime = 30 * 60 # 30 minutes
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1260 except ValueError:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1261 raise UsageError("Value 'lifetime' must be an integer specify lifetime in seconds. Got %s." % input_payload['lifetime'].value)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1262
8229
c24b02266077 chore(ruff): handle magic number warnings.
John Rouillard <rouilj@ieee.org>
parents: 8227
diff changeset
1263 if lifetime > 3600 or lifetime < 1: # noqa: PLR2004
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1264 raise UsageError("Value 'lifetime' must be between 1 second and 1 hour (3600 seconds). Got %s." % input_payload['lifetime'].value)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1265
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1266 try:
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1267 # if generic tag exists, we don't care about the value
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1268 is_generic = input_payload['generic']
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1269 # we generate a generic POE token
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1270 is_generic = True
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1271 except KeyError:
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1272 is_generic = False
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1273
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1274 # a POE must be used within lifetime (30 minutes default).
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1275 # Default OTK lifetime is 1 week. So to make different
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1276 # lifetime, take current time, subtract 1 week and add
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1277 # lifetime.
6814
3f60a71b0812 Summary: Support selecion session/otk data store. Add redis as data store.
John Rouillard <rouilj@ieee.org>
parents: 6693
diff changeset
1278 ts = otks.lifetime(lifetime)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1279 if is_generic:
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1280 otks.set(u2s(poe_key), uid=self.db.getuid(),
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1281 __timestamp=ts)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1282 else:
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1283 otks.set(u2s(poe_key), uid=self.db.getuid(),
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1284 class_name=class_name,
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1285 __timestamp=ts)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1286 otks.commit()
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1287
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1288 return 200, {'link': '%s/%s/@poe/%s' %
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1289 (self.data_path, class_name, poe_key),
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1290 'expires': ts + (60 * 60 * 24 * 7)}
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1291
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1292 @Routing.route("/data/<:class_name>/@poe/<:post_token>", 'POST')
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1293 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1294 def post_once_exactly_collection(self, class_name, post_token, input_payload):
6349
c1a672b1ad85 Document post once functions.
John Rouillard <rouilj@ieee.org>
parents: 6311
diff changeset
1295 """Post exactly one to the resource named by class_name"""
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1296 otks = self.db.Otk
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1297
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1298 # remove expired keys so we don't use an expired key
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1299 otks.clean()
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1300
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1301 if not otks.exists(u2s(post_token)):
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1302 # Don't log this failure. Would allow attackers to fill
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1303 # logs.
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1304 raise UsageError("POE token '%s' not valid." % post_token)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1305
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1306 # find out what user owns the key
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1307 user = otks.get(u2s(post_token), 'uid', default=None)
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1308 # find out what class it was meant for
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1309 cn = otks.get(u2s(post_token), 'class_name', default=None)
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1310
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1311 # Invalidate the key as it has been used.
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1312 otks.destroy(u2s(post_token))
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1313 otks.commit()
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1314
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1315 # verify the same user that requested the key is the user
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1316 # using the key.
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1317 if user != self.db.getuid():
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1318 # Tell the roundup admin that there is an issue
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1319 # as the key got compromised.
5799
7ba0ee980fc7 logger.warn is deprecated. Replace with logger.warning.
John Rouillard <rouilj@ieee.org>
parents: 5745
diff changeset
1320 logger.warning(
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1321 'Post Once key owned by user%s was denied. Used by user%s', user, self.db.getuid()
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1322 )
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1323 # Should we indicate to user that the token is invalid
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1324 # because they are not the user who owns the key? It could
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1325 # be a logic bug in the application. But I assume that
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1326 # the key has been stolen and we don't want to tip our hand.
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1327 raise UsageError("POE token '%s' not valid." % post_token)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1328
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1329 if cn != class_name and cn is not None:
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1330 raise UsageError("POE token '%s' not valid for %s, was generated for class %s" % (post_token, class_name, cn))
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1331
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1332 # handle this as though they POSTed to /rest/data/class
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1333 return self.post_collection_inner(class_name, input_payload)
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
1334
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1335 def post_collection_inner(self, class_name, input_payload):
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1336 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1337 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1338 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1339 'Create', self.db.getuid(), class_name
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1340 ):
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1341 raise Unauthorised('Permission to create %s denied' % class_name)
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1342
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1343 class_obj = self.db.getclass(class_name)
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1344
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1345 # convert types
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1346 props = self.props_from_args(class_obj, input_payload.value)
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1347
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1348 # check for the key property
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1349 key = class_obj.getkey()
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1350 if key and key not in props:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
1351 raise UsageError("Must provide the '%s' property." % key)
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1352
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1353 for key in props:
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1354 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1355 'Create', self.db.getuid(), class_name, property=key
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1356 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1357 raise Unauthorised(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1358 'Permission to create %s.%s denied' % (class_name, key)
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1359 )
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1360
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1361 # do the actual create
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1362 try:
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
1363 item_id = class_obj.create(**props)
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1364 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1365 except (TypeError, IndexError, ValueError) as message:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
1366 raise ValueError(message)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1367 except KeyError as msg:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
1368 raise UsageError("Must provide the %s property." % msg)
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
1369
5573
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
1370 # set the header Location
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1371 link = '%s/%s/%s' % (self.data_path, class_name, item_id)
5573
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
1372 self.client.setHeader("Location", link)
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
1373
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1374 self.client.setHeader(
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1375 "Allow",
6544
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6543
diff changeset
1376 None
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1377 )
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1378 self.client.setHeader(
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1379 "Access-Control-Allow-Methods",
6544
9aa8df0b4426 issue2551178 - fix Traceback in Apache WSGI
John Rouillard <rouilj@ieee.org>
parents: 6543
diff changeset
1380 None
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1381 )
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1382
5573
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
1383 # set the response body
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1384 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1385 'id': item_id,
5573
89ae4ef34efe Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5572
diff changeset
1386 'link': link
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1387 }
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
1388 return 201, result
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1389
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1390 @Routing.route("/data/<:class_name>/<:item_id>", 'PUT')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1391 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1392 def put_element(self, class_name, item_id, input_payload):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1393 """PUT a new content to an object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1394
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1395 Replace the content of the existing object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1396
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1397 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1398 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1399 item_id (string): id of the resource (Ex: 12, 15)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1400 input_payload (list): the submitted form of the user
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1401
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1402 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1403 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1404 dict: a dictionary represents the modified object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1405 id: id of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1406 type: class name of the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1407 link: link to the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1408 attributes: a dictionary represent only changed attributes of
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1409 the object
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1410 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1411 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1412 raise NotFound('Class %s not found' % class_name)
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
1413 class_obj = self.db.getclass(class_name)
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
1414
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1415 props = self.props_from_args(class_obj, input_payload.value, item_id)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1416 for p in props:
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1417 if not self.db.security.hasPermission(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1418 'Edit', self.db.getuid(), class_name, p, item_id
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1419 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1420 raise Unauthorised(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1421 'Permission to edit %s of %s%s denied' %
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1422 (p, class_name, item_id)
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1423 )
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
1424 try:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1425 self.raise_if_no_etag(class_name, item_id, input_payload)
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
1426 result = class_obj.set(item_id, **props)
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
1427 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1428 except (TypeError, IndexError, ValueError) as message:
5576
77d11a24f718 Exceptions
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5575
diff changeset
1429 raise ValueError(message)
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1430 except KeyError as message:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1431 # key error returned for changing protected keys
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1432 # and changing invalid keys
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1433 raise UsageError(message)
5564
da6b5724314f Added Partial PUT
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5563
diff changeset
1434
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1435 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1436 'id': item_id,
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1437 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1438 'link': '%s/%s/%s' % (self.data_path, class_name, item_id),
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1439 'attribute': result
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1440 }
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
1441 return 200, result
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
1442
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1443 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'PUT')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1444 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1445 def put_attribute(self, class_name, item_id, attr_name, input_payload):
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1446 """PUT an attribute to an object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1447
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1448 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1449 class_name (string): class name of the resource (Ex: issue, msg)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1450 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1451 attr_name (string): attribute of the resource (Ex: title, nosy)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1452 input_payload (list): the submitted form of the user
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1453
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1454 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1455 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1456 dict:a dictionary represents the modified object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1457 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1458 type: class name of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1459 link: link to the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1460 attributes: a dictionary represent only changed attributes of
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1461 the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1462 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1463 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1464 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1465 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1466 'Edit', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1467 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1468 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1469 'Permission to edit %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1470 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1471 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1472 class_obj = self.db.getclass(class_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1473 props = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1474 attr_name: self.prop_from_arg(
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1475 class_obj, attr_name, input_payload['data'].value, item_id
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1476 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1477 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1478
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1479 try:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1480 self.raise_if_no_etag(class_name, item_id, input_payload)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1481 result = class_obj.set(item_id, **props)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1482 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1483 except (TypeError, IndexError, ValueError) as message:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1484 raise ValueError(message)
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1485 except KeyError as message:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1486 # key error returned for changing protected keys
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1487 # and changing invalid keys
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
1488 raise AttributeError(message)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1489
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1490 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1491 'id': item_id,
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1492 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1493 'link': '%s/%s/%s' % (self.data_path, class_name, item_id),
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1494 'attribute': result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1495 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1496
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1497 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1498
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1499 @Routing.route("/data/<:class_name>", 'DELETE')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1500 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1501 def delete_collection(self, class_name, input_payload):
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1502 """DELETE (retire) all objects in a class
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1503 There is currently no use-case, so this is disabled and
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1504 always returns Unauthorised.
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1505
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1506 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1507 class_name (string): class name of the resource (Ex: issue, msg)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1508 input_payload (list): the submitted form of the user
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1509
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1510 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1511 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1512 dict:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1513 status (string): 'ok'
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1514 count (int): number of deleted objects
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1515 """
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1516 raise Unauthorised('Deletion of a whole class disabled')
5740
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
1517 ''' Hide original code to silence pylint.
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
1518 Leave it here in case we need to re-enable.
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
1519 FIXME: Delete in December 2020 if not used.
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1520 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1521 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1522 if not self.db.security.hasPermission(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1523 'Retire', self.db.getuid(), class_name
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1524 ):
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1525 raise Unauthorised('Permission to delete %s denied' % class_name)
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1526
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1527 class_obj = self.db.getclass(class_name)
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1528 for item_id in class_obj.list():
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1529 if not self.db.security.hasPermission(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1530 'Retire', self.db.getuid(), class_name, itemid=item_id
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1531 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1532 raise Unauthorised(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1533 'Permission to retire %s %s denied' % (class_name, item_id)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1534 )
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1535
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1536 count = len(class_obj.list())
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1537 for item_id in class_obj.list():
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1538 class_obj.retire (item_id)
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1539
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1540 self.db.commit()
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1541 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1542 'status': 'ok',
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1543 'count': count
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1544 }
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1545
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
1546 return 200, result
5740
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
1547 '''
5561
7aa7f779198b Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5560
diff changeset
1548
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1549 @Routing.route("/data/<:class_name>/<:item_id>", 'DELETE')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1550 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1551 def delete_element(self, class_name, item_id, input_payload):
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1552 """DELETE (retire) an object in a class
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1553
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1554 Args:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1555 class_name (string): class name of the resource (Ex: issue, msg)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1556 item_id (string): id of the resource (Ex: 12, 15)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1557 input_payload (list): the submitted form of the user
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1558
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1559 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1560 int: http status code 200 (OK)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1561 dict:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1562 status (string): 'ok'
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1563 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1564 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1565 raise NotFound('Class %s not found' % class_name)
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1566 class_obj = self.db.classes[class_name]
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1567 if not self.db.security.hasPermission(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1568 'Retire', self.db.getuid(), class_name, itemid=item_id
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1569 ):
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1570 raise Unauthorised(
5604
ed02a1e0aa5d Fix actions
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5602
diff changeset
1571 'Permission to retire %s %s denied' % (class_name, item_id)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1572 )
5563
9a1614ff752d Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5562
diff changeset
1573
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1574 self.raise_if_no_etag(class_name, item_id, input_payload)
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1575 class_obj.retire(item_id)
5562
70df783c4c0b Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5561
diff changeset
1576 self.db.commit()
5570
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1577 result = {
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1578 'status': 'ok'
8431a872b008 Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5569
diff changeset
1579 }
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1580
5572
c4c88466da69 Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5571
diff changeset
1581 return 200, result
5559
3d80e7752783 Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5558
diff changeset
1582
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1583 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'DELETE')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1584 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1585 def delete_attribute(self, class_name, item_id, attr_name, input_payload):
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1586 """DELETE an attribute in a object by setting it to None or empty
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1587
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1588 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1589 class_name (string): class name of the resource (Ex: issue, msg)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1590 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1591 attr_name (string): attribute of the resource (Ex: title, nosy)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1592 input_payload (list): the submitted form of the user
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1593
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1594 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1595 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1596 dict:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1597 status (string): 'ok'
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1598 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1599 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1600 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1601 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1602 'Edit', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1603 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1604 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1605 'Permission to delete %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1606 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1607 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1608
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1609 class_obj = self.db.getclass(class_name)
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1610 if attr_name not in class_obj.getprops(protected=False):
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1611 if attr_name in class_obj.getprops(protected=True):
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1612 raise AttributeError("Attribute '%s' can not be deleted "
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1613 "for class %s." % (attr_name, class_name))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
1614 raise UsageError("Attribute '%s' not valid for class %s." % (
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
1615 attr_name, class_name))
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1616 if attr_name in class_obj.get_required_props():
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1617 raise UsageError("Attribute '%s' is required by class %s and can not be deleted." % (
5740
abbea26a11df Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents: 5732
diff changeset
1618 attr_name, class_name))
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1619 props = {}
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1620 prop_obj = class_obj.get(item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1621 if isinstance(prop_obj, list):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1622 props[attr_name] = []
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1623 else:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1624 props[attr_name] = None
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1625
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1626 try:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1627 self.raise_if_no_etag(class_name, item_id, input_payload)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1628 class_obj.set(item_id, **props)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1629 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1630 except (TypeError, IndexError, ValueError) as message:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1631 raise ValueError(message)
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1632 except KeyError as message:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1633 # key error returned for changing protected keys
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1634 # and changing invalid keys
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1635 raise UsageError(message)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1636
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1637 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1638 'status': 'ok'
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1639 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1640
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1641 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1642
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1643 @Routing.route("/data/<:class_name>/<:item_id>", 'PATCH')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1644 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1645 def patch_element(self, class_name, item_id, input_payload):
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1646 """PATCH an object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1647
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1648 Patch an element using 3 operators
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1649 ADD : Append new value to the object's attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1650 REPLACE: Replace object's attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1651 REMOVE: Clear object's attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1652
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1653 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1654 class_name (string): class name of the resource (Ex: issue, msg)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1655 item_id (string): id of the resource (Ex: 12, 15)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1656 input_payload (list): the submitted form of the user
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1657
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1658 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1659 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1660 dict: a dictionary represents the modified object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1661 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1662 type: class name of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1663 link: link to the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1664 attributes: a dictionary represent only changed attributes of
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1665 the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1666 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1667 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1668 raise NotFound('Class %s not found' % class_name)
5580
d5a54b1851aa Add default op action for Patch
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5579
diff changeset
1669 try:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1670 op = input_payload['@op'].value.lower()
5580
d5a54b1851aa Add default op action for Patch
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5579
diff changeset
1671 except KeyError:
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
1672 op = self.__default_patch_op
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1673 class_obj = self.db.getclass(class_name)
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1674
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1675 self.raise_if_no_etag(class_name, item_id, input_payload)
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1676
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1677 # if patch operation is action, call the action handler
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1678 action_args = [class_name + item_id]
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1679 if op == 'action':
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1680 # extract action_name and action_args from form fields
5926
3ca3bfe6de16 Code-robustness, error-message improved
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5904
diff changeset
1681 name = None
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1682 for form_field in input_payload.value:
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1683 key = form_field.name
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1684 value = form_field.value
5659
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
1685 if key == "@action_name":
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1686 name = value
5659
1e51a709431c Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5658
diff changeset
1687 elif key.startswith('@action_args'):
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1688 action_args.append(value)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1689
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1690 if name in self.actions:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1691 action_type = self.actions[name]
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1692 else:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1693 raise UsageError(
5926
3ca3bfe6de16 Code-robustness, error-message improved
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5904
diff changeset
1694 'action "%s" is not supported, allowed: %s' %
3ca3bfe6de16 Code-robustness, error-message improved
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5904
diff changeset
1695 (name, ', '.join(self.actions.keys()))
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1696 )
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1697 action = action_type(self.db, self.translator)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1698 result = action.execute(*action_args)
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1699
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1700 result = {
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1701 'id': item_id,
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1702 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1703 'link': '%s/%s/%s' % (self.data_path, class_name, item_id),
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1704 'result': result
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1705 }
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1706 else:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1707 # else patch operation is processing data
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1708 props = self.props_from_args(class_obj, input_payload.value, item_id,
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1709 skip_protected=False)
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1710
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1711 required_props = class_obj.get_required_props()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1712 for prop in props:
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1713 if not self.db.security.hasPermission(
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1714 'Edit', self.db.getuid(), class_name, prop, item_id
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1715 ):
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1716 raise Unauthorised(
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1717 'Permission to edit %s of %s%s denied' %
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1718 (prop, class_name, item_id)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1719 )
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1720 if op == 'remove' and prop in required_props:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1721 raise UsageError(
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1722 "Attribute '%s' is required by class %s "
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1723 "and can not be removed." % (prop, class_name)
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1724 )
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1725
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1726 props[prop] = self.patch_data(
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1727 op, class_obj.get(item_id, prop), props[prop]
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1728 )
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1729
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1730 try:
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1731 result = class_obj.set(item_id, **props)
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1732 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1733 except (TypeError, IndexError, ValueError) as message:
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1734 raise ValueError(message)
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1735
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1736 result = {
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1737 'id': item_id,
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1738 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1739 'link': '%s/%s/%s' % (self.data_path, class_name, item_id),
5599
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1740 'attribute': result
a76d88673375 Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5598
diff changeset
1741 }
5578
c2214d0c9df8 Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5577
diff changeset
1742 return 200, result
5557
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
1743
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1744 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'PATCH')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1745 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1746 def patch_attribute(self, class_name, item_id, attr_name, input_payload):
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1747 """PATCH an attribute of an object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1748
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1749 Patch an element using 3 operators
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1750 ADD : Append new value to the attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1751 REPLACE: Replace attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1752 REMOVE: Clear attribute
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1753
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1754 Args:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1755 class_name (string): class name of the resource (Ex: issue, msg)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1756 item_id (string): id of the resource (Ex: 12, 15)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1757 attr_name (string): attribute of the resource (Ex: title, nosy)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1758 input_payload (list): the submitted form of the user
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1759
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1760 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1761 int: http status code 200 (OK)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1762 dict: a dictionary represents the modified object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1763 id: id of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1764 type: class name of the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1765 link: link to the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1766 attributes: a dictionary represent only changed attributes of
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1767 the object
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1768 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1769 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1770 raise NotFound('Class %s not found' % class_name)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1771 try:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1772 op = input_payload['@op'].value.lower()
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1773 except KeyError:
5593
344b6a87dac6 Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5591
diff changeset
1774 op = self.__default_patch_op
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1775
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1776 if not self.db.security.hasPermission(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1777 'Edit', self.db.getuid(), class_name, attr_name, item_id
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1778 ):
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1779 raise Unauthorised(
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1780 'Permission to edit %s%s %s denied' %
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1781 (class_name, item_id, attr_name)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1782 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1783
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1784 prop = attr_name
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1785 class_obj = self.db.getclass(class_name)
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
1786 if (attr_name not in class_obj.getprops(protected=False) and
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
1787 attr_name in class_obj.getprops(protected=True)):
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1788 raise AttributeError("Attribute '%s' can not be updated "
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1789 "for class %s." % (attr_name, class_name))
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1790
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1791 self.raise_if_no_etag(class_name, item_id, input_payload)
5630
07abc8d36940 Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents: 5622
diff changeset
1792
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1793 props = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1794 prop: self.prop_from_arg(
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1795 class_obj, prop, input_payload['data'].value, item_id
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1796 )
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1797 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1798
5595
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
1799 props[prop] = self.patch_data(
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
1800 op, class_obj.get(item_id, prop), props[prop]
65caddd54da2 Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5594
diff changeset
1801 )
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1802
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1803 try:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1804 result = class_obj.set(item_id, **props)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1805 self.db.commit()
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
1806 except (TypeError, IndexError, ValueError) as message:
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1807 raise ValueError(message)
5705
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1808 except KeyError as message:
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1809 # key error returned for changing protected keys
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1810 # and changing invalid keys
457fc482e6b1 Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents: 5702
diff changeset
1811 raise UsageError(message)
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1812
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1813 result = {
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1814 'id': item_id,
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1815 'type': class_name,
5600
e2c74d8121f3 Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5599
diff changeset
1816 'link': '%s/%s/%s' % (self.data_path, class_name, item_id),
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1817 'attribute': result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1818 }
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1819 return 200, result
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1820
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1821 @Routing.route("/data/<:class_name>", 'OPTIONS')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1822 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1823 def options_collection(self, class_name, input_payload):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1824 """OPTION return the HTTP Header for the class uri
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1825
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1826 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1827 int: http status code 204 (No content)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1828 body (string): an empty string
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1829 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1830 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1831 raise NotFound('Class %s not found' % class_name)
5702
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1832 self.client.setHeader(
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1833 "Allow",
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1834 "OPTIONS, GET, POST"
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1835 )
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1836
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1837 self.client.setHeader(
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1838 "Access-Control-Allow-Methods",
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1839 "OPTIONS, GET, POST"
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1840 )
5575
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1841 return 204, ""
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1842
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1843 @Routing.route("/data/<:class_name>/<:item_id>", 'OPTIONS')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1844 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1845 def options_element(self, class_name, item_id, input_payload):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1846 """OPTION return the HTTP Header for the object uri
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1847
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1848 Returns:
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1849 int: http status code 204 (No content)
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1850 body (string): an empty string
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
1851 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1852 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1853 raise NotFound('Class %s not found' % class_name)
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1854 self.client.setHeader(
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
1855 "Accept-Patch",
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1856 "application/x-www-form-urlencoded, multipart/form-data"
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1857 )
5702
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1858 self.client.setHeader(
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1859 "Allow",
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1860 "OPTIONS, GET, PUT, DELETE, PATCH"
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1861 )
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1862 self.client.setHeader(
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1863 "Access-Control-Allow-Methods",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1864 "OPTIONS, GET, PUT, DELETE, PATCH"
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1865 )
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1866 return 204, ""
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1867
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1868 @Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'OPTIONS')
5587
cb2b320fde16 Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5584
diff changeset
1869 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1870 def option_attribute(self, class_name, item_id, attr_name, input_payload):
5584
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1871 """OPTION return the HTTP Header for the attribute uri
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1872
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1873 Returns:
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1874 int: http status code 204 (No content)
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1875 body (string): an empty string
53098db851f2 Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5583
diff changeset
1876 """
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1877 if class_name not in self.db.classes:
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
1878 raise NotFound('Class %s not found' % class_name)
5702
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1879 class_obj = self.db.getclass(class_name)
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1880 if attr_name in class_obj.getprops(protected=False):
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1881 self.client.setHeader(
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1882 "Accept-Patch",
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1883 "application/x-www-form-urlencoded, multipart/form-data"
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1884 )
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1885 self.client.setHeader(
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1886 "Allow",
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1887 "OPTIONS, GET, PUT, DELETE, PATCH"
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1888 )
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1889 self.client.setHeader(
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1890 "Access-Control-Allow-Methods",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1891 "OPTIONS, GET, PUT, DELETE, PATCH"
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1892 )
5702
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1893 elif attr_name in class_obj.getprops(protected=True):
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1894 # It must match a protected prop. These can't be written.
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1895 self.client.setHeader(
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1896 "Allow",
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1897 "OPTIONS, GET"
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1898 )
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1899 self.client.setHeader(
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1900 "Access-Control-Allow-Methods",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1901 "OPTIONS, GET"
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
1902 )
5702
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
1903 else:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1904 raise NotFound('Attribute %s not valid for Class %s' % (
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
1905 attr_name, class_name))
5575
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1906 return 204, ""
7a7927643357 Added OPTIONS method
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5574
diff changeset
1907
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1908 @openapi_doc({
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1909 "summary": "Describe Roundup rest endpoint.",
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1910 "description": (
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1911 "Report all supported api versions "
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1912 "and default api version. "
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1913 "Also report next level of link "
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1914 "endpoints below /rest endpoint"),
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1915 "responses": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1916 "200": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1917 "description": "Successful response.",
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1918 "content": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1919 "application/json": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1920 "examples": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1921 "success": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1922 "summary": "Normal json data.",
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1923 "value": """
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1924 {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1925 "data": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1926 "default_version": 1,
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1927 "supported_versions": [ 1 ],
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1928 "links": [
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1929 {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1930 "uri": "https://tracker.example.com/demo/rest",
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1931 "rel": "self"
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1932 },
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1933 {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1934 "uri": "https://tracker.example.com/demo/rest/data",
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1935 "rel": "data"
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1936 },
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1937 {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1938 "uri": "https://tracker.example.com/demo/rest/summary",
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1939 "rel": "summary"
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1940 }
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1941 ]
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1942 }
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1943 }"""
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1944 }
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1945 }
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1946 },
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1947 "application/xml": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1948 "examples": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1949 "success": {
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1950 "summary": "Normal xml data",
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1951 "value": """
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1952 <dataf type="dict">
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1953 <default_version type="int">1</default_version>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1954 <supported_versions type="list">
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1955 <item type="int">1</item>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1956 </supported_versions>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1957 <links type="list">
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1958 <item type="dict">
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1959 <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest</uri>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1960 <rel type="str">self</rel>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1961 </item>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1962 <item type="dict">
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1963 <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest/data</uri>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1964 <rel type="str">data</rel>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1965 </item>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1966 <item type="dict">
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1967 <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest/summary</uri>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1968 <rel type="str">summary</rel>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1969 </item>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1970 <item type="dict">
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1971 <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest/summary2</uri>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1972 <rel type="str">summary2</rel>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1973 </item>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1974 </links>
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1975 </dataf>"""
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1976 }
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1977 }
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1978 }
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1979 }
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1980 }
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1981 }
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1982 }
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1983 )
5632
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
1984 @Routing.route("/")
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
1985 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
1986 def describe(self, input_payload):
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1987 """Describe the rest endpoint. Return direct children in
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1988 links list.
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1989 """
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1990
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1991 # paths looks like ['^rest/$', '^rest/summary$',
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1992 # '^rest/data/<:class>$', ...]
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1993 paths = Routing._Routing__route_map.keys()
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1994
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1995 links = []
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1996 # p[1:-1] removes ^ and $ from regexp
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
1997 # if p has only 1 /, it's a child of rest/ root.
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1998 child_paths = sorted([p[1:-1] for p in paths if
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
1999 p.count('/') == 1])
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2000 for p in child_paths:
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2001 # p.split('/')[1] is the residual path after
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2002 # removing rest/. child_paths look like:
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2003 # ['rest/', 'rest/summary'] etc.
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2004 rel = p.split('/')[1]
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2005 if rel:
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2006 rel_path = "/" + rel
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2007 else:
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2008 rel_path = rel
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2009 rel = "self"
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
2010 links.append({"uri": self.base_path + rel_path,
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
2011 "rel": rel})
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2012
5632
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2013 result = {
5685
4b4885f0c6ad Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents: 5682
diff changeset
2014 "default_version": self.__default_api_version,
4b4885f0c6ad Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents: 5682
diff changeset
2015 "supported_versions": self.__supported_api_versions,
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2016 "links": links
5632
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2017 }
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2018
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2019 return 200, result
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2020
6384
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2021 @Routing.route("/", 'OPTIONS')
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2022 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2023 def options_describe(self, input_payload):
6384
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2024 """OPTION return the HTTP Header for the root
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2025
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2026 Returns:
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2027 int: http status code 204 (No content)
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2028 body (string): an empty string
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2029 """
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2030 self.client.setHeader(
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2031 "Allow",
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2032 "OPTIONS, GET"
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2033 )
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2034 self.client.setHeader(
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2035 "Access-Control-Allow-Methods",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2036 "OPTIONS, GET"
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2037 )
6384
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2038 return 204, ""
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2039
5632
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2040 @Routing.route("/data")
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2041 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2042 def data(self, input_payload):
5658
3401daf8613b Fix hardcoded /data
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5655
diff changeset
2043 """Describe the subelements of data
5632
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2044
5658
3401daf8613b Fix hardcoded /data
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5655
diff changeset
2045 One entry for each class the user may view
5632
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2046 """
5658
3401daf8613b Fix hardcoded /data
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5655
diff changeset
2047 result = {}
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2048 uid = self.db.getuid()
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2049 for cls in sorted(self.db.classes):
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2050 if self.db.security.hasPermission('View', uid, cls):
8201
d5ad7fcb9bf6 chore(ruff): replace dict(...) with equivalent {...}
John Rouillard <rouilj@ieee.org>
parents: 8199
diff changeset
2051 result[cls] = {"link": self.base_path + '/data/' + cls}
5632
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2052 return 200, result
a29a8dae2095 Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents: 5631
diff changeset
2053
6384
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2054 @Routing.route("/data", 'OPTIONS')
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2055 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2056 def options_data(self, input_payload):
6384
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2057 """OPTION return the HTTP Header for the /data element
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2058
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2059 Returns:
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2060 int: http status code 204 (No content)
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2061 body (string): an empty string
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2062 """
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2063 self.client.setHeader(
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2064 "Allow",
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2065 "OPTIONS, GET"
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2066 )
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2067 self.client.setHeader(
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2068 "Access-Control-Allow-Methods",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2069 "OPTIONS, GET"
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2070 )
6384
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2071 return 204, ""
66a061e52435 Test options in rest interface against live server; rest doc update
John Rouillard <rouilj@ieee.org>
parents: 6349
diff changeset
2072
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
2073 @Routing.route("/summary")
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2074 @_data_decorator
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2075 def summary(self, input_payload):
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2076 """Get a summary of resource from class URI.
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2077
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2078 This function returns only items have View permission
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2079 class_name should be valid already
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2080
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2081 Args:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2082 class_name (string): class name of the resource (Ex: issue, msg)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2083 input_payload (list): the submitted form of the user
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2084
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2085 Returns:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2086 int: http status code 200 (OK)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2087 list:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2088 """
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2089 if not self.db.security.hasPermission(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2090 'View', self.db.getuid(), 'issue'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2091 ) and not self.db.security.hasPermission(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2092 'View', self.db.getuid(), 'status'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2093 ) and not self.db.security.hasPermission(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2094 'View', self.db.getuid(), 'issue'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2095 ):
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2096 raise Unauthorised('Permission to view summary denied')
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2097
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2098 old = date.Date('-1w')
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2099
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2100 created = []
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2101 summary = {}
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2102 messages = []
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2103
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2104 # loop through all the recently-active issues
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2105 for issue_id in self.db.issue.filter(None, {'activity': '-1w;'}):
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2106 num = 0
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2107 status_name = self.db.status.get(
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2108 self.db.issue.get(issue_id, 'status'),
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2109 'name'
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2110 )
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2111 issue_object = {
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2112 'id': issue_id,
5621
39dbe83643c0 Fix path of links in /rest/summary.
John Rouillard <rouilj@ieee.org>
parents: 5620
diff changeset
2113 'link': self.base_path + '/data/issue/' + issue_id,
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2114 'title': self.db.issue.get(issue_id, 'title')
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2115 }
6009
d56e290ecab7 flake8 cleanups. Rename unused for loop vars argument unpacking.
John Rouillard <rouilj@ieee.org>
parents: 5998
diff changeset
2116 for _x, ts, _uid, action, data in self.db.issue.history(issue_id):
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2117 if ts < old:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2118 continue
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2119 if action == 'create':
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2120 created.append(issue_object)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2121 elif action == 'set' and 'messages' in data:
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2122 num += 1
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2123 summary.setdefault(status_name, []).append(issue_object)
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2124 messages.append((num, issue_object))
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2125
5668
a4bb88a1a643 A fix for https://issues.roundup-tracker.org/issue2551034
John Rouillard <rouilj@ieee.org>
parents: 5662
diff changeset
2126 sorted(messages, key=lambda tup: tup[0], reverse=True)
5596
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2127
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2128 result = {
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2129 'created': created,
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2130 'summary': summary,
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2131 'most_discussed': messages[:10]
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2132 }
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2133
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2134 return 200, result
55fa81de6a57 Added summary page
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5595
diff changeset
2135
5732
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2136 def getRateLimit(self):
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2137 ''' By default set one rate limit for all users. Values
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2138 for period (in seconds) and count set in config.
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2139 However there is no reason these settings couldn't
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2140 be pulled from the user's entry in the database. So define
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2141 this method to allow a user to change it in the interfaces.py
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2142 to use a field in the user object.
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2143 '''
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2144 # FIXME verify can override from interfaces.py.
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2145 calls = self.db.config.WEB_API_CALLS_PER_INTERVAL
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2146 interval = self.db.config.WEB_API_INTERVAL_IN_SEC
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2147 if calls and interval:
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2148 return RateLimit(calls, timedelta(seconds=interval))
8203
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
2149
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
2150 # disable rate limiting if either parameter is 0
ef1333b153e3 chore(ruff): changes to else/elif and nested ifs to reduce nesting
John Rouillard <rouilj@ieee.org>
parents: 8201
diff changeset
2151 return None
5732
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2152
7605
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2153 def handle_apiRateLimitExceeded(self, apiRateLimit):
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2154 """Determine if the rate limit is exceeded.
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2155
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2156 If not exceeded, return False and the rate limit header values.
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2157 If exceeded, return error message and None
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2158 """
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2159 gcra = Gcra()
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2160 # unique key is an "ApiLimit-" prefix and the uid)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2161 apiLimitKey = "ApiLimit-%s" % self.db.getuid()
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2162 otk = self.db.Otk
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2163 try:
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2164 val = otk.getall(apiLimitKey)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2165 gcra.set_tat_as_string(apiLimitKey, val['tat'])
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2166 except KeyError:
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2167 # ignore if tat not set, it's 1970-1-1 by default.
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2168 pass
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2169 # see if rate limit exceeded and we need to reject the attempt
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2170 reject = gcra.update(apiLimitKey, apiRateLimit)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2171
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2172 # Calculate a timestamp that will make OTK expire the
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2173 # unused entry 1 hour in the future
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2174 ts = otk.lifetime(3600)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2175 otk.set(apiLimitKey,
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2176 tat=gcra.get_tat_as_string(apiLimitKey),
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2177 __timestamp=ts)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2178 otk.commit()
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2179
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2180 limitStatus = gcra.status(apiLimitKey, apiRateLimit)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2181 if not reject:
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2182 return (False, limitStatus)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2183
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2184 for header, value in limitStatus.items():
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2185 self.client.setHeader(header, value)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2186
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2187 # User exceeded limits: tell humans how long to wait
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2188 # Headers above will do the right thing for api
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2189 # aware clients.
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2190 try:
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2191 retry_after = limitStatus['Retry-After']
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2192 except KeyError:
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2193 # handle race condition. If the time between
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2194 # the call to grca.update and grca.status
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2195 # is sufficient to reload the bucket by 1
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2196 # item, Retry-After will be missing from
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2197 # limitStatus. So report a 1 second delay back
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2198 # to the client. We treat update as sole
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2199 # source of truth for exceeded rate limits.
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2200 retry_after = '1'
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2201 self.client.setHeader('Retry-After', retry_after)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2202
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2203 msg = _("Api rate limits exceeded. Please wait: %s seconds.") % retry_after
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2204 output = self.error_obj(429, msg, source="ApiRateLimiter")
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2205
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2206 # expose these headers to rest clients. Otherwise they can't
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2207 # respond to:
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2208 # rate limiting (*RateLimit*, Retry-After)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2209 # obsolete API endpoint (Sunset)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2210 # options request to discover supported methods (Allow)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2211 self.client.setHeader(
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2212 "Access-Control-Expose-Headers",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2213 ", ".join([
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2214 "X-RateLimit-Limit",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2215 "X-RateLimit-Remaining",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2216 "X-RateLimit-Reset",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2217 "X-RateLimit-Limit-Period",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2218 "Retry-After",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2219 "Sunset",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2220 "Allow",
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2221 ])
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2222 )
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2223
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2224 return (self.format_dispatch_output(
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2225 self.__default_accept_type,
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2226 output,
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2227 True # pretty print for this error case as a
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2228 # human may read it
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2229 ), None)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2230
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2231 def determine_output_format(self, uri):
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2232 """Returns tuple of:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2233
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2234 (format for returned output,
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2235 possibly modified uri,
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2236 output error object (if error else None))
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2237
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2238 Verify that client is requesting an output we can produce
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2239 with a version we support.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2240
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2241 Only application/json and application/xml (optional)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2242 are currently supported. .vcard might be useful
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2243 in the future for user objects.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2244
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2245 Find format for returned output:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2246
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2247 1) Get format from url extension (.json, .xml) and return
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2248 if invalid return (None, uri, 406 error)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2249 if not found continue
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2250 2) Parse Accept header obeying q values
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2251 if header unparsible return 400 error object.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2252 3) if empty or missing Accept header
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2253 return self.__default_accept_type
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2254 4) match and return best Accept header/version
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2255 this includes matching mime types for file downloads
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2256 using the binary_content property
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2257 if version error found in matching type return 406 error
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2258 5) if no requested format is supported return 406
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2259 error
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2260
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2261 """
8208
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2262 MAX_MIME_EXTENSION_LENGTH = 11 # application in /etc/mime.types
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2263
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2264 # get the request format for response
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2265 # priority : extension from uri (/rest/data/issue.json)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2266 # only json or xml valid at this time.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2267 # header (Accept: application/json, application/xml)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2268 # default (application/json)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2269 ext_type = os.path.splitext(urlparse(uri).path)[1][1:]
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2270
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2271 # Check to see if the extension matches a value in
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2272 # self.__accepted_content_type. In the future other output
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2273 # such as .vcard for downloading user info can be
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2274 # supported. This method also allow detection of mistyped
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2275 # types like jon for json. Limit extension length to less than
8208
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2276 # MAX_MIME_EXTENSION_LENGTH characters to allow passing JWT
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2277 # via URL path. Could be useful for magic link login method or
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2278 # account recovery workflow, using a JWT with a short
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2279 # expiration time and limited rights (e.g. only password
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2280 # change permission))
d87350f56100 chore(ruff): use variable not magic number.
John Rouillard <rouilj@ieee.org>
parents: 8207
diff changeset
2281 if ext_type and (len(ext_type) < MAX_MIME_EXTENSION_LENGTH):
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2282 if ext_type not in list(self.__accepted_content_type.values()):
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2283 self.client.response_code = 406
8272
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2284 return (
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2285 None, uri,
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2286 self.error_obj(
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2287 406,
8275
e3099f18a395 fix: missing space in translated message.
John Rouillard <rouilj@ieee.org>
parents: 8272
diff changeset
2288 _("Content type '%(requested)s' requested in URL is "
8272
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2289 "not available.\nAcceptable types: "
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2290 "%(acceptable)s\n") %
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2291 { "requested": ext_type,
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2292 "acceptable": ", ".join(sorted(
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2293 set(self.__accepted_content_type.values())))}))
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2294
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2295 # strip extension so uri makes sense.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2296 # E.G. .../issue.json -> .../issue
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2297 uri = uri[:-(len(ext_type) + 1)]
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2298 return (ext_type, uri, None)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2299
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2300 # parse Accept header and get the content type
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2301 # Acceptable types ordered with preferred one (by q value)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2302 # first in list.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2303 try:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2304 accept_header = parse_accept_header(
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2305 self.client.request.headers.get('Accept')
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2306 )
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2307 except UsageError as e:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2308 self.client.response_code = 406
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2309 return (None, uri, self.error_obj(
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2310 400, _("Unable to parse Accept Header. %(error)s. "
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2311 "Acceptable types: */*, %(acceptable_types)s") % {
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2312 'error': e.args[0],
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2313 'acceptable_types': ", ".join(sorted(
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2314 self.__accepted_content_type.keys()))}))
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2315
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2316 if not accept_header:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2317 # we are using the default
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2318 return (self.__default_accept_type, uri, None)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2319
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2320 accept_type = ""
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2321 valid_binary_content_types = []
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2322 if uri.endswith("/binary_content"):
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2323 request_path = uri
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2324 request_class, request_id = request_path.split('/')[-3:-1]
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2325 try:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2326 designator_type = self.db.getclass(
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2327 request_class).get(request_id, "type")
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2328 except (KeyError, IndexError):
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2329 # class (KeyError) or
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2330 # id (IndexError) does not exist
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2331 # Return unknown mime type and no error.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2332 # The 400/404 error will be thrown by other code.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2333 return (None, uri, None)
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2334
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2335 if designator_type:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2336 # put this first as we usually require exact mime
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2337 # type match and this will be matched most often.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2338 # Also for text/* Accept header it will be returned.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2339 valid_binary_content_types.append(designator_type)
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2340
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2341 if not designator_type or designator_type.startswith('text/'):
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2342 # allow text/* as msg items can have empty type field
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2343 # also match text/* for text/plain, text/x-rst,
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2344 # text/markdown, text/html etc.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2345 valid_binary_content_types.append("text/*")
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2346
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2347 # Octet-stream should be allowed for any content.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2348 # client.py sets 'X-Content-Type-Options: nosniff'
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2349 # for file downloads (sendfile) via the html interface,
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2350 # so we should be able to set it in this code as well.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2351 valid_binary_content_types.append("application/octet-stream")
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2352
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2353 for part in accept_header:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2354 if accept_type:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2355 # we accepted the best match, stop searching for
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2356 # lower quality matches.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2357 break
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2358
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2359 # check for structured rest return types (json xml)
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2360 if part[0] in self.__accepted_content_type:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2361 accept_type = self.__accepted_content_type[part[0]]
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2362 # Version order:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2363 # 1) accept header version=X specifier
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2364 # application/vnd.x.y; version=1
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2365 # 2) from type in accept-header type/subtype-vX
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2366 # application/vnd.x.y-v1
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2367 # 3) from @apiver in query string to make browser
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2368 # use easy
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2369 # This code handles 1 and 2. Set api_version to none
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2370 # to trigger @apiver parsing below
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2371 # Places that need the api_version info should
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2372 # use default if version = None
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2373 try:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2374 self.api_version = int(part[1]['version'])
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2375 if self.api_version not in self.__supported_api_versions:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2376 raise ValueError
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2377 except KeyError:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2378 self.api_version = None
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2379 except (ValueError, TypeError):
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2380 self.client.response_code = 406
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2381 # TypeError if int(None)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2382 msg = _("Unrecognized api version: %s. "
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2383 "See /rest without specifying api version "
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2384 "for supported versions.") % (
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2385 part[1]['version'])
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2386 return (None, uri,
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2387 self.error_obj(406, msg))
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2388
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2389 if part[0] == "*/*":
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2390 if valid_binary_content_types:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2391 self.client.setHeader("X-Content-Type-Options", "nosniff")
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2392 accept_type = valid_binary_content_types[0]
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2393 else:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2394 accept_type = "json"
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2395
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2396 # check type of binary_content
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2397 if part[0] in valid_binary_content_types:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2398 self.client.setHeader("X-Content-Type-Options", "nosniff")
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2399 accept_type = part[0]
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2400 # handle text wildcard
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2401 if ((part[0] in 'text/*') and
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2402 "text/*" in valid_binary_content_types):
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2403 self.client.setHeader("X-Content-Type-Options", "nosniff")
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2404 # use best choice of mime type, try not to use
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2405 # text/* if there is a real text mime type/subtype.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2406 accept_type = valid_binary_content_types[0]
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2407
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2408 # accept_type will be empty only if there is an Accept header
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2409 # with invalid values.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2410 if accept_type:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2411 return (accept_type, uri, None)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2412
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2413 if valid_binary_content_types:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2414 return (None, uri,
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2415 self.error_obj(
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2416 406,
8272
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2417 _("Requested content type(s) '%(requested)s' not "
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2418 "available.\nAcceptable mime types are: */*, "
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2419 "%(acceptable)s") %
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2420 {"requested":
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2421 self.client.request.headers.get('Accept'),
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2422 "acceptable": ", ".join(sorted(
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2423 valid_binary_content_types))}))
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2424
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2425 return (None, uri,
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2426 self.error_obj(
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2427 406,
8272
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2428 _("Requested content type(s) '%(requested)s' not "
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2429 "available.\nAcceptable mime types are: */*, "
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2430 "%(acceptable)s") %
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2431 {"requested":
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2432 self.client.request.headers.get('Accept'),
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2433 "acceptable": ", ".join(sorted(
fde5893b6c25 fix: correct strings with multiple %s that can't be translated
John Rouillard <rouilj@ieee.org>
parents: 8230
diff changeset
2434 self.__accepted_content_type.keys()))}))
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2435
8534
1f8492d68aca bug: using 'null' value for attributes causes error.
John Rouillard <rouilj@ieee.org>
parents: 8530
diff changeset
2436 @timer(name="rest_dispatch", tag="args[2]",
1f8492d68aca bug: using 'null' value for attributes causes error.
John Rouillard <rouilj@ieee.org>
parents: 8530
diff changeset
2437 writer=logging.getLogger('roundup.timer').error)
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2438 def dispatch(self, method, uri, input_payload):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
2439 """format and process the request"""
5732
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2440 output = None
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2441
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2442 # Before we do anything has the user hit the rate limit.
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2443
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2444 # Get the limit here and not in the init() routine to allow
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2445 # for a different rate limit per user.
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2446 apiRateLimit = self.getRateLimit()
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2447
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2448 if apiRateLimit: # if None, disable rate limiting
7605
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2449 LimitExceeded, limitStatus = self.handle_apiRateLimitExceeded(
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2450 apiRateLimit)
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2451 if LimitExceeded:
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2452 return LimitExceeded # error message
7595
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2453
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2454 for header, value in limitStatus.items():
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2455 # Retry-After will be 0 because
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2456 # user still has quota available.
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2457 # Don't put out the header.
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2458 if header in ('Retry-After',):
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2459 continue
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2460 self.client.setHeader(header, value)
5732
0e6ed3d72f92 Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents: 5731
diff changeset
2461
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
2462 # if X-HTTP-Method-Override is set, follow the override method
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
2463 headers = self.client.request.headers
5620
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2464 # Never allow GET to be an unsafe operation (i.e. data changing).
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2465 # User must use POST to "tunnel" DELETE, PUT, OPTIONS etc.
5650
e8ca7072c629 Fix Python 3 issues in REST code.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5646
diff changeset
2466 override = headers.get('X-HTTP-Method-Override')
5620
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2467 if override:
5730
4aa26a9f3b47 Tighten up use of X-HTTP-Method-Override to only work with POST.
John Rouillard <rouilj@ieee.org>
parents: 5729
diff changeset
2468 if method.upper() == 'POST':
5620
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2469 logger.debug(
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2470 'Method overridden from %s to %s', method, override)
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2471 method = override
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2472 else:
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2473 output = self.error_obj(400,
5730
4aa26a9f3b47 Tighten up use of X-HTTP-Method-Override to only work with POST.
John Rouillard <rouilj@ieee.org>
parents: 5729
diff changeset
2474 "X-HTTP-Method-Override: %s must be used with "
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2475 "POST method not %s." % (override, method.upper()))
5620
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2476 logger.info(
5730
4aa26a9f3b47 Tighten up use of X-HTTP-Method-Override to only work with POST.
John Rouillard <rouilj@ieee.org>
parents: 5729
diff changeset
2477 'Ignoring X-HTTP-Method-Override using %s request on %s',
4aa26a9f3b47 Tighten up use of X-HTTP-Method-Override to only work with POST.
John Rouillard <rouilj@ieee.org>
parents: 5729
diff changeset
2478 method.upper(), uri)
4aa26a9f3b47 Tighten up use of X-HTTP-Method-Override to only work with POST.
John Rouillard <rouilj@ieee.org>
parents: 5729
diff changeset
2479
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2480 # FIXME: when this method is refactored, change
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2481 # determine_output_format to raise an exception. Catch it here
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2482 # and return early. Also set self.client.response_code from
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2483 # error object['error']['status'] and remove from
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2484 # determine_output_format.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2485 (output_format, uri, error) = self.determine_output_format(uri)
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2486 if error:
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2487 output = error
7596
e5fa31aad344 fix: replace bad reverted code change; allow js rate headers
John Rouillard <rouilj@ieee.org>
parents: 7595
diff changeset
2488
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2489 if method.upper() == 'OPTIONS':
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2490 # add access-control-allow-* access-control-max-age to support
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2491 # CORS preflight
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2492 self.client.setHeader(
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2493 "Access-Control-Allow-Headers",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2494 "Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override"
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2495 )
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2496 # can be overridden by options handlers to provide supported
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2497 # methods for endpoint
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2498 self.client.setHeader(
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2499 "Access-Control-Allow-Methods",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2500 "HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH"
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2501 )
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2502 # cache the Access headings for a week. Allows one CORS pre-flight
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2503 # request to be reused again and again.
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2504 self.client.setHeader("Access-Control-Max-Age", "86400")
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2505
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2506 # response may change based on Origin value.
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
2507 self.client.setVary("Origin")
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2508
7156
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2509 # expose these headers to rest clients. Otherwise they can't
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2510 # respond to:
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2511 # rate limiting (*RateLimit*, Retry-After)
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2512 # obsolete API endpoint (Sunset)
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2513 # options request to discover supported methods (Allow)
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2514 self.client.setHeader(
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2515 "Access-Control-Expose-Headers",
7173
5159d8ea585a chore: flake8 formatting fixes
John Rouillard <rouilj@ieee.org>
parents: 7158
diff changeset
2516 ", ".join([
7156
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2517 "X-RateLimit-Limit",
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2518 "X-RateLimit-Remaining",
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2519 "X-RateLimit-Reset",
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2520 "X-RateLimit-Limit-Period",
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2521 "Retry-After",
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2522 "Sunset",
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2523 "Allow",
7173
5159d8ea585a chore: flake8 formatting fixes
John Rouillard <rouilj@ieee.org>
parents: 7158
diff changeset
2524 ])
7156
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2525 )
6f09103a6522 [issue2551263] expose headers to rest clients
John Rouillard <rouilj@ieee.org>
parents: 7155
diff changeset
2526
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2527 # Allow-Origin must match origin supplied by client. '*' doesn't
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2528 # work for authenticated requests.
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
2529 self.client.setHeader(
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2530 "Access-Control-Allow-Origin",
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2531 self.client.request.headers.get("Origin")
5581
30793a435185 Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5580
diff changeset
2532 )
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2533
7155
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2534 # Allow credentials if origin is acceptable.
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2535 #
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2536 # If Access-Control-Allow-Credentials header not returned,
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2537 # but the client request is made with credentials
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2538 # data will be sent but not made available to the
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2539 # calling javascript in browser.
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2540 # Prevents exposure of data to an invalid origin when
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2541 # credentials are sent by client.
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2542 #
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2543 # If admin puts * first in allowed_api_origins
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2544 # we do not allow credentials but do reflect the origin.
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2545 # This allows anonymous access.
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2546 if self.client.is_origin_header_ok(api=True, credentials=True):
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2547 self.client.setHeader(
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2548 "Access-Control-Allow-Credentials",
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2549 "true"
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2550 )
89a59e46b3af improve REST interface security
John Rouillard <rouilj@ieee.org>
parents: 6926
diff changeset
2551
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2552 # set allow header in case of error. 405 handlers below should
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2553 # replace it with a custom version as will OPTIONS handler
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2554 # doing CORS.
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
2555 self.client.setHeader(
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
2556 "Allow",
5702
61874fd78ced Fix OPTIONS responses:
John Rouillard <rouilj@ieee.org>
parents: 5701
diff changeset
2557 "OPTIONS, GET, POST, PUT, DELETE, PATCH"
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
2558 )
6693
9a1f5e496e6c issue2551203 - Add support for CORS preflight request
John Rouillard <rouilj@ieee.org>
parents: 6561
diff changeset
2559
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2560 # Is there an input_payload.value with format json data?
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2561 # If so turn it into an object that emulates enough
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2562 # of the FieldStorge methods/props to allow a response.
5650
e8ca7072c629 Fix Python 3 issues in REST code.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5646
diff changeset
2563 content_type_header = headers.get('Content-Type', None)
5655
207e0f5d551c Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
parents: 5650 5653
diff changeset
2564 # python2 is str type, python3 is bytes
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2565 if type(input_payload.value) in (str, bytes) and content_type_header:
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2566 # the structure of a content-type header
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2567 # is complex: mime-type; options(charset ...)
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2568 # for now we just accept application/json.
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2569 # FIXME there should be a function:
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2570 # parse_content_type_header(content_type_header)
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2571 # that returns a tuple like the Accept header parser.
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2572 # Then the test below could use:
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2573 # parsed_content_type_header[0].lower() == 'json'
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2574 # That way we could handle stuff like:
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2575 # application/vnd.roundup-foo+json; charset=UTF8
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2576 # for example.
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2577 if content_type_header.lower() == "application/json":
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2578 try:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2579 input_payload = SimulateFieldStorageFromJson(b2s(input_payload.value))
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2580 except ValueError as msg:
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2581 output = self.error_obj(400, msg)
6311
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
2582 else:
8094
8e310a7b5e09 issue2551131 - Return accept-patch if patch body not accepted (415 code)
John Rouillard <rouilj@ieee.org>
parents: 7983
diff changeset
2583 if method.upper() == "PATCH":
8e310a7b5e09 issue2551131 - Return accept-patch if patch body not accepted (415 code)
John Rouillard <rouilj@ieee.org>
parents: 7983
diff changeset
2584 self.client.setHeader("Accept-Patch",
8e310a7b5e09 issue2551131 - Return accept-patch if patch body not accepted (415 code)
John Rouillard <rouilj@ieee.org>
parents: 7983
diff changeset
2585 "application/json, "
8e310a7b5e09 issue2551131 - Return accept-patch if patch body not accepted (415 code)
John Rouillard <rouilj@ieee.org>
parents: 7983
diff changeset
2586 "application/x-www-form-urlencoded")
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
2587 output = self.error_obj(415,
6311
be8d5a8e090a Fix uncaught error when parsing rest headers, document
John Rouillard <rouilj@ieee.org>
parents: 6254
diff changeset
2588 "Unable to process input of type %s" %
6926
626ef84579a3 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 6824
diff changeset
2589 content_type_header)
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2590
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2591 # check for pretty print
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2592 try:
8194
2ecd1a871993 chore(ruff): replace not a == b with a != b
John Rouillard <rouilj@ieee.org>
parents: 8193
diff changeset
2593 pretty_output = input_payload['@pretty'].value.lower() != "false"
5823
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5808
diff changeset
2594 # Can also return a TypeError ("not indexable")
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5808
diff changeset
2595 # In case the FieldStorage could not parse the result
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5808
diff changeset
2596 except (KeyError, TypeError):
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2597 pretty_output = True
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2598
6185
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
2599 # check for runtime statistics
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
2600 try:
6561
01a5dd90286e Remove unused report_stats
John Rouillard <rouilj@ieee.org>
parents: 6559
diff changeset
2601 # self.report_stats initialized to False
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2602 self.report_stats = input_payload['@stats'].value.lower() == "true"
6185
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
2603 # Can also return a TypeError ("not indexable")
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
2604 # In case the FieldStorage could not parse the result
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
2605 except (KeyError, TypeError):
6561
01a5dd90286e Remove unused report_stats
John Rouillard <rouilj@ieee.org>
parents: 6559
diff changeset
2606 pass
6185
1cb2375015f0 Enable timing stats reporting in REST interface.
John Rouillard <rouilj@ieee.org>
parents: 6111
diff changeset
2607
5686
eb51c0d9c9bf Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents: 5685
diff changeset
2608 # check for @apiver in query string
6510
d5a3fe9ac12d Make error message for bad apiver a little better.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2609 msg = _("Unrecognized api version: %s. "
d5a3fe9ac12d Make error message for bad apiver a little better.
John Rouillard <rouilj@ieee.org>
parents: 6509
diff changeset
2610 "See /rest without specifying api version "
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2611 "for supported versions.")
5686
eb51c0d9c9bf Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents: 5685
diff changeset
2612 try:
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2613 # FIXME: the version priority here is different
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2614 # from accept header. accept mime type in url
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2615 # takes priority over Accept header. Opposite here.
5686
eb51c0d9c9bf Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents: 5685
diff changeset
2616 if not self.api_version:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2617 self.api_version = int(input_payload['@apiver'].value)
5823
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5808
diff changeset
2618 # Can also return a TypeError ("not indexable")
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5808
diff changeset
2619 # In case the FieldStorage could not parse the result
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5808
diff changeset
2620 except (KeyError, TypeError):
5686
eb51c0d9c9bf Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents: 5685
diff changeset
2621 self.api_version = None
eb51c0d9c9bf Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents: 5685
diff changeset
2622 except ValueError:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2623 output = self.error_obj(406, msg % input_payload['@apiver'].value)
5711
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2624
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2625 # by this time the API version is set. Error if we don't
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2626 # support it?
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2627 if self.api_version is None:
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2628 # FIXME: do we need to raise an error if client did not specify
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2629 # version? This may be a good thing to require. Note that:
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2630 # Accept: application/json; version=1 may not be legal but....
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2631 # Use default if not specified for now.
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2632 self.api_version = self.__default_api_version
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2633 elif self.api_version not in self.__supported_api_versions:
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2634 output = self.error_obj(406, msg % self.api_version)
5711
aea2cc142c1b Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents: 5710
diff changeset
2635
5691
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
2636 # sadly del doesn't work on FieldStorage which can be the type of
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2637 # input_payload. So we have to ignore keys starting with @ at other
5691
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
2638 # places in the code.
dbf422a8cff7 Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents: 5690
diff changeset
2639 # else:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2640 # del(input_payload['@apiver'])
5686
eb51c0d9c9bf Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents: 5685
diff changeset
2641
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
2642 # Call the appropriate method
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
2643 try:
5620
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2644 # If output was defined by a prior error
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2645 # condition skip call
5f8e6034427c Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents: 5619
diff changeset
2646 if not output:
8188
e5362f8e1808 chore(ruff): rename input and id parms/vars - don't shadow builtin
John Rouillard <rouilj@ieee.org>
parents: 8180
diff changeset
2647 output = Routing.execute(self, uri, method, input_payload)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
2648 except NotFound as msg:
5597
de9933cfcfc4 Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5596
diff changeset
2649 output = self.error_obj(404, msg)
5602
c40d04915e23 Python3 fixes
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5600
diff changeset
2650 except Reject as msg:
6525
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2651 output = self.error_obj(405, msg.args[0])
c505c774a94d Mutiple changes to REST code.
John Rouillard <rouilj@ieee.org>
parents: 6517
diff changeset
2652 self.client.setHeader("Allow", msg.args[1])
5567
1af57f9d5bf7 Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5566
diff changeset
2653
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2654 return self.format_dispatch_output(output_format,
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2655 output,
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2656 pretty_output)
7595
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2657
7605
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2658 def format_dispatch_output(self, accept_mime_type, output,
5b3ecdfd77f7 refactor(api): extract api rate limit handling; add default val
John Rouillard <rouilj@ieee.org>
parents: 7597
diff changeset
2659 pretty_print=True):
5590
4d8746c73fdb Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5589
diff changeset
2660 # Format the content type
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2661 # if accept_mime_type is None, the client specified invalid
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2662 # mime types so we default to json output.
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2663 if accept_mime_type == "json" or accept_mime_type is None:
5589
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
2664 self.client.setHeader("Content-Type", "application/json")
7595
26ef5054e510 refactor(api): early return if REST rate limit is exceeded
John Rouillard <rouilj@ieee.org>
parents: 7569
diff changeset
2665 if pretty_print:
5589
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
2666 indent = 4
5574
55f97de157e7 Headers
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5573
diff changeset
2667 else:
5589
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
2668 indent = None
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
2669 output = RoundupJSONEncoder(indent=indent).encode(output)
8177
2967f37e73e4 refactor: issue2551289. invalid REST Accept header stops request
John Rouillard <rouilj@ieee.org>
parents: 8126
diff changeset
2670 elif accept_mime_type == "xml" and dicttoxml:
5631
a5c890d308c3 Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents: 5630
diff changeset
2671 self.client.setHeader("Content-Type", "application/xml")
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2672 if 'error' in output:
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2673 # capture values in error with types unsupported
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2674 # by dicttoxml e.g. an exception, into something it
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2675 # can handle
8207
894eabf95385 chore(ruff): sort imports.
John Rouillard <rouilj@ieee.org>
parents: 8206
diff changeset
2676 import collections
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2677 import numbers
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2678 for key, val in output['error'].items():
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2679 if isinstance(val, numbers.Number) or type(val) in \
8205
4993e122235e chore(ruff): suppress combine branches with one or expression
John Rouillard <rouilj@ieee.org>
parents: 8204
diff changeset
2680 (str, unicode): # noqa: SIM114
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2681 pass
8205
4993e122235e chore(ruff): suppress combine branches with one or expression
John Rouillard <rouilj@ieee.org>
parents: 8204
diff changeset
2682 elif hasattr(val, 'isoformat'): # datetime # noqa: SIM114
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2683 pass
8205
4993e122235e chore(ruff): suppress combine branches with one or expression
John Rouillard <rouilj@ieee.org>
parents: 8204
diff changeset
2684 elif type(val) is bool: # noqa: SIM114
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2685 pass
8205
4993e122235e chore(ruff): suppress combine branches with one or expression
John Rouillard <rouilj@ieee.org>
parents: 8204
diff changeset
2686 elif isinstance(val, dict): # noqa: SIM114
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2687 pass
8205
4993e122235e chore(ruff): suppress combine branches with one or expression
John Rouillard <rouilj@ieee.org>
parents: 8204
diff changeset
2688 elif isinstance(val, collections.Iterable): # noqa: SIM114
5707
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2689 pass
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2690 elif val is None:
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2691 pass
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2692 else:
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2693 output['error'][key] = str(val)
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2694
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2695 output = '<?xml version="1.0" encoding="UTF-8" ?>\n' + \
f9a762678af6 Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents: 5705
diff changeset
2696 b2s(dicttoxml(output, root=False))
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2697 elif accept_mime_type:
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2698 self.client.setHeader("Content-Type", accept_mime_type)
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2699 # do not send etag when getting binary_content. The ETag
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2700 # is for the item not the content of the item. So the ETag
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2701 # can change even though the content is the same. Since
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2702 # content is immutable by default, the client shouldn't
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2703 # need the etag for writing.
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2704 self.client.setHeader("ETag", None)
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2705 return output['data']['data']
5589
5a2de4c19109 Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5588
diff changeset
2706 else:
8180
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2707 self.client.response_code = 500
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2708 output = _("Internal error while formatting response.\n"
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2709 "accept_mime_type is not defined. This should\n"
d02ce1d14acd feat: issue2551068 - Provide way to retrieve file/msg data via rest endpoint.
John Rouillard <rouilj@ieee.org>
parents: 8177
diff changeset
2710 "never happen\n")
5557
213a56c91471 Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5556
diff changeset
2711
5639
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
2712 # Make output json end in a newline to
f576957cbb1f Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents: 5638
diff changeset
2713 # separate from following text in logs etc..
5653
ba67e397f063 Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents: 5646
diff changeset
2714 return bs2b(output + "\n")
5566
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2715
5567
1af57f9d5bf7 Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5566
diff changeset
2716
5566
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2717 class RoundupJSONEncoder(json.JSONEncoder):
5582
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
2718 """RoundupJSONEncoder overrides the default JSONEncoder to handle all
519b7fd8c8c3 Added docstring
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5581
diff changeset
2719 types of the object without returning any error"""
5566
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2720 def default(self, obj):
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2721 try:
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2722 result = json.JSONEncoder.default(self, obj)
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2723 except TypeError:
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2724 result = str(obj)
2830793d1510 Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents: 5565
diff changeset
2725 return result
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2726
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2727
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2728 class SimulateFieldStorageFromJson():
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2729 '''
5689
2c516d113620 Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5687
diff changeset
2730 The internals of the rest interface assume the data was sent as
2c516d113620 Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5687
diff changeset
2731 application/x-www-form-urlencoded. So we should have a
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2732 FieldStorage and MiniFieldStorage structure.
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2733
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2734 However if we want to handle json data, we need to:
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2735 1) create the Fieldstorage/MiniFieldStorage structure
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2736 or
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2737 2) simultate the interface parts of FieldStorage structure
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2738
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2739 To do 2, create a object that emulates the:
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2740
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2741 object['prop'].value
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2742
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2743 references used when accessing a FieldStorage structure.
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2744
5690
4aae822e2cb4 Added a few comments and a test that fails with the pre-patched code
John Rouillard <rouilj@ieee.org>
parents: 5689
diff changeset
2745 That's what this class does with all names and values as native
4aae822e2cb4 Added a few comments and a test that fails with the pre-patched code
John Rouillard <rouilj@ieee.org>
parents: 5689
diff changeset
2746 strings. Note that json is UTF-8, so we convert any unicode to
4aae822e2cb4 Added a few comments and a test that fails with the pre-patched code
John Rouillard <rouilj@ieee.org>
parents: 5689
diff changeset
2747 string.
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2748
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2749 '''
8472
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
2750
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
2751 __slots__ = ("json_dict", "value")
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
2752
8534
1f8492d68aca bug: using 'null' value for attributes causes error.
John Rouillard <rouilj@ieee.org>
parents: 8530
diff changeset
2753 @timer(name="simultateFieldStorage", tag="args[1][:10]",
1f8492d68aca bug: using 'null' value for attributes causes error.
John Rouillard <rouilj@ieee.org>
parents: 8530
diff changeset
2754 writer=logging.getLogger('roundup.timer').error)
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2755 def __init__(self, json_string):
8218
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2756 '''Parse the json string into an internal dict.
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2757
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2758 Because spec for rest post once exactly (POE) shows
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2759 posting empty content. An empty string results in an empty
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2760 dict, not a json parse error.
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2761 '''
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2762 def raise_error_on_constant(x):
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2763 raise ValueError("Unacceptable number: %s" % x)
8218
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2764 if json_string == "":
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2765 self.json_dict = {}
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2766 self.value = None
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2767 return
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2768
5710
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
2769 try:
0b79bfcb3312 Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents: 5707
diff changeset
2770 self.json_dict = json.loads(json_string,
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2771 parse_constant=raise_error_on_constant)
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2772 self.value = [self.FsValue(index, self.json_dict[index])
8534
1f8492d68aca bug: using 'null' value for attributes causes error.
John Rouillard <rouilj@ieee.org>
parents: 8530
diff changeset
2773 for index in self.json_dict if
1f8492d68aca bug: using 'null' value for attributes causes error.
John Rouillard <rouilj@ieee.org>
parents: 8530
diff changeset
2774 self.json_dict[index] is not None]
8220
818751637b77 fix: make rest.py still load on python2, do not test bad json
John Rouillard <rouilj@ieee.org>
parents: 8218
diff changeset
2775 except (JSONDecodeError, ValueError) as e:
8218
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2776 raise ValueError(e.args[0] + ". JSON is: " + json_string)
32aaf5dc562b fix(REST): issue2551383; improve errors for bad json, fix PUT docs
John Rouillard <rouilj@ieee.org>
parents: 8213
diff changeset
2777
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2778 class FsValue:
8472
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
2779
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
2780 __slots__ = ("name", "value")
224ccb8b49ca refactor: change some classes to use __slots__
John Rouillard <rouilj@ieee.org>
parents: 8319
diff changeset
2781
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2782 '''Class that does nothing but response to a .value property '''
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2783 def __init__(self, name, val):
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2784 self.name = u2s(name)
5689
2c516d113620 Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5687
diff changeset
2785 if is_us(val):
5690
4aae822e2cb4 Added a few comments and a test that fails with the pre-patched code
John Rouillard <rouilj@ieee.org>
parents: 5689
diff changeset
2786 # handle most common type first
5998
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2787 self.value = u2s(val)
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2788 elif isinstance(val, type([])):
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2789 # then lists of strings
776ca681f925 flake8 cleanups
John Rouillard <rouilj@ieee.org>
parents: 5987
diff changeset
2790 self.value = [u2s(v) for v in val]
8530
36be91f671d0 bug: fix case where null json value for datetime fails
John Rouillard <rouilj@ieee.org>
parents: 8472
diff changeset
2791 elif val is None:
36be91f671d0 bug: fix case where null json value for datetime fails
John Rouillard <rouilj@ieee.org>
parents: 8472
diff changeset
2792 self.value = None
5689
2c516d113620 Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5687
diff changeset
2793 else:
5690
4aae822e2cb4 Added a few comments and a test that fails with the pre-patched code
John Rouillard <rouilj@ieee.org>
parents: 5689
diff changeset
2794 # then stringify anything else (int, float)
5689
2c516d113620 Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5687
diff changeset
2795 self.value = str(val)
5643
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2796
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2797 def __getitem__(self, index):
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2798 '''Return an FsValue created from the value of self.json_dict[index]
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2799 '''
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2800 return self.FsValue(index, self.json_dict[index])
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2801
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2802 def __contains__(self, index):
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2803 ''' implement: 'foo' in DICT '''
a60cbbcc9309 Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents: 5639
diff changeset
2804 return index in self.json_dict

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