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 _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 _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']) context_dict = yield admin.get_context(self.createdContext['id']) steps_dict = yield admin.get_context_steps(self.createdContext['id']) notif_dict = yield admin.notification.get_notification() yield admin.import_memory_variables() node_dict = yield admin.admin_serialize_node() # is a mock 'trigger_info' and 'trigger_parent' at the moment self.tip['name'] = ' foo ' self.tip['size'] = ' 123 ' self.tip['content_type'] = ' application/javascript ' self.tip['creation_date'] = context_dict['creation_date'] self.tip['type'] = ' sorry maker ' # this is requested in the file cases self.event = Event(type = event_type, trigger = event_trigger, notification_settings = notif_dict, node_info = node_dict, receiver_info = receiver_dict, context_info = context_dict, steps_info = steps_dict, plugin = None, trigger_info = self.tip, trigger_parent = self.tip )
def update_node_properties(self): node_desc = yield admin.admin_serialize_node('en') self.assertEqual(node_desc['can_postpone_expiration'], False) node_desc['can_postpone_expiration'] = True stuff = u"³²¼½¬¼³²" for attrname in models.Node.localized_strings: node_desc[attrname] = stuff node_desc = yield admin.update_node(node_desc, True, 'en') self.assertEqual(node_desc['can_postpone_expiration'], True)
def update_node_properties(self): node_desc = yield admin.admin_serialize_node() self.assertEqual(node_desc['postpone_superpower'], False) node_desc['postpone_superpower'] = True stuff = u"³²¼½¬¼³²" for attrname in models.Node.localized_strings: node_desc[attrname] = stuff node_desc = yield admin.update_node(node_desc) self.assertEqual(node_desc['postpone_superpower'], True)
def operation(self): expired_or_expiring = yield self.pgp_validation_check() admin_user = yield admin_serialize_user('admin') node_desc = yield admin_serialize_node(admin_user['language']) notification_settings = yield get_notification(admin_user['language']) if expired_or_expiring: yield self.send_admin_pgp_alerts(node_desc, admin_user, notification_settings, expired_or_expiring) for receiver_desc in expired_or_expiring: yield self.send_pgp_alerts(node_desc, receiver_desc, notification_settings)
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 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 test_keywords_conversion(self): yield self.perform_full_submission_actions() self.receiver_dict = yield admin.get_receiver( self.dummyReceiver_1['id'], 'en') self.context_dict = yield admin.get_context(self.dummyContext['id'], 'en') self.notif_dict = yield admin.notification.get_notification('en') self.node_dict = yield admin.admin_serialize_node('en') self.rtip_dict = self.dummyRTips[0]['itip'] self.templates = {} for t, keywords_list in templates_desc.iteritems(): self.templates[t] = "" for kwl in keywords_list: for keyword in kwl: self.templates[t] += " " + keyword + " / " for template_name, template in self.templates.iteritems(): # look for appropriate event_type, event_trigger event_type = u'' event_trigger = '' for e_t, e_tri in supported_event_types.iteritems(): if template_name.startswith(e_t): event_type = e_t event_trigger = e_tri break if not event_type: # we've nothing to do not! continue self._fill_event_dict(event_type, event_trigger) # with the event, we can finally call the template filler gentext = Templating().format_template(template, self.event) if template_name != 'ping_mail_template' and template_name != 'ping_mail_title': self.assertSubstring(self.context_dict['name'], gentext) self.assertSubstring(self.node_dict['public_site'], gentext) self.assertSubstring(self.node_dict['hidden_service'], gentext)
def test_keywords_conversion(self): yield self.perform_full_submission_actions() self.receiver_dict = yield admin.get_receiver(self.dummyReceiver_1['id'], 'en') self.context_dict = yield admin.get_context(self.dummyContext['id'], 'en') self.steps_dict = yield admin.get_context_steps(self.dummyContext['id'], 'en') self.notif_dict = yield admin.notification.get_notification('en') self.node_dict = yield admin.admin_serialize_node('en') self.rtip_dict = self.dummyRTips[0]['itip'] self.templates = {} for t, keywords_list in templates_desc.iteritems(): self.templates[t] = "" for kwl in keywords_list: for keyword in kwl: self.templates[t] += " " + keyword + " / " for template_name, template in self.templates.iteritems(): # look for appropriate event_type, event_trigger event_type = u'' event_trigger = '' for e_t, e_tri in supported_event_types.iteritems(): if template_name.startswith(e_t): event_type = e_t event_trigger = e_tri break if not event_type: # we've nothing to do not! continue self._fill_event_dict(event_type, event_trigger) # with the event, we can finally call the template filler gentext = Templating().format_template(template, self.event) if template_name != 'ping_mail_template' and template_name != 'ping_mail_title': self.assertSubstring(self.context_dict['name'], gentext) self.assertSubstring(self.node_dict['public_site'], gentext) self.assertSubstring(self.node_dict['hidden_service'], gentext)
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 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()
def create_tip_notification_events(self, store): """ 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.admin_serialize_node(store.find(models.Node).one(), GLSetting.memory_copy.default_language) if not_notified_tips.count(): log.debug("Receiver Tips found to be notified: %d" % not_notified_tips.count() ) for rtip in not_notified_tips: if not rtip.internaltip or not rtip.internaltip.context: log.err("(tip_notification) Integrity failure: missing InternalTip|Context") continue context_desc = admin.admin_serialize_context(rtip.internaltip.context, GLSetting.memory_copy.default_language) receiver_desc = admin.admin_serialize_receiver(rtip.receiver, GLSetting.memory_copy.default_language) if not receiver_desc.has_key('notification_fields') or\ not rtip.receiver.notification_fields.has_key('mail_address'): log.err("Receiver %s lack of email address!" % rtip.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" % rtip.receiver.user.username) rtip.mark = models.ReceiverTip._marker[3] # 'disabled' store.commit() continue tip_desc = serialize_receivertip(rtip) event = Event(type=u'tip', trigger='Tip', notification_settings=self.notification_settings, trigger_info=tip_desc, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, plugin=plugin) events.append((unicode(rtip.id), event)) return events
def create_file_notification_events(self, store): """ 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.admin_serialize_node(store.find(models.Node).one(), 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: 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('notification_fields') or \ not rfile.receiver.notification_fields.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 event = Event(type=u'file', trigger='File', notification_settings=self.notification_settings, trigger_info=file_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
def create_comment_notification_events(self, store): """ 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.admin_serialize_node(store.find(models.Node).one(), 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: 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 = tip.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('notification_fields') or\ not receiver.notification_fields.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._types == 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 event = Event(type=u'comment', trigger='Comment', notification_settings=self.notification_settings, trigger_info=comment_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
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()