示例#1
0
def importBlobFromViur2(dlKey, fileName):
    if not conf.get("viur.viur2import.blobsource"):
        return False
    existingImport = db.Get(db.Key("viur-viur2-blobimport", dlKey))
    if existingImport:
        if existingImport["success"]:
            return existingImport["dlurl"]
        return False
    if conf["viur.viur2import.blobsource"]["infoURL"]:
        try:
            importDataReq = urlopen(
                conf["viur.viur2import.blobsource"]["infoURL"] + dlKey)
        except:
            marker = db.Entity(db.Key("viur-viur2-blobimport", dlKey))
            marker["success"] = False
            marker["error"] = "Failed URL-FETCH 1"
            db.Put(marker)
            return False
        if importDataReq.status != 200:
            marker = db.Entity(db.Key("viur-viur2-blobimport", dlKey))
            marker["success"] = False
            marker["error"] = "Failed URL-FETCH 2"
            db.Put(marker)
            return False
        importData = json.loads(importDataReq.read())
        oldBlobName = conf["viur.viur2import.blobsource"][
            "gsdir"] + "/" + importData["key"]
        srcBlob = storage.Blob(
            bucket=bucket,
            name=conf["viur.viur2import.blobsource"]["gsdir"] + "/" +
            importData["key"])
    else:
        oldBlobName = conf["viur.viur2import.blobsource"]["gsdir"] + "/" + dlKey
        srcBlob = storage.Blob(
            bucket=bucket,
            name=conf["viur.viur2import.blobsource"]["gsdir"] + "/" + dlKey)
    if not srcBlob.exists():
        marker = db.Entity(db.Key("viur-viur2-blobimport", dlKey))
        marker["success"] = False
        marker["error"] = "Local SRC-Blob missing"
        marker["oldBlobName"] = oldBlobName
        db.Put(marker)
        return False
    bucket.rename_blob(srcBlob, "%s/source/%s" % (dlKey, fileName))
    marker = db.Entity(db.Key("viur-viur2-blobimport", dlKey))
    marker["success"] = True
    marker["old_src_key"] = dlKey
    marker["old_src_name"] = fileName
    marker["dlurl"] = utils.downloadUrlFor(dlKey, fileName, False, None)
    db.Put(marker)
    return marker["dlurl"]
示例#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:`onViewed`

		: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 = db.Key(self.editSkel().kindName, self.getKey())

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

        self.onViewed(skel)
        return self.render.view(skel)
示例#3
0
def validate(key: str, useSessionKey: bool) -> Union[bool, db.Entity]:
    """
		Validates a onetime securitykey

		:type key: str
		:param key: The key to validate
		:type useSessionKey: Bool
		:param useSessionKey: If True, we validate against the session's skey, otherwise we'll lookup an unbound key
		:returns: False if the key was not valid for whatever reasons, the data (given during createSecurityKey) as dictionary or True if the dict is empty.
	"""
    if useSessionKey:
        if key == "staticSessionKey":
            skeyHeaderValue = currentRequest.get().request.headers.get(
                "Sec-X-ViUR-StaticSKey")
            if skeyHeaderValue and currentSession.get(
            ).validateStaticSecurityKey(skeyHeaderValue):
                return True
        elif currentSession.get().validateSecurityKey(key):
            return True
        return False
    if not key:
        return False
    dbKey = db.Key(securityKeyKindName, key)
    dbObj = db.Get(dbKey)
    if dbObj:
        db.Delete(dbKey)
        if dbObj["until"] < datetime.now():  # This key has expired
            return False
        del dbObj["until"]
        if not dbObj:
            return True
        return dbObj
    return False
