def _fill_event_dict(self, event_type, event_trigger): """ A notification is based on the Node, Context and Receiver values, that has to be taken from the database. """ self.subevent = {} # this is requested in the file cases if event_type == 'ping_mail': self.subevent = {'counter': 42} elif event_type == 'admin_pgp_expiration_alert': self.subevent = {'expired_or_expiring': [self.receiver_dict]} else: self.subevent['name'] = ' foo ' self.subevent['size'] = ' 123 ' self.subevent['content_type'] = ' application/javascript ' self.subevent['creation_date'] = datetime_now() self.subevent['type'] = ' sorry maker ' self.event = Event(type=event_type, trigger=event_trigger, node_info=self.node_dict, receiver_info=self.receiver_dict, context_info=self.context_dict, tip_info=self.rtip_dict, subevent_info=self.subevent, do_mail=False)
def _fill_event(self, event_type, trigger, trigger_id): """ Here I'm testing only encrypted_tip because trigger a bigger amount of %KeyWords% """ self.assertEqual(event_type, u'encrypted_tip') self.assertEqual(trigger, 'Tip') if event_type == u'encrypted_tip' and trigger == 'Tip': receiver_dict = yield admin.get_receiver( self.createdReceiver['id']) context_dict = yield admin.get_context(self.createdContext['id']) notif_dict = yield admin.get_notification() yield admin.import_memory_variables() node_dict = yield admin.admin_serialize_node() tip_dict = yield self.get_a_fucking_random_submission() self.event = Event(type=u'encrypted_tip', trigger='Tip', notification_settings=notif_dict, node_info=node_dict, receiver_info=receiver_dict, context_info=context_dict, plugin=None, trigger_info=tip_dict, trigger_parent=None)
def process_event(self, store, comment): comment_desc = rtip.receiver_serialize_comment(comment) context_desc = admin.admin_serialize_context(store, comment.internaltip.context, self.language) # for every comment, iterate on the associated receiver(s) log.debug("Comments from %s - Receiver(s) %d" % \ (comment.author, comment.internaltip.receivers.count())) for receiver in comment.internaltip.receivers: if comment.type == u'receiver' and comment.author == receiver.name: log.debug("Receiver is the Author (%s): skipped" % receiver.user.username) return receivertip = store.find(models.ReceiverTip, (models.ReceiverTip.internaltip_id == comment.internaltip_id, models.ReceiverTip.receiver_id == receiver.id)).one() tip_desc = serialize_receivertip(store, receivertip, self.language) do_mail, receiver_desc = self.import_receiver(receiver) self.events.append(Event(type=self.template_type, trigger=self.trigger, node_info={}, receiver_info=receiver_desc, context_info=context_desc, tip_info=tip_desc, subevent_info=comment_desc, do_mail=do_mail))
def append_event(self, tip_info, subevent_info): event = Event(type=self.template_type, trigger=self.trigger, node_info={}, steps_info=self.steps_info_desc, tip_info=tip_info, subevent_info=subevent_info, receiver_info=self.receiver_desc, context_info=self.context_desc, do_mail=self.do_mail) self.events.append(event )
def post(self, rtip_id, compression): files_dict = yield download_all_files(self.current_user.user_id, rtip_id) if compression is None: compression = 'zipdeflated' opts = get_compression_opts(compression) node_dict = yield admin.admin_serialize_node(self.request.language) receiver_dict = yield get_receiver_from_rtip(rtip_id, self.request.language) rtip_dict = yield get_rtip_info(rtip_id, self.request.language) collection_tip_dict = yield get_collection_info(rtip_id) context_dict = yield admin.get_context(rtip_dict['context_id'], 'en') notif_dict = yield admin.notification.get_notification( self.request.language) mock_event = Event( type=u'zip_collection', trigger='Download', node_info=node_dict, receiver_info=receiver_dict, context_info=context_dict, tip_info=rtip_dict, subevent_info=collection_tip_dict, do_mail=False, ) formatted_coll = Templating().format_template( notif_dict['zip_description'], mock_event).encode('utf-8') files_dict.append({ 'buf': formatted_coll, 'name': "COLLECTION_INFO.txt" }) self.set_status(200) self.set_header('X-Download-Options', 'noopen') self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment; filename=\"%s\"' % opts['filename']) if compression in ['zipstored', 'zipdeflated']: for data in ZipStream(files_dict, opts['compression_type']): self.write(data) self.finish()
def process_event(self, store, rfile): context_desc = admin.admin_serialize_context(store, rfile.internalfile.internaltip.context, self.language) tip_desc = serialize_receivertip(store, rfile.receivertip, self.language) file_desc = serialize_internalfile(rfile.internalfile, rfile.id) do_mail, receiver_desc = self.import_receiver(rfile.receiver) self.events.append(Event(type=self.template_type, trigger=self.trigger, node_info={}, receiver_info=receiver_desc, context_info=context_desc, tip_info=tip_desc, subevent_info=file_desc, do_mail=do_mail))
def process_event(self, store, rtip): do_mail, receiver_desc = self.import_receiver(rtip.receiver) context_desc = admin.admin_serialize_context(store, rtip.internaltip.context, self.language) expiring_tip_desc = serialize_receivertip(store, rtip, self.language) self.events.append( Event(type=self.template_type, trigger=self.trigger, node_info={}, receiver_info=receiver_desc, context_info=context_desc, tip_info=expiring_tip_desc, subevent_info=None, do_mail=do_mail))
def test_encrypt_message(self): dummy_template = "In %EventTime% you've got a crush for Taryn Southern, yay!! \ more info on: https://www.youtube.com/watch?v=C7JZ4F3zJdY \ and know that you're not alone!" mock_event = Event( type=u'encrypted_tip', trigger='Tip', tip_info={ 'creation_date': '2013-05-13T17:49:26.105485', #epoch! 'id': 'useless', 'wb_steps': fill_random_fields(self.dummyContext['id']), }, node_info=MockDict().dummyNode, receiver_info=MockDict().dummyReceiver, context_info=MockDict().dummyContext, steps_info={}, subevent_info={}, do_mail=False) mail_content = Templating().format_template(dummy_template, mock_event) # setup the GPG key before GLSetting.gpgroot = GPGROOT fake_receiver_desc = { 'gpg_key_armor': unicode(VALID_PGP_KEY1), 'gpg_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'gpg_key_status': u'enabled', 'username': u'*****@*****.**', } gpgobj = GLBGPG() gpgobj.load_key(VALID_PGP_KEY1) encrypted_body = gpgobj.encrypt_message( fake_receiver_desc['gpg_key_fingerprint'], mail_content) self.assertSubstring('-----BEGIN PGP MESSAGE-----', encrypted_body) gpgobj.destroy_environment()
def test_Class_encryption_message(self): dummy_template = { "en": "In %EventTime% you've got a crush for Taryn Southern, yay!!" "more info on: https://www.youtube.com/watch?v=C7JZ4F3zJdY " "and know that you're not alone!" } mock_event = Event( type=u'encrypted_tip', trigger='Tip', notification_settings=dummy_template, trigger_info={ 'creation_date': '2013-05-13T17:49:26.105485', #epoch! 'id': 'useless', 'wb_fields': fill_random_fields(self.dummyContext), }, node_info=MockDict().dummyNode, receiver_info=MockDict().dummyReceiver, context_info=MockDict().dummyContext, plugin=MailNotification(), trigger_parent={}) mail_content = Templating().format_template(dummy_template, mock_event) # setup the GPG key before GLSetting.gpgroot = GPGROOT fake_receiver_desc = { 'gpg_key_armor': unicode(VALID_PGP_KEY), 'gpg_key_fingerprint': u"CF4A22020873A76D1DCB68D32B25551568E49345", 'gpg_key_status': Receiver._gpg_types[1], 'username': u'*****@*****.**', } gpob = GLBGPG(fake_receiver_desc) self.assertTrue(gpob.validate_key(VALID_PGP_KEY)) encrypted_body = gpob.encrypt_message(mail_content) self.assertSubstring('-----BEGIN PGP MESSAGE-----', encrypted_body)
def process_event(self, store, message): message_desc = rtip.receiver_serialize_message(message) # message.type can be 'receiver' or 'wb' at the moment, we care of the latter if message.type == u"receiver": return tip_desc = serialize_receivertip(store, message.receivertip, self.language) context_desc = admin.admin_serialize_context(store, message.receivertip.internaltip.context, self.language) do_mail, receiver_desc = self.import_receiver(message.receivertip.receiver) self.events.append(Event(type=self.template_type, trigger=self.trigger, node_info={}, receiver_info=receiver_desc, context_info=context_desc, tip_info=tip_desc, subevent_info=message_desc, do_mail=do_mail))
def _fill_event_dict(self, event_type, event_trigger): """ A notification is based on the Node, Context and Receiver values, that has to be taken from the database. """ receiver_dict = yield admin.get_receiver(self.createdReceiver['id'], 'en') context_dict = yield admin.get_context(self.createdContext['id'], 'en') steps_dict = yield admin.get_context_steps(self.createdContext['id'], 'en') notif_dict = yield admin.notification.get_notification('en') node_dict = yield admin.admin_serialize_node('en') self.subevent = {} # this is requested in the file cases if event_type == 'ping_mail': self.subevent = {'counter': 42} elif event_type == 'admin_pgp_expiration_alert': self.subevent = {'expired_or_expiring': [receiver_dict]} else: self.subevent['name'] = ' foo ' self.subevent['size'] = ' 123 ' self.subevent['content_type'] = ' application/javascript ' self.subevent['creation_date'] = context_dict['creation_date'] self.subevent['type'] = ' sorry maker ' self.event = Event(type=event_type, trigger=event_trigger, node_info=node_dict, receiver_info=receiver_dict, context_info=context_dict, steps_info=steps_dict, tip_info=self.tip, subevent_info=self.subevent, do_mail=False)
def create_tip_notification_events(self, store, notification_counter): """ This transaction will return all a list of tuples containing the tips for which the notification event has not been run. Returns: events: a list of tuples containing (tip_id, an instance of :class:`globaleaks.plugins.base.Event`). """ events = [] # settings.notification_plugins contain a list of supported plugin # at the moment only 1. so [0] is used. but different context/receiver # may use different code-plugin: cplugin = GLSetting.notification_plugins[0] plugin = getattr(notification, cplugin)() not_notified_tips = store.find( models.ReceiverTip, models.ReceiverTip.mark == models.ReceiverTip._marker[0]) node_desc = admin.db_admin_serialize_node( store, GLSetting.memory_copy.default_language) if not_notified_tips.count(): log.debug("Receiver Tips found to be notified: %d" % not_notified_tips.count()) for receiver_tip in not_notified_tips: notification_counter += 1 if notification_counter >= GLSetting.notification_limit: log.debug( "Notification counter has reached the suggested limit: %d (tip)" % notification_counter) break if not receiver_tip.internaltip or not receiver_tip.internaltip.context: log.err( "(tip_notification) Integrity failure: missing InternalTip|Context" ) continue context_desc = admin.admin_serialize_context( receiver_tip.internaltip.context, GLSetting.memory_copy.default_language) receiver_desc = admin.admin_serialize_receiver( receiver_tip.receiver, GLSetting.memory_copy.default_language) if not receiver_desc.has_key('mail_address'): log.err("Receiver %s lack of email address!" % receiver_tip.receiver.name) continue # check if the receiver has the Tip notification enabled or not if not receiver_desc['tip_notification']: log.debug("Receiver %s has tip notification disabled" % receiver_tip.receiver.user.username) receiver_tip.mark = models.ReceiverTip._marker[3] # 'disabled' store.commit() continue tip_desc = serialize_receivertip(receiver_tip) if receiver_desc[ 'gpg_key_status'] == u'Enabled': # Receiver._gpg_types[1] template_type = u'encrypted_tip' else: template_type = u'plaintext_tip' event = Event(type=template_type, trigger='Tip', notification_settings=self.notification_settings, trigger_info=tip_desc, trigger_parent=None, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, plugin=plugin) events.append((unicode(receiver_tip.id), event)) return events, notification_counter
def create_file_notification_events(self, store, notification_counter): """ Creates events for performing notification of newly added files.. Returns: events: a list of tuples containing ((receiverfile_id, receiver_id), an instance of :class:`globaleaks.plugins.base.Event`). """ events = [] cplugin = GLSetting.notification_plugins[0] plugin = getattr(notification, cplugin)() not_notified_rfiles = store.find( models.ReceiverFile, models.ReceiverFile.mark == models.ReceiverFile._marker[0]) node_desc = admin.db_admin_serialize_node( store, GLSetting.memory_copy.default_language) if not_notified_rfiles.count(): log.debug("Receiverfiles found to be notified: %d" % not_notified_rfiles.count()) for rfile in not_notified_rfiles: notification_counter += 1 if notification_counter >= GLSetting.notification_limit: log.debug( "Notification counter has reached the suggested limit: %d (files)" % notification_counter) break if not rfile.internalfile: log.err( "(file_notification) Integrity check failure (InternalFile)" ) continue file_desc = serialize_internalfile(rfile.internalfile) if not rfile.internalfile or \ not rfile.internalfile.internaltip or \ not rfile.internalfile.internaltip.context: log.err( "(file_notification) Integrity check failure (File+Tip)") continue context_desc = admin.admin_serialize_context( rfile.internalfile.internaltip.context, GLSetting.memory_copy.default_language) receiver_desc = admin.admin_serialize_receiver( rfile.receiver, GLSetting.memory_copy.default_language) if not receiver_desc.has_key('mail_address'): log.err("Receiver %s lack of email address!" % rfile.receiver.user.name) continue # check if the receiver has the File notification enabled or not if not rfile.receiver.file_notification: log.debug( "Receiver %s has file notification disabled: %s skipped" % (rfile.receiver.user.username, rfile.internalfile.name)) rfile.mark = models.ReceiverFile._marker[3] # 'disabled' store.commit() continue # by ticket https://github.com/globaleaks/GlobaLeaks/issues/444 # send notification of file only if notification of tip is already on send status if rfile.receiver_tip.mark == models.ReceiverTip._marker[ 0]: # 'not notified' rfile.mark = models.ReceiverFile._marker[4] # 'skipped' log.debug( "Skipped notification of %s (for %s) because Tip not yet notified" % (rfile.internalfile.name, rfile.receiver.name)) store.commit() continue tip_desc = serialize_receivertip(rfile.receiver_tip) if receiver_desc[ 'gpg_key_status'] == u'Enabled': # Receiver._gpg_types[1] template_type = u'encrypted_file' else: template_type = u'plaintext_file' event = Event(type=template_type, trigger='File', notification_settings=self.notification_settings, trigger_info=file_desc, trigger_parent=tip_desc, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, plugin=plugin) events.append( ((unicode(rfile.id), unicode(rfile.receiver.id)), event)) return events, notification_counter
def create_comment_notification_events(self, store, notification_counter): """ Creates events for performing notification of newly added comments. Returns: events: a list of tuples containing ((comment_id, receiver_id), an instance of :class:`globaleaks.plugins.base.Event`). """ events = [] cplugin = GLSetting.notification_plugins[0] plugin = getattr(notification, cplugin)() not_notified_comments = store.find( models.Comment, models.Comment.mark == models.Comment._marker[0]) node_desc = admin.db_admin_serialize_node( store, GLSetting.memory_copy.default_language) if not_notified_comments.count(): log.debug("Comments found to be notified: %d" % not_notified_comments.count()) for comment in not_notified_comments: notification_counter += 1 if notification_counter >= GLSetting.notification_limit: log.debug( "Notification counter has reached the suggested limit: %d (comment)" % notification_counter) break if comment.internaltip is None or comment.internaltip.receivers is None: log.err( "Comment %s has internaltip or receivers broken reference" % comment.id) comment.mark = models.Comment._marker[2] # 'unable to notify' continue # for every comment, iter on the associated receiver log.debug("Comments receiver: %d" % comment.internaltip.receivers.count()) comment_desc = rtip.receiver_serialize_comment(comment) if not comment.internaltip.context: log.err( "(comment_notification) Integrity check failure Context") continue context_desc = admin.admin_serialize_context( comment.internaltip.context, GLSetting.memory_copy.default_language) # XXX BUG! All notification is marked as correctly send, # This can't be managed by callback, and can't be managed by actual DB design comment.mark = models.Comment._marker[1] # 'notified' for receiver in comment.internaltip.receivers: receiver_desc = admin.admin_serialize_receiver( receiver, GLSetting.memory_copy.default_language) if not receiver_desc.has_key('mail_address'): log.err("Receiver %s lack of email address!" % receiver.name) continue # if the comment author is the one to be notified: skip the notification # ----- BUG, remind, # if two receiver has the same name, and one has notification disabled # also the homonymous would get the notification dropped. if comment.type == models.Comment._types[ 0] and comment.author == receiver.name: log.debug("Receiver is the Author (%s): skipped" % receiver.user.username) continue # check if the receiver has the Comment notification enabled or not if not receiver.comment_notification: log.debug( "Receiver %s has comment notification disabled: skipped [source: %s]" % (receiver.user.username, comment.author)) continue receivertip = store.find( models.ReceiverTip, (models.ReceiverTip.internaltip_id == comment.internaltip_id, models.ReceiverTip.receiver_id == receiver.id)).one() tip_desc = serialize_receivertip(receivertip) if receiver_desc[ 'gpg_key_status'] == u'Enabled': # Receiver._gpg_types[1] template_type = u'encrypted_comment' else: template_type = u'plaintext_comment' event = Event(type=template_type, trigger='Comment', notification_settings=self.notification_settings, trigger_info=comment_desc, trigger_parent=tip_desc, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, plugin=plugin) events.append( ((unicode(comment.id), unicode(receiver.id)), event)) return events, notification_counter
def create_message_notification_events(self, store, notification_counter): """ Creates events for performing notification of newly added messages. Returns: events: a list of tuples containing ((message_id, receiver_id), an instance of :class:`globaleaks.plugins.base.Event`). """ events = [] cplugin = GLSetting.notification_plugins[0] plugin = getattr(notification, cplugin)() not_notified_messages = store.find( models.Message, models.Message.mark == models.Message._marker[0]) node_desc = admin.db_admin_serialize_node( store, GLSetting.memory_copy.default_language) if not_notified_messages.count(): log.debug("Messages found to be notified: %d" % not_notified_messages.count()) for message in not_notified_messages: notification_counter += 1 if notification_counter >= GLSetting.notification_limit: log.debug( "Notification counter has reached the suggested limit: %d (messages)" % notification_counter) break if message.receivertip is None: log.err("Message %s has ReceiverTip broken reference" % message.id) message.mark = models.Message._marker[2] # 'unable to notify' continue tip_desc = serialize_receivertip(message.receivertip) receiver = store.find( Receiver, Receiver.id == message.receivertip.receiver_id).one() if not receiver: log.err("Message %s do not find receiver!?" % message.id) if not receiver.mail_address: log.err("Receiver %s lack of email address!" % receiver.name) continue receiver_desc = admin.admin_serialize_receiver( receiver, GLSetting.memory_copy.default_language) log.debug("Messages receiver: %s" % message.receivertip.receiver.name) context = message.receivertip.internaltip.context if not context: log.err("Reference chain fail!") continue context_desc = admin.admin_serialize_context( context, GLSetting.memory_copy.default_language) message_desc = rtip.receiver_serialize_message(message) message.mark = u'notified' # models.Message._marker[1] if message.type == u"receiver": log.debug("Receiver is the Author (%s): skipped" % receiver.user.username) continue # check if the receiver has the Message notification enabled or not if not receiver.message_notification: log.debug( "Receiver %s has message notification disabled: skipped [source: %s]" % (receiver.user.username, message.author)) continue if receiver_desc[ 'gpg_key_status'] == u'Enabled': # Receiver._gpg_types[1] template_type = u'encrypted_message' else: template_type = u'plaintext_message' event = Event(type=template_type, trigger='Message', notification_settings=self.notification_settings, trigger_info=message_desc, trigger_parent=tip_desc, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, plugin=plugin) events.append(((unicode(message.id), unicode(receiver.id)), event)) return events, notification_counter
def post(self, rtip_id, compression): files_dict = yield download_all_files(self.current_user.user_id, rtip_id) if not files_dict: raise errors.DownloadLimitExceeded if compression is None: compression = 'zipstored' opts = get_compression_opts(compression) node_dict = yield admin.admin_serialize_node() receiver_dict = yield get_receiver_from_rtip(rtip_id) rtip_dict = yield get_rtip_info(rtip_id) collection_tip_dict = yield get_collection_info(rtip_id) context_dict = yield admin.get_context(rtip_dict['context_id']) notif_dict = yield admin.get_notification() mock_event = Event(type=u'zip_collection', trigger='Download', notification_settings=notif_dict, node_info=node_dict, receiver_info=receiver_dict, context_info=context_dict, plugin=None, trigger_info=collection_tip_dict, trigger_parent=rtip_dict) formatted_coll = Templating().format_template( notif_dict['zip_description'], mock_event).encode('utf-8') # log.debug("Generating collection content with: %s" % formatted_coll) files_dict.append({ 'buf': formatted_coll, 'name': "COLLECTION_INFO.txt" }) self.set_status(200) self.set_header('X-Download-Options', 'noopen') self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment; filename=\"%s\"' % opts['filename']) if compression in ['zipstored', 'zipdeflated']: for data in ZipStream(files_dict, opts['compression_type']): self.write(data) elif compression in ['tar', 'targz', 'tarbz2']: collectionstreamer = CollectionStreamer(self) tar = tarfile.open("collection." + compression, 'w|' + opts['compression_type'], collectionstreamer) for f in files_dict: if 'path' in f: try: tar.add(f['path'], f['name']) except (OSError, IOError) as excpd: log.err( "OSError while adding %s to files collection: %s" % (f['path'], excpd)) elif 'buf' in f: tarinfo = tarfile.TarInfo(f['name']) tarinfo.size = len(f['buf']) tar.addfile(tarinfo, StringIO.StringIO(f['buf'])) tar.close() self.finish()