def admin_userpermission_change(token, u_id, permission_id):
    fl = 1
    u_id = int(u_id)
    permission_id = int(permission_id)
    data = load()
    userDict = data['userDict']
    for user in userDict:
        if u_id == user['u_id']:
            fl = 0
    if fl == 1:
        raise ValueError('Wrong user id')
    if permission_id not in range(1, 4):
        raise ValueError('Unmatch permission id')

    opid = getUserFromToken(token)
    for user in userDict:
        if user['u_id'] == opid:
            if user['permission_id'] == 2 and permission_id == 1:
                raise AccessError(
                    'Permission Denied: Trying to give owner by admin')
            if user['permission_id'] == 3:
                raise AccessError('Permission Denied : member can not do this')
    for sb in userDict:
        if sb['u_id'] == u_id:
            if sb['permission_id'] == 1:
                raise AccessError(
                    'Permission Denied: Trying to change owner permission')
            sb['permission_id'] = permission_id
    data['userDict'] = userDict
    save(data)
    pass
Exemple #2
0
def channel_addowner(token, channel_id, u_id):
    DATA = load()
    channelDict = DATA['channelDict']
    if channel_id_check(channel_id) == False:
        raise ValueError("channel_id is invalid")
    # already an owner
    getUserFromToken(token)
    u_id = int(u_id)
    channel_id = int(channel_id)
    for parts in channelDict:
        if parts['channel_id'] == channel_id and u_id in parts['channel_owner']:
            raise ValueError("user is already an owner in the channel")
    if not if_User_Owner(token, channel_id):
        raise AccessError(
            "the authorised user is not an owner of the slackr, or an owner of this channel"
        )
    if u_id not in channelDict[channel_id - 1]['channel_member']:
        raise AccessError("the user is not a member of this channel")
    for parts in channelDict:
        if parts['channel_id'] == channel_id:
            parts['channel_owner'].append(u_id)
            parts['channel_member'].remove(u_id)
    DATA['channelDict'] = channelDict
    save(DATA)
    return {}
Exemple #3
0
def standup_send(token, channel_id, message):
    channel_id = int(channel_id)
    data = load()
    channelDict = data['channelDict']
    userDict = data['userDict']

    opid = getUserFromToken(token)
    for user in userDict:
        if int(user['u_id']) == int(opid):
            name = user['first_name']
            break
    if len(message) > 1000:
        raise ValueError("Message too long")
    for ch in channelDict:
        if int(channel_id) == int(ch['channel_id']):
            if opid not in ch['channel_member'] and opid not in ch[
                    'channel_owner']:
                raise AccessError('You are not a member of this channel')
            if ch['standUp'] != True:
                raise ValueError(
                    'An active standup is not currently running in this channel'
                )
            append = str(name) + ': ' + str(message)
            if not ch['standlist']:
                ch['standlist'] = append
                data['channelDict'] = channelDict
                save(data)
                return {}
            else:
                ch['standlist'] += '\r\n' + append
                data['channelDict'] = channelDict
                save(data)
                return {}
    raise ValueError('Channel ID is not a valid channel')
def message_send(token, channel_id, message):
    u_id = getUserFromToken(token)
    DATA = load()
    messDict = DATA['messDict']
    channelDict = DATA['channelDict']
    if len(message) > 1000:
        raise ValueError("Message is more than 1000 characters")

    for cha in channelDict:
        if cha['channel_id'] == channel_id:
            if u_id not in cha['channel_owner'] and u_id not in cha[
                    'channel_member']:
                raise AccessError(
                    "The authorised user has not joined the channel they are trying to post to"
                )
    DATA['messID'] += 1
    mess = {
        'channel_id': int(channel_id),
        'message_id': int(DATA['messID']),
        'u_id': int(u_id),
        'message': message,
        'time_created': int(datetime.now().timestamp()),
        'reacts': [{
            'react_id': None,
            'u_ids': [],
            'is_this_user_reacted': False
        }],
        'is_pinned': False
    }

    mess_id = int(mess['message_id'])
    messDict.append(mess)
    DATA['messDict'] = messDict
    save(DATA)
    return int(mess_id)
