示例#1
0
def message_unpin(token, message_id):
    """Given a message within a channel, remove it's mark as unpinned"""
    # Validate token
    if not validator.is_valid_token(token):
        raise ValueError(INVALID_TOKEN)

    # Decode token
    u_id = jwt_handler.decode_token(token)

    user = database.get_user_by_id(u_id)
    message = database.get_message_by_id(message_id)
    if message is None:
        raise ValueError(MESSAGE_UNPIN_NOT_EXIST)
    channel = database.get_channel_by_id(message["channel_id"])

    if user["permission"] not in [OWNER, ADMIN] \
            and u_id not in channel["owner_ids"]:
        raise AccessError(MESSAGE_UNPIN_NO_AUTH)

    # Checking data
    if u_id not in channel["auth_ids"]:
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    if message["is_pinned"] is False:
        raise ValueError(MESSAGE_NOT_PINNED)

    # Unpinning message
    database.update_message_by_id(message_id, {"is_pinned": False})
    return {}
示例#2
0
def message_pin(token, message_id):
    """
    Given a message within a channel, mark it as "pinned" to be given special
    display treatment by the frontend
    """
    # Validate token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    # Decode token
    u_id = jwt_handler.decode_token(token)

    user = database.get_user_by_id(u_id)
    message = database.get_message_by_id(message_id)
    if message is None:
        raise ValueError(MESSAGE_PIN_NOT_EXIST)
    channel = database.get_channel_by_id(message["channel_id"])

    if user["permission"] not in [OWNER, ADMIN] \
            and u_id not in channel["owner_ids"]:
        raise ValueError(MESSAGE_PIN_NO_AUTH)

    # Checking data
    if u_id not in channel["auth_ids"]:
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    if message["is_pinned"] is True:
        raise ValueError(MESSAGE_ALREADY_PINNED)

    # Pinning message
    database.update_message_by_id(message_id, {"is_pinned": True})
    return {}
示例#3
0
def channel_removeowner(token, channel_id, u_id):
    """Remove user with user id u_id an owner of this channel"""
    # Convert channel_id and u_id to integer
    channel_id = int(channel_id)
    u_id = int(u_id)

    # Validate token, channel and user
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel(channel_id):
        raise ValueError(INVALID_CHANNEL)
    if not validator.is_valid_user(u_id):
        raise ValueError(INVALID_USER)

    # Locate channel and user in database
    channel = database.get_channel_by_id(channel_id)
    auth_user_id = jwt_handler.decode_token(token)
    auth_user = database.get_user_by_id(auth_user_id)
    owner_list = channel["owner_ids"]

    if auth_user["permission"] not in [OWNER, ADMIN] or\
            auth_user_id not in channel["owner_ids"]:
        raise AccessError(CHANNEL_DEL_OWNER_NO_AUTH)

    # Check that the added_user is currently an owner
    if u_id not in owner_list:
        raise ValueError(CHANNEL_NOT_OWNER)

    # Remove user from owner_ids
    owner_list.remove(u_id)
    database.update_channel_by_id(channel_id, {
        "owner_ids": owner_list
    })

    return {}
示例#4
0
def admin_userpermission_change(token, u_id, permission_id):
    """Given a User by their user ID, set their permissions to new permissions
    described by permission_id"""
    permission_id = int(permission_id)
    # Check validity
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_user(u_id):
        raise ValueError(INVALID_USER)
    if permission_id not in [OWNER, ADMIN, MEMBER]:
        raise ValueError(INVALID_PERM_ID)

    # Get users
    user_acting = database.get_user_by_id(jwt_handler.decode_token(token))
    user_target = database.get_user_by_id(u_id)

    # Check that token has valid permissions for this permission id, then make
    # the change
    if user_acting["permission"] == OWNER:
        # Owners can do anything
        database.update_user_by_id(u_id, {"permission": permission_id})
    elif user_acting["permission"] == ADMIN and\
            user_target["permission"] != OWNER and\
            permission_id != OWNER:
        database.update_user_by_id(u_id, {"permission": permission_id})
    else:
        raise AccessError(NO_PERMISSION)

    return {}
