Beispiel #1
0
def auth_login_v2(email, password):
    """Summary
        Given a registered user's email and password, returns a new session token and their user id
    Args:
        email (string): An email address
        password (string): A password
    
    Returns:
        Dictionary: Contains the user's token and user id
    
    Raises:
        InputError: When an invalid email is given, the given password is incorrect, or the email entered does not
                    match any registered user's email
    """
    global tokens
    if not valid_email(email):
        raise InputError(f"Email {email} is not a valid email")

    for user in users:
        if user['email'] == email and user[
                'permission'] != 0:  # Check for email match to valid, non-removed user
            if user['password'] == get_hash(
                    password
            ):  # Compare stored password hash to hashed password input
                auth_user_id = user['u_id']
                token = generate_token(auth_user_id)
                return {'token': token, 'auth_user_id': auth_user_id}
            else:
                raise InputError(f"Password {password} is not correct")

    raise InputError(f"Email {email} does not belong to a user.")
Beispiel #2
0
def message_sendlater(token, channel_id, message, time_sent):
    '''
    sends a message at a given time_sent, where time_sent is a unix timestamp
    greater than the current time.
    '''
    u_id = check_token(token)
    if not is_valid_channel(channel_id):
        raise InputError(description="No channel exists with that ID")
    if not is_user_a_member(channel_id, u_id):
        raise AccessError(description='You are not a member of this channel')
    if len(message) > 1000 or len(message) < 1:
        raise InputError(
            description=
            'Your message should be less than 1000 characters and at least 1 character'
        )
    curr_time = get_current_timestamp()
    if curr_time >= time_sent:
        raise InputError(description="You can not send a message back in time")
    delay = time_sent - curr_time
    message_id = get_num_messages()
    set_num_messages(message_id + 1)
    message_template = create_message(u_id, message_id, time_sent, message)
    timer = Timer(delay, sendlater_end, args=[channel_id, message_template])
    timer.start()
    return {'message_id': message_id}
Beispiel #3
0
def user_profile_sethandle_v1(token, handle_str):
    # token check
    if check_token_valid(token) is False:
        raise AccessError("Invalid Token")

    handle = ''.join(handle_str.split())
    handle = handle.replace("@","")
    handle = handle.lower()

    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)

    for i in range(len(data['users'])):
        if data['users'][i]['handle'] == handle:
            raise InputError("Handle already in use")

    for j in range(len(data['users'])):
        if data['users'][j]['token'] == token:
            if len(handle) < 3 or len(handle) > 20:
                raise InputError("Invalid handle")

            data['users'][j]['handle'] = handle

            with open('src/data.json', 'w') as FILE:
                json.dump(data,FILE, indent = 4)

    return {
    }
Beispiel #4
0
def auth_passwordreset_reset_v1(reset_code, new_password):
    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)

    # check for valid code
    valid = False
    for i in range(len(data["reset_codes"])):
        if data["reset_codes"][i]["reset_code"] == reset_code:
            email = data["reset_codes"][i]["email"]
            valid = True

    if valid == False:
        raise InputError("Invalid code")

    # checks if password is less than 6 characters
    if len(new_password) < 6:
        raise InputError("Password too short")

    # encode new password and set it
    new_password = hashlib.sha256(new_password.encode()).hexdigest()
    for i in range(len(data["users"])):
        if data['users'][i]['email'] == email:
            data['users'][i]['password'] = new_password

    # remove reset code from data once it has been used
    for i in range(len(data["reset_codes"])):
        if data["reset_codes"][i]["reset_code"] == reset_code:
            del data["reset_codes"][i]

    with open('src/data.json', 'w') as FILE:
        json.dump(data, FILE, indent=4)

    return {}
Beispiel #5
0
def errorcheck_user_profile_setemail_v2(token, email):
    if check_valid_email(email) == None:
        raise InputError(description="Email is invalid")

    if is_existing_email(email) == True:
        raise InputError(
            description="Email is already being used by another user")
Beispiel #6
0
def auth_passwordreset_reset_v1(reset_code, new_password):
    '''
    Summary:
        Given a reset code for a user, set that user's new password to the password provided
    Args:
        reset_code (string): A string of numbers and captial letters
        password (string): The password that the user wants to change theirs to
    Returns: 
        empty dictionary
    Raises:
        InputError when:
            reset_code is not a valid reset code
            Password entered is less than 6 characters long
    '''
    global users, reset_codes
    if len(new_password) < 6:
        raise InputError("Password entered is less than 6 characters long")

    for code_data in list(
            reset_codes
    ):  #ask team i delete the code after because we dont need it anymore i need list() here right
        if code_data['code'] == reset_code:
            for user in users:
                if code_data['u_id'] == user[
                        'u_id']:  #i can add email here as well to double check, u_id i unique though,should be fine
                    user['password'] = get_hash(new_password)
                    reset_codes.remove(
                        code_data
                    )  #delete after because dont need anymore? added list() here right
                    return {}

    # If loop exits without returning, code is invalid
    raise InputError("reset_code is not a valid reset code")
