Exemple #1
0
    def handle_group_exclude(self, req, connection):
        data = json.loads(req.body)
        if not data["users"]:
            raise HTTPError(400, "Bad Request")

        token = data["auth_token"]
        admin = self._tokens_conn[token].login
        chat_name = data["name"]
        users = set(data["users"])
        users = users.intersection(set(self._users.keys()))

        if not self._chat_groups.exists(chat_name):
            raise HTTPError(404, 'Not found')

        if admin != self._chat_groups[chat_name].admin:
            raise HTTPError(401, "Unauthorized")

        all_users = self._chat_groups[chat_name].users.copy()
        self._chat_groups.remove_users(chat_name, users)
        inform = handle_response(req=req, resp_body={"status": "users excluded", "name": chat_name, "users": list(users)},
                                 resp_status=200, resp_reason="OK", encoding="utf-8")
        for user in users:
            self._users[user].chats.discard(chat_name)

        self.broadcast(inform, all_users, connection)
        return handle_response(req=req, resp_body={"status": "excluded", "name": chat_name, "users": list(users)},
                               resp_status=200, resp_reason="OK", encoding="utf-8")
Exemple #2
0
    def handle_message(self, req: Request,
                       connection: socket.socket) -> Response:
        recievers_group = req.path[len('/message/'):]
        data = json.loads(req.body)
        fl = True
        auth_token = data["auth_token"]
        if self._tokens_conn[auth_token] is None:
            raise HTTPError(404, 'Not found')

        if not self._chat_groups.exists(recievers_group):
            raise HTTPError(404, 'Not found')

        if self._chat_groups[recievers_group].has_user(
                self._tokens_conn[auth_token].login):
            data["text"] = (
                self._tokens_conn[auth_token].login) + ": " + data["text"]
            fl = False
            self.send_message(req, recievers_group, data, connection)
        else:
            raise HTTPError(401, "Unauthorized")
        if fl:
            data["text"] = (
                self._tokens_conn[auth_token].login) + ": " + data["text"]
        return handle_response(req=req,
                               resp_body={
                                   "status": "sent",
                                   "text": data["text"],
                                   "group": recievers_group
                               },
                               resp_status=200,
                               resp_reason='OK',
                               encoding='utf-8')
Exemple #3
0
    def handle_group_delete(self, req, connection):
        data = json.loads(req.body)
        token = data["auth_token"]
        admin = self._tokens_conn[token].login
        chat_name = data["name"]
        if not self._chat_groups.exists(chat_name):
            raise HTTPError(404, 'Not found')

        if admin != self._chat_groups[chat_name].admin:
            raise HTTPError(401, "Unauthorized")

        users = self._chat_groups[chat_name].users.copy()
        del self._chat_groups[chat_name]
        for user in users:
            self._users[user].chats.discard(chat_name)

        inform = handle_response(req=req,
                                 resp_body={
                                     "status": "group deleted",
                                     "name": chat_name
                                 },
                                 resp_status=200,
                                 resp_reason="OK",
                                 encoding="utf-8")
        self.broadcast(inform, users, connection)
        return handle_response(req=req,
                               resp_body={
                                   "status": "delete group",
                                   "name": chat_name
                               },
                               resp_status=200,
                               resp_reason="OK",
                               encoding="utf-8")
Exemple #4
0
    def handle_group_create(self, req, connection):
        data = json.loads(req.body)
        if not data["users"]:
            raise HTTPError(400, "Bad Request")
        token = data["auth_token"]
        admin = self._tokens_conn[token].login
        if not self._chat_groups.exists(data["name"]):
            users = set(data["users"]).intersection(set(self._users.keys()))
            self._chat_groups[data["name"]] = ChatGroup(
                data["name"], admin, users)
            self._users[admin].chats.add(data["name"])
            for user in users:
                self._users[user].chats.add(data["name"])

            inform = handle_response(req=req,
                                     resp_body={
                                         "status": "added to group",
                                         "name": data["name"]
                                     },
                                     resp_status=200,
                                     resp_reason="OK",
                                     encoding="utf-8")
            self.broadcast(inform, users, connection)

            return handle_response(req=req,
                                   resp_body={
                                       "status": "create group",
                                       "name": data["name"]
                                   },
                                   resp_status=204,
                                   resp_reason="Created",
                                   encoding="utf-8")

        raise HTTPError(401, "Unauthorized")
Exemple #5
0
 def parse_request(self, conn):
     rfile = conn.makefile('rb')
     method, target, ver = self.parse_request_line(rfile)
     headers = self.parse_headers(rfile)
     host = headers.get('Host')
     if not host:
         raise HTTPError(400, 'Bad request', 'Host header is missing')
     if host not in (self._server_name,
                     f'{self._server_name}:{self._port}'):
         raise HTTPError(404, 'Not found')
     return Request(method, target, ver, headers, rfile)
