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