def test_generate_handle():
    '''
    Ensures handles that are generated are unique
    '''
    # Initialisation
    global_var.initialise_all()

    # First instance of handle in server
    user1 = auth.auth_register("*****@*****.**", "pass123", "Ashley", "Huang")
    user1 = helpers.get_user_by_token(user1["token"])
    assert user1.handle == "ashleyhuang"

    # Non-first instance of handle in server - substitute found
    user2 = auth.auth_register("*****@*****.**", "pass123", "Ashley", "Huang")
    user2 = helpers.get_user_by_token(user2["token"])
    assert user2.handle == "1ashleyhuang"

    # Non-first instance of handle in server - first no substitute found
    auth.auth_register("*****@*****.**", "pass123", "3Ashley", "Huang")
    user4 = auth.auth_register("*****@*****.**", "pass123", "Ashley", "Huang")
    user4 = helpers.get_user_by_token(user4["token"])
    assert user4.handle == "0"

    # Non-first instance of handle in server - second no substitute found
    auth.auth_register("*****@*****.**", "pass123", "5Ashley", "Huang")
    user6 = auth.auth_register("*****@*****.**", "pass123", "Ashley", "Huang")
    user6 = helpers.get_user_by_token(user6["token"])
    assert user6.handle == "1"
def test_get_user_token_by_u_id():
    '''
    Ensures that the correct token is obtained by get_user_token_by_u_id
    '''

    # Initialisation
    global_var.initialise_all()

    # Creating a user
    user = auth.auth_register("*****@*****.**", "pass123", "Raydon", "Smith")

    assert helpers.get_user_token_by_u_id(user["u_id"]) == user["token"]

    with pytest.raises(AccessError, match="Invalid Token"):
        helpers.get_user_by_token(-1)
def message_edit(token, message_id, message):
    '''
    Given a message, update it's text with new text. If the new message is an
    empty string, the message is deleted.
    '''

    channel = get_channel_by_message_id(message_id)
    message_obj = get_message_by_message_id(message_id)
    user = get_user_by_token(token)

    # message_id does not refer to an existing message
    if not valid_message_id(message_id):
        raise ValueError("Message does not exist")

    # message is not of appropriate length
    if valid_message(message):
        raise ValueError("Message length too long")

    # User does not have permission to edit message
    if not  message_obj.user_sent_message(user.u_id) and \
            not token_is_admin(token) and \
            not token_is_owner(token) and \
            not channel.is_owner(user.u_id):
        raise AccessError("User does not have permission")

    # Edit channel message
    if not message.strip():
        # If empty message, delete
        channel = get_channel_by_message_id(message_id)
        channel.remove_message(message_id)
    else:
        # Otherwise, edit message
        message_obj.edit_message(message)

    return {}
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
    '''

    channel = get_channel_by_message_id(message_id)
    message_obj = get_message_by_message_id(message_id)
    user = get_user_by_token(token)

    # Message_id does not refer to an existing message
    if not valid_message_id(message_id):
        raise ValueError("Message does not exist")

    # User is not a member of the channel
    if not channel.is_member(user.u_id):
        raise AccessError("Authorised user is not a member of the channel")

    # React_id does not refer to a valid react
    if not valid_react_id(react_id):
        raise ValueError("Invalid React ID")

    # Message already has an react id by the given user
    if not message_obj.user_has_reacted(user.u_id, react_id):
        raise ValueError("Message does not contain an active react")

    # Removing react from message
    message_obj.remove_react(user.u_id, react_id)

    return {}
def message_sendlater(token, channel_id, message, time_sent):
    '''
    Sends a message from authorised_user to the channel specified by
    channel_id automatically at a specified time in the future
    '''

    channel = get_channel_by_channel_id(channel_id)
    user = get_user_by_token(token)

    # Channel_id does not refer to a valid channel
    if channel is None:
        raise ValueError("Invalid Channel ID")

    # Message is not of appropriate length
    if valid_message(message):
        raise ValueError("Message length too long")

    # Time to be sent is in the past
    if time_sent < datetime.datetime.now().timestamp():
        raise ValueError("Time sent was in the past")

    # User has not joined the channel
    if not channel.is_member(user.u_id):
        raise AccessError("Authorised user is not a member of the channel")

    # create new message object and update send time
    message_object = global_var.Message(user.u_id, message, channel_id)
    message_object.time_created = time_sent

    time_diff = time_sent - datetime.datetime.now().timestamp()
    Timer(time_diff, channel.add_message, args=[message_object]).start()

    return {
        "message_id": message_object.id
    }
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
    '''

    channel = get_channel_by_message_id(message_id)
    message_obj = get_message_by_message_id(message_id)
    user = get_user_by_token(token)

    # Message_id does not refer to an existing message
    if not valid_message_id(message_id):
        raise ValueError("Message does not exist")

    # Message_id is already pinned
    if message_obj.is_pinned:
        raise ValueError("Message is currently pinned")

    # User is not a member of the channel
    if not channel.is_member(user.u_id):
        raise AccessError("Authorised user is not a member of the channel")

    # User is not an owner of the channel
    if not channel.is_owner(user.u_id) and \
        not token_is_admin(token) and \
        not token_is_owner(token):
        raise ValueError("User is not an admin")

    # Pin message
    message_obj.pin_message()

    return {}