Exemple #6
0
    def handle_post_login(self, req, connection: socket.socket):
        data = json.loads(req.body)
        login, password = data["login"], data["password"]
        if self._users[login] is None:
            raise HTTPError(404, 'Not found')

        if self._users[login].password != password:
            raise HTTPError(404, "Unauthorized - wrong password")

        auth_token = self._users.token_for_user(login=login, tokens_conn=self._tokens_conn,
                                                conn_pool=self._pool, conn=connection)
        logging.info(self._users[login].chats)
        return handle_response(req=req, resp_body={"status": "logged in", "token": auth_token, "chats": list(self._users[login].chats)}, resp_status=200,
                               resp_reason='OK', encoding='utf-8', keep_alive=True)
Exemple #7
0
    def parse_request_line(self, rfile):
        raw = rfile.readline(MAX_LINE + 1)
        if len(raw) > MAX_LINE:
            raise HTTPError(400, 'Bad request', 'Request line is too long')

        req_line = str(raw, 'iso-8859-1')
        words = req_line.split()
        if len(words) != 3:
            raise HTTPError(400, 'Bad request', 'Malformed request line')

        method, target, ver = words
        if ver != 'HTTP/1.1':
            raise HTTPError(505, 'HTTP Version Not Supported')
        return method, target, ver
Exemple #8
0
    def handle_request(self, req: Request, connection: socket.socket) -> Response:
        if req.path == '/disconnect' and req.method == 'POST':
            self.handle_post_disconnect(req, connection)

        if req.path == '/registry' and req.method == 'POST':
            return self.handle_post_registry(req)

        if req.path == '/remove' and req.method == 'POST':
            return self.handle_post_remove(req)

        if req.path == '/login' and req.method == 'POST':
            return self.handle_post_login(req, connection)

        if req.path == '/logout' and req.method == 'POST':
            self._connections[connection] = ConnStatus.closing
            return self.handle_post_logout(req)

        if req.path == '/users' and req.method == 'GET':
            return self.handle_get_users(req)

        if req.path == '/test' and req.method == 'GET':
            return self.handle_inf_test(req)

        if req.path.startswith('/message/') and req.method == 'POST':
            return self.handle_message(req, connection)

        if req.path.startswith('/group/') and req.method == 'POST':
            return self.handle_group_action(req, connection)

        if req.path.startswith('/users/'):
            user_id = req.path[len('/users/'):]
            if user_id.isdigit():
                return self.handle_get_user(req, user_id)

        raise HTTPError(404, 'Not found')
Exemple #9
0
    def parse_headers(self, rfile):
        headers = []
        while True:
            line = rfile.readline(MAX_LINE + 1)
            if len(line) > MAX_LINE:
                raise HTTPError(494, 'Request header too large')

            if line in (b'\r\n', b'\n', b''):
                break

            headers.append(line)
            if len(headers) > MAX_HEADERS:
                raise HTTPError(494, 'Too many headers')

        sheaders = b''.join(headers).decode('iso-8859-1')
        return Parser().parsestr(sheaders)
Exemple #10
0
    def handle_group_action(self, req, connection):
        data = json.loads(req.body)
        action = req.path[len('/group/'):]
        if not data["auth_token"]:
            raise HTTPError(401, "Unauthorized")
        if not data["name"]:
            raise HTTPError(400, "Bad Request")
        if action == "create":
            return self.handle_group_create(req, connection)
        elif action == "delete":
            return self.handle_group_delete(req, connection)
        elif action == "add":
            return self.handle_group_add(req, connection)
        elif action == "exclude":
            return self.handle_group_exclude(req, connection)

        raise HTTPError(404, 'Not found')
Exemple #11
0
 def handle_prepare(self, req: Request):
     accept = req.headers.get('Accept')
     data = json.loads(req.body)
     auth_token = data["auth_token"]
     if self._tokens_conn.get(auth_token):
         return accept, data, auth_token
     else:
         raise HTTPError(400, "Invalid token")
Exemple #12
0
 def handle_get_user(self, req: Request, login: str) -> Response:
     user = self._users[login]
     if not user:
         raise HTTPError(404, 'Not found')
     return handle_response(req=req,
                            resp_body=user.json_prepare(),
                            resp_status=200,
                            resp_reason='OK',
                            encoding='utf-8')
Exemple #13
0
def handle_response(req: Request, resp_body, resp_status, resp_reason, encoding: str, default=None,
                    keep_alive=False) -> Response:
    accept = req.headers.get('Accept')
    if 'application/json' in accept:
        contentType = f'application/json; charset={encoding}'
        body = json.dumps(resp_body, default=default)
    else:
        # https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
        raise HTTPError(406, 'Not Acceptable')

    body = body.encode(f'{encoding}')
    headers = [('Content-Type', contentType),
               ('Content-Length', len(body))]
    if keep_alive:
        headers.append(('Connection', 'Keep-Alive'))
        headers.append(('Keep-Alive', 'timeout=5, max=1000'))
    return Response(resp_status, resp_reason, headers, body)