Ejemplo n.º 1
0
    def view(self, *args, **kwargs):
        """
		Prepares and renders a single entry for viewing.

		The entry is fetched by its entity key, which either is provided via *kwargs["key"]*,
		or as the first parameter in *args*. The function performs several access control checks
		on the requested entity before it is rendered.

		.. seealso:: :func:`viewSkel`, :func:`canView`, :func:`onItemViewed`

		:returns: The rendered representation of the requested entity.

		:raises: :exc:`server.errors.NotAcceptable`, when no *key* is provided.
		:raises: :exc:`server.errors.NotFound`, when no entry with the given *key* was found.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		"""
        if "key" in kwargs:
            key = kwargs["key"]
        elif len(args) >= 1:
            key = args[0]
        else:
            raise errors.NotAcceptable()
        if not len(key):
            raise errors.NotAcceptable()
        skel = self.viewSkel()
        if key == u"structure":
            # We dump just the structure of that skeleton, including it's default values
            if "canView" in dir(self):
                if not self.canView(skel):
                    raise errors.Unauthorized()
            else:
                if self.listFilter(self.viewSkel().all()) is None:
                    raise errors.Unauthorized()
        else:
            # We return a single entry for viewing
            if "canView" in dir(self):
                if not skel.fromDB(key):
                    raise errors.NotFound()
                if not self.canView(skel):
                    raise errors.Unauthorized()
            else:
                queryObj = self.viewSkel().all().mergeExternalFilter(
                    {"key": key})
                queryObj = self.listFilter(queryObj)  #Access control
                if queryObj is None:
                    raise errors.Unauthorized()
                skel = queryObj.getSkel()
                if not skel:
                    raise errors.NotFound()
            self.onItemViewed(skel)
        return self.render.view(skel)
Ejemplo n.º 2
0
	def view( self, *args, **kwargs ):
		"""
		Prepares and renders the singleton entry for viewing.

		The function performs several access control checks on the requested entity before it is rendered.

		.. seealso:: :func:`viewSkel`, :func:`canView`, :func:`onItemViewed`

		:returns: The rendered representation of the entity.

		:raises: :exc:`server.errors.NotFound`, if there is no singleton entry existing, yet.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		"""

		skel = self.viewSkel()
		if not self.canView( ):
			raise errors.Unauthorized()

		key = str( db.Key.from_path( self.editSkel().kindName, self.getKey() ) )

		if not skel.fromDB(key):
			raise errors.NotFound()

		self.onItemViewed( skel )
		return self.render.view( skel )
Ejemplo n.º 3
0
    def getBill(self, key, *args, **kwargs):
        """
			Returns the Bill for the given order.
		"""
        skel = self.viewSkel()

        if "canView" in dir(self):
            if not self.canView(key):
                raise errors.Unauthorized()
        else:
            queryObj = self.viewSkel().all().mergeExternalFilter({"key": key})
            queryObj = self.listFilter(queryObj)  #Access control

            if queryObj is None:
                raise errors.Unauthorized()

        bill = self.getBillPdf(key)

        if not bill:
            raise errors.NotFound()

        request.current.get(
        ).response.headers['Content-Type'] = "application/pdf"

        return (bill)
Ejemplo n.º 4
0
    def list(self, parent, *args, **kwargs):
        """
		List the entries which are direct children of the given *parent*.
		Any other supplied parameters are interpreted as filters for the elements displayed.

		.. seealso:: :func:`canList`, :func:`server.db.mergeExternalFilter`

		:param parent: URL-safe key of the parent.
		:type parent: str

		:returns: The rendered list objects for the matching entries.

		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		:raises: :exc:`server.errors.NotFound`, if *parent* could not be found.
		"""
        if not parent or not self.canList(parent):
            raise errors.Unauthorized()

        parentSkel = self.viewSkel()

        if not parentSkel.fromDB(parent):
            if not str(parent) in [
                    str(x["key"]) for x in self.getAvailableRootNodes()
            ]:
                # It isn't a rootNode either
                raise errors.NotFound()
            else:
                parentSkel = None

        query = self.viewSkel().all()
        query.mergeExternalFilter(kwargs)
        query.filter("parententry", parent)
        return self.render.list(query.fetch(),
                                parent=parent,
                                parentSkel=parentSkel)
