def _send(msgData): server = smtplib.SMTP(*config.SMTP_SERVER) if config.SMTP_USE_TLS: server.ehlo() (code, errormsg) = server.starttls() if code != 220: raise MaKaCError( _("Can't start secure connection to SMTP server: %d, %s")%(code, errormsg)) if config.SMTP_LOGIN: login = config.SMTP_LOGIN password = config.SMTP_PASSWORD (code, errormsg) = server.login(login, password) if code != 235: raise MaKaCError( _("Can't login on SMTP server: %d, %s")%(code, errormsg)) to_addrs = msgData['toList'] | msgData['ccList'] | msgData['bccList'] try: Logger.get('mail').info('Sending email: To: {} / CC: {} / BCC: {}'.format( ', '.join(msgData['toList']) or 'None', ', '.join(msgData['ccList']) or 'None', ', '.join(msgData['bccList']) or 'None')) server.sendmail(msgData['fromAddr'], to_addrs, msgData['msg']) except smtplib.SMTPRecipientsRefused as e: raise MaKaCError('Email address is not valid: {}'.format(e.recipients)) finally: server.quit() Logger.get('mail').info('Mail sent to {}'.format(', '.join(to_addrs)))
def __readConfigFile(self): """initializes configuration parameters (Search order: indico.conf, default_values) IF YOU WANT TO CREATE NEW USER CONFIGURABLE OPTIONS: If you need to define a new configuration option you _need_ to specify it here with its default value and then you can put it in indico.conf. #### Indico will not see options that don't appear here #### """ self._configVars = {} from indico.legacy.errors import MaKaCError # When populating configuration variables indico.conf's values have priority config_path = get_config_path() config_vars = self.__load_config(config_path) self._configVars = { k: config_vars.get(k, default) for k, default in self.default_values.iteritems() } self._configVars['ConfigFilePath'] = config_path # options that are derived automatically self._deriveOptions() if ('XMLCacheDir' in config_vars and ('CacheDir' not in config_vars or config_vars['XMLCacheDir'] != config_vars['CacheDir'])): raise ValueError( 'XMLCacheDir has been renamed to CacheDir. Please update the config.' ) if self.getSanitizationLevel() not in range(4): raise MaKaCError( "Invalid SanitizationLevel value (%s). Valid values: 0, 1, 2, 3" % (self._configVars['SanitizationLevel'])) if self.getCSRFLevel() not in range(4): raise MaKaCError( "Invalid CSRFLevel value (%s). Valid values: 0, 1, 2, 3" % (self._configVars['CSRFLevel'])) if self.getStaticFileMethod() is not None and len( self.getStaticFileMethod()) != 2: raise MaKaCError( 'StaticFileMethod must be None, a string or a 2-tuple') if self.getDefaultTimezone() not in pytz.all_timezones_set: raise ValueError('Invalid default timezone: {}'.format( self.getDefaultTimezone())) if self.getAttachmentStorage() not in self.getStorageBackends(): raise ValueError( 'Attachment storage "{}" is not defined in storage backends'. format(self.getAttachmentStorage()))
def _getAnswer(self): """ To be overloaded. It should contain the code that does the actual business logic and returns a result (python JSON-serializable object). If this method is not overloaded, an exception will occur. If you don't want to return an answer, you should still implement this method with 'pass'. """ # This exception will happen if the _getAnswer method is not implemented in a derived class raise MaKaCError("No answer was returned")
def _redirect(self, targetURL, status=303): if isinstance(targetURL, Response): status = targetURL.status_code targetURL = targetURL.headers['Location'] else: targetURL = str(targetURL) if "\r" in targetURL or "\n" in targetURL: raise MaKaCError(_("http header CRLF injection detected")) self._responseUtil.redirect = (targetURL, status)
def _prepare(notification): fromAddr = notification.getFromAddr() replyAddr = getattr(notification, '_replyAddr', None) toList = set(filter(None, notification.getToList())) ccList = set(filter(None, notification.getCCList())) if hasattr(notification, "getBCCList"): bccList = set(notification.getBCCList()) else: bccList = set() if not toList and not ccList and not bccList: return msg = MIMEMultipart() msg["Subject"] = to_unicode(notification.getSubject()).strip() msg["From"] = fromAddr msg["To"] = ', '.join(toList) if toList else 'Undisclosed-recipients:;' if ccList: msg["Cc"] = ', '.join(ccList) if replyAddr: msg['Reply-to'] = replyAddr msg["Date"] = formatdate() try: ct = notification.getContentType() except Exception: ct = "text/plain" body = notification.getBody() if ct == "text/plain": part1 = MIMEText(body, "plain", "utf-8") elif ct == "text/html": part1 = MIMEText(body, "html", "utf-8") else: raise MaKaCError(_("Unknown MIME type: %s") % (ct)) msg.attach(part1) if hasattr(notification, 'getAttachments'): attachments = notification.getAttachments() or [] for attachment in attachments: part2 = MIMEApplication(attachment["binary"]) part2.add_header("Content-Disposition", 'attachment;filename="%s"' % (attachment["name"])) msg.attach(part2) return { 'msg': msg.as_string(), 'toList': toList, 'ccList': ccList, 'bccList': bccList, 'fromAddr': fromAddr, }
def _encodeUnicode(params): index = 0 for i in params: # params can be a list or a dictonary # we need to define k depending if it is a list or a dictonary # in order to be able to do such a operation: params[k] = something. if isinstance(params, dict): param = params[i] k = i else: param = i k = index # since we are looping a list, we need to increment the index to index += 1 # get the correct 'k' in the next iteration. if isinstance(param, str) and param != "": params[k] = encodeUnicode(param) if params[k] == "": raise MaKaCError( _("Your browser is using an encoding which is not recognized by Indico... Please make sure you set your browser encoding to utf-8" )) elif isinstance(param, list) or isinstance(param, dict): Sanitization._encodeUnicode(param)