示例#4
0
    def storeEntry2(self, e, key):
        if not self._checkKey(key, export=False):
            raise errors.Forbidden()
        entry = pickle.loads(e.decode("HEX"))
        if not "key" in entry and "id" in entry:
            entry["key"] = entry["id"]
        for k in list(entry.keys())[:]:
            if isinstance(entry[k], str):
                entry[k] = entry[k].decode("UTF-8")
        key = db.Key(encoded=utils.normalizeKey(entry["key"]))

        dbEntry = db.Entity(kind=key.kind(),
                            parent=key.parent(),
                            id=key.id(),
                            name=key.name())  # maybe some more fixes here ?
        for k in entry.keys():
            if k != "key":
                val = entry[k]
                dbEntry[k] = val
        db.Put(dbEntry)
        if dbEntry.key().id():
            # Ensure the Datastore knows that it's id is in use
            datastore._GetConnection()._reserve_keys([dbEntry.key()])
        try:
            skel = skeletonByKind(key.kind())()
        except:
            logging.error("Unknown Skeleton - skipping")
        skel.fromDB(str(dbEntry.key()))
        skel.refresh()
        skel.toDB(clearUpdateTag=True)
示例#5
0
 def setKeyTxn(orderKey, idx):
     """Assigns the new order to the given order"""
     dbObj = db.Get(db.Key(orderKey))
     if not dbObj:
         return
     dbObj["idx"] = idx
     db.Put(dbObj)
示例#6
0
def doCheckForUnreferencedBlobs(cursor=None):
	def getOldBlobKeysTxn(dbKey):
		obj = db.Get(dbKey)
		res = obj["old_blob_references"] or []
		if obj["is_stale"]:
			db.Delete(dbKey)
		else:
			obj["has_old_blob_references"] = False
			obj["old_blob_references"] = []
			db.Put(obj)
		return res

	query = db.Query("viur-blob-locks").filter("has_old_blob_references", True).setCursor(cursor)
	for lockObj in query.run(100):
		oldBlobKeys = db.RunInTransaction(getOldBlobKeysTxn, lockObj.key)
		for blobKey in oldBlobKeys:
			if db.Query("viur-blob-locks").filter("active_blob_references =", blobKey).getEntry():
				# This blob is referenced elsewhere
				logging.info("Stale blob is still referenced, %s" % blobKey)
				continue
			# Add a marker and schedule it for deletion
			fileObj = db.Query("viur-deleted-files").filter("dlkey", blobKey).getEntry()
			if fileObj:  # Its already marked
				logging.info("Stale blob already marked for deletion, %s" % blobKey)
				return
			fileObj = db.Entity(db.Key("viur-deleted-files"))
			fileObj["itercount"] = 0
			fileObj["dlkey"] = str(blobKey)
			logging.info("Stale blob marked dirty, %s" % blobKey)
			db.Put(fileObj)
	newCursor = query.getCursor()
	if newCursor:
		doCheckForUnreferencedBlobs(newCursor)
示例#7
0
    def assignBillSequence(self, orderKey):
        """
			Assigns an unique order-order to the given order.
		"""
        def getKeyTxn(kindName, orderKey):
            """Generates and returns a new, unique Key"""
            seqObj = db.GetOrInsert(kindName,
                                    "viur_bill_sequences",
                                    count=1000)
            idx = seqObj["count"]
            seqObj["count"] += 1
            db.Put(seqObj)
            return str(idx)

        def setKeyTxn(orderKey, idx):
            """Assigns the new order to the given order"""
            dbObj = db.Get(db.Key(orderKey))
            if not dbObj:
                return
            dbObj["idx"] = idx
            db.Put(dbObj)

        dbObj = db.Get(db.Key(orderKey))
        if not dbObj:
            return

        idx = db.RunInTransaction(getKeyTxn,
                                  self.viewSkel().kindName, orderKey)
        db.RunInTransaction(setKeyTxn, orderKey, idx)
        self.billSequenceAvailable(orderKey)