Ejemplo n.º 5
0
    def triggerSendNewsletter(self, key, skey, *args, **kwargs):
        if not securitykey.validate(skey):
            raise errors.PreconditionFailed()

        user = utils.getCurrentUser()
        if not (user and "root" in user["access"]):
            raise errors.Unauthorized()

        skel = self.viewSkel()
        if not skel.fromDB(key):
            raise errors.NotFound()

        if skel["triggered"] or skel["sent"]:
            raise errors.Forbidden("This newsletter was already sent.")

        try:
            setStatus(skel["key"],
                      values={
                          "triggered": True,
                          "triggereddate": datetime.datetime.now(),
                      },
                      check={
                          "triggered": False,
                          "sent": False
                      })
        except Exception as e:
            logging.exception(e)
            raise errors.Forbidden()

        self.fetchNewsletterRecipients(str(skel["key"]))

        return json.dumps("OKAY")
Ejemplo n.º 6
0
    def view(self, *args, **kwargs):
        """
		Prepares and renders a single entry for viewing.

		The entry is fetched by its entity key, which either is provided via *kwargs["key"]*,
		or as the first parameter in *args*. The function performs several access control checks
		on the requested entity before it is rendered.

		.. seealso:: :func:`viewSkel`, :func:`canView`, :func:`onItemViewed`

		:returns: The rendered representation of the requested entity.

		:raises: :exc:`server.errors.NotAcceptable`, when no *key* is provided.
		:raises: :exc:`server.errors.NotFound`, when no entry with the given *key* was found.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		"""
        if "key" in kwargs:
            key = kwargs["key"]
        elif len(args) >= 1:
            key = args[0]
        else:
            raise errors.NotAcceptable()
        if not len(key):
            raise errors.NotAcceptable()
        skel = self.viewSkel()

        if not skel.fromDB(key):
            raise errors.NotFound()

        if not self.canView(skel):
            raise errors.Unauthorized()

        self.onItemViewed(skel)
        return self.render.view(skel)
Ejemplo n.º 7
0
    def pathToKey(self, key):
        """
		Returns the recursively expanded path through the Tree from the root-node to the given *key*.

		:param key: URL-safe key of the destination node.
		:type key: str

		:returns: An nested dictionary with information about all nodes in the path from root to the \
		given node key.
		:rtype: dict
		"""
        nodeSkel = self.viewNodeSkel()

        if not nodeSkel.fromDB(key):
            raise errors.NotFound()

        if not self.canList("node", key):
            raise errors.Unauthorized()

        res = [self.render.collectSkelData(nodeSkel)]

        for x in range(0, 99):
            if not nodeSkel["parentdir"]:
                break

            parentdir = nodeSkel["parentdir"]

            nodeSkel = self.viewNodeSkel()
            if not nodeSkel.fromDB(parentdir):
                break

            res.append(self.render.collectSkelData(nodeSkel))

        return (res[::-1])
Ejemplo n.º 8
0
    def delete(self, key, skey, *args, **kwargs):
        """
		Delete an entry and all its children.

		The function runs several access control checks on the data before it is deleted.

		.. seealso:: :func:`canDelete`, :func:`editSkel`, :func:`onItemDeleted`

		:param key: URL-safe key of the entry to be deleted.
		:type key: str

		:returns: The rendered, deleted object of the entry.

		:raises: :exc:`server.errors.NotFound`, when no entry with the given *key* was found.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		:raises: :exc:`server.errors.PreconditionFailed`, if the *skey* could not be verified.
		"""
        if not securitykey.validate(skey, acceptSessionKey=True):
            raise errors.PreconditionFailed()

        skel = self.editSkel()

        if not skel.fromDB(key):
            raise errors.NotFound()

        if not self.canDelete(skel):
            raise errors.Unauthorized()

        self.deleteRecursive(key)
        skel.delete()
        self.onItemDeleted(skel)
        self.onItemChanged(skel)

        return self.render.deleteSuccess(skel)
