def getAvailableRootNodes(self, *args, **kwargs): if utils.getCurrentUser(): repo = self.ensureOwnModuleRootNode() res = [{"name": _(u"Dateien"), "key": str(repo.key())}] return res return []
def canMove(self, skelType, node, destNode): """ Access control function for moving permission. Checks if the current user has the permission to move an entry. The default behavior is: - If no user is logged in, deleting is generally refused. - If the user has "root" access, deleting is generally allowed. - If the user has the modules "edit" permission (module-edit) enabled, \ moving is allowed. It should be overridden for a module-specific behavior. :param skelType: Defines the type of the node that shall be deleted. :type skelType: str :param node: URL-safe key of the node to be moved. :type node: str :param node: URL-safe key of the node where *node* should be moved to. :type node: str .. seealso:: :func:`move` :returns: True, if deleting entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return (False) if user["access"] and "root" in user["access"]: return (True) if user and user["access"] and "%s-edit" % self.moduleName in user[ "access"]: return (True) return (False)
def canEdit(self, skelType, skel): """ Access control function for modification permission. Checks if the current user has the permission to edit an entry. The default behavior is: - If no user is logged in, editing is generally refused. - If the user has "root" access, editing is generally allowed. - If the user has the modules "edit" permission (module-edit) enabled, editing is allowed. It should be overridden for a module-specific behavior. .. seealso:: :func:`edit` :param skelType: Defines the type of the node that shall be modified. :type skelType: str :param skel: The Skeleton that should be edited. :type skel: :class:`server.skeleton.Skeleton` :returns: True, if editing entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user and user["access"] and "%s-edit" % self.moduleName in user[ "access"]: return True return False
def canView(self): """ Access control function for viewing permission. Checks if the current user has the permission to view the singletons entry. The default behavior is: - If no user is logged in, viewing is generally refused. - If the user has "root" access, viewing is generally allowed. - If the user has the modules "view" permission (module-view) enabled, viewing is allowed. It should be overridden for a module-specific behavior. .. seealso:: :func:`view` :param skel: The Skeleton that should be viewed. :type skel: :class:`server.skeleton.Skeleton` :returns: True, if viewing is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return( False ) if user["access"] and "root" in user["access"]: return( True ) if user["access"] and "%s-view" % self.moduleName in user["access"]: return( True ) return( False )
def fromClient(self, valuesCache, name, data): """ Reads a value from the client. If this value is valid for this bone, store this value and return None. Otherwise our previous value is left unchanged and an error-message is returned. :param name: Our name in the skeleton :type name: String :param data: *User-supplied* request-data :type data: Dict :returns: None or String """ if request.current.get().isDevServer: #We dont enforce captchas on dev server return None user = utils.getCurrentUser() if user and "root" in user["access"]: # Don't bother trusted users with this (not supported by admin/vi anyways) return None if not "g-recaptcha-response" in data: return u"No Captcha given!" data = {"secret": self.privateKey, "remoteip": request.current.get().request.remote_addr, "response": data["g-recaptcha-response"] } response = urlfetch.fetch(url="https://www.google.com/recaptcha/api/siteverify", payload=urllib.urlencode( data ), method=urlfetch.POST, headers={"Content-Type": "application/x-www-form-urlencoded"} ) if json.loads(response.content.decode("UTF-8")).get("success"): return None return( u"Invalid Captcha" )
def canView(self, skel): """ Access control function for viewing permission. Checks if the current user has the permission to view an entry. The default behavior is: - If no user is logged in, viewing is generally refused. - If the user has "root" access, viewing is generally allowed. - If the user has the modules "view" permission (module-view) enabled, viewing is allowed. If skel is None, it's a check if the current user is allowed to retrieve the skeleton structure from this module (ie. there is or could be at least one entry that is visible to that user) It should be overridden for a module-specific behavior. .. seealso:: :func:`view` :param skel: The Skeleton that should be viewed. :type skel: :class:`server.skeleton.Skeleton` | None :returns: True, if viewing is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user["access"] and "%s-view" % self.moduleName in user["access"]: return True return False
def canAdd(self): """ Access control function for adding permission. Checks if the current user has the permission to add a new entry. The default behavior is: - If no user is logged in, adding is generally refused. - If the user has "root" access, adding is generally allowed. - If the user has the modules "add" permission (module-add) enabled, adding is allowed. It should be overridden for a module-specific behavior. .. seealso:: :func:`add` :returns: True, if adding entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False # root user is always allowed. if user["access"] and "root" in user["access"]: return True # user with add-permission is allowed. if user and user["access"] and "%s-add" % self.moduleName in user[ "access"]: return True return False
def canAdd(self, parent): """ Access control function for adding permission. Checks if the current user has the permission to add a new entry to *parent*. The default behavior is: - If no user is logged in, adding is generally refused. - If the user has "root" access, adding is generally allowed. - If the user has the modules "add" permission (module-add) enabled, adding is allowed. It should be overridden for a module-specific behavior. .. seealso:: :func:`add` :param parent: URL-safe key of the parent node under which the element shall be added. :type parent: str :returns: True, if adding entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user["access"] and "%s-add" % self.moduleName in user["access"]: return True return False
def canPreview(self): """ Access control function for preview permission. Checks if the current user has the permission to preview an entry. The default behavior is: - If no user is logged in, previewing is generally refused. - If the user has "root" access, previewing is generally allowed. - If the user has the modules "add" or "edit" permission (module-add, module-edit) enabled, \ previewing is allowed. It should be overridden for module-specific behavior. .. seealso:: :func:`preview` :returns: True, if previewing entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user["access"] and ("%s-edit" % self.moduleName in user["access"] or "%s-add" % self.moduleName in user["access"]): return True return False
def canList(self, parent): """ Access control function for listing permission. Checks if the current user has the permission to list the children of the given *parent*. The default behavior is: - If no user is logged in, listing is generally refused. - If the user has "root" access, listing is generally allowed. - If the user has the modules "view" permission (module-view) enabled, listing is allowed. It should be overridden for a module-specific behavior. .. seealso:: :func:`list` :param parent: URL-safe key of the parent. :type parent: str :returns: True, if listing is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user["access"] and "%s-view" % self.moduleName in user["access"]: return True return False
def canSetIndex(self, item, index): """ Access control function for changing order permission. Checks if the current user has the permission to change the ordering of an entry. The default behavior is: - If no user is logged in, any modification is generally refused. - If the user has "root" access, modification is generally allowed. - If the user has the modules "edit" or "add" permission (module-edit, module-add) enabled, \ modification is allowed. It should be overridden for a module-specific behavior. :param item: URL-safe key of the entry. :type item: str :param item: New sortindex for this item. :type item: float .. seealso:: :func:`setIndex` :returns: True, if changing the order of entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return (False) if user["access"] and "root" in user["access"]: return (True) if user["access"] and ("%s-edit" % self.moduleName in user["access"] or "%s-add" % self.moduleName in user["access"]): return (True) return (False)
def mailSkel(self): cuser = utils.getCurrentUser() assert cuser skel = messageSkel() skel.setBoneValue("user", cuser["key"]) return skel
def canReparent(self, item, dest): """ Access control function for item moving permission. Checks if the current user has the permission to move *item* to *dest*. The default behavior is: - If no user is logged in, any modification is generally refused. - If the user has "root" access, modification is generally allowed. - If the user has the modules "edit" permission (module-edit) enabled, moving is allowed. It should be overridden for a module-specific behavior. :param item: URL-safe key of the entry. :type item: str :param item: URL-safe key of the new parent to be moved to. :type item: float .. seealso:: :func:`reparent` :returns: True, if changing the order of entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user["access"] and "%s-edit" % self.moduleName in user["access"]: return True return False
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 canDelete(self, skel): """ Access control function for delete permission. Checks if the current user has the permission to delete an entry. The default behavior is: - If no user is logged in, deleting is generally refused. - If the user has "root" access, deleting is generally allowed. - If the user has the modules "deleting" permission (module-delete) enabled, \ deleting is allowed. It should be overridden for a module-specific behavior. :param skel: The Skeleton that should be deleted. :type skel: :class:`server.skeleton.Skeleton` .. seealso:: :func:`delete` :returns: True, if deleting entries is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user["access"] and "%s-delete" % self.moduleName in user["access"]: return True return False
def canCall(self): """ Checks wherever the current user can execute this task :returns: bool """ user = utils.getCurrentUser() return user is not None and "root" in user["access"]
def canEdit( self ): """ Access control function for modification permission. Checks if the current user has the permission to edit the singletons entry. The default behavior is: - If no user is logged in, editing is generally refused. - If the user has "root" access, editing is generally allowed. - If the user has the modules "edit" permission (module-edit) enabled, editing is allowed. It should be overridden for a module-specific behavior. .. seealso:: :func:`edit` :returns: True, if editing is allowed, False otherwise. :rtype: bool """ user = utils.getCurrentUser() if not user: return False if user["access"] and "root" in user["access"]: return True if user["access"] and "%s-edit" % self.moduleName in user["access"]: return True return False
def getCurrentUser(render): """ Jinja2 global: Returns the current user from the session, or None if not logged in. :return: A dict containing user data. Returns None if no user data is available. :rtype: dict """ return utils.getCurrentUser()
def mkDefered(func, self=__undefinedFlag_, *args, **kwargs): from server.utils import getCurrentUser try: req = request.current.get() except: #This will fail for warmup requests req = None if req is not None and "HTTP_X_APPENGINE_TASKRETRYCOUNT".lower() in [ x.lower() for x in os.environ.keys() ] and not "DEFERED_TASK_CALLED" in dir( req): #This is the deferred call req.DEFERED_TASK_CALLED = True #Defer recursive calls to an deferred function again. if self is __undefinedFlag_: return func(*args, **kwargs) else: return func(self, *args, **kwargs) else: try: funcPath = "%s/%s" % (self.modulePath, func.func_name) command = "rel" except: funcPath = "%s.%s" % (func.__name__, func.__module__) if self != __undefinedFlag_: args = ( self, ) + args #Reappend self to args, as this function is (hopefully) unbound command = "unb" taskargs = dict((x, kwargs.pop(("_%s" % x), None)) for x in ("countdown", "eta", "name", "target", "retry_options")) taskargs["url"] = "/_tasks/deferred" transactional = kwargs.pop("_transactional", False) taskargs["headers"] = {"Content-Type": "application/octet-stream"} queue = "default" # Try to preserve the important data from the current environment env = {"user": None} usr = getCurrentUser() if usr: env["user"] = { "key": usr["key"], "name": usr["name"], "access": usr["access"] } try: env["lang"] = request.current.get().language except AttributeError: #This isn't originating from a normal request pass if conf["viur.tasks.customEnvironmentHandler"]: # Check if this project relies on additional environmental variables and serialize them too assert isinstance(conf["viur.tasks.customEnvironmentHandler"], tuple) \ and len(conf["viur.tasks.customEnvironmentHandler"])==2 \ and callable(conf["viur.tasks.customEnvironmentHandler"][0]), \ "Your customEnvironmentHandler must be a tuple of two callable if set!" env["custom"] = conf["viur.tasks.customEnvironmentHandler"][0]( ) pickled = json.dumps((command, (funcPath, args, kwargs, env))) task = taskqueue.Task(payload=pickled, **taskargs) return task.add(queue, transactional=transactional)
def renderEmail(self, skel, tpl, dests, params=None,**kwargs ): """ Renders an email. :param skel: Skeleton or dict which data to supply to the template. :type skel: server.db.skeleton.Skeleton | dict :param tpl: Name of the email-template to use. If this string is longer than 100 characters, this string is interpreted as the template contents instead of its filename. :type tpl: str :param dests: Destination recipients. :type dests: list | str :param params: Optional data that will be passed unmodified to the template :type params: object :return: Returns a tuple consisting of email header and body. :rtype: str, str """ headers = {} user = utils.getCurrentUser() if isinstance(skel, BaseSkeleton): res = self.collectSkelData( skel ) elif isinstance(skel, list) and all([isinstance(x, BaseSkeleton) for x in skel]): res = [ self.collectSkelData( x ) for x in skel ] else: res = skel if len(tpl)<101: try: template = self.getEnv().from_string( codecs.open( "emails/"+tpl+".email", "r", "utf-8" ).read() ) except Exception as err: logging.exception(err) template = self.getEnv().get_template( tpl+".email" ) else: template = self.getEnv().from_string( tpl ) data = template.render(skel=res, dests=dests, user=user, params=params, **kwargs) body = False lineCount=0 for line in data.splitlines(): if lineCount>3 and body is False: body = "\n\n" if body != False: body += line+"\n" else: if line.lower().startswith("from:"): headers["from"]=line[ len("from:"):] elif line.lower().startswith("subject:"): headers["subject"]=line[ len("subject:"): ] elif line.lower().startswith("references:"): headers["references"]=line[ len("references:"):] else: body="\n\n" body += line lineCount += 1 return( headers, body )
def listFilter(self, query): query = super(Duty, self).listFilter(query) if not query: return None query.filter("kind", "duty") cuser = utils.getCurrentUser() if cuser and isinstance(self.render, htmlRender): query.mergeExternalFilter({"user.dest.key": cuser["key"]}) return query
def listFilter(self, query): query.filter("kind", "aircraft") if not query.getOrders(): query.order("sortindex") # All club aircraft are exposed, as they are not considered to be "private" if isinstance(self.render, htmlRender) or not utils.getCurrentUser(): query.filter("is_clubowned", True) return query return query
def execute(self, module, compact="", *args, **kwargs): usr = utils.getCurrentUser() if not usr: logging.warning("Don't know who to inform after rebuilding finished") notify = None else: notify = usr["name"] if module == "*": for module in listKnownSkeletons(): logging.info("Rebuilding search index for module '%s'" % module) processChunk(module, compact, None, notify=notify) else: processChunk(module, compact, None, notify=notify)
def editSkel(self, *args, **kwargs): skel = super(User, self).editSkel().clone() self.extendAccessRights(skel) skel.password = passwordBone( descr="Passwort", required=False ) user = utils.getCurrentUser() lockFields = not (user and "root" in user["access"]) # If we aren't root, make certain fields read-only skel.name.readOnly = lockFields skel.access.readOnly = lockFields skel.status.readOnly = lockFields return skel
def list(self, *args, **kwargs): cuser = utils.getCurrentUser() if cuser and "root" in cuser["access"]: return super(user, self).list(*args, **kwargs) # This is a restricted access query = self.listFilter( super(user, self).viewSkel().subSkel( "restricted").all().mergeExternalFilter(kwargs)) if query is None: raise errors.Unauthorized() res = query.fetch() return self.render.list(res)
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 onItemEdited( self, skel ): """ Hook function that is called after modifying the entry. It should be overridden for a module-specific behavior. The default is writing a log entry. :param skel: The Skeleton that has been modified. :type skel: :class:`server.skeleton.Skeleton` .. seealso:: :func:`edit` """ logging.info("Entry changed: %s" % skel["key"] ) user = utils.getCurrentUser() if user: logging.info("User: %s (%s)" % (user["name"], user["key"] ) )
def listFilter(self, query): query = super(Appointment, self).listFilter(query) if not query: return None query.filter("kind", "meeting") cuser = utils.getCurrentUser() if cuser and isinstance(self.render, htmlRender): user = conf["viur.mainApp"].user.viewSkel() if user.fromDB(cuser["key"]): query.filter("recipients IN", user["interests"]) return query
def onItemSetIndex(self, skel): """ Hook function that is called after setting a new index an entry. It should be overridden for a module-specific behavior. The default is writing a log entry. :param skel: The Skeleton that has got a new index. :type skel: :class:`server.skeleton.Skeleton` .. seealso:: :func:`setIndex` """ logging.info("Entry has a new index: %s" % skel["key"]) user = utils.getCurrentUser() if user: logging.info("User: %s (%s)" % (user["name"], user["key"]))
def onItemReparent(self, skel): """ Hook function that is called after reparenting an entry. It should be overridden for a module-specific behavior. The default is writing a log entry. :param skel: The Skeleton that has been reparented. :type skel: :class:`server.skeleton.Skeleton` .. seealso:: :func:`reparent` """ logging.debug("data: %r, %r", skel, skel.keys()) logging.info("Entry reparented: %s" % skel["key"]) user = utils.getCurrentUser() if user: logging.info("User: %s (%s)" % (user["name"], user["key"]))