示例#8
0
 def sofortStatus(self, *args, **kwargs):
     sortOrder = [
         "transaction", "user_id", "project_id", "sender_holder",
         "sender_account_number", "sender_bank_code", "sender_bank_name",
         "sender_bank_bic", "sender_iban", "sender_country_id",
         "recipient_holder", "recipient_account_number",
         "recipient_bank_code", "recipient_bank_name", "recipient_bank_bic",
         "recipient_iban", "recipient_country_id",
         "international_transaction", "amount", "currency_id", "reason_1",
         "reason_2", "security_criteria", "user_variable_0",
         "user_variable_1", "user_variable_2", "user_variable_3",
         "user_variable_4", "user_variable_5", "created"
     ]
     hashstr = "|".join([kwargs[key] for key in sortOrder] +
                        [conf["sofort"]["notificationpassword"]])
     if hashlib.sha512(
             hashstr.encode("utf-8")).hexdigest() != kwargs["hash"]:
         logging.error(
             "RECEIVED INVALID HASH FOR sofort (%s!=%s)" % (hashlib.sha512(
                 hashstr.encode("utf-8")).hexdigest(), kwargs["hash"]))
         return ("INVALID HASH")
     order = db.Get(db.Key(kwargs["user_variable_0"]))
     if not order:
         logging.error("RECEIVED UNKNOWN ORDER by sofort (%s)" %
                       (kwargs["user_variable_0"]))
         return ("UNKNOWN ORDER")
     if ("%.2f" % order["price"]) != kwargs["amount"]:
         logging.error("RECEIVED INVALID AMOUNT PAYED sofort (%s!=%s)" %
                       (order["price"], kwargs["amount"]))
         return ("INVALID AMOUNT")
     self.orderHandler.setPayed(kwargs["user_variable_0"])
     return ("OKAY")
示例#9
0
def validate(key: str, useSessionKey: bool) -> Union[bool, db.Entity]:
    """
		Validates a security key. If useSessionKey is true, the key is expected to be the sessions current security key
		(or it's static security key). Otherwise it must be a key created with a duration (so it's not session
		dependent)

		:param key: The key to validate
		:param useSessionKey: If True, we validate against the session's skey, otherwise we'll lookup an unbound key
		:returns: False if the key was not valid for whatever reasons, the data (given during createSecurityKey) as
			dictionary or True if the dict is empty (or :param:useSessionKey was true).
	"""
    if useSessionKey:
        if key == "staticSessionKey":
            skeyHeaderValue = currentRequest.get().request.headers.get(
                "Sec-X-ViUR-StaticSKey")
            if skeyHeaderValue and currentSession.get(
            ).validateStaticSecurityKey(skeyHeaderValue):
                return True
        elif currentSession.get().validateSecurityKey(key):
            return True
        return False
    if not key:
        return False
    dbKey = db.Key(securityKeyKindName, key)
    dbObj = db.Get(dbKey)
    if dbObj:
        db.Delete(dbKey)
        until = dbObj["until"]
        if until < utcNow():  # This key has expired
            return False
        del dbObj["until"]
        if not dbObj:
            return True
        return dbObj
    return False
示例#10
0
	def load(self, req):
		"""
			Initializes the Session.

			If the client supplied a valid Cookie, the session is read
			from the memcache/datastore, otherwise a new, empty session
			will be initialized.
		"""
		self.changed = False
		self.isInitial = False
		self.cookieKey = None
		self.sslKey = None
		self.staticSecurityKey = None
		self.securityKey = None
		self.session = {}
		if self.cookieName in req.request.cookies:
			cookie = str(req.request.cookies[self.cookieName])
			data = db.Get(db.Key(self.kindName, cookie))
			if data:  # Loaded successfully from Memcache
				if data["lastseen"] < time() - conf["viur.session.lifeTime"]:
					# This session is too old
					self.reset()
					return False
				self.session = data["data"]
				self.staticSecurityKey = data["staticSecurityKey"]
				self.securityKey = data["securityKey"]
				self.cookieKey = cookie
				if data["lastseen"] < time() - 5 * 60:  # Refresh every 5 Minutes
					self.changed = True
			else:
				# We could not load from firebase; create a new one
				self.reset()
		else:
			self.reset()
示例#11
0
        def txn(orderKey, state, removeState):
            dbObj = db.Get(db.Key(orderKey))
            if not dbObj:
                return

            dbObj["state_%s" % state] = "1" if not removeState else "0"
            dbObj["changedate"] = datetime.now()
            db.Put(dbObj)