示例#5
0
def channel_join(token, channel_id):
    """Given a channel_id of a channel that the authorised user can join, adds
    them to that channel"""
    # Validate token and channel ID
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel(channel_id):
        raise ValueError(INVALID_CHANNEL)

    # Convert token to u_id
    u_id = jwt_handler.decode_token(token)
    user = database.get_user_by_id(u_id)

    # Locate channel in database
    channel = database.get_channel_by_id(channel_id)

    # If channel is private
    if not channel["is_public"] and user["permission"] == MEMBER:
        # If the user is not an admin/owner
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    # Add user to authorised users in channel
    auth_list = channel["auth_ids"]
    if u_id not in auth_list:
        auth_list.append(u_id)
        database.update_channel_by_id(channel_id, {
            "auth_ids": auth_list
        })
    else:
        raise ValueError(CHANNEL_ALREADY_JOINED)

    return {}
示例#6
0
def message_edit(token, message_id, message):
    """Given a message, update it's text with new text"""
    # Validate token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    # If the message is empty, perform deletion instead
    if message == "":
        return message_remove(token, message_id)

    if not validator.is_valid_message(message):
        raise ValueError(INVALID_MESSAGE)

    # Convert token to u_id
    u_id = jwt_handler.decode_token(token)

    user = database.get_user_by_id(u_id)
    message_dict = database.get_message_by_id(message_id)
    if message_dict is None:
        raise ValueError(MESSAGE_EDIT_NOT_EXIST)

    channel_id = message_dict["channel_id"]
    channel = database.get_channel_by_id(channel_id)

    # Check if user can edit this message
    if u_id == message_dict["u_id"] or user["permission"] in [OWNER, ADMIN] \
            or u_id in channel["owner_ids"]:
        database.update_message_by_id(message_id, {"message": message})
        return {}
    raise AccessError(MESSAGE_EDIT_NO_AUTH)
示例#7
0
def channel_invite(token, channel_id, u_id):
    """Invites a user (with user id u_id) to join a channel with ID channel_id.
    Once invited the user is added to the channel immediately"""
    # Convert channel_id and u_id to integer
    channel_id = int(channel_id)
    u_id = int(u_id)

    # Validate token, channel and user
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel(channel_id):
        raise ValueError(INVALID_CHANNEL)
    if not validator.is_valid_user(u_id):
        raise ValueError(INVALID_USER)

    # Find invitor
    invitor_id = jwt_handler.decode_token(token)

    # Locate channel in database
    channel = database.get_channel_by_id(channel_id)

    # Check that the invitor is authorised
    auth_list = channel["auth_ids"]

    if invitor_id not in auth_list:
        raise AccessError(CHANNEL_INV_NO_AUTH)
    if u_id in auth_list:
        raise ValueError(CHANNEL_ALREADY_JOINED)
    auth_list.append(u_id)
    database.update_channel_by_id(channel_id, {
        "auth_ids": auth_list
    })
    return {}