Exemple #5
0
def channel_join(token, channel_id):
    DATA = load()
    channelDict = DATA['channelDict']
    if channel_id_check(channel_id) == False:
        raise ValueError("channel_id is invalid")
    id = getUserFromToken(token)
    id = int(id)
    # private channel
    if channel_property_check(channel_id) == False:
        if channel_admin_check(token) == False:
            raise AccessError(
                "authorised user is not an admin when channel is private")
        else:
            for parts in channelDict:
                if parts['channel_id'] == int(channel_id):
                    parts['channel_owner'].append(id)
    # public channel
    else:
        for parts in channelDict:
            if parts['channel_id'] == int(channel_id):
                if channel_admin_check(token) == False:
                    if parts['channel_member'] == []:
                        parts['channel_member'] = [id]
                    else:
                        parts['channel_member'].append(id)
                else:
                    parts['channel_owner'].append(id)
    DATA['channelDict'] = channelDict
    save(DATA)
Exemple #6
0
def start_standup(token, channel_id, length):
    '''
    Start a standup
    Length is in seconds
    '''
    data = get_data()
    channel = get_channel(data, channel_id)
    user = get_user_from_token(data, token)
    # If the channel is Invalid
    if channel == None:
        raise ValueError(description='Invalid Channel')
    # If the channel is alreay in stadup mode
    if is_standup_active(channel):
        raise ValueError(description='Standup is already active')
    # If the user is not in this channel
    if not user_in_channel(user['u_id'], channel):
        raise AccessError(description='User is not in channel')
    # Else start a start up session
    channel['standup_active'] = True

    # setup the timer for with the length specified
    timer = threading.Timer(length, stop_standup, [token, channel_id])
    time_finish = (datetime.now() + timedelta(seconds=length)).timestamp()
    channel['standup_finish'] = time_finish

    pickle_data(data)
    timer.start()
    return {'time_finish': time_finish}
Exemple #7
0
def get_messages(token, channel_id, start):
    '''
    given a token, channel_id and the start, show all th emessages in channel with
    channel_id after the start as long as the user with token is part of the channel
    '''
    data = get_data()
    user = get_user_from_token(data, token)
    channel = get_channel(data, channel_id)

    if channel is None:
        raise ValueError('Channel does not exist')

    num_messages = len(channel['message_ids'])
    if start > num_messages:
        raise ValueError('Start is greater than the total number of messages')
    if not user_in_channel(user['u_id'], channel):
        raise AccessError('User is not in channel')
    end = start + 50
    if end > num_messages:
        end = -1
        messages = return_messages(data, channel['message_ids'][start:], token)
    else:
        messages = return_messages(data, channel['message_ids'][start:end],
                                   token)
    return {'messages': messages, 'start': start, 'end': end}
Exemple #8
0
def channel_addowner(token, channel_id, u_id):
    '''
    make an user an owner of the channel
    '''

    channel = get_channel_by_channel_id(channel_id)

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

    # user is already an owner of the channel
    if channel.is_owner(u_id):
        raise ValueError("User is already an owner of the channel")

    # User does not have permission to add owner
    if not channel.is_owner(decode_token(token)) and \
            not token_is_admin(token) and \
            not token_is_owner(token):
        raise AccessError("User is not an owner of the channel or slackrowner")

    # User is added as owner
    channel.add_owner(u_id)

    return {}
def message_edit(token, message_id, message):
    '''
    Given a message, update it's text with new text. If the new message is an
    empty string, the message is deleted.
    '''

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

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

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

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

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

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

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

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

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

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

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

    # Unpinning message
    message_obj.unpin_message()

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

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

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

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

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

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

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

    return {
        "message_id": message_object.id
    }
