示例#1
0
文件: channel.py 项目: Vinceyn/slackr
def channel_details(token, channel_id):
    '''
    Give the details of a channel
    -------
    token: string
        Requester 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.
    AccessError when:
        token does not refer to a valid user which is part of the channel
    --------
    Returns a dictionnary containing the name of the channel and info about the users and owners
    '''
    type_check_token(token)
    type_check_channel_id(channel_id)

    check_channel_exists(channel_id)
    check_user_in_channel_access_error(auth_check_token(token), channel_id,
                                       'The requester user is not in channel')

    channel_name = store.get('channel_data', 'channel_id', channel_id)[0]['name']
    channel_owners = store.get('channel_data', 'channel_id', channel_id)[0]['owners']
    channel_members = store.get('channel_data', 'channel_id', channel_id)[0]['members']
    return {'name': channel_name,
            'owner_members': channel_owners,
            'all_members': channel_members}
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 {}
示例#3
0
文件: channel.py 项目: Vinceyn/slackr
def create_member_from_u_id(u_id):
    '''
    Given a u_id, this function returns it under the 'member' form.
    '''
    member = {
        'u_id' : u_id,
        'name_first' : store.get('users', 'u_id', u_id)[0]['name_first'],
        'name_last' : store.get('users', 'u_id', u_id)[0]['name_last']
    }
    return member
示例#4
0
def validate_user(token, update_id, input_type: str, pin=False, \
    react_channel_id="tmp", react_message_id="tmp"):
    ''' Function determined if the user has sufficient permissions to perform
    functionality specified in arguments'''
    u_id = auth_check_token(token)
    if input_type == "channel":
        user_data = store.get("users", "u_id", u_id)[0]
        for channel in user_data["channels"]:
            if channel["channel_id"] == update_id:
                return
        raise AccessError(
            "User is not part of channel or channel does not exist")
    if input_type == "message":
        message_data = get_message_data_from_m_id(update_id)
        if u_id == message_data["u_id"]:
            return
        channel_data = get_channel_data_from_m_id(update_id)
        for owner in channel_data["owners"]:
            if owner["u_id"] == u_id:
                return
        if is_admin(token):
            return
        raise AccessError("User doesn't have permission to alter message")
    if input_type == "react":
        # Not sure the values a react id should have hence jsut return
        message_data = store.get("channel_data", "channel_id",
                                 react_channel_id)[0]["messages"]
        for message in message_data:
            if message["message_id"] == react_message_id:
                for react in message["reacts"]:
                    for uid in react["u_ids"]:
                        if uid["u_id"] == u_id:
                            if pin:
                                return
                            raise ValueError("User already reacted")
        if pin:
            raise ValueError
        return
    if input_type == "pin":
        message = get_message_data_from_m_id(update_id)
        if not is_admin(token):
            raise ValueError("User not admin, must be admin to pin")
        if message["is_pinned"] and pin:
            raise ValueError("Message already pinned")
        if not message["is_pinned"] and not pin:
            raise ValueError("Message is not pinned")
        return
    raise ValueError(
        "Incorrect type to validate: use 'channel', 'message' or 'react'")
示例#5
0
def auth_check_token(token):
    """
    Given a token, verify that it is a valid token, with a valid session ID, and return
    the u_id of the token owner
    """
    # Decode token
    try:
        payload = jwt.decode(token, HMAC_SECRET, algorithms=['HS256'])
    except:
        # invalid token
        raise AccessError("Error parsing & verifying token")

    # Check if session exists in store
    results = store.get("sessions", "jwt_id", payload.get("jti"))
    if not results:
        raise AccessError("Invalid session token")

    # Check that session belongs to this user
    # multiple sessions may share a session ID, so we iterate through
    # this is pretty unlikely though, so we comment this out
    # sess = None
    # for index in results:
    #     if index.get("u_id") == payload.get("uid"):
    #         sess = index
    # if sess == None:
    #     raise AccessError("Invalid session token")

    return results[0].get("u_id")