Beispiel #7
0
def admin_userpermission_change_v1(token, u_id, permission_id):
    """Summary
        Enables a Dreams owner to change the permissions of another user between Dreams owner (1) and
        standard user (2).
    Args:
        token (string): User session token
        u_id (integer): User id number
        permission_id (integer): Either 1, indicating Dreams owner, or 2, indicating standard user
    
    Returns:
        Empty dictionary
    
    Raises:
        AccessError: When an invalid token value is given, or when the user associated with the token
                     is not a Dreams owner
        InputError: When permission_id does not refer to a valid permission, or 
                    u_id does not refer to a valid user
    """
    check_token(token)  # Check for invalid token

    if user_from_token(token)['permission'] != 1:
        raise AccessError("Authorised user is not an owner.")

    if not 1 <= permission_id <= 2:  # Check for invalid permission_id
        raise InputError("permission_id does not refer to a valid permission.")

    # Search for user with user id u_id and change their permission if found
    for user in users:
        if user['u_id'] == u_id:
            user['permission'] = permission_id
            return {}
    raise InputError("u_id does not refer to a valid user.")
Beispiel #8
0
def permission_change(token, u_id, permission_id):
    '''change a user's permissions on the server

    :param token: jwt token
    :type token: str
    :param u_id: User id corresponding to the target user
    :type u_id: int
    :param permission_id: ID of user new permissions
    :type permission_id: int
    :raises InputError: u_id does not correspond to a user
    :raises InputError: Invalid Permission ID
    :raises AccessError: User is not a slackr owner
    :return: empty dictionary
    :rtype: dict
    '''
    user_id = check_token(token)
    if not user_id in get_slackr_owners():
        raise AccessError(
            description='You are not permitted to perform this action')

    if not is_valid_user(u_id):
        raise InputError(description='User does not exist')
    if permission_id not in (1, 2):
        raise InputError(description='Invalid permission ID')
    # all possible errors raised.
    if permission_id == 1:
        get_users()[u_id]['is_owner'] = True
    elif permission_id == 2:
        get_users()[u_id]['is_owner'] = False

    return {}
Beispiel #9
0
def message_pin(token, message_id):
    '''
    Pins a message in a channel
    '''
    u_id = check_token(token)
    channel_specific = get_channel_by_msg_id(message_id)
    message_specific = get_message_by_msg_id(message_id)

    if u_id not in channel_specific['members'] and not is_channel_owner(
            token, channel_specific):
        raise AccessError(
            description=
            'The authorised user is not a member of the channel that the message is within'
        )

    if not is_channel_owner(token, channel_specific):
        raise InputError(description='The authorised user is not an owner')

    if message_specific['is_pinned']:
        raise InputError(
            description='Message with ID message_id is already pinned')

    if is_channel_owner(token, channel_specific
                        ) is True and message_specific['is_pinned'] is False:
        message_specific['is_pinned'] = True

    return {}
Beispiel #10
0
def admin_userpermission_change_v1(token, u_id, permission_id):

    # token check
    if check_token_valid(token) is False:
        raise AccessError("Invalid Token")

    if permission_id is not 1 and permission_id is not 2:
        raise InputError("Invalid permission_id")

    if not check_user_exists(u_id):
        raise InputError("invalid u_id")

    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)

    owner = False
    owner_id = convert_token(token)
    if data['users'][owner_id]['permission_id'] == 1:
        owner = True

    if owner == True:
        for i in range(len(data['users'])):
            if u_id == data['users'][i]['u_id']:
                data['users'][i]['permission_id'] = permission_id
    else:
        raise AccessError("Unauthorised user, user is not an owner")

    with open ('src/data.json', 'w') as FILE:
        json.dump(data, FILE, indent = 4)

    return {
        
    }
def user_profile_setname_v2(token, name_first, name_last):
    """ 
    Given  valid token and first/last names, changes a registered users name

    Arguments:
        token (string) - valid token associated with a registered user's session
        name_first (string) - first name the user wants to update to
        name_last (string) - last name the user wants to update to

    Exceptions:
        InputError - When either name_first or name_last is not between 1 and 50 characters, inclusive
        AccessError - Occurs if token is invalid


    Return value:
        {}
    """
    #Retrieving data from export.json
    data = getData()
    #Testing for a valid token and finding the associated u_id
    u_id = findUser(token)
    #Checking if the names are of valid length
    if len(name_first) > 50 or len(name_first) < 1:
        raise InputError(description="Length of first name is not valid")
    elif len(name_last) > 50 or len(name_last) < 1:
        raise InputError(description="Length of last name is not valid")
    #Finding the user and changing their names
    for user in data['users']:
        if u_id == user['u_id']:
            user['name_first'] = name_first
            user['name_last'] = name_last
            #Writing data to export.json
            writeData(data)
    return {}