def message_unreact(token, message_id, react_id):
    '''
    Given a message within a channel the authorised user is part of, remove a
    "react" to that particular message
    '''

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

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

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

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

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

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

    return {}
def message_pin(token, message_id):
    '''
    Given a message within a channel, mark it as "pinned" to be given special
    display treatment by the frontend
    '''

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

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

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

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

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

    # Pin message
    message_obj.pin_message()

    return {}
def message_pin(token, message_id):
    u_id = getUserFromToken(token)
    u_id = int(u_id)
    message_id = int(message_id)
    DATA = load()
    messDict = DATA['messDict']

    found = False
    for mess in messDict:
        if mess['message_id'] == message_id:
            if mess['is_pinned']:
                raise ValueError('already pinned')
            channelID = mess['channel_id']
            message = mess
            found = True
            break
    if not found:
        raise ValueError("Invalid message_id")
    if not if_User_Owner(token, channelID):
        raise ValueError('The authorised user is not an admin')

    if not is_in_channel(u_id, channelID):
        raise AccessError(
            'message_id is not a valid message within a channel that the authorised user has joined'
        )
    message['is_pinned'] = True
    DATA['messDict'] = messDict
    save(DATA)

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

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

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

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

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

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

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

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

    return {
        "message_id": message_object.id
    }
Exemple #16
0
def send_message(token, channel_id, message_str):
    """
    Send a message to the channel associated with channel_id
    """
    data = get_data()
    channel = get_channel(data, channel_id)
    user = get_user_from_token(data, token)
    message_id = get_next_message_id(data)

    if not valid_message_len(message_str):
        raise ValueError("Message too long")
    if not user_in_channel(user['u_id'], channel):
        raise AccessError("User is not in channel")

    # get the current time in utc
    now = datetime.utcnow().replace(tzinfo=timezone.utc).timestamp()
    # set up the information to save in the 'database'
    message_info = generate_message_info(channel_id, message_id, user['u_id'],
                                         message_str, now)

    # insert the message into the front of the message ids
    # stored in the channel
    channel['message_ids'].insert(0, message_id)
    # add the message object to the messages list
    data['messages'].append(message_info)
    pickle_data(data)
    return {'message_id': message_id}
Exemple #17
0
def channels_messages(token, channel_id, start):
    u_id = getUserFromToken(token)
    u_id = int(u_id)
    DATA = load()
    messDict = DATA['messDict']
    start = int(start)
    if channel_id_check(channel_id) == False:
        raise ValueError("channel_id is invalid")
    if auth_id_check(token, channel_id) == False:
        raise AccessError("Auth user is not a member of channnel")
    dic = {'messages': [], 'start': start, 'end': None}
    lis = []
    for parts in messDict:
        if int(parts['channel_id']) == int(channel_id):
            lis.append(int(parts['message_id']))
    if len(lis) != 1:
        lis = lis[::-1]
    lis = get_messages(u_id, lis)
    if len(lis) < int(start):
        raise ValueError(
            "start is greater than the total number of messages in the channel"
        )

    if int(start) + 50 >= len(lis):
        for parts in lis[int(start):len(lis)]:
            dic['messages'].append(parts)
        dic['end'] = -1
    else:
        for parts in lis[int(start):int(start) + 50]:
            dic['messages'].append(parts)
        dic['end'] = start + 50
    return dic
Exemple #18
0
def standup_start(token, channel_id, length):
    '''
    For a given channel, start the standup period whereby for the next "length"
    seconds if someone calls "standup_send" with a message, it is buffered
    during the X second window then at the end of the X second window a message
    will be added to the message queue in the channel from the user who started
    the standup. X is an integer that denotes the number of seconds that the
    standup occurs for
    '''

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

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

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

    return {"time_finish" : time.timestamp()}
