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

« back to all changes in this revision

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

Added config validation spec: ivle/config/ivle-spec.conf.
ivle.conf.conf: No longer needs to do the cast-to-int hack.
ivle.config: Runs against the validator (with a XXX problem).
setup.util: ivle-spec.conf is installed with a new whitelist.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
import cjson
24
24
 
25
25
from ivle.webapp.base.views import BaseView
26
 
from ivle.webapp.errors import BadRequest, MethodNotAllowed, Unauthorized
 
26
from ivle.webapp.errors import BadRequest, MethodNotAllowed
27
27
 
28
28
class RESTView(BaseView):
29
29
    """
49
49
        lambda self: [m for m in ('GET', 'PUT', 'PATCH')
50
50
                      if hasattr(self, m)] + ['POST'])
51
51
 
52
 
    def authorize(self, req):
53
 
        return True # Real authz performed in render().
54
 
 
55
 
    def authorize_method(self, req, op):
56
 
        if not hasattr(op, '_rest_api_permission'):
57
 
            raise Unauthorized()
58
 
 
59
 
        if op._rest_api_permission not in self.get_permissions(req.user):
60
 
            raise Unauthorized()
61
 
 
62
52
    def render(self, req):
63
53
        if req.method not in self._allowed_methods:
64
54
            raise MethodNotAllowed(allowed=self._allowed_methods)
65
55
 
66
56
        if req.method == 'GET':
67
 
            self.authorize_method(req, self.GET)
68
57
            outjson = self.GET(req)
69
58
        # Since PATCH isn't yet an official HTTP method, we allow users to
70
59
        # turn a PUT into a PATCH by supplying a special header.
71
60
        elif req.method == 'PATCH' or (req.method == 'PUT' and
72
61
              'X-IVLE-Patch-Semantics' in req.headers_in and
73
62
              req.headers_in['X-IVLE-Patch-Semantics'].lower() == 'yes'):
74
 
            self.authorize_method(req, self.PATCH)
75
63
            try:
76
64
                input = cjson.decode(req.read())
77
65
            except cjson.DecodeError:
78
66
                raise BadRequest('Invalid JSON data')
79
67
            outjson = self.PATCH(req, input)
80
68
        elif req.method == 'PUT':
81
 
            self.authorize_method(req, self.PUT)
82
69
            try:
83
70
                input = cjson.decode(req.read())
84
71
            except cjson.DecodeError:
103
90
               not op._rest_api_callable:
104
91
                raise BadRequest('Invalid named operation.')
105
92
 
106
 
            self.authorize_method(req, op)
107
 
 
108
93
            # Find any missing arguments, except for the first two (self, req)
109
94
            (args, vaargs, varkw, defaults) = inspect.getargspec(op)
110
95
            args = args[2:]
135
120
            req.write(cjson.encode(outjson))
136
121
            req.write("\n")
137
122
 
138
 
class named_operation(object):
 
123
def named_operation(meth):
139
124
    '''Declare a function to be accessible to HTTP users via the REST API.
140
125
    '''
141
 
    def __init__(self, permission):
142
 
        self.permission = permission
143
 
 
144
 
    def __call__(self, func):
145
 
        func._rest_api_callable = True
146
 
        func._rest_api_permission = self.permission
147
 
        return func
148
 
 
149
 
class require_permission(object):
150
 
    '''Declare the permission required for use of a method via the REST API.
151
 
    '''
152
 
    def __init__(self, permission):
153
 
        self.permission = permission
154
 
 
155
 
    def __call__(self, func):
156
 
        func._rest_api_permission = self.permission
157
 
        return func
 
126
    meth._rest_api_callable = True
 
127
    return meth
158
128