Beispiel #1
0
    def refresh(self, skel, boneName):
        from viur.core.skeleton import skeletonByKind

        def recreateFileEntryIfNeeded(val):
            # Recreate the (weak) filenetry referenced by the relation *val*. (ViUR2 might have deleted them)
            skel = skeletonByKind("file")()
            if skel.fromDB(val["key"]
                           ):  # This file-object exist, no need to recreate it
                return
            skel["key"] = val["key"]
            skel["name"] = val["name"]
            skel["mimetype"] = val["mimetype"]
            skel["dlkey"] = val["dlkey"]
            skel["size"] = val["size"]
            skel["width"] = val["width"]
            skel["height"] = val["height"]
            skel["weak"] = True
            skel["pending"] = False
            k = skel.toDB()

        from viur.core.modules.file import importBlobFromViur2
        super().refresh(skel, boneName)
        if conf.get("viur.viur2import.blobsource"):
            # Just ensure the file get's imported as it may not have an file entry
            val = skel[boneName]
            if isinstance(val, list):
                for x in val:
                    importBlobFromViur2(x["dest"]["dlkey"], x["dest"]["name"])
                    recreateFileEntryIfNeeded(x["dest"])
            elif isinstance(val, dict):
                if not "dest" in val:
                    return
                importBlobFromViur2(val["dest"]["dlkey"], val["dest"]["name"])
                recreateFileEntryIfNeeded(val["dest"])
Beispiel #2
0
	def login(self, skey="", token="", *args, **kwargs):
		# FIXME: Check if already logged in
		if not conf.get("viur.user.google.clientID"):
			raise errors.PreconditionFailed("Please configure 'viur.user.google.clientID' in your conf!")
		if not skey or not token:
			currentRequest.get().response.headers["Content-Type"] = "text/html"
			# Fixme: Render with Jinja2?
			tplStr = open("viur/core/template/vi_user_google_login.html", "r").read()
			tplStr = tplStr.replace("{{ clientID }}", conf["viur.user.google.clientID"])
			return tplStr
		if not securitykey.validate(skey, useSessionKey=True):
			raise errors.PreconditionFailed()
		userInfo = id_token.verify_oauth2_token(token, requests.Request(), conf["viur.user.google.clientID"])
		if userInfo['iss'] not in {'accounts.google.com', 'https://accounts.google.com'}:
			raise ValueError('Wrong issuer.')
		# Token looks valid :)
		uid = userInfo['sub']
		email = userInfo['email']
		addSkel = skeletonByKind(self.userModule.addSkel().kindName)  # Ensure that we have the full skeleton
		userSkel = addSkel().all().filter("uid =", uid).getSkel()
		if not userSkel:
			# We'll try again - checking if there's already an user with that email
			userSkel = addSkel().all().filter("name.idx =", email.lower()).getSkel()
			if not userSkel:  # Still no luck - it's a completely new user
				if not self.registrationEnabled:
					if userInfo.get("hd") and userInfo["hd"] in conf["viur.user.google.gsuiteDomains"]:
						print("User is from domain - adding account")
					else:
						logging.warning("Denying registration of %s", email)
						raise errors.Forbidden("Registration for new users is disabled")
				userSkel = addSkel()  # We'll add a new user
			userSkel["uid"] = uid
			userSkel["name"] = email
			isAdd = True
		else:
			isAdd = False
		now = datetime.datetime.now()
		if isAdd or (now - userSkel["lastlogin"]) > datetime.timedelta(minutes=30):
			# Conserve DB-Writes: Update the user max once in 30 Minutes
			userSkel["lastlogin"] = now
			#if users.is_current_user_admin():
			#	if not userSkel["access"]:
			#		userSkel["access"] = []
			#	if not "root" in userSkel["access"]:
			#		userSkel["access"].append("root")
			#	userSkel["gaeadmin"] = True
			#else:
			#	userSkel["gaeadmin"] = False
			assert userSkel.toDB()
		return self.userModule.continueAuthenticationFlow(self, userSkel["key"])
Beispiel #3
0
def sendEMail(dests, name, skel, extraFiles=[], cc=None, bcc=None, replyTo=None, *args, **kwargs):
	"""
	General purpose function for sending e-mail.

	This function allows for sending e-mails, also with generated content using the Jinja2 template engine.

	:type dests: str | list of str
	:param dests: Full-qualified recipient email addresses; These can be assigned as list, for multiple targets.

	:type name: str
	:param name: The name of a template from the appengine/emails directory, or the template string itself.

	:type skel: server.skeleton.Skeleton | dict | None
	:param skel: The data made available to the template. In case of a Skeleton, its parsed the usual way;\
	Dictionaries are passed unchanged.

	:type extraFiles: list of fileobjects
	:param extraFiles: List of **open** fileobjects to be sent within the mail as attachments

	:type cc: str | list of str
	:param cc: Carbon-copy recipients

	:type bcc: str | list of str
	:param bcc: Blind carbon-copy recipients

	:type replyTo: str
	:param replyTo: A reply-to email address
	"""
	if conf["viur.emailRecipientOverride"]:
		logging.warning("Overriding destination %s with %s", dests, conf["viur.emailRecipientOverride"])

		oldDests = dests
		if isinstance(oldDests, str):
			oldDests = [oldDests]

		newDests = conf["viur.emailRecipientOverride"]
		if isinstance(newDests, str):
			newDests = [newDests]

		dests = []
		for newDest in newDests:
			if newDest.startswith("@"):
				for oldDest in oldDests:
					dests.append(oldDest.replace(".", "_dot_").replace("@", "_at_") + newDest)
			else:
				dests.append(newDest)

	elif conf["viur.emailRecipientOverride"] is False:
		logging.warning("Sending emails disabled by config[viur.emailRecipientOverride]")
		return

	handler = conf.get("viur.emailHandler")

	if handler is None:
		handler = _GAE_sendEMail

	if not callable(handler):
		logging.warning("Invalid emailHandler configured, no email will be sent.")
		return False

	logging.debug("CALLING %s" % str(handler))

	return handler(dests, name, skel, extraFiles=extraFiles, cc=cc, bcc=bcc, replyTo=replyTo, *args, **kwargs)