示例#12
0
 def wrapF(self, *args, **kwargs) -> Union[str, bytes]:
     currReq = currentRequest.get()
     if conf["viur.disableCache"] or currReq.disableCache:
         # Caching disabled
         if conf["viur.disableCache"]:
             logging.debug("Caching is disabled by config")
         return f(self, *args, **kwargs)
     # How many arguments are part of the way to the function called (and how many are just *args)
     offset = -len(currReq.args) or len(currReq.pathlist)
     path = "/" + "/".join(currReq.pathlist[:offset])
     if not path in urls:
         # This path (possibly a sub-render) should not be cached
         logging.debug("Not caching for %s" % path)
         return f(self, *args, **kwargs)
     key = keyFromArgs(f, userSensitive, languageSensitive, evaluatedArgs,
                       path, args, kwargs)
     if not key:
         # Something is wrong (possibly the parameter-count)
         # Let's call f, but we knew already that this will clash
         return f(self, *args, **kwargs)
     dbRes = db.Get(db.Key(viurCacheName, key))
     if dbRes is not None:
         if not maxCacheTime \
          or dbRes["creationtime"] > utils.utcNow() - timedelta(seconds=maxCacheTime):
             # We store it unlimited or the cache is fresh enough
             logging.debug("This request was served from cache.")
             currReq.response.headers['Content-Type'] = dbRes[
                 "content-type"]
             return dbRes["data"]
     # If we made it this far, the request wasn't cached or too old; we need to rebuild it
     oldAccessLog = db.startDataAccessLog()
     try:
         res = f(self, *args, **kwargs)
     finally:
         accessedEntries = db.endDataAccessLog(oldAccessLog)
     dbEntity = db.Entity(db.Key(viurCacheName, key))
     dbEntity["data"] = res
     dbEntity["creationtime"] = utils.utcNow()
     dbEntity["path"] = path
     dbEntity["content-type"] = currReq.response.headers['Content-Type']
     dbEntity["accessedEntries"] = list(accessedEntries)
     dbEntity.exclude_from_indexes = ["data", "content-type"
                                      ]  # We can save 2 DB-Writs :)
     db.Put(dbEntity)
     logging.debug("This request was a cache-miss. Cache has been updated.")
     return res
示例#13
0
			def exchangeSecurityKey():
				dbSession = db.Get(db.Key(self.kindName, self.cookieKey))
				if not dbSession:  # Should not happen (except if session.reset has been called in the same request)
					return False
				if dbSession["securityKey"] != key:  # Race-Condidtion: That skey has been used in another instance
					return False
				dbSession["securityKey"] = utils.generateRandomString(13)
				db.Put(dbSession)
				return dbSession["securityKey"]
示例#14
0
	def ensureOwnModuleRootNode(self) -> db.Entity:
		"""
		Ensures, that general root-node for the current module exists.
		If no root-node exists yet, it will be created.

		:returns: The entity of the root-node.
		"""
		key = "rep_module_repo"
		kindName = self.viewSkel("node").kindName
		return db.GetOrInsert(db.Key(kindName, key), creationdate=datetime.datetime.now(), rootNode=1)
示例#15
0
 def updateTxn(cacheKey):
     key = db.Key(self.rateLimitKind, cacheKey)
     obj = db.Get(key)
     if obj is None:
         obj = db.Entity(key)
         obj["value"] = 0
     obj["value"] += 1
     obj["expires"] = utils.utcNow() + timedelta(minutes=2 *
                                                 self.minutes)
     db.Put(obj)
示例#16
0
 def getSofortURL(self, orderID):
     order = db.Get(db.Key(orderID))
     hashstr = "%s|%s|||||%.2f|EUR|%s||%s||||||%s" % (
         conf["sofort"]["userid"], conf["sofort"]["projectid"],
         float(order["price"]), str(order.key()), str(
             order.key()), conf["sofort"]["projectpassword"])
     hash = hashlib.sha512(hashstr.encode("UTF-8")).hexdigest()
     returnURL = "https://www.sofortueberweisung.de/payment/start?user_id=%s&project_id=%s&amount=%.2f&currency_id=EUR&reason_1=%s&user_variable_0=%s&hash=%s" % (
         conf["sofort"]["userid"], conf["sofort"]["projectid"],
         float(order["price"]), str(order.key()), str(order.key()), hash)
     return (returnURL)
