def transition(obj=None, transition=None): """Perform a workflow transition for the object. :param obj: [required] Object for which we want to perform the workflow transition. :type obj: Content object :param transition: [required] Name of the workflow transition. :type transition: string :raises: :class:`~plone.api.exc.MissingParameterError`, :class:`~plone.api.exc.InvalidParameterError` :Example: :ref:`content_transition_example` """ if not obj or not transition: raise MissingParameterError('You have to provide the ``obj`` and the ' '``transition`` parameters') workflow = getToolByName(portal.get(), 'portal_workflow') try: workflow.doActionFor(obj, transition) except WorkflowException: transitions = [ action['id'] for action in workflow.listActions(object=obj) ] raise InvalidParameterError( "Invalid transition '%s'. \n" "Valid transitions are:\n" "%s" % (transition, '\n'.join(sorted(transitions))))
def get_tool(name=None): """Get a portal tool in a simple way. :param name: [required] Name of the tool you want. :type name: string :returns: The tool that was found by name :raises: :class:`~plone.api.exc.MissingParameterError`, :class:`~plone.api.exc.InvalidParameterError` :Example: :ref:`portal_get_tool_example` """ if not name: raise MissingParameterError("Missing required parameter: name") try: return getToolByName(get(), name) except AttributeError: # get a list of all tools so we can display their names in the error msg portal = get() tools = [] for id in portal.objectIds(): if id.startswith('portal_'): tools.append(id) raise InvalidParameterError( "Cannot find a tool with name '%s'. \n" "Available tools are:\n" "%s" % (name, '\n'.join(tools)))
def create(email=None, username=None, password=None, roles=('Member', ), properties=None): """Create a user. :param email: [required] Email for the new user. :type email: string :param username: Username for the new user. This is required if email is not used as a username. :type username: string :param password: Password for the new user. If it's not set we generate a random 8-char alpha-numeric one. :type password: string :param properties: User properties to assign to the new user. The list of available properties is available in ``portal_memberdata`` through ZMI. :type properties: dict :returns: Newly created user :rtype: MemberData object :raises: MissingParameterError InvalidParameterError :Example: :ref:`user_create_example` """ if properties is None: # Never use a dict as default for a keyword argument. properties = {} # it may happen that someone passes email in the properties dict, catch # that and set the email so the code below this works fine if not email and properties.get('email'): email = properties.get('email') if not email: raise MissingParameterError("You need to pass the new user's email.") site = portal.get() props = site.portal_properties use_email_as_username = props.site_properties.use_email_as_login if not use_email_as_username and not username: raise InvalidParameterError( "The portal is configured to use username " "that is not email so you need to pass a username.") registration = portal.get_tool('portal_registration') user_id = use_email_as_username and email or username # Generate a random 8-char password if not password: chars = string.ascii_letters + string.digits password = ''.join(random.choice(chars) for x in range(8)) properties.update(username=user_id) properties.update(email=email) registration.addMember(user_id, password, roles, properties=properties) return get(username=user_id)
def get_view(name=None, context=None, request=None): """Get a BrowserView object. :param name: [required] Name of the view. :type name: string :param context: [required] Context on which to get view. :type context: context object :param request: [required] Request on which to get view. :type request: request object :raises: :class:`~plone.api.exc.MissingParameterError`, :class:`~plone.api.exc.InvalidParameterError` :Example: :ref:`content_get_view_example` """ if not name: raise MissingParameterError("Missing required parameter: name") if not context: raise MissingParameterError("Missing required parameter: context") if not request: raise MissingParameterError("Missing required parameter: request") # It happens sometimes that ACTUAL_URL is not set in tests. To be nice # and not throw strange errors, we set it to be the same as URL. # TODO: if/when we have api.env.test_mode() boolean in the future, use that config = getConfiguration() if config.dbtab.__module__ == 'plone.testing.z2': request['ACTUAL_URL'] = request['URL'] try: return getMultiAdapter((context, request), name=name) except: # get a list of all views so we can display their names in the error msg sm = getSiteManager() views = sm.adapters.lookupAll(required=(providedBy(context), providedBy(request)), provided=Interface) views_names = [view[0] for view in views] raise InvalidParameterError("Cannot find a view with name '%s'. \n" "Available views are:\n" "%s" % (name, '\n'.join(sorted(views_names))))
def wrapped(f, *args, **kwargs): """The wrapped function (whose docstring will get replaced).""" supplied_args = _get_supplied_args(signature_params, args, kwargs) candidates = [s for s in supplied_args if s in candidate_params] if len(candidates) < 1: raise MissingParameterError( "At least one of these parameters must be " "supplied: {0}.".format(", ".join(candidate_params))) return f(*args, **kwargs)
def wrapped(f, *args, **kwargs): """The wrapped function (whose docstring will get replaced)""" supplied_args = _get_supplied_args(signature_params, args, kwargs) missing = [p for p in required_params if p not in supplied_args] if len(missing): raise MissingParameterError( "Missing required parameter(s): {0}".format( ", ".join(missing))) return f(*args, **kwargs)
def rename(obj=None, new_id=None, safe_id=False): """Rename the object. :param obj: [required] Object that we want to rename. :type obj: Content object :param new_id: New id of the object. :type new_id: string :param safe_id: When False, the given id will be enforced. If the id is conflicting with another object in the container, raise a InvalidParameterError. When True, choose a new, non-conflicting id. :type safe_id: boolean :Example: :ref:`content_rename_example` """ if not obj: raise MissingParameterError("Missing required parameter: obj") if not new_id: raise MissingParameterError("Missing required parameter: new_id") move(source=obj, id=new_id, safe_id=safe_id)
def decrypt_token(self, token): """ @param token: the JWT token we have to decrypt @return: the JWT token payload """ secret = api.portal.get_registry_record( self.registry_record, default=None ) if not secret: """ We miss a parameter """ raise MissingParameterError("Secret is missing") decoded = jwt.decode(token, secret, algorithms=self.algorithm) return decoded
def wrapped(function, *args, **kwargs): """The wrapped function (whose docstring will get replaced)""" supplied_args = _get_supplied_args(signature_params, args, kwargs) missing = [ param for param in required_params if param not in supplied_args ] if len(missing): raise MissingParameterError( 'Missing required parameter(s): {params}'.format( params=', '.join(missing), ), ) return function(*args, **kwargs)
def wrapped(function, *args, **kwargs): """The wrapped function (whose docstring will get replaced).""" supplied_args = _get_supplied_args(signature_params, args, kwargs) candidates = [ candidate for candidate in supplied_args if candidate in candidate_params ] if len(candidates) < 1: raise MissingParameterError( 'At least one of these parameters must be ' 'supplied: {params}.'.format( params=', '.join(candidate_params), ), ) return function(*args, **kwargs)
def generate_token(self, expiration=None, payload={}): """ @param obj: the reservation @param time: eventual expiration date or time @return a new JWT token """ secret = api.portal.get_registry_record( self.registry_record, default=None ) if not secret: """ We miss a parameter """ raise MissingParameterError("Secret is missing") if expiration: # Right now not handled payload.update({"expiration": expiration.isoformat()}) else: # we set as a default midnight of the previous day payload.update({"expiration": None}) encoded = jwt.encode(payload, secret, algorithm=self.algorithm) return encoded
def create(container=None, type=None, id=None, title=None, safe_id=False, **kwargs): """Create a new content item. :param container: [required] Container object in which to create the new object. :type container: Folderish content object :param type: [required] Type of the object. :type type: string :param id: Id of the object. If the id conflicts with another object in the container, a suffix will be added to the new object's id. If no id is provided, automatically generate one from the title. If there is no id or title provided, raise a ValueError. :type id: string :param title: Title of the object. If no title is provided, use id as the title. :type title: string :param safe_id: When False, the given id will be enforced. If the id is conflicting with another object in the target container, raise a InvalidParameterError. When True, choose a new, non-conflicting id. :type safe_id: boolean :returns: Content object :raises: KeyError, :class:`~plone.api.exc.MissingParameterError`, :class:`~plone.api.exc.InvalidParameterError` :Example: :ref:`content_create_example` """ if not container: raise MissingParameterError("Missing required parameter: container") if not type: raise MissingParameterError("Missing required parameter: type") if not id and not title: raise MissingParameterError( 'You have to provide either the ``id`` or the ' '``title`` parameter') # Create a temporary id if the id is not given content_id = not safe_id and id or str(random.randint(0, 99999999)) if title: kwargs['title'] = title try: container.invokeFactory(type, content_id, **kwargs) except ValueError: if ISiteRoot.providedBy(container): types = [type.id for type in container.allowedContentTypes()] else: types = container.getLocallyAllowedTypes() raise InvalidParameterError( "Cannot add a '%s' object to the container. \n" "Allowed types are:\n" "%s" % (type, '\n'.join(sorted(types)))) content = container[content_id] # Archetypes specific code if IBaseObject.providedBy(content): # Will finish Archetypes content item creation process, # rename-after-creation and such content.processForm() if not id or (safe_id and id): # Create a new id from title chooser = INameChooser(container) derived_id = id or title new_id = chooser.chooseName(derived_id, content) # kacee: we must do a partial commit, else the renaming fails because # the object isn't in the zodb. # Thus if it is not in zodb, there's nothing to move. We should # choose a correct id when # the object is created. # maurits: tests run fine without this though. transaction.savepoint(optimistic=True) content.aq_parent.manage_renameObject(content_id, new_id) return content