Ejemplo n.º 9
0
	def download(self, blobKey, fileName = "", download = "", *args, **kwargs):
		"""
		Download a file.

		:param blobKey: The unique blob key of the file.
		:type blobKey: str

		:param fileName: Optional filename to provide in the header.
		:type fileName: str

		:param download: Set header to attachment retrival, set explictly to "1" if download is wanted.
		:type download: str
		"""
		if download == "1":
			fname = "".join([c for c in fileName if c in string.ascii_lowercase+string.ascii_uppercase + string.digits+".-_"])
			request.current.get().response.headers.add_header("Content-disposition", ("attachment; filename=%s" % (fname)).encode("UTF-8"))
		info = blobstore.get(blobKey)
		if not info:
			raise errors.NotFound()
		request.current.get().response.clear()
		request.current.get().response.headers['Content-Type'] = str(info.content_type)
		if self.blobCacheTime:
			request.current.get().response.headers['Cache-Control'] = "public, max-age=%s" % self.blobCacheTime
		request.current.get().response.headers[blobstore.BLOB_KEY_HEADER] = str(blobKey)
		return ""
Ejemplo n.º 10
0
    def get_users(self, data) -> dict:
        # get users
        query = self.session.query(models.User)

        # businesss logic - sorting
        if data["sort_by"] != "":
            column = getattr(models.User, data["sort_by"])
            if data["order"] == "desc":
                query = query.order_by(column.desc())
            else:
                query = query.order_by(column.asc())
        else:
            query = query.order_by(models.User.createTime.desc())

        # pagination
        offset = (data["page"] - 1) * data["limit"]
        query = query.limit(data["limit"]).offset(offset)

        # bounds checking
        if query.count() == 0:
            raise errors.NotFound("found no users for query input")

        # return query results
        results = schema.UserSchema(many=True).dump(query)
        output = {"users": results}
        return output
Ejemplo n.º 11
0
    def getTemplateFileName(self, template, ignoreStyle=False):
        """
			Returns the filename of the template.

			This function decides in which language and which style a given template is rendered.
			The style is provided as get-parameters for special-case templates that differ from
			their usual way.

			It is advised to override this function in case that
			:func:`server.render.jinja2.default.Render.getLoaders` is redefined.

			:param template: The basename of the template to use.
			:type template: str

			:param ignoreStyle: Ignore any maybe given style hints.
			:type ignoreStyle: bool

			:returns: Filename of the template
			:rtype: str
		"""
        validChars = "abcdefghijklmnopqrstuvwxyz1234567890-"
        if "htmlpath" in dir(self):
            htmlpath = self.htmlpath
        else:
            htmlpath = "html"
        if not ignoreStyle\
         and "style" in list( request.current.get().kwargs.keys())\
         and all( [ x in validChars for x in request.current.get().kwargs["style"].lower() ] ):
            stylePostfix = "_" + request.current.get().kwargs["style"]
        else:
            stylePostfix = ""
        lang = request.current.get().language  #session.current.getLanguage()
        fnames = [template + stylePostfix + ".html", template + ".html"]
        if lang:
            fnames = [
                os.path.join(lang, template + stylePostfix + ".html"),
                template + stylePostfix + ".html",
                os.path.join(lang, template + ".html"), template + ".html"
            ]
        for fn in fnames:  #check subfolders
            prefix = template.split("_")[0]
            if os.path.isfile(os.path.join(os.getcwd(), "html", prefix, fn)):
                return ("%s/%s" % (prefix, fn))
        for fn in fnames:  #Check the templatefolder of the application
            if os.path.isfile(os.path.join(os.getcwd(), htmlpath, fn)):
                self.checkForOldLinePrefix(
                    os.path.join(os.getcwd(), htmlpath, fn))
                return (fn)
        for fn in fnames:  #Check the fallback
            if os.path.isfile(
                    os.path.join(os.getcwd(), "server", "template", fn)):
                self.checkForOldLinePrefix(
                    os.path.join(os.getcwd(), "server", "template", fn))
                return (fn)
        raise errors.NotFound("Template %s not found." % template)
Ejemplo n.º 12
0
	def setSortIndex(self, key, index, skey, *args, **kwargs):
		if not securitykey.validate(skey, acceptSessionKey=True):
			raise errors.PreconditionFailed()

		skel = self.editSkel()
		if not skel.fromDB(key):
			raise errors.NotFound()

		skel["sortindex"] = float(index)
		skel.toDB(clearUpdateTag=True)
		return self.render.renderEntry(skel, "setSortIndexSuccess")
Ejemplo n.º 13
0
    def get_user(self, data: dict) -> dict:
        # find a user
        user = (
            self.session.query(models.User).filter_by(user_id=data["user_id"]).first()
        )
        if user is None:
            raise errors.NotFound("a user with the given user_id could not be found")

        # return our found user
        output = schema.UserSchema().dump(user)
        return output