示例#17
0
def flushCache(prefix: str = None,
               key: Union[db.Key, None] = None,
               kind: Union[str, None] = None):
    """
		Flushes the cache. Its possible the flush only a part of the cache by specifying
		the path-prefix. The path is equal to the url that caused it to be cached (eg /page/view) and must be one
		listed in the 'url' param of :meth:`viur.core.cache.enableCache`.

		:param prefix: Path or prefix that should be flushed.
		:param key: Flush all cache entries which may contain this key. Also flushes entries
			which executed a query over that kind.
		:param kind: Flush all cache entries which executed a query over that kind.

		Examples:
			- "/" would flush the main page (and only that),
			- "/*" everything from the cache, "/page/*" everything from the page-module (default render),
			- and "/page/view/*" only that specific subset of the page-module.
	"""
    if prefix is None and key is None and kind is None:
        prefix = "/*"
    if prefix is not None:
        items = db.Query(viurCacheName).filter("path =",
                                               prefix.rstrip("*")).iter()
        for item in items:
            db.Delete(item)
        if prefix.endswith("*"):
            items = db.Query(viurCacheName) \
             .filter("path >", prefix.rstrip("*")) \
             .filter("path <", prefix.rstrip("*") + u"\ufffd") \
             .iter()
            for item in items:
                db.Delete(item)
        logging.debug(
            "Flushing cache succeeded. Everything matching \"%s\" is gone." %
            prefix)
    if key is not None:
        items = db.Query(viurCacheName).filter("accessedEntries =", key).iter()
        for item in items:
            logging.info("Deleted cache entry %s", item["path"])
            db.Delete(item.key)
        if not isinstance(key, db.Key):
            key = db.Key(encoded=key)
        items = db.Query(viurCacheName).filter("accessedEntries =",
                                               key.kind).iter()
        for item in items:
            logging.info("Deleted cache entry %s", item["path"])
            db.Delete(item.key)
    if kind is not None:
        items = db.Query(viurCacheName).filter("accessedEntries =",
                                               kind).iter()
        for item in items:
            logging.info("Deleted cache entry %s", item["path"])
            db.Delete(item.key)
示例#18
0
    def getContents(self):
        """
		Returns the entity of this singleton application as :class:`server.skeleton.Skeleton` object.

		:returns: The content as Skeleton provided by :func:`viewSkel`.
		"""
        skel = self.viewSkel()
        key = db.Key(self.viewSkel().kindName, self.getKey())

        if not skel.fromDB(key):
            return None

        return skel
示例#19
0
    def ensureOwnModuleRootNode(self):
        """
		Ensures, that general root-node for the current module exists.
		If no root-node exists yet, it will be created.

		:returns: The entity of the root-node.
		:rtype: :class:`server.db.Entity`
		"""
        key = "rep_module_repo"
        kindName = self.viewSkel("node").kindName
        return db.GetOrInsert(db.Key(kindName, key),
                              creationdate=utils.utcNow(),
                              rootNode=1)
