async def post(self): args = await self.request.post() if self.csrf_token and self.csrf_token != args.get('csrf_token', ''): raise error.CsrfTokenError() roles = dict() # unmodifiable roles are not modifiable so that we are not using get_all_roles() here for role in self.domain['roles']: perms = 0 for perm in args.getall(role, []): perm = int(perm) if perm in builtin.PERMS_BY_KEY: perms |= perm roles[role] = perms await domain.set_roles(self.domain_id, roles) self.json_or_redirect(self.url)
def wrapper(self, *args, **kwargs): if self.csrf_token and self.csrf_token != kwargs.pop('csrf_token', ''): raise error.CsrfTokenError() return func(self, *args, **kwargs)
async def handle_file_upload(self, form_fields=None, raise_error=True): """Handles file upload, fills form fields and returns file_id whose metadata.link is already increased.""" reader = await self.request.multipart() try: # Check csrf token. if self.csrf_token: field = await reader.next() check_type_and_name(field, 'csrf_token') post_csrf_token = await field.read_chunk( len(self.csrf_token.encode())) if self.csrf_token.encode() != post_csrf_token: raise error.CsrfTokenError() # Read form fields. if form_fields: for k in form_fields: field = await reader.next() check_type_and_name(field, k) form_fields[k] = ( await field.read_chunk(TEXT_FIELD_MAX_LENGTH)).decode() # Read file data. field = await reader.next() check_type_and_name(field, 'file') file_type = mimetypes.guess_type(field.filename)[0] if not file_type or not any( file_type.startswith(allowed_type) for allowed_type in ALLOWED_MIMETYPE_PREFIX): raise error.FileTypeNotAllowedError('file', file_type) grid_in = None finally_delete = True try: grid_in = await fs.add(file_type) # Copy file data and check file length. size = 0 chunk_size = max(field.chunk_size, 8192) chunk = await field.read_chunk(chunk_size) while chunk: size += len(chunk) if size > FILE_MAX_LENGTH: raise error.FileTooLongError('file') _, chunk = await asyncio.gather(grid_in.write(chunk), field.read_chunk(chunk_size)) if chunk: # remaining await grid_in.write(chunk) if not size: # empty file raise error.ValidationError('file') await grid_in.close() # Deduplicate. file_id = await fs.link_by_md5(grid_in.md5, except_id=grid_in._id) if file_id: return file_id finally_delete = False return grid_in._id except: raise finally: if grid_in: await grid_in.close() if finally_delete: await fs.unlink(grid_in._id) except Exception: if raise_error: raise else: return None