def test_static_reset(self): # new way will obsolete test_gen_new_keys when rm #2115 in cleartext = "We never really grow up, we only learn how to act in public." c = self.client # after successful login should get re-direct to / response = c.post('/login/', {'username': '******', 'password': '******'}) c.COOKIES = {'ss': response.cookies['ss'].value} c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) msg = encrypt_object(SecureTestMessage, {}, cleartext, opub) c.user.set_password('gorilla') c.user.save() creds = strengthen_key(ADMIN_PASSWORD) admin_rsa = import_rsa(ADMIN_RESET_ENCD_RSA, creds) privs = UserPrivateKey.objects.filter(user=c.user, credtype=CRED_WEBAPP) reset_keys(privs, admin_rsa, 'gorilla') c.logout() response = c.post('/login/', {'username': '******', 'password': '******'}) c.COOKIES = {'ss': response.cookies['ss'].value} decrypted_cleartext = decrypt_object(c, msg) self.assertEqual(decrypted_cleartext, cleartext) msg.id += 1 with self.assertRaises(KeyInvalidException): decrypt_object(c, msg) response = c.logout()
def test_encrypt_object_withIVR(self): u = User.objects.get(username="******") opub = OwnerPublicKey.objects.get_pubkey(owner=u, keytype=RSA_IVR) m = encrypt_object(SecureTestMessage, {}, self.clear_text, opub) # Set up a fake request object. request = HttpRequest() request.session = dict() response = HttpResponse() request.user = u store_user_key(request, response, self.ivr_pin) request.COOKIES['ss'] = response.cookies['ss'].value m_get = SecureTestMessage.objects.get(pk=m.pk) m_body = decrypt_object(request, m_get, ivr=True) self.assertEqual(m_body, self.clear_text) # Set up a fake IVR request object. ivr_request = HttpRequest() ivr_request.session = dict() ivr_response = HttpResponse() ivr_request.user = u store_user_key(ivr_request, ivr_response, self.ivr_pin) ivr_request.COOKIES['ss'] = ivr_response.cookies['ss'].value ivr_m_get = SecureTestMessage.objects.get(pk=m.pk) ivr_m_body = decrypt_object(ivr_request, ivr_m_get, ivr=True) self.assertEqual(ivr_m_body, self.clear_text)
def test_static_reset(self): # new way will obsolete test_gen_new_keys when rm #2115 in cleartext = "We never really grow up, we only learn how to act in public." c = self.client # after successful login should get re-direct to / response = c.post('/login/', { 'username': '******', 'password': '******' }) c.COOKIES = {'ss': response.cookies['ss'].value} c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) msg = encrypt_object(SecureTestMessage, {}, cleartext, opub) c.user.set_password('gorilla') c.user.save() creds = strengthen_key(ADMIN_PASSWORD) admin_rsa = import_rsa(ADMIN_RESET_ENCD_RSA, creds) privs = UserPrivateKey.objects.filter(user=c.user, credtype=CRED_WEBAPP) reset_keys(privs, admin_rsa, 'gorilla') c.logout() response = c.post('/login/', { 'username': '******', 'password': '******' }) c.COOKIES = {'ss': response.cookies['ss'].value} decrypted_cleartext = decrypt_object(c, msg) self.assertEqual(decrypted_cleartext, cleartext) msg.id += 1 with self.assertRaises(KeyInvalidException): decrypt_object(c, msg) response = c.logout()
def test_gen_new_keys(self): cleartext = "A sql query walks in to a bar, approaches two tables and asks 'may I join you?'" c = self.client # after successful login should get re-direct to / response = c.post('/login/', {'username': '******', 'password': '******'}) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) msg = encrypt_object(SecureTestMessage, {}, cleartext) gen_keys_for_users(msg, [c.user], None, c, ivr=True) generate_new_user_keys(c.user, 'monkey') c.user.set_password('monkey') c.user.save() # logout. cleanup response = c.logout() # simulate admin update invalid keys creds = strengthen_key(ADMIN_PASSWORD) admin_rsa = import_rsa(ADMIN_RESET_ENCD_RSA, creds) reset_user_invalid_keys(MHLUser.objects.get(id=c.user.id), admin_rsa) # login with new password and verify we can decrypt message response = c.post('/login/', {'username': '******', 'password': '******'}) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') # verify we are logged in self.assertEqual(c.session['_auth_user_id'], c.user.id) decrypted_cleartext = decrypt_object(c, msg) self.assertEqual(decrypted_cleartext, cleartext) response = c.logout()
def body_decryption_helper(request, obj): """ Assists in decrypting by catching KMS.exceptions.KMSException """ try: return_data = decrypt_object(request, obj) except KMSException as e: # Not much to do here. logger.critical('Got error %s' % repr(e)) return_data = _('Data decryption error. Administrators have been notified.') return return_data
def body_decryption_helper(request, obj): """ Assists in decrypting by catching KMS.exceptions.KMSException """ try: return_data = decrypt_object(request, obj) except KMSException as e: # Not much to do here. logger.critical('Got error %s' % repr(e)) return_data = _( 'Data decryption error. Administrators have been notified.') return return_data
def read_message(request, msg_body, ss=None): """Read message, this function include following logic: 1. Decrypt message body, and return the decrypted body. 2. Mark the message is read. In addition, if the message's type is ANS, mark the related user(receiver and ccs)'s message body is read, and send push notification to these users. :param request: HTTP request object. :param msg_body: an instance of MessageBodyUserStatus. :param ss: user's private key """ body = decrypt_object(request, msg_body, ss=ss) mark_message_as_read(request.user, msg_body) return body
def test_encrypt_object_noIVR(self): u = MHLUser.objects.get(username="******") opub = OwnerPublicKey.objects.get_pubkey(owner=u) m = encrypt_object(SecureTestMessage, {}, self.clear_text, opub) # Set up a fake request object. request = HttpRequest() request.session = dict() response = HttpResponse() request.user = u store_user_key(request, response, self.password) request.COOKIES['ss'] = response.cookies['ss'].value m_get = SecureTestMessage.objects.get(pk=m.pk) m_body = decrypt_object(request, m_get) self.assertEqual(m_body, self.clear_text)
def test_gen_new_keys(self): cleartext = "A sql query walks in to a bar, approaches two tables and asks 'may I join you?'" c = self.client # after successful login should get re-direct to / response = c.post('/login/', { 'username': '******', 'password': '******' }) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) msg = encrypt_object(SecureTestMessage, {}, cleartext) gen_keys_for_users(msg, [c.user], None, c, ivr=True) generate_new_user_keys(c.user, 'monkey') c.user.set_password('monkey') c.user.save() # logout. cleanup response = c.logout() # simulate admin update invalid keys creds = strengthen_key(ADMIN_PASSWORD) admin_rsa = import_rsa(ADMIN_RESET_ENCD_RSA, creds) reset_user_invalid_keys(MHLUser.objects.get(id=c.user.id), admin_rsa) # login with new password and verify we can decrypt message response = c.post('/login/', { 'username': '******', 'password': '******' }) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') # verify we are logged in self.assertEqual(c.session['_auth_user_id'], c.user.id) decrypted_cleartext = decrypt_object(c, msg) self.assertEqual(decrypted_cleartext, cleartext) response = c.logout()
def message_view(request, message_id, type): """Process message view request: :param request: The HTTP message view request :type request: django.core.handlers.wsgi.WSGIRequest :param message_id: The message id :type message_id: int :returns: django.http.HttpResponse -- the JSON result in an HttpResonse object :raises: None """ resolved = request.GET['resolved'] thread_uuid = Message.objects.get(uuid=message_id).thread_uuid msgs = MessageBodyUserStatus.objects.filter(user=request.user, delete_flag=False, msg_body__message__thread_uuid=thread_uuid).order_by( '-msg_body__message__send_timestamp').\ select_related('msg_body', 'msg_body__message', 'msg_body__message__sender')\ .extra(select={'sender_title':"SELECT MHLUsers_mhluser.title \ FROM MHLUsers_mhluser INNER JOIN Messaging_message ON \ MHLUsers_mhluser.user_ptr_id = Messaging_message.sender_id \ INNER JOIN Messaging_messagebody ON \ Messaging_message.id = Messaging_messagebody.message_id \ WHERE Messaging_messagebody.id = Messaging_messagebodyuserstatus.msg_body_id" }) if (resolved == ''): pass elif str(resolved).lower() in ("true"): msgs = msgs.filter(msg_body__message__in=[ m.msg_body.message for m in msgs if m.msg_body.message.resolved_by != None ]) else: msgs = msgs.filter(msg_body__message__in=[ m.msg_body.message for m in msgs if m.msg_body.message.resolved_by == None ]) msgs.select_related( 'msg_body', 'msg_body__message', 'msg_body__message__sender', ) msgs = list(msgs) context = get_context(request) user = request.session['MHL_Users']['MHLUser'] local_tz = getCurrentTimeZoneForUser( user, current_practice=context['current_practice']) is_received = type == 'received' current_user = getCurrentUserInfo(request) current_user_mobile = getCurrentUserMobile(current_user) call_enable = bool(current_user_mobile) and settings.CALL_ENABLE msgs_list = [] audio_list = [] for status_obj in msgs: try: read_flag = status_obj.read_flag body = decrypt_object(request, status_obj.msg_body) # TODO, this function need to refactor, when get threading message list, # don't need to decrypt every message body in the threading message. # When refactors, use following line while reading message body. # body = read_message(request, status_obj.msg_body) if not read_flag: status_obj.read_flag = read_flag status_obj.save() except KeyInvalidException: mail_admins( _('Message Body Decryption Error'), ''.join([('An error occurred decryption data for user '), request.user.username, (' on server '), settings.SERVER_ADDRESS, '.\n', ('Message ID: '), message_id])) callbacks = CallbackLog.objects.filter(message=status_obj.msg_body.message).\ order_by('time').values('time') callbacks = [{ 'timestamp': _get_system_time_as_tz(c['time'], local_tz).strftime('%m/%d/%y %H:%M'), 'caller_name': 'Joe Bloggs', 'caller_id': 123, } for c in callbacks] msg_cc_maps = MessageCC.objects.filter(message=status_obj.msg_body.message).\ select_related('user').extra(select={'title':'SELECT title FROM MHLUsers_mhluser \ WHERE MHLUsers_mhluser.user_ptr_id = Messaging_message_ccs.user_id' })\ .only('user__first_name', 'user__last_name', 'message') ccs = '; '.join([get_fullname_bystr(msg_cc_map.user.last_name,\ msg_cc_map.user.first_name,msg_cc_map.title)\ for msg_cc_map in msg_cc_maps]) msg_to_maps = MessageRecipient.objects.filter(message=status_obj.msg_body.message).\ select_related('user').extra(select={'title':'SELECT title FROM MHLUsers_mhluser \ WHERE MHLUsers_mhluser.user_ptr_id = Messaging_message_recipients.user_id' })\ .only('user__first_name', 'user__last_name', 'message') recipients = '; '.join([get_fullname_bystr(msg_to_map.user.last_name,\ msg_to_map.user.first_name,msg_to_map.title)\ for msg_to_map in msg_to_maps]) to_recipient_ids = [] msg_sender = status_obj.msg_body.message.sender msg_sender_id = None if msg_sender: msg_sender_id = msg_sender.id to_recipient_ids.append(str(msg_sender_id)) for rec in msg_to_maps: if rec.user.id != request.user.id: to_recipient_ids.append(str(rec.user.id)) cc_recipient_ids = [] for cc in msg_cc_maps: cc_recipient_ids.append(str(cc.user.id)) is_read = status_obj.read_flag user_id = request.user.id read_recipients = [ r.id for r in status_obj.msg_body.message.recipients.all() ] read_ccs = [c.id for c in status_obj.msg_body.message.ccs.all()] if not is_read: if is_received: if user_id not in read_recipients + read_ccs: is_read = True else: if msg_sender_id != request.user.id: is_read = True is_sender = request.user.id == msg_sender_id if is_received and (request.user.id == msg_sender_id and user_id in read_recipients + read_ccs): is_sender = False result = { 'id': status_obj.msg_body.message.uuid, 'sender': sender_name_safe(status_obj.msg_body.message, title=status_obj.sender_title), 'sender_id': msg_sender_id, 'thread_uuid': status_obj.msg_body.message.thread_uuid, 'timestamp': formatTimeSetting(user, status_obj.msg_body.message.send_timestamp, local_tz), 'subject': conditional_escape(status_obj.msg_body.message.subject), 'body': replace_number(status_obj.msg_body.clear_data, call_enable), 'answering_service': status_obj.msg_body.message.message_type == 'ANS', 'callback_number': replace_number(status_obj.msg_body.message.callback_number, call_enable), 'callbacks': callbacks, 'urgent': status_obj.msg_body.message.urgent, 'ccs': ccs, 'recipients': recipients, 'to_recipient_ids': ','.join(to_recipient_ids), 'cc_recipient_ids': ','.join(cc_recipient_ids), 'is_sender': is_sender, 'is_resolved': status_obj.msg_body.message.resolved_by != None, 'read': 'true' if is_read else '' } attachments = MessageAttachment.objects.filter( message=status_obj.msg_body.message) result["attachments"] = [] for att in attachments: attach_dict = { 'id': att.uuid, 'suffix': att.suffix, 'size': att.size, 'metadata': att.metadata, 'filename': att.decrypt_filename(request), 'msgId': status_obj.msg_body.message.uuid } result["attachments"].append(attach_dict) if att.suffix and att.suffix.lower() in ['mp3', 'wav']: audio_list.append(attach_dict) result["refer"] = _get_refer_from_mbus(status_obj, call_enable=call_enable) result["action_history"] = get_message_action_history( status_obj.msg_body.message.id, user, time_zone=local_tz) msgs_list.append(result) context['msgs'] = msgs_list context['audio_list'] = audio_list context['type'] = type return HttpResponse( render_to_string('DoctorCom/Messaging/MessageBody.html', context))
def message_view(request, message_id, type): """Process message view request: :param request: The HTTP message view request :type request: django.core.handlers.wsgi.WSGIRequest :param message_id: The message id :type message_id: int :returns: django.http.HttpResponse -- the JSON result in an HttpResonse object :raises: None """ resolved = request.GET['resolved'] thread_uuid = Message.objects.get(uuid=message_id).thread_uuid msgs = MessageBodyUserStatus.objects.filter(user=request.user, delete_flag=False, msg_body__message__thread_uuid=thread_uuid).order_by( '-msg_body__message__send_timestamp').\ select_related('msg_body', 'msg_body__message', 'msg_body__message__sender')\ .extra(select={'sender_title':"SELECT MHLUsers_mhluser.title \ FROM MHLUsers_mhluser INNER JOIN Messaging_message ON \ MHLUsers_mhluser.user_ptr_id = Messaging_message.sender_id \ INNER JOIN Messaging_messagebody ON \ Messaging_message.id = Messaging_messagebody.message_id \ WHERE Messaging_messagebody.id = Messaging_messagebodyuserstatus.msg_body_id"}) if (resolved == ''): pass elif str(resolved).lower() in ("true"): msgs = msgs.filter(msg_body__message__in=[m.msg_body.message for m in msgs if m.msg_body.message.resolved_by != None]) else: msgs = msgs.filter(msg_body__message__in=[m.msg_body.message for m in msgs if m.msg_body.message.resolved_by == None]) msgs.select_related('msg_body', 'msg_body__message', 'msg_body__message__sender',) msgs = list(msgs) context = get_context(request) user = request.session['MHL_Users']['MHLUser'] local_tz = getCurrentTimeZoneForUser(user, current_practice=context['current_practice']) is_received = type == 'received' current_user = getCurrentUserInfo(request) current_user_mobile = getCurrentUserMobile(current_user) call_enable = bool(current_user_mobile) and settings.CALL_ENABLE msgs_list = [] audio_list = [] for status_obj in msgs: try: read_flag = status_obj.read_flag body = decrypt_object(request, status_obj.msg_body) # TODO, this function need to refactor, when get threading message list, # don't need to decrypt every message body in the threading message. # When refactors, use following line while reading message body. # body = read_message(request, status_obj.msg_body) if not read_flag: status_obj.read_flag = read_flag status_obj.save() except KeyInvalidException: mail_admins(_('Message Body Decryption Error'), ''.join([ ('An error occurred decryption data for user '), request.user.username, (' on server '), settings.SERVER_ADDRESS, '.\n', ('Message ID: '), message_id ])) callbacks = CallbackLog.objects.filter(message=status_obj.msg_body.message).\ order_by('time').values('time') callbacks = [ { 'timestamp': _get_system_time_as_tz(c['time'], local_tz).strftime('%m/%d/%y %H:%M'), 'caller_name': 'Joe Bloggs', 'caller_id': 123, } for c in callbacks] msg_cc_maps = MessageCC.objects.filter(message=status_obj.msg_body.message).\ select_related('user').extra(select={'title':'SELECT title FROM MHLUsers_mhluser \ WHERE MHLUsers_mhluser.user_ptr_id = Messaging_message_ccs.user_id'})\ .only('user__first_name', 'user__last_name', 'message') ccs = '; '.join([get_fullname_bystr(msg_cc_map.user.last_name,\ msg_cc_map.user.first_name,msg_cc_map.title)\ for msg_cc_map in msg_cc_maps]) msg_to_maps = MessageRecipient.objects.filter(message=status_obj.msg_body.message).\ select_related('user').extra(select={'title':'SELECT title FROM MHLUsers_mhluser \ WHERE MHLUsers_mhluser.user_ptr_id = Messaging_message_recipients.user_id'})\ .only('user__first_name', 'user__last_name', 'message') recipients = '; '.join([get_fullname_bystr(msg_to_map.user.last_name,\ msg_to_map.user.first_name,msg_to_map.title)\ for msg_to_map in msg_to_maps]) to_recipient_ids = [] msg_sender = status_obj.msg_body.message.sender msg_sender_id = None if msg_sender: msg_sender_id = msg_sender.id to_recipient_ids.append(str(msg_sender_id)) for rec in msg_to_maps: if rec.user.id != request.user.id: to_recipient_ids.append(str(rec.user.id)) cc_recipient_ids = [] for cc in msg_cc_maps: cc_recipient_ids.append(str(cc.user.id)) is_read = status_obj.read_flag user_id = request.user.id read_recipients = [r.id for r in status_obj.msg_body.message.recipients.all()] read_ccs = [c.id for c in status_obj.msg_body.message.ccs.all()] if not is_read: if is_received: if user_id not in read_recipients + read_ccs: is_read = True else: if msg_sender_id != request.user.id: is_read = True is_sender = request.user.id == msg_sender_id if is_received and (request.user.id == msg_sender_id and user_id in read_recipients + read_ccs): is_sender = False result = { 'id':status_obj.msg_body.message.uuid, 'sender':sender_name_safe(status_obj.msg_body.message,title=status_obj.sender_title), 'sender_id':msg_sender_id, 'thread_uuid':status_obj.msg_body.message.thread_uuid, 'timestamp':formatTimeSetting(user, status_obj.msg_body.message.send_timestamp, local_tz), 'subject':conditional_escape(status_obj.msg_body.message.subject), 'body':replace_number(status_obj.msg_body.clear_data, call_enable), 'answering_service':status_obj.msg_body.message.message_type == 'ANS', 'callback_number': replace_number( status_obj.msg_body.message.callback_number, call_enable), 'callbacks': callbacks, 'urgent':status_obj.msg_body.message.urgent, 'ccs':ccs, 'recipients':recipients, 'to_recipient_ids':','.join(to_recipient_ids), 'cc_recipient_ids':','.join(cc_recipient_ids), 'is_sender':is_sender, 'is_resolved':status_obj.msg_body.message.resolved_by != None, 'read': 'true' if is_read else '' } attachments = MessageAttachment.objects.filter(message=status_obj.msg_body.message) result["attachments"] = [] for att in attachments: attach_dict = {'id': att.uuid, 'suffix': att.suffix, 'size': att.size, 'metadata': att.metadata, 'filename': att.decrypt_filename(request), 'msgId': status_obj.msg_body.message.uuid } result["attachments"].append(attach_dict) if att.suffix and att.suffix.lower() in ['mp3', 'wav']: audio_list.append(attach_dict) result["refer"] = _get_refer_from_mbus(status_obj, call_enable=call_enable) result["action_history"] = get_message_action_history( status_obj.msg_body.message.id, user, time_zone=local_tz) msgs_list.append(result) context['msgs'] = msgs_list context['audio_list'] = audio_list context['type'] = type return HttpResponse(render_to_string('DoctorCom/Messaging/MessageBody.html', context))
def test_secure_message(self): cleartext = "I drive a Dodge Stratus, don't tell anyone." c = self.client response = c.post('/login/', {'username': '******', 'password': '******'}) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) # verify we are logged in self.assertEqual(c.session['_auth_user_id'], c.user.id) # These should match: self.assertEqual(b64encode(get_user_key(c)), b64encode(strengthen_key('healme'))) # query our KeyPair we created in setup opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) with self.assertRaises(AttributeError): encrypt_object(str, {}, "boo") # NOTE: encrypt_object leaks m._key but using that fact to test this for now msg = encrypt_object(SecureTestMessage, {}, cleartext) # verify keys don't exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, False) with self.assertRaises(Exception): gen_keys_for_users(msg, [c.user], None, None) gen_keys_for_users(msg, [c.user], None, c, ivr=True) # does both default & ivr # test with cache gen_keys_for_users(msg, [self.drbob], msg._key, c) msg._key = None # uncache, test with diff user gen_keys_for_users(msg, [self.adminguy], None, c) # verify keys do exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, True) exists = check_keys_exist_for_users(msg, [c.user, self.adminguy]) self.assertEqual(exists, True) # time passes by .... now decrypt it encobj = EncryptedObject.objects.get_object(msg, opub) # do step by step instead of helper decrypt_object opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) upriv = UserPrivateKey.objects.get(user=c.user, opub=opub) creds = get_user_key(c, response.cookies['ss'].value) clearkey = encobj.decrypt_cipherkey(upriv, creds) self.assertEqual(clearkey, decrypt_cipherkey(c, msg)) # now call the object's decrypt method decrypted_cleartext = msg.decrypt(c, clearkey) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # now try calling top level helper decrypt_object and verify decrypted_cleartext = decrypt_object(c, msg) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # try calling encobj's decrypt with invalid creds with self.assertRaises(KeyInvalidException): decrypt_object(c, msg, ss="malarkey") # create encrypted object without encrypting msg2 = encrypt_object(SecureTestMessage, {}) self.assertTrue(len(msg2.ciphertext) == 0) # now logout, we can alternatively call c.post('/logout/') response = c.logout() self.assertTrue('_auth_user_id' not in c.session) # test str rep of opub self.assertEqual(unicode(opub), u"%s, key type: %s" % (c.user, RSA_TYPES[opub.keytype]), opub) ### tickle the admin interface with all the objs created in this UT ### response = c.post('/login/', {'username': '******', 'password': '******'}) user = authenticate(username='******', password='******') opub = OwnerPublicKey.objects.get_pubkey(owner=user) url = reverse("admin:%s_%s_change" % (opub._meta.app_label, opub._meta.module_name), args=[opub.id]) response = c.get(url) upriv = opub.userprivatekey.get() url = reverse("admin:%s_%s_change" % (upriv._meta.app_label, upriv._meta.module_name), args=[upriv.id]) response = c.get(url) encobj = EncryptedObject.objects.all()[0] url = reverse("admin:%s_%s_change" % (encobj._meta.app_label, encobj._meta.module_name), args=[encobj.id]) response = c.get(url) response = c.logout()
def test_secure_message(self): cleartext = "I drive a Dodge Stratus, don't tell anyone." c = self.client response = c.post('/login/', { 'username': '******', 'password': '******' }) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) # verify we are logged in self.assertEqual(c.session['_auth_user_id'], c.user.id) # These should match: self.assertEqual(b64encode(get_user_key(c)), b64encode(strengthen_key('healme'))) # query our KeyPair we created in setup opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) with self.assertRaises(AttributeError): encrypt_object(str, {}, "boo") # NOTE: encrypt_object leaks m._key but using that fact to test this for now msg = encrypt_object(SecureTestMessage, {}, cleartext) # verify keys don't exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, False) with self.assertRaises(Exception): gen_keys_for_users(msg, [c.user], None, None) gen_keys_for_users(msg, [c.user], None, c, ivr=True) # does both default & ivr # test with cache gen_keys_for_users(msg, [self.drbob], msg._key, c) msg._key = None # uncache, test with diff user gen_keys_for_users(msg, [self.adminguy], None, c) # verify keys do exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, True) exists = check_keys_exist_for_users(msg, [c.user, self.adminguy]) self.assertEqual(exists, True) # time passes by .... now decrypt it encobj = EncryptedObject.objects.get_object(msg, opub) # do step by step instead of helper decrypt_object opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) upriv = UserPrivateKey.objects.get(user=c.user, opub=opub) creds = get_user_key(c, response.cookies['ss'].value) clearkey = encobj.decrypt_cipherkey(upriv, creds) self.assertEqual(clearkey, decrypt_cipherkey(c, msg)) # now call the object's decrypt method decrypted_cleartext = msg.decrypt(c, clearkey) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # now try calling top level helper decrypt_object and verify decrypted_cleartext = decrypt_object(c, msg) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # try calling encobj's decrypt with invalid creds with self.assertRaises(KeyInvalidException): decrypt_object(c, msg, ss="malarkey") # create encrypted object without encrypting msg2 = encrypt_object(SecureTestMessage, {}) self.assertTrue(len(msg2.ciphertext) == 0) # now logout, we can alternatively call c.post('/logout/') response = c.logout() self.assertTrue('_auth_user_id' not in c.session) # test str rep of opub self.assertEqual( unicode(opub), u"%s, key type: %s" % (c.user, RSA_TYPES[opub.keytype]), opub) ### tickle the admin interface with all the objs created in this UT ### response = c.post('/login/', { 'username': '******', 'password': '******' }) user = authenticate(username='******', password='******') opub = OwnerPublicKey.objects.get_pubkey(owner=user) url = reverse("admin:%s_%s_change" % (opub._meta.app_label, opub._meta.module_name), args=[opub.id]) response = c.get(url) upriv = opub.userprivatekey.get() url = reverse("admin:%s_%s_change" % (upriv._meta.app_label, upriv._meta.module_name), args=[upriv.id]) response = c.get(url) encobj = EncryptedObject.objects.all()[0] url = reverse("admin:%s_%s_change" % (encobj._meta.app_label, encobj._meta.module_name), args=[encobj.id]) response = c.get(url) response = c.logout()