def root(couch, env, username): '''request handler for document URL: /[dbname]/[docid] Methods: GET, COPY, PUT, POST Authentication: GET|COPY|PUT: Row filtering (read access) POST|DELETE: Row filtering (admin access) ''' req_headers = {'Content-type': 'application/json'} path = env['PATH_INFO'].lstrip('/') params = parse_qs(env['QUERY_STRING'] or '') if env['REQUEST_METHOD'] not in ['GET','COPY','PUT','POST','DELETE']: return 501, {}, '501 Not implemented' status, headers, body = couch.get(path, headers=req_headers, **params) doc = json.loads(body) if env['REQUEST_METHOD'] == 'GET': if validate.validate_view_doc(doc, username): body = json.dumps(doc) return status, headers, body else: return 404, {}, '404 Not found' elif env['REQUEST_METHOD'] == 'COPY': if validate.validate_view_doc(doc, username): status, headers, body = couch.copy(path, headers=req_headers, **params) return status, headers, body else: return 404, {}, '404 Not found' elif env['REQUEST_METHOD'] == 'POST': if validate.validate_modify_doc(doc, username): try: req_length = int(env['CONTENT_LENGTH']) req_body = env['wsgi.input'].read(req_length) except ValueError: req_body = '' status, headers, body = couch.post(path, req_body, headers=req_headers, **params) return status, headers, body elif validate.validate_view_doc(doc, username): return 401, {}, '401 Forbidden' else: return 404, {}, '404 Not found' elif env['REQUEST_METHOD'] == 'DELETE': if validate.validate_modify_doc(doc, username): status, headers, body = couch.delete(path, headers=req_headers, **params) return status, headers, body elif validate.validate_view_doc(doc, username): return 401, {}, '401 Forbidden' else: return 404, {}, '404 Not found' elif env['REQUEST_METHOD'] == 'PUT': return 501, {}, '501 Not implemented' else: return 405, {}, ''
def view(couch, env, username): '''request handler for view URL: /[dbname]/_design/[designname]/_view/[viewname] Methods: GET Authentication: Row filtering (read access) ''' if env['REQUEST_METHOD'] == 'GET': req_headers = {'Content-type': 'application/json'} path = env['PATH_INFO'].lstrip('/') params = {'include_docs': True} params.update(parse_qs(env['QUERY_STRING'] or '')) status, headers, body = couch.get(path, headers=req_headers, **params) # select only rows allowed by access control view = json.loads(body) result = {'total_rows': 0, 'offset': view['offset'], 'rows': []} for row in view['rows']: if validate.validate_view_doc(row['doc'], username): del row['doc'] # FIXME: unless user asked for it in query result['rows'].append(row) result['total_rows'] += 1 body = json.dumps(result) # fixme leave as a list del headers['transfer-encoding'] return status, headers, body return 405, {}, ''
def design(couch, env, username): '''request handler for design document URL: /[dbname]/[docid]/_design/[designname] Methods: GET, COPY, PUT, POST Authentication: GET|COPY|PUT: Row filtering (read access) POST|DELETE: Row filtering (admin access) ''' req_headers = {'Content-type': 'application/json'} path = env['PATH_INFO'].lstrip('/') params = parse_qs(env['QUERY_STRING'] or '') status, headers, body = couch.get(path, headers=req_headers, **params) doc = json.loads(body) if env['REQUEST_METHOD'] == 'GET': if validate.validate_view_doc(doc, username): body = json.dumps(doc) return status, headers, body else: return 404, {}, '404 Not found' return 501, {}, '501 Not implemented'
def attachment(couch, env, username): '''request handler for document attachment URL: /[dbname]/[docid]/[attachment] Methods: GET, COPY, PUT, POST Authentication: GET|COPY|PUT: Row filtering (read access) POST|DELETE: Row filtering (admin access) ''' path = env['PATH_INFO'].lstrip('/') params = parse_qs(env['QUERY_STRING'] or '') match = re.match(r'^(?P<dbname>\w+)\/(?P<docid>\w+)\/(?P<attach>.+)$', path) doc_path = '/'.join([match.group('dbname'), match.group('docid')]) if env['REQUEST_METHOD'] == 'GET': status, headers, body = couch.get(doc_path, headers={'Content-type': 'application/json'}) doc = json.loads(body) if validate.validate_view_doc(doc, username): return couch.get(urllib.quote(path)) else: return 404, {}, '404 Not found' return 501, {}, '501 Not implemented'