示例#8
0
def message_sendlater(token, channel_id, message, time_sent):
    """
    Send a message from authorised_user to the channel specified by channel_id
    """
    # Validate data
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_message(message):
        raise ValueError(INVALID_MESSAGE)

    # Convert token to u_id
    u_id = jwt_handler.decode_token(token)
    # Check channel exists
    channel = database.get_channel_by_id(channel_id)
    if channel is None:
        raise ValueError(INVALID_CHANNEL)

    # Read time_sent
    time_to_send = json_time_translator.timestamp_to_datetime(time_sent)
    # Check time_to_send is not in the past
    if time_to_send <= datetime.utcnow():
        raise ValueError(MESSAGE_TIME_INVALID)

    if u_id not in channel["auth_ids"]:
        raise AccessError(MESSAGE_SEND_NO_AUTH)

    # Create message
    message_id = database.add_message({
        "u_id":
        u_id,
        "message":
        message,
        "channel_id":
        int(channel_id),
        "time_created":
        json_time_translator.datetime_to_json(time_to_send),
        "is_pinned":
        False,
        "reacts": []
    })
    # Insert into channel's list of messages in order of time
    message_id_list = channel["messages"]

    inserted = False
    for i in reversed(range(len(message_id_list))):
        json_time = database.get_message_by_id(
            message_id_list[i])["time_created"]
        timestamp = json_time_translator.json_to_timestamp(json_time)
        if timestamp <= int(float(time_sent)):
            message_id_list.insert(i + 1, message_id)
            inserted = True
            break
    if inserted is False:
        message_id_list.insert(0, message_id)
    database.update_channel_by_id(channel_id, {"messages": message_id_list})
    return {"message_id": message_id}
示例#9
0
def message_react(token, message_id, react_id):
    """
    Given a message within a channel the authorised user is part of, add a
    "react" to that particular message
    """
    # Validate
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    # Decode token
    u_id = jwt_handler.decode_token(token)

    # Change react_id to an integer
    if not isinstance(react_id, int):
        react_id = int(react_id)
    if not isinstance(message_id, int):
        message_id = int(message_id)

    # Validate data
    message = database.get_message_by_id(message_id)
    channel = database.get_channel_by_id(message["channel_id"])

    if u_id not in channel["auth_ids"]:
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    if react_id != 1:
        print(react_id)
        raise ValueError(INVALID_REACT)

    react_id_exists = False
    for react in message["reacts"]:
        if react_id == react["react_id"]:
            react_id_exists = True
            if u_id in react["u_id"]:
                raise ValueError(MESSAGE_ALREADY_REACTED)
            break

    # Add react to message
    react_list = message["reacts"]
    if not react_id_exists:
        react_list.append({"react_id": react_id, "u_id": [u_id]})
    else:
        for react in react_list:
            if react_id == react["react_id"]:
                react["u_id"].append(u_id)
                break

    database.update_message_by_id(message_id, {"reacts": react_list})
    return {}
示例#10
0
def auth_passwordreset_request(email):
    """Given an email address, if the user is a registered user, send's them a
    an email containing a specific secret code, that when entered in
    auth_passwordreset_reset, shows that the user trying to reset the password
    is the one who got sent this email."""
    # Validate data
    users = database.get_all_users()
    if validator.is_unique_email(email):
        raise ValueError(EMAIL_NOT_FOUND)

    for user in users:
        if user["email"] == email:
            # Deletes previous reset code
            if user["pw_reset_code"] != "":
                code_generator.delete_reset_code(user["pw_reset_code"])

            reset_code_str = code_generator.generate_code()
            database.update_user_by_id(user["u_id"],
                                       {"pw_reset_code": reset_code_str})

            # Sends email with reset_code
            mail = Mail(current_app)
            try:
                msg = Message("Password reset from COMP1531",
                              sender="*****@*****.**",
                              recipients=[email])
                msg.body = reset_code_str
                mail.send(msg)
            except Exception as excp:
                print(str(excp))
    return {}
示例#11
0
def channel_leave(token, channel_id):
    """Given a channel ID, the user removed as a member of this channel"""
    # Validate token and channel ID
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel(channel_id):
        raise ValueError(INVALID_CHANNEL)

    # Convert token to u_id
    u_id = jwt_handler.decode_token(token)


    # Locate channel
    channel = database.get_channel_by_id(channel_id)

    # Validate user is in channel
    auth_list = channel["auth_ids"]
    if u_id not in auth_list:
        raise AccessError(NOT_IN_CHANNEL)

    # Remove user from auth_list
    auth_list.remove(u_id)
    database.update_channel_by_id(channel_id, {
        "auth_ids": auth_list
    })

    # If owner, remove from owner_list
    owner_list = channel["owner_ids"]
    if u_id in owner_list:
        owner_list.remove(u_id)
        database.update_channel_by_id(channel_id, {
            "owner_ids": owner_list
        })

    return {}
