def send_message(self, group): contacts_noemail = [] language = translation.get_language() sync_info = { 'backend': EXTERNAL_MESSAGE_BACKEND_NAME, 'language': language, } if self.support_expiration_date(): delta = self.cleaned_data['expiration_date'] - date.today() expiration = delta.days sync_info['expiration'] = expiration json_sync_info = json.dumps(sync_info) for contact_id in self.cleaned_data['ids'].split(','): contact = get_object_or_404(Contact, pk=contact_id) if not contact.get_fieldvalues_by_type('EMAIL'): contacts_noemail.append(contact) contact_msg = ContactMsg(contact=contact, group=group) contact_msg.send_date = now() contact_msg.subject = self.cleaned_data['subject'] contact_msg.text = self.cleaned_data['message'] contact_msg.sync_info = json_sync_info contact_msg.save() return contacts_noemail
def read_answers(msg): "step 3 : Fetch answers" sync_info = json.loads(msg.sync_info) if 'answer_password' not in sync_info: return if 'deleted' in sync_info: # Ignore message that were deleted on remote storage return # We have to open a new connection each time # since we can't handle keep-alive yet ot_conn = http.client.HTTPSConnection('onetime.info', timeout=TIMEOUT) ot_conn.request( 'POST', '/'+sync_info['otid']+'/answers', urllib.parse.urlencode( {'password': sync_info['answer_password']}), { 'Content-type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json, text/javascript, */*; q=0.01', }) response = ot_conn.getresponse() # TODO: except httplib.BadStatusLine if response.status == 404: logger.info("Message is gone: %s %s", response.status, response.reason) # tag the message as deleted, so we stop trying to synchronise again # and again sync_info['deleted'] = True msg.sync_info = json.dumps(sync_info) msg.save() return if response.status != 200: logger.error("Temporary storage server error: %s %s", response.status, response.reason) logger.error("%s", response.read()) return # jresponse = json.load(response) sresponse = response.read() jresponse = json.loads(force_str(sresponse)) logger.debug(jresponse) if 'read_date' in jresponse and not msg.read_date: read_date = jresponse.get('read_date', None) read_date = datetime.datetime.strptime(read_date, '%Y-%m-%d %H:%M:%S') if settings.USE_TZ: read_date = timezone.make_aware( read_date, timezone.get_default_timezone()) msg.read_date = read_date msg.save() passphrase = sync_info.get('passphrase_out', None) for response_text in jresponse['answers']: logger.info('Received answer from %s.', msg.contact) if passphrase: try: response_text += '\n' # openssl limitation response_text = response_text.encode(settings.DEFAULT_CHARSET) response_text = subprocess.check_output( ['openssl', 'enc', '-aes-256-cbc', '-pass', 'pass:{}'.format(passphrase), '-d', '-base64', '-A'], input=response_text) response_text = force_text(response_text) except subprocess.CalledProcessError: # Retry with an empty passphrase try: response_text = subprocess.check_output( ['openssl', 'enc', '-aes-256-cbc', '-pass', 'pass:'******'-d', '-base64', '-A'], input=response_text) response_text = force_text(response_text) except subprocess.CalledProcessError: logger.error("Message decryption failed.") answer_msg = ContactMsg( group_id=msg.group_id, contact_id=msg.contact_id, send_date=timezone.now(), subject=jresponse['subject'], text=response_text, is_answer=True, sync_info=json.dumps({ 'backend': __name__, 'otid': sync_info['otid'], }), ) answer_msg.save()