class SesssonStoreTest(TestCase): def setUp(self): # create session and key self.session = SessionStore() self.session.create() self.session_key = self.session.session_key def test_flush(self): # check that folder and key exists self.assertTrue(os.path.exists(os.path.join(settings.UPLOADED_IMAGES_ROOT, self.session_key))) Session.objects.get(session_key=self.session_key) # flush the session self.session.flush() # check that session doesnt exist and folder is deleted with self.assertRaises(Session.DoesNotExist): Session.objects.get(session_key=self.session_key) self.assertFalse(os.path.exists(os.path.join(settings.UPLOADED_IMAGES_ROOT, self.session_key))) def test_create(self): self.assertTrue(self.session.exists(self.session_key)) root = os.path.join(settings.UPLOADED_IMAGES_ROOT, self.session_key) self.assertTrue(os.path.exists(root)) self.assertTrue(os.path.exists(os.path.join(root, "undo"))) self.assertTrue(os.path.exists(os.path.join(root, "redo"))) def tearDown(self): if self.session.exists(self.session_key): self.session.flush()
def clear_all(): sessions = Session.objects.get_queryset() for s in sessions: SessionStore(s.session_key).flush() for session_folder in [x for x in os.walk(settings.UPLOADED_IMAGES_ROOT)][0][1]: path = os.path.join(settings.UPLOADED_IMAGES_ROOT, session_folder) shutil.rmtree(path)
def session_clean(testing=True): """Runs at set periods, cleans session images and database""" if settings.TESTING and testing: return print("\n\tRUNNING CLEAN") max_time = 1_209_600 # 2 weeks # clear expired SessionStore.clear_expired() print("\tCLEARED EXPIRED 1 WEEK AFTER INACTIVITY") cleared_after_max_time = [] cleared_if_no_folder = [] # get queryset to iterate over sessions sessions = Session.objects.get_queryset() for s in sessions: # clear after max_time if s.get_decoded()["start"] + max_time < time.time(): SessionStore(s.session_key).flush() cleared_after_max_time.append(s.session_key) # if folder doesn't exist if not os.path.exists(os.path.join(settings.UPLOADED_IMAGES_ROOT, s.session_key)): cleared_if_no_folder.append(s.session_key) SessionStore(s.session_key).flush() cleared_folders = [] session_keys = [s.session_key for s in sessions] # all session keys for session_folder in [x for x in os.walk(settings.UPLOADED_IMAGES_ROOT)][0][1]: # clear if folder does not have session key if session_folder not in session_keys: path = os.path.join(settings.UPLOADED_IMAGES_ROOT, session_folder) shutil.rmtree(path) cleared_folders.append(session_folder) # output clear details print(f"""\tCleared after {max_time} seconds: {cleared_after_max_time} \tCleared because it had no folder: {cleared_if_no_folder} \tCleared because folder had no key in database: {cleared_folders} \tSessions in database: {len(session_keys)}\n""")
def remove_session(r): """Removes session from same ip""" # removes another session from same ip try: # get ip ip, _ = get_client_ip(r) # iterate over sessions for s in Session.objects.iterator(): # decode session data decoded = s.get_decoded() # if session's ip is clients ip, remove it and break from loop if decoded["ip"] == ip: SessionStore(s.session_key).flush() return JsonResponse({"status": "success"}) return JsonResponse({"status": "fail"}) except: return JsonResponse({"status": "fail"})
def test_remove_session(self): # set ip in request headers self.r.META.update({ 'HTTP_X_FORWARDED_FOR': '127.0.0.1', }) # session ips to populate database with ips = ["127.0.0.1", "127.0.0.1", "0"] # in try, finally block to remove all sessions in case an error occurs try: # create other sessions sessions = [] for ip in ips: s = SessionStore() s["ip"] = ip s.create() sessions.append(s) # send through view response = views.remove_session(self.r) # check for success self.assertTrue( json.loads(response.getvalue())["status"] == "success") # get all remaining ips all_ips = [ s.get_decoded()["ip"] for s in Session.objects.get_queryset() ] # check that 1 ip has been removed self.assertTrue(len(all_ips) == len(ips) - 1) # there should be 1 '127.0.0.1' and 1 '0' ip left self.assertTrue("127.0.0.1" in all_ips) self.assertTrue("0" in all_ips) finally: # clear other sessions for s in sessions: s.flush()
def test_upload_page_with_session(self): try: self.r.session.create() # set request headers so the ip should be 127.0.0.1 self.r.META.update({ 'HTTP_X_FORWARDED_FOR': '127.0.0.1', }) response = views.image_upload_page(self.r) response_parse = BeautifulSoup(response.getvalue(), "html.parser") upload_page_parser = BeautifulSoup( render(self.r, "image_editor_app/upload.html").getvalue(), "html.parser") self.assertTrue(response_parse.get_text, upload_page_parser.get_text) sessions = [] # create sessions for _ in range(3): s = SessionStore() s["ip"] = "127.0.0.1" s.create() sessions.append(s) response = views.image_upload_page(self.r) self.assertTrue( response._headers["location"][-1] == reverse("uploadpage") + "?error=iplimit") finally: try: for s in sessions: s.flush() except NameError: pass
def setUp(self): self.s = SessionStore()
class TestSessionClean(TestCase): def setUp(self): self.s = SessionStore() def test_clear_inactive(self): # set expiry to 1 second self.s.set_expiry(1) # create session self.s.create() # wait 3 seconds time.sleep(3) # call the cleaner with False testing argument as, with testing=True, function returns instantly session_cleaner.session_clean(False) # check expired session is cleared self.assertTrue([s for s in Session.objects.get_queryset()] == []) def test_max_time(self): # set start to 0, should be expired self.s["start"] = 0 # set to high value, shouldn't be cleared from activity expiration self.s.set_expiry(1000) self.s.create() # call the cleaner with False testing argument as, with testing=True, function returns instantly session_cleaner.session_clean(False) # check session deleted self.assertTrue([s for s in Session.objects.get_queryset()] == []) def test_no_session_key(self): # make a folder in uploaded images directory path = os.path.join(settings.UPLOADED_IMAGES_ROOT, "test_should_be_deleted") os.mkdir(path) # call the cleaner with False testing argument as, with testing=True, function returns instantly session_cleaner.session_clean(False) # check folder is deleted self.assertFalse(os.path.exists(path)) def test_no_folder(self): # create session self.s["start"] = time.time() self.s.set_expiry(1000) self.s.create() # remove folder shutil.rmtree(os.path.join(settings.UPLOADED_IMAGES_ROOT, self.s.session_key)) # call the cleaner with False testing argument as, with testing=True, function returns instantly session_cleaner.session_clean(False) # check session is cleared self.assertTrue([s for s in Session.objects.get_queryset()] == []) def test_valid(self): # no expiry, with folder, nothing should be removed self.s["start"] = time.time() self.s.set_expiry(1000) self.s.create() # call the cleaner with False testing argument as, with testing=True, function returns instantly session_cleaner.session_clean(False) # check sessions in database is a list with the session key self.assertTrue([s.session_key for s in Session.objects.get_queryset()] == [self.s.session_key]) def tearDown(self): if self.s.exists(self.s.session_key): self.s.flush()
def setUp(self): self.r = HttpRequest() self.r.session = SessionStore() self.r.session["ip"] = "127.0.0.1"
def test_perform_action(self): # json data for edit data = {"type": "rotate", "data": "1"} # create custom request object that returns the json data when read from self.r = CustomReadRequest(json.dumps(data)) # create session object self.r.session = SessionStore() self.r.session["ip"] = "127.0.0.1" self.r.session["last"] = time.time() self.r.session["type"] = ".jpeg" self.r.session.create() """test only works with POST""" # check raises Http404 when not using POST self.assertRaises(Http404, views.perform_action, self.r) # set method to POST self.r.method = "POST" """test time throttling""" # check that number of edits is throttled self.r.session["last"] = time.time() self.assertTrue( json.loads(views.perform_action(self.r).getvalue())["error-type"] == "time") self.r.session["last"] = 0 """test normal request""" # path of 'current.jpeg' image current_root = os.path.join(settings.UPLOADED_IMAGES_ROOT, self.r.session.session_key, "current.jpeg") # create random image image_array = np.random.randint(0, 255, size=(5, 10, 3)) # save random image Image.fromarray(image_array, mode="RGB").save(current_root, format="JPEG") # get response response = views.perform_action(self.r) # regex for the link ( anything, session_key/current., any 3 or 4 characters (file extension) ) link_regex = ".*/" + self.r.session.session_key + "/current\.[a-z]{3,4}" link = json.loads(response.getvalue())["imageLink"] # check given link is correct against regex self.assertIsNotNone(match(link_regex, link)) # check image has been rotated self.assertTrue(np.array(Image.open(current_root)).shape == (10, 5, 3)) self.r.session.flush() """test incorrect json""" # incorrect json data for edit data = {"incorrectjson": "incorrect"} # create custom request object that returns the json data when read from self.r = CustomReadRequest(json.dumps(data)) # create session object self.r.session = SessionStore() # set settings self.r.session["ip"] = "127.0.0.1" self.r.session["last"] = 0 self.r.session["type"] = ".jpeg" self.r.session.create() self.r.method = "POST" # check error due to incorrect json self.assertTrue( json.loads(views.perform_action(self.r).getvalue())["type"] == "error") """test only works with valid session""" self.r.session.flush() self.assertRaises(Http404, views.perform_action, self.r)
def setUp(self): # create session and key self.session = SessionStore() self.session.create() self.session_key = self.session.session_key