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)
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 )
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)
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)
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")
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)
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])
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)
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 ""
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
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)
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")
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
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()
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)
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")
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
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))
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"]))
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
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)
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
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)
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 ) )
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