Example #1
0
def user_migrate(event, context):
    logger.info("User migaration triggered")

    try:
        user_data = event['request']['userAttributes']
    except:
        logger.info("failed to get user data")

    try:
        if user_data is not None:
            db.collection("users").add({
                "email":
                user_data["email"],
                "uId":
                user_data["sub"],
                "email_verified":
                user_data["email_verified"],
                "username":
                user_data["preferred_username"],
                "Gender":
                user_data["gender"]
            })
    except:
        logger.info("Failed to put user object!")

    return event
Example #2
0
def send_message(event, context):
    body = _get_body(event)
    if not isinstance(body, dict):
        return _get_response(400, "Message body not in dict format.")
    for attribute in ["token", "content"]:
        if attribute not in body:
            return _get_response(400, "'{}' not in message dict" \
                                 .format(attribute))

    # Verify the token
    try:
        auth_data = ws_token_auth(body["token"],
                                  body["auth"] if "auth" in body else 0)
        if auth_data['effect'] == "Deny":
            return _get_response(400, "Token verification failed.")

        email = auth_data['data']['email']
        username = auth_data['data']['preferred_username']
    except:
        return _get_response(400, "Token verification failed.")

    table = dynamodb.Table("serverless-chat_Messages")
    # Add the new message to the database
    timestamp = int(time.time())
    content = body["content"]
    table_ref = db.collection(u'rooms').document(u'general').collection(
        u'messages')
    table_ref.add({
        "created_at": timestamp,
        "email": email,
        "content": content
    })

    # Get all current connections
    table = dynamodb.Table("serverless-chat_Connections")
    response = table.scan(ProjectionExpression="ConnectionID")
    items = response.get("Items", [])
    connections = db.collection(u'connections').get()
    connections = list(map(lambda doc: doc.id, connections))

    # Send the message data to all connections
    message = {
        "sender": {
            "username": username,
            "email": email
        },
        "content": content,
        "created_at": timestamp
    }
    logger.debug("Broadcasting message: {}".format(message))
    data = {"messages": [message], "end": 1}
    for connectionID in connections:
        _send_to_connection(connectionID, data, event)
    return _get_response(200, "Message sent to {} connections." \
                         .format(len(connections)))
Example #3
0
def connection_manager(event, context):
    # logger.info(event)
    connectionID = event["requestContext"].get("connectionId")
    token = event.get("queryStringParameters", {}).get("token")

    if event["requestContext"]["eventType"] == "CONNECT":
        # logger.info("Connect requested (CID: {}, Token: {})" \
        #             .format(connectionID, token))

        # Ensure connectionID and token are set
        if not connectionID:
            logger.error("Failed: connectionId value not set.")
            return _get_response(500, "connectionId value not set.")
        if not token:
            return _get_response(400, "token query parameter not provided.")

        if event.get("requestContext", {}).get("authorizer") is not None:
            email = event.get("requestContext", {}).get("authorizer",
                                                        {}).get("email")
        else:
            user_obj = get_user_by_email(jwt_decode(token)['email'])
            if len(user_obj) > 0:
                email = user_obj[0]["email"]

        # Add connectionID to the database
        user_ref = db.collection(u'users').document(email)
        user_ref.update({'connectionID': connectionID})

        connection_ref = db.collection(u'connections').document(connectionID)
        connection_ref.set({'email': email})

        return _get_response(200, "Connect successful.")

    elif event["requestContext"]["eventType"] == "DISCONNECT":
        logger.info("Disconnect requested (CID: {})".format(connectionID))

        # Ensure connectionID is set
        if not connectionID:
            logger.error("Failed: connectionId value not set.")
            return _get_response(500, "connectionId value not set.")

        # Remove the connectionID from the database
        connections_ref = db.collection(u'connections').document(
            connectionID).get()
        if connections_ref.exists:
            conn_obj = connections_ref.to_dict()

            email = conn_obj['email']

            user_ref = db.collection(u'users').document(email)
            user_ref.update({'connectionID': ''})

            db.collection(u'connections').document(connectionID).delete()
            return _get_response(200, "Disconnect successful.")
        else:
            return _get_response(400, "Invalid connection id.")
    else:
        logger.error("Connection manager received unrecognized eventType '{}'" \
                     .format(event["requestContext"]["eventType"]))
        return _get_response(500, "Unrecognized eventType.")