Beispiel #12
0
def errorcheck_removeowner_v1(token, channel_id, u_id):
    # assumes the user must be in the channel before being added as an owner
    # if not, raise an input error

    data_structure = token_check(token)

    if is_valid_u_id(u_id) == False:
        raise InputError("Invalid u_id")

    if is_valid_channel_id(channel_id) == False:
        raise InputError("Invalid channel_id")

    if is_user_channel_membertype(channel_id, u_id, CHANNEL_MEMBER) == False:
        raise InputError(
            "user with user id u_id is not already a member of the channel")
    if is_user_channel_membertype(channel_id, u_id, CHANNEL_OWNER) == False:
        raise InputError(
            "user with user id u_id is not already a channel owner")

    if is_user_channel_membertype(
            channel_id, int(data_structure["u_id"]),
            CHANNEL_OWNER) == False and find_auth_user_permission_id(
                int(data_structure["u_id"])) == 2:
        raise AccessError(
            "auth_user is not an owner of the channel or an owner of **Dreams**"
        )

    if is_user_only_owner(channel_id) == True:
        raise InputError("user to be removed is the only owner in the channel")
Beispiel #13
0
def user_profile_setname_v1(token, name_first, name_last):

    if check_token_valid(token) is False:
        raise AccessError("Invalid Token")

    # checks if first and last names are between 1-50 characters long
    if len(name_first) < 1 or len(name_first) > 50:
        raise InputError("Name must be between 1-50 characters")
        
    if len(name_last) < 1 or len(name_last) > 50:
        raise InputError("Name must be between 1-50 characters")

    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)

    for i in range(len(data['users'])):
        if data['users'][i]['token'] == token:
            data['users'][i]['name_first'] = name_first
            data['users'][i]['name_last'] = name_last

            with open('src/data.json', 'w') as FILE:
                json.dump(data,FILE, indent = 4)

    return {
    }