示例#12
0
def message_remove(token, message_id):
    """
    Given a message_id for a message, this message is removed from the chxnel
    """
    # Validate token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    if not isinstance(message_id, int):
        message_id = int(message_id)

    # Convert token to u_id
    u_id = jwt_handler.decode_token(token)

    # Check u_id is authorised
    user = database.get_user_by_id(u_id)
    message = database.get_message_by_id(message_id)
    if message is None:
        raise ValueError(MESSAGE_REMOVE_NOT_EXIST)

    channel_id = message["channel_id"]
    channel = database.get_channel_by_id(channel_id)
    # if sender of message
    if u_id == message["u_id"] or\
            user["permission"] in [OWNER, ADMIN] or\
            u_id in channel["owner_ids"]:
        # Delete message from database
        database.delete_message_by_id(message_id)
        # Delete message from channel
        channel["messages"].remove(message_id)
        database.update_channel_by_id(channel_id, channel)
        return {}
    raise AccessError(MESSAGE_EDIT_NO_AUTH)
示例#13
0
def standup_start(token, channel_id, length):
    """Will return standup finish time if user and channel are both valid"""
    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    length = int(length)

    # Check channel existence
    channel = database.get_channel_by_id(channel_id)
    if channel is None:
        raise ValueError(INVALID_CHANNEL)

    # Check user is member of channel
    u_id = jwt_handler.decode_token(token)
    if u_id not in channel["auth_ids"]:
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    # Check the startup is not currently active in this channel
    old_time_end = database.get_standup_finish_time(channel_id)
    if old_time_end is not None and\
            json_time_translator.json_to_datetime(old_time_end) >= datetime.utcnow():
        raise ValueError(STANDUP_RUNNING)

    # Check for non-zero length
    if length <= 0:
        raise ValueError(STANDUP_TIME_INVALID)

    # Set channel standup_end to now+X min and add finish time to database
    time_end_datetime = datetime.utcnow() + timedelta(seconds=length)
    time_end_json = json_time_translator.datetime_to_json(time_end_datetime)

    # Move old standup messages
    database.move_standup_to_unused_by_id(channel_id)

    database.update_standup_by_id(channel_id, {
        "time_finish": time_end_json,
        "length": length
    })

    time_end_timestamp = int(
        json_time_translator.datetime_to_timestamp(time_end_datetime))

    # Start threaded timer
    standup_timer_start(token, channel_id, length)

    return {"time_finish": time_end_timestamp}
示例#14
0
def message_unreact(token, message_id, react_id):
    """
    Given a message within a channel the authorised user is part of, remove a
    "react" to that particular message
    """
    # Validate
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    # Decode token
    u_id = jwt_handler.decode_token(token)

    # Change react_id to an integer
    if not isinstance(react_id, int):
        react_id = int(react_id)
    if not isinstance(message_id, int):
        message_id = int(message_id)

    # Validate data
    message = database.get_message_by_id(message_id)
    channel = database.get_channel_by_id(message["channel_id"])

    if u_id not in channel["auth_ids"]:
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    if react_id != 1:
        print(react_id)
        raise ValueError(INVALID_REACT)

    react_list = message["reacts"]
    react_found = False
    for react in react_list:
        if react_id == react["react_id"] and u_id in react["u_id"]:
            react_found = True
            break

    if not react_found:
        raise ValueError(MESSAGE_NOT_REACTED)

    # Remove react from message
    for react in react_list:
        if react_id == react["react_id"]:
            react["u_id"].remove(u_id)

    database.update_message_by_id(message_id, {"reacts": react_list})
    return {}