Ejemplo n.º 14
0
	def index( self,template="index",*arg,**kwargs ):
		if ".." in template or "/" in template:
			return

		try:

			template = self.render.getEnv().get_template( self.render.getTemplateFileName( "sites/"+template ) )
		except:
			raise errors.NotFound()

		return template.render()
Ejemplo n.º 15
0
    def edit(self, skelType, key, skey="", *args, **kwargs):
        """
		Modify an existing entry, and render the entry, eventually with error notes on incorrect data.
		Data is taken by any other arguments in *kwargs*.

		The function performs several access control checks on the requested entity before it is added.

		.. seealso:: :func:`onItemAdded`, :func:`canEdit`

		:param skelType: Defines the type of the entry that should be modified and may either be "node" or "leaf".
		:type skelType: str
		:param key: URL-safe key of the item to be edited.
		:type key: str

		:returns: The rendered, modified object of the entry, eventually with error hints.

		:raises: :exc:`server.errors.NotAcceptable`, when no valid *skelType* was provided.
		:raises: :exc:`server.errors.NotFound`, when no valid *node* was found.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		:raises: :exc:`server.errors.PreconditionFailed`, if the *skey* could not be verified.
		"""
        if skelType == "node":
            skel = self.editNodeSkel()
        elif skelType == "leaf":
            skel = self.editLeafSkel()
        else:
            raise errors.NotAcceptable()

        if not skel.fromDB(key):
            raise errors.NotFound()

        if not self.canEdit(skelType, skel):
            raise errors.Unauthorized()

        if (len(kwargs) == 0  # no data supplied
                or skey == ""  # no security key
                #or not request.current.get().isPostRequest fixme: POST-method check missing?  # failure if not using POST-method
                or not skel.fromClient(
                    kwargs)  # failure on reading into the bones
                or ("bounce" in kwargs and kwargs["bounce"] == "1"
                    )  # review before adding
            ):
            return self.render.edit(skel)

        if not securitykey.validate(skey, acceptSessionKey=True):
            raise errors.PreconditionFailed()

        skel.toDB()
        self.onItemEdited(skel)

        return self.render.editItemSuccess(skel)
Ejemplo n.º 16
0
    def resetPassword(self, key, *args, **kwargs):
        cuser = utils.getCurrentUser()
        if not (cuser and "root" in cuser["access"]):
            raise errors.Unauthorized("Only 'root' can do this!")

        skel = self.editSkel()
        if not skel.fromDB(key):
            raise errors.NotFound()

        skel["password"] = utils.generateRandomString(10)
        skel["changepassword"] = True
        assert skel.toDB()

        self.sendWelcomeMail(str(skel["key"]), skel["password"])
        return json.dumps("OK")
Ejemplo n.º 17
0
	def view( self, *args, **kwargs ):
		"""
			View or download a file.
		"""
		try:
			return super(File, self).view(*args, **kwargs)
		except (errors.NotFound, errors.NotAcceptable, TypeError) as e:
			if len(args) > 0 and blobstore.get(args[0]):
				raise errors.Redirect("%s/download/%s" % (self.modulePath, args[0]))
			elif len(args) > 1 and blobstore.get(args[1]):
				raise errors.Redirect("%s/download/%s" % (self.modulePath, args[1]))
			elif isinstance( e, TypeError ):
				raise errors.NotFound()
			else:
				raise e
Ejemplo n.º 18
0
    def delete(self, skelType, key, *args, **kwargs):
        """
		Deletes an entry or an directory (including its contents).

		The function runs several access control checks on the data before it is deleted.

		.. seealso:: :func:`canDelete`, :func:`onItemDeleted`

		:param skelType: Defines the type of the entry that should be deleted and may either be "node" or "leaf".
		:type skelType: str
		:param key: URL-safe key of the item to be deleted.
		:type key: str

		:returns: The rendered, deleted object of the entry.

		:raises: :exc:`server.errors.NotFound`, when no entry with the given *key* was found.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		:raises: :exc:`server.errors.PreconditionFailed`, if the *skey* could not be verified.
		"""
        if skelType == "node":
            skel = self.viewNodeSkel()
        elif skelType == "leaf":
            skel = self.viewLeafSkel()
        else:
            raise errors.NotAcceptable()

        if "skey" in kwargs:
            skey = kwargs["skey"]
        else:
            skey = ""

        if not skel.fromDB(key):
            raise errors.NotFound()

        if not self.canDelete(skelType, skel):
            raise errors.Unauthorized()
        if not securitykey.validate(skey, acceptSessionKey=True):
            raise errors.PreconditionFailed()

        if type == "leaf":
            skel.delete()
        else:
            self.deleteRecursive(key)
            skel.delete()

        self.onItemDeleted(skel)
        return (self.render.deleteSuccess(skel, skelType=skelType))