示例#20
0
	def _rewriteQuery(self, name, skel, dbFilter, rawFilter):
		"""
			Rewrites a datastore query to operate on "viur-relations" instead of the original kind.
			This is needed to perform relational queries on n:m relations.
		"""
		origFilter = dbFilter.filters
		origSortOrders = dbFilter.orders
		if isinstance(origFilter, list):
			raise NotImplementedError(
				"Doing a relational Query with multiple=True and \"IN or !=\"-filters is currently unsupported!")
		dbFilter.filters = {}
		dbFilter.kind = "viur-relations"
		dbFilter.filter("viur_src_kind =", skel.kindName)
		dbFilter.filter("viur_dest_kind =", self.kind)
		dbFilter.filter("viur_src_property", name)
		# FIXME vvvv
		# if dbFilter._origCursor:  # Merge the cursor in again (if any)
		#	dbFilter.cursor(dbFilter._origCursor)
		if origFilter:
			for k, v in origFilter.items():  # Merge old filters in
				# Ensure that all non-relational-filters are in parentKeys
				if k == db.KEY_SPECIAL_PROPERTY:
					# We must process the key-property separately as its meaning changes as we change the datastore kind were querying
					if isinstance(v, list) or isinstance(v, tuple):
						logging.warning(
							"Invalid filtering! Doing an relational Query on %s with multiple key= filters is unsupported!" % (
								name))
						raise RuntimeError()
					if not isinstance(v, db.Key):
						v = db.Key(v)
					dbFilter.ancestor(v)
					continue
				boneName = k.split(".")[0].split(" ")[0]
				if boneName not in self.parentKeys and boneName != "__key__":
					logging.warning(
						"Invalid filtering! %s is not in parentKeys of RelationalBone %s!" % (boneName, name))
					raise RuntimeError()
				dbFilter.filter("src.%s" % k, v)
		orderList = []
		for k, d in origSortOrders:  # Merge old sort orders in
			if k == db.KEY_SPECIAL_PROPERTY:
				orderList.append(("%s" % k, d))
			elif not k in self.parentKeys:
				logging.warning("Invalid filtering! %s is not in parentKeys of RelationalBone %s!" % (k, name))
				raise RuntimeError()
			else:
				orderList.append(("src.%s" % k, d))
		if orderList:
			dbFilter.order(*orderList)
		return name, skel, dbFilter, rawFilter
示例#21
0
    def save(self, req):
        """
			Writes the session to the memcache/datastore.

			Does nothing, if the session hasn't been changed in the current request.
		"""
        try:
            if self.changed or self.isInitial:
                serialized = base64.b64encode(
                    pickle.dumps(self.session,
                                 protocol=pickle.HIGHEST_PROTOCOL))
                # Get the current user id
                try:
                    # Check for our custom user-api
                    userid = conf["viur.mainApp"].user.getCurrentUser()["key"]
                except:
                    userid = None
                if self.isInitial and not req.isSSLConnection:
                    # Reset the Secure only key to None - we can't set it anyway.
                    self.sslKey = None
                try:
                    dbSession = db.Entity(db.Key(self.kindName, self.httpKey))
                    dbSession["data"] = serialized
                    dbSession["sslkey"] = self.sslKey
                    dbSession["staticSecurityKey"] = self.staticSecurityKey
                    dbSession["securityKey"] = self.securityKey
                    dbSession["lastseen"] = time()
                    # Store the userid inside the sessionobj, so we can kill specific sessions if needed
                    dbSession["user"] = str(userid) or "guest"
                    db.Put(dbSession)
                except Exception as e:
                    logging.exception(e)
                    raise  # FIXME
                    pass
                if self.sameSite:
                    sameSite = "; SameSite=%s" % self.sameSite
                else:
                    sameSite = ""
                req.response.headerlist.append(
                    ("Set-Cookie", "%s=%s; Max-Age=99999; Path=/; HttpOnly%s" %
                     (self.plainCookieName, self.httpKey, sameSite)))
                if req.isSSLConnection:
                    req.response.headerlist.append(
                        ("Set-Cookie",
                         "%s=%s; Max-Age=99999; Path=/; Secure; HttpOnly%s" %
                         (self.sslCookieName, self.sslKey, sameSite)))
        except Exception as e:
            raise  # FIXME
            logging.exception(e)
示例#22
0
def normalizeKey(key: Union[None, 'db.KeyClass']) -> Union[None, 'db.KeyClass']:
	"""
		Normalizes a datastore key (replacing _application with the current one)

		:param key: Key to be normalized.

		:return: Normalized key in string representation.
	"""
	if key is None:
		return None
	if key.parent:
		parent = normalizeKey(key.parent)
	else:
		parent = None
	return db.Key(key.kind, key.id_or_name, parent=parent)