示例#15
0
def user_profiles_uploadphoto(token, img_url, x_start, y_start, x_end, y_end):
    """Given a URL of an image on the internet, crops the image within bounds
    (x_start, y_start) and (x_end, y_end). Position (0,0) is the top left."""
    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    x_start = int(x_start)
    y_start = int(y_start)
    x_end = int(x_end)
    y_end = int(y_end)


    if img_url[-3:].lower() != "jpg" and img_url[-4:].lower() != "jpeg":
        raise ValueError(IMAGE_NOT_JPG)

    # Save Image
    file_name = json_time_translator.datetime_to_timestamp(datetime.utcnow())
    local_url = f"server_files/static/{file_name}"
    try:
        urlretrieve(img_url, local_url + ".jpg")
    except Exception:
        raise ValueError(IMAGE_CANT_FETCH)

    image_object = Image.open(local_url + ".jpg")

    width, height = image_object.size
    if not 0 <= x_start < width or not 0 < x_end <= width or not \
            0 <= y_start < height or not 0 < y_end <= height:
        raise ValueError(INVALID_COORDINATES)

    if x_end <= x_start or y_end <= y_start:
        raise ValueError(INVALID_CROP)

    cropped = image_object.crop((x_start, y_start, x_end, y_end))
    cropped.save(local_url + "_crop.jpg")

    # Change current user's profile image
    u_id = jwt_handler.decode_token(token)
    database.update_user_by_id(u_id, {
        "profile_img_url": f"http://127.0.0.1:5001/static/{file_name}_crop.jpg"
    })

    return {}
示例#16
0
def channel_addowner(token, channel_id, u_id):
    """Make user with user id u_id an owner of this channel"""
    # Convert channel_id and u_id to integer
    channel_id = int(channel_id)
    u_id = int(u_id)

    # Validate token, channel and user
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel(channel_id):
        raise ValueError(INVALID_CHANNEL)
    if not validator.is_valid_user(u_id):
        raise ValueError(INVALID_USER)

    # Locate channel and user in database
    channel = database.get_channel_by_id(channel_id)
    auth_user_id = jwt_handler.decode_token(token)
    auth_user = database.get_user_by_id(auth_user_id)

    # Check auth_user permissions
    if auth_user["permission"] not in [OWNER, ADMIN] or\
            auth_user_id not in channel["owner_ids"]:
        raise AccessError(CHANNEL_ADD_OWNER_NO_AUTH)


    # Add user to auth_ids
    auth_list = channel["auth_ids"]
    if u_id not in auth_list:
        auth_list.append(u_id)
        database.update_channel_by_id(channel_id, {
            "auth_ids": auth_list
        })

    # Add user to owner_ids
    owner_list = channel["owner_ids"]
    if u_id in owner_list:
        raise ValueError(CHANNEL_ALREADY_OWNER)
    owner_list.append(u_id)
    database.update_channel_by_id(channel_id, {
        "owner_ids": owner_list
    })

    return {}
示例#17
0
def standup_send(token, channel_id, message):
    """Adds message to standup buffer if standup is currently active"""

    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    # Check channel existence
    channel = database.get_channel_by_id(channel_id)
    if channel is None:
        raise ValueError(INVALID_CHANNEL)

    # Check user is member of channel
    u_id = jwt_handler.decode_token(token)
    if u_id not in channel["auth_ids"]:
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    # Check the startup is not currently active in this channel
    old_time_end = database.get_standup_finish_time(channel_id)
    if old_time_end is None or\
            json_time_translator.json_to_datetime(old_time_end) < datetime.utcnow():
        raise ValueError(STANDUP_NOT_RUNNING)

    # Check valid message
    if not validator.is_valid_message(message):
        raise ValueError(INVALID_MESSAGE)

    # Save message
    database.add_standup_message(
        channel_id, {
            "u_id":
            u_id,
            "message":
            message,
            "time_created":
            json_time_translator.datetime_to_json(datetime.utcnow()),
        })

    return {}