Ejemplo n.º 19
0
    def list(self, skelType, node, *args, **kwargs):
        """
		List the entries and directories of the given *skelType* under the given *node*.
		Any other supplied parameters are interpreted as filters for the elements displayed.

		.. seealso:: :func:`canList`, :func:`server.db.mergeExternalFilter`

		:param skelType: May either be "node" or "leaf".
		:type skelType: str
		:param node: URL-safe key of the parent.
		:type node: str

		:returns: The rendered list objects for the matching entries.

		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		:raises: :exc:`server.errors.NotFound`, if *node* could not be found.
		:raises: :exc:`server.errors.NotAcceptable`, if anything else than "node" or "leaf" is provided to *skelType*.
		"""
        if skelType == "node":
            skel = self.viewNodeSkel()
        elif skelType == "leaf":
            skel = self.viewLeafSkel()
        else:
            raise errors.NotAcceptable()

        if skel is None:
            raise errors.NotAcceptable()

        if not self.canList(skelType, node):
            raise errors.Unauthorized()

        nodeSkel = self.viewNodeSkel()
        if not nodeSkel.fromDB(node):
            raise errors.NotFound()

        query = skel.all()

        if "search" in kwargs and kwargs["search"]:
            query.filter("parentrepo =", str(nodeSkel["key"]))
        else:
            query.filter("parentdir =", str(nodeSkel["key"]))

        query.mergeExternalFilter(kwargs)
        res = query.fetch()

        return self.render.list(res, node=str(nodeSkel["key"]))
Ejemplo n.º 20
0
    def update_user(self, path_data: dict, body_data: dict) -> dict:
        # find the user to update
        user = (
            self.session.query(models.User)
            .filter_by(user_id=path_data["user_id"])
            .first()
        )
        if user is None:
            raise errors.NotFound("a user with the given user_id could not be found")

        # update the user
        user = user.update(body_data)
        self.session.add(user)
        self.session.commit()

        # return our updated user
        output = schema.UserSchema().dump(user)
        return output
Ejemplo n.º 21
0
    def view(self, skelType, key, *args, **kwargs):
        """
		Prepares and renders a single entry for viewing.

		The entry is fetched by its *key* and its *skelType*.
		The function performs several access control checks on the requested entity before it is rendered.

		.. seealso:: :func:`canView`, :func:`onItemViewed`

		:returns: The rendered representation of the requested entity.

		:param skelType: May either be "node" or "leaf".
		:type skelType: str
		:param node: URL-safe key of the parent.
		:type node: str

		:raises: :exc:`server.errors.NotAcceptable`, when an incorrect *skelType* is provided.
		:raises: :exc:`server.errors.NotFound`, when no entry with the given *key* was found.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		"""

        if skelType == "node":
            skel = self.viewNodeSkel()
        elif skelType == "leaf":
            skel = self.viewLeafSkel()
        else:
            raise errors.NotAcceptable()
        if skel is None:
            raise errors.NotAcceptable()
        if not len(key):
            raise errors.NotAcceptable()
        if key == u"structure":
            # We dump just the structure of that skeleton, including it's default values
            if not self.canView(skelType, None):
                raise errors.Unauthorized()
        else:
            # We return a single entry for viewing
            if not skel.fromDB(key):
                raise errors.NotFound()
            if not self.canView(skelType, skel):
                raise errors.Unauthorized()
            self.onItemViewed(skel)
        return self.render.view(skel)