示例#23
0
    def load(self, req):
        """
			Initializes the Session.

			If the client supplied a valid Cookie, the session is read
			from the memcache/datastore, otherwise a new, empty session
			will be initialized.
		"""
        self.changed = False
        self.isInitial = False
        self.httpKey = None
        self.sslKey = None
        self.staticSecurityKey = None
        self.securityKey = None
        self.session = {}
        if self.plainCookieName in req.request.cookies:
            cookie = str(req.request.cookies[self.plainCookieName])
            try:
                data = db.Get(db.Key(self.kindName, cookie))
            except:
                raise  # FIXME
                return False
            if data:  # Loaded successfully from Memcache
                if data["lastseen"] < time() - conf["viur.session.lifeTime"]:
                    # This session is too old
                    self.reset()
                    return False

                self.session = pickle.loads(base64.b64decode(data["data"]))
                self.sslKey = data["sslkey"]
                self.staticSecurityKey = data["staticSecurityKey"]
                self.securityKey = data["securityKey"]
                self.httpKey = cookie
                if data["lastseen"] < time(
                ) - 5 * 60:  # Refresh every 5 Minutes
                    self.changed = True
            else:
                # We could not load from firebase; create a new one
                self.reset()
            if req.isSSLConnection and self.sslKey and not req.request.cookies.get(
                    self.sslCookieName) == self.sslKey:
                logging.critical(
                    "Possible session hijack attempt! Session dropped.")
                self.reset()
                return False
            return True
        else:
            self.reset()
示例#24
0
	def startProcessing(self, step, orderID):
		def setTokenTxn(key, token):
			order = db.Get(key)
			if not order:
				return
			order["paypal_token"] = urllib.unquote(token)
			db.Put(order)

		paypal = PayPal.PayPalHandler()
		key = db.Key(orderID)
		order = db.Get(key)
		if not order:
			return
		token = paypal.SetExpressCheckout("%.2f" % order["price"])
		db.RunInTransaction(setTokenTxn, key, token)
		raise (errors.Redirect(paypal.getPayURL(token)))
示例#25
0
def shortKey(render, val):
	"""
	Jinja2 filter: Make a shortkey from an entity-key.

	:param val: Entity-key as string.
	:type val: str

	:returns: Shortkey on success, None on error.
	:rtype: str
	"""

	try:
		k = db.Key(encoded=str(val))
		return k.id_or_name()
	except:
		return None
示例#26
0
    def calculateOrderSum(self, step, orderKey, *args, **kwargs):
        """
		Calculates the final price for this order.
		This function *must* be called before any attempt is made to start a payment process.


		:param step: Current step within the ordering process
		:type step: int

		:param orderKey: order to calculate the price for
		:type orderKey: str
		"""
        price = sum([x[3] for x in self.getBillItems(orderKey)])
        orderObj = db.Get(db.Key(str(orderKey)))
        orderObj["price"] = price
        db.Put(orderObj)
