~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/webapp/base/rest.py

Replaced Python config files (conf.py) with new config files system, using
    configobj (INI-file style config files).

setup.py config now produces ./etc/ivle.conf, a new-style config file.
ivle/conf/conf.py is now part of the IVLE source code. It reads the new config
file and provides the same legacy interface, so all of IVLE still functions,
including setup.py config.

Added /etc to the source tree (config files will be stored here).
Added configobj as a dependency in doc/setup/install_proc.txt.

setup.py install copies ./etc/ivle.conf into /etc/ivle/ivle.conf.

Removed boilerplate code generation from setup/configure.py (that code is now
part of ivle/conf/conf.py which is now in the source tree).

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
# Author: Matt Giuca, Will Grant
19
19
 
20
20
import cgi
21
 
import urlparse
22
21
import inspect
23
22
 
24
23
import cjson
25
24
 
26
25
from ivle.webapp.base.views import BaseView
27
 
from ivle.webapp.errors import BadRequest, MethodNotAllowed, Unauthorized
 
26
from ivle.webapp.errors import BadRequest, MethodNotAllowed
28
27
 
29
28
class RESTView(BaseView):
30
29
    """
50
49
        lambda self: [m for m in ('GET', 'PUT', 'PATCH')
51
50
                      if hasattr(self, m)] + ['POST'])
52
51
 
53
 
    def authorize(self, req):
54
 
        return True # Real authz performed in render().
55
 
 
56
 
    def authorize_method(self, req, op):
57
 
        if not hasattr(op, '_rest_api_permission'):
58
 
            raise Unauthorized()
59
 
 
60
 
        if op._rest_api_permission not in self.get_permissions(req.user):
61
 
            raise Unauthorized()
62
 
    
63
 
    def convert_bool(self, value):
64
 
        if value in ('True', 'true', True):
65
 
            return True
66
 
        elif value in ('False', 'false', False):
67
 
            return False
68
 
        else:
69
 
            raise BadRequest()
70
 
 
71
52
    def render(self, req):
72
53
        if req.method not in self._allowed_methods:
73
54
            raise MethodNotAllowed(allowed=self._allowed_methods)
74
55
 
75
56
        if req.method == 'GET':
76
 
            self.authorize_method(req, self.GET)
77
57
            outjson = self.GET(req)
78
58
        # Since PATCH isn't yet an official HTTP method, we allow users to
79
59
        # turn a PUT into a PATCH by supplying a special header.
80
60
        elif req.method == 'PATCH' or (req.method == 'PUT' and
81
61
              'X-IVLE-Patch-Semantics' in req.headers_in and
82
62
              req.headers_in['X-IVLE-Patch-Semantics'].lower() == 'yes'):
83
 
            self.authorize_method(req, self.PATCH)
84
63
            try:
85
64
                input = cjson.decode(req.read())
86
65
            except cjson.DecodeError:
87
66
                raise BadRequest('Invalid JSON data')
88
67
            outjson = self.PATCH(req, input)
89
68
        elif req.method == 'PUT':
90
 
            self.authorize_method(req, self.PUT)
91
69
            try:
92
70
                input = cjson.decode(req.read())
93
71
            except cjson.DecodeError:
96
74
        # POST implies named operation.
97
75
        elif req.method == 'POST':
98
76
            # TODO: Check Content-Type and implement multipart/form-data.
99
 
            data = req.read()
100
 
            opargs = dict(cgi.parse_qsl(data, keep_blank_values=1))
 
77
            opargs = dict(cgi.parse_qsl(req.read()))
101
78
            try:
102
79
                opname = opargs['ivle.op']
103
80
                del opargs['ivle.op']
113
90
               not op._rest_api_callable:
114
91
                raise BadRequest('Invalid named operation.')
115
92
 
116
 
            self.authorize_method(req, op)
117
 
 
118
93
            # Find any missing arguments, except for the first two (self, req)
119
94
            (args, vaargs, varkw, defaults) = inspect.getargspec(op)
120
95
            args = args[2:]
145
120
            req.write(cjson.encode(outjson))
146
121
            req.write("\n")
147
122
 
148
 
class named_operation(object):
 
123
def named_operation(meth):
149
124
    '''Declare a function to be accessible to HTTP users via the REST API.
150
125
    '''
151
 
    def __init__(self, permission):
152
 
        self.permission = permission
153
 
 
154
 
    def __call__(self, func):
155
 
        func._rest_api_callable = True
156
 
        func._rest_api_permission = self.permission
157
 
        return func
158
 
 
159
 
class require_permission(object):
160
 
    '''Declare the permission required for use of a method via the REST API.
161
 
    '''
162
 
    def __init__(self, permission):
163
 
        self.permission = permission
164
 
 
165
 
    def __call__(self, func):
166
 
        func._rest_api_permission = self.permission
167
 
        return func
 
126
    meth._rest_api_callable = True
 
127
    return meth
168
128