Ejemplo n.º 22
0
 def findAndCall(self, path, *args,
                 **kwargs):  #Do the actual work: process the request
     # Prevent Hash-collision attacks
     assert len(self.request.arguments()) < conf["viur.maxPostParamsCount"]
     # Fill the (surprisingly empty) kwargs dict with named request params
     tmpArgs = dict((k, self.request.get_all(k))
                    for k in self.request.arguments() if k is not None)
     for key in tmpArgs.keys()[:]:
         if len(tmpArgs[key]) == 0:
             continue
         if not key in kwargs.keys():
             if len(tmpArgs[key]) == 1:
                 kwargs[key] = tmpArgs[key][0]
             else:
                 kwargs[key] = tmpArgs[key]
         else:
             if isinstance(kwargs[key], list):
                 kwargs[key] = kwargs[key] + tmpArgs[key]
             else:
                 kwargs[key] = [kwargs[key]] + tmpArgs[key]
     del tmpArgs
     if "self" in kwargs.keys():  #self is reserved for bound methods
         raise errors.BadRequest()
     #Parse the URL
     path = urlparse.urlparse(path).path
     self.pathlist = [
         urlparse.unquote(x) for x in path.strip("/").split("/")
     ]
     caller = conf["viur.mainApp"]
     idx = 0  #Count how may items from *args we'd have consumed (so the rest can go into *args of the called func
     for currpath in self.pathlist:
         if "canAccess" in dir(caller) and not caller.canAccess():
             # We have a canAccess function guarding that object,
             # and it returns False...
             raise (errors.Unauthorized())
         idx += 1
         currpath = currpath.replace("-", "_").replace(".", "_")
         if currpath in dir(caller):
             caller = getattr(caller, currpath)
             if (("exposed" in dir(caller) and caller.exposed) or
                 ("internalExposed" in dir(caller)
                  and caller.internalExposed
                  and self.internalRequest)) and hasattr(
                      caller, '__call__'):
                 args = self.pathlist[idx:] + [
                     x for x in args
                 ]  #Prepend the rest of Path to args
                 break
         elif "index" in dir(caller):
             caller = getattr(caller, "index")
             if (("exposed" in dir(caller) and caller.exposed) or
                 ("internalExposed" in dir(caller)
                  and caller.internalExposed
                  and self.internalRequest)) and hasattr(
                      caller, '__call__'):
                 args = self.pathlist[idx - 1:] + [x for x in args]
                 break
             else:
                 raise (errors.NotFound(
                     "The path %s could not be found" % "/".join([("".join([
                         y for y in x if y.lower() in
                         "0123456789abcdefghijklmnopqrstuvwxyz"
                     ])) for x in self.pathlist[:idx]])))
         else:
             raise (errors.NotFound(
                 "The path %s could not be found" % "/".join([("".join([
                     y for y in x
                     if y.lower() in "0123456789abcdefghijklmnopqrstuvwxyz"
                 ])) for x in self.pathlist[:idx]])))
     if (not callable(caller)
             or ((not "exposed" in dir(caller) or not caller.exposed)) and
         (not "internalExposed" in dir(caller) or not caller.internalExposed
          or not self.internalRequest)):
         if "index" in dir( caller ) \
          and (callable( caller.index ) \
          and ( "exposed" in dir( caller.index ) and caller.index.exposed) \
          or ("internalExposed" in dir( caller.index ) and caller.index.internalExposed and self.internalRequest)):
             caller = caller.index
         else:
             raise (errors.MethodNotAllowed())
     # Check for forceSSL flag
     if not self.internalRequest \
      and "forceSSL" in dir( caller ) \
      and caller.forceSSL \
      and not self.request.host_url.lower().startswith("https://") \
      and not "Development" in os.environ['SERVER_SOFTWARE']:
         raise (errors.PreconditionFailed(
             "You must use SSL to access this ressource!"))
     # Check for forcePost flag
     if "forcePost" in dir(
             caller) and caller.forcePost and not self.isPostRequest:
         raise (errors.MethodNotAllowed(
             "You must use POST to access this ressource!"))
     self.args = []
     for arg in args:
         if isinstance(x, unicode):
             self.args.append(arg)
         else:
             try:
                 self.args.append(arg.decode("UTF-8"))
             except:
                 pass
     self.kwargs = kwargs
     # Check if this request should bypass the caches
     if self.request.headers.get("X-Viur-Disable-Cache"):
         from server import utils
         #No cache requested, check if the current user is allowed to do so
         user = utils.getCurrentUser()
         if user and "root" in user["access"]:
             logging.debug(
                 "Caching disabled by X-Viur-Disable-Cache header")
             self.disableCache = True
     try:
         if (conf["viur.debug.traceExternalCallRouting"]
                 and not self.internalRequest
             ) or conf["viur.debug.traceInternalCallRouting"]:
             logging.debug("Calling %s with args=%s and kwargs=%s" %
                           (str(caller), unicode(args), unicode(kwargs)))
         self.response.out.write(caller(*self.args, **self.kwargs))
     except TypeError as e:
         if self.internalRequest:  #We provide that "service" only for requests originating from outside
             raise
         #Check if the function got too few arguments and raise a NotAcceptable error
         tmpRes = {}
         argsOrder = list(
             caller.__code__.co_varnames)[1:caller.__code__.co_argcount]
         # Map default values in
         reversedArgsOrder = argsOrder[::-1]
         for defaultValue in list(caller.func_defaults or [])[::-1]:
             tmpRes[reversedArgsOrder.pop(0)] = defaultValue
         del reversedArgsOrder
         # Map args in
         setArgs = []  # Store a list of args already set by *args
         for idx in range(0, min(len(args), len(argsOrder))):
             setArgs.append(argsOrder[idx])
             tmpRes[argsOrder[idx]] = args[idx]
         # Last, we map the kwargs in
         for k, v in kwargs.items():
             if k in setArgs:  #This key has already been set by *args
                 raise (
                     errors.NotAcceptable()
                 )  #We reraise that exception as we got duplicate arguments
             tmpRes[k] = v
         # Last check, that every parameter is satisfied:
         if not all([x in tmpRes.keys() for x in argsOrder]):
             raise (errors.NotAcceptable())
         raise
