def parseQuery(context, request): """parse query""" reg = getUtility(IRegistry) conditions = [] form = request.form or {} body_form = json_body(request).get("form") or {} data_query = json_body(request).get("data_query") or [] # Update form with body form form.update(body_form) # Compute data_query from form form_data_query = getDataQuery(form) # Merge queries _data_query = mergeLists(data_query, form_data_query) # Parse sql query db_version = form.get("db_version") or "latest" sql_parsed = getParsedSQLQuery(context, db_version) # Get context properties parameters = getParameters(context.parameters) required_parameters = context.required_parameters collate = context.collate # Get indexes __data_query = [] __indexes = [] for row in _data_query: _index = row.get("i") if not parameters: break if _index not in parameters: continue __data_query.append(row) __indexes.append(_index) # Check if required parameters exists in data_query if not hasRequiredParameters(required_parameters, __indexes): return None for row in __data_query: operator = row.get("o", None) index = row.get("i", None) value = row.get("v", None) table = parameters.get(index) if parameters else None function_path = operator if "eea.api.dataconnector.queryparser" not in operator: function_path = reg["%s.operation" % operator].replace( "plone.app.querystring", "eea.api.dataconnector") row = Row(index=index, values=value, table=table, collate=collate) parser = resolve(function_path) condition = parser(row) if condition: if isinstance(condition, list): condition = {"and": condition} conditions.append(condition) return { "query": sql_parsed, "conditions": conditions, "form": form, "data_query": _data_query, }
def __init__(self, request, results): self.request = request self.b_start = int(json_body(self.request).get( "b_start", False)) or int(self.request.form.get("b_start", 0)) self.b_size = int(json_body(self.request).get("b_size", False)) or int( self.request.form.get("b_size", DEFAULT_BATCH_SIZE)) self.batch = Batch(results, self.b_size, self.b_start)
def __init__(self, request, results): self.request = request self.b_start = int( json_body(self.request).get("b_start", False) ) or int(self.request.form.get("b_start", 0)) self.b_size = int(json_body(self.request).get("b_size", False)) or int( self.request.form.get("b_size", DEFAULT_BATCH_SIZE) ) self.hits = getattr(results, "hits", 0)
def computeDataQuery(request): """compute data_query""" form = request.form or {} body_form = json_body(request).get("form") or {} data_query = json_body(request).get("data_query") or [] # Update form with body form form.update(body_form) # Compute data_query from form form_data_query = getDataQuery(form) # Merge queries _data_query = mergeLists(data_query, form_data_query) return _data_query
def reply(self): if self.transition is None: self.request.response.setStatus(400) return dict(error=dict( type='BadRequest', message='Missing transition')) data = json_body(self.request) if data.keys() not in [[], ['comment']]: self.request.response.setStatus(400) return dict(error=dict( type='BadRequest', message='Invalid body')) wftool = getToolByName(self.context, 'portal_workflow') # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) try: wftool.doActionFor(self.context, self.transition, **data) except WorkflowException as e: self.request.response.setStatus(400) return dict(error=dict( type='WorkflowException', message=translate(e.message, context=self.request))) history = wftool.getInfoFor(self.context, "review_history") return json_compatible(history[-1])
def reply(self): data = json_body(self.request) category = data.get('category', DEFAULT_COMMENT_CATEGORY) comment = data.get('comment') if not comment: raise BadRequest("The request body requires the 'comment' attribute") if not self._validate_category(category): raise BadRequest("The provided 'category' does not exists.") documents, invalid_urls = self._lookup_documents( data.get('related_documents', [])) if invalid_urls: raise BadRequest( "Could not lookup the following documents: {}".format( ', '.join(invalid_urls))) contacts = [] users = [] entry = ManualJournalEntry(self.context, category, comment, contacts, users, documents) entry.save() self.request.response.setStatus(204) return super(JournalPost, self).reply()
def reply(self): data = json_body(self.request) result = [] for element in data["data"]: self.request.set("BODY", json.dumps(element)) result.extend(super(ImportPost, self).reply()) return {"data": result}
def reply(self): data = json_body(self.request) option_type = data.get('option_type') if not option_type: raise BadRequest(error_msgs.get('missing_option_type')) reminder_option = TASK_REMINDER_OPTIONS.get(option_type) if not reminder_option: raise BadRequest(error_msgs.get('non_existing_option_type')) # Disable CSRF protection alsoProvides(self.request, IDisableCSRFProtection) task_reminder = TaskReminder() if task_reminder.get_reminder(self.context): self.request.response.setStatus(409) return super(TaskReminderPost, self).reply() task_reminder.set_reminder(self.context, reminder_option) self.context.sync() self.request.response.setStatus(204) return super(TaskReminderPost, self).reply()
def __call__(self): data = json_body(self.request) sharing_view = getMultiAdapter((self.context, self.request), name="sharing") # inherit roles inherit_reindex = False # block can be None, so we might get False or None, so we test # for a marker. inherit = data.get("inherit", marker) if inherit is not marker: inherit_reindex = sharing_view.update_inherit(status=inherit, reindex=False) # roles roles_reindex = False new_roles = data.get("entries", None) if new_roles is not None: # the roles are converted into a FrozenSet so we have to filter # the data structure we get. for user in new_roles: roles_list = [ key for key in user["roles"] if user["roles"][key] ] user["roles"] = roles_list roles_reindex = sharing_view.update_role_settings(new_roles, reindex=False) # reindex object security can_reindex = ICatalogAware( self.context, None) or IPloneSiteRoot.providedBy(self.context) if can_reindex and (inherit_reindex or roles_reindex): self.context.reindexObjectSecurity() if LOCALROLES_MODIFIED_EVENT_AVAILABLE: notify(LocalrolesModifiedEvent(self.context, self.request))
def reply(self): data = json_body(self.request) sender_from_address = data.get('from', None) message = data.get('message', None) sender_fullname = data.get('name', '') subject = data.get('subject', '') if not sender_from_address or not message: raise BadRequest('Missing from or message parameters') overview_controlpanel = getMultiAdapter((self.context, self.request), name='overview-controlpanel') if overview_controlpanel.mailhost_warning(): raise BadRequest('MailHost is not configured.') # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) contact_info_view = getMultiAdapter((self.context, self.request), name='contact-info') contact_info_view.send_message( dict(message=message, subject=subject, sender_from_address=sender_from_address, sender_fullname=sender_fullname)) self.request.response.setStatus(204) return
def reply(self): # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) data = json_body(self.request) id_ = data.get("id", None) if id_ is None: self.request.response.setStatus(400) return dict(error=dict(type="BadRequest", message="Missing content id to link to")) target = self.get_object(id_) if target is None: self.request.response.setStatus(400) return dict(error=dict(type="BadRequest", message="Content does not exist")) target_language = ILanguage(target).get_language() manager = ITranslationManager(self.context) current_translation = manager.get_translation(target_language) if current_translation is not None: self.request.response.setStatus(400) return dict(error=dict( type="BadRequest", message="Already translated into language {}".format( target_language), )) manager.register_translation(target_language, target) self.request.response.setStatus(201) self.request.response.setHeader("Location", self.context.absolute_url()) return {}
def reply(self): alsoProvides(self.request, IDisableCSRFProtection) form_data = json_body(self.request) self.validate_form(form_data=form_data) tool = getUtility(self.store) try: res = tool.add(form_data) except ValueError as e: self.request.response.setStatus(500) return dict( error=dict( type="InternalServerError", message=getattr(e, "message", e.__str__()), ) ) if res: return self.reply_no_content() self.request.response.setStatus(500) return dict( error=dict( type="InternalServerError", message="Unable to add. Contact site manager.", ) )
def reply(self): data = json_body(self.request) group = self._get_group(self._get_group_id) if not group: raise BadRequest('Trying to update a non-existing group.') title = data.get('title', None) description = data.get('description', None) roles = data.get('roles', None) groups = data.get('groups', None) # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) portal_groups = getToolByName(self.context, 'portal_groups') portal_groups.editGroup(self._get_group_id, roles=roles, groups=groups, title=title, description=description) properties = {} for id, property in group.propertyItems(): if data.get(id, False): properties[id] = data[id] group.setGroupProperties(properties) self.request.response.setStatus(204) return None
def reply(self): if self.transition is None: self.request.response.setStatus(400) return dict( error=dict(type='BadRequest', message='Missing transition')) data = json_body(self.request) if data.keys() not in [[], ['comment']]: self.request.response.setStatus(400) return dict(error=dict(type='BadRequest', message='Invalid body')) wftool = getToolByName(self.context, 'portal_workflow') # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) try: wftool.doActionFor(self.context, self.transition, **data) except WorkflowException as e: self.request.response.setStatus(400) return dict( error=dict(type='WorkflowException', message=translate(e.message, context=self.request))) history = wftool.getInfoFor(self.context, "review_history") action = history[-1] action['title'] = self.context.translate( wftool.getTitleForStateOnType(action['review_state'], self.context.portal_type)) return json_compatible(action)
def parse_query(self): data = json_body(self.request) if "file" not in data: raise BadRequest( _("missing_file", default=u"You need to pass a file at least.")) return data
def reply(self): data = json_body(self.request) option_type = data.get('option_type') params = data.get('params') if not option_type: raise BadRequest(error_msgs.get('missing_option_type')) if option_type not in REMINDER_TYPE_REGISTRY: raise BadRequest(error_msgs.get('non_existing_option_type')) reminder_data = {'option_type': option_type, 'params': params} try: reminder = Reminder.deserialize(reminder_data) except (ValidationError, ValueError) as exc: raise BadRequest(repr(exc)) # Disable CSRF protection alsoProvides(self.request, IDisableCSRFProtection) if self.context.get_reminder(): self.request.response.setStatus(409) return _no_content_marker self.context.set_reminder(reminder) self.context.sync() self.request.response.setStatus(204) return _no_content_marker
def reply(self): data = json_body(self.request) option_type = data.get('option_type') params = data.get('params') if option_type and option_type not in REMINDER_TYPE_REGISTRY: raise BadRequest(error_msgs.get('non_existing_option_type')) # Disable CSRF protection alsoProvides(self.request, IDisableCSRFProtection) if option_type or params: existing_reminder = self.context.get_reminder() if not existing_reminder: raise NotFound # Pick existing settings if not given (PATCH semantics) option_type = option_type or existing_reminder.option_type params = params if 'params' in data else existing_reminder.params reminder_data = {'option_type': option_type, 'params': params} try: reminder = Reminder.deserialize(reminder_data) except (ValidationError, ValueError) as exc: raise BadRequest(repr(exc)) self.context.set_reminder(reminder) self.context.sync() self.request.response.setStatus(204) return _no_content_marker
def update(self, action): action_delta = json_body(self.request) # Reject any fields that aren't user-controlled or unknown errors = get_unknown_fields(action_delta, IWebActionSchema) if errors: raise BadRequest(errors) scrub_json_payload(action_delta) # Validate on a copy action_copy = action.copy() action_copy.update(action_delta) errors = get_validation_errors(action_copy, IPersistedWebActionSchema) if errors: raise BadRequest(errors) # If validation succeeded, update actual action storage = get_storage() try: storage.update(action['action_id'], action_delta) except ActionAlreadyExists as exc: raise BadRequest([('unique_name', exc)]) self.request.response.setStatus(204) return _no_content_marker
def reply(self): data = json_body(self.request) sender_from_address = data.get("from", None) message = data.get("message", None) sender_fullname = data.get("name", "") subject = data.get("subject", "") if not sender_from_address or not message: raise BadRequest("Missing from or message parameters") overview_controlpanel = getMultiAdapter((self.context, self.request), name="overview-controlpanel") if overview_controlpanel.mailhost_warning(): raise BadRequest("MailHost is not configured.") # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) contact_info_view = getMultiAdapter((self.context, self.request), name="contact-info") contact_info_view.send_message( dict( message=message, subject=subject, sender_from_address=sender_from_address, sender_fullname=sender_fullname, )) return self.reply_no_content()
def show_all_metadata_fields(self): query = self.request.form if not query: # maybe its a POST request query = json_body(self.request) metadata_fields = query.get("metadata_fields", []) return "_all" in metadata_fields or self.force_all_metadata
def reply(self): data = json_body(self.request) category = data.get('category', DEFAULT_COMMENT_CATEGORY) comment = data.get('comment') if not comment: raise BadRequest( "The request body requires the 'comment' attribute") if not self._validate_category(category): raise BadRequest("The provided 'category' does not exists.") documents, invalid_urls = self._lookup_documents( data.get('related_documents', [])) if invalid_urls: raise BadRequest( "Could not lookup the following documents: {}".format( ', '.join(invalid_urls))) contacts = [] users = [] entry = ManualJournalEntry(self.context, category, comment, contacts, users, documents) entry.save() self.request.response.setStatus(204) return super(JournalPost, self).reply()
def reply(self): # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) data = json_body(self.request) manager = ITranslationManager(self.context) language = data.get('language', None) if language is None: self.request.response.setStatus(400) return dict(error=dict( type='BadRequest', message='You need to provide the language to unlink')) if language not in manager.get_translations().keys(): self.request.response.setStatus(400) return dict( error=dict(type='BadRequest', message='This objects is not translated into {}'. format(language))) manager.remove_translation(language) self.request.response.setStatus(204) return {}
def reply(self): data = json_body(self.request) result = [] for element in data["data"]: self.request.set("BODY", json.dumps(element)) result.extend(super(BulkFolderPost, self).create_content()) return {"data": result}
def __call__(self, validate_all=False, data=None, create=False): if data is None: data = json_body(self.request) context = super(DeserializeMailFromJson, self).__call__(validate_all=validate_all, data=data, create=create) if context.message and context.message.filename.lower().endswith( '.msg'): self.context.original_message = context.message transform = Msg2MimeTransform() eml = transform.transform(context.message.data) file_ = NamedBlobFile(data=eml, filename=context.message.filename[:-3] + 'eml', contentType='message/rfc822') context.message = file_ if create and 'message' in data: if not data.get('title'): context._update_title_from_message_subject() initalize_title(context, None) initialize_metadata(context, None) return context
def reply(self): # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) data = json_body(self.request) manager = ITranslationManager(self.context) language = data.get("language", None) if language is None: self.request.response.setStatus(400) return dict(error=dict( type="BadRequest", message="You need to provide the language to unlink", )) if language not in list(manager.get_translations()): self.request.response.setStatus(400) return dict(error=dict( type="BadRequest", message="This objects is not translated into {}".format( language), )) manager.remove_translation(language) return self.reply_no_content()
def generate_query_for_events(self): data = json_body(self.request) parsed_query = queryparser.parseFormquery(context=self.context, formquery=data["query"]) fullobjects = data.get("fullobjects", False) b_size = data.get("b_size", None) b_start = data.get("b_start", 0) query = { k: v for k, v in parsed_query.items() if k not in ["start", "end"] } limit = int(data.get("limit", 1000)) sort = "start" sort_reverse = False start, end = self.parse_event_dates(parsed_query) if data.get("sort_on", ""): sort = data["sort_on"] if data.get("sort_order", ""): sort_reverse = data["sort_order"] == "descending" and True or False return ( start, end, fullobjects, b_size, b_start, query, sort_reverse, sort, limit, )
def reply(self): if not self.comment_id: raise BadRequest("Comment id is a required part of the url") conversation = IConversation(self.context) if self.comment_id not in list(conversation): self.request.response.setStatus(404) return comment = conversation[self.comment_id] # Permission checks if not (edit_comment_allowed() and can_edit(comment)): raise Unauthorized() # Fake request data body = json_body(self.request) for key, value in body.items(): self.request.form["form.widgets." + key] = value form = EditCommentForm(comment, self.request) form.__parent__ = form.context.__parent__.__parent__ form.update() action = form.actions["comment"] data, errors = form.extractData() if errors: raise BadRequest({"errors": [err.error for err in errors]}) comment.modification_date = datetime.utcnow() form.handleComment(form=form, action=action) fix_location_header(self.context, self.request) return self.reply_no_content()
def reply(self): # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) conversation = IConversation(self.context) if self.comment_id and self.comment_id not in list(conversation): self.request.response.setStatus(404) return # Fake request data body = json_body(self.request) for key, value in body.items(): self.request.form["form.widgets." + key] = value form = CommentForm(self.context, self.request) form.update() action = form.actions["comment"] data, errors = form.extractData() if errors: raise BadRequest({"errors": [err.error for err in errors]}) form.handleComment(form=form, action=action) fix_location_header(self.context, self.request) return self.reply_no_content()
def reply(self): portal = getSite() data = json_body(self.request) groupname = data.get("groupname", None) if not groupname: raise BadRequest("Property 'groupname' is required") email = data.get("email", None) title = data.get("title", None) description = data.get("description", None) roles = data.get("roles", None) groups = data.get("groups", None) users = data.get("users", []) properties = { "title": title, "description": description, "email": email } gtool = getToolByName(self.context, "portal_groups") regtool = getToolByName(self.context, "portal_registration") if not regtool.isMemberIdAllowed(groupname): raise BadRequest("The group name you entered is not valid.") already_exists = gtool.getGroupById(groupname) if already_exists: raise BadRequest("The group name you entered already exists.") # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) success = gtool.addGroup( groupname, roles, groups, properties=properties, title=title, description=description, ) if not success: raise BadRequest( f"Error occurred, could not add group {groupname}.") # Add members group = gtool.getGroupById(groupname) for userid in users: group.addMember(userid) self.request.response.setStatus(201) self.request.response.setHeader( "Location", portal.absolute_url() + "/@groups/" + groupname) serializer = queryMultiAdapter((group, self.request), ISerializeToJson) return serializer()
def render(self): data = json_body(self.request) type_ = data.get('@type', None) id_ = data.get('id', None) title = data.get('title', None) if not type_: raise BadRequest("Property '@type' is required") # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) # Generate a temporary id if the id is not given if not id_: now = DateTime() new_id = '{}.{}.{}{:04d}'.format(type_.lower().replace(' ', '_'), now.strftime('%Y-%m-%d'), str(now.millis())[7:], randint(0, 9999)) else: new_id = id_ # Create object try: new_id = self.context.invokeFactory(type_, new_id, title=title) except BadRequest as e: self.request.response.setStatus(400) return dict(error=dict(type='DeserializationError', message=str(e.message))) except ValueError as e: self.request.response.setStatus(400) return dict(error=dict(type='DeserializationError', message=str(e.message))) # Update fields obj = self.context[new_id] deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: self.request.response.setStatus(501) return dict(error=dict( message='Cannot deserialize type {}'.format(obj.portal_type))) try: deserializer(validate_all=True) except DeserializationError as e: self.request.response.setStatus(400) return dict( error=dict(type='DeserializationError', message=str(e))) # Rename if generated id if not id_: self.rename_object(obj) self.request.response.setStatus(201) self.request.response.setHeader('Location', obj.absolute_url()) return None
def reply(self): if not self.params: raise BadRequest("Missing parameter typename") data = json_body(self.request) # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) # Make sure we get the right dexterity-types adapter if IPloneRestapiLayer.providedBy(self.request): noLongerProvides(self.request, IPloneRestapiLayer) name = self.params.pop() context = queryMultiAdapter((self.context, self.request), name="dexterity-types") context = context.publishTraverse(self.request, name) factory = data.get("factory", None) if not factory: raise BadRequest("Missing parameter: 'factory'") if factory == "fieldset": res = add_fieldset(context, self.request, data) else: res = add_field(context, self.request, data) self.request.response.setStatus(201) return res
def __call__(self, validate_all=False, data=None): if data is None: data = json_body(self.request) if 'message' in data: field = IMail['message'] deserializer = queryMultiAdapter( (field, self.context, self.request), IFieldDeserializer) message = deserializer(data['message']) if message and message.filename.lower().endswith('.msg'): self.context.original_message = message transform = Msg2MimeTransform() eml = transform.transform(message.data) data['message'] = { 'data': eml, 'content-type': 'message/rfc822', 'filename': message.filename[:-3] + 'eml', } context = super(DeserializeMailFromJson, self).__call__( validate_all=validate_all, data=data) context._update_title_from_message_subject() initialize_metadata(context, None) initalize_title(context, None) return context
def reply(self): data = json_body(self.request) query = data.get("query", None) b_start = int(data.get("b_start", 0)) b_size = int(data.get("b_size", 25)) sort_on = data.get("sort_on", None) sort_order = data.get("sort_order", None) limit = int(data.get("limit", 1000)) fullobjects = data.get("fullobjects", False) if query is None: raise Exception("No query supplied") if sort_order: sort_order = "descending" if sort_order else "ascending" querybuilder = getMultiAdapter( (self.context, self.request), name="querybuilderresults" ) results = querybuilder( query=query, brains=True, b_start=b_start, b_size=b_size, sort_on=sort_on, sort_order=sort_order, limit=limit, ) results = getMultiAdapter((results, self.request), ISerializeToJson)( fullobjects=fullobjects ) return results
def reactivate_dossier(self, objs, comment, publication_dates, include_children=False): # Reject explicit attempts to non-recursively reactivate a dossier if not json_body(self.request).get('include_children', True): raise BadRequest('Reactivating dossier must always be recursive') reactivator = Reactivator(self.context) reactivator.reactivate()
def reply(self): # return 401/403 Forbidden if the user has no permission if not checkPermission('cmf.AddPortalContent', self.context): pm = getToolByName(self.context, 'portal_membership') if bool(pm.isAnonymousUser()): self.request.response.setStatus(401) else: self.request.response.setStatus(403) return data = json_body(self.request) source = data.get('source', None) if not source: raise BadRequest("Property 'source' is required") # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) if not isinstance(source, list): source = [source] parents_ids = {} for item in source: obj = self.get_object(item) if obj is not None: # -- Commented out the following block to disable checking for # -- delete permission, as in GEVER the user is not allowed to # -- delete content. # if self.is_moving: # # To be able to safely move the object, the user requires # # permissions on the parent # if not checkPermission('zope2.DeleteObjects', obj) and \ # not checkPermission( # 'zope2.DeleteObjects', aq_parent(obj)): # self.request.response.setStatus(403) # return parent = aq_parent(obj) if parent in parents_ids: parents_ids[parent].append(obj.getId()) else: parents_ids[parent] = [obj.getId()] results = [] for parent, ids in parents_ids.items(): result = self.context.manage_pasteObjects( cb_copy_data=self.clipboard(parent, ids)) for res in result: results.append({ 'source': '{}/{}'.format( parent.absolute_url(), res['id']), 'target': '{}/{}'.format( self.context.absolute_url(), res['new_id']), }) return results
def __call__(self, validate_all=False, data=None, create=False): if data is None: data = json_body(self.request) # set default values if create: container = aq_parent(aq_inner(self.context)) set_default_values(self.context, container, data) # super call return original___call__(self, validate_all, data, create)
def reply(self): userid, notification_id = self.read_params() mark_as_read = json_body(self.request).get('read', False) if userid != api.user.get_current().getId(): raise Unauthorized( "It's not allowed to access notifications of other users.") notification = self.get_notification(userid, notification_id) if mark_as_read: self.center.mark_notification_as_read(notification.notification_id) self.request.response.setStatus(204)
def reply(self): # Only allow updating a documents file if the document is checked-out # by the current user. manager = getMultiAdapter((self.context, self.request), ICheckinCheckoutManager) if not manager.is_checked_out_by_current_user(): data = json_body(self.request) if 'file' in data: self.request.response.setStatus(403) return dict(error=dict( type='Forbidden', message='Document not checked-out by current user.')) return super(DocumentPatch, self).reply()
def reply(self): plugin = None acl_users = getToolByName(self, "acl_users") plugins = acl_users._getOb('plugins') authenticators = plugins.listPlugins(IAuthenticationPlugin) for id_, authenticator in authenticators: if authenticator.meta_type == "JWT Authentication Plugin": plugin = authenticator break if plugin is None: self.request.response.setStatus(501) return dict(error=dict( type='Login failed', message='JWT authentication plugin not installed.')) data = json_body(self.request) if 'login' not in data or 'password' not in data: self.request.response.setStatus(400) return dict(error=dict( type='Missing credentials', message='Login and password must be provided in body.')) # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) userid = data['login'].encode('utf8') password = data['password'].encode('utf8') uf = self._find_userfolder(userid) if uf is not None: user = uf.authenticate( userid, password, self.request) else: user = None if not user: self.request.response.setStatus(401) return dict(error=dict( type='Invalid credentials', message='Wrong login and/or password.')) payload = {} payload['fullname'] = user.getProperty('fullname') return { 'token': plugin.create_token(user.getId(), data=payload) }
def reply(self): userid = self.validate_user(self.get_userid()) data = self.validate_data(json_body(self.request)) obj = self.lookup_object(data) favorite = FavoriteManager().get_favorite(obj, api.user.get_current()) if favorite: # favorite already exists self.request.response.setStatus(409) return favorite.serialize(api.portal.get().absolute_url()) favorite = FavoriteManager().add(userid, obj) self.request.response.setStatus(201) url = favorite.api_url(api.portal.get().absolute_url()) self.request.response.setHeader('Location', url) return favorite.serialize(api.portal.get().absolute_url())
def resolve_dossier(self, objs, comment, publication_dates, include_children=False): if self.is_already_resolved(): # XXX: This should be prevented by the workflow tool. # For some reason it currently doesn't. raise BadRequest('Dossier has already been resolved.') # Reject explicit attempts to non-recursively resolve a dossier if not json_body(self.request).get('include_children', True): raise BadRequest('Resolving dossier must always be recursive') resolve_manager = LockingResolveManager(self.context) if resolve_manager.is_archive_form_needed(): raise BadRequest( "Can't resolve dossiers via REST API if filing number " "feature is activated") resolve_manager.resolve()
def __call__(self, validate_all=False): data = json_body(self.request) obj = self.context modified = False for field in obj.Schema().fields(): if not field.writeable(obj): continue name = field.getName() if name in data: deserializer = queryMultiAdapter((field, obj, self.request), IFieldDeserializer) if deserializer is None: continue value, kwargs = deserializer(data[name]) mutator = field.getMutator(obj, **kwargs) mutator(value) modified = True if modified: errors = obj.validate(data=True, metadata=True) if not validate_all: errors = {f: e for f, e in errors.items() if f in data} if errors: errors = [{ 'message': e, 'field': f, 'error': 'ValidationError'} for f, e in errors.items()] raise BadRequest(errors) if obj.checkCreationFlag(): obj.unmarkCreationFlag() notify(ObjectInitializedEvent(obj)) obj.at_post_create_script() else: notify(ObjectEditedEvent(obj)) obj.at_post_edit_script() return obj
def reply(self): manager = getMultiAdapter((self.context, self.request), ICheckinCheckoutManager) if not manager.is_checkin_allowed(): self.request.response.setStatus(403) return {'error': { 'type': 'Forbidden', 'message': 'Checkin is not allowed.', }} # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) data = json_body(self.request) comment = data.get('comment', '') manager.checkin(comment=comment) self.request.response.setStatus(204) return super(Checkin, self).reply()
def reply(self): # Disable CSRF protection alsoProvides(self.request, IDisableCSRFProtection) action_data = json_body(self.request) scrub_json_payload(action_data) errors = get_validation_errors(action_data, IWebActionSchema) if errors: raise BadRequest(errors) storage = get_storage() try: action_id = storage.add(action_data) except ActionAlreadyExists as exc: raise BadRequest([('unique_name', exc)]) serialized_action = serialize_webaction(storage.get(action_id)) self.request.response.setStatus(201) self.request.response.setHeader('Location', serialized_action['@id']) return serialized_action
def reply(self): userid, fav_id = self.read_params() if userid != api.user.get_current().getId(): raise Unauthorized( "It's not allowed to update favorites of other users.") data = json_body(self.request) if data.get('title') is None and data.get('position') is None: raise BadRequest('Missing parameter title or position') FavoriteManager().update( userid, fav_id, title=data.get('title'), position=data.get('position')) prefer = self.request.getHeader('Prefer') if prefer == 'return=representation': self.request.response.setStatus(200) favorite = Favorite.query.get(fav_id) return favorite.serialize(api.portal.get().absolute_url()) self.request.response.setStatus(204) return None
def recurse_transition(self, objs, comment, publication_dates, include_children=False): data = json_body(self.request) for obj in objs: if publication_dates: deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) deserializer(data=publication_dates) adapter = queryMultiAdapter( (obj, getRequest()), ITransitionExtender, name=self.transition) if adapter: errors = adapter.validate_schema(data) if errors: raise BadRequest(errors) self.wftool.doActionFor(obj, self.transition, comment=comment, transition_params=data) if include_children and IFolderish.providedBy(obj): self.recurse_transition( obj.objectValues(), comment, publication_dates, include_children)
def perform_custom_transition(self): data = json_body(self.request) self.disable_csrf_protection() # TODO: Do we need to handle comments and publication dates # etc. for dossier transitions like the original implementation does? # For now we also extract these, but we don't do anything with them # in the case of resolving a dossier. comment = data.get('comment', '') include_children = data.get('include_children', False) publication_dates = self.parse_publication_dates(data) args = [self.context], comment, publication_dates, include_children if self.transition == 'dossier-transition-resolve': self.resolve_dossier(*args) elif self.transition == 'dossier-transition-activate': self.activate_dossier(*args) elif self.transition == 'dossier-transition-deactivate': self.deactivate_dossier(*args) elif self.transition == 'dossier-transition-reactivate': self.reactivate_dossier(*args) else: raise BadRequest('Unexpected custom transition %r' % self.transition)
def __call__(self, validate_all=False): data = json_body(self.request) modified = False schema_data = {} errors = [] for schema in iterSchemata(self.context): write_permissions = mergedTaggedValueDict( schema, WRITE_PERMISSIONS_KEY) for name, field in getFields(schema).items(): field_data = schema_data.setdefault(schema, {}) if field.readonly: continue if name in data: dm = queryMultiAdapter((self.context, field), IDataManager) if not dm.canWrite(): continue if not self.check_permission(write_permissions.get(name)): continue # Deserialize to field value deserializer = queryMultiAdapter( (field, self.context, self.request), IFieldDeserializer) if deserializer is None: continue try: value = deserializer(data[name]) except ValueError as e: errors.append({ 'message': e.message, 'field': name, 'error': e}) except ValidationError as e: errors.append({ 'message': e.doc(), 'field': name, 'error': e}) else: field_data[name] = value if value != dm.get(): dm.set(value) modified = True elif validate_all: # Never validate the changeNote of p.a.versioningbehavior # The Versionable adapter always returns an empty string # which is the wrong type. Should be unicode and should be # fixed in p.a.versioningbehavior if name == 'changeNote': continue dm = queryMultiAdapter((self.context, field), IDataManager) bound = field.bind(self.context) try: bound.validate(dm.get()) except ValidationError as e: errors.append({ 'message': e.doc(), 'field': name, 'error': e}) # Validate schemata for schema, field_data in schema_data.items(): validator = queryMultiAdapter( (self.context, self.request, None, schema, None), IManagerValidator) for error in validator.validate(field_data): errors.append({'error': error, 'message': error.message}) if errors: raise BadRequest(errors) if modified: notify(ObjectModifiedEvent(self.context)) return self.context
def render(self): data = json_body(self.request) type_ = data.get('@type', None) id_ = data.get('id', None) title = data.get('title', None) if not type_: raise BadRequest("Property '@type' is required") # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) # Generate a temporary id if the id is not given if not id_: now = DateTime() new_id = '{}.{}.{}{:04d}'.format( type_.lower().replace(' ', '_'), now.strftime('%Y-%m-%d'), str(now.millis())[7:], randint(0, 9999)) else: new_id = id_ # Create object try: new_id = self.context.invokeFactory(type_, new_id, title=title) except BadRequest as e: self.request.response.setStatus(400) return dict(error=dict( type='DeserializationError', message=str(e.message))) except ValueError as e: self.request.response.setStatus(400) return dict(error=dict( type='DeserializationError', message=str(e.message))) # Update fields obj = self.context[new_id] deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: self.request.response.setStatus(501) return dict(error=dict( message='Cannot deserialize type {}'.format(obj.portal_type))) try: deserializer(validate_all=True) except DeserializationError as e: self.request.response.setStatus(400) return dict(error=dict( type='DeserializationError', message=str(e))) # Rename if generated id if not id_: self.rename_object(obj) self.request.response.setStatus(201) self.request.response.setHeader('Location', obj.absolute_url()) return None
def reply(self): portal = getSite() data = json_body(self.request) username = data.get('username', None) email = data.get('email', None) password = data.get('password', None) roles = data.get('roles', []) properties = data.get('properties', {}) security_settings = getAdapter(self.context, ISecuritySchema) use_email_as_login = security_settings.use_email_as_login if not username and not use_email_as_login: raise BadRequest("Property 'username' is required") if not email and use_email_as_login: raise BadRequest("Property 'email' is required") if not password: raise BadRequest("Property 'password' is required") # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) # set username based on the login settings (username or email) if use_email_as_login: username = email properties['username'] = email else: properties['username'] = username # set email property if email: properties['email'] = email # Create user try: registration = getToolByName(portal, 'portal_registration') user = registration.addMember( username, password, roles, properties=properties ) except ValueError as e: self.request.response.setStatus(400) return dict(error=dict( type='MissingParameterError', message=str(e.message))) if not username and use_email_as_login: username = email self.request.response.setStatus(201) self.request.response.setHeader( 'Location', portal.absolute_url() + '/@users/' + username ) serializer = queryMultiAdapter( (user, self.request), ISerializeToJson ) return serializer()
def render(self): sm = getSecurityManager() if not sm.checkPermission('Add portal content', self.context): raise Unauthorized data = json_body(self.request) type_ = data.get('@type', None) id_ = data.get('id', None) title = data.get('title', None) if not type_: raise BadRequest("Property '@type' is required") # Disable CSRF protection if 'IDisableCSRFProtection' in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) # Generate a temporary id if the id is not given if not id_: now = DateTime() new_id = '%s.%s' % (now.millis(), randint(0, 99999999)) else: new_id = id_ # Create object try: new_id = self.context.invokeFactory(type_, new_id, title=title) except BadRequest as e: self.request.response.setStatus(400) return dict(error=dict( type='DeserializationError', message=str(e.message))) except ValueError as e: self.request.response.setStatus(400) return dict(error=dict( type='DeserializationError', message=str(e.message))) # Update fields obj = self.context[new_id] deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: self.request.response.setStatus(501) return dict(error=dict( message='Cannot deserialize type {}'.format(obj.portal_type))) try: deserializer(validate_all=True) except DeserializationError as e: self.request.response.setStatus(400) return dict(error=dict( type='DeserializationError', message=str(e))) # Rename if generated id if not id_: chooser = INameChooser(self.context) # INameFromTitle adaptable objects should not get a name # suggestion. NameChooser would prefer the given name instead of # the one provided by the INameFromTitle adapter. name_from_title = INameFromTitle(obj, None) if name_from_title is None: name = chooser.chooseName(title, obj) else: name = chooser.chooseName(None, obj) transaction.savepoint(optimistic=True) self.context.manage_renameObject(new_id, name) self.request.response.setStatus(201) self.request.response.setHeader('Location', obj.absolute_url()) return None