def __init__(self, port, ip, client_process): self.channel_port = port self.ip = ip self.registry = UserRegistry() self.client_process = client_process self.receiver = MessageReceiver(self.ip, self.channel_port) logger.info("Server initialized.")
def _wrapper(func): user = None if pk: user = User.objects.get(pk=pk) else: if hasattr(settings,"USER_REGISTRY__SYSTEM_USER_ID"): user = User.objects.get(pk=settings.USER_REGISTRY__SYSTEM_USER_ID) if user: UserRegistry.register(user) else: raise UserRegistryNoSystemUserError() return func
class TestUserRegistry(unittest.TestCase): """ Tests user registry by setting up the registry and sending messages. Alternatively, methods of registry could be tested separately. """ def setUp(self): self.senderMailboxMock = MailboxMock() self.userRegistryMailbox = MailboxMock(proxyMock=self.senderMailboxMock) self.userRegistry = UserRegistry(self.userRegistryMailbox, 0.01) self.userRegistry.start() def tearDown(self): self.userRegistry.stop() self.userRegistry.join() def test_register_user(self): testUserName = '******' try: # Should register new user correctly requestMsg = self.userRegistryMailbox.create_message(MessageType.USER_REGISTRY_NEW_USER, testUserName) self.userRegistryMailbox.put(requestMsg) responseMsg = self.senderMailboxMock.get(timeout=1) self.assertEqual(MessageType.USER_REGISTRY_NEW_USER, responseMsg.messageType) userName, isSuccess = responseMsg.data self.assertEqual(testUserName, userName) self.assertTrue(isSuccess) # Should not register same user twice self.userRegistryMailbox.put(requestMsg) responseMsg = self.senderMailboxMock.get(timeout=1) self.assertEqual(MessageType.USER_REGISTRY_NEW_USER, responseMsg.messageType) userName, isSuccess = responseMsg.data self.assertEqual(testUserName, userName) self.assertFalse(isSuccess) except queue.Empty: self.fail('user registry did not respond in time')
class Server: """ Murmur server. """ def __init__(self, port, ip, client_process): self.channel_port = port self.ip = ip self.registry = UserRegistry() self.client_process = client_process self.receiver = MessageReceiver(self.ip, self.channel_port) logger.info("Server initialized.") def start_processing(self): """ Starts the server for actual processing. """ logger.info("Server processing started.") Thread(name='Server Processing Thread', target=self.__process_requests, daemon=True).start() def __process_requests(self): """ Processes local and network messages. If it originates from a known client, it will try to parse the command or send it to everyone if it is not a command. If it originated from an unknown client it will try to register them. """ for received_message in self.receiver: if self.registry.ip_known(received_message.sender): logger.info("Message received from registered client.") if received_message.body.startswith(COMMAND_FLAG_CHAR): logger.debug("Message was a command.") self.parse(received_message.body) else: logger.debug("Message was generic.") self.send_to_all(received_message) else: logger.info("Message received from an unregistered client.") self.attempt_to_register(received_message) def parse(self, message: Message): """ Try to make sense out of a command sent to the server from a registered client. message - a message object """ pass def register_hosting_client(self, username: str): """ Registers the hosting client's username with the registry. username - a client's username """ if self.validate_name(username): self.registry.register(username, 'local') def attempt_to_register(self, message: Message): """ Called when a message is received from an unregistered client. Tries to match the sent message with the proper registration format. If it can't register the client, the client is ignored. message - a Message object to parse. """ logger.info("Attempting to register client.") successful_parse = re.match(r'\/regi (.{1,30})', message.body) if successful_parse and self.validate_name(successful_parse.group(1)): logger.info("Client successfully registered.") self.registry.register(successful_parse.group(1), message.sender) else: logger.info("Client not registered") # Ignore the message def validate_name(self, username: str) -> bool: """ Checks to see if the username is valid. username - a string for the registering client's username """ return not self.registry.name_taken(username) def send(self, message_body: str, target: str): """ Sends a message to a client. If the message fails to send, the target is removed from the registry and presumed to be disconnected. target - the ip of the message recipient. message_body - a string to send the target. """ if target == 'local': self.client_process(message_body) else: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: try: sock.settimeout(1) sock.connect((target, self.channel_port)) sock.send(message_body.encode()) except socket.timeout: self.registry.delete_ip(target) def send_to_all(self, message: Message): """ Sends a message to all ips in the registry. Appends the username before sending the message. message - a message object """ to_send = self.registry.get_user(message.sender) + ": " + message.body for ip in self.registry.ip(): self.send(to_send, ip) def send_as_hosting_user(self, message_body: str): """ Sends a message under the server's registered user name. message_body - a string to send """ self.receiver.receive(Message(message_body, 'local'))
def setUp(self): self.senderMailboxMock = MailboxMock() self.userRegistryMailbox = MailboxMock(proxyMock=self.senderMailboxMock) self.userRegistry = UserRegistry(self.userRegistryMailbox, 0.01) self.userRegistry.start()
def process_response(self, request, response): user = self.get_user(request) if user: UserRegistry.unregister(user, request) return response
def process_request(self, request): user = self.get_user(request) if user: UserRegistry.register(user, request)