Ejemplo n.º 23
0
    def move(self, skelType, key, destNode, *args, **kwargs):
        """
		Move a node (including its contents) or a leaf to another node.

		.. seealso:: :func:`canMove`

		:param skelType: Defines the type of the entry that should be moved and may either be "node" or "leaf".
		:type skelType: str
		:param key: URL-safe key of the item to be moved.
		:type key: str
		:param destNode: URL-safe key of the destination node, which must be a node.
		:type destNode: str

		:returns: The rendered, edited object of the entry.

		:raises: :exc:`server.errors.NotFound`, when no entry with the given *key* was found.
		:raises: :exc:`server.errors.Unauthorized`, if the current user does not have the required permissions.
		:raises: :exc:`server.errors.PreconditionFailed`, if the *skey* could not be verified.
		"""
        if skelType == "node":
            srcSkel = self.editNodeSkel()
        elif skelType == "leaf":
            srcSkel = self.editLeafSkel()
        else:
            raise errors.NotAcceptable()

        if "skey" in kwargs:
            skey = kwargs["skey"]
        else:
            skey = ""

        destSkel = self.editNodeSkel()
        if not self.canMove(skelType, key, destNode):
            raise errors.Unauthorized()

        if key == destNode:
            # Cannot move a node into itself
            raise errors.NotAcceptable()

        ## Test for recursion
        isValid = False
        currLevel = db.Get(destNode)

        for x in range(0, 99):
            if str(currLevel.key()) == key:
                break
            if "rootNode" in currLevel and currLevel["rootNode"] == 1:
                #We reached a rootNode
                isValid = True
                break
            currLevel = db.Get(currLevel["parentdir"])

        if not isValid:
            raise errors.NotAcceptable()

        #Test if key points to a rootNone
        tmp = db.Get(key)

        if "rootNode" in tmp and tmp["rootNode"] == 1:
            #Cant move a rootNode away..
            raise errors.NotAcceptable()

        if not srcSkel.fromDB(key) or not destSkel.fromDB(destNode):
            # Could not find one of the entities
            raise errors.NotFound()

        if not securitykey.validate(skey, acceptSessionKey=True):
            raise errors.PreconditionFailed()

        srcSkel["parentdir"] = str(destNode)
        srcSkel["parentrepo"] = destSkel[
            "parentrepo"]  #Fixme: Need to recursive fixing to parentrepo?
        srcSkel.toDB()
        self.updateParentRepo(key, destSkel["parentrepo"])

        return self.render.editItemSuccess(srcSkel,
                                           skelType=skelType,
                                           action="move",
                                           destNode=destSkel)