示例#6
0
文件: message.py 项目: Vinceyn/slackr
def get_channel_id_from_message_id(message_id):
    ''' Helper function to get channel_id from message id'''
    channel_data = store.get("channel_data")
    for channel in channel_data:
        for message in channel["messages"]:
            if message["message_id"] == message_id:
                return channel["channel_id"]
    raise ValueError("Message ID doesn't exist")
示例#7
0
文件: channel.py 项目: Vinceyn/slackr
def get_channel(channel_id):
    '''
    This function gets channel storage value from channel_id.
    '''
    return {
        'channel_id' : channel_id,
        'name' : store.get('channel_data', 'channel_id', channel_id)[0]['name']
    }
示例#8
0
文件: channel.py 项目: Vinceyn/slackr
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 {}
示例#9
0
def get_message_data_from_m_id(message_id):
    ''' Helper function to get message data from message_id'''
    channel_data = store.get("channel_data")
    for channel in channel_data:
        for message in channel["messages"]:
            if message["message_id"] == message_id:
                return message
    raise ValueError("message id doesn't exist")
示例#10
0
def standup_end(token, channel_id):
    ''' Prints executive summary as a message and closes standup'''
    standup_data = store.get("standup", "channel_id", channel_id)[0]
    standup_data["is_active"] = False
    index = standup_data["standup_id"]
    summary = standup_data["summaries"][index]
    print(f"Summary: {summary}")
    if summary != "Standup summary:\n":
        message_send(token, channel_id, summary)
示例#11
0
文件: message.py 项目: Vinceyn/slackr
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
示例#12
0
文件: channel.py 项目: Vinceyn/slackr
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 {}
示例#13
0
文件: channel.py 项目: Vinceyn/slackr
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 {}
示例#14
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 {}
示例#15
0
文件: channel.py 项目: Vinceyn/slackr
def channel_exist(channel_id):
    '''
    This function finds if the channel_id exists or not.
    '''
    channel_list = store.get('channel_data')
    channel_exist_bool = False
    for channel in channel_list:
        if channel_id == channel['channel_id']:
            channel_exist_bool = True
    return channel_exist_bool
示例#16
0
文件: channel.py 项目: Vinceyn/slackr
def owner_in_channel(u_id, channel_id):
    '''
    This function finds if the u_id is an owner of the channel or not.
    '''
    members = store.get('channel_data', 'channel_id', channel_id)[0]['owners']
    is_in_channel = False
    for member in members:
        if u_id == member['u_id']:
            is_in_channel = True
    return is_in_channel
示例#17
0
文件: channel.py 项目: Vinceyn/slackr
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 {}
示例#18
0
文件: channel.py 项目: Vinceyn/slackr
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 {}
示例#19
0
文件: channel.py 项目: Vinceyn/slackr
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}
示例#20
0
文件: channel.py 项目: Vinceyn/slackr
def channel_messages(token, channel_id, start):
    '''
    Give a list of me    # Checking for a valid channel_id.
    ssages of a channel, starting from an index
    -------
    token: string
        Requester token
    channel_id: int
        id of the channel
    start: int
        starting index 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
        start is either greater or equal to total number of messages in the channel, or is negative

    AccessError when:
        Authorised user is not a member of channel with channel_id
    --------
    Returns - start and end index (-1 if it reached the end)
            - and all of the messages between the 2 index
    '''
    type_check_token(token)
    type_check_channel_id(channel_id)
    if not isinstance(start, int):
        raise ValueError('start is not an int')

    check_channel_exists(channel_id)
    check_user_in_channel_access_error(auth_check_token(token), channel_id,
                                       'requester is not a member of the channel')

    messages = store.get('channel_data', 'channel_id', channel_id)[0]['messages']
    if (start < 0 or start > len(messages)):
        raise ValueError('Start index is not correctly indexed')

    start_index = - (start + 1)
    end_return = -1
    returned_messages = []
    if start + 50 <= len(messages):
        end_return = start + 49
        returned_messages = messages[start_index: - (start + 51):-1]
    else:
        returned_messages = messages[start_index::-1]

    return {
        'messages': returned_messages,
        'start' : start,
        'end': end_return
    }