Example #4
0
def get_user_by_email(email=""):
    username_obj = []
    if type(email) == str and email != "":
        try:
            username_response = db.collection(u'users').document(email).get()
            if username_response.exists:
                username_obj.append({
                    **username_response.to_dict(), 'email':
                    email
                })
        except ValueError as e:
            logger.debug("Failed: Table parse failed.")

        return username_obj
Example #5
0
def set_user(event, context):
    body = _get_body(event)
    if body['email'] is None:
        return _get_response(400, "'{}' not in request" \
                             .format("email"))

    email = body['email']
    user_obj = get_user_by_email(email)

    if len(user_obj) > 0:
        return _get_response(404, "User already exists")
    else:
        # username_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, username))
        tokens = get_auth_tokens(email)
        # try:
        user_item = {
            "email_verified": False,
            "username": email.split("@")[0],
            "accessToken": tokens["access_token"],
            "refreshToken": tokens["refresh_token"],
            "connectionID": ""
        }
        db.collection("users").document(email).set(user_item)
        return _get_response(200, user_item)
Example #6
0
def get_recent_messages(event, context):
    body = _get_body(event)
    connectionID = event["requestContext"].get("connectionId")
    logger.info("Retrieving most recent messages for CID '{}'" \
                .format(connectionID))

    # Ensure connectionID is set
    if not connectionID:
        logger.error("Failed: connectionId value not set.")
        return _get_response(500, "connectionId value not set.")

    LastEvaluatedKeyIn = None
    if "LastEvaluatedKey" in body:
        LastEvaluatedKeyIn = body["LastEvaluatedKey"]

    limit = 100
    try:
        if "limit" in body and body["limit"] < 60:
            limit = body["limit"]
    except ValueError:
        logger.error("Error in getting limit")

    logger.info(LastEvaluatedKeyIn)

    messages = []
    if LastEvaluatedKeyIn is not None:
        query = db.collection(u'rooms').\
            document(u'general').collection(u'messages').\
            order_by(u'created_at', direction=firestore.Query.DESCENDING).\
            limit(limit).start_after(LastEvaluatedKeyIn).stream()
        print(response)
    else:
        query = db.collection(u'rooms'). \
            document(u'general').collection(u'messages'). \
            order_by(u'created_at', direction=firestore.Query.DESCENDING).\
            start_after("54zvuhw1yi80bVMU5ZCd").limit(limit).stream()

    LastEvaluatedKeyOut = None
    for doc in query:
        LastEvaluatedKeyOut = doc.to_dict()
        message = doc.to_dict()
        messages.append({
            "email": message["email"],
            "content": message["content"],
            "created_at": message["created_at"]
        })

    messages.reverse()
    parsed_user = {}

    def map_function(x):
        if x['email'] not in parsed_user:
            parsed_user[x['email']] = get_user_by_email(x['email'])[0]

        resp = {
            **x, "sender": {
                "username": parsed_user[x['email']]["username"],
                "email": parsed_user[x['email']]["email"]
            }
        }
        if "email" in resp:
            del resp['email']

        return resp

    messages = list(map(map_function, messages))
    logger.info(messages)

    # Send them to the client who asked for it
    data = {"messages": messages}

    if LastEvaluatedKeyOut is not None:
        data["LastEvaluatedKey"] = LastEvaluatedKeyOut

    _send_to_connection(connectionID, data, event)

    return _get_response(200, "Sent recent messages to '{}'." \
                         .format(connectionID))