Ejemplo n.º 24
0
	def upload( self, node=None, *args, **kwargs ):
		try:
			canAdd = self.canAdd("leaf", node)
		except:
			canAdd = False
		if not canAdd:
			for upload in self.getUploads():
				upload.delete()
			raise errors.Forbidden()
		try:
			res = []
			if node:
				# The file is uploaded into a rootNode
				nodeSkel = self.editNodeSkel()
				if not nodeSkel.fromDB(node):
					for upload in self.getUploads():
						upload.delete()
					raise errors.NotFound()
				else:
					weak = False
					parentDir = str(node)
					parentRepo =  nodeSkel["parentrepo"]
			else:
				weak = True
				parentDir = None
				parentRepo = None
			# Handle the actual uploads
			for upload in self.getUploads():
				fileName = self.decodeFileName(upload.filename)
				if str(upload.content_type).startswith("image/"):
					try:
						servingURL = images.get_serving_url(upload.key())
						if request.current.get().isDevServer:
							# NOTE: changed for Ticket ADMIN-37
							servingURL = urlparse(servingURL).path
						elif servingURL.startswith("http://"):
							# Rewrite Serving-URLs to https if we are live
							servingURL = servingURL.replace("http://", "https://")
					except:
						servingURL = ""
				else:
					servingURL = ""
				fileSkel = self.addLeafSkel()
				try:
					# only fetching the file header or all if the file is smaller than 1M
					data = blobstore.fetch_data(upload.key(), 0, min(upload.size, 1000000))
					image = images.Image(image_data=data)
					height = image.height
					width = image.width
				except Exception, err:
					height = width = 0
					logging.error(
						"some error occurred while trying to fetch the image header with dimensions")
					logging.exception(err)

				fileSkel.setValues(
					{
						"name": utils.escapeString(fileName),
						"size": upload.size,
						"mimetype": utils.escapeString(upload.content_type),
						"dlkey": str(upload.key()),
						"servingurl": servingURL,
						"parentdir": parentDir,
						"parentrepo": parentRepo,
						"weak": weak,
						"width": width,
						"height": height
					}
				)
				fileSkel.toDB()
				res.append(fileSkel)
				self.onItemUploaded(fileSkel)
			# Uploads stored successfully, generate response to the client
			for r in res:
				logging.info("Upload successful: %s (%s)" % (r["name"], r["dlkey"]))
			user = utils.getCurrentUser()
			if user:
				logging.info("User: %s (%s)" % (user["name"], user["key"]))
			return( self.render.addItemSuccess( res ) )
Ejemplo n.º 25
0
    def pathToKey(self, key=None):
        """
		Returns the recursively expanded path through the Hierarchy from the root-node to a
		requested node.

		:param key: URL-safe key of the destination entity.
		:type key: str

		:returns: An nested dictionary with information about all nodes in the path from root \
		to the requested node.
		:rtype: dict
		"""
        def getName(obj):
            """
				Tries to return a suitable name for the given object.
			"""
            if "name" in obj:
                return obj["name"]

            skel = self.viewSkel()
            if "name" in skel:
                nameBone = getattr(skel, "name")

                if (isinstance(nameBone, baseBone)
                        and "languages" in dir(nameBone)
                        and nameBone.languages):
                    skel.setValues(obj)
                    return unicode(skel["name"])

            return None

        availableRepos = self.getAvailableRootNodes()
        if not key:
            try:
                key = availableRepos[0]["key"]
            except:
                raise errors.NotFound()

            keylist = []
        else:
            if str(key).isdigit():
                key = str(db.Key.from_path(self.viewSkel().kindName,
                                           long(key)))
            keylist = [key]

        if not self.canList(key):
            raise errors.Unauthorized()

        res = []

        lastChildren = []

        for x in range(0, 99):
            q = db.Query(self.viewSkel().kindName)
            q.filter("parententry =", str(key))
            q.order("sortindex")
            entryObjs = q.run(100)
            lastChildren = res[:]
            res = []

            for obj in entryObjs:
                if "parententry" in obj:
                    parent = str(obj["parententry"])
                else:
                    parent = None

                r = {
                    "name": getName(obj),
                    "key": str(obj.key()),
                    "parent": parent,
                    "hrk": obj["hrk"] if "hrk" in obj else None,
                    "active": (str(obj.key()) in keylist)
                }

                if r["active"]:
                    r["children"] = lastChildren

                res.append(r)

            if key in [x["key"] for x in availableRepos]:
                break
            else:
                item = db.Get(str(key))

                if item and "parententry" in item:
                    keylist.append(key)
                    key = item["parententry"]

                else:
                    break

        return res