示例#21
0
文件: user.py 项目: Vinceyn/slackr
def user_profile(u_id):
    results = store.get("users", "u_id", u_id)
    if len(results) != 1:
        raise ValueError("u_id is not valid")

    user = results[0]

    return {
        "email": user.get("email"),
        "name_first": user.get("name_first"),
        "name_last": user.get("name_last"),
        "handle_str": user.get("handle_str"),
        "profile_img_url": user.get("profile_img_url")
    }
示例#22
0
文件: user.py 项目: Vinceyn/slackr
def user_all():
    # We need to filter the dicts we get from the store, so we only return
    # relevant, non-sensitive information
    all_users = store.get("users")
    filtered_users = [{
        "u_id": i.get("u_id"),
        "email": i.get("email"),
        "name_first": i.get("name_first"),
        "name_last": i.get("name_last"),
        "handle_str": i.get("handle_str"),
        "profile_img_url": i.get("profile_img_url")
    } for i in all_users]

    return {"users": filtered_users}
示例#23
0
文件: channel.py 项目: Vinceyn/slackr
def channels_list(token):
    '''
    Given a token, list all the channel the token is part of
    --------
    token: string
        token of the requester
    --------
    ValueError when:
        The token doesn't refer to a proper user
    --------
        return: list of all the channels the token is part of
    '''
    type_check_token(token)
    return {"channels": store.get("users", "u_id", auth_check_token(token))[0]["channels"]}
示例#24
0
def standup_active(token, channel_id):
    ''' Returns if there is an active standup in the channel'''
    validate_user(token, channel_id, "channel")
    active = False
    end_time = None
    try:
        standup_data = store.get("standup", "channel_id", channel_id)[0]
        if standup_data["is_active"]:
            active = True
            end_time = standup_data["end"]
    # pylint: disable=broad-except
    except Exception:
        pass
    return {"is_active":active, "time_finish":convert_time(end_time)}
示例#25
0
文件: user.py 项目: Vinceyn/slackr
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 {}
示例#26
0
文件: channel.py 项目: Vinceyn/slackr
def channels_listall(token):
    '''
    Given a token, list all the channel
    --------
    token: string
        token of the requester
    --------
    ValueError when:
        The token doesn't refer to a proper user
    --------
        return: list of all the channels
    '''
    type_check_token(token)
    if store.n_elems('channel_data') == 0:
        return {'channels': []}
    return {'channels': store.get('channels')}
示例#27
0
文件: user.py 项目: Vinceyn/slackr
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 {}
示例#28
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 {}
示例#29
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)}
示例#30
0
文件: reset.py 项目: Vinceyn/slackr
def gen_request():
    global MAIN_APP
    if MAIN_APP == None:
        # should never happen
        raise ValueError()
        pass

    mail = Mail(MAIN_APP)
    email = request.form.get("email")

    # Check if email exists
    results = store.get("users", "email", email)
    if len(results) == 0:
        raise ValueError("Email does not belong to any user") # this should get caught by our handler
    user = results[0]

    # Generate a reset code
    # it's highly unlikely we'll have a clash :))))
    code = "".join([RESET_CHARS[random.randint(0, len(RESET_CHARS) - 1)] for i in range(16)])
    auth_passwordreset_addcode(code, user.get("u_id"))

    # Send email
    msg = Message("Your slackr password reset",
        sender=SLACKR_ADDR,
        recipients=[email])
    msg.body = f"""Hi {user.get("name_first")},

    Someone requested a password reset for your email on slackr.

    Your reset code is: {code}

    If you did not request this, please contact our very existant support team.
    """
    mail.send(msg)

    return {}