Ejemplo n.º 1
0
def get_next_message_id():
    ''' Helper function to get next message id to be assigned'''
    try:
        message_id = store.get("next_id", "type", "message_id")[0]["value"]
        store.update("next_id", "value", message_id + 1, "type", "message_id")
    except ValueError:
        message_id = 0
        store.insert("next_id", {"type": "message_id", "value": 1})
    return message_id
Ejemplo n.º 2
0
def standup_send(token, channel_id, message):
    ''' Sends a standup message and a normal message'''
    message_send(token, channel_id, message)
    standup_data = store.get("standup", "channel_id", channel_id)[0]
    if not standup_data["is_active"]:
        raise AccessError
    summaries = standup_data["summaries"]
    summaries[standup_data["standup_id"]] += get_name_from_token(token) + ' - ' + message + '\n'
    store.update("standup", "summaries", summaries, "channel_id", channel_id)
    return {}
Ejemplo n.º 3
0
def channels_create(token, name, is_public):
    '''
    Create a new channel
    --------
    token: string
        token of the requester
    name: string
        name of the channel
    is_public: bool
        boolean indicating if the channel will be public or private
    \u207b-------
    ValueError when:
        name is more than 20 characters long
    --------
    return: channel_id
    '''
    type_check_token(token)
    if not isinstance(name, str):
        raise ValueError('Name is not a string')
    if not isinstance(is_public, bool):
        raise ValueError('is_public is not a boolean')
    if not isinstance(name, str):
        raise ValueError('Name is not a string')
    if len(name) > 20:
        raise ValueError('Name is more than 20 characters long')
    if len(name) <= 0:
        raise ValueError('Name is invalid')

    channel_id = store.n_elems('channel_data') + 1
    u_id = auth_check_token(token)
    member = create_member_from_u_id(u_id)
    store.insert('channel_data', {
        'channel_id': channel_id,
        'name': name,
        'messages': [],
        'members': [member],
        'owners': [member],
        'is_public': is_public
    })

    store.insert('channels', {
        'channel_id': channel_id,
        'name' : name
    })

    channels = store.get('users', 'u_id', u_id)[0]['channels']
    channels.append({
        'channel_id': channel_id,
        'name' : name
    })
    store.update('users', 'channels', channels, 'u_id', u_id)

    return {'channel_id': channel_id}
Ejemplo n.º 4
0
def user_profiles_uploadphoto(img_url,
                              x_start,
                              y_start,
                              x_end,
                              y_end,
                              caller_u_id=None):
    # Ideally, we'd have some kind of configuration system to provide us with a way to access
    # the absolute path we need, and our server's URL.
    # However, for the purposes of this project, I think it's good enough to use a relative
    # path and hardcode our URL - especially since the frontend has the loopback address
    # hardcoded too.

    # Check paramater validity
    if x_start >= x_end or y_start >= y_end or min(x_start, x_end, y_start,
                                                   y_end) < 0:
        raise ValueError("Invalid crop coordinates")

    # Get response object for image, and check validity of response
    try:
        resp = urlrequest.urlopen(img_url)
    except HTTPError:
        # non-200 response
        raise ValueError("Image URL did not open successfully")

    if resp.getheader(
            "Content-Type") == None or "image/jpeg" not in resp.getheader(
                "Content-Type"):
        raise ValueError("URL did not point to a JPEG image")

    # Get PIL.Image object for the image
    img = Image.open(resp)
    if x_start > img.width or x_end > img.width or y_start > img.height or y_end > img.height:
        raise ValueError("Invalid crop coordinates")

    # Crop & save the image
    img_cropped = img.crop((x_start, y_start, x_end, y_end))

    file_path = f"../static/img/{str(caller_u_id)}.jpg"  # shady relative path but it's fine
    img_cropped.save(os.path.abspath(file_path))

    # Close images to release memory
    img_cropped.close()
    img.close()

    # Update user dict with URL to profile photo
    photo_URL = f"http://127.0.0.1:5001/img/{str(caller_u_id)}.jpg"
    store.update("users", "profile_img_url", photo_URL, "u_id", caller_u_id)

    return {}