def message_unpin(token, message_id):
    '''
    Given a message within a channel, remove it's mark as unpinned
    '''

    channel = get_channel_by_message_id(message_id)
    message_obj = get_message_by_message_id(message_id)
    user = get_user_by_token(token)

    # Message_id does not refer to an existing message
    if not valid_message_id(message_id):
        raise ValueError("Message does not exist")

    # Message_id is already unpinned
    if not message_obj.is_pinned:
        raise ValueError("Message is currently unpinned")

    # User is not a member of the channel
    if not channel.is_member(user.u_id):
        raise AccessError("Authorised user is not a member of the channel")

    # User is not an owner of the channel
    if not channel.is_owner(user.u_id) and \
        not token_is_admin(token) and \
        not token_is_owner(token):
        raise ValueError("User is not an admin")

    # Unpinning message
    message_obj.unpin_message()

    return {}
def message_send(token, channel_id, message):
    '''
    Send a message from authorised_user to the channel specified by channel_id
    '''

    channel = get_channel_by_channel_id(channel_id)
    user = get_user_by_token(token)

    # Channel_id does not refer to a valid channel
    if channel is None:
        raise ValueError("Invalid Channel ID")

    # Message is not of appropriate length
    if valid_message(message):
        raise ValueError("Message length too long")

    # User has not joined the channel
    if not channel.is_member(user.u_id):
        raise AccessError("Authorised user is not a member of the channel")

    message_object = global_var.Message(user.u_id, message, channel_id)

    # Append message to channel list
    channel.add_message(message_object)

    return {
        "message_id": message_object.id
    }
Exemplo n.º 9
0
def standup_start(token, channel_id, length):
    '''
    For a given channel, start the standup period whereby for the next "length"
    seconds if someone calls "standup_send" with a message, it is buffered
    during the X second window then at the end of the X second window a message
    will be added to the message queue in the channel from the user who started
    the standup. X is an integer that denotes the number of seconds that the
    standup occurs for
    '''

    channel = get_channel_by_channel_id(channel_id)
    user = get_user_by_token(token)

    if channel is None:
        raise ValueError("Channel Does Not Exist")
    if channel.standup_running() is not False:
        raise ValueError("Standup Already Running")
    if not channel.is_member(user.u_id):
        raise AccessError("Cannot Access Channel")

    # Start standup and after length seconds end the standup
    time = datetime.datetime.now() + datetime.timedelta(seconds=length)
    channel.start_standup(time.timestamp())
    Timer(length, channel.end_standup, args=[token]).start()

    return {"time_finish" : time.timestamp()}
Exemplo n.º 10
0
def test_auth_register():
    '''
    Test functions for auth_register
    '''

    data.initialise_all()

    #A user is registered
    user = auth.auth_register("*****@*****.**", "valid_password", "a", "b")

    # Check database for id and token
    user_id = get_user_by_email("*****@*****.**").u_id
    user_token = get_user_token_by_u_id(user_id)

    # confirm that register returned the correct ID and token
    assert user == {"u_id": user_id, "token": user_token}

    # A invalid email is given
    with pytest.raises(ValueError, match="Invalid Email"):
        auth.auth_register("invalid_email", "valid_password", "a", "b")
    # Email given is already in use
    with pytest.raises(ValueError, match="Email Already Registered"):
        auth.auth_register("*****@*****.**", "valid_password", "a", "b")
    # Password provided is not strong enough
    with pytest.raises(ValueError, match="Password Not Strong"):
        auth.auth_register("*****@*****.**", "bpas", "a", "b")
    # First name is invalid
    with pytest.raises(ValueError, match="Invalid First Name"):
        invalid = "a" * 51
        auth.auth_register("*****@*****.**", "valid_password", invalid,
                           "b")
    # Last name is invalid
    with pytest.raises(ValueError, match="Invalid Last Name"):
        auth.auth_register("*****@*****.**", "valid_password", "a",
                           invalid)

    # Testing unique handle
    # Creating user: first_name="asd", last_name="dsa"
    user1 = auth.auth_register("*****@*****.**", "valid_password", "asd", "dsa")
    user1 = get_user_by_token(user1["token"])
    assert user1.handle == "asddsa"

    # Creating user: first_name="asd", last_name="dsa"
    user2 = auth.auth_register("*****@*****.**", "valid_password", "asd", "dsa")
    user2 = get_user_by_token(user2["token"])
    assert user2.handle == "2asddsa"
