def connect(self): """ set user along with connection info """ username = self.request.json_body.get('username') def_status = self.request.registry.settings['status_codes']['online'] user_status = int(self.request.json_body.get('status', def_status)) conn_id = self.request.json_body.get('conn_id') subscribe_to_channels = self.request.json_body.get('channels') if username is None: self.request.response.status = 400 return {'error': "No username specified"} if not subscribe_to_channels: self.request.response.status = 400 return {'error': "No channels specified"} # everything is ok so lets add new user and channels with lock: if not username in USERS: user = User(username, def_status) USERS[username] = user else: user = USERS[username] user.last_active = datetime.utcnow() for channel_name in subscribe_to_channels: channel = CHANNELS.get(channel_name) if not channel: channel = Channel(channel_name) CHANNELS[channel_name] = channel else: channel.last_active = datetime.utcnow() user.allowed_channels.extend(subscribe_to_channels) log.info('connecting %s' % username) return {'status': user.status}
def test_create_defaults(self): user = User("test_user") user.state_from_dict({"key": "1", "key2": "2"}) user.state_public_keys = ["key2"] assert repr(user) == "<User:test_user, connections:0>" assert sorted(user.state.items()) == sorted({"key": "1", "key2": "2"}.items()) assert user.public_state == {"key2": "2"}
def connect(self): """return the id of connected users - will be secured with password string for webapp to internally call the server - we combine conn string with user id, and we tell which channels the user is allowed to subscribe to""" user_name = self.request.json_body.get('user') def_status = self.request.registry.server_config['status_codes'][ 'online'] user_status = int(self.request.json_body.get('status', def_status)) conn_id = self.request.json_body.get('conn_id') subscribe_to_channels = self.request.json_body.get('channels') if user_name is None: self.request.response.status = 400 return {'error': "No username specified"} if not subscribe_to_channels: self.request.response.status = 400 return {'error': "No channels specified"} # everything is ok so lets add new connection to channel and connection list if not user_name in users: user = User(user_name, def_status) users[user_name] = user else: user = users[user_name] connection = Connection(user_name, conn_id) if not connection.id in connections: connections[connection.id] = connection user.add_connection(connection) for channel_name in subscribe_to_channels: # user gets assigned to a channel if channel_name not in channels: channel = Channel(channel_name) channels[channel_name] = channel channels[channel_name].add_connection(connection) log.info('connecting %s with uuid %s' % (user_name, connection.id)) return {'conn_id': connection.id, 'status': user.status}
def test_user_single_assignment(self, test_uuids): server_state = get_state() user = User("test_user") connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) channel = Channel("test") server_state.channels[channel.name] = channel channel.add_connection(connection) assert [channel] == user.get_channels()
def test_create_defaults(self): user = User("test_user") user.state_from_dict({"key": "1", "key2": "2"}) user.state_public_keys = ["key2"] assert repr(user) == "<User:test_user, connections:0>" assert sorted(user.state.items()) == sorted({ "key": "1", "key2": "2" }.items()) assert user.public_state == {"key2": "2"}
def test_remove_connection_w_presence(self, test_uuids): server_state = get_state() user = User("test_user") server_state.users[user.username] = user connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) config = {"notify_presence": True, "broadcast_presence_with_user_lists": True} channel = Channel("test", channel_config=config) channel.add_connection(connection) channel.remove_connection(connection)
def test_users_active(self): server_state = get_state() user = User("test_user") server_state.users[user.username] = user user2 = User("test_user2") server_state.users[user2.username] = user2 channelstream.gc.gc_users() assert len(server_state.users.items()) == 2 user.last_active -= timedelta(days=2) channelstream.gc.gc_users() assert len(server_state.users.items()) == 1
def test_presence_message(self, test_uuids): user = User("test_user") connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) channel = Channel("test") channel.add_connection(connection) payload = channel.send_notify_presence_info("test_user", "join") assert payload["user"] == "test_user" assert payload["message"]["action"] == "join" assert payload["type"] == "presence" assert payload["channel"] == "test" assert len(payload["users"]) == 0
def test_remove_connection_w_presence(self, test_uuids): server_state = get_state() user = User("test_user") server_state.users[user.username] = user connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) config = { "notify_presence": True, "broadcast_presence_with_user_lists": True } channel = Channel("test", channel_config=config) channel.add_connection(connection) channel.remove_connection(connection)
def test_user_state(self, test_uuids): user = User("test_user") changed = user.state_from_dict({"key": "1", "key2": "2"}) user.state_public_keys = ["key2"] connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) channel = Channel("test") channel.add_connection(connection) payload = channel.send_user_state(user, changed) assert payload["user"] == "test_user" assert payload["message"]["state"] == {"key2": "2"} assert payload["message"]["changed"] == [{"key": "key2", "value": "2"}] assert payload["type"] == "user_state_change" assert payload["channel"] == "test"
def test_add_connection_w_presence(self): server_state = get_state() user = User("test_user") server_state.users[user.username] = user connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) config = { "notify_presence": True, "broadcast_presence_with_user_lists": True } channel = Channel("test", channel_config=config) channel.add_connection(connection) assert len(channel.connections["test_user"]) == 1 assert "test_user" in channel.connections assert connection in channel.connections["test_user"]
def test_gc_connections_collecting(self, test_uuids): server_state = get_state() channel = Channel("test") server_state.channels[channel.name] = channel channel2 = Channel("test2") server_state.channels[channel2.name] = channel2 user = User("test_user") server_state.users[user.username] = user user2 = User("test_user2") server_state.users[user2.username] = user2 connection = Connection("test_user", test_uuids[1]) server_state.connections[connection.id] = connection connection2 = Connection("test_user", test_uuids[2]) connection2.mark_for_gc() server_state.connections[connection2.id] = connection2 connection3 = Connection("test_user2", test_uuids[3]) connection3.mark_for_gc() server_state.connections[connection3.id] = connection3 connection4 = Connection("test_user2", test_uuids[4]) server_state.connections[connection4.id] = connection4 user.add_connection(connection) user.add_connection(connection2) channel.add_connection(connection) channel.add_connection(connection2) user2.add_connection(connection3) user2.add_connection(connection4) channel2.add_connection(connection3) channel2.add_connection(connection4) channelstream.gc.gc_conns() assert len(server_state.connections.items()) == 2 conns = server_state.channels["test"].connections["test_user"] assert len(conns) == 1 assert conns == [connection] conns = server_state.channels["test2"].connections["test_user2"] assert len(conns) == 1 assert conns == [connection4] assert len(user.connections) == 1 assert len(user2.connections) == 1 connection.mark_for_gc() connection4.mark_for_gc() channelstream.gc.gc_conns() assert "test_user" not in server_state.channels["test"].connections assert "test_user2" not in server_state.channels["test2"].connections assert len(server_state.channels["test"].connections.items()) == 0 assert len(server_state.channels["test2"].connections.items()) == 0
def connect( username=None, fresh_user_state=None, state_public_keys=None, update_user_state=None, conn_id=None, channels=None, channel_configs=None, ): """ :param username: :param fresh_user_state: :param state_public_keys: :param update_user_state: :param conn_id: :param channels: :param channel_configs: :return: """ server_state = get_state() with server_state.lock: if username not in server_state.users: user = User(username) user.state_from_dict(fresh_user_state) server_state.users[username] = user else: user = server_state.users[username] if state_public_keys is not None: user.state_public_keys = state_public_keys user.state_from_dict(update_user_state) connection = Connection(username, conn_id) if connection.id not in server_state.connections: server_state.connections[connection.id] = connection user.add_connection(connection) for channel_name in channels: # user gets assigned to a channel if channel_name not in server_state.channels: channel = Channel( channel_name, channel_config=channel_configs.get(channel_name) ) server_state.channels[channel_name] = channel server_state.channels[channel_name].add_connection(connection) log.info("connecting %s with uuid %s" % (username, connection.id)) return connection, user
def test_messages(self, test_uuids): user = User("test_user") connection = Connection("test_user", conn_id=test_uuids[1]) connection.queue = Queue() connection2 = Connection("test_user", conn_id=test_uuids[2]) connection2.queue = Queue() user.add_connection(connection) user.add_connection(connection2) user.add_message({ "type": "message", "no_history": False, "pm_users": [], "exclude_users": [], }) assert len(user.connections) == 2 assert len(user.connections[0].queue.get()) == 1 assert len(user.connections[1].queue.get()) == 1
def test_gc_connections_active(self, test_uuids): server_state = get_state() channel = Channel("test") server_state.channels[channel.name] = channel channel2 = Channel("test2") server_state.channels[channel2.name] = channel2 user = User("test_user") server_state.users[user.username] = user user2 = User("test_user2") server_state.users[user2.username] = user2 connection = Connection("test_user", test_uuids[1]) server_state.connections[connection.id] = connection connection2 = Connection("test_user", test_uuids[2]) server_state.connections[connection2.id] = connection2 connection3 = Connection("test_user2", test_uuids[3]) server_state.connections[connection3.id] = connection3 connection4 = Connection("test_user2", test_uuids[4]) server_state.connections[connection4.id] = connection4 user.add_connection(connection) user.add_connection(connection2) channel.add_connection(connection) channel.add_connection(connection2) user2.add_connection(connection3) user2.add_connection(connection4) channel2.add_connection(connection3) channel2.add_connection(connection4) channelstream.gc.gc_conns() conns = server_state.channels["test"].connections["test_user"] assert len(conns) == 2 assert len(server_state.connections.items()) == 4 conns = server_state.channels["test2"].connections["test_user2"] assert len(conns) == 2 assert len(user.connections) == 2 assert len(user2.connections) == 2 assert sorted(channel.connections.keys()) == ["test_user"] assert sorted(channel2.connections.keys()) == ["test_user2"]
def test_user_multi_assignment(self, test_uuids): server_state = get_state() user = User("test_user") connection = Connection("test_user", conn_id=test_uuids[1]) connection2 = Connection("test_user", conn_id=test_uuids[2]) connection3 = Connection("test_user", conn_id=test_uuids[3]) user.add_connection(connection) user.add_connection(connection2) user.add_connection(connection3) channel = Channel("test") channel2 = Channel("test2") server_state.channels[channel.name] = channel server_state.channels[channel2.name] = channel2 channel.add_connection(connection) channel.add_connection(connection2) channel2.add_connection(connection3) assert ["test", "test2"] == sorted([c.name for c in user.get_channels()])
def test_messages(self, test_uuids): user = User("test_user") connection = Connection("test_user", conn_id=test_uuids[1]) connection.queue = Queue() connection2 = Connection("test_user", conn_id=test_uuids[2]) connection2.queue = Queue() user.add_connection(connection) user.add_connection(connection2) user.add_message( { "type": "message", "no_history": False, "pm_users": [], "exclude_users": [], } ) assert len(user.connections) == 2 assert len(user.connections[0].queue.get()) == 1 assert len(user.connections[1].queue.get()) == 1
def test_presence_message_w_users(self, test_uuids): server_state = get_state() user = User("test_user") user.state_from_dict({"key": "1", "key2": "2"}) user.state_public_keys = ["key2"] server_state.users[user.username] = user connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) user2 = User("test_user2") user2.state_from_dict({"key": "1", "key2": "2"}) server_state.users[user2.username] = user2 connection2 = Connection("test_user2", conn_id=test_uuids[2]) user2.add_connection(connection2) config = {"notify_presence": True, "broadcast_presence_with_user_lists": True} channel = Channel("test", channel_config=config) channel.add_connection(connection) channel.add_connection(connection2) payload = channel.send_notify_presence_info("test_user", "join") assert len(payload["users"]) == 2 sorted_users = sorted(payload["users"], key=lambda x: x["user"]) assert sorted_users == [ {"state": {"key2": "2"}, "user": "******"}, {"state": {}, "user": "******"}, ]
def test_presence_message_w_users(self, test_uuids): server_state = get_state() user = User("test_user") user.state_from_dict({"key": "1", "key2": "2"}) user.state_public_keys = ["key2"] server_state.users[user.username] = user connection = Connection("test_user", conn_id=test_uuids[1]) user.add_connection(connection) user2 = User("test_user2") user2.state_from_dict({"key": "1", "key2": "2"}) server_state.users[user2.username] = user2 connection2 = Connection("test_user2", conn_id=test_uuids[2]) user2.add_connection(connection2) config = { "notify_presence": True, "broadcast_presence_with_user_lists": True } channel = Channel("test", channel_config=config) channel.add_connection(connection) channel.add_connection(connection2) payload = channel.send_notify_presence_info("test_user", "join") assert len(payload["users"]) == 2 sorted_users = sorted(payload["users"], key=lambda x: x["user"]) assert sorted_users == [ { "state": { "key2": "2" }, "user": "******" }, { "state": {}, "user": "******" }, ]