示例#27
0
    def edit(self, *args, **kwargs):
        """
		Modify the existing entry, and render the entry, eventually with error notes on incorrect data.

		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 singleton's entity before it is modified.

		.. seealso:: :func:`editSkel`, :func:`onEdited`, :func:`canEdit`

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

		: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 "skey" in kwargs:
            skey = kwargs["skey"]
        else:
            skey = ""

        skel = self.editSkel()

        if not self.canEdit():
            raise errors.Unauthorized()

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

        if not skel.fromDB(
                key):  # Its not there yet; we need to set the key again
            skel["key"] = key
        if (len(kwargs) == 0  # no data supplied
                or skey == ""  # no skey provided
                or not skel.fromClient(
                    kwargs)  # failure on reading into the bones
                or ("bounce" in kwargs
                    and kwargs["bounce"] == "1")):  # review before changing
            return self.render.edit(skel)

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

        skel.toDB()
        self.onEdited(skel)
        return self.render.editSuccess(skel)
示例#28
0
	def filterHook(self, name, query, param, value):  # FIXME
		"""
			Hook installed by buildDbFilter.
			This rewrites all filters added to the query after buildDbFilter has been run to match the
			layout of our viur-relations index.
			Also performs sanity checks wherever this query is possible at all.
		"""
		if param.startswith("src.") or param.startswith("dest.") or param.startswith("viur_"):
			# This filter is already valid in our relation
			return (param, value)
		if param.startswith("%s." % name):
			# We add a constrain filtering by properties of the referenced entity
			refKey = param.replace("%s." % name, "")
			if " " in refKey:  # Strip >, < or = params
				refKey = refKey[:refKey.find(" ")]
			if refKey not in self.refKeys:
				logging.warning("Invalid filtering! %s is not in refKeys of RelationalBone %s!" % (refKey, name))
				raise RuntimeError()
			if self.multiple:
				return (param.replace("%s." % name, "dest."), value)
			else:
				return (param, value)
		else:
			# We filter by a property of this entity
			if not self.multiple:
				# Not relational, not multiple - nothing to do here
				return (param, value)
			# Prepend "src."
			srcKey = param
			if " " in srcKey:
				srcKey = srcKey[: srcKey.find(" ")]  # Cut <, >, and =
			if srcKey == db.KEY_SPECIAL_PROPERTY:  # Rewrite key= filter as its meaning has changed
				if isinstance(value, list) or isinstance(value, tuple):
					logging.warning(
						"Invalid filtering! Doing an relational Query on %s with multiple key= filters is unsupported!" % (
							name))
					raise RuntimeError()
				if not isinstance(value, db.Key):
					value = db.Key(value)
				query.ancestor(value)
				return (None)
			if srcKey not in self.parentKeys:
				logging.warning("Invalid filtering! %s is not in parentKeys of RelationalBone %s!" % (srcKey, name))
				raise RuntimeError()
			return ("src.%s" % param, value)
示例#29
0
    def save(self, req):
        """
			Writes the session to the datastore.

			Does nothing, if the session hasn't been changed in the current request.
		"""
        try:
            if self.changed or self.isInitial:
                if not (req.isSSLConnection or req.isDevServer
                        ):  # We will not issue sessions over http anymore
                    return False
                # Get the current user id
                try:
                    # Check for our custom user-api
                    userid = conf["viur.mainApp"].user.getCurrentUser()["key"]
                except:
                    userid = None
                try:
                    dbSession = db.Entity(db.Key(self.kindName,
                                                 self.cookieKey))
                    dbSession["data"] = db.fixUnindexableProperties(
                        self.session)
                    dbSession["staticSecurityKey"] = self.staticSecurityKey
                    dbSession["securityKey"] = self.securityKey
                    dbSession["lastseen"] = time()
                    # Store the userid inside the sessionobj, so we can kill specific sessions if needed
                    dbSession["user"] = str(userid) or "guest"
                    dbSession.exclude_from_indexes = ["data"]
                    db.Put(dbSession)
                except Exception as e:
                    logging.exception(e)
                    raise  # FIXME
                    pass
                sameSite = "; SameSite=%s" % self.sameSite if self.sameSite else ""
                secure = "; Secure" if not req.isDevServer else ""
                maxAge = "; Max-Age=%s" % conf[
                    "viur.session.lifeTime"] if not self.sessionCookie else ""
                req.response.headerlist.append(
                    ("Set-Cookie", "%s=%s; Path=/; HttpOnly%s%s%s" %
                     (self.cookieName, self.cookieKey, sameSite, secure,
                      maxAge)))
        except Exception as e:
            raise  # FIXME
            logging.exception(e)
示例#30
0
def create(duration: Union[None, int] = None, **kwargs) -> str:
    """
		Creates a new onetime Securitykey or returns the current sessions csrf-token.
		The custom data (given as keyword arguments) that can be stored with the key if :param:duration is set must
		be serializable by the datastore.

		:param duration: Make this key valid for a fixed timeframe (and independent of the current session)
		:returns: The new onetime key
	"""
    if not duration:
        return currentSession.get().getSecurityKey()
    key = generateRandomString()
    duration = int(duration)
    dbObj = db.Entity(db.Key(securityKeyKindName, key))
    for k, v in kwargs.items():
        dbObj[k] = v
    dbObj["until"] = utcNow() + timedelta(seconds=duration)
    db.Put(dbObj)
    return key