Ejemplo n.º 5
0
def user_profile_setemail(email, caller_u_id=None):
    # check email validity
    if not is_valid_email(email):
        raise ValueError(f"{email} is not a valid email")

    # check if user with email exists
    results = store.get("users", "email", email)
    if len(results) > 0:
        raise ValueError(f"User with email {email} already exists")

    # update email in store
    store.update("users", "email", email, "u_id", caller_u_id)  # != 1:
    #    raise Exception("Error updating email")

    return {}
Ejemplo n.º 6
0
def user_profile_setname(name_first, name_last, caller_u_id=None):
    # check name length requirements
    if len(name_first) < 1 or len(name_first) > 50:
        raise ValueError("Names must be between 1 and 50 characters long")
    if len(name_last) < 1 or len(name_last) > 50:
        raise ValueError("Names must be between 1 and 50 characters long")

    # update names in store
    store.update("users", "name_first", name_first, "u_id",
                 caller_u_id)  # != 1:
    #    raise Exception("Error updating first name")
    store.update("users", "name_last", name_last, "u_id", caller_u_id)  # != 1:
    #    raise Exception("Error updating last name")

    return {}
Ejemplo n.º 7
0
def admin_userpermission_change(token, u_id, permission_id):
    """
    Given a user ID, set their permissions to new permissions described by permission_id.
    """
    if not isinstance(u_id, int):
        raise ValueError("u_id is not an int")
    if not isinstance(permission_id, int):
        raise ValueError("permission_id is not an int")
    if permission_id < 1 or permission_id > 3:
        raise ValueError("permission_id is not valid")

    # Check requesting user's permissions
    req_u_id = auth_check_token(token)
    req_user = store.get("users", "u_id", req_u_id)[0]
    req_perm = req_user.get("permission_id")
    if req_perm == 3:
        raise AccessError("requesting user is not an owner or admin")
    if req_perm == 2 and permission_id == 1:
        raise AccessError("admins cannot make users owners")

    # Check target user
    results = store.get("users", "u_id", u_id)
    if len(results) != 1:
        raise ValueError(f"user with u_id {u_id} does not exist")
    target = results[0]

    target_perm = target.get("permission_id")
    if req_perm == 2 and target_perm == 1:
        raise AccessError("admins cannot change owners' permissions")

    # Execute permission change
    index = store.update("users", "permission_id", permission_id, "u_id", u_id)
    if index == 0:
        raise ValueError("Invalid user ID")
    return {}
Ejemplo n.º 8
0
def user_profile_sethandle(handle_str, caller_u_id=None):
    # check handle length requirements
    if len(handle_str) < 3 or len(handle_str) > 20:
        raise ValueError("handle must be between 3 and 20 characters long")

    # check if user with handle exists
    results = store.get("users", "handle_str", handle_str)
    if len(results) > 0:
        raise ValueError(f"user with handle {handle_str} already exists")

    # update handle in store
    store.update("users", "handle_str", handle_str, "u_id",
                 caller_u_id)  # != 1:
    #    raise Exception("error updating handle")

    return {}
Ejemplo n.º 9
0
def channel_removeowner(token, channel_id, u_id):
    '''
    Change an owner into an user in the channel
    -------
    token: string
        Changer token
    channel_id: int
        id of the channel
    u_id: int
        id of the owner who will become user
    --------
    ValueError when:

        channel_id does not refer to a valid channel that the authorised user is part of.
        u_id does not refer to a valid user which is part of the channel
        u_id is already an owner of the channel
        token does not refer to a valid user

    AccessError when:
        the authorised user is not an owner of the slackr, or an owner of this channel
    --------
    Returns {}
    '''
    type_check_token(token)
    type_check_channel_id(channel_id)
    type_check_u_id(u_id)

    check_channel_exists(channel_id)
    if not owner_in_channel(u_id, channel_id):
        raise ValueError('The user with ID u_id is not an owner of the channel')

    requester_u_id = auth_check_token(token)
    req_perm = store.get('users', 'u_id', requester_u_id)[0]['permission_id']

    if req_perm == 3 and not user_in_channel(requester_u_id, channel_id):
        raise ValueError('The requester is not part of the channel and is also not an admin/owner')
    if req_perm == 3 and not owner_in_channel(requester_u_id, channel_id):
        raise AccessError('Requester has not the right to add an owner')
    if nb_of_channel_owners(channel_id) == 1:
        raise ValueError('The requested u_id is the only owner of the channel')

    channel_owners = store.get('channel_data', 'channel_id', channel_id)[0]['owners']
    remove_member_from_list(u_id, channel_owners)
    store.update('channel_data', 'owners', channel_owners, 'channel_id', channel_id)

    return {}
