def channel_removeowner(token, channel_id, u_id): """ Function that removes target user as owner. Global owner cannot be removed except for by another global owner. Parameters: token (str): A unique token to determine authorisation channel_id (int): A unique identifier of channels u_id (int): A unique identidier to indicate the target of this function Returns: {} """ # Check that token is valid caller_id = authenticate_token(token) caller = valid_user_id(caller_id) target = valid_user_id(u_id) # Check that channel_id is valid channel = valid_channel_id(channel_id) # Check that caller is a member if not channel.existing_member(caller): raise AccessError(description="Caller not in channel") # Check that access is from an owner and targeted at an owner if caller.u_id not in [ user['u_id'] for user in channel.channel_details()['owner_members'] ]: raise AccessError(description="Caller is not an owner") if target.u_id not in [ user['u_id'] for user in channel.channel_details()['owner_members'] ]: raise InputError(description="Target is not an owner") # Only a global owner can remove a global owner if caller.permission_id != 1 and target.permission_id == 1: raise AccessError('Need global permissions to remove global owner') # If reached, here then successful channel.remove_owner(target) return {}
def user_profile(token, u_id): """ Function that returns the profile of the user with the given u_id as a dictionary. Parameters: token (str): Used to validate the users login session Return: { user: { u_id (int): Unique identification number of target email (str): email address of target name_first (str): first name of target name_last (str): last name of target handle_str (str): Not sure what this is used for }, } """ valid_user_id(u_id) authenticate_token(token) return {'user': data.users[u_id].user_details()}
def message_send(token, channel_id, message_in): """ Sends a message from an authenticated user to a valid channel the user is in Generates a message_id and returns it. Parameters: token (str): Used to authenticate and identify the user channel_id (int): the unique id of a channel in the system message (str): the message which will be sent in the channel Return: message_id (int): the unique id of a message in the system """ # Check message length, raise InputError if characters in message: # -> length of characters > 1000 # -> length of characters == 0 (empty message) if len(message_in) > 1000 or len(message_in) == 0: raise InputError(description='Invalid message length') # Check if token and channel_id exists in data user_id = authenticate_token(token) user = valid_user_id(user_id) channel = valid_channel_id(channel_id) # Check if user is in the channel, raise AccessError if user is not in channel if not channel.existing_member(user): raise AccessError("User not in desired channel") # Check if message is related to hangman and edit it accordingly if it is msg_check = message_in.split() is_guess = False if msg_check[0] == "/guess" and channel.hangman.get_details()['mode']: if len(msg_check) == 2: message_in = msg_check[1] is_guess = True if message_in == "/hangman start" or is_guess: message_in = hangman(message_in, channel) message_id = data.message_index data.message_index += 1 message_object = message(message_in, user_id, message_id) channel.new_message(message_object) return {'message_id': message_object.message_id}
def message_sendlater(token, channel_id, message, time_sent): """ Sends a message from an authenticated user to a valid channel the user is in Generates a message_id and returns it at the specified time_sent in the future. Parameters: token (str): Used to authenticate and identify the user channel_id (int): the unique id of a channel in the system message (str): the message which will be sent in the channel time_sent (int): unix integer timestamp for a given time (consist of year, month, day and time) Return: message_id (int): the unique id of a message in the system """ # Check message length, raise InputError if characters in message is invalid if len(message) > 1000 or len(message) == 0: raise InputError(description='Invalid message length') # Check if token is valid and channel_id exists in data user_id = authenticate_token(token) channel = valid_channel_id(channel_id) user = valid_user_id(user_id) # Check if the time_sent is not a time in the past cur_time = int(time.time()) if time_sent < cur_time: raise InputError(description='Time sent is a time in the past') # Check if user is in the channel, raise AccessError if user is not in channel if not channel.existing_member(user): raise AccessError("User not in desired channel") # Generate message id and increment the counter in the data # Message_id is generated when message_sendlater is called msg_id = data.message_index data.message_index += 1 # Send the message according to the desired time timer = time_sent - cur_time send_after = threading.Timer( timer, send_msg, [msg_id, user_id, message, channel, time_sent]) send_after.start() # Return the generated message_id return {'message_id': msg_id}
def standup_start(token, channel_id, length): """ Starts the timer that calls timed_send when it finishes Parameters: token (str): Check that the user is validated to call. channel_id (int): Specifies which channel the standup is to be in. length (int): Specifies the duration of the standup ( > 0). Returns: { time_finish (UNIX timestamp): When will timed_send be called? } """ u_id = authenticate_token(token) user = valid_user_id(u_id) # Check valid channel and user belongs to channel channel = valid_channel_id(channel_id) if not channel.existing_member(user): raise AccessError('User is not in the target channel') # Check that the object is not currently running if standup_active(token, channel_id)['is_active']: raise InputError(description="Standup already in progress") # Check length is positive if length <= 0: raise InputError("Duration must be positive") # Start the timer if reached here timer = threading.Timer(length, timed_send, [token, channel_id]) timer.start() current_time = int(time.time()) added = current_time + length channel.standup_end = added return {'time_finish': channel.standup_end}
def message_react(token, message_id, react_id): """ Given a valid user appointed with the token, react to an existing message under the user's u_id. If the given message does not have any of the react yet, it will create append a new dictionary for the react_id. Parameters: token (str): Used to authenticate and identify the user message_id (int): the unique id of a message in the system react_id (int): the unique id of a 'react' that will be reacted to Return: {} """ # Check if token is valid user_id = authenticate_token(token) user = valid_user_id(user_id) # Check if message exists in the data msg_check = check_message_valid(message_id) ch_index = msg_check['ch_index'] msg_index = msg_check['msg_index'] channel = valid_channel_id(ch_index) # Check if user is a member of the channel where the message was posted if not channel.existing_member(user): raise InputError(description="User is not in desired channel") # Check if the given react_id is a valid react_id, function will raise InputError if it is invalid check_valid_react_id(react_id) # Find the current user_id in the reacts u_id list cur_msg = data.channels[ch_index].channel_messages[msg_index] is_already_reacted = False for react in cur_msg.reacts: if react['react_id'] == react_id and user_id in react['u_ids']: is_already_reacted = True # Check if the current message has not been reacted by the user previously if is_already_reacted is True: raise InputError( description="Message has already been reacted by the user") # Get the index of the react_id in the list of reacts react_index = find_react_id_index(cur_msg.reacts, react_id) # react_id has yet to exist in the message, create a new react dictionary # with the current user data to append to the reacts list if react_index == -1: new_react_dict = {} new_react_dict['react_id'] = react_id new_react_dict['u_ids'] = [user_id] new_react_dict['is_this_user_reacted'] = False cur_msg.reacts.append(new_react_dict) else: # Add react data on the current dictionary cur_react_dict = cur_msg.reacts[react_index] # Append the current user_id into the u_ids list cur_react_dict['u_ids'].append(user_id) # Updates the is_this_user_reacted value if the current user who reacted is the # same user who sent the message if user_id == cur_msg.u_id: cur_msg.reacts[react_index]['is_this_user_reacted'] = True return {}
def test_valid_user_id_valid_user(): clear() user1 = auth_register('*****@*****.**', 'password', 'Test', 'Test') result = valid_user_id(user1['u_id']) assert result.name_first == "Test"