Mercurial > p > roundup > code
annotate roundup/rest.py @ 5874:6630baff5f68
Implement exact string search in REST API
Now with ':=' instead of '=' an exact string match is requested.
In addition we now support '~=' for a substring search.
The old semantics of '=' is kept. The new syntax works for all
types of properties but only makes a difference for String properties.
Note that this is not yet documented, pending discussion if we want to
keep this syntax.
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Tue, 27 Aug 2019 18:37:18 +0200 |
| parents | 14f5c3179711 |
| children | 2b78e21d7047 |
| 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 | |
| 10 try: | |
| 11 from urllib.parse import urlparse | |
| 12 except ImportError: | |
| 13 from urlparse import urlparse | |
| 5574 | 14 import os |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
15 import json |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
16 import sys |
|
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
17 import time |
|
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
18 import traceback |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
19 import re |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
20 |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
21 try: |
|
5653
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
22 # if dicttoxml installed in roundup directory, use it |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
23 from roundup.dicttoxml 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
|
24 except ImportError: |
|
5653
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
25 try: |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
26 # else look in sys.path |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
27 from dicttoxml import dicttoxml |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
28 except ImportError: |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
29 # else not supported |
|
ba67e397f063
Fix string/bytes issues under python 3.
John Rouillard <rouilj@ieee.org>
parents:
5646
diff
changeset
|
30 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
|
31 |
|
5808
bab86c874efb
Fix: PendingDeprecationWarning: HMAC() without an explicit digestmod
John Rouillard <rouilj@ieee.org>
parents:
5799
diff
changeset
|
32 from hashlib import md5 |
|
bab86c874efb
Fix: PendingDeprecationWarning: HMAC() without an explicit digestmod
John Rouillard <rouilj@ieee.org>
parents:
5799
diff
changeset
|
33 |
|
5557
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
34 from roundup import hyperdb |
| 5596 | 35 from roundup import date |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
36 from roundup import actions |
|
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
|
37 from roundup.i18n import _ |
|
5689
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
38 from roundup.anypy.strings import bs2b, b2s, u2s, is_us |
|
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
|
39 from roundup.rate_limit import RateLimit, Gcra |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
40 from roundup.exceptions import * |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
41 from roundup.cgi.exceptions import * |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
42 |
|
5726
e199d0ae4a25
issue2551033: prevent reverse engineering hidden data by using etags
John Rouillard <rouilj@ieee.org>
parents:
5715
diff
changeset
|
43 import hmac |
|
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
|
44 from datetime import timedelta |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
45 |
| 5602 | 46 # Py3 compatible basestring |
| 47 try: | |
| 48 basestring | |
| 49 except NameError: | |
| 50 basestring = str | |
| 51 unicode = str | |
|
5588
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
52 |
|
5620
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
53 import logging |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
54 logger = logging.getLogger('roundup.rest') |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
55 |
|
5710
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
56 import roundup.anypy.random_ as random_ |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
57 if not random_.is_weak: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
58 logger.debug("Importing good random generator") |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
59 else: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
60 logger.warning("**SystemRandom not available. Using poor random generator") |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
61 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
62 chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
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' |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
94 except: |
|
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() |
| 5602 | 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 |
| 5602 | 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 |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
110 result = { |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
111 'error': { |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
112 'status': code, |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
113 'msg': data |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
114 } |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
115 } |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
116 else: |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
117 result = { |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
118 'data': data |
|
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 return result |
|
6b3a9655a7d9
Move decorator to outside of the class
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5587
diff
changeset
|
121 return format_object |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
122 |
|
5729
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
123 def calculate_etag (node, key, classname="Missing", id="0", |
|
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
124 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
|
125 '''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
|
126 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
|
127 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
128 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
|
129 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
|
130 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
131 <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
|
132 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
133 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
|
134 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
135 {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
|
136 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
137 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
|
138 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
|
139 calculate the etag. |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
140 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
141 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
|
142 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
|
143 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
144 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
|
145 ''' |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
146 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
147 items = node.items(protected=True) # include every item |
|
5729
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
148 etag = hmac.new(bs2b(key),bs2b(repr_format + |
|
5808
bab86c874efb
Fix: PendingDeprecationWarning: HMAC() without an explicit digestmod
John Rouillard <rouilj@ieee.org>
parents:
5799
diff
changeset
|
149 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
|
150 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
|
151 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
|
152 # 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
|
153 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
|
154 |
|
5729
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
155 def check_etag (node, key, etags, classname="Missing", id="0", |
|
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
156 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
|
157 '''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
|
158 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
159 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
|
160 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
|
161 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
|
162 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
|
163 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
164 ''' |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
165 have_etag_match=False |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
166 |
|
5729
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
167 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
|
168 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
|
169 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
170 for etag in etags: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
171 if etag is not None: |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
172 if etag != node_etag: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
173 return False |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
174 have_etag_match=True |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
175 |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
176 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
|
177 return True |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
178 else: |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
179 return False |
|
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 def obtain_etags(headers,input): |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
182 '''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
|
183 etags = [] |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
184 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
|
185 etags.append(input['@etag'].value) |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
186 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
|
187 return etags |
| 5596 | 188 |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
189 def parse_accept_header(accept): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
190 """ |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
191 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
|
192 [(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
|
193 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
194 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
|
195 application/vnd.yourcompany.yourproduct-v1.1+json |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
196 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
197 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
|
198 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
|
199 negotiation decisions can be made. |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
200 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
201 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
|
202 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
203 # 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
|
204 # 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
|
205 # https://github.com/martinblech/mimerender |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
206 """ |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
207 result = [] |
|
5731
058ef18af5fd
Prevent crash when clients do not set accept header. Use
John Rouillard <rouilj@ieee.org>
parents:
5730
diff
changeset
|
208 if not accept: |
|
058ef18af5fd
Prevent crash when clients do not set accept header. Use
John Rouillard <rouilj@ieee.org>
parents:
5730
diff
changeset
|
209 return result |
|
058ef18af5fd
Prevent crash when clients do not set accept header. Use
John Rouillard <rouilj@ieee.org>
parents:
5730
diff
changeset
|
210 |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
211 for media_range in accept.split(","): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
212 parts = media_range.split(";") |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
213 media_type = parts.pop(0).strip() |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
214 media_params = [] |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
215 # 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
|
216 # docstring) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
217 typ, subtyp = media_type.split('/') |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
218 # check for a + in the sub-type |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
219 if '+' in subtyp: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
220 # 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
|
221 vnd, sep, extra = subtyp.partition('+') |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
222 if vnd.startswith('vnd'): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
223 # 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
|
224 # version out |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
225 if '-v' in vnd: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
226 vnd, sep, rest = vnd.rpartition('-v') |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
227 if len(rest): |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
228 # add the version as a media param |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
229 try: |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
230 media_params.append(('version', |
|
5685
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
231 rest)) |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
232 except ValueError: |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
233 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
|
234 # 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
|
235 media_params.append(('vendor', vnd)) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
236 # 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
|
237 # 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
|
238 media_type = '{}/{}'.format(typ, extra) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
239 q = 1.0 |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
240 for part in parts: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
241 (key, value) = part.lstrip().split("=", 1) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
242 key = key.strip() |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
243 value = value.strip() |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
244 if key == "q": |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
245 q = float(value) |
|
5744
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
246 if q > 1.0: |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
247 # 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
|
248 # 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
|
249 # 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
|
250 q = 0.0001 |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
251 else: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
252 media_params.append((key, value)) |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
253 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
|
254 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
|
255 return result |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
256 |
| 5596 | 257 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
258 class Routing(object): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
259 __route_map = {} |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
260 __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
|
261 url_to_regex = r"([\\w.\-~!$&'()*+,;=:\%%]+)" |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
262 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
263 @classmethod |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
264 def route(cls, rule, methods='GET'): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
265 """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
|
266 given URL rule: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
267 @self.route('/') |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
268 def index(): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
269 return 'Hello World' |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
270 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
271 rest/ will be added to the beginning of the url string |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
272 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
273 Args: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
274 rule (string): the URL rule |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
275 methods (string or tuple or list): the http method |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
276 """ |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
277 # strip the '/' character from rule string |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
278 rule = rule.strip('/') |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
279 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
280 # add 'rest/' to the rule string |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
281 if not rule.startswith('rest/'): |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
282 rule = '^rest/' + rule + '$' |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
283 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
284 if isinstance(methods, basestring): # convert string to tuple |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
285 methods = (methods,) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
286 methods = set(item.upper() for item in methods) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
287 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
288 # convert a rule to a compiled regex object |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
289 # so /data/<:class>/<:id> will become |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
290 # /data/([charset]+)/([charset]+) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
291 # and extract the variable names to a list [(class), (id)] |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
292 func_vars = cls.__var_to_regex.findall(rule) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
293 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
|
294 # 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
|
295 # 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
|
296 # 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
|
297 # func_obj dict indexed by method. |
|
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
298 pattern = rule.pattern |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
299 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
300 # then we decorate it: |
|
5851
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
301 # route_map[pattern] = (rule, func_dict) |
|
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
302 # 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
|
303 # indexed by method name |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
304 def decorator(func): |
|
5851
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
305 rule_route = cls.__route_map.get(pattern, (rule, {})) |
|
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
306 rule_dict = rule_route [1] |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
307 func_obj = { |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
308 'func': func, |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
309 'vars': func_vars |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
310 } |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
311 for method in methods: |
|
5851
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
312 rule_dict[method] = func_obj |
|
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
313 cls.__route_map[pattern] = rule_route |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
314 return func |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
315 return decorator |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
316 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
317 @classmethod |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
318 def execute(cls, instance, path, method, input): |
| 5679 | 319 # format the input, note that we may not lowercase the path |
| 320 # here, URL parameters are case-sensitive | |
| 321 path = path.strip('/') | |
|
5622
2a7d23a098ca
Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents:
5621
diff
changeset
|
322 if path == 'rest': |
|
2a7d23a098ca
Make @Routing.route('/') decoration work. This decoration matches
John Rouillard <rouilj@ieee.org>
parents:
5621
diff
changeset
|
323 # 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
|
324 path = 'rest/' |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
325 method = method.upper() |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
326 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
327 # find the rule match the path |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
328 # then get handler match the method |
|
5851
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
329 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
|
330 # use compiled regex to find rule |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
331 match_obj = path_regex.match(path) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
332 if match_obj: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
333 try: |
|
5851
167ef847fcdf
issue2551053: Fix routing dict in rest.py
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5842
diff
changeset
|
334 func_obj = funcs[method] |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
335 except KeyError: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
336 raise Reject('Method %s not allowed' % method) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
337 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
338 # retrieve the vars list and the function caller |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
339 list_vars = func_obj['vars'] |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
340 func = func_obj['func'] |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
341 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
342 # 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
|
343 args = dict(zip(list_vars, match_obj.groups())) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
344 args['input'] = input |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
345 return func(instance, **args) |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
346 raise NotFound('Nothing matches the given URI') |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
347 |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
348 |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
349 class RestfulInstance(object): |
| 5582 | 350 """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
|
351 |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
352 __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
|
353 __accepted_content_type = { |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
354 "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
|
355 "*/*": "json", |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
356 } |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
357 __default_accept_type = "json" |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
358 |
|
5685
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
359 __default_api_version = 1 |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
360 __supported_api_versions = [ 1 ] |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
361 |
|
5687
83037aaf3b9d
Move definition/initialization of api_version into the class and out
John Rouillard <rouilj@ieee.org>
parents:
5686
diff
changeset
|
362 |
|
83037aaf3b9d
Move definition/initialization of api_version into the class and out
John Rouillard <rouilj@ieee.org>
parents:
5686
diff
changeset
|
363 api_version = None |
|
83037aaf3b9d
Move definition/initialization of api_version into the class and out
John Rouillard <rouilj@ieee.org>
parents:
5686
diff
changeset
|
364 |
|
5568
edab9daa8015
Make objects returned by REST follow the standard
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5567
diff
changeset
|
365 def __init__(self, client, db): |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
366 self.client = client |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
367 self.db = db |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
368 self.translator = client.translator |
| 5604 | 369 # This used to be initialized from client.instance.actions which |
| 370 # would include too many actions that do not make sense in the | |
| 371 # REST-API context, so for now we only permit the retire and | |
| 372 # restore actions. | |
| 373 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
|
374 |
|
5616
aa4c271514ae
Original code generated url's using a harcoded protocol and took the
John Rouillard <rouilj@ieee.org>
parents:
5604
diff
changeset
|
375 # 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
|
376 self.base_path = '%srest' % (self.db.config.TRACKER_WEB) |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
377 self.data_path = self.base_path + '/data' |
|
5569
2718aeb55ffa
Add base_path to generate uri
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5568
diff
changeset
|
378 |
|
5744
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
379 if dicttoxml: # add xml if supported |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
380 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
|
381 |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
382 def props_from_args(self, cl, args, itemid=None, skip_protected=True): |
| 5582 | 383 """Construct a list of properties from the given arguments, |
| 384 and return them after validation. | |
| 385 | |
| 386 Args: | |
| 387 cl (string): class object of the resource | |
| 388 args (list): the submitted form of the user | |
| 389 itemid (string, optional): itemid of the object | |
| 390 | |
| 391 Returns: | |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
392 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
|
393 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
|
394 |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
395 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
|
396 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
|
397 |
| 5582 | 398 |
| 399 """ | |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
400 unprotected_class_props = cl.properties.keys() |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
401 protected_class_props = [ p for p in |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
402 list(cl.getprops(protected=True)) |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
403 if p not in unprotected_class_props ] |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
404 props = {} |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
405 # props = dict.fromkeys(class_props, None) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
406 |
|
5710
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
407 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
|
408 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
|
409 |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
410 for arg in args: |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
411 key = arg.name |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
412 value = arg.value |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
413 if key.startswith('@'): |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
414 # meta setting, not db property setting/reference |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
415 continue |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
416 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
|
417 # 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
|
418 # 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
|
419 # 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
|
420 # 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
|
421 # 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
|
422 # 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
|
423 # 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
|
424 # 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
|
425 # 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
|
426 # 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
|
427 # 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
|
428 # I am not positive. |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
429 if skip_protected: |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
430 continue |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
431 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
|
432 # report bad props as this is an error. |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
433 raise UsageError("Property %s not found in class %s"%(key, |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
434 cl.classname)) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
435 props[key] = self.prop_from_arg(cl, key, value, itemid) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
436 |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
437 return props |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
438 |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
439 def prop_from_arg(self, cl, key, value, itemid=None): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
440 """Construct a property from the given argument, |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
441 and return them after validation. |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
442 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
443 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
444 cl (string): class object of the resource |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
445 key (string): attribute key |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
446 value (string): attribute value |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
447 itemid (string, optional): itemid of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
448 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
449 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
450 value: value of validated properties |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
451 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
452 """ |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
453 prop = None |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
454 if isinstance(key, unicode): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
455 try: |
| 5602 | 456 x = key.encode('ascii') |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
457 except UnicodeEncodeError: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
458 raise UsageError( |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
459 'argument %r is not a valid ascii keyword' % key |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
460 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
461 if value: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
462 try: |
| 5602 | 463 prop = hyperdb.rawToHyperdb(self.db, cl, itemid, key, value) |
| 464 except hyperdb.HyperdbValueError as msg: | |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
465 raise UsageError(msg) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
466 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
467 return prop |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
468 |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
469 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
|
470 """Return an error object""" |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
471 self.client.response_code = status |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
472 result = { |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
473 'error': { |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
474 'status': status, |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
475 'msg': msg |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
476 } |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
477 } |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
478 if source is not None: |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
479 result['error']['source'] = source |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
480 |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
481 return result |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
482 |
|
5595
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
483 def patch_data(self, op, old_val, new_val): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
484 """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
|
485 |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
486 Args: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
487 op (string): PATCH operation: add, replace, remove |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
488 old_val: old value of the property |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
489 new_val: new value of the property |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
490 |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
491 Returns: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
492 result (string): value after performed the operation |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
493 """ |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
494 # 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
|
495 # Otherwise, concat those 2 value |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
496 if op == 'add': |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
497 if old_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
498 result = new_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
499 elif new_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
500 result = old_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
501 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
502 result = old_val + new_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
503 # Replace operation: new value is returned |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
504 elif op == 'replace': |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
505 result = new_val |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
506 # Remove operation: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
507 # 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
|
508 # 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
|
509 # change it to none |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
510 # 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
|
511 # 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
|
512 elif op == 'remove': |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
513 if isinstance(old_val, list): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
514 if new_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
515 result = [] |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
516 elif isinstance(new_val, list): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
517 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
|
518 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
519 if new_val in old_val: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
520 old_val.remove(new_val) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
521 elif isinstance(old_val, dict): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
522 if new_val is None: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
523 result = {} |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
524 elif isinstance(new_val, dict): |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
525 for x in new_val: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
526 old_val.pop(x, None) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
527 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
528 old_val.pop(new_val, None) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
529 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
530 result = None |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
531 else: |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
532 raise UsageError('PATCH Operation %s is not allowed' % op) |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
533 |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
534 return result |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
535 |
|
5729
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
536 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
|
537 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
|
538 if not check_etag(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
|
539 self.db.config.WEB_SECRET_KEY, |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
540 obtain_etags(self.client.request.headers, input), |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
541 class_name, |
|
5729
9ea2ce9d10cf
A few internet references report that etags for the same underlying
John Rouillard <rouilj@ieee.org>
parents:
5727
diff
changeset
|
542 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
|
543 raise PreconditionFailed( |
|
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
544 "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
|
545 " 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
|
546 |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
547 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
|
548 ''' 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
|
549 props. |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
550 ''' |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
551 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
|
552 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
|
553 if self.api_version == None: |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
554 version = self.__default_api_version |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
555 else: |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
556 version = self.api_version |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
557 |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
558 # 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
|
559 # 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
|
560 # placeholder for later use. |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
561 result = {} |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
562 try: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
563 # pn = propname |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
564 for pn in sorted(props): |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
565 prop = props[pn] |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
566 if not self.db.security.hasPermission( |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
567 'View', uid, class_name, pn, item_id |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
568 ): |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
569 continue |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
570 v = getattr(node, pn) |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
571 if isinstance (prop, (hyperdb.Link, hyperdb.Multilink)): |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
572 linkcls = self.db.getclass (prop.classname) |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
573 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
|
574 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
|
575 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
|
576 r = [] |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
577 for id in v: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
578 d = dict(id = id, link = cp + id) |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
579 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
|
580 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
|
581 d [label] = linkcls.get(id, label) |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
582 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
|
583 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
|
584 else: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
585 result[pn] = dict(id = v, link = cp + v) |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
586 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
|
587 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
|
588 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
|
589 else: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
590 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
|
591 elif isinstance (prop, hyperdb.String) and pn == 'content': |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
592 # 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
|
593 # 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
|
594 # 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
|
595 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
|
596 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
|
597 p = u + '%s%s/' % (class_name, node.id) |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
598 result[pn] = dict(link = p) |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
599 else: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
600 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
|
601 elif isinstance(prop, hyperdb.Password): |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
602 if v != None: # locked users like anonymous have None |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
603 result[pn] = "[password hidden scheme %s]"%v.scheme |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
604 else: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
605 # 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
|
606 # 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
|
607 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
|
608 else: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
609 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
|
610 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
|
611 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
|
612 |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
613 return result |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
614 |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
615 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
616 @Routing.route("/data/<:class_name>", 'GET') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
617 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
618 def get_collection(self, class_name, input): |
| 5582 | 619 """GET resource from class URI. |
| 620 | |
| 621 This function returns only items have View permission | |
| 622 class_name should be valid already | |
| 623 | |
| 624 Args: | |
| 625 class_name (string): class name of the resource (Ex: issue, msg) | |
| 626 input (list): the submitted form of the user | |
| 627 | |
| 628 Returns: | |
| 629 int: http status code 200 (OK) | |
| 630 list: list of reference item in the class | |
| 631 id: id of the object | |
| 632 link: path to the object | |
| 633 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
634 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
635 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
|
636 |
|
1fa59181ce58
Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents:
5674
diff
changeset
|
637 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
|
638 |
|
5864
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
639 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
|
640 raise Unauthorised('Permission to view %s denied' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
641 |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
642 class_obj = self.db.getclass(class_name) |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
643 class_path = '%s/%s/' % (self.data_path, class_name) |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
644 |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
645 # Handle filtering and pagination |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
646 filter_props = {} |
|
5874
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
647 exact_props = {} |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
648 page = { |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
649 'size': None, |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
650 'index': 1 # setting just size starts at page 1 |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
651 } |
|
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
|
652 verbose = 1 |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
653 display_props = {} |
|
5865
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
654 sort = [] |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
655 for form_field in input.value: |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
656 key = form_field.name |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
657 value = form_field.value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
658 if key.startswith("@page_"): # serve the paging purpose |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
659 key = key[6:] |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
660 value = int(value) |
|
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
661 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
|
662 elif key == "@verbose": |
|
1fa59181ce58
Add support for @verbose=2 to a GET on a collection object. Using this
John Rouillard <rouilj@ieee.org>
parents:
5674
diff
changeset
|
663 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
|
664 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
|
665 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
|
666 if len(f) == 1: |
|
5682
e8ac82b8d074
Fix parse of @fields/@attrs with : as separator. Add tests @verbose and @fields.
John Rouillard <rouilj@ieee.org>
parents:
5681
diff
changeset
|
667 f=value.split(":") |
|
5824
352e78c3b4ab
Allow @fields to include protected properties, document @protected
John Rouillard <rouilj@ieee.org>
parents:
5823
diff
changeset
|
668 allprops=class_obj.getprops(protected=True) |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
669 for i in f: |
|
5681
6457fd696a43
Handle bad property name in @fields/@attrs. Raise exception and
John Rouillard <rouilj@ieee.org>
parents:
5680
diff
changeset
|
670 try: |
|
5824
352e78c3b4ab
Allow @fields to include protected properties, document @protected
John Rouillard <rouilj@ieee.org>
parents:
5823
diff
changeset
|
671 display_props[i] = allprops[i] |
|
5681
6457fd696a43
Handle bad property name in @fields/@attrs. Raise exception and
John Rouillard <rouilj@ieee.org>
parents:
5680
diff
changeset
|
672 except KeyError as err: |
|
6457fd696a43
Handle bad property name in @fields/@attrs. Raise exception and
John Rouillard <rouilj@ieee.org>
parents:
5680
diff
changeset
|
673 raise UsageError("Failed to find property '%s' " |
|
6457fd696a43
Handle bad property name in @fields/@attrs. Raise exception and
John Rouillard <rouilj@ieee.org>
parents:
5680
diff
changeset
|
674 "for class %s."%(i, class_name)) |
|
5865
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
675 elif key == "@sort": |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
676 f = value.split(",") |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
677 allprops=class_obj.getprops(protected=True) |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
678 for p in f : |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
679 if not p: |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
680 raise UsageError("Empty property " |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
681 "for class %s."%(class_name)) |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
682 if p[0] in ('-', '+'): |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
683 pn = p[1:] |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
684 ss = p[0] |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
685 else: |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
686 ss = '+' |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
687 pn = p |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
688 # 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
|
689 # Note that hasSearchPermission already returns 0 for |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
690 # non-existing properties. |
|
5865
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
691 if self.db.security.hasSearchPermission( |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
692 uid, class_name, pn |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
693 ): |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
694 sort.append((ss, pn)) |
|
5691
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
695 elif key.startswith("@"): |
|
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
696 # 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
|
697 # like @apiver |
|
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
698 pass |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
699 else: # serve the filter purpose |
|
5874
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
700 exact = False |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
701 if key.endswith (':') : |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
702 exact = True |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
703 key = key [:-1] |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
704 elif key.endswith ('~') : |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
705 key = key [:-1] |
|
5872
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
706 p = key.split('.', 1)[0] |
|
5691
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
707 try: |
|
5872
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
708 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
|
709 except KeyError: |
|
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
710 raise UsageError("Field %s is not valid for %s class."%( |
|
5872
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
711 p, class_name)) |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
712 # We drop properties without search permission silently |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
713 # This reflects the current behavior of other roundup |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
714 # interfaces |
|
5872
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
715 # Note that hasSearchPermission already returns 0 for |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
716 # non-existing properties. |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
717 if not self.db.security.hasSearchPermission( |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
718 uid, class_name, key |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
719 ): |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
720 continue |
|
5872
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
721 |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
722 linkcls = class_obj |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
723 for p in key.split('.'): |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
724 prop = linkcls.getprops(protected = True)[p] |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
725 linkcls = getattr (prop, 'classname', None) |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
726 if linkcls: |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
727 linkcls = self.db.getclass(linkcls) |
|
1b91e3df3fd0
Implement transitive props for sort and filter
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5870
diff
changeset
|
728 |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
729 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
|
730 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
|
731 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
|
732 else: |
|
9c6617857032
Support use of duplicate rest filters keys. So URL's like:
John Rouillard <rouilj@ieee.org>
parents:
5824
diff
changeset
|
733 vals = [] |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
734 for p in value.split(","): |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
735 if prop.try_id_parsing and p.isdigit(): |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
736 vals.append(p) |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
737 else: |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
738 vals.append(linkcls.lookup(p)) |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
739 filter_props[key] = vals |
|
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
740 else: |
|
5874
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
741 if not isinstance (prop, hyperdb.String): |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
742 exact = False |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
743 props = filter_props |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
744 if exact: |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
745 props = exact_props |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
746 if key in props: |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
747 if isinstance(props[key], list): |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
748 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
|
749 else: |
|
5874
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
750 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
|
751 else: |
|
5874
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
752 props[key] = value |
|
5865
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
753 l = [filter_props] |
|
5870
5ae426616576
Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5865
diff
changeset
|
754 kw = {} |
|
5865
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
755 if sort: |
|
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
756 l.append(sort) |
|
5874
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
757 if exact_props: |
|
6630baff5f68
Implement exact string search in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5873
diff
changeset
|
758 kw ['exact_match_spec'] = exact_props |
|
5870
5ae426616576
Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5865
diff
changeset
|
759 if page ['size'] is not None and page ['size'] > 0: |
|
5ae426616576
Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5865
diff
changeset
|
760 kw ['limit'] = page ['size'] |
|
5ae426616576
Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5865
diff
changeset
|
761 if page ['index'] is not None and page ['index'] > 1: |
|
5ae426616576
Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5865
diff
changeset
|
762 kw ['offset'] = (page ['index'] - 1) * page ['size'] |
|
5ae426616576
Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5865
diff
changeset
|
763 obj_list = class_obj.filter(None, *l, **kw) |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
764 |
|
5865
04deafac71ab
Implement sorting of collections in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5864
diff
changeset
|
765 # 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
|
766 # 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
|
767 |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
768 # 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
|
769 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
|
770 lp = class_obj.labelprop() |
|
5873
14f5c3179711
Fix lookup of labelprop in REST
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5872
diff
changeset
|
771 # Label prop may be a protected property like activity |
|
14f5c3179711
Fix lookup of labelprop in REST
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5872
diff
changeset
|
772 display_props[lp] = class_obj.getprops (protected = True)[lp] |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
773 |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
774 # extract result from data |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
775 result={} |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
776 result['collection']=[] |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
777 for item_id in obj_list: |
|
5864
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
778 r = {} |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
779 if self.db.security.hasPermission( |
|
5864
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
780 'View', uid, class_name, itemid=item_id, property='id' |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
781 ): |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
782 r = {'id': item_id, 'link': class_path + item_id} |
|
5864
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
783 if display_props : |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
784 for p in display_props: |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
785 if self.db.security.hasPermission( |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
786 'View', uid, class_name, itemid=item_id, property=p |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
787 ): |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
788 r.update(self.format_item(class_obj.getnode(item_id), |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
789 item_id, props=display_props, verbose=verbose)) |
|
5e8e160fe2a0
Fix security checks for individual properties
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5851
diff
changeset
|
790 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
|
791 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
|
792 |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
793 result_len = len(result['collection']) |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
794 |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
795 # 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
|
796 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
|
797 result['@links'] = {} |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
798 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
|
799 if rel == 'next': |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
800 # if current index includes all data, continue |
|
5870
5ae426616576
Implement pagination in REST API via limit/offset
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5865
diff
changeset
|
801 if page['size'] > result_len: continue |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
802 index=page['index']+1 |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
803 if rel == 'prev': |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
804 if page['index'] <= 1: continue |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
805 index=page['index']-1 |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
806 if rel == 'self': index=page['index'] |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
807 |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
808 result['@links'][rel] = [] |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
809 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
|
810 'rel': rel, |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
811 'uri': "%s/%s?@page_index=%s&"%(self.data_path, |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
812 class_name,index) \ |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
813 + '&'.join([ "%s=%s"%(field.name,field.value) \ |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
814 for field in input.value \ |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
815 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
|
816 |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
817 result['@total_size'] = result_len |
|
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
818 self.client.setHeader("X-Count-Total", str(result_len)) |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
819 return 200, result |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
820 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
821 @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
|
822 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
823 def get_element(self, class_name, item_id, input): |
| 5582 | 824 """GET resource from object URI. |
| 825 | |
| 826 This function returns only properties have View permission | |
| 827 class_name and item_id should be valid already | |
| 828 | |
| 829 Args: | |
| 830 class_name (string): class name of the resource (Ex: issue, msg) | |
| 831 item_id (string): id of the resource (Ex: 12, 15) | |
| 5678 | 832 or (if the class has a key property) this can also be |
| 833 the key name, e.g. class_name = status, item_id = 'open' | |
| 5582 | 834 input (list): the submitted form of the user |
| 835 | |
| 836 Returns: | |
| 837 int: http status code 200 (OK) | |
| 838 dict: a dictionary represents the object | |
| 839 id: id of the object | |
| 840 type: class name of the object | |
| 841 link: link to the object | |
| 842 attributes: a dictionary represent the attributes of the object | |
| 843 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
844 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
845 raise NotFound('Class %s not found' % class_name) |
| 5678 | 846 class_obj = self.db.getclass(class_name) |
| 847 uid = self.db.getuid() | |
| 848 # If it's not numeric it is a key | |
| 849 if item_id.isdigit(): | |
| 5679 | 850 itemid = item_id |
| 5678 | 851 else: |
| 852 keyprop = class_obj.getkey() | |
| 853 try: | |
| 854 k, v = item_id.split('=', 1) | |
| 855 if k != keyprop: | |
|
5691
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
856 raise UsageError ("Field %s is not key property"%k) |
| 5678 | 857 except ValueError: |
| 858 v = item_id | |
| 859 if not self.db.security.hasPermission( | |
| 860 'View', uid, class_name, itemid=item_id, property=keyprop | |
| 861 ): | |
| 862 raise Unauthorised( | |
| 863 'Permission to view %s%s.%s denied' | |
| 864 % (class_name, item_id, keyprop) | |
| 865 ) | |
| 5679 | 866 itemid = class_obj.lookup(v) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
867 if not self.db.security.hasPermission( |
| 5679 | 868 'View', uid, class_name, itemid=itemid |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
869 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
870 raise Unauthorised( |
| 5679 | 871 'Permission to view %s%s denied' % (class_name, itemid) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
872 ) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
873 |
| 5679 | 874 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
|
875 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
|
876 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
|
877 props = None |
|
5638
7e3cceec3f4f
Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents:
5636
diff
changeset
|
878 protected=False |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
879 verbose=1 |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
880 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
|
881 key = form_field.name |
|
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
882 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
|
883 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
|
884 if props is None: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
885 props = {} |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
886 # support , or : separated elements |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
887 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
|
888 if len(f) == 1: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
889 f=value.split(":") |
|
5824
352e78c3b4ab
Allow @fields to include protected properties, document @protected
John Rouillard <rouilj@ieee.org>
parents:
5823
diff
changeset
|
890 allprops=class_obj.getprops(protected=True) |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
891 for i in f: |
|
5681
6457fd696a43
Handle bad property name in @fields/@attrs. Raise exception and
John Rouillard <rouilj@ieee.org>
parents:
5680
diff
changeset
|
892 try: |
|
5824
352e78c3b4ab
Allow @fields to include protected properties, document @protected
John Rouillard <rouilj@ieee.org>
parents:
5823
diff
changeset
|
893 props[i] = allprops[i] |
|
5681
6457fd696a43
Handle bad property name in @fields/@attrs. Raise exception and
John Rouillard <rouilj@ieee.org>
parents:
5680
diff
changeset
|
894 except KeyError as err: |
|
6457fd696a43
Handle bad property name in @fields/@attrs. Raise exception and
John Rouillard <rouilj@ieee.org>
parents:
5680
diff
changeset
|
895 raise UsageError("Failed to find property '%s' for class %s."%(i, class_name)) |
|
5680
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
896 elif key == "@protected": |
|
5638
7e3cceec3f4f
Allow client to access read only/protected properties like creator,
John Rouillard <rouilj@ieee.org>
parents:
5636
diff
changeset
|
897 # 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
|
898 # 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
|
899 # 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
|
900 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
|
901 elif key == "@verbose": |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
902 verbose = int (value) |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
903 |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
904 result = {} |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
905 if props is None: |
|
5661
b08a308c273b
Better display for Link/Multilink and content
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5660
diff
changeset
|
906 props = 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
|
907 else: |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
908 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
|
909 lp = class_obj.labelprop() |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
910 props[lp] = class_obj.properties[lp] |
|
5598
be81e8cca38c
Added the ability to limit returned fields by GET
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5597
diff
changeset
|
911 |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
912 result = { |
| 5679 | 913 'id': itemid, |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
914 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
915 '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
|
916 'attributes': self.format_item(node, itemid, props=props, |
|
f77209ddd579
Refactored REST code that formats an item for display. A GET on
John Rouillard <rouilj@ieee.org>
parents:
5679
diff
changeset
|
917 verbose=verbose), |
|
5630
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
918 '@etag': etag |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
919 } |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
920 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
921 self.client.setHeader("ETag", etag) |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
922 return 200, result |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
923 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
924 @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
|
925 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
926 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
|
927 """GET resource from attribute URI. |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
928 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
929 This function returns only attribute has View permission |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
930 class_name should be valid already |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
931 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
932 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
933 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
|
934 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
935 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
936 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
937 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
938 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
939 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
940 list: a dictionary represents the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
941 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
942 type: class name of the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
943 link: link to the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
944 data: data of the requested attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
945 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
946 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
947 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
948 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
949 'View', self.db.getuid(), class_name, attr_name, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
950 ): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
951 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
952 'Permission to view %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
953 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
954 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
955 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
956 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
|
957 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
|
958 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
|
959 class_name, item_id, 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
|
960 data = node.__getattr__(attr_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
961 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
962 '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
|
963 'type': str(type(data)), |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
964 'link': "%s/%s/%s/%s" % |
|
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
965 (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
|
966 'data': data, |
|
07abc8d36940
Add etag support to rest interface to prevent multiple users from
John Rouillard <rouilj@ieee.org>
parents:
5622
diff
changeset
|
967 '@etag': etag |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
968 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
969 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
970 self.client.setHeader("ETag", etag) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
971 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
972 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
973 @Routing.route("/data/<:class_name>", 'POST') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
974 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
975 def post_collection(self, class_name, input): |
| 5582 | 976 """POST a new object to a class |
| 977 | |
| 978 If the item is successfully created, the "Location" header will also | |
| 979 contain the link to the created object | |
| 980 | |
| 981 Args: | |
| 982 class_name (string): class name of the resource (Ex: issue, msg) | |
| 983 input (list): the submitted form of the user | |
| 984 | |
| 985 Returns: | |
| 986 int: http status code 201 (Created) | |
| 987 dict: a reference item to the created object | |
| 988 id: id of the object | |
| 989 link: path to the object | |
| 990 """ | |
|
5710
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
991 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
|
992 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
993 @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
|
994 @_data_decorator |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
995 def post_once_exactly_collection(self, 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
|
996 otks=self.db.Otk |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
997 poe_key = ''.join([random_.choice(chars) for x in range(40)]) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
998 while otks.exists(u2s(poe_key)): |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
999 poe_key = ''.join([random_.choice(chars) for x in range(40)]) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1000 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1001 try: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1002 lifetime=int(input['lifetime'].value) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1003 except KeyError as e: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1004 lifetime=30 * 60 # 30 minutes |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1005 except ValueError as e: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1006 raise UsageError("Value 'lifetime' must be an integer specify lifetime in seconds. Got %s."%input['lifetime'].value) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1007 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1008 if lifetime > 3600 or lifetime < 1: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1009 raise UsageError("Value 'lifetime' must be between 1 second and 1 hour (3600 seconds). Got %s."%input['lifetime'].value) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1010 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1011 try: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1012 # if generic tag exists, we don't care about the value |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1013 is_generic=input['generic'] |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1014 # we generate a generic POE token |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1015 is_generic=True |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1016 except KeyError as e: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1017 is_generic=False |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1018 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1019 # 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
|
1020 # 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
|
1021 # 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
|
1022 # lifetime. |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1023 ts = time.time() - (60 * 60 * 24 * 7) + lifetime |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1024 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
|
1025 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
|
1026 __timestamp=ts ) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1027 else: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1028 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
|
1029 class_name=class_name, |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1030 __timestamp=ts ) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1031 otks.commit() |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1032 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1033 return 200, { 'link': '%s/%s/@poe/%s'%(self.data_path, class_name, poe_key), |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1034 'expires' : ts + (60 * 60 * 24 * 7) } |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1035 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1036 @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
|
1037 @_data_decorator |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1038 def post_once_exactly_collection(self, class_name, post_token, input): |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1039 otks=self.db.Otk |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1040 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1041 # 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
|
1042 otks.clean() |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1043 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1044 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
|
1045 # 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
|
1046 # logs. |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1047 raise UsageError("POE token '%s' not valid."%post_token) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1048 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1049 # 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
|
1050 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
|
1051 # 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
|
1052 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
|
1053 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1054 # 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
|
1055 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
|
1056 otks.commit() |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1057 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1058 # 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
|
1059 # 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
|
1060 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
|
1061 # 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
|
1062 # as the key got compromised. |
|
5799
7ba0ee980fc7
logger.warn is deprecated. Replace with logger.warning.
John Rouillard <rouilj@ieee.org>
parents:
5745
diff
changeset
|
1063 logger.warning( |
|
5710
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1064 'Post Once key owned by user%s was denied. Used by user%s',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
|
1065 ) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1066 # 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
|
1067 # 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
|
1068 # 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
|
1069 # the key has been stolen and we don't want to tip our hand. |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1070 raise UsageError("POE token '%s' not valid."%post_token) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1071 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1072 if cn != class_name and cn != None: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1073 raise UsageError("POE token '%s' not valid for %s, was generated for class %s"%(post_token, class_name, cn)) |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1074 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1075 # 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
|
1076 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
|
1077 |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
1078 def post_collection_inner(self, class_name, input): |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1079 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1080 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1081 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1082 'Create', self.db.getuid(), class_name |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1083 ): |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1084 raise Unauthorised('Permission to create %s denied' % class_name) |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1085 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1086 class_obj = self.db.getclass(class_name) |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1087 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1088 # convert types |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1089 props = self.props_from_args(class_obj, input.value) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1090 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1091 # check for the key property |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1092 key = class_obj.getkey() |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1093 if key and key not in props: |
| 5576 | 1094 raise UsageError("Must provide the '%s' property." % key) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1095 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1096 for key in props: |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1097 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1098 'Create', self.db.getuid(), class_name, property=key |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1099 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1100 raise Unauthorised( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1101 'Permission to create %s.%s denied' % (class_name, key) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1102 ) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1103 |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1104 # do the actual create |
|
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1105 try: |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
1106 item_id = class_obj.create(**props) |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1107 self.db.commit() |
| 5602 | 1108 except (TypeError, IndexError, ValueError) as message: |
| 5576 | 1109 raise ValueError(message) |
| 5602 | 1110 except KeyError as msg: |
| 5576 | 1111 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
|
1112 |
|
5573
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
1113 # set the header Location |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1114 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
|
1115 self.client.setHeader("Location", link) |
|
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
1116 |
|
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
1117 # set the response body |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1118 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1119 'id': item_id, |
|
5573
89ae4ef34efe
Handle response header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5572
diff
changeset
|
1120 'link': link |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1121 } |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
1122 return 201, result |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1123 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1124 @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
|
1125 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
1126 def put_element(self, class_name, item_id, input): |
| 5582 | 1127 """PUT a new content to an object |
| 1128 | |
| 1129 Replace the content of the existing object | |
| 1130 | |
| 1131 Args: | |
| 1132 class_name (string): class name of the resource (Ex: issue, msg) | |
| 1133 item_id (string): id of the resource (Ex: 12, 15) | |
| 1134 input (list): the submitted form of the user | |
| 1135 | |
| 1136 Returns: | |
| 1137 int: http status code 200 (OK) | |
| 1138 dict: a dictionary represents the modified object | |
| 1139 id: id of the object | |
| 1140 type: class name of the object | |
| 1141 link: link to the object | |
| 1142 attributes: a dictionary represent only changed attributes of | |
| 1143 the object | |
| 1144 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1145 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1146 raise NotFound('Class %s not found' % class_name) |
| 5564 | 1147 class_obj = self.db.getclass(class_name) |
| 1148 | |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1149 props = self.props_from_args(class_obj, input.value, item_id) |
| 5602 | 1150 for p in props: |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1151 if not self.db.security.hasPermission( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1152 'Edit', self.db.getuid(), class_name, p, item_id |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1153 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1154 raise Unauthorised( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1155 'Permission to edit %s of %s%s denied' % |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1156 (p, class_name, item_id) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1157 ) |
| 5564 | 1158 try: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1159 self.raise_if_no_etag(class_name, item_id, input) |
| 5564 | 1160 result = class_obj.set(item_id, **props) |
| 1161 self.db.commit() | |
| 5602 | 1162 except (TypeError, IndexError, ValueError) as message: |
| 5576 | 1163 raise ValueError(message) |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1164 except KeyError as message: |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1165 # 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
|
1166 # and changing invalid keys |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1167 raise UsageError(message) |
| 5564 | 1168 |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1169 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1170 'id': item_id, |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1171 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1172 '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
|
1173 'attribute': result |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1174 } |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
1175 return 200, result |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
1176 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1177 @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
|
1178 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1179 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
|
1180 """PUT an attribute to an object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1181 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1182 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1183 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
|
1184 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1185 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1186 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1187 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1188 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1189 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1190 dict:a dictionary represents the modified object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1191 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1192 type: class name of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1193 link: link to the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1194 attributes: a dictionary represent only changed attributes of |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1195 the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1196 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1197 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1198 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1199 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1200 'Edit', self.db.getuid(), class_name, attr_name, item_id |
|
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 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1203 'Permission to edit %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1204 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1205 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1206 class_obj = self.db.getclass(class_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1207 props = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1208 attr_name: self.prop_from_arg( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1209 class_obj, attr_name, input['data'].value, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1210 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1211 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1212 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1213 try: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1214 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
|
1215 result = class_obj.set(item_id, **props) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1216 self.db.commit() |
| 5602 | 1217 except (TypeError, IndexError, ValueError) as message: |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1218 raise ValueError(message) |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1219 except KeyError as message: |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1220 # 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
|
1221 # 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
|
1222 raise AttributeError(message) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1223 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1224 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1225 'id': item_id, |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1226 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1227 '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
|
1228 'attribute': result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1229 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1230 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1231 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1232 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1233 @Routing.route("/data/<:class_name>", 'DELETE') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
1234 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
1235 def delete_collection(self, class_name, input): |
| 5604 | 1236 """DELETE (retire) all objects in a class |
| 1237 There is currently no use-case, so this is disabled and | |
| 1238 always returns Unauthorised. | |
| 5582 | 1239 |
| 1240 Args: | |
| 1241 class_name (string): class name of the resource (Ex: issue, msg) | |
| 1242 input (list): the submitted form of the user | |
| 1243 | |
| 1244 Returns: | |
| 1245 int: http status code 200 (OK) | |
| 1246 dict: | |
| 1247 status (string): 'ok' | |
| 1248 count (int): number of deleted objects | |
| 1249 """ | |
| 5604 | 1250 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
|
1251 ''' 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
|
1252 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
|
1253 FIXME: Delete in December 2020 if not used. |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1254 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1255 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1256 if not self.db.security.hasPermission( |
| 5604 | 1257 'Retire', self.db.getuid(), class_name |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1258 ): |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1259 raise Unauthorised('Permission to delete %s denied' % class_name) |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1260 |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1261 class_obj = self.db.getclass(class_name) |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1262 for item_id in class_obj.list(): |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1263 if not self.db.security.hasPermission( |
| 5604 | 1264 'Retire', self.db.getuid(), class_name, itemid=item_id |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1265 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1266 raise Unauthorised( |
| 5604 | 1267 'Permission to retire %s %s denied' % (class_name, item_id) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1268 ) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1269 |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1270 count = len(class_obj.list()) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1271 for item_id in class_obj.list(): |
| 5604 | 1272 class_obj.retire (item_id) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1273 |
|
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1274 self.db.commit() |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1275 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1276 'status': 'ok', |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1277 'count': count |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1278 } |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1279 |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
1280 return 200, result |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
1281 ''' |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
1282 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1283 @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
|
1284 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
1285 def delete_element(self, class_name, item_id, input): |
| 5604 | 1286 """DELETE (retire) an object in a class |
| 5582 | 1287 |
| 1288 Args: | |
| 1289 class_name (string): class name of the resource (Ex: issue, msg) | |
| 1290 item_id (string): id of the resource (Ex: 12, 15) | |
| 1291 input (list): the submitted form of the user | |
| 1292 | |
| 1293 Returns: | |
| 1294 int: http status code 200 (OK) | |
| 1295 dict: | |
| 1296 status (string): 'ok' | |
| 1297 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1298 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1299 raise NotFound('Class %s not found' % class_name) |
| 5604 | 1300 class_obj = self.db.classes [class_name] |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1301 if not self.db.security.hasPermission( |
| 5604 | 1302 'Retire', self.db.getuid(), class_name, itemid=item_id |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1303 ): |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1304 raise Unauthorised( |
| 5604 | 1305 'Permission to retire %s %s denied' % (class_name, item_id) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1306 ) |
|
5563
9a1614ff752d
Implement delete collection
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5562
diff
changeset
|
1307 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1308 self.raise_if_no_etag(class_name, item_id, input) |
| 5604 | 1309 class_obj.retire (item_id) |
|
5562
70df783c4c0b
Cleanup, fixed a bug with delete action
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5561
diff
changeset
|
1310 self.db.commit() |
|
5570
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1311 result = { |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1312 'status': 'ok' |
|
8431a872b008
Response is now following the design format
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5569
diff
changeset
|
1313 } |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1314 |
|
5572
c4c88466da69
Added successful response status code
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5571
diff
changeset
|
1315 return 200, result |
|
5559
3d80e7752783
Added POST and DELETE
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5558
diff
changeset
|
1316 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1317 @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
|
1318 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1319 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
|
1320 """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
|
1321 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1322 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1323 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
|
1324 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1325 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1326 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1327 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1328 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1329 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1330 dict: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1331 status (string): 'ok' |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1332 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1333 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1334 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1335 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1336 'Edit', self.db.getuid(), class_name, attr_name, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1337 ): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1338 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1339 'Permission to delete %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1340 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1341 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1342 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1343 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
|
1344 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
|
1345 if attr_name in class_obj.getprops(protected=True): |
|
5707
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1346 raise AttributeError("Attribute '%s' can not be deleted " \ |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1347 "for class %s."%(attr_name, class_name)) |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1348 else: |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1349 raise UsageError("Attribute '%s' not valid for class %s."%( |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1350 attr_name, class_name)) |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1351 if attr_name in class_obj.get_required_props(): |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
1352 raise UsageError("Attribute '%s' is required by class %s and can not be deleted."%( |
|
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
1353 attr_name, class_name)) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1354 props = {} |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1355 prop_obj = class_obj.get(item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1356 if isinstance(prop_obj, list): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1357 props[attr_name] = [] |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1358 else: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1359 props[attr_name] = None |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1360 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1361 try: |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1362 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
|
1363 class_obj.set(item_id, **props) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1364 self.db.commit() |
| 5602 | 1365 except (TypeError, IndexError, ValueError) as message: |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1366 raise ValueError(message) |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1367 except KeyError as message: |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1368 # 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
|
1369 # and changing invalid keys |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1370 raise UsageError(message) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1371 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1372 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1373 'status': 'ok' |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1374 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1375 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1376 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1377 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1378 @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
|
1379 @_data_decorator |
|
5561
7aa7f779198b
Split all rest action into 2 type
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5560
diff
changeset
|
1380 def patch_element(self, class_name, item_id, input): |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1381 """PATCH an object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1382 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1383 Patch an element using 3 operators |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1384 ADD : Append new value to the object's attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1385 REPLACE: Replace object's attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1386 REMOVE: Clear object's attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1387 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1388 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1389 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
|
1390 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1391 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1392 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1393 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1394 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1395 dict: a dictionary represents the modified object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1396 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1397 type: class name of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1398 link: link to the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1399 attributes: a dictionary represent only changed attributes of |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1400 the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1401 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1402 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1403 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
|
1404 try: |
|
5660
d8d2b7724292
First attempt at REST-API documentation
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5659
diff
changeset
|
1405 op = input['@op'].value.lower() |
|
5580
d5a54b1851aa
Add default op action for Patch
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5579
diff
changeset
|
1406 except KeyError: |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
1407 op = self.__default_patch_op |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1408 class_obj = self.db.getclass(class_name) |
|
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1409 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1410 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
|
1411 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1412 # if patch operation is action, call the action handler |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1413 action_args = [class_name + item_id] |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1414 if op == 'action': |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1415 # extract action_name and action_args from form fields |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1416 for form_field in input.value: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1417 key = form_field.name |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1418 value = form_field.value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
1419 if key == "@action_name": |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1420 name = value |
|
5659
1e51a709431c
Make Searching work in REST API
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5658
diff
changeset
|
1421 elif key.startswith('@action_args'): |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1422 action_args.append(value) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1423 |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1424 if name in self.actions: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1425 action_type = self.actions[name] |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1426 else: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1427 raise UsageError( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1428 'action "%s" is not supported %s' % |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1429 (name, ','.join(self.actions.keys())) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1430 ) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1431 action = action_type(self.db, self.translator) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1432 result = action.execute(*action_args) |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1433 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1434 result = { |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1435 'id': item_id, |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1436 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1437 '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
|
1438 'result': result |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1439 } |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1440 else: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1441 # 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
|
1442 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
|
1443 skip_protected=False) |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1444 |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1445 required_props = class_obj.get_required_props() |
| 5602 | 1446 for prop in props: |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1447 if not self.db.security.hasPermission( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1448 'Edit', self.db.getuid(), class_name, prop, item_id |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1449 ): |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1450 raise Unauthorised( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1451 'Permission to edit %s of %s%s denied' % |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1452 (prop, class_name, item_id) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1453 ) |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1454 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
|
1455 raise UsageError( |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1456 "Attribute '%s' is required by class %s " |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1457 "and can not be removed."%(prop, class_name) |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1458 ) |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1459 |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1460 props[prop] = self.patch_data( |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1461 op, class_obj.get(item_id, prop), props[prop] |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1462 ) |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1463 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1464 try: |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1465 result = class_obj.set(item_id, **props) |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1466 self.db.commit() |
| 5602 | 1467 except (TypeError, IndexError, ValueError) as message: |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1468 raise ValueError(message) |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1469 |
|
5599
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1470 result = { |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1471 'id': item_id, |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1472 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1473 '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
|
1474 'attribute': result |
|
a76d88673375
Added Patch operator 'action'
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5598
diff
changeset
|
1475 } |
|
5578
c2214d0c9df8
Added PATCH an element
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5577
diff
changeset
|
1476 return 200, result |
|
5557
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
1477 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1478 @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
|
1479 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1480 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
|
1481 """PATCH an attribute of an object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1482 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1483 Patch an element using 3 operators |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1484 ADD : Append new value to the attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1485 REPLACE: Replace attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1486 REMOVE: Clear attribute |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1487 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1488 Args: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1489 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
|
1490 item_id (string): id of the resource (Ex: 12, 15) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1491 attr_name (string): attribute of the resource (Ex: title, nosy) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1492 input (list): the submitted form of the user |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1493 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1494 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1495 int: http status code 200 (OK) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1496 dict: a dictionary represents the modified object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1497 id: id of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1498 type: class name of the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1499 link: link to the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1500 attributes: a dictionary represent only changed attributes of |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1501 the object |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1502 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1503 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1504 raise NotFound('Class %s not found' % class_name) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1505 try: |
|
5660
d8d2b7724292
First attempt at REST-API documentation
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5659
diff
changeset
|
1506 op = input['@op'].value.lower() |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1507 except KeyError: |
|
5593
344b6a87dac6
Added support to print error
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5591
diff
changeset
|
1508 op = self.__default_patch_op |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1509 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1510 if not self.db.security.hasPermission( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1511 'Edit', self.db.getuid(), class_name, attr_name, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1512 ): |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1513 raise Unauthorised( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1514 'Permission to edit %s%s %s denied' % |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1515 (class_name, item_id, attr_name) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1516 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1517 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1518 prop = attr_name |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1519 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
|
1520 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
|
1521 if attr_name in class_obj.getprops(protected=True): |
|
5707
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1522 raise AttributeError("Attribute '%s' can not be updated " \ |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1523 "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
|
1524 |
|
5674
6dc4dba1c225
REST: Use If-Match header for incoming requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5669
diff
changeset
|
1525 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
|
1526 |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1527 props = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1528 prop: self.prop_from_arg( |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1529 class_obj, prop, input['data'].value, item_id |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1530 ) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1531 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1532 |
|
5595
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
1533 props[prop] = self.patch_data( |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
1534 op, class_obj.get(item_id, prop), props[prop] |
|
65caddd54da2
Handle operation for patch separately
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5594
diff
changeset
|
1535 ) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1536 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1537 try: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1538 result = class_obj.set(item_id, **props) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1539 self.db.commit() |
| 5602 | 1540 except (TypeError, IndexError, ValueError) as message: |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1541 raise ValueError(message) |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1542 except KeyError as message: |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1543 # 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
|
1544 # and changing invalid keys |
|
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1545 raise UsageError(message) |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1546 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1547 result = { |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1548 'id': item_id, |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1549 'type': class_name, |
|
5600
e2c74d8121f3
Update resource links
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5599
diff
changeset
|
1550 '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
|
1551 'attribute': result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1552 } |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1553 return 200, result |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1554 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1555 @Routing.route("/data/<:class_name>", 'OPTIONS') |
|
5587
cb2b320fde16
Added decorator to handle formatting output data
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5584
diff
changeset
|
1556 @_data_decorator |
| 5575 | 1557 def options_collection(self, class_name, input): |
| 5582 | 1558 """OPTION return the HTTP Header for the class uri |
| 1559 | |
| 1560 Returns: | |
| 1561 int: http status code 204 (No content) | |
| 1562 body (string): an empty string | |
| 1563 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1564 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1565 raise NotFound('Class %s not found' % class_name) |
| 5702 | 1566 self.client.setHeader( |
| 1567 "Allow", | |
| 1568 "OPTIONS, GET, POST" | |
| 1569 ) | |
| 5575 | 1570 return 204, "" |
| 1571 | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1572 @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
|
1573 @_data_decorator |
| 5575 | 1574 def options_element(self, class_name, item_id, input): |
| 5582 | 1575 """OPTION return the HTTP Header for the object uri |
| 1576 | |
| 1577 Returns: | |
| 1578 int: http status code 204 (No content) | |
| 1579 body (string): an empty string | |
| 1580 """ | |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1581 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1582 raise NotFound('Class %s not found' % class_name) |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1583 self.client.setHeader( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1584 "Accept-Patch", |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1585 "application/x-www-form-urlencoded, multipart/form-data" |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1586 ) |
| 5702 | 1587 self.client.setHeader( |
| 1588 "Allow", | |
| 1589 "OPTIONS, GET, PUT, DELETE, PATCH" | |
| 1590 ) | |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1591 return 204, "" |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1592 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1593 @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
|
1594 @_data_decorator |
|
5584
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1595 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
|
1596 """OPTION return the HTTP Header for the attribute uri |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1597 |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1598 Returns: |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1599 int: http status code 204 (No content) |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1600 body (string): an empty string |
|
53098db851f2
Added attribute URI handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5583
diff
changeset
|
1601 """ |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1602 if class_name not in self.db.classes: |
|
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1603 raise NotFound('Class %s not found' % class_name) |
| 5702 | 1604 class_obj = self.db.getclass(class_name) |
| 1605 if attr_name in class_obj.getprops(protected=False): | |
| 1606 self.client.setHeader( | |
| 1607 "Accept-Patch", | |
| 1608 "application/x-www-form-urlencoded, multipart/form-data" | |
| 1609 ) | |
| 1610 self.client.setHeader( | |
| 1611 "Allow", | |
| 1612 "OPTIONS, GET, PUT, DELETE, PATCH" | |
| 1613 ) | |
| 1614 elif attr_name in class_obj.getprops(protected=True): | |
| 1615 # It must match a protected prop. These can't be written. | |
| 1616 self.client.setHeader( | |
| 1617 "Allow", | |
| 1618 "OPTIONS, GET" | |
| 1619 ) | |
| 1620 else: | |
| 1621 raise NotFound('Attribute %s not valid for Class %s' %( | |
| 1622 attr_name,class_name)) | |
| 5575 | 1623 return 204, "" |
| 1624 | |
|
5632
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1625 @Routing.route("/") |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1626 @_data_decorator |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1627 def describe(self, input): |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1628 """Describe the rest endpoint""" |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1629 result = { |
|
5685
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1630 "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
|
1631 "supported_versions": self.__supported_api_versions, |
|
5632
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1632 "links": [ { "uri": self.base_path +"/summary", |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1633 "rel": "summary"}, |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1634 { "uri": self.base_path, |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1635 "rel": "self"}, |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1636 { "uri": self.base_path + "/data", |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1637 "rel": "data"} |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1638 ] |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1639 } |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1640 |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1641 return 200, result |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1642 |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1643 @Routing.route("/data") |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1644 @_data_decorator |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1645 def data(self, input): |
| 5658 | 1646 """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
|
1647 |
| 5658 | 1648 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
|
1649 """ |
| 5658 | 1650 result = {} |
| 1651 uid = self.db.getuid () | |
| 1652 for cls in sorted (self.db.classes) : | |
| 1653 if self.db.security.hasPermission('View', uid, cls) : | |
| 1654 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
|
1655 return 200, result |
|
a29a8dae2095
Initial implementation of function to return data for / and /data
John Rouillard <rouilj@ieee.org>
parents:
5631
diff
changeset
|
1656 |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1657 @Routing.route("/summary") |
| 5596 | 1658 @_data_decorator |
| 1659 def summary(self, input): | |
| 1660 """Get a summary of resource from class URI. | |
| 1661 | |
| 1662 This function returns only items have View permission | |
| 1663 class_name should be valid already | |
| 1664 | |
| 1665 Args: | |
| 1666 class_name (string): class name of the resource (Ex: issue, msg) | |
| 1667 input (list): the submitted form of the user | |
| 1668 | |
| 1669 Returns: | |
| 1670 int: http status code 200 (OK) | |
| 1671 list: | |
| 1672 """ | |
| 1673 if not self.db.security.hasPermission( | |
| 1674 'View', self.db.getuid(), 'issue' | |
| 1675 ) and not self.db.security.hasPermission( | |
| 1676 'View', self.db.getuid(), 'status' | |
| 1677 ) and not self.db.security.hasPermission( | |
| 1678 'View', self.db.getuid(), 'issue' | |
| 1679 ): | |
| 1680 raise Unauthorised('Permission to view summary denied') | |
| 1681 | |
| 1682 old = date.Date('-1w') | |
| 1683 | |
| 1684 created = [] | |
| 1685 summary = {} | |
| 1686 messages = [] | |
| 1687 | |
| 1688 # loop through all the recently-active issues | |
| 1689 for issue_id in self.db.issue.filter(None, {'activity': '-1w;'}): | |
| 1690 num = 0 | |
| 1691 status_name = self.db.status.get( | |
| 1692 self.db.issue.get(issue_id, 'status'), | |
| 1693 'name' | |
| 1694 ) | |
| 1695 issue_object = { | |
| 1696 'id': issue_id, | |
|
5621
39dbe83643c0
Fix path of links in /rest/summary.
John Rouillard <rouilj@ieee.org>
parents:
5620
diff
changeset
|
1697 'link': self.base_path + '/data/issue/' + issue_id, |
| 5596 | 1698 'title': self.db.issue.get(issue_id, 'title') |
| 1699 } | |
| 1700 for x, ts, uid, action, data in self.db.issue.history(issue_id): | |
| 1701 if ts < old: | |
| 1702 continue | |
| 1703 if action == 'create': | |
| 1704 created.append(issue_object) | |
| 1705 elif action == 'set' and 'messages' in data: | |
| 1706 num += 1 | |
| 1707 summary.setdefault(status_name, []).append(issue_object) | |
| 1708 messages.append((num, issue_object)) | |
| 1709 | |
|
5668
a4bb88a1a643
A fix for https://issues.roundup-tracker.org/issue2551034
John Rouillard <rouilj@ieee.org>
parents:
5662
diff
changeset
|
1710 sorted(messages, key=lambda tup: tup[0], reverse=True) |
| 5596 | 1711 |
| 1712 result = { | |
| 1713 'created': created, | |
| 1714 'summary': summary, | |
| 1715 'most_discussed': messages[:10] | |
| 1716 } | |
| 1717 | |
| 1718 return 200, result | |
| 1719 | |
|
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
|
1720 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
|
1721 ''' 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
|
1722 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
|
1723 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
|
1724 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
|
1725 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
|
1726 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
|
1727 ''' |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1728 # 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
|
1729 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
|
1730 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
|
1731 if calls and 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
|
1732 return RateLimit(calls,timedelta(seconds=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
|
1733 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
|
1734 # 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
|
1735 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
|
1736 |
|
5556
d75aa88c2a99
Added RestInstance and calling rest from client.py
Chau Nguyen <dangchau1991@yahoo.com>
parents:
diff
changeset
|
1737 def dispatch(self, method, uri, input): |
| 5582 | 1738 """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
|
1739 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
|
1740 |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1741 # 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
|
1742 # This should (but doesn't at the moment) bypass |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1743 # all other processing to minimize load of badly |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1744 # behaving client. |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1745 |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1746 # 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
|
1747 # 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
|
1748 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
|
1749 |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1750 if apiRateLimit: # if None, disable rate limiting |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1751 gcra=Gcra() |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1752 # unique key is an "ApiLimit-" prefix and the uid) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1753 apiLimitKey = "ApiLimit-%s"%self.db.getuid() |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1754 otk=self.db.Otk |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1755 try: |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1756 val=otk.getall(apiLimitKey) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1757 gcra.set_tat_as_string(apiLimitKey, val['tat']) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1758 except KeyError: |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1759 # ignore if tat not set, it's 1970-1-1 by default. |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1760 pass |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1761 # see if rate limit exceeded and we need to reject the attempt |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1762 reject=gcra.update(apiLimitKey, apiRateLimit) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1763 |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1764 # Calculate a timestamp that will make OTK expire the |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1765 # unused entry 1 hour in the future |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1766 ts = time.time() - (60 * 60 * 24 * 7) + 3600 |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1767 otk.set(apiLimitKey, tat=gcra.get_tat_as_string(apiLimitKey), |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1768 __timestamp=ts) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1769 otk.commit() |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1770 |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1771 limitStatus=gcra.status(apiLimitKey, apiRateLimit) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1772 if reject: |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1773 for header, value in limitStatus.items(): |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1774 self.client.setHeader(header, value) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1775 # User exceeded limits: tell humans how long to wait |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1776 # Headers above will do the right thing for api |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1777 # aware clients. |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1778 msg=_("Api rate limits exceeded. Please wait: %d seconds.")%limitStatus['Retry-After'] |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1779 output = self.error_obj(429, msg, source="ApiRateLimiter") |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1780 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
|
1781 for header,value in limitStatus.items(): |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1782 # Retry-After will be 0 because |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1783 # user still has quota available. |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1784 # Don't put out the header. |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1785 if header in ( 'Retry-After', ): |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1786 continue |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1787 self.client.setHeader(header, value) |
|
0e6ed3d72f92
Rest rate limiting code first commit. It is a bit rough and turned off
John Rouillard <rouilj@ieee.org>
parents:
5731
diff
changeset
|
1788 |
| 5574 | 1789 # 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
|
1790 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
|
1791 # 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
|
1792 # 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
|
1793 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
|
1794 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
|
1795 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
|
1796 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
|
1797 '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
|
1798 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
|
1799 else: |
|
5f8e6034427c
Do not honor the X-HTTP-Method-Override if the original method used
John Rouillard <rouilj@ieee.org>
parents:
5619
diff
changeset
|
1800 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
|
1801 "X-HTTP-Method-Override: %s must be used with " |
|
4aa26a9f3b47
Tighten up use of X-HTTP-Method-Override to only work with POST.
John Rouillard <rouilj@ieee.org>
parents:
5729
diff
changeset
|
1802 "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
|
1803 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
|
1804 '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
|
1805 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
|
1806 |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1807 # parse Accept header and get the content type |
|
5744
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1808 # Acceptable types ordered with preferred one first |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1809 # in list. |
|
5650
e8ca7072c629
Fix Python 3 issues in REST code.
Joseph Myers <jsm@polyomino.org.uk>
parents:
5646
diff
changeset
|
1810 accept_header = parse_accept_header(headers.get('Accept')) |
|
5744
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1811 if not accept_header: |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1812 accept_type = self.__default_accept_type |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1813 else: |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1814 accept_type = None |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1815 for part in accept_header: |
|
5744
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1816 if accept_type: |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1817 # we accepted the best match, stop searching for |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1818 # lower quality matches. |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1819 break |
|
5594
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1820 if part[0] in self.__accepted_content_type: |
|
864cf6cb5790
Added ability to parse HTTP accept header
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5593
diff
changeset
|
1821 accept_type = self.__accepted_content_type[part[0]] |
|
5685
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1822 # Version order: |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1823 # 1) accept header version=X specifier |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1824 # application/vnd.x.y; version=1 |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1825 # 2) from type in accept-header type/subtype-vX |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1826 # application/vnd.x.y-v1 |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1827 # 3) from @apiver in query string to make browser |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1828 # use easy |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1829 # This code handles 1 and 2. Set api_version to none |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1830 # to trigger @apiver parsing below |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1831 # Places that need the api_version info should |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1832 # use default if version = None |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1833 try: |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1834 self.api_version = int(part[1]['version']) |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1835 except KeyError: |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1836 self.api_version = None |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
1837 except (ValueError, TypeError): |
|
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
1838 # TypeError if int(None) |
|
5685
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1839 msg=( "Unrecognized version: %s. " |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1840 "See /rest without specifying version " |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1841 "for supported versions."%( |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1842 part[1]['version'])) |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1843 output = self.error_obj(400, msg) |
|
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1844 |
| 5574 | 1845 # get the request format for response |
|
5685
4b4885f0c6ad
Set up basic framework for handling versioning of interface.
John Rouillard <rouilj@ieee.org>
parents:
5682
diff
changeset
|
1846 # priority : extension from uri (/rest/data/issue.json), |
| 5574 | 1847 # header (Accept: application/json, application/xml) |
| 1848 # default (application/json) | |
| 5602 | 1849 ext_type = os.path.splitext(urlparse(uri).path)[1][1:] |
|
5744
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1850 data_type = ext_type or accept_type or "invalid" |
| 5574 | 1851 |
|
5617
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1852 if ( ext_type ): |
|
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1853 # strip extension so uri make sense |
|
5619
1c9208fa9127
Make sure a commentis a comment.
John Rouillard <rouilj@ieee.org>
parents:
5618
diff
changeset
|
1854 # .../issue.json -> .../issue |
|
5617
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1855 uri = uri[:-( len(ext_type) + 1 )] |
|
38b7c4693d9a
Original code supported setting accept type to json (or other
John Rouillard <rouilj@ieee.org>
parents:
5616
diff
changeset
|
1856 |
| 5582 | 1857 # add access-control-allow-* to support CORS |
| 5574 | 1858 self.client.setHeader("Access-Control-Allow-Origin", "*") |
|
5581
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1859 self.client.setHeader( |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1860 "Access-Control-Allow-Headers", |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1861 "Content-Type, Authorization, X-HTTP-Method-Override" |
|
30793a435185
Code convention improved
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5580
diff
changeset
|
1862 ) |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1863 self.client.setHeader( |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1864 "Allow", |
| 5702 | 1865 "OPTIONS, GET, POST, PUT, DELETE, PATCH" |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1866 ) |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1867 self.client.setHeader( |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1868 "Access-Control-Allow-Methods", |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1869 "HEAD, OPTIONS, GET, PUT, DELETE, PATCH" |
|
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1870 ) |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1871 # 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
|
1872 # 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
|
1873 # 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
|
1874 content_type_header = headers.get('Content-Type', None) |
|
5655
207e0f5d551c
Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
diff
changeset
|
1875 # python2 is str type, python3 is bytes |
|
207e0f5d551c
Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
diff
changeset
|
1876 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
|
1877 parsed_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
|
1878 # 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
|
1879 # 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
|
1880 # 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
|
1881 # 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
|
1882 # 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
|
1883 # 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
|
1884 # 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
|
1885 # 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
|
1886 # 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
|
1887 # 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
|
1888 # for example. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1889 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
|
1890 try: |
|
5655
207e0f5d551c
Merge in non-conflicting changes from ba67e397f063
John Rouillard <rouilj@ieee.org>
diff
changeset
|
1891 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
|
1892 except ValueError as msg: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1893 output = self.error_obj(400, msg) |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1894 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1895 # check for pretty print |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1896 try: |
|
5701
fabb12ba9466
Change pretty url parameter to @pretty to stop collision with field name.
John Rouillard <rouilj@ieee.org>
parents:
5691
diff
changeset
|
1897 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
|
1898 # Can also return a TypeError ("not indexable") |
|
edd9e2c67785
Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5808
diff
changeset
|
1899 # 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
|
1900 except (KeyError, TypeError): |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1901 pretty_output = True |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
1902 |
|
5686
eb51c0d9c9bf
Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents:
5685
diff
changeset
|
1903 # check for @apiver in query string |
|
5711
aea2cc142c1b
Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents:
5710
diff
changeset
|
1904 msg=( "Unrecognized version: %s. " |
|
aea2cc142c1b
Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents:
5710
diff
changeset
|
1905 "See /rest without specifying version " |
|
aea2cc142c1b
Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents:
5710
diff
changeset
|
1906 "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
|
1907 try: |
|
eb51c0d9c9bf
Move @apiver version extraction code after the input is parsed for
John Rouillard <rouilj@ieee.org>
parents:
5685
diff
changeset
|
1908 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
|
1909 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
|
1910 # Can also return a TypeError ("not indexable") |
|
edd9e2c67785
Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5808
diff
changeset
|
1911 # 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
|
1912 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
|
1913 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
|
1914 except ValueError: |
|
5711
aea2cc142c1b
Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents:
5710
diff
changeset
|
1915 output = self.error_obj(400, msg%input['@apiver'].value) |
|
aea2cc142c1b
Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents:
5710
diff
changeset
|
1916 |
|
aea2cc142c1b
Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents:
5710
diff
changeset
|
1917 # 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
|
1918 # support it? |
|
aea2cc142c1b
Added some more rest testing and make sure api version is valid.
John Rouillard <rouilj@ieee.org>
parents:
5710
diff
changeset
|
1919 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
|
1920 # 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
|
1921 # 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
|
1922 # 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
|
1923 # 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
|
1924 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
|
1925 elif self.api_version not in self.__supported_api_versions: |
|
5740
abbea26a11df
Clean up pylint reports of unused modules, duplicate imports, indent
John Rouillard <rouilj@ieee.org>
parents:
5732
diff
changeset
|
1926 raise UsageError(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
|
1927 |
|
5691
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
1928 # 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
|
1929 # 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
|
1930 # places in the code. |
|
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
1931 # else: |
|
dbf422a8cff7
Add error handling. @apiver was being processed as a search
John Rouillard <rouilj@ieee.org>
parents:
5690
diff
changeset
|
1932 # 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
|
1933 |
| 5582 | 1934 # Call the appropriate method |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1935 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
|
1936 # 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
|
1937 # 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
|
1938 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
|
1939 output = Routing.execute(self, uri, method, input) |
| 5602 | 1940 except NotFound as msg: |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1941 output = self.error_obj(404, msg) |
| 5602 | 1942 except Reject as msg: |
|
5597
de9933cfcfc4
Added routing decorator
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5596
diff
changeset
|
1943 output = self.error_obj(405, msg) |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
1944 |
|
5590
4d8746c73fdb
Change the way core function is called
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5589
diff
changeset
|
1945 # Format the content type |
|
5591
a25d79e874cb
Added filtering and pagination
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5590
diff
changeset
|
1946 if data_type.lower() == "json": |
|
5589
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1947 self.client.setHeader("Content-Type", "application/json") |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1948 if pretty_output: |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1949 indent = 4 |
| 5574 | 1950 else: |
|
5589
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1951 indent = None |
|
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1952 output = RoundupJSONEncoder(indent=indent).encode(output) |
|
5631
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
1953 elif data_type.lower() == "xml" and dicttoxml: |
|
a5c890d308c3
Add simple support for xml output if the third party dict2xml.py module
John Rouillard <rouilj@ieee.org>
parents:
5630
diff
changeset
|
1954 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
|
1955 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
|
1956 # 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
|
1957 # 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
|
1958 # 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
|
1959 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
|
1960 import collections |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1961 for key,val in output['error'].items(): |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1962 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
|
1963 (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
|
1964 pass |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1965 elif hasattr(val, 'isoformat'): # datetime |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1966 pass |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1967 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
|
1968 pass |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1969 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
|
1970 pass |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1971 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
|
1972 pass |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1973 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
|
1974 pass |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1975 else: |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1976 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
|
1977 |
|
f9a762678af6
Change some 400 errors to 405 (method not allowed) errors where user is
John Rouillard <rouilj@ieee.org>
parents:
5705
diff
changeset
|
1978 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
|
1979 b2s(dicttoxml(output, root=False)) |
|
5589
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1980 else: |
|
5705
457fc482e6b1
Method PUT: ignore specification of protected properties which can not
John Rouillard <rouilj@ieee.org>
parents:
5702
diff
changeset
|
1981 # 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
|
1982 # 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
|
1983 # display acceptable output. |
|
5589
5a2de4c19109
Fix an indentation bug
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5588
diff
changeset
|
1984 self.client.response_code = 406 |
|
5744
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1985 output = ( "Requested content type is not available.\n" |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1986 "Acceptable types: %s"%( |
|
d4de45cde106
Accept header parsing fixes. Now return first acceptable match rather
John Rouillard <rouilj@ieee.org>
parents:
5740
diff
changeset
|
1987 ", ".join(self.__accepted_content_type.keys()))) |
|
5557
213a56c91471
Implement getting resource from database
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5556
diff
changeset
|
1988 |
|
5639
f576957cbb1f
Add support for prev/next/self links when returning paginated results.
John Rouillard <rouilj@ieee.org>
parents:
5638
diff
changeset
|
1989 # 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
|
1990 # 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
|
1991 return bs2b(output + "\n") |
|
5566
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1992 |
|
5567
1af57f9d5bf7
Added exception Handling
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5566
diff
changeset
|
1993 |
|
5566
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1994 class RoundupJSONEncoder(json.JSONEncoder): |
| 5582 | 1995 """RoundupJSONEncoder overrides the default JSONEncoder to handle all |
| 1996 types of the object without returning any error""" | |
|
5566
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1997 def default(self, obj): |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1998 try: |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
1999 result = json.JSONEncoder.default(self, obj) |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
2000 except TypeError: |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
2001 result = str(obj) |
|
2830793d1510
Added RoundupJSONEncoder
Chau Nguyen <dangchau1991@yahoo.com>
parents:
5565
diff
changeset
|
2002 return result |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2003 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2004 class SimulateFieldStorageFromJson(): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2005 ''' |
|
5689
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2006 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
|
2007 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
|
2008 FieldStorage and MiniFieldStorage structure. |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2009 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2010 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
|
2011 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
|
2012 or |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2013 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
|
2014 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2015 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
|
2016 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2017 object['prop'].value |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2018 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2019 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
|
2020 |
|
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
|
2021 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
|
2022 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
|
2023 string. |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2024 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2025 ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2026 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
|
2027 ''' 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
|
2028 def raise_error_on_constant(x): |
|
5644
b4d7588c74a4
Make exception raising work on python 3.
John Rouillard <rouilj@ieee.org>
parents:
5643
diff
changeset
|
2029 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
|
2030 try: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
2031 self.json_dict = json.loads(json_string, |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2032 parse_constant = raise_error_on_constant) |
|
5710
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
2033 self.value = [ self.FsValue(index, self.json_dict[index]) for index in self.json_dict.keys() ] |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
2034 except ValueError as e: |
|
0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
John Rouillard <rouilj@ieee.org>
parents:
5707
diff
changeset
|
2035 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
|
2036 self.value = None |
|
5643
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2037 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2038 class FsValue: |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2039 '''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
|
2040 def __init__(self, name, val): |
|
5689
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2041 self.name=u2s(name) |
|
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2042 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
|
2043 # handle most common type first |
|
5689
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2044 self.value=u2s(val) |
|
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2045 elif type(val) == type([]): |
|
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
|
2046 # then lists of strings |
|
5689
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2047 self.value = [ u2s(v) for v in val ] |
|
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2048 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
|
2049 # then stringify anything else (int, float) |
|
5689
2c516d113620
Fix encoding for incoming json requests
Ralf Schlatterbeck <rsc@runtux.com>
parents:
5687
diff
changeset
|
2050 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
|
2051 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2052 def __getitem__(self, index): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2053 '''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
|
2054 ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2055 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
|
2056 |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2057 def __contains__(self, index): |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2058 ''' implement: 'foo' in DICT ''' |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2059 return index in self.json_dict |
|
a60cbbcc9309
Added support for accepting application/json payload in addition to
John Rouillard <rouilj@ieee.org>
parents:
5639
diff
changeset
|
2060 |