示例#18
0
def auth_login(email, password):
    """Given a registered users' email and password and generates a valid token
    for the user to remain authenticated"""
    # Validate data
    if not validator.is_valid_email(email):
        raise ValueError(INVALID_EMAIL)

    # Loop searches within the user database
    users = database.get_all_users()
    for user in users:
        # Checks if email matches an email
        if user["email"] == email:
            # Checks if password matches the email's password
            if user["password"] != password:
                raise ValueError(WRONG_PASS)
            # Creates a new token for the user
            token = jwt_handler.encode_u_id(user["u_id"])
            token_list = user["tokens"]
            token_list.append(token)
            # Updates the json file
            database.update_user_by_id(user["u_id"], {"tokens": token_list})
            return {"u_id": user["u_id"], "token": token}
    raise ValueError(EMAIL_NOT_FOUND)
示例#19
0
def user_profile_sethandle(token, handle_str):
    """Update the authorised user's handle (i.e. display name)"""

    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    u_id = jwt_handler.decode_token(token)

    # Check valid handle
    if not validator.is_valid_handle(handle_str):
        raise ValueError(INVALID_HANDLE)

    # Check if handle is already in use
    if not validator.is_unique_handle(handle_str):
        raise ValueError(NOT_UNIQUE_HANDLE)

    # Update the database with new changes
    database.update_user_by_id(u_id, {
        "handle": handle_str
    })

    return {}
示例#20
0
def user_profile_setemail(token, email):
    """Update the authorised user's email address"""

    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    u_id = jwt_handler.decode_token(token)

    # Check valid email
    if not validator.is_valid_email(email):
        raise ValueError(INVALID_EMAIL)

    # Check that email is not already in use
    if not validator.is_unique_email(email):
        raise ValueError(NOT_UNIQUE_EMAIL)

    # Update the database with new changes
    database.update_user_by_id(u_id, {
        "email": email
    })

    return {}
示例#21
0
def auth_passwordreset_reset(reset_code, new_password):
    """Given a reset code for a user, set that user's new password to the
    password provided"""
    # Validate data
    if not validator.is_valid_password(new_password):
        raise ValueError(INVALID_PASS)

    # Ignore reset_code
    if reset_code == "":
        raise ValueError(EMPTY_RESET_CODE)

    users = database.get_all_users()
    reset_code_found = False
    for user in users:
        if user["pw_reset_code"] == reset_code:
            reset_code_found = True
            database.update_user_by_id(user["u_id"], {
                "password": new_password,
                "pw_reset_code": ""
            })
            code_generator.delete_reset_code(reset_code)
    if not reset_code_found:
        raise ValueError(INVALID_RESET_CODE)
    return {}
示例#22
0
def channel_details(token, channel_id):
    """Given a Channel with ID channel_id that the authorised user is part of,
    provide basic details about the channel"""
    # Validate token and channel
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel(channel_id):
        raise ValueError(INVALID_CHANNEL)

    # Find user in database
    u_id = jwt_handler.decode_token(token)

    # Locate in database
    channel = database.get_channel_by_id(channel_id)
    user = database.get_user_by_id(u_id)

    # Check user is authorised
    if u_id not in channel["auth_ids"] and user["permission"] == MEMBER:
        raise AccessError(CHANNEL_CANT_VIEW_DETAIL)

    # Compile channel details
    owner_list = channel["owner_ids"]
    auth_list = channel["auth_ids"]
    owner_list_with_details = []
    auth_list_with_details = []
    for owner_id in owner_list:
        owner = database.get_user_by_id(owner_id)
        owner_list_with_details.append({
            "u_id": owner_id,
            "name_first": owner["name_first"],
            "name_last": owner["name_last"],
            "profile_img_url": owner["profile_img_url"]})
    for auth_id in auth_list:
        auth = database.get_user_by_id(auth_id)
        auth_list_with_details.append({
            "u_id": auth_id,
            "name_first": auth["name_first"],
            "name_last": auth["name_last"],
            "profile_img_url": auth["profile_img_url"]})
    return {
        "name": channel["name"],
        "owner_members": owner_list_with_details,
        "all_members": auth_list_with_details
    }