Ejemplo n.º 10
0
def channel_addowner(token, channel_id, u_id):
    '''
    Change a user into an owner in the channel
    -------
    token: string
        Changer token
    channel_id: int
        id of the channel
    u_id: int
        id of the user who will become owner
    --------
    ValueError when:

        channel_id does not refer to a valid channel that the authorised user is part of.
        u_id does not refer to a valid user which is part of the channel
        u_id is already an owner of the channel
        token does not refer to a valid user

    AccessError when

        the authorised user is not already a member of the channel
    --------
    Returns {}
    '''
    type_check_token(token)
    type_check_channel_id(channel_id)
    type_check_u_id(u_id)

    check_channel_exists(channel_id)
    if owner_in_channel(u_id, channel_id):
        raise ValueError('The user with ID u_id is already an owner of the channel')

    requester_u_id = auth_check_token(token)
    req_perm = store.get('users', 'u_id', requester_u_id)[0]['permission_id']
    if req_perm == 3 and not user_in_channel(requester_u_id, channel_id):
        ValueError('Requester is not part of the channel, and is a normal user in the slackr')
    if req_perm == 3 and not owner_in_channel(requester_u_id, channel_id):
        raise AccessError('Requester has not the right to add an owner')

    channel_owners = store.get('channel_data', 'channel_id', channel_id)[0]['owners']
    channel_owners.append(create_member_from_u_id(u_id))
    store.update('channel_data', 'owners', channel_owners, 'channel_id', channel_id)

    return {}
Ejemplo n.º 11
0
def channel_invite(token, channel_id, u_id):
    '''
    Invite a user in the channel
    -------
    token: string
        Inviter token
    channel_id: int
        id of the channel
    u_id: int
        id of the user invited
    --------
    ValueError when:

        channel_id does not refer to a valid channel that the authorised user is part of.
        u_id does not refer to a valid user which is part of the channel
        token does not refer to a valid user

    AccessError when

        the authorised user is not already a member of the channel
    --------
    Returns {}
    '''
    type_check_token(token)
    type_check_channel_id(channel_id)
    type_check_u_id(u_id)

    check_channel_exists(channel_id)
    check_user_not_in_channel_value_error(u_id, channel_id, 'u_id is already part of the channel')
    check_user_in_channel_access_error(auth_check_token(token), channel_id,
                                       'The token is not a member of channel')

    channel_members = store.get('channel_data', 'channel_id', channel_id)[0]['members']
    new_member = create_member_from_u_id(u_id)
    channel_members.append(new_member)
    store.update('channel_data', 'members', channel_members, 'channel_id', channel_id)

    user_channels = store.get('users', 'u_id', u_id)[0]['channels']
    user_channels.append(get_channel(channel_id))
    store.update('users', 'channels', user_channels, 'u_id', u_id)

    return {}
Ejemplo n.º 12
0
def channel_join(token, channel_id):
    '''
    Join a channel
    -------
    token: string
        joiner token
    channel_id: int
        id of the channel
    --------
    ValueError when:

        channel_id does not refer to a valid channel that the authorised user is part of.
        token does not refer to a valid user which is not part of the channel

    AccessError whenchannel_id refers to a channel that is private
    - when the authorised user is not an admins
    --------
    Returns {}
    '''
    type_check_token(token)
    type_check_channel_id(channel_id)

    check_channel_exists(channel_id)
    req_u_id = auth_check_token(token)
    check_user_not_in_channel_value_error(req_u_id, channel_id, 'token is already in channel')

    req_permission = store.get('users', 'u_id', req_u_id)[0]['permission_id']
    channel_is_public = store.get('channel_data', 'channel_id', channel_id)[0]['is_public']
    if (not channel_is_public) and (req_permission == 3):
        raise AccessError('The user is not an admin and he tries to access a private channel')

    member = create_member_from_u_id(req_u_id)
    new_list_members = store.get('channel_data', 'channel_id', channel_id)[0]['members']
    new_list_members.append(member)
    store.update('channel_data', 'members', new_list_members, 'channel_id', channel_id)

    user_channels = store.get('users', 'u_id', req_u_id)[0]['channels']
    user_channels.append(get_channel(channel_id))
    store.update('users', 'channels', user_channels, 'u_id', req_u_id)

    return {}