def user_profile_uploadphoto_v1(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.
            
    Arguments:
        token (string) - valid token associated with a registered user's session
        img_url (string) - URl to a jpg online
        x_start (int) - indicates leftmost point on image
        y_start (int) - indicates topmost point on image
        x_end (int) - indicates righttmost point on image
        y_end (int) - indicates bottommost point on image
  
    Exceptions:
        InputError - img_url returns an HTTP status other than 200.
        InputError - any of x_start, y_start, x_end, y_end are not within the dimensions of the image at the URL.
        InputError - Image uploaded is not a JPG

    Return value:
        { }
    """
    #Retrieving data from dictionary
    data = getData()
    #Find user id from their token
    u_id = findUser(token)
    #Define URL
    URL = f'{img_url}'
    #Define file path
    fileName = f'src/static/{u_id}.jpg'
    #Trying to open URL, if it fails raise an InputError
    try:
        status = requests.get(URL).status_code
    except:
        status = -1

    if status != 200:
        raise InputError(description='Invalid URL')
    #Raising an error if the URL does not point to a jpg
    if not URL.endswith('.jpg'):
        raise InputError(description='Image is not a jpg')
    #Retrieve the URL abd save the image as fileName
    urllib.request.urlretrieve(URL, fileName)
    #Open the image
    img = Image.open(fileName)
    #Define the size of the image
    width, height = img.size
    #Raising an error if the crop points aren't valid
    if x_start < 0 or y_start < 0 or x_end > width or y_end > height or x_end < x_start or y_end < y_start:
        raise InputError(description='Crop start or end points not valid')
    #Cropping and saving the image
    crop_img = img.crop((x_start, y_start, x_end, y_end))
    crop_img.save(fileName)
    #Changin the user's associated URL to the new image
    for user in data['users']:
        if u_id == user['u_id']:
            user['profile_img_url'] = f'{config.url}/images/{u_id}.jpg'
    #Writing data to dictionary
    writeData(data)
    return {}
Beispiel #15
0
def dm_invite_v1(token, dm_id, u_id):
    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)
    inviteid = None
    # check that token is valid
    for i in range(len(data['users'])):
        if data['users'][i]['token'] == token:
            inviteid = data["users"][i]["u_id"]
    if inviteid is None:
        raise AccessError("Invalid token")
    # check if the dm_id exists
    if check_dm_exists(dm_id) == False:
        raise InputError("Invalid dm")
    # check if the u_id is valid
    if check_user_exists(u_id) == False:
        raise InputError("Invalid User")
    # checking if the person inviting is in the dm
    if check_user_in_dm(inviteid, dm_id) == False:
        raise AccessError("Authorised user needs to be a member of the dm")
    # checking if the person being invited is already in the dm
    if check_user_in_dm(u_id, dm_id) == True:
        raise InputError("User already a member of this dm")
    new_user = {
        'u_id': u_id,
        'email': data["users"][u_id]["email"],
        'name_first': data["users"][u_id]["name_first"],
        'name_last': data["users"][u_id]["name_last"],
        'handle': data["users"][u_id]["handle"]
    }

    memberslist = data["dms"][dm_id]["name"].split(", ")
    memberslist.append(data["users"][u_id]["handle"])
    sortedlist = sorted(memberslist, key=str.lower)
    final_list = ", ".join(sortedlist)

    #name = data["dms"][dm_id]["name"] + ", " + data["users"][u_id]["handle"]
    data["dms"][dm_id]["members"].append(new_user)
    data["dms"][dm_id]["name"] = final_list

    num_dms_joined = data["user_stats"][u_id]["stats"]["dms_joined"][-1][
        "num_dms_joined"] + 1
    dms_joined = {
        "num_dms_joined": num_dms_joined,
        "time_stamp": create_timestamp()
    }
    data["user_stats"][u_id]["stats"]["dms_joined"].append(dms_joined)

    with open('src/data.json', 'w') as FILE:
        json.dump(data, FILE, indent=4)

    notif_msg = data["users"][inviteid][
        "handle"] + " added you to dm " + final_list
    create_notifications(u_id, -1, dm_id, notif_msg)

    calc_involement_rate(u_id)
    calc_utilisation_rate()

    return {}
def message_unreact_v1(token, message_id, react_id):
    '''
    Arguments:
        token (string) - the token of the user who wants to create a channel
        message_id - the id of the message being reacted to
        react_id (int) - the id of the react

    Exceptions:
        InputError - message_id is not a valid message within a channel or DM that the authorised user has joined
        InputError - react_id is not a valid React ID. The only valid react ID the frontend has is 1
        InputError - Message with ID message_id does not contain an active React with ID react_id from the authorised user
        AccessError - The authorised user is not a member of the channel or DM that the message is within

    Return value:
        Returns {}
    '''

    # get data
    data = getData()

    # get id
    auth_user_id = findUser(token)

    # Gets message
    msg = get_message(message_id, data)

    # Message does not exist (has been removed or invalid message_id passed in)
    if msg == -1:
        raise InputError("Message is not a valid.")

    # Gets message key
    msg_key = data['messages'].index(msg)

    # Gets list of dictionary containing all the reacts for that message
    react_list = data['messages'][msg_key]['reacts']

    # Checks react id is valid and in use already
    if react_id != 1:
        raise InputError("React ID is not valid.")
    elif not has_user_reacted(auth_user_id, react_id, react_list, data):
        raise InputError("User has not already reacted with this react.")

    # Checks the user is part of the channel/dm
    check_user_permissions(data, msg_key, auth_user_id)

    # Remove/update react
    react_key = get_react(react_id, react_list, msg_key, data)
    data['messages'][msg_key]['reacts'][react_key]['u_ids'].remove(
        auth_user_id)
    if data['messages'][msg_key]['reacts'][react_key]['u_ids'] == []:
        data['messages'][msg_key]['reacts'].remove({
            'react_id': react_id,
            'u_ids': []
        })

    writeData(data)

    return {}
Beispiel #17
0
def channel_addowner_v1(token, channel_id, u_id):
    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)
    # check that token is valid
    user_id = None
    for i in range(len(data['users'])):
        if data['users'][i]['token'] == token:
            user_id = data['users'][i]['u_id']
    if user_id is None:
        raise AccessError("Invalid token")
    # check if the channel_id exists
    if check_channel_exists(channel_id) == False:
        raise InputError("Invalid channel")

    # check if the user is already an owner of the channel
    for i in range(len(data["channels"][channel_id]["owner_members"])):
        if data["channels"][channel_id]["owner_members"][i]["u_id"] == u_id:
            raise InputError("User already an owner")

    # check if u_id belongs to an existing member of the channel
    if check_user_in_channel(u_id, channel_id) == False:
        raise InputError(
            "User must be a member of the channel to become owner")

    dreamsowner = False
    channelowner = False

    # confirm if token belongs to a dream owner
    if data['users'][user_id]['permission_id'] == 1:
        dreamsowner = True

    # confirm if token belongs to an owner
    for i in range(len(data["channels"][channel_id]["owner_members"])):
        if data["channels"][channel_id]["owner_members"][i]["u_id"] == user_id:
            channelowner = True

    if dreamsowner or channelowner:
        # information of new owner to be added
        new_owner = {
            "u_id": u_id,
            'email': data["users"][u_id]["email"],
            'name_first': data["users"][u_id]["name_first"],
            'name_last': data["users"][u_id]["name_last"],
            'handle': data["users"][u_id]["handle"]
        }
        data["channels"][channel_id]["owner_members"].append(new_owner)
    else:
        raise AccessError("Unauthorised user, user is not an owner")

    with open('src/data.json', 'w') as FILE:
        json.dump(data, FILE, indent=4)

    notif_msg = data["users"][u_id][
        "handle"] + " added you as owner in " + data["channels"][channel_id][
            "name"]
    create_notifications(u_id, channel_id, -1, notif_msg)

    return {}
Beispiel #18
0
def errorcheck_user_profile_setname_v2(token, name_first, name_last):
    if is_name_within_str_length(name_first) == False:
        raise InputError(
            description="First name is outside of range 1 - 50 chars")
    if is_name_within_str_length(name_last) == False:
        raise InputError(
            description="Last name is outside of range 1 - 50 chars")
    if name_first == "Removed" and name_last == "user":
        raise InputError(description="Illegal name change")
Beispiel #19
0
def message_edit_v2(token, message_id, message):
    """Summary
        Given a message, update its text with new text. If the new message is an empty string, the message 
        is deleted.
    Args:
        token (string): A user session token
        message_id (int): A message id number
        message (string): The text with which the user wishes to replace the current message
    
    Returns:
        Empty dictionary
    
    Raises:
        AccessError: When an invalid token is given, or the user attempts to delete a message that they did
                     not write, or one in a channel that they do not own, and they are not a dreams owner
        InputError: If the message is not a string, is longer than 1000 characters, or message_id does not
                    refer to a valid message
    """
    global messages
    check_token(token)
    auth_user = user_from_token(token)

    if type(message) != str:
        raise InputError(f"Message {message} is not of type string")

    if len(message) > 1000:
        raise InputError(
            f"Length of message is over 1000 characters (length is {len(message)})"
        )

    for msg in messages:
        if msg['message_id'] == message_id:
            can_edit = False
            if auth_user['u_id'] == msg['author_id'] or is_dreams_owner(
                    auth_user['u_id']):
                # If the user is the author of the message or a dreams owner, they can always edit it
                can_edit = True
            elif msg['channel_id'] != -1 and is_channel_owner(
                    auth_user['u_id'], msg['channel_id']):
                # If the message was sent to a channel and the user is the channel owner
                can_edit = True

            if can_edit:
                if not len(
                        message
                ):  # If the new message text is blank, delete the message
                    message_remove_v1(token, message_id)
                else:  # Replace the current message text with the new text
                    msg['message'] = message
                return {}
            raise AccessError(
                f"User {auth_user['handle_str']} does not have permission to edit message with id {message_id}"
            )

    raise InputError(
        f"Message with id {message_id} does not exist (it may have been deleted)"
    )
def admin_userpermission_change_v1(token, u_id, permission_id):
    """
    Given a User by their user ID, set their permissions to new permissions
    described by permission_id.

    Arguments:
        token (str)          - token passed in to the function
        u_id (int)           - id of user to change permission of
        permission_id (int)  - new permission id

    Exceptions:
        AccessError - when token passed in is not a valid id
        InputError  - when u_id does not refer to a valid user
        InputError  - when permission_id does not refer to a valid permission
        AccessError - when authorised user is not an owner

    Return value:
        {}
    """

    data_store = getData()

    # Check for exceptions
    # validate token
    auth_user_id = findUser(token)

    # check if u_id is a valid user, and also get index of position if valid
    valid = False
    for user_index, user in enumerate(data_store["users"]):
        if user["u_id"] == u_id:
            valid = True
            break

    if not valid:
        raise InputError(description="u_id does not refer to a valid user")

    # Check permission_id is valid
    if permission_id != 1 and permission_id != 2:
        raise InputError(description="Invalid permission_id")

    # Check if authorised user is an owner (with permission 1)
    for user in data_store["users"]:
        if user["u_id"] == auth_user_id:
            if user["permission_id"] != 1:
                raise AccessError(description="Authorised user is not an owner.")

    # Cannot change permission to permission_id 2 if there is only one
    # owner remaining in Dreams
    if permission_id == 2:
        if get_dream_owners_count(data_store) > 1:
            data_store["users"][user_index]["permission_id"] = permission_id
    else:
        data_store["users"][user_index]["permission_id"] = permission_id

    writeData(data_store)

    return {}
Beispiel #21
0
def search_v2(token, query_str):
    """ Given a query string, return a collection of messages in
    all the channels/DMs that the authorised user has joined
    that match the query

    Arguments:
        token (string)          - token of authenticated user
        query_str (string)      - string to be searched for

    Exceptions:
        InputError  - Occurs when query_str is above 1000 characters
                    - Occurs when query_str is empty
        AccessError - Occurs when token is invalid

    Return value:
        {
            messages      - List of dictionaries, 
                            where each dictionary contains types: 
                            {message_id, u_id, message, time_created}
        }
    """

    # Check validity of token
    findUser(token)

    # Check query_str is less than 1000 characters or not empty
    if len(query_str) > 1000:
        raise InputError(description="query string can't be over 1000 characters")
    if len(query_str) == 0:
        raise InputError(description="query string can't be empty")

    # Define messages return type
    message_dict = {
        "messages" : []
    }

    # Go through channels
    u_channels_list = channels_list_v2(token)["channels"]
    for channel in u_channels_list:
        msgs = channel_messages_v2(token, channel["channel_id"], 0)
        look_for_message(query_str, msgs, message_dict)
        while msgs["end"] != -1:
            msgs = channel_messages_v2(token, channel["channel_id"], msgs["end"])
            look_for_message(query_str, msgs, message_dict)

    # Go through dms
    u_dms_list = dm_list_v1(token)["dms"]
    for dm in u_dms_list:
        msgs = dm_messages_v1(token, dm["dm_id"], 0)
        look_for_message(query_str, msgs, message_dict)
        while msgs["end"] != -1:
            msgs = dm_messages_v1(token, dm["dm_id"], msgs["end"])
            look_for_message(query_str, msgs, message_dict)
    
    return message_dict
Beispiel #22
0
def standup_start_v1(token, channel_id, length):
    '''
    Summary:
       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
    Args:
        token (string): A user session token 
        channel_id (int): A channel_id number
        length (int): A length of how long the standup runs
    Returns: 
        dictionary which contains the time_finished 
    Raises:
        InputError when:
            Channel ID is not a valid channel
            An active standup is currently running in this channel
        AccessError when:
            Authorised user is not in the channel
    '''
    global channels
    check_token(token)

    if valid_channel(channel_id) == False:
        raise InputError(f'Channel ID {channel_id} is not a valid channel')

    auth_user_id = user_from_token(token)['u_id']

    if is_channel_member(auth_user_id, channel_id) == False:
        raise AccessError(f'Authorised user is not in the channel')

    current_channel = find_channel(channel_id)

    if current_channel['standup']['is_active'] == True:
        raise InputError(
            f'An active standup is currently running in this channel')

    standup_period_finish = datetime.now(
        timezone.utc) + timedelta(seconds=length)
    timestamp = standup_period_finish.replace(tzinfo=timezone.utc).timestamp()

    # what will i add to the message here
    #dummy = ''
    #message_id = message_sendlater_v1(token, channel_id, dummy, timestamp)
    #message id here or standup send
    #standup_info = {}
    #create the standup dicitonary in channel create
    current_channel['standup']['is_active'] = True
    current_channel['standup']['creator'] = auth_user_id
    current_channel['standup']['messages'] = []
    current_channel['standup']['time_finish'] = timestamp

    #current_channel['standup'] = standup_info

    return {'time_finish': timestamp}
Beispiel #23
0
def errorcheck_user_profile_sethandle_v1(token, handle_str):
    if is_handle_str_str(handle_str) == False:
        raise InputError(description="handle_str is not a string")

    if is_within_str_length(handle_str) == False:
        raise InputError(
            description=
            "handle_str is not between 3 and 20 characters inclusive")

    if is_handle_exists(handle_str) == True:
        raise InputError(description="handle is already used by another user")
Beispiel #24
0
def channel_removeowner_v1(token, channel_id, u_id):
    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)
    # check that token is valid
    removeid = None
    for i in range(len(data['users'])):
        if data['users'][i]['token'] == token:
            removeid = data['users'][i]['u_id']
    if removeid is None:
        raise AccessError("Invalid token")
    # check if the channel_id exists
    if check_channel_exists(channel_id) == False:
        raise InputError("Invalid channel")

    ownercheck = False
    index = 0

    # make sure person being removed is an existing owner
    for i in range(len(data["channels"][channel_id]["owner_members"])):
        if data["channels"][channel_id]["owner_members"][i]["u_id"] == u_id:
            ownercheck = True
            index = i
    if ownercheck is False:
        raise InputError("User not an owner")

    dreamsowner = False
    channelowner = False

    if len(data["channels"][channel_id]["owner_members"]) == 1 and len(
            data["channels"][channel_id]["all_members"]) == 1:
        raise AccessError("Last member can not remove themselves as an owner")
    # check person trying to remove owner is a dreams owner
    if data['users'][removeid]['permission_id'] == 1:
        dreamsowner = True
    # check person trying to remove owner is a channel owner
    for i in range(len(data["channels"][channel_id]["owner_members"])):
        if data["channels"][channel_id]["owner_members"][i][
                "u_id"] == removeid:
            channelowner = True

    if dreamsowner or channelowner:
        del data["channels"][channel_id]["owner_members"][index]
    else:
        raise AccessError("Unauthorised user, user is not an owner")

    with open('src/data.json', 'w') as FILE:
        json.dump(data, FILE, indent=4)

    notif_msg = data["users"][removeid][
        "handle"] + " removed you as owner in " + data["channels"][channel_id][
            "name"]
    create_notifications(u_id, channel_id, -1, notif_msg)

    return {}
Beispiel #25
0
def standup_send_v1(token, channel_id, message):
    '''
    Starts a standup in a channel for 'length' seconds.

    Arguments:
        token (string)          - token of user starting standup
        channel_id (integer)    - id of channel standup is in
        message (string)        - buffered message that is sent to standup

    Exceptions:
        InputError  - Occurs when channel_id does not refer to a valid channel
                    - Occurs when the message is over 1000 characters in length
                    (excluding the name of the user)
                    - Occurs when there is no active standup in the channel
        AccessError - Occurs when the token passed in is not valid
                    - Occurs when the authorised user is not already
                    a member of the channel

    Return Value:
        Returns {}
    '''
    # exception checks
    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)
    u_id = None
    for i in range(len(data['users'])):
        if data['users'][i]['token'] == token:
            u_id = data['users'][i]['u_id']
    if u_id is None:
        raise AccessError("Invalid token")
    if check_channel_exists(channel_id) == False:
        raise InputError("Invalid channel")
    if check_user_in_channel(u_id, channel_id) == False:
        raise AccessError("Authorised user is not part of the channel")
    if len(message) > 1000:
        raise InputError("Message is longer than the 1000 character limit")
    standupActive = standup_active_v1(token, channel_id)
    if standupActive['is_active'] == False:
        raise InputError("No active standup running in this channel")

    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)

    for i in range(len(data['users'])):
        if data["users"][i]['token'] == token:
            firstName = data["users"][i]['name_first']

    new_message = {'name': firstName, 'message': message}
    for i in range(len(data["standups"])):
        if data["standups"][i]["channel_id"] == channel_id:
            data["standups"][i]["messages"].append(new_message)

    return {}
Beispiel #26
0
def standup_start_v1(user_token, channel_id, length):
    """The function start a standup and will last for some seconds. All the message sent in
    that time period will be buffered and send together afer that.

    Args:
        user_token (string): a token string used to authorise and get the user id
        channel_id (int): the channel id where the standup starts
        length (int): the number of seconds

    Raises:
        InputError: channel id invalid
        InputError: standup already starts
        AccessError: user not in the

    Returns:
        dictionary: {'time_finish': time_finish}
    """

    database = getData()

    auth_user_id = findUser(user_token)

    if is_channel_valid(database, channel_id) == False:
        raise InputError(description="Channel id is not valid")
    
    index = get_channel_index(database, channel_id)
    channel = database['channels'][index]

    if channel['standup']['is_active'] == True:
        raise InputError(description="Standup is already active")

    if is_user_in_channel(auth_user_id, channel) == False:
        raise AccessError(description="You are no in the channel")

    time_finish = (datetime.datetime.now()+datetime.timedelta(seconds=length)).strftime("%Y-%m-%d %H:%M:%S")
    time_finish = time.strptime(time_finish, "%Y-%m-%d %H:%M:%S")
    time_finish = time.mktime(time_finish)

    standup_length = length

    database['channels'][index]['standup']['is_active'] = True
    database['channels'][index]['standup']['standup_length'] = standup_length
    database['channels'][index]['standup']['time_finish'] = time_finish
    database['channels'][index]['standup']['messages'] = ""

    with open(file_address, "w") as f:
        json.dump(database, f)

    new_thread = threading.Timer(length, standup_package, args=[index, user_token, channel_id, time_finish])
    new_thread.start()

    return {'time_finish': time_finish}
Beispiel #27
0
def message_edit_v2(token, message_id, message):
    with open('src/data.json', 'r') as FILE:
        data = json.load(FILE)
    editorid = None
    for i in range(len(data['users'])):
        if data['users'][i]['token'] == token:
            editorid = data["users"][i]["u_id"]
    if editorid is None:
        raise AccessError("Invalid token")
    if len(message) > 1000:
        raise InputError("Message is longer than the 1000 character limit")
    # check to see if message exists
    if check_message_exists(message_id) == False:
        raise InputError("Message does not exist")
    # check to see if message is being edited by authorised user
    valid = True
    if check_message_sent_by_user(editorid, message_id) == False:
        valid = False
    # check to see if token belongs to the owner of channel being deleted
    for i in range(len(data["messages"])):
        if data["messages"][i]["message_id"] == message_id:
            channel_id = data["messages"][i]["channel_id"]

    if channel_id is not -1:
        for i in range(len(data["messages"])):
            if data["messages"][i]["message_id"] == message_id:
                channel_id = data["messages"][i]["channel_id"]
        for i in range(len(data["channels"][channel_id]["owner_members"])):
            if data["channels"][channel_id]["owner_members"][i][
                    "u_id"] == editorid:
                valid = True
        if valid == False:
            raise AccessError(
                "Authorised User is not the owner of this channel and did not send this message"
            )
    else:
        if valid == False:
            raise AccessError(
                "Authorised User is not the owner of this dm and did not send this message"
            )

    with open('src/data.json') as FILE:
        data2 = json.load(FILE)
    for i in range(len(data2["messages"]) - 1):
        if data2["messages"][i]["message_id"] == message_id:
            if message is '':
                del data2["messages"][i]
            else:
                data2["messages"][i]["message"] = message
    with open('src/data.json', 'w') as FILE:
        json.dump(data2, FILE, indent=4)
    return {}
Beispiel #28
0
def standup_send_v1(user_token, channel_id, message):
    """get the messages that will be buffered

    Args:
        user_token (string): a token string used to authorise and get the user id
        channel_id (int): the channel id where the standup starts
        message (string): the message

    Raises:
        InputError: channel id invalid
        InputError: message too long
        InputError: standup not started yet
        AccessError: user not in the channel
    
    Returns:
        dic: {}
    """


    database = getData()
    auth_user_id = findUser(user_token)

    if is_channel_valid(database, channel_id) == False:
        raise InputError(description="Channel id is not valid")

    if len(message) > 1000:
        raise InputError(description="Too much charecters in message")
         
    index = get_channel_index(database, channel_id)
    channel = database['channels'][index]

    if channel['standup']['is_active'] == False:
        raise InputError(description="The channel does not have an active standup")

    if is_user_in_channel(auth_user_id, channel) == False:
        raise AccessError(description="You are no in the channel")

    user = use_id_to_find_user(auth_user_id)

    original_msg = database['channels'][index]['standup']['messages']
    if original_msg == "":
        original_msg = user['handle_str'] + ": " + message
    else:
        original_msg = original_msg + "\n" + user['handle_str'] + ": " + message 
    
    database['channels'][index]['standup']['messages'] = original_msg

    with open(file_address, "w") as f:
        json.dump(database, f)

    return {}
Beispiel #29
0
def standup_start_v1(token, channel_id, length):
    with open("data.json") as json_file:
        data = load(json_file)

    auth_user_id = token_check(token)["u_id"]

    is_channel_exist = False
    for channel_data in data["channels"]:
        if channel_data["channel_id"] == channel_id:
            channel = channel_data
            is_channel_exist = True

    if is_channel_exist is False:
        raise InputError("Channel ID is not a valid channel")

    is_standup_already_active = False
    for standup_data in data["standups"]:
        if standup_data["channel_id"] == channel_id:
            is_standup_already_active = True

    if is_standup_already_active is True:
        raise InputError(
            "An active standup is currently running in this channel")

    is_auth_user_member = False
    if auth_user_id in channel["all_members"]:
        is_auth_user_member = True
    if is_auth_user_member is False:
        raise AccessError("Authorised user is not in the channel")

    time_finish = time.time() + length

    data["standups"].append({
        "channel_id": channel_id,
        "message": [],
        "time_finish": time_finish
    })

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    t = threading.Timer(length,
                        standup_close_v1,
                        kwargs={
                            "token": token,
                            "channel_id": channel_id,
                            "u_id": auth_user_id
                        })
    t.start()

    return {"time_finish": time_finish}
Beispiel #30
0
def channels_create_v2(token, name, is_public):
    '''
    Creates a new channel with that name that is either a public or private channel
    
    Returns type:
        { channel_id }

    Input Error:
        Name is more than 20 characters long
    '''
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    # Decode token (u_id) if valid, otherwise raise AccessError
    user = token_check(token)
    # Raise error if channel name is > 20 characters
    # or if there is no name given
    if len(name) > 20:
        raise InputError("Channel name is more than 20 characters.")
    if len(name) == 0:
        raise InputError("No channel name has been entered.")

    # Ensure users sets channel to private or public
    if is_public not in (True, False):
        raise InputError("Channel privacy is undefined")

    # Makes the channel id in order from 1 as they are created
    channel_id = len(data["channels"]) + 1
    # Store data in data.py channels
    user_stats_update(data, user["u_id"], stat_types.CH_JOIN, time_stamp)
    dreams_stats_update(data, stat_types.CH_CREATE, time_stamp)

    data["channels"].append(
        {
            'channel_id': channel_id,
            'name': name,
            'owner_members': [user['u_id']],
            'all_members': [user['u_id']],
            'invites' : [],
            'is_public': is_public,
            'messages': []
        }
    )
    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return { 
        'channel_id': channel_id 
    }