def send_pgp_alerts(self, node_desc, receiver_desc, notification_settings): fakeevent = OD() fakeevent.type = u'pgp_expiration_alert' fakeevent.node_info = node_desc fakeevent.context_info = None fakeevent.steps_info = None fakeevent.receiver_info = receiver_desc fakeevent.tip_info = None fakeevent.subevent_info = None body = Templating().format_template( notification_settings['pgp_alert_mail_template'], fakeevent) title = Templating().format_template( notification_settings['pgp_alert_mail_title'], fakeevent) to_address = receiver_desc['mail_address'] message = MIME_mail_build(GLSetting.memory_copy.notif_source_name, GLSetting.memory_copy.notif_source_email, to_address, to_address, title, body) yield sendmail(authentication_username=GLSetting.memory_copy.notif_username, authentication_password=GLSetting.memory_copy.notif_password, from_address=GLSetting.memory_copy.notif_source_email, to_address=to_address, message_file=message, smtp_host=GLSetting.memory_copy.notif_server, smtp_port=GLSetting.memory_copy.notif_port, security=GLSetting.memory_copy.notif_security, event=None)
def get(self, rtip_id): tip_export = yield get_tip_export(self.request.tid, self.current_user.user_id, rtip_id, self.request.language) if tip_export['crypto_tip_prv_key']: tip_export['tip'] = yield deferToThread( decrypt_tip, self.current_user.cc, tip_export['crypto_tip_prv_key'], tip_export['tip']) for file_dict in tip_export['tip']['rfiles'] + tip_export['tip'][ 'wbfiles']: if file_dict.get('status', '') == 'encrypted' or file_dict.get('forged'): continue tip_prv_key = GCE.asymmetric_decrypt( self.current_user.cc, tip_export['crypto_tip_prv_key']) file_dict['fo'] = GCE.streaming_encryption_open( 'DECRYPT', tip_prv_key, file_dict['path']) del file_dict['path'] for file_dict in tip_export['tip']['rfiles']: file_dict['name'] = 'files/' + file_dict['name'] if file_dict.get('status', '') == 'encrypted': file_dict['name'] += '.pgp' for file_dict in tip_export['tip']['wbfiles']: file_dict[ 'name'] = 'files_attached_from_recipients/' + file_dict['name'] tip_export['comments'] = tip_export['tip']['comments'] tip_export['messages'] = tip_export['tip']['messages'] files = tip_export['tip']['rfiles'] + tip_export['tip']['wbfiles'] del tip_export['tip']['rfiles'], tip_export['tip']['wbfiles'] export_template = Templating().format_template( tip_export['notification']['export_template'], tip_export).encode() export_template = msdos_encode(export_template.decode()).encode() files.append({ 'fo': BytesIO(export_template), 'name': 'data.txt', 'forged': True }) self.request.setHeader(b'X-Download-Options', b'noopen') self.request.setHeader(b'Content-Type', b'application/octet-stream') self.request.setHeader(b'Content-Disposition', b'attachment; filename="submission.zip"') self.zip_stream = iter(ZipStream(files)) yield ZipStreamProducer(self, self.zip_stream).start()
def ping_mail_flush(self, notification_settings, receivers_synthesis): """ TODO This function should be implemented as a clean and testable plugin in the way defined in plugin/base.py and plugin/notification.py, and/or is the opportunity to review these classes, at the moment is a simplified version that just create a ping email and send it via sendmail. """ for _, data in receivers_synthesis.iteritems(): receiver_dict, winks = data receiver_name = receiver_dict['name'] receiver_email = receiver_dict['ping_mail_address'] fakeevent = OD() fakeevent.type = u'ping_mail' fakeevent.node_info = None fakeevent.context_info = None fakeevent.receiver_info = receiver_dict fakeevent.tip_info = None fakeevent.subevent_info = {'counter': winks} body = Templating().format_template( notification_settings['ping_mail_template'], fakeevent) title = Templating().format_template( notification_settings['ping_mail_title'], fakeevent) # so comfortable for a developer!! :) source_mail_name = GLSettings.developer_name if GLSettings.devel_mode \ else GLSettings.memory_copy.notif_source_name message = MIME_mail_build(source_mail_name, GLSettings.memory_copy.notif_source_email, receiver_name, receiver_email, title, body) fakeevent2 = OD() fakeevent2.type = "Ping mail for %s (%d info)" % (receiver_email, winks) return sendmail(authentication_username=GLSettings.memory_copy.notif_username, authentication_password=GLSettings.memory_copy.notif_password, from_address= GLSettings.memory_copy.notif_source_email, to_address= [receiver_email], message_file=message, smtp_host=GLSettings.memory_copy.notif_server, smtp_port=GLSettings.memory_copy.notif_port, security=GLSettings.memory_copy.notif_security, event=fakeevent2)
def get_tip_export(store, user_id, rtip_id, language): rtip = db_access_rtip(store, user_id, rtip_id) receiver = rtip.receiver export_dict = { 'type': u'export_template', 'node': db_admin_serialize_node(store, language), 'notification': db_get_notification(store, language), 'tip': serialize_rtip(store, rtip, language), 'context': admin_serialize_context(store, rtip.internaltip.context, language), 'receiver': admin_serialize_receiver(receiver, language), 'comments': db_get_comment_list(rtip), 'messages': db_get_message_list(rtip), 'files': [] } export_template = Templating().format_template(export_dict['notification']['export_template'], export_dict).encode('utf-8') export_dict['files'].append({'buf': export_template, 'name': "data.txt"}) for rf in store.find(models.ReceiverFile, models.ReceiverFile.receivertip_id == rtip_id): rf.downloads += 1 file_dict = serialize_receiver_file(rf) file_dict['name'] = 'files/' + file_dict['name'] export_dict['files'].append(copy.deepcopy(file_dict)) return export_dict
def post(self): user = yield get_user_settings(self.current_user.user_id, GLSettings.memory_copy.default_language) language = user['language'] yield get_notification(language) data = {} data['type'] = 'admin_test_static' data['node'] = yield admin_serialize_node(language) data['notification'] = yield get_notification(language) subject, body = Templating().get_mail_subject_and_body(data) send_to = user['mail_address'] log.debug("Attempting to send test email to: %s" % send_to) # If sending the email fails the exception mail address will be mailed. # If the failure is due to a bad SMTP config that will fail too, but it # doesn't hurt to try! try: yield sendmail(send_to, subject, body) except Exception as e: log.debug("Sending to admin failed. Trying an exception mail") raise e
def test_keywords_conversion(self): yield self.perform_full_submission_actions() yield Delivery().run() data = {} data['type'] = 'tip' data['user'] = yield user.get_user(1, self.dummyReceiver_1['id'], u'en') data['context'] = yield admin.context.get_context( 1, self.dummyContext['id'], u'en') data['notification'] = yield tw(admin.notification.db_get_notification, 1, u'en') data['node'] = yield tw(admin.node.db_admin_serialize_node, 1, u'en') for tip in self.dummyRTips: if tip['receiver_id'] == self.dummyReceiver_1['id']: tip_id = tip['id'] break data['tip'], _ = yield rtip.get_rtip(1, self.dummyReceiver_1['id'], tip_id, u'en') data['comments'] = data['tip']['comments'] data['comment'] = data['comments'][0] data['messages'] = data['tip']['messages'] data['message'] = data['messages'][0] files = yield rtip.receiver_get_rfile_list(data['tip']['id']) data['file'] = files[0] for key in ['tip', 'comment', 'message', 'file']: data['type'] = key template = ''.join(supported_template_types[key].keyword_list) Templating().format_template(template, data)
def test_keywords_conversion(self): yield self.perform_full_submission_actions() yield DeliverySchedule().run() data = {} data['type'] = 'tip' data['receiver'] = yield admin.receiver.get_receiver(self.dummyReceiver_1['id'], u'en') data['context'] = yield admin.context.get_context(self.dummyContext['id'], u'en') data['notification'] = yield admin.notification.get_notification(u'en') data['node'] = yield admin.node.admin_serialize_node(u'en') if self.dummyRTips[0]['receiver_id'] == self.dummyReceiver_1['id']: tip_id = self.dummyRTips[0]['id'] else: tip_id = self.dummyRTips[1]['id'] data['tip'] = yield rtip.get_rtip(self.dummyReceiver_1['id'], tip_id, u'en') data['comments'] = data['tip']['comments'] data['comment'] = data['comments'][0] data['messages'] = data['tip']['messages'] data['message'] = data['messages'][0] files = yield rtip.receiver_get_rfile_list(data['tip']['id']) data['file'] = files[0] for key in ['tip', 'comment', 'message', 'file']: data['type'] = key template = ''.join(supported_template_types[key].keyword_list) Templating().format_template(template, data)
def check_for_expiring_submissions(self, store): threshold = datetime_now() - timedelta( GLSettings.memory_copy.tip_expiration_threshold) for itip in store.find(models.InternalTip, models.InternalTip.expiration_date < threshold): for rtip in itip.receivertips: user = rtip.receiver.user language = user.language node_desc = db_admin_serialize_node(store, language) notification_desc = db_get_notification(store, language) context_desc = admin_serialize_context( store, rtip.internaltip.context, language) receiver_desc = admin_serialize_receiver( rtip.receiver, language) tip_desc = serialize_rtip(store, rtip, user.language) data = { 'type': u'tip_expiration', 'node': node_desc, 'context': context_desc, 'receiver': receiver_desc, 'notification': notification_desc, 'tip': tip_desc } subject, body = Templating().get_mail_subject_and_body(data) mail = models.Mail({ 'address': data['receiver']['mail_address'], 'subject': subject, 'body': body }) store.add(mail)
def test_keywords_conversion(self): yield self.perform_full_submission_actions() yield DeliverySchedule().operation() data = {} data['type'] = 'tip' data['receiver'] = yield admin.receiver.get_receiver( self.dummyReceiver_1['id'], 'en') data['context'] = yield admin.context.get_context( self.dummyContext['id'], 'en') data['notification'] = yield admin.notification.get_notification('en') data['node'] = yield admin.node.admin_serialize_node('en') data['tip'] = self.dummyRTips[0] comments = yield rtip.get_comment_list(self.dummyReceiver_1['id'], data['tip']['id']) data['comment'] = comments[0] messages = yield rtip.get_message_list(self.dummyReceiver_1['id'], data['tip']['id']) data['message'] = messages[0] files = yield rtip.get_files_receiver(self.dummyReceiver_1['id'], data['tip']['id']) data['file'] = files[0] for key in ['tip', 'comment', 'message', 'file']: data['type'] = key template = ''.join(supported_template_types[key].keyword_list) ret = Templating().format_template(template, data)
def db_create_identityaccessrequest_notifications(session, tid, itip, rtip, iar): users = session.query(models.User).filter(models.User.role == u'custodian', models.User.notification == True) for user in users: node = db_admin_serialize_node(session, tid, user.language) context = session.query(models.Context).filter( models.Context.id == itip.context_id, models.Context.tid == tid).one() data = {'type': 'identity_access_request'} data['user'] = user_serialize_user(session, user, user.language) data['tip'] = serialize_rtip(session, rtip, itip, user.language) data['context'] = admin_serialize_context(session, context, user.language) data['iar'] = serialize_identityaccessrequest(session, iar) data['node'] = db_admin_serialize_node(session, tid, user.language) if data['node']['mode'] == u'default': data['notification'] = db_get_notification(session, tid, user.language) else: data['notification'] = db_get_notification(session, 1, user.language) subject, body = Templating().get_mail_subject_and_body(data) session.add( models.Mail({ 'address': data['user']['mail_address'], 'subject': subject, 'body': body, 'tid': tid }))
def process_mail_creation(self, store, data): # https://github.com/globaleaks/GlobaLeaks/issues/798 # TODO: the current solution is global and configurable only by the admin receiver_id = data['receiver']['id'] sent_emails = GLSettings.get_mail_counter(receiver_id) if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour: log.debug( "Discarding emails for receiver %s due to threshold already exceeded for the current hour" % receiver_id) return GLSettings.increment_mail_counter(receiver_id) if sent_emails >= GLSettings.memory_copy.notification_threshold_per_hour: log.info( "Reached threshold of %d emails with limit of %d for receiver %s" % (sent_emails, GLSettings.memory_copy.notification_threshold_per_hour, receiver_id)) # simply changing the type of the notification causes # to send the notification_limit_reached data['type'] = u'receiver_notification_limit_reached' data['notification'] = db_get_notification( store, data['receiver']['language']) data['node'] = db_admin_serialize_node(store, data['receiver']['language']) if not data['node']['allow_unencrypted'] and data['receiver'][ 'pgp_key_status'] != u'enabled': return subject, body = Templating().get_mail_subject_and_body(data) # If the receiver has encryption enabled encrypt the mail body if data['receiver']['pgp_key_status'] == u'enabled': gpob = GLBPGP() try: gpob.load_key(data['receiver']['pgp_key_public']) body = gpob.encrypt_message( data['receiver']['pgp_key_fingerprint'], body) except Exception as excep: log.err( "Error in PGP interface object (for %s: %s)! (notification+encryption)" % (data['receiver']['username'], str(excep))) return finally: # the finally statement is always called also if # except contains a return or a raise gpob.destroy_environment() mail = models.Mail({ 'address': data['receiver']['mail_address'], 'subject': subject, 'body': body }) store.add(mail)
def certificate_mail_creation(self, store, expiration_date): for user_desc in db_get_admin_users(store): lang = user_desc['language'] template_vars = { 'type': 'https_certificate_expiration', 'expiration_date': expiration_date, 'node': db_admin_serialize_node(store, lang), 'notification': db_get_notification(store, lang) } subject, body = Templating().get_mail_subject_and_body( template_vars) # encrypt the notification if the admin has configured the issue. pub_key = user_desc['pgp_key_public'] if len(pub_key) > 0: body = encrypt_pgp_message(pub_key, user_desc['pgp_key_fingerprint'], body) store.add( models.Mail({ 'address': user_desc['mail_address'], 'subject': subject, 'body': body }))
def process_mail_creation(self, session, tid, data): user_id = data['user']['id'] language = data['user']['language'] # Do not spool emails if the receiver has disabled notifications if not data['user']['notification'] or ('tip' in data and not data['tip']['enable_notifications']): log.debug("Discarding emails for %s due to receiver's preference.", user_id) return data['node'] = self.serialize_config(session, 'node', tid, language) data['submission_statuses'] = db_get_submission_statuses(session, tid, language) if data['node']['mode'] == 'default': data['notification'] = self.serialize_config(session, 'notification', tid, language) else: data['notification'] = self.serialize_config(session, 'notification', 1, language) subject, body = Templating().get_mail_subject_and_body(data) # If the receiver has encryption enabled encrypt the mail body if data['user']['pgp_key_public']: pgpctx = PGPContext(self.state.settings.tmp_path) fingerprint = pgpctx.load_key(data['user']['pgp_key_public'])['fingerprint'] body = pgpctx.encrypt_message(fingerprint, body) session.add(models.Mail({ 'address': data['user']['mail_address'], 'subject': subject, 'body': body, 'tid': tid, }))
def process_mail_creation(self, session, tid, data): user_id = data['user']['id'] # Do not spool emails if the receiver has opted out of ntfns for this tip. if not data['tip']['enable_notifications']: log.debug("Discarding emails for %s due to receiver's preference.", user_id) return # https://github.com/globaleaks/GlobaLeaks/issues/798 # TODO: the current solution is global and configurable only by the admin sent_emails = self.state.get_mail_counter(user_id) if sent_emails >= self.state.tenant_cache[ tid].notification.notification_threshold_per_hour: log.debug( "Discarding emails for receiver %s due to threshold already exceeded for the current hour", user_id) return self.state.increment_mail_counter(user_id) if sent_emails >= self.state.tenant_cache[ tid].notification.notification_threshold_per_hour: log.info( "Reached threshold of %d emails with limit of %d for receiver %s", sent_emails, self.state.tenant_cache[tid].notification. notification_threshold_per_hour, user_id, tid=tid) # simply changing the type of the notification causes # to send the notification_limit_reached data['type'] = u'receiver_notification_limit_reached' data['node'] = self.serialize_config(session, 'node', tid, data['user']['language']) if data['node']['mode'] != u'whistleblowing.it': data['notification'] = self.serialize_config( session, 'notification', tid, data['user']['language']) else: data['notification'] = self.serialize_config( session, 'notification', 1, data['user']['language']) subject, body = Templating().get_mail_subject_and_body(data) # If the receiver has encryption enabled encrypt the mail body if data['user']['pgp_key_public']: pgpctx = PGPContext(self.state.settings.tmp_path) fingerprint = pgpctx.load_key( data['user']['pgp_key_public'])['fingerprint'] body = pgpctx.encrypt_message(fingerprint, body) session.add( models.Mail({ 'address': data['user']['mail_address'], 'subject': subject, 'body': body, 'tid': tid, }))
def test_tor2web_absence(self): """ This test checks: https://github.com/globaleaks/GlobaLeaks/issues/268 """ ### INITIALIZE BLOCK self.mockContext = helpers.MockDict().dummyContext self.mockReceiver = helpers.MockDict().dummyReceiver self.mockNode = helpers.MockDict().dummyNode self.createdContext = yield admin.create_context(self.mockContext) self.assertTrue(self.createdContext.has_key('id')) self.mockReceiver['contexts'] = [self.createdContext['id']] self.createdReceiver = yield admin.create_receiver(self.mockReceiver) self.assertTrue(self.createdReceiver.has_key('id')) self.createdNode = yield admin.update_node(self.mockNode) self.assertTrue(self.createdNode.has_key('version')) ### END OF THE INITIALIZE BLOCK # be sure of Tor2Web capability for attrname in Node.localized_strings: self.mockNode[attrname] = self.mockNode[attrname]['en'] self.createdNode = yield admin.update_node(self.mockNode) yield admin.import_memory_variables() self._load_defaults() self.mockSubmission = helpers.MockDict().dummySubmission self.mockSubmission['finalize'] = True self.mockSubmission['context_id'] = self.createdReceiver['contexts'][0] self.mockSubmission['receivers'] = [self.createdReceiver['id']] self.mockSubmission['wb_fields'] = helpers.fill_random_fields( self.createdContext) self.createdSubmission = yield submission.create_submission( self.mockSubmission, finalize=True) created_rtip = yield delivery_sched.tip_creation() self.assertEqual(len(created_rtip), 1) yield self._fill_event(u'encrypted_tip', 'Tip', created_rtip[0]) # adding funny configured variables self.templates['default_ETNT.txt'][ 'en'] += " %OttimoDireiOOOttimoDirei%" # with the event, we can finally call the format checks gentext = Templating().format_template( self.templates['default_ETNT.txt'], self.event) self.assertSubstring(self.createdContext['name'], gentext) self.assertSubstring(created_rtip[0], gentext) self.assertNotSubstring("%TipT2WURL%", gentext) # test against funny configured variables self.assertSubstring("%OttimoDireiOOOttimoDirei%", gentext)
def get_tip_export(session, tid, user_id, rtip_id, language): rtip, itip = db_access_rtip(session, tid, user_id, rtip_id) user, context = session.query(models.User, models.Context) \ .filter(models.User.id == rtip.receiver_id, models.Context.id == models.InternalTip.context_id, models.InternalTip.id == rtip.internaltip_id, models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == tid).one() rtip_dict = serialize_rtip(session, rtip, itip, language) export_dict = { 'type': u'export_template', 'node': db_admin_serialize_node(session, tid, language), 'notification': db_get_notification(session, tid, language), 'tip': rtip_dict, 'user': user_serialize_user(session, user, language), 'context': admin_serialize_context(session, context, language), 'comments': rtip_dict['comments'], 'messages': rtip_dict['messages'], 'files': [] } export_template = Templating().format_template( export_dict['notification']['export_template'], export_dict).encode('utf-8') export_template = msdos_encode(text_type(export_template, 'utf-8')).encode('utf-8') export_dict['files'].append({ 'fo': BytesIO(export_template), 'name': "data.txt" }) for rfile in session.query(models.ReceiverFile).filter( models.ReceiverFile.receivertip_id == rtip_id): rfile.last_access = datetime_now() rfile.downloads += 1 file_dict = models.serializers.serialize_rfile(session, tid, rfile) file_dict['name'] = 'files/' + file_dict['name'] file_dict['path'] = os.path.join(Settings.attachments_path, file_dict['filename']) export_dict['files'].append(file_dict) for wf in session.query(models.WhistleblowerFile).filter( models.WhistleblowerFile.receivertip_id == models.ReceiverTip.id, models.ReceiverTip.internaltip_id == rtip.internaltip_id, models.InternalTip.id == rtip.internaltip_id): file_dict = models.serializers.serialize_wbfile(session, tid, wf) file_dict['name'] = 'files_from_recipients/' + file_dict['name'] file_dict['path'] = os.path.join(Settings.attachments_path, file_dict['filename']) export_dict['files'].append(file_dict) return export_dict
def login(session, tid, username, password, authcode, client_using_tor, client_ip): """ login returns a session """ user = None users = session.query(User).filter(User.username == username, User.state != u'disabled', UserTenant.user_id == User.id, UserTenant.tenant_id == tid).distinct() for u in users: if GCE.check_password(u.hash_alg, password, u.salt, u.password): user = u break if user is None: log.debug("Login: Invalid credentials") Settings.failed_login_attempts += 1 raise errors.InvalidAuthentication connection_check(client_ip, tid, user.role, client_using_tor) if State.tenant_cache[ 1].two_factor_auth and user.last_login != datetime_null(): token = TwoFactorTokens.get(user.id) if token is not None and authcode != '': if token.token == authcode: TwoFactorTokens.revoke(user.id) else: raise errors.InvalidTwoFactorAuthCode elif token is None and authcode == '': token = TwoFactorTokens.new(user.id) data = {'type': '2fa', 'authcode': str(token.token)} data['node'] = db_admin_serialize_node(session, tid, user.language) data['notification'] = db_get_notification(session, tid, user.language) subject, body = Templating().get_mail_subject_and_body(data) State.sendmail(1, user.mail_address, subject, body) raise errors.TwoFactorAuthCodeRequired else: raise errors.TwoFactorAuthCodeRequired user.last_login = datetime_now() crypto_prv_key = '' if State.tenant_cache[1].encryption and user.crypto_prv_key: user_key = GCE.derive_key(password.encode('utf-8'), user.salt) crypto_prv_key = GCE.symmetric_decrypt(user_key, user.crypto_prv_key) return Sessions.new(tid, user.id, user.role, user.password_change_needed, crypto_prv_key)
def format_and_send_mail(self, session, tid, user_desc, template_vars): subject, body = Templating().get_mail_subject_and_body(template_vars) if user_desc.get('pgp_key_public', ''): pgpctx = PGPContext(self.settings.tmp_path) fingerprint = pgpctx.load_key(user_desc['pgp_key_public'])['fingerprint'] body = pgpctx.encrypt_message(fingerprint, body) db_schedule_email(session, tid, user_desc['mail_address'], subject, body)
def send_pgp_alerts(self, receiver_desc): user_language = receiver_desc['language'] node_desc = yield admin_serialize_node(user_language) notification_settings = yield get_notification(user_language) fakeevent = OD() fakeevent.type = u'pgp_expiration_alert' fakeevent.node_info = node_desc fakeevent.context_info = None fakeevent.receiver_info = receiver_desc fakeevent.tip_info = None fakeevent.subevent_info = None subject = Templating().format_template( notification_settings['pgp_alert_mail_title'], fakeevent) body = Templating().format_template( notification_settings['pgp_alert_mail_template'], fakeevent) yield sendmail(receiver_desc['mail_address'], subject, body)
def prepare_user_pgp_alerts(self, store, user_desc): user_language = user_desc['language'] data = { 'address': user_desc['mail_address'], 'type': u'pgp_alert', 'node': db_admin_serialize_node(store, user_language), 'notification': db_get_notification(store, user_language), 'user': user_desc } Templating().db_prepare_mail(store, data)
def process_mail_creation(self, store, data): user_id = data['user']['id'] # Do not spool emails if the receiver has opted out of ntfns for this tip. if not data['tip']['enable_notifications']: log.debug("Discarding emails for %s due to receiver's preference.", user_id) return # https://github.com/globaleaks/GlobaLeaks/issues/798 # TODO: the current solution is global and configurable only by the admin sent_emails = State.get_mail_counter(user_id) if sent_emails >= State.tenant_cache[ 1].notif.notification_threshold_per_hour: log.debug( "Discarding emails for receiver %s due to threshold already exceeded for the current hour", user_id) return State.increment_mail_counter(user_id) if sent_emails >= State.tenant_cache[ 1].notif.notification_threshold_per_hour: log.info( "Reached threshold of %d emails with limit of %d for receiver %s", sent_emails, State.tenant_cache[1].notif.notification_threshold_per_hour, user_id) # simply changing the type of the notification causes # to send the notification_limit_reached data['type'] = u'receiver_notification_limit_reached' data['notification'] = self.serialize_config(store, 'notification', data['user']['language']) data['node'] = self.serialize_config(store, 'node', data['user']['language']) if not data['node']['allow_unencrypted'] and len( data['user']['pgp_key_public']) == 0: return subject, body = Templating().get_mail_subject_and_body(data) # If the receiver has encryption enabled encrypt the mail body if data['user']['pgp_key_public']: body = encrypt_message(data['user']['pgp_key_public'], body) store.add( models.Mail({ 'address': data['user']['mail_address'], 'subject': subject, 'body': body }))
def send_admin_pgp_alerts(self, admin_desc, expired_or_expiring): user_language = admin_desc['language'] node_desc = yield admin_serialize_node(user_language) notification_settings = yield get_notification(user_language) fakeevent = OD() fakeevent.type = u'admin_pgp_expiration_alert' fakeevent.node_info = node_desc fakeevent.context_info = None fakeevent.receiver_info = None fakeevent.tip_info = None fakeevent.subevent_info = {'expired_or_expiring': expired_or_expiring} subject = Templating().format_template( notification_settings['admin_pgp_alert_mail_title'], fakeevent) body = Templating().format_template( notification_settings['admin_pgp_alert_mail_template'], fakeevent) admin_users = yield get_admin_users() for u in admin_users: yield sendmail(u['mail_address'], subject, body)
def get_tip_export(store, user_id, rtip_id, language): rtip = db_access_rtip(store, user_id, rtip_id) receiver = rtip.receiver rtip_dict = serialize_rtip(store, rtip, language) export_dict = { 'type': u'export_template', 'node': db_admin_serialize_node(store, language), 'notification': db_get_notification(store, language), 'tip': serialize_rtip(store, rtip, language), 'context': admin_serialize_context(store, rtip.internaltip.context, language), 'receiver': admin_serialize_receiver(store, receiver, language), 'comments': rtip_dict['comments'], 'messages': rtip_dict['messages'], 'files': [] } export_template = Templating().format_template( export_dict['notification']['export_template'], export_dict).encode('utf-8') export_template = msdos_encode(export_template) export_dict['files'].append({'buf': export_template, 'name': "data.txt"}) for rf in store.find(models.ReceiverFile, models.ReceiverFile.receivertip_id == rtip_id): rf.downloads += 1 file_dict = models.serializers.serialize_rfile(rf) file_dict['name'] = 'files/' + file_dict['name'] export_dict['files'].append(file_dict) rtips_ids = [rt.id for rt in rtip.internaltip.receivertips] wfs = store.find(models.WhistleblowerFile, In(models.WhistleblowerFile.receivertip_id, rtips_ids)) for wf in wfs: file_dict = models.serializers.serialize_wbfile(wf) file_dict['name'] = 'files_from_recipients/' + file_dict['name'] export_dict['files'].append(file_dict) return export_dict
def prepare_admin_pgp_alerts(self, store, expired_or_expiring): for user_desc in db_get_admin_users(store): user_language = user_desc['language'] data = { 'address': user_desc['mail_address'], 'type': u'admin_pgp_alert', 'node': db_admin_serialize_node(store, user_language), 'notification': db_get_notification(store, user_language), 'users': expired_or_expiring } Templating().db_prepare_mail(store, data)
def _generate_admin_alert_mail(store, alert): for user_desc in db_get_admin_users(store): user_language = user_desc['language'] data = { 'address': user_desc['mail_address'], 'type': u'admin_anomaly', 'node': db_admin_serialize_node(store, user_language), 'notification': db_get_notification(store, user_language), 'alert': alert } Templating().db_prepare_mail(store, data)
def prepare_user_pgp_alerts(self, store, user_desc): user_language = user_desc['language'] data = { 'type': u'pgp_alert', 'node': db_admin_serialize_node(store, user_language), 'notification': db_get_notification(store, user_language), 'user': user_desc } subject, body = Templating().get_mail_subject_and_body(data) db_schedule_email(store, user_desc['mail_address'], subject, body)
def db_check_for_expiring_submissions(self, session): for tid in self.state.tenant_state: threshold = datetime_now() + timedelta( hours=self.state.tenant_cache[tid].notification. tip_expiration_threshold) for user in session.query(models.User).filter( models.User.role == u'receiver', models.UserTenant.user_id == models.User.id, models.UserTenant.tenant_id == tid): itip_ids = [ id[0] for id in session.query(models.InternalTip.id).filter( models.InternalTip.tid == tid, models.ReceiverTip. internaltip_id == models.InternalTip.id, models.InternalTip.expiration_date < threshold, models.ReceiverTip.receiver_id == user.id) ] if not len(itip_ids): continue earliest_expiration_date = session.query(func.min(models.InternalTip.expiration_date)) \ .filter(models.InternalTip.id.in_(itip_ids)).one()[0] user_desc = user_serialize_user(session, user, user.language) data = { 'type': u'tip_expiration_summary', 'node': db_admin_serialize_node(session, tid, user.language), 'notification': db_get_notification(session, tid, user.language), 'user': user_desc, 'expiring_submission_count': len(itip_ids), 'earliest_expiration_date': datetime_to_ISO8601(earliest_expiration_date) } subject, body = Templating().get_mail_subject_and_body(data) session.add( models.Mail({ 'tid': tid, 'address': user_desc['mail_address'], 'subject': subject, 'body': body }))
def prepare_admin_pgp_alerts(self, store, expired_or_expiring): for user_desc in db_get_admin_users(store): user_language = user_desc['language'] data = { 'type': u'admin_pgp_alert', 'node': db_admin_serialize_node(store, user_language), 'notification': db_get_notification(store, user_language), 'users': expired_or_expiring } subject, body = Templating().get_mail_subject_and_body(data) db_schedule_email(store, user_desc['mail_address'], subject, body)
def generate_admin_alert_mail(store, alert): for user_desc in db_get_admin_users(store): user_language = user_desc['language'] data = { 'type': u'admin_anomaly', 'node': db_admin_serialize_node(store, user_language), 'notification': db_get_notification(store, user_language), 'alert': alert } subject, body = Templating().get_mail_subject_and_body(data) db_schedule_email(store, user_desc['mail_address'], subject, body)
def format_and_send_mail(self, session, tid, user_desc, template_vars): subject, body = Templating().get_mail_subject_and_body(template_vars) if user_desc.get('pgp_key_public', ''): pgpctx = PGPContext(self.settings.tmp_path) fingerprint = pgpctx.load_key(user_desc['pgp_key_public'])['fingerprint'] body = pgpctx.encrypt_message(fingerprint, body) session.add(models.Mail({ 'address': user_desc['mail_address'], 'subject': subject, 'body': body, 'tid': tid, }))