Ejemplo n.º 13
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
    TODO stub
    """
    # Check if reset code is valid
    res = store.get("resets", "reset_code", reset_code)
    if not res:
        raise ValueError("invalid reset code")
    reset = res[0]

    # Change password
    if len(new_password) < 6:
        raise ValueError("new password must be at least 6 characters")

    pwhash = hashlib.sha256(new_password.encode("utf-8")).hexdigest()
    store.update("users", "password", pwhash, "u_id", reset.get("u_id"))

    # Remove reset obj from store (after successful reset, just in case user screws up)
    store.remove("resets", "reset_code", reset_code)

    return {}
Ejemplo n.º 14
0
def standup_start(token, channel_id, standup_length=15*60):
    ''' Begin standup in channel, calls end standup after the time has expired'''
    validate_user(token, channel_id, "channel")
    except_message = "Already currently active standup"
    try:
        standup_data = store.get("standup", "channel_id", channel_id)[0]
        if standup_data["is_active"]:
            raise ValueError(except_message)
        store.update("standup", "is_active", True, "channel_id", channel_id)
        new_message_index = standup_data["standup_id"]
        store.update("standup", "standup_id", new_message_index+1, "channel_id", channel_id)
        summaries = standup_data["summaries"]
        summaries.append("Standup summary:\n")
        store.update("standup", "summaries", summaries, "channel_id", channel_id)
    except (ValueError) as ex:
        if ex.args[0] == except_message:
            raise ValueError(ex)
        store.insert("standup", {"channel_id": channel_id, "is_active": True,\
            "standup_id": 0, "summaries": ["Standup summary:\n"]})
    end = datetime.now()+timedelta(seconds=standup_length)
    my_timer(end, standup_end, (token, channel_id))
    store.update("standup", "end", end, "channel_id", channel_id)
    return {"time_finish" : convert_time(end)}
Ejemplo n.º 15
0
def channel_leave(token, channel_id):
    '''
    Leaves a channel
    -------
    token: string
        leaver token
    channel_id: int
        id of the channel
    --------
    ValueError when:

        channel_id does not refer to a valid channel that the authorised user is part of.
        token does not refer to a valid user which is part of the channel
    --------
    Returns {}
    '''
    type_check_token(token)
    type_check_channel_id(channel_id)
    check_channel_exists(channel_id)

    req_u_id = auth_check_token(token)
    check_user_in_channel_value_error(req_u_id, channel_id, 'User is not in channel')

    if nb_of_channel_members(channel_id) == 1:
        raise ValueError('You can\'t quit a channel with 1 member')
    if nb_of_channel_owners(channel_id) == 1 and owner_in_channel(req_u_id, channel_id):
        raise ValueError('You are the only owner of the channel')

    members_before = store.get("channel_data", "channel_id", channel_id)[0].get("members")
    remove_member_from_list(req_u_id, members_before)
    store.update("channel_data", "members", members_before, "channel_id", channel_id)

    owners_before = store.get("channel_data", "channel_id", channel_id)[0].get("owners")
    try:
        remove_member_from_list(req_u_id, owners_before)
        store.update("channel_data", "owners", owners_before, "channel_id", channel_id)
    except ValueError:
        pass

    channels_before = store.get("users", "u_id", req_u_id)[0].get("channels")
    remove_channel_from_list(channel_id, channels_before)
    store.update("users", "channels", channels_before, "u_id", req_u_id)

    return {}
Ejemplo n.º 16
0
def update_channel_messages(channel_id, messages):
    ''' Helper function to store updated messages back in channel'''
    store.update("channel_data", "messages", messages, "channel_id",
                 channel_id)