Esempio n. 1
0
    def contacts_contains(self, user1_email, user2_email):
        valid_contact_email1 = validate_and_normalize_email(user1_email)
        valid_contact_email2 = validate_and_normalize_email(user2_email)
        if not valid_contact_email1 or not valid_contact_email2:
            return "Invalid Email Address."

        email1_hash = SHA256.new(valid_contact_email1.encode()).hexdigest()
        user = self.users[email1_hash]
        return user.contacts and valid_contact_email2 in user.contacts
Esempio n. 2
0
 def add_contact(self, email, contact_name, contact_email):
     valid_contact_email = validate_and_normalize_email(contact_email)
     if not valid_contact_email:
         return "Invalid Email Address."
     if not contact_name:
         return "Invalid contact name."
     email_hash = SHA256.new(email.encode()).hexdigest()
     user = self.users[email_hash]
     if not user.contacts:
         user.contacts = dict()
     user.contacts[valid_contact_email] = contact_name
     self.write_json()
     return ""
Esempio n. 3
0
 def register_new_user(self, name, email, password):
     valid_email = validate_and_normalize_email(email)
     if valid_email is None:
         return "Invalid Email Address."
     email_hash = SHA256.new(valid_email.encode()).hexdigest()
     if email_hash in self.users:
         return "User already exists."
     self.users[email_hash] = ClientData(name=name,
                                         email=valid_email,
                                         password=password,
                                         contacts=dict())
     self.write_json()
     log.info("User Registered.")
     return ""
Esempio n. 4
0
    async def add_contact(self):
        msg = None
        try:
            name = input("Enter Full Name: ")
            email = input("Enter Email Address: ")
            valid_email = validate_and_normalize_email(email)
            if valid_email is None:
                raise RuntimeError("Invalid Email Address.")
            if not name:
                raise RuntimeError("Empty name input.")

            await self.write(bytes(AddContactPackets(name, valid_email)))
            msg = StatusPackets(data=(await self.read())[4:]).message
            if msg != "":
                raise RuntimeError(msg)
        except RuntimeError as e:
            msg = str(e)
        if msg != "":
            print("Failed to add contact: ", msg)
Esempio n. 5
0
    def register_prompt(self):
        name = input("Enter Full Name: ")
        email = input("Enter Email Address: ")
        valid_email = validate_and_normalize_email(email)
        if valid_email is None:
            raise RuntimeError("Invalid Email Address.")
        if valid_email in self.users:
            raise RuntimeError("That email already exists!")

        pw1 = getpass.getpass(prompt="Enter Password: "******"Re-enter password: "******"The two entered passwords don't match!")

        # enforce password length to min of 12 characters
        if len(pw1) < 12:
            raise RuntimeError(
                "Password is too short! Password must be at least 12 characters"
            )

        if not name or not valid_email or not pw1:
            raise RuntimeError("Empty input")

        return name, valid_email, pw1
Esempio n. 6
0
    async def send_file(self):
        msg = None
        try:
            # 1. `X -> Y/F -> S`: X wants to send F to Y

            recipient_email = input("Enter the recipient's email address: ")
            file_path = os.path.abspath(input("Enter the file path: "))
            valid_email = validate_and_normalize_email(recipient_email)
            if valid_email is None:
                raise RuntimeError("Invalid Email Address.")
            if not file_path:
                raise RuntimeError("Empty file path.")
            if not os.path.exists(file_path):
                raise RuntimeError("Cannot find file: {}".format(file_path))
            if not os.path.isfile(file_path):
                raise RuntimeError("Not a file: {}".format(file_path))

            file_base = os.path.basename(file_path)
            file_size = os.path.getsize(file_path)
            file_sha256 = sha256_file(file_path)
            file_info = {
                "name": file_base,
                "size": file_size,
                "SHA256": file_sha256,
            }

            # send request
            await self.write(
                bytes(FileTransferRequestPackets(valid_email, file_info)))

            # this only checks if the request is valid
            # this does not check if the recipient accepted or denied the request
            msg = StatusPackets(data=(await self.read())[4:]).message
            if msg != "":
                raise RuntimeError(msg)

            # 7. `S -> Token/Port -> X`: S sends the same token and port to X

            # denied request is indicated by empty token and port
            port_and_token = FileTransferSendPortTokenPackets(
                data=(await self.read())[4:])
            port, token = port_and_token.port, port_and_token.token
            if token and port:
                print(
                    "User {} accepted the file transfer Connecting to recipient on port "
                    .format(valid_email, port))
            else:
                raise RuntimeError(
                    "User {} declined the file transfer request".format(
                        valid_email))

            progress = shared_memory.SharedMemory(create=True, size=8)
            progress_lock = Lock()
            p2p_client = P2PClient(port, token, file_path, file_size,
                                   file_sha256, progress.name, progress_lock)

            time_start = time.time()
            sentinel = False

            chunk_size = FILE_TRANSFER_P2P_CHUNK_SIZE

            def unguarded_print_sent_progress(final=False):
                utils.print_status(
                    *utils.get_progress(
                        int.from_bytes(progress.buf[0:4], byteorder='little'),
                        int.from_bytes(progress.buf[4:8], byteorder='little'),
                        chunk_size), "sent", final)

            def print_sent_progress():
                while not sentinel:
                    with progress_lock:
                        unguarded_print_sent_progress()
                    time.sleep(0.03)

            # i was having trouble with asyncio.gather, so just run status printer in a new thread
            status_thread = Thread(target=print_sent_progress)
            status_thread.start()

            # wait until p2p transfer completes, unless keyboard interrupt
            try:
                await p2p_client.main()
            except KeyboardInterrupt:
                raise RuntimeError("User requested abort")
            finally:
                sentinel = True
                status_thread.join()
                unguarded_print_sent_progress(final=True)
                progress.close()
                progress.unlink()
                time_end = time.time()

            print(
                "\nFile transfer completed in {} seconds.".format(time_end -
                                                                  time_start))

        except RuntimeError as e:
            msg = str(e)
        if msg != "":
            print("Failed to send file: ", msg)