示例#23
0
def user_profile_setname(token, name_first, name_last):
    """Update the authorised user's first and last name"""

    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    u_id = jwt_handler.decode_token(token)

    # Check Valid input Name
    if not validator.is_valid_name(name_first) or not validator.is_valid_name(name_last):
        raise ValueError(INVALID_NAME)

    # Update the database with new changes
    database.update_user_by_id(u_id, {
        "name_first": name_first,
        "name_last": name_last
    })

    return {}
示例#24
0
def standup_active(token, channel_id):
    """Adds message to standup buffer if standup is currently active"""

    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    # Check channel existence
    channel = database.get_channel_by_id(channel_id)
    if channel is None:
        raise ValueError(INVALID_CHANNEL)

    is_active = is_standup_running(channel_id)
    time_finish = None
    if is_active:
        time_finish = int(
            json_time_translator.json_to_timestamp(
                database.get_standup_finish_time(channel_id)))

    return {"is_active": is_active, "time_finish": time_finish}
示例#25
0
def user_profile(token, u_id):
    """For a valid user, returns information about their email, first name,
    last name, and handle"""

    # Check valid token
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)

    # Check u_id is valid
    if not validator.is_valid_user(u_id):
        raise ValueError(INVALID_USER)

    # Return user profile
    user = database.get_user_by_id(u_id)
    return {
        "email": user["email"],
        "name_first": user["name_first"],
        "name_last": user["name_last"],
        "handle_str": user["handle"],
        "profile_img_url": user["profile_img_url"]
    }
示例#26
0
def channels_create(token, name, is_public):
    """Creates a new channel with that name that is either a public or private channel"""
    # Convert is_public to boolean
    is_public = is_public.lower() in ("true", "yes", "t", "1")

    # Validate token & data
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel_name(name):
        raise ValueError(CHANNEL_LONG_NAME)

    # Convert token to u_id
    u_id = jwt_handler.decode_token(token)

    # Create channel and get ID
    channel_id = database.add_channel({
        "name": name,
        "messages": [],
        "is_public": is_public,
        "owner_ids": [u_id],
        "auth_ids": [u_id]
    })
    return {"channel_id": channel_id}
