def db_load(self, store): not_notified_rfiles = store.find(models.ReceiverFile, models.ReceiverFile.new == True) if not_notified_rfiles.count(): log.debug("new Files found to be notified: %d" % not_notified_rfiles.count()) for rfile in not_notified_rfiles: context_desc = admin.admin_serialize_context(store, rfile.internalfile.internaltip.context, self.language) steps_desc = admin.db_get_context_steps(store, context_desc['id'], self.language) tip_desc = serialize_receivertip(rfile.receivertip) 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, steps_info=steps_desc, tip_info=tip_desc, subevent_info=file_desc, do_mail=do_mail)) rfile.new = False
def db_archive_questionnaire_schema(store, submission): if (store.find(ArchivedSchema, ArchivedSchema.hash == submission.questionnaire_hash).count() <= 0): for lang in GLSettings.memory_copy.languages_enabled: aqs = ArchivedSchema() aqs.hash = submission.questionnaire_hash aqs.type = u'questionnaire' aqs.language = lang aqs.schema = db_get_context_steps(store, submission.context_id, lang) store.add(aqs) preview = [] for s in aqs.schema: for f in s['children']: if f['preview']: preview.append(f) aqsp = ArchivedSchema() aqsp.hash = submission.questionnaire_hash aqsp.type = u'preview' aqsp.language = lang aqsp.schema = preview store.add(aqsp)
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(message.receivertip) context_desc = admin.admin_serialize_context(store, message.receivertip.internaltip.context, self.language) steps_desc = admin.db_get_context_steps(store, context_desc['id'], 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, steps_info=steps_desc, tip_info=tip_desc, subevent_info=message_desc, do_mail=do_mail))
def load_files(self, store): not_notified_rfiles = store.find(models.ReceiverFile, models.ReceiverFile.mark == u'not notified') if not_notified_rfiles.count(): log.debug("new [Files✖Receiver] found to be notified: %d" % not_notified_rfiles.count()) for rfile in not_notified_rfiles: if not self.context_desc.has_key('id') or \ self.context_desc['id'] != rfile.internalfile.internaltip.context_id: self.context_desc = admin.admin_serialize_context(store, rfile.internalfile.internaltip.context, self.language) self.steps_info_desc = admin.db_get_context_steps(store, self.context_desc['id'], self.language) file_desc = serialize_internalfile(rfile.internalfile, rfile.id) tip_desc = serialize_receivertip(rfile.receiver_tip) rfile.mark = u'notified' self.do_mail = self.import_receiver(rfile.receiver) self.append_event(tip_info=tip_desc, subevent_info=file_desc)
def load_messages(self, store): not_notified_messages = store.find(models.Message, models.Message.mark == u'not notified') if not_notified_messages.count(): log.debug("Messages found to be notified: %d" % not_notified_messages.count()) for message in not_notified_messages: message_desc = rtip.receiver_serialize_message(message) message.mark = u'notified' # message.type can be 'receiver' or 'wb' at the moment, we care of the 2nd if message.type == u"receiver": continue tip_desc = serialize_receivertip(message.receivertip) self.do_mail = self.import_receiver(message.receivertip.receiver) # this check is to avoid ask continuously the same context: if not self.context_desc.has_key('id') or \ self.context_desc['id'] != message.receivertip.internaltip.context_id: self.context_desc = admin.admin_serialize_context(store, message.receivertip.internaltip.context, self.language) self.steps_info_desc = admin.db_get_context_steps(store, self.context_desc['id'], self.language) # append the event based on the self.* and the iteration serialization: self.append_event(tip_info=tip_desc, subevent_info=message_desc)
def load_tips(self, store): not_notified_tips = store.find(models.ReceiverTip, models.ReceiverTip.mark == u'not notified') 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: self.do_mail = self.import_receiver(receiver_tip.receiver) tip_desc = serialize_receivertip(receiver_tip) receiver_tip.mark = u'notified' # this check is to avoid ask continuously the same context: if not self.context_desc.has_key('id') or \ self.context_desc['id'] != receiver_tip.internaltip.context_id: self.context_desc = admin.admin_serialize_context(store, receiver_tip.internaltip.context, self.language) self.steps_info_desc = admin.db_get_context_steps(store, self.context_desc['id'], self.language) # append the event (use the self.* and the iteration serialization): self.append_event(tip_info=tip_desc, subevent_info=None)
def db_update_submission(store, submission_id, request, finalize, language): context = store.find(Context, Context.id == unicode(request['context_id'])).one() if not context: log.err("Context requested: [%s] not found!" % request['context_id']) raise errors.ContextIdNotFound submission = store.find(InternalTip, InternalTip.id == unicode(submission_id)).one() if not submission: log.err("Invalid Submission requested %s in PUT" % submission_id) raise errors.SubmissionIdNotFound # this may happen if a submission try to update a context if submission.context_id != context.id: log.err("Can't be changed context in a submission update") raise errors.ContextIdNotFound() if submission.mark != u'submission': log.err("Submission %s do not permit update (status %s)" % (submission_id, submission.mark)) raise errors.SubmissionConcluded try: import_files(store, submission, request['files']) except Exception as excep: log.err("Submission update: files import fail: %s" % excep) log.exception(excep) raise excep try: wb_steps = request['wb_steps'] if finalize: steps = db_get_context_steps(store, context.id, language) verify_steps(steps, wb_steps) submission.wb_steps = wb_steps except Exception as excep: log.err("Submission update: fields validation fail: %s" % excep) log.exception(excep) raise excep try: import_receivers(store, submission, request['receivers'], required=finalize) except Exception as excep: log.err("Submission update: receiver import fail: %s" % excep) log.exception(excep) raise excep if finalize: submission.mark = u'finalize' # Finalized else: submission.mark = u'submission' # Submission submission_dict = wb_serialize_internaltip(submission) return submission_dict
def db_create_submission(store, request, finalize, language): context = store.find(Context, Context.id == unicode(request['context_id'])).one() if not context: log.err("Context requested: [%s] not found!" % request['context_id']) raise errors.ContextIdNotFound submission = InternalTip() submission.access_limit = context.tip_max_access submission.download_limit = context.file_max_download submission.expiration_date = utc_future_date( seconds=context.tip_timetolive) submission.context_id = context.id submission.creation_date = datetime_now() if finalize: submission.mark = u'finalize' # Finalized else: submission.mark = u'submission' # Submission try: store.add(submission) except Exception as excep: log.err("Storm/SQL Error: %s (create_submission)" % excep) raise errors.InternalServerError("Unable to commit on DB") try: import_files(store, submission, request['files']) except Exception as excep: log.err("Submission create: files import fail: %s" % excep) raise excep try: wb_steps = request['wb_steps'] if finalize: steps = db_get_context_steps(store, context.id, language) verify_steps(steps, wb_steps) submission.wb_steps = wb_steps except Exception as excep: log.err("Submission create: fields validation fail: %s" % excep) raise excep try: import_receivers(store, submission, request['receivers'], required=finalize) except Exception as excep: log.err("Submission create: receivers import fail: %s" % excep) raise excep submission_dict = wb_serialize_internaltip(submission) return submission_dict
def fill_random_fields(store, context_id, value=None): """ return randomly populated contexts associated to specified context """ steps = db_get_context_steps(store, context_id, 'en') for step in steps: for field in step['children']: fill_random_field_recursively(field) return steps
def update_submission(store, submission_id, request, finalize, language=GLSetting.memory_copy.default_language): context = store.find(Context, Context.id == unicode(request['context_id'])).one() if not context: log.err("Context requested: [%s] not found!" % request['context_id']) raise errors.ContextIdNotFound submission = store.find(InternalTip, InternalTip.id == unicode(submission_id)).one() if not submission: log.err("Invalid Submission requested %s in PUT" % submission_id) raise errors.SubmissionIdNotFound # this may happen if a submission try to update a context if submission.context_id != context.id: log.err("Can't be changed context in a submission update") raise errors.ContextIdNotFound("Context are immutable") if submission.mark != u'submission': log.err("Submission %s do not permit update (status %s)" % (submission_id, submission.mark)) raise errors.SubmissionConcluded try: import_files(store, submission, request['files'], finalize) except Exception as excep: log.err("Submission update: files import fail: %s" % excep) log.exception(excep) raise excep try: wb_steps = request['wb_steps'] if finalize: steps = db_get_context_steps(store, context.id, language) verify_steps(steps, wb_steps) submission.wb_steps = wb_steps except Exception as excep: log.err("Submission update: fields validation fail: %s" % excep) log.exception(excep) raise excep try: import_receivers(store, submission, request['receivers'], required=finalize) except Exception as excep: log.err("Submission update: receiver import fail: %s" % excep) log.exception(excep) raise excep if finalize: submission.mark = u'finalize' # Finalized else: submission.mark = u'submission' # Submission submission_dict = wb_serialize_internaltip(submission) return submission_dict
def fill_random_fields(store, context_id, value=None): """ return randomly populated contexts associated to specified context """ steps = db_get_context_steps(store, context_id) for step in steps: for field in step['children']: fill_random_field_recursively(field) return steps
def db_create_submission(store, token, request, language): context = store.find(Context, Context.id == token.context_associated).one() if not context: # this can happen only if the context is removed # between submission POST and PUT.. :) that's why is better just # ignore this check, take che cached and wait the reference below fault log.err("Context requested: [%s] not found!" % token.context_associated) raise errors.ContextIdNotFound submission = InternalTip() submission.expiration_date = utc_future_date(seconds=context.tip_timetolive) submission.context_id = context.id submission.creation_date = datetime_now() store.add(submission) try: for filedesc in token.uploaded_files: associated_f = InternalFile() associated_f.name = filedesc['filename'] # aio, when we are going to implement file.description ? associated_f.description = "" associated_f.content_type = filedesc['content_type'] associated_f.size = filedesc['body_len'] associated_f.internaltip_id = submission.id associated_f.file_path = filedesc['encrypted_path'] store.add(associated_f) log.debug("=> file associated %s|%s (%d bytes)" % ( associated_f.name, associated_f.content_type, associated_f.size)) except Exception as excep: log.err("Unable to create a DB entry for file! %s" % excep) raise excep try: wb_steps = request['wb_steps'] steps = db_get_context_steps(store, context.id, language) verify_steps(steps, wb_steps) submission.wb_steps = wb_steps except Exception as excep: log.err("Submission create: fields validation fail: %s" % excep) raise excep try: import_receivers(store, submission, request['receivers']) except Exception as excep: log.err("Submission create: receivers import fail: %s" % excep) raise excep submission_dict = wb_serialize_internaltip(submission) return submission_dict
def fill_random_answers(self, store, context_id, value=None): """ return randomly populated contexts associated to specified context """ answers = {} steps = db_get_context_steps(store, context_id, 'en') for step in steps: for field in step['children']: self.fill_random_field_recursively(answers, field) return answers
def create_submission(store, request, finalize, language=GLSetting.memory_copy.default_language): context = store.find(Context, Context.id == unicode(request['context_id'])).one() if not context: log.err("Context requested: [%s] not found!" % request['context_id']) raise errors.ContextIdNotFound submission = InternalTip() submission.access_limit = context.tip_max_access submission.download_limit = context.file_max_download submission.expiration_date = utc_future_date(seconds=context.tip_timetolive) submission.context_id = context.id submission.creation_date = datetime_now() if finalize: submission.mark = u'finalize' # Finalized else: submission.mark = u'submission' # Submission try: store.add(submission) except Exception as excep: log.err("Storm/SQL Error: %s (create_submission)" % excep) raise errors.InternalServerError("Unable to commit on DB") try: import_files(store, submission, request['files'], finalize) except Exception as excep: log.err("Submission create: files import fail: %s" % excep) raise excep try: wb_steps = request['wb_steps'] if finalize: steps = db_get_context_steps(store, context.id, language) verify_steps(steps, wb_steps) submission.wb_steps = wb_steps except Exception as excep: log.err("Submission create: fields validation fail: %s" % excep) raise excep try: import_receivers(store, submission, request['receivers'], required=finalize) except Exception as excep: log.err("Submission create: receivers import fail: %s" % excep) raise excep submission_dict = wb_serialize_internaltip(submission) return submission_dict
def db_load(self, store): not_notified_comments = store.find(models.Comment, models.Comment.new == True) if not_notified_comments.count(): log.debug("Comments found to be notified: %d" % not_notified_comments.count()) for comment in not_notified_comments: comment_desc = rtip.receiver_serialize_comment(comment) context_desc = admin.admin_serialize_context(store, comment.internaltip.context, self.language) steps_desc = admin.db_get_context_steps(store, context_desc['id'], 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) 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) 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, steps_info=steps_desc, tip_info=tip_desc, subevent_info=comment_desc, do_mail=do_mail)) comment.new = False
def load_comments(self, store): not_notified_comments = store.find(models.Comment, models.Comment.mark == u'not notified' ) if not_notified_comments.count(): log.debug("Comments found to be notified: %d" % not_notified_comments.count()) for comment in not_notified_comments: if not self.context_desc.has_key('id') or \ self.context_desc['id'] != comment.internaltip.context_id: self.context_desc = admin.admin_serialize_context(store, comment.internaltip.context, self.language) self.steps_info_desc = admin.db_get_context_steps(store, self.context_desc['id'], self.language) comment_desc = rtip.receiver_serialize_comment(comment) comment.mark = u'notified' # 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: self.do_mail = self.import_receiver(receiver) if comment.type == u'receiver' and comment.author == receiver.name: log.debug("Receiver is the Author (%s): skipped" % receiver.user.username) 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) self.append_event(tip_info=tip_desc, subevent_info=comment_desc)
def process_event(self, store, rfile): context_desc = admin.admin_serialize_context(store, rfile.internalfile.internaltip.context, self.language) steps_desc = admin.db_get_context_steps(store, context_desc['id'], self.language) tip_desc = serialize_receivertip(rfile.receivertip) 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, steps_info=steps_desc, tip_info=tip_desc, subevent_info=file_desc, do_mail=do_mail))
def db_load(self, store): not_notified_messages = store.find(models.Message, models.Message.new == True) if not_notified_messages.count(): log.debug("Messages found to be notified: %d" % not_notified_messages.count()) for message in not_notified_messages: 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": continue tip_desc = serialize_receivertip(message.receivertip) context_desc = admin.admin_serialize_context(store, message.receivertip.internaltip.context, self.language) steps_desc = admin.db_get_context_steps(store, context_desc['id'], 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, steps_info=steps_desc, tip_info=tip_desc, subevent_info=message_desc, do_mail=do_mail)) message.new = False
def db_archive_questionnaire_schema(store, submission): if (store.find(ArchivedSchema, ArchivedSchema.hash == submission.questionnaire_hash).count() <= 0): for lang in GLSettings.memory_copy.languages_enabled: aqs = ArchivedSchema() aqs.hash = submission.questionnaire_hash aqs.type = u'questionnaire' aqs.language = lang aqs.schema = db_get_context_steps(store, submission.context_id, lang) store.add(aqs) preview = [] for s in aqs.schema: for f in s['children']: if f['preview']: preview.append(f) aqsp = ArchivedSchema() aqsp.hash = submission.questionnaire_hash aqsp.type = u'preview' aqsp.language = lang aqsp.schema = preview store.add(aqsp)
def notify(self, store, tip_id): expiring_rtips = store.find(ReceiverTip, ReceiverTip.internaltip_id == tip_id) for ertip in expiring_rtips: do_mail, receiver_desc = self.import_receiver(ertip.receiver) context_desc = admin.admin_serialize_context(store, ertip.internaltip.context, self.language) steps_desc = admin.db_get_context_steps(store, context_desc['id'], self.language) expiring_tip_desc = serialize_receivertip(ertip) self.events.append(Event(type=self.template_type, trigger=self.trigger, node_info={}, receiver_info=receiver_desc, context_info=context_desc, steps_info=steps_desc, tip_info=expiring_tip_desc, subevent_info=None, do_mail=do_mail))
def db_create_submission(store, token_id, request, t2w, language): # the .get method raise an exception if the token is invalid token = TokenList.get(token_id) if not token.context_associated == request['context_id']: raise errors.InvalidInputFormat("Token context does not match the one specified in submission payload") token.validate(request) TokenList.delete(token_id) answers = request['answers'] context = store.find(Context, Context.id == token.context_associated).one() if not context: # this can happen only if the context is removed # between submission POST and PUT.. :) that's why is better just # ignore this check, take che cached and wait the reference below fault log.err("Context requested: [%s] not found!" % token.context_associated) raise errors.ContextIdNotFound submission = InternalTip() submission.expiration_date = utc_future_date(seconds=context.tip_timetolive) submission.context_id = context.id submission.creation_date = datetime_now() # Tor2Web is spot in the handler and passed here, is done to keep track of the # security level adopted by the whistleblower submission.tor2web = t2w try: questionnaire = db_get_context_steps(store, context.id, GLSettings.memory_copy.default_language) questionnaire_hash = sha256(json.dumps(questionnaire)) submission.questionnaire_hash = questionnaire_hash submission.preview = extract_answers_preview(questionnaire, answers) store.add(submission) db_archive_questionnaire_schema(store, submission) db_save_questionnaire_answers(store, submission, answers) except Exception as excep: log.err("Submission create: fields validation fail: %s" % excep) raise excep try: import_receivers(store, submission, request['receivers']) except Exception as excep: log.err("Submission create: receivers import fail: %s" % excep) raise excep try: for filedesc in token.uploaded_files: associated_f = InternalFile() associated_f.name = filedesc['filename'] associated_f.description = "" associated_f.content_type = filedesc['content_type'] associated_f.size = filedesc['body_len'] associated_f.internaltip_id = submission.id associated_f.file_path = filedesc['encrypted_path'] store.add(associated_f) log.debug("=> file associated %s|%s (%d bytes)" % ( associated_f.name, associated_f.content_type, associated_f.size)) except Exception as excep: log.err("Unable to create a DB entry for file! %s" % excep) raise excep receipt = db_create_whistleblower_tip(store, submission) submission_dict = wb_serialize_internaltip(store, submission) submission_dict.update({'receipt': receipt}) return submission_dict
def db_create_submission(store, token_id, request, t2w, language): # the .get method raise an exception if the token is invalid token = TokenList.get(token_id) if not token.context_associated == request['context_id']: raise errors.InvalidInputFormat( "Token context does not match the one specified in submission payload" ) token.validate(request) TokenList.delete(token_id) answers = request['answers'] context = store.find(Context, Context.id == token.context_associated).one() if not context: # this can happen only if the context is removed # between submission POST and PUT.. :) that's why is better just # ignore this check, take che cached and wait the reference below fault log.err("Context requested: [%s] not found!" % token.context_associated) raise errors.ContextIdNotFound submission = InternalTip() submission.expiration_date = utc_future_date( seconds=context.tip_timetolive) submission.context_id = context.id submission.creation_date = datetime_now() # Tor2Web is spot in the handler and passed here, is done to keep track of the # security level adopted by the whistleblower submission.tor2web = t2w try: questionnaire = db_get_context_steps( store, context.id, GLSettings.memory_copy.default_language) questionnaire_hash = sha256(json.dumps(questionnaire)) submission.questionnaire_hash = questionnaire_hash submission.preview = extract_answers_preview(questionnaire, answers) store.add(submission) db_archive_questionnaire_schema(store, submission) db_save_questionnaire_answers(store, submission, answers) except Exception as excep: log.err("Submission create: fields validation fail: %s" % excep) raise excep try: import_receivers(store, submission, request['receivers']) except Exception as excep: log.err("Submission create: receivers import fail: %s" % excep) raise excep try: for filedesc in token.uploaded_files: associated_f = InternalFile() associated_f.name = filedesc['filename'] associated_f.description = "" associated_f.content_type = filedesc['content_type'] associated_f.size = filedesc['body_len'] associated_f.internaltip_id = submission.id associated_f.file_path = filedesc['encrypted_path'] store.add(associated_f) log.debug("=> file associated %s|%s (%d bytes)" % (associated_f.name, associated_f.content_type, associated_f.size)) except Exception as excep: log.err("Unable to create a DB entry for file! %s" % excep) raise excep receipt = db_create_whistleblower_tip(store, submission) submission_dict = wb_serialize_internaltip(store, submission) submission_dict.update({'receipt': receipt}) return submission_dict
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`). """ language = GLSetting.memory_copy.default_language 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, 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) store.remove(message) 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 = models.Receiver.get(store, message.receivertip.receiver_id) 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, 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(store, context, 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' notification_settings = self._get_notification_settings(store, receiver_desc['language']) event = Event(type=template_type, trigger='Message', notification_settings=notification_settings, trigger_info=message_desc, trigger_parent=tip_desc, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, steps_info = admin.db_get_context_steps(store, context_desc['id'], language), plugin=plugin) events.append(((unicode(message.id), unicode(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`). """ language = GLSetting.memory_copy.default_language 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, 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) store.remove(comment) 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") store.remove(comment) continue context_desc = admin.admin_serialize_context(store, comment.internaltip.context, 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, 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' notification_settings = self._get_notification_settings(store, receiver_desc['language']) event = Event(type=template_type, trigger='Comment', notification_settings=notification_settings, trigger_info=comment_desc, trigger_parent=tip_desc, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, steps_info = admin.db_get_context_steps(store, context_desc['id'], language), plugin=plugin) events.append(((unicode(comment.id), unicode(receiver.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`). """ language = GLSetting.memory_copy.default_language 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, 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) store.remove(rfile) break if not rfile.internalfile: log.err("(file_notification) Integrity check failure (InternalFile)") store.remove(rfile) continue file_desc = serialize_internalfile(rfile.internalfile) if not rfile.internalfile.internaltip or \ not rfile.internalfile.internaltip.context: log.err("(file_notification) Integrity check failure (InternalTip/Context)") store.remove(rfile) continue context_desc = admin.admin_serialize_context(store, rfile.internalfile.internaltip.context, language) receiver_desc = admin.admin_serialize_receiver(rfile.receiver, 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' notification_settings = self._get_notification_settings(store, receiver_desc['language']) event = Event(type=template_type, trigger='File', notification_settings=notification_settings, trigger_info=file_desc, trigger_parent=tip_desc, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, steps_info = admin.db_get_context_steps(store, context_desc['id'], language), plugin=plugin) events.append(((unicode(rfile.id), unicode(rfile.receiver.id)), event)) return events, notification_counter
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`). """ language = GLSetting.memory_copy.default_language 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, 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)") store.remove(receiver_tip) continue context_desc = admin.admin_serialize_context(store, receiver_tip.internaltip.context, language) receiver_desc = admin.admin_serialize_receiver(receiver_tip.receiver, 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' notification_settings = self._get_notification_settings(store, receiver_desc['language']) event = Event(type=template_type, trigger='Tip', notification_settings=notification_settings, trigger_info=tip_desc, trigger_parent=None, node_info=node_desc, receiver_info=receiver_desc, context_info=context_desc, steps_info = admin.db_get_context_steps(store, context_desc['id'], language), plugin=plugin) events.append((unicode(receiver_tip.id), event)) return events, notification_counter