Exemplo n.º 11
0
def test_get_reset_code_from_email():
    ''' Returns a reset_code according to a user email '''

    # Register a user
    user = auth.auth_register("*****@*****.**", "passsword", "a", "b")
    user = helpers.get_user_by_token(user["token"])

    user2 = auth.auth_register("*****@*****.**", "passsword", "a", "b")
    user2 = helpers.get_user_by_token(user2["token"])
    auth.auth_passwordreset_request(user2.email)

    # No such email request
    assert helpers.get_reset_code_from_email("*****@*****.**") is None

    # Reset email request
    auth.auth_passwordreset_request(user.email)
    assert helpers.get_reset_code_from_email(user.email) ==\
        global_var.data["reset_code"][1]["reset_code"]
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 x and
    y co-oridinates

    ValueError:
    - img_url returns an HTTP status other than 200 (2xx indicates success)
    - xy points are outside the dimensions of the image at the url
    '''

    req = Request(img_url, headers={"User-Agent": "Mozilla/5.0"})
    # Checking if the img_url is an accessable URL
    try:
        response = urlopen(req)
    except URLError as error:
        raise ValueError(f"The server cannot be reached: {error.reason}")

    # Obtaining image
    image_object = Image.open(response)

    # Checks if image is a jpg
    if image_object.format != "JPEG":
        raise ValueError("Image uploaded is not a JPG")

    # Check that the crop co-ordinates are valid
    # Getting the width and height of image
    width, height = image_object.size

    # Checking if the crop coordinates are within the bounds of the image
    valid_crop(x_start, x_end, y_start, y_end, width, height)

    # Obtaining user_id (user_id will be the unique filename)
    user = get_user_by_token(token)

    # Creating file path if it doesn't already exist
    if not os.path.exists("server/assets/images/"):
        os.makedirs("server/assets/images/")

    # File path
    img_file_path = f"server/assets/images/{create_photo_path(user)}.jpg"

    # Gets image from url and saves it in images folder
    urllib.request.urlretrieve(img_url, img_file_path)

    # Cropping image
    img_file = open(img_file_path, "wb")
    cropped = image_object.crop((x_start, y_start, x_end, y_end))
    cropped.save(img_file)

    # Use request in running server context and give default url for unit tests
    try:
        url = request.host_url
    except:
        url = "http://localhost:5001/"
    user.upload_photo(f"{url}imgurl/{img_file_path}")

    return {}
Exemplo n.º 13
0
def test_unique_handle():
    '''
    Ensure that handles are unique
    '''
    # Initialisation
    global_var.initialise_all()

    # Testing unique handle
    assert helpers.unique_handle("AshleyHuang") is True

    # Testing not unique handle
    user = auth.auth_register("*****@*****.**", "pass123", "Ashley", "Huang")
    get_user = helpers.get_user_by_token(user["token"])
    assert helpers.unique_handle(get_user.handle) is False
Exemplo n.º 14
0
def channels_list(token):
    '''
    Provides a list of all channels and details that the auth user is part of
    '''

    user = get_user_by_token(token)
    channels_user_is_member = []

    # Create a list of channels that the user is apart of
    for channel in global_var.data["channels"]:
        if channel.is_member(user.u_id):
            channels_user_is_member.append({"channel_id": channel.id, \
                                             "name": channel.name})

    return {"channels": channels_user_is_member}
def search(token, query_str):
    '''
    Given a query string, return a collection of messages in all of the
    channels that the user has joined that match the query
    '''

    messages = []
    # Searching for messages with query string
    for channel in data.data["channels"]:
        # Checking all channels which the user has joined
        if channel.user_in_channel(get_user_by_token(token).u_id):
            # Returning all messages in channel with substring
            messages = messages + channel.search_message(token, query_str)

    return {"messages": messages}
Exemplo n.º 16
0
def channel_leave(token, channel_id):
    '''
    Given a channel ID, the user is removed as a member of the channel
    '''

    channel = get_channel_by_channel_id(channel_id)
    user = get_user_by_token(token)

    # channel_id does not refer to a valid channel
    if channel is None:
        raise ValueError("Channel does not exist")

    # User is removed as a member of the channel
    channel.remove_user(user.u_id)
    channel.remove_owner(user.u_id)

    return {}
Exemplo n.º 17
0
def channels_create(token, name, is_public):
    '''
    Create a channel with the name that is either public or private
    '''

    # Exception raised
    if len(name) > MAX_CHANNEL_LENGTH:
        raise ValueError("Name is longer than 20 characters")

    user = get_user_by_token(token)

    # A channel object is created
    new_channel = global_var.Channel(name, user.u_id, is_public)

    # channel is added to channels list
    global_var.data["channels"].append(new_channel)

    return {"channel_id": new_channel.id}
def user_profile_sethandle(token, handle_str):
    '''
    Update the authorised user's handle
    '''

    if len(handle_str) > MAX_HANDLE_LENGTH or len(handle_str) < \
        MIN_HANDLE_LENGTH:
        raise ValueError("Invalid Handle")
    if not unique_handle(handle_str):
        raise ValueError("Handle Taken")

    # Changes user's handle in database
    user = get_user_by_token(token)

    # Update user's handle
    user.update_handle(handle_str)

    return {}
Exemplo n.º 19
0
def test_token_is_owner():
    '''
    Test if a token is in an owner
    '''

    # Initialisation
    global_var.initialise_all()

    # Creating a user
    user = auth.auth_register("*****@*****.**", "pass123", "Raydon", "Smith")

    with pytest.raises(AccessError, match="Invalid Token"):
        helpers.token_is_owner("-1")

    token = user["token"]
    user = helpers.get_user_by_token(token)
    user.permission = 1
    assert helpers.token_is_owner(token) is True
    user.permission = 0
    assert helpers.token_is_owner(token) is False
Exemplo n.º 20
0
def standup_send(token, channel_id, message):
    '''
    Sending a message to get buffered in the standup queue, assuming a standup
    is currently active
    '''

    channel = get_channel_by_channel_id(channel_id)
    user = get_user_by_token(token)

    if channel is None:
        raise ValueError("Channel Does Not Exist")
    if len(message) > MAX_MESSAGE_LENGTH:
        raise ValueError("Message Too Long")
    if not channel.is_member(user.u_id):
        raise AccessError("Cannot Access Channel")
    if channel.standup_running() is False:
        raise ValueError("Not Currently In Standup")

    channel.add_standup_message(token, message)

    return {}
def message_remove(token, message_id):
    ''' Given a message ID, the message is removed '''

    channel = get_channel_by_message_id(message_id)
    message = get_message_by_message_id(message_id)
    user = get_user_by_token(token)

    # Message_id does not refer to an existing message
    if not valid_message_id(message_id):
        raise ValueError("Message does not exist")

    # User does not have permission to remove message
    if not message.user_sent_message(user.u_id) and \
        not token_is_admin(token) and \
        not token_is_owner(token) and \
        not channel.is_owner(user.u_id):
        raise AccessError("User does not have permission")

    # Removing message
    channel.remove_message(message_id)

    return {}
def user_profile_setname(token, name_first, name_last):
    '''
    Update the authorised user's first and last name

    ValueError:
    - name_first is more than 50 characters
    - name_last is more than 50 characters
    '''

    if len(name_first) > MAX_NAME_LENGTH:
        raise ValueError("Name too long")
    if len(name_last) > MAX_NAME_LENGTH:
        raise ValueError("Name too long")

    user = get_user_by_token(token)

    # Update user's first name
    user.update_name_first(name_first)

    # Update user's last name
    user.update_name_last(name_last)

    return {}
def user_profile_setemail(token, email):
    '''
    Updates the authorised user's email address

    ValueError:
    - Email entered is not a valid email
    - Email address is already being used by another user
    '''

    user = get_user_by_email(email)

    if valid_email(email) is False:
        raise ValueError("Invalid email")
    if user:
        raise ValueError("Email already in use")

    # Changes user's email in database
    user = get_user_by_token(token)

    # Update user's email
    user.update_email(email)

    return {}
Exemplo n.º 24
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
    '''

    channel = get_channel_by_channel_id(channel_id)
    user = get_user_by_token(token)

    # channel_id does not refer to a valid channel
    if channel is None:
        raise ValueError("Channel does not exist")

    # User does not have permission to join channel without invite
    if not channel.is_public and \
         not token_is_admin(token) and \
            not token_is_owner(token):
        raise AccessError("Channel is private and user is not admin")

    # User is added to channel
    channel.add_user(user.u_id)

    return {}
Exemplo n.º 25
0
 def add_standup_message(self, token, message):
     self.standup_messages.append({
         'user': helpers.get_user_by_token(token).handle,
         'message': message
     })