示例#27
0
def channel_messages(token, channel_id, start):
    """Given a Channel with ID channel_id that the authorised user is part of,
    return up to 50 messages between index "start" and "start + 50". Message
    with index 0 is the most recent message in the channel. This function
    returns a new index "end" which is the value of "start + 50", or, if this
    function has returned the least recent messages in the channel, returns -1
    in "end" to indicate there are no more messages to load after this
    return."""
    # Convert 'start' to an integer
    start = int(start)

    # Validate token and channel ID
    if not validator.is_valid_token(token):
        raise AccessError(INVALID_TOKEN)
    if not validator.is_valid_channel(channel_id):
        raise ValueError(INVALID_CHANNEL)

    # Locate channel
    channel = database.get_channel_by_id(channel_id)

    # Validate that token user is in channel
    u_id = jwt_handler.decode_token(token)
    if u_id not in channel["auth_ids"]:
        raise AccessError(CHANNEL_CANT_VIEW_MSG)

    # Validate messages exist
    total_messages = len(channel['messages'])
    if total_messages <= 0:
        return {
            "messages": [],
            "start": start,
            "end": -1
        }

    # Validate start point
    if start > (total_messages - 1) or start < 0:
        raise ValueError(CHANNEL_NO_MORE_MSG)

    # Find index for the most recent message (reference list backwards)
    start_index = len(channel['messages']) - 1 - start
    # Get all recent messages up to 50
    messages = []
    end = start + 49
    for msg_num in range(50):
        index = start_index - msg_num
        # If there are less than 50 msgs
        if index < 0:
            end = -1
            break

        # Get message object
        message_id = channel['messages'][index]
        message = database.get_message_by_id(message_id)

        # If message is sent later or not there
        if message is None or\
                json_time_translator.json_to_datetime(message["time_created"]) >= datetime.utcnow():
            continue

        # Create output-able list of reacts
        react_list = []
        reacted_ids = []
        all_reacts = database.get_all_reacts(message_id)
        react_id = 1
        for react in all_reacts:
            is_this_user_reacted = False
            if react["react_id"] == react_id:
                reacted_ids.extend(react["u_id"])
                if u_id in react["u_id"]:
                    is_this_user_reacted = True
                # Only add the reaction if it has at least one count of a user
                react_list.append({
                    "react_id": react_id,
                    "u_ids": reacted_ids,
                    "is_this_user_reacted": is_this_user_reacted
                })

        # print(message["time_created"])
        # print(json_time_translator.json_to_datetime(message["time_created"]))
        # print(json_time_translator.json_to_timestamp(message["time_created"]))
        # Append to file
        messages.append({
            "message_id": message_id,
            "u_id": message["u_id"],
            "message": message["message"],
            "time_created": json_time_translator.json_to_timestamp(message["time_created"]),
            "reacts": react_list,
            "is_pinned": message["is_pinned"]
        })

    return {
        "messages": messages,
        "start": start,
        "end": end
    }
示例#28
0
def auth_register(email, password, name_first, name_last):
    """Given a user's first and last name, email address, and password,
    create a new account for them and return a new token for authentication
    in their session. A handle is generated that is the concatentation of a
    lowercase-only first name and last name. If the concatenation is longer
    than 20 characters, it is cutoff at 20 characters. If the handle is
    already taken, you may modify the handle in any way you see fit to
    make it unique."""
    # Validate data
    if not validator.is_valid_name(name_first):
        raise ValueError(INVALID_NAME_FIRST)
    if not validator.is_valid_name(name_last):
        raise ValueError(INVALID_NAME_LAST)
    if not validator.is_valid_email(email):
        raise ValueError(INVALID_EMAIL)
    if not validator.is_unique_email(email):
        raise ValueError(NOT_UNIQUE_EMAIL)
    if not validator.is_valid_password(password):
        raise ValueError(INVALID_PASS)

    # Set permission to MEMBER
    perm = constants.MEMBER
    # If no members, permission is OWNER
    if len(database.get_all_users()) == 0:
        perm = constants.OWNER

    # user["handle"] handling
    if len(name_first + name_last) > 20:
        handle = []
        temp = (name_first + name_last).lower()

        for x in range(0, 20):
            handle.append(temp[x])
        handle_str = "".join(handle)
    else:
        handle_str = (name_first + name_last).lower()

    users = database.get_all_users()
    index = 0
    for user in users:
        if user["handle"][0:len(handle_str)] == handle_str:
            index += 1

    if index > 0:
        handle_str = handle_str + str(index)

    u_id = database.add_user({
        "tokens": [],
        "name_first":
        name_first,
        "name_last":
        name_last,
        "handle":
        handle_str,
        "email":
        email,
        "password":
        password,
        "permission":
        perm,
        "pw_reset_code":
        "",
        "profile_img_url":
        "http://127.0.0.1:5001/static/default.jpg"
    })

    token = jwt_handler.encode_u_id(u_id)
    user = database.get_user_by_id(u_id)
    token_list = user["tokens"]
    token_list.append(token)
    database.update_user_by_id(u_id, {"tokens": token_list})
    return {"token": token}