Exemple #19
0
def channel_messages(token, channel_id, start):
    '''
    Returns up to 50 messages between index "start" and "start + 50".
    Message with 0 index is the most recent message

    end = start + 50

    If function has returned the least recent messages in the channel
    returns -1 in "end" to indicate there are no more msgs to load

    '''

    channel = get_channel_by_channel_id(channel_id)
    u_id = decode_token(token)

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

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

    # If the start is greater than the number of messages in the channel given
    if start > len(channel.messages):
        raise ValueError("Start index is invalid")

    messages = []

    for i in range(MAX_MESSAGES):
        # End index of -1 to indicate there are no more messages to load
        if start + i >= len(channel.messages):
            return {"messages": messages, "start": start, "end": -1}

        # Gets message object
        message = channel.messages[start + i]

        # Add information regarding if user has reacted to this message
        reacts = message.reacts
        for react in reacts:
            react["is_this_user_reacted"] = \
                message.user_has_reacted(u_id, react['react_id'])

        # Append message dictionary into messages list
        messages.append({
            "message_id": message.id,
            "u_id": message.sender,
            "message": message.message,
            "time_created": message.time_created,
            "reacts": reacts,
            "is_pinned": message.is_pinned,
        })

    # Check which
    if start + MAX_MESSAGES >= len(channel.messages):
        end = -1
    else:
        end = start + MAX_MESSAGES
    return {"messages": messages, "start": start, "end": end}
def getUserFromToken(token):
    global SECRET
    try:
        decoded = jwt.decode(token[2:len(token) - 1],
                             SECRET,
                             algorithms=['HS256'])
        u_id = decoded['u_id']
        return u_id
    except:
        raise AccessError('Invalid token')
Exemple #21
0
def channel_invite(token, channel_id, u_id):
    if channel_id_check(int(channel_id)) == False:
        raise ValueError("channel_id is invalid")
    if u_id_check(u_id) == False:
        raise ValueError("u_id does not refer to a valid user")
    if auth_id_check(token, channel_id) == False:
        raise AccessError("Auth user is not a member of channel")
    if is_in_channel(u_id, channel_id):
        raise AccessError('The user you are inviting is already in this channel.')
    DATA = load()
    channelDict = DATA['channelDict']
    for parts in channelDict:
        if int(parts['channel_id']) == int(channel_id):
            # the user invite by owner is also a owner
            if if_slackr_owner(token) == True:
                parts['channel_owner'].append(int(u_id))
            else:
                parts['channel_member'].append(int(u_id))
    DATA['channelDict'] = channelDict
    save(DATA)
    return {}
Exemple #22
0
def channel_details(token, channel_id):
    DATA = load()
    channelDict = DATA['channelDict']
    if channel_id_check(channel_id) == False:
        raise ValueError("channel_id is invalid")
    if not auth_id_check(token, channel_id):
        raise AccessError("Auth user is not a member of channel")
    detail = {}
    for parts in channelDict:
        if int(parts['channel_id']) == int(channel_id):
            all_members = list(parts['channel_member']) + list(parts['channel_owner'])
            detail['name'] = parts['name']
            detail['all_members'] = list(get_members(all_members))
            detail['owner_members'] = list(get_members(list(parts['channel_owner'])))
    return dict(detail)
Exemple #23
0
def join_channel(token, channel_id):
    '''
    given a user's token and a channel_id, the user can join the channel as long as the channel
    is private or the user has permissions such as being an admin or owner of slackr
    '''
    data = get_data()
    user = get_user_from_token(data, token)
    channel = get_channel(data, channel_id)
    #print(user_in_channel(user['email'], channel))
    if channel is None or user_in_channel(user['u_id'], channel):
        raise ValueError('invalid channel id')
    if user['perm_id'] == MEMBER_ID and not channel['is_public']:
        raise AccessError('User is not an admin or owner of slackr')
    user_info = generate_user_info(user)
    channel['members'].append(user_info)
    pickle_data(data)
    return {}
Exemple #24
0
def details_channel(token, channel_id):
    '''
    given a token of a user and a channel_id, show the owners and members of the channel
    with channel_id as long as the user is a member of the channel
    '''
    data = get_data()
    user = get_user_from_token(data, token)
    channel = get_channel(data, channel_id)
    if channel is None:
        raise ValueError('invalid channel id')
    if not user_in_channel(user['u_id'], channel):
        raise AccessError('user not part of channel')

    pickle_data(data)
    return {
        'name': channel['name'],
        'owner_members': get_members(channel['owners']),
        'all_members': get_members(channel['members'])
    }
Exemple #25
0
def edit_message(token, message_id, message_str):
    """
    Edit message with message_id with new message
    If message is empty, delete the message
    """
    if len(message_str) == 0:
        return remove_message(token, message_id)
    data = get_data()
    og_message = get_msg_from_msg_id(data, message_id)
    user = get_user_from_token(data, token)
    channel = get_channel(data, og_message['channel_id'])
    # check if user did not send original message and user is admin/owner
    if (not user_sent_message(user['u_id'], og_message)
            and not user_is_admin_or_owner(user, channel)):
        raise AccessError("User did not send message or not enough privileges")
    # edit the original message with the new message
    og_message['message'] = message_str
    pickle_data(data)
    return {}
def message_remove(token, message_id):
    DATA = load()
    messDict = DATA['messDict']
    found = False

    for mess in messDict:
        if mess['message_id'] == int(message_id):
            channelID = int(mess['channel_id'])
            message = mess
            found = True
            break
    if not found:
        raise ValueError("Message (based on ID) no longer exists")
    if not is_owner(token, channelID) and not is_sender(token, message_id):
        raise AccessError('Unauthorised remove !')
    messDict.remove(message)
    DATA['messDict'] = messDict
    save(DATA)

    return {}
Exemple #27
0
def remove_message(token, message_id):
    """
    Remove message with message_id from channel
    """
    data = get_data()
    user = get_user_from_token(data, token)
    message = get_msg_from_msg_id(data, message_id)
    if message is None:
        raise ValueError('Message no longer exists')

    channel = get_channel(data, message['channel_id'])
    if not user_sent_message(user['u_id'],
                             message) and not user_is_admin_or_owner(
                                 user, channel):
        raise AccessError("User did not send message or not enough privileges")

    # remove the message object and the message_id from the 'database'
    data['messages'].remove(message)
    channel['message_ids'].remove(message_id)
    pickle_data(data)
    return {}
Exemple #28
0
def standup_send(token, channel_id, message):
    '''
    Sending a message to get buffered in the standup queue, assuming a standup
    is currently active
    '''

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

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

    channel.add_standup_message(token, message)

    return {}
Exemple #29
0
def admin_userpermission_change(token, u_id, permission_id):
    '''
    Given a User by their user ID, set their permissions to new permissions
    described by permission_id
    '''

    # Getting user object
    user = get_user_by_u_id(u_id)

    # Checking validity of permission change request
    if not user:
        raise ValueError('Invalid User ID')
    if not valid_permission_id(permission_id):
        raise ValueError('Permission ID is invalid')
    if not (token_is_admin(token) or token_is_owner(token)):
        raise AccessError('Current user is not an admin or owner')

    # Changing user's permission
    user.change_permissions(permission_id)

    return {}
Exemple #30
0
def unpin_message(token, message_id):
    """
    Unpin message with message_id
    """
    data = get_data()
    user = get_user_from_token(data, token)
    message = get_msg_from_msg_id(data, message_id)
    if message is None:
        raise ValueError("Invalid message_id")
    channel = get_channel(data, message['channel_id'])
    if not perm_id_is_admin_owner(user['perm_id']):
        raise ValueError("User is not an admin or owner")
    if not message['is_pinned']:
        raise ValueError("Message is not pinned")
    if not user_in_channel(user['u_id'], channel):
        raise AccessError(
            "User not part of channel that the message is within")

    # set the pin flag on the message to False
    message['is_pinned'] = False
    pickle_data(data)
    return {}