Example #1
0
def message_remove(token, message_id):
    """
    Given a message_id for a message, this message is removed from the channel.
    """
    u_id = get_current_user(token)

    message_location = get_message_location(message_id)

    channel_id = message_location["channel_id"]
    channel_data = get_channel_data(channel_id)

    if u_id not in channel_data['member_ids']:
        raise AccessError(
            description="User must be a member of the channel they are trying"
            + " to access.")

    # Find the message to be deleted. At this point
    #   The message definitely exists and the user is definitely a member of the channel
    #   it exists in.
    for message in channel_data["messages"]:
        if message['message_id'] == message_id:
            if message["u_id"] != u_id and get_permission_dict(u_id).get(
                    'permission_id') != 1:
                raise AccessError(
                    description="Authorised user did not send the message " +
                    "and is not a server/channel owner.")
            else:
                remove_message(message_id)

    return {}
def standup_send(token, channel_id, message):
    """ Add a message to standup queue """

    # If token is valid, take u_id which is used to look through users
    u_id = database.get_current_user(token)

    # Check if user is member of channel that message is within
    # if not then raise an AccessError
    channel_data = database.get_channel_data(channel_id)
    if u_id not in channel_data['member_ids']:
        raise error.AccessError(
            description="You are not a member of this channel")

    # Check if message if more than 1000 characters long and raise InputError if that is the case
    if len(message) > 1000:
        raise error.InputError(
            description="The message entered is more than 1000 characters long"
        )

    # Check if standup is currently active in channel, raise InputError if not
    if standup_active(token, channel_id)['is_active'] is False:
        raise error.InputError(
            description="There are no standups active in this channel")

    # Format message to "handle_str: message"
    handle_str = database.get_user_data(u_id)['handle_str']
    string = handle_str + ": " + message

    # Now add string to the appropriate list in queues
    QUEUES[str(channel_id)].append(string)

    return {}
Example #3
0
def message_unpin(token, message_id):
    """
    Given a message within a channel, remove it's mark as unpinned.
    """
    u_id = get_current_user(token)
    message_location = get_message_location(message_id)
    message_file = get_message(message_id)

    ################### START ERROR CHECKS ############################

    channel_data = get_channel_data(message_location['channel_id'])

    check = next((i for i in channel_data['member_ids'] if i == u_id), False)

    if check is False:
        raise AccessError(description='The authorised user is not ' +
                          'a member of the channel that the message is within')

    if u_id not in channel_data['owner_ids']:
        raise AccessError(description='The authorised user is not an owner')

    ##################### END ERROR CHECKS ########################

    if message_file['is_pinned'] is False:
        raise InputError(
            description='Message with ID message_id is already unpinned')
    else:
        message_file['is_pinned'] = False
    return {}
def channels_create(token, name, is_public):
    """ Create a channel using the given parameters """

    # Check if name is more than 20 characters long and return InputError if this is the case
    if len(name) > 20:
        raise error.InputError(
            description="The name you entered is more than 20 characters long")

    # Generate a channel_id for the new channel
    # Simply done in order of time of creation (1..)
    # Generation of channel_id will be done in this way as long as ability to delete channels
    # remains unimplemented
    num_channels = len(database.get_channels())
    channel_id = num_channels + 1

    # Use database.set_channel to create channel in the database
    channel = {'channel_id': channel_id, 'name': name}
    database.set_channel(channel)
    channel_data = database.get_channel_data(channel_id)
    channel_data['is_public'] = is_public
    database.set_channel_data(channel_data)

    # User who creates the channel joins it automatically
    channel_join(token, channel_id)

    return {'channel_id': channel_id}
Example #5
0
def is_user_channel_member(channel_id, u_id):
    """
    Helper function to check if a user is part of a channel
    """
    for selected_id in database.get_channel_data(channel_id)["member_ids"]:
        if selected_id == u_id:
            return True
    return False
Example #6
0
def channel_invite(token, channel_id, u_id):
    """
    Invites a user (with user id u_id) to join a channel with
    ID channel_id. Once invited the user is added to the channel immediately
    """

    if database.get_current_user(token) not in database.get_channel_data(channel_id)['member_ids']:
        raise error.AccessError(description="""Authorised user is not
                                a member of channel with that channel_id.""")
    if u_id in database.get_channel_data(channel_id).get('member_ids'):
        raise error.InputError(description="This user is already a part of the channel.")

    new_channel_data = database.get_channel_data(channel_id)

    new_channel_data['member_ids'].append(u_id)
    if database.get_permission_dict(u_id).get('permission_id') == 1:
        new_channel_data['owner_ids'].append(u_id)

    database.set_channel_data(new_channel_data)

    return {}
def call_bot(channel_id):
    """ Bot is registered if not a user.
    Bot is logged in if not logged in.
    Bot joins the channel if not a member of the channel. """

    if database.get_user_data(-1) is None:
        register_bot()
    elif database.get_token_from_user(-1) is None:
        login_bot()

    channel_data = database.get_channel_data(channel_id)
    if -1 not in channel_data['member_ids']:
        channel.channel_join(BOT_TOKEN, channel_id)

    return {"bot_id": -1}
def search(token, query_str):
    """
    returns all messages that user is in with certain quesry string
    """
    if query_str == "":
        raise error.InputError(description="search received an empty query string")
    # user_channels = {'channels': [], []}
    user_channels = channels.channels_list(token)
    message_list = []
    for channel in user_channels['channels']:
        channel_data = database.get_channel_data(channel['channel_id'])
        for message in channel_data['messages']:
            if query_str in message['message']:
                message_list.append(message)
    message_list.sort(key=itemgetter('time_created'), reverse=True)
    return {"messages" : message_list}
def channels_list(token):
    """ Returns {channels}, where channels is a list of channels that the user is part of.
    i.e. {'channels': [{channel_id, name}, {channel_id, name}]} """

    u_id = database.get_current_user(token)

    output = {'channels': []}

    # obtain channels so that I can see lists of members
    # insert channel into the output list if user is a member
    for channel in database.get_channels():
        channeldata = database.get_channel_data(channel['channel_id'])
        if u_id in channeldata['member_ids']:
            output['channels'].append(channel)

    return output
Example #10
0
 def wrapper_func(*args, **kwargs):
     """ Wrapper function """
     try:
         cidarg_index = argspec.args.index("channel_id")
         target_channel = database.get_channel_data(args[cidarg_index])
         # Check the u_id is valid.
         if target_channel is None:
             # u_id is invalid
             raise error.InputError(
                 description="Channel ID is not a valid channel")
         else:
             return func(*args, **kwargs)
     except ValueError:
         print("\033[93m" +
               "WARNING: c_id arg not found - running function " +
               f"{func.__name__} without c_id check." + "\033[0m")
         return func(*args, **kwargs)
Example #11
0
def channel_addowner(token, channel_id, u_id):
    """
    This function intakes the token of current authorised (auth) user, channel_id and a user u_id
    It then adds the user u_id as an owner of the channel,
    as long as the current auth user is an owner of slackr/channel
    """
    # Check if token is valid and raise AccessError if not
    curr_id = database.get_current_user(token)
    # gets current channel data
    curr_channel = database.get_channel_data(channel_id)
    # gets the permissions of current user from database
    user_perms = database.get_permission_dict(curr_id)

    # check if user u_id is already an owner of the channel and raise InputError if so
    # also checks to see if current auth user is a owner of channel

    # a counter to check if user is a member of the channel
    is_curr_owner = False
    for owner_id in curr_channel["owner_ids"]:
        if u_id == owner_id:
            raise error.InputError(description="user u_id is already an owner of this channel")
        # checks if curr_id is an owner of channel
        if curr_id == owner_id:
            is_curr_owner = True

    # checks if the user u_id is a member of the channel already
    is_u_member = False
    for member_id in curr_channel["member_ids"]:
        if u_id == member_id:
            is_u_member = True


    # if the auth user is an owner of the slackr, allow him to add u_id as owner of channel
    if is_u_member is True:
        if user_perms["permission_id"] == 1:
            # adds the user into channel_owner
            curr_channel["owner_ids"].append(u_id)
        # if the auth user is an owner of the channel, allow him to add u_id as owner of channel
        elif is_curr_owner is True:
            # adds the user into channel_owner
            curr_channel["owner_ids"].append(u_id)
        # else the auth user is not an owner and thus cannot use addowner
        else:
            raise error.AccessError(description="""current user is not an owner of the channel,
                                    or of the slackr""")
Example #12
0
def channel_details(token, channel_id):
    """
    This function is given a valid token and channel_id.
    It then returns the name, owners and members of the channel
    """
    # Check if token is valid and raise AccessError if not
    curr_id = database.get_current_user(token)

    # check if user is a member of channel with channel_ID and return AccessError if not
    if is_user_channel_member(channel_id, curr_id) is False:
        raise error.AccessError(description="""You must be a member of the channel to view its
                                details.""")

    # now we return the name, owners and members of the channel
    details = {"name": "", "owner_members": [], "all_members": []}
    # for owner/all_members we need a list of dictionaries containing u_id, first name and last name
    # {"u_id": [], "name_first": "", "name_last": ""}

    channel = database.get_channel(channel_id)
    members = database.get_channel_data(channel_id)

    details["name"] = channel["name"]
    for user_id in members["owner_ids"]:

        owner_id = user_id
        user_data = database.get_user_data(owner_id)
        name_first = user_data["name_first"]
        name_last = user_data["name_last"]
        profile_img_url = user_data['profile_img_url']
        details["owner_members"].append({"u_id": owner_id, "name_first": name_first,
                                         "name_last": name_last,
                                         "profile_img_url": profile_img_url})

    for user_id in members["member_ids"]:
        member_id = user_id
        user_data = database.get_user_data(member_id)
        name_first = user_data["name_first"]
        name_last = user_data["name_last"]
        profile_img_url = user_data['profile_img_url']
        details["all_members"].append({"u_id": member_id, "name_first": name_first,
                                       "name_last": name_last,
                                       "profile_img_url": profile_img_url})

    return details
def remove_user(token, u_id):
    """ Given a u_id, remove the user from the Slackr. """

    # we get the current user data
    terminator = database.get_current_user(token)

    # Raise AccessError if user is not an owner of the Slackr
    terminator_perm = database.get_permission_dict(terminator)
    if terminator_perm['permission_id'] != 1:
        raise error.AccessError(description="""Action cannot be performed
                                               because you are not a Slackr owner.""")

    # Do a soft remove
    # they stay a part of everything, but they are removed from owner/memberID
    # in channels, and they are also banned from ever logging in again.

    # we get the token of the user to be removed

    # introduce a new permission ID 66:
    # terminated and set the user to be removed to perm_id 66: terminated
    terminated_id = 66
    database.set_permissions(u_id, terminated_id)

    # remove the user from every channel's member_id and owner_id
    #first we call a list of every channel
    all_channels = database.get_channels()
    # we then get the data for each channel
    for each_channel in all_channels:
        channel_data = database.get_channel_data(each_channel["channel_id"])

        # remove user u_id from owner_ids
        for owner_id in channel_data['owner_ids']:
            if u_id == owner_id:
                channel.channel_removeowner(token, channel_data["channel_id"], u_id)

        # remove user u_id from member_ids
        if u_id in channel_data['member_ids']:
            channel_data['member_ids'].remove(u_id)
        database.set_channel_data(channel_data)

    # finally we log the user out of the session (invalidating terminated token)
    terminated_token = database.get_token_from_user(u_id)
    if terminated_token is not None:
        auth.auth_logout(terminated_token)
Example #14
0
def user_in_message_channel(message_id, u_id):
    """
    A helper function to check whether the user is in channel with channel_id provided
    Returns True if passes check - otherwise raises InputError.
    """
    message_location = get_message_location(message_id)
    channel_id = message_location["channel_id"]
    channel_data = get_channel_data(channel_id)
    check = False

    for user in channel_data["member_ids"]:
        if user == u_id:
            check = True
    if check is False:
        raise InputError(
            description='message_id is not a valid message within' +
            'a channel that the authorised user has joined')
    else:
        return check
Example #15
0
def channel_removeowner(token, channel_id, u_id):
    """
    This function intakes the token of current authorised (auth) user, channel_id and a user u_id
    It then removes the user u_id as an owner of the channel,
    as long as the current auth user is an owner of slackr/channel
    and the user u_id is an owner
    """
    # Check if token is valid and raise AccessError if not
    curr_id = database.get_current_user(token)
    # gets current channel data
    curr_channel = database.get_channel_data(channel_id)
    # gets the permissions of current user from database
    user_perms = database.get_permission_dict(curr_id)

    u_id_permission = database.get_permission_dict(u_id)
    if u_id_permission["permission_id"] == 1:
        raise error.AccessError(description="user being removed is the owner of the slackr")

    # checks if u_id is not an owner of the channel
    # also checks if current auth user is an owner of the channel
    is_u_owner = False
    is_curr_owner = False
    for owner_id in curr_channel["owner_ids"]:
        if u_id == owner_id:
            is_u_owner = True
        if curr_id == owner_id:
            is_curr_owner = True
    if is_u_owner is False:
        raise error.InputError(description="user being removed is not an owner of the channel")


    # if the auth user is owner of slackr, allows him to remove u_id as owner
    if user_perms["permission_id"] == 1:
        # removes the user from channel_owner
        curr_channel["owner_ids"].remove(u_id)
    # if the auth user is an owner of the channel, allow him to remove u_id as owner of channel
    elif is_curr_owner is True:
        # adds the user into channel_owner
        curr_channel["owner_ids"].remove(u_id)
    # else the auth user is not an owner and thus cannot use addowner
    else:
        raise error.AccessError(description="""Authorised user user is not an owner of the channel,
                                or of the slackr""")
Example #16
0
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.
    """
    u_id = get_current_user(token)

    message_location = get_message_location(message_id)

    # if message is longer than 1000 an Inputerror should be raised.
    if len(message) > 1000:
        raise InputError(
            description=
            'Message is more than 1000 characters or try to send an empty message'
        )

    channel_id = message_location["channel_id"]
    channel_data = get_channel_data(channel_id)

    if u_id not in channel_data['member_ids']:
        raise AccessError(
            description="User must be a member of the channel they are trying"
            + " to access.")

    # Find the message to be deleted (assume it definitely exists)
    msg_to_edit = next(msg for msg in channel_data['messages']
                       if msg['message_id'] == message_id)

    if msg_to_edit['u_id'] != u_id and get_permission_dict(
            u_id)['permission_id'] != 1:
        raise AccessError(
            description="Authorised user did not send the message " +
            "and is not a server/channel owner.")

    if message == '':
        remove_message(message_id)
    else:
        msg_to_edit['message'] = message
        set_message(channel_id, msg_to_edit)

    return {}
Example #17
0
def channel_join(token, channel_id):
    """
    this function is passed a valid token and channel_id.
    It adds the user associated with the token into the channel, unless the channel is private
    """

    # Check if token is valid and raise AccessError if not
    curr_id = database.get_current_user(token)

    # gets current channel data
    curr_channel = database.get_channel_data(channel_id)
    # gets the permissions of current user from database
    user_perms = database.get_permission_dict(curr_id)

    # checks if user is already a part of channel
    for user_id in curr_channel["member_ids"]:
        if curr_id == user_id:
            raise error.InputError(description="user is joining a channel user is already in")

    # this checks if the channel is empty (or new) in this case we make the new member an owner.
    if curr_channel["member_ids"] == []:
        # adds the user into channel_member
        curr_channel["member_ids"].append(curr_id)
        # adds the user into channel_owner
        curr_channel["owner_ids"].append(curr_id)
    # this checks if the user is an owner of the slacker
    # if they are they are given owner privelages in the channel
    # else they are a member
    elif user_perms["permission_id"] == 1:
        # adds the user into channel_member
        curr_channel["member_ids"].append(curr_id)
        # adds the user into channel_owner
        curr_channel["owner_ids"].append(curr_id)
    elif curr_channel["is_public"] is True:
        # adds the user into the channel_member
        curr_channel["member_ids"].append(curr_id)
    elif curr_channel["is_public"] is False:
        raise error.InputError(description="""channel_join recieved a channel_id
                               for a private channel""")
Example #18
0
def channel_leave(token, channel_id):
    """
    This function takes in a token and channel ID.
    if both are valid, it will then remove the member from channel
    """

    # Check if token is valid and raise AccessError if not
    curr_id = database.get_current_user(token)

    # check if user is a member of channel with channel_ID and return AccessError if not
    user_channel = is_user_channel_member(channel_id, curr_id)
    if user_channel is False:
        raise error.AccessError(description="user is not a member of this channel")

    # remove user with u_id from the channel (from member_ids)
    curr_channel = database.get_channel_data(channel_id)

    curr_channel["member_ids"].remove(curr_id)
    # if user is an owner it removes them as an owner as well
    for owner_id in curr_channel["owner_ids"]:
        if owner_id == curr_id:
            curr_channel["owner_ids"].remove(curr_id)

    database.set_channel_data(curr_channel)
Example #19
0
def channel_messages(token, channel_id, start):
    """
    Retrieve a set of 50 or less messages from the channel.
    Returns a {messages, start, end} dictionary.
    """
    # Check if token is valid and raise AccessError if not
    curr_id = database.get_current_user(token)

    # check if user is a member of channel with channel_ID and return AccessError if not
    if is_user_channel_member(channel_id, curr_id) is False:
        raise error.AccessError(description="user is not a member of this channel")

    #get channel data
    curr_channel = database.get_channel_data(channel_id)
    # find the length of messages
    messages_length = len(curr_channel["messages"])

    # if start is after the oldest message in messages InputError is raised
    # if messages is called and start is 0 on an empty channel, it returns an empty channel.
    # if start is after the oldest message in messages InputError is raised

    if messages_length <= start and (messages_length != 0 or start > 0):
        raise error.InputError(description="""The start value selected is
                               past the oldest message in the list""")

    if messages_length == 0 and start == 0:
        return {"messages": [], "start": start, "end": -1}

    # get the list of dictionaries 'message'
    curr_messages = curr_channel["messages"]
    messages_returned = []

    end = start + 50
    num_msgs_to_check = messages_length - start

    # If end is larger than the total no. of messages,
    # the function will print till end and return -1
    if num_msgs_to_check < 50:

        counter = 0
        while counter < num_msgs_to_check:
            target_message_index = start + counter
            messages_returned.append(curr_messages[target_message_index])
            counter += 1

        end = -1
    # else if end is within total no of messages,
    # function will print 50 messaages from start and return start + 50
    else:
        # loop to add each message to return up till 50 messages is returned
        counter = 0
        while counter < 50:
            target_message_index = start + counter
            messages_returned.append(curr_messages[target_message_index])
            counter += 1

    for msg in messages_returned:
        for react in msg['reacts']:
            react['is_this_user_reacted'] = curr_id in react['u_ids']

    return {"messages": messages_returned, "start": start, "end": end}