def search(token, query_str): """ Given a query string, return a collection of messages in all of the channels that the user has joined that match that query. :param token: The token of an authorised Flockr user :type token: str :param u_id: The user ID of the user whose permissions we want to change :type u_id: int :return: A dictionary with nested list of messages containing the query string :rtype: dict with nested list """ # check token validity if get_user_from_token(token) is None: raise AccessError(description="Unauthorised access") result = [] user = get_user_from_token(token) # search for messages with query string for channel_id in user['channels']: channel = get_channel_from_id(channel_id) for message in channel['messages']: if query_str in message['message']: if user['u_id'] in message['reacts'][0]['u_ids']: message['reacts'][0]['is_this_user_reacted'] = True else: message['reacts'][0]['is_this_user_reacted'] = False result.append(message) return {'messages': result}
def channel_join(token, channel_id): ''' User joins a channel. Parameters: token - channel_id - Returns: {} Errors: InputError: Invalid channel id. AccessError: Channel is private. ''' check_token(token) data = get_data() if not find_id_in_list(data['channels'], channel_id, 'channel_id'): # Channel ID is not a valid channel raise InputError(description='Channel does not exist') current_channel = data['channels'][channel_id - 1] target_u_id = get_user_from_token(token) target = get_user_data(target_u_id) if not current_channel['is_public'] and target['permission_id'] != 1: raise AccessError(description='Private channel') user_info = { 'u_id': target['u_id'], 'name_first': target['name_first'], 'name_last': target['name_last'], } data['channels'][channel_id - 1]['all_members'].append(user_info) return {}
def channel_leave(token, channel_id): ''' User leaves a channel. Parameters: token - channel_id - Returns: {} Errors: InputError: Invalid channel id. AccessError: User is not inside channel. ''' check_token(token) data = get_data() if not find_id_in_list(data['channels'], channel_id, 'channel_id'): raise InputError(description='Channel does not exist') current_channel = data['channels'][channel_id - 1] target_u_id = get_user_from_token(token) if find_id_in_list(current_channel['all_members'], target_u_id, 'u_id'): target = get_user_data(target_u_id) user_info = { 'u_id': target['u_id'], 'name_first': target['name_first'], 'name_last': target['name_last'], } data['channels'][channel_id - 1]['all_members'].remove(user_info) return {} # the authorised user is not a member of channel with channel_id raise AccessError( description='The authorised user is not a member of this channel')
def users_all(token): """ Returns a list of all users and their associated details. :param token: The token of any authorised user :type token: str :return: A dictionary containing a list of all users and their associated details :rtype: dict with nested list """ # check token validity if get_user_from_token(token) is None: raise AccessError(description="Unauthorised access") all_users = [] for user in users: user_details = {} user_details['u_id'] = user['u_id'] user_details['email'] = user['email'] user_details['name_first'] = user['name_first'] user_details['name_last'] = user['name_last'] user_details['handle_str'] = user['handle'] user_details['profile_img_url'] = user['profile_img_url'] all_users.append(user_details) return { 'users': all_users, }
def user_profile_setemail(token, email): ''' This function is for updating the authorised user's email. Args: param1: authorised user's token param2: new email Returns: it will return an empty dictionary Raises: InputError: 1. Email entered is not a valid email 2. Email address is already being used by another user AccessError: given token does not refer to a valid user ''' request_user = get_user_from_token(token) # raise AccessError when given token does not refer to a valid user if request_user is None: raise AccessError(description='Invalid token') # raise InputError when new email is invalid if is_email_valid(email) is False: raise InputError(description='Invalid email') # raise InputError when new email has been occupied for user in users: if user['email'] == email: raise InputError(description='Email already in use') request_user['email'] = email return {}
def user_remove(): '''admin removes a user from slackr''' data = get_data() payload = request.get_json() token = payload['token'] u_id = int(payload['u_id']) check_token(token) user_data = get_user_data(u_id) if user_data == {}: raise InputError(description='No such user exists') person_u_id = get_user_from_token(token) person_data = get_user_data(person_u_id) if person_data['permission_id'] != 1: raise AccessError(description='The authorised person is not an owner of slackr') user_info = { 'u_id': u_id, 'name_first': user_data['name_first'], 'name_last': user_data['name_last'], } for channel in data['channels']: if user_info in channel['owner_members']: curr_channel_id = channel['channel_id'] data['channels'][curr_channel_id - 1]['owner_members'].remove(user_info) data['channels'][curr_channel_id - 1]['all_members'].remove(user_info) elif user_info in channel['all_members']: curr_channel_id = channel['channel_id'] data['channels'][curr_channel_id - 1]['all_members'].remove(user_info) dumps({})
def auth_logout(token): ''' This will invalidate user with given token to log the user out. This will return a dictionary with success information if success, else raise errors. Args: param1: token Returns: This will return a dictionary. { 'is_success' : (boolean) } Raises: AccessError: token does not refer to a valid token ''' auth_user = get_user_from_token(token) # access error when given token does not refer to a exsiting user exist = False for user in users: if user['token'] == token: exist = True if exist is False: raise AccessError(description='Invalid token.') # return false if auth_user's status is logout if auth_user is None: return {'is_success': False} # return true and update token if logout success auth_user['token'] = token_generate(auth_user['u_id'], 'logout') return {'is_success': True}
def user_profile_setemail(token, email): ''' Update the authorised user's email address Parameters: token - The user's token that was generated from their user id email - The email the user wants to change to Returns: An empty dictionary Errors: InputError: The email is an invalid email The email has already been taken by another user ''' check_token(token) data = get_data() # Checking if the email is valid if not check(email): raise InputError(description="Invalid email") # Checking if email is taken for user in data['users']: if user['email'] == email: raise InputError(description="Email is already taken") # Setting the email u_id = get_user_from_token(token) for user in data['users']: if user['u_id'] == u_id: user['email'] = email return { }
def user_profile_sethandle(token, handle_str): ''' This function is for updating the authorised user's handle. Args: param1: authorised user's token param2: new handle Returns: it will return an empty dictionary Raises: InputError: 1. handle_str in not between 3 and 20 characters inclusive 2. handle is already used by another user AccessError: given token does not refer to a valid user ''' request_user = get_user_from_token(token) # raise AccessError when given token does not refer to a valid user if request_user is None: raise AccessError(description='Invalid token') # raise InputError if the length of handle is not valid if len(handle_str) > 20 or len(handle_str) < 3: raise InputError(description='Invalid length of handle') # raise InputError if new handle has been occupied by someone for user in users: if user['handle'] == handle_str: raise InputError(description='Handle already in use') request_user['handle'] = handle_str return {}
def user_profile_setname(token, name_first, name_last): ''' Update the authorised user's first and last name Parameters: token - The user's token that was generated from their user id handle_str - The handle the user wants to change to Returns: An empty dictionary Errors: InputError: Either name is greater than 50 characters Either name is less than 1 characters ''' check_token(token) data = get_data() # Checking if the name is too long or short if len(name_first) > 50 or len(name_last) > 50: raise InputError(description="Name is too long. Maximum characer length 50.") if len(name_first) < 1 or len(name_last) < 1: raise InputError(description="Name is too short. Minimum character length 1.") # Setting the name u_id = get_user_from_token(token) for user in data['users']: if user['u_id'] == u_id: user['name_first'] = name_first user['name_last'] = name_last return { }
def user_profile_setname(token, name_first, name_last): ''' This function is for updating the authorised user's first and last name. Args: param1: authorised user's token param2: new first name param3: new last name Returns: it will return an empty dictionary Raises: InputError: 1. name_first is not between 1 and 50 characters inclusively in length 2. name_last is not between 1 and 50 characters inclusively in length AccessError: given token does not refer to a valid user ''' request_user = get_user_from_token(token) # raise AccessError when given token does not refer to a valid user if request_user is None: raise AccessError(description='Invalid token') if len(name_first) == 0 or len(name_last) == 0: raise InputError(description='Name cannot be empty') if len(name_first) > 50 or len(name_last) > 50: raise InputError(description='Name too long') request_user['name_first'] = name_first request_user['name_last'] = name_last return {}
def user_profile_sethandle(token, handle_str): ''' Update the authorised user's handle (i.e. display name) Parameters: token - The user's token that was generated from their user id handle_str - The handle the user wants to change to Returns: An empty dictionary Errors: InputError: The handle name is greater than 20 characters The handle name is less than 2 characters ''' check_token(token) data = get_data() # Checking if the handle is too long or short if len(handle_str) > 20: raise InputError(description="Handle is too long. Maximum characer length 20.") if len(handle_str) < 2: raise InputError(description="Handle is too short. Minimum character length 2.") #Check if handle is already taken by another user for user in data['users']: if user['handle_str'] == handle_str: raise InputError(description="Handle is already taken") # Setting the handle u_id = get_user_from_token(token) for user in data['users']: if user['u_id'] == u_id: user['handle_str'] = handle_str return { }
def channels_listall(token): ''' Provide a list of all channels (and their associated details) Parameters: token - The user's token that was generated from their user id Returns: A dictionary containing a list of channels that are public or the user is in Errors: ''' check_token(token) data = get_data() c_list = [] u_id = get_user_from_token(token) # Iterating through the list of channels for channel in data['channels']: # If the user is in the channel append the channel to the list if find_id_in_list(channel['all_members'], u_id, 'u_id') or channel['is_public']: current_channel = { 'channel_id': channel['channel_id'], 'name': channel['name'], } c_list.append(current_channel) return {'channels': c_list}
def message_sendlater(token, channel_id, message, time_sent): ''' Send a message from authorised_user to the channel \ specified by channel_id automatically at a specified time in the future Parameters: token - The user's token that was generated from their user id channel_id - The id of the channel the user wishes to message message - The message the user wishes to send time_sent Returns: A dictionary containing a bool is_sucess Errors: InputError: Channel ID is not a valid channel Message is more than 1000 characters Time sent is a time in the past AccessError: The authorised user has not joined the channel they are trying to post to ''' check_token(token) data = get_data() #check channel exist if not find_id_in_list(data['channels'], channel_id, 'channel_id'): raise InputError(description="Channel does not exist") if len(message) > 1000: raise InputError(description="Message is too long") curr_time = datetime.utcnow() time_stamp = int(time.mktime(curr_time.timetuple())) if time_sent < time_stamp: raise InputError(description="Cannot send messages in the past") curr_channel = data['channels'][int(channel_id) - 1] u_id = get_user_from_token(token) if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id'): raise AccessError("Cannot send messages in channels you're not in") message_id = get_max_msg_id() + 1 new_message = { 'u_id': u_id, 'channel_id': channel_id, 'message_id': message_id, 'message': message, 'time_created': time_sent, 'send_later': True, 'react': [], 'is_pinned': False } curr_time = datetime.utcnow() time_stamp = int(time.mktime(curr_time.timetuple())) timer = threading.Timer(time_sent - time_stamp, data['messages'].insert(0, new_message)) timer.start() return {"message_id": new_message['message_id']}
def message_send_later(token, channel_id, message, time_sent): ''' This function will send a message from an authorised user to the channel specified by channel_id automatically at a specified time in the future. Args: param1(str): authorised uesr's token param2(int): id of target channel param3(str): sent message param4(int): unix_timestamp, a future time Returns: It will return a dict with message_id Raises: InputError if: - Channel_id is invalid - Message is more than 1000 characters - Time sent is a time in the past AccessError if: - when the authorised use hasn't joined the channel - when given token is invalid ''' ## Errors auth_user = get_user_from_token(token) channel = get_channel_from_id(channel_id) # access error when given token does not refer to a valid user if auth_user is None: raise AccessError(description='Invalid token') # input error when given channel_id is invalid if channel is None: raise InputError(description='Invalid channel.') # access error when the authorised use hasn't joined the channel if auth_user['u_id'] not in channel['all_members']: raise AccessError(description='User is not a member of channel.') # input error when message is more than 1000 characters if len(message) > 1000: raise InputError(description='Message exceeds 1000 characters.') ### InputError for time in past countdown = time_sent - int(time.time()) if countdown < 0: raise InputError(description='past time given') ### Initiate timer for message_send function new_msg = create_new_msg(message, channel, auth_user['u_id']) channel['latest_msg_id'] += 1 timer = threading.Timer(countdown, append_msg_to_channel, args=[new_msg, channel]) timer.start() return {'message_id': new_msg['message_id']}
def auth_logout(token): '''This program logs a user out''' check_token(token) data = get_data() u_id = get_user_from_token(token) for user in data['users']: if user['u_id'] == u_id: # Set the specified users login flag to 0 to log them off if user['logged_in'] == 1: user['logged_in'] = 0 return {'is_success': True} return {'is_success': False}
def user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end, server_url): ''' Given a URL of an image on the internet, crops the image within bounds (x_start, y_start) and (x_end, y_end). Position (0,0) is the top left. Args: param1(str): authorised user param2(str): photo path param3-6(int): bounds of photo param6(str): server url Returns: It will return am empty dict Args: InputError: 1. img_url returns an HTTP status other than 200. 2. any of x_start, y_start, x_end, y_end are not within the dimensions of the image at the URL. 3. Image uploaded is not a JPG AccessError: given token does not refer to a valid user ''' ssl._create_default_https_context = ssl._create_unverified_context auth_user = get_user_from_token(token) # access error when given token is invalid if auth_user is None: raise AccessError(description='Invalid token') file_path = './src/static/' file_name = str(auth_user['u_id']) + '.jpg' # input error when given img is not in jpg form if img_url[-4:] != '.jpg': raise InputError(description='Invalid form') # input error when given url is invalid try: urllib.request.urlretrieve(img_url, file_path + file_name) except: raise InputError(description='Invalid url') img_object = Image.open(file_path + file_name) # input error when given bounds are invalid width, height = img_object.size if x_start > width or x_end > width or y_start > height or y_end > height: raise InputError(description='Invalid bounds') if x_start < 0 or x_end < 0 or y_start < 0 or y_end < 0: raise InputError(description='Invalid bounds') # do crop cropped = img_object.crop((x_start, y_start, x_end, y_end)) cropped.save(file_path + file_name) # do store url auth_user['profile_img_url'] = server_url + '/static/' + file_name return {}
def user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end): ''' Given a URL of an image on the internet, crops the image within bounds (x_start, y_start) and (x_end, y_end). Position (0,0) is the top left Parameters: token - The user's token that was generated from their user id img_url - The url containing the image the user wants to upload as their profile picture x_start - The left side of the area the user wishes to crop the photo at the url x_end - The right side of the area the user wishes to crop the photo at the url y_start - The top of the area the user wishes to crop the photo at the url y_end - The bottom of the area the user wishes to crop the photo at the url Returns: An empty dictionary Errors: InputError: The img_url returns a non 200 response The image at the url is not a jpg The start values for the crop are greater then or equal to then end values One of the values given for the crop are outside the bounds of the photo ''' check_token(token) data = get_data() if not os.path.exists('static/images'): os.makedirs('static/images') filename = 'images/' + uuid.uuid4().hex + '.jpg' response = requests.get(img_url) if not response.status_code == 200: raise InputError(description="img_url does not return a 200 status code") urllib.request.urlretrieve(img_url, 'static/' + filename) img = Image.open(BytesIO(response.content)) if img.format != ('JPEG' or 'JPG' or 'jpg' or 'jpeg'): raise InputError(description="Image is not a JPG") width, height = img.size if x_start >= x_end or y_start >= y_end: raise InputError(description="End coordinates must be greater that start coordinates ") if ((x_start or y_start or x_end or y_end) < 0 or (x_start or x_end) > width or (y_start or y_end) > height): raise InputError(description="Crop is not within the bounds of the image") area = (x_start, y_start, x_end, y_end) img = img.crop(area) img.save('static/' + filename) u_id = get_user_from_token(token) img_url = url_for('static', filename=filename, _external=True) for user in data['users']: if user['u_id'] == u_id: user['profile_img_url'] = img_url return { }
def channel_addowner(token, channel_id, u_id): ''' This will set the user with u_id as the owner of target channel. Token refers to one of the owner of target channel. It will return an empty dictionaty. Args: param1: authorised user's token. param2: target channel. param3: new owner's u_id Returns: This will return an empty dictionary. Raises: InputError: 1. Channel ID is not a valid channel 2. When user with user id u_id is already an owner of the channel AccessError: 1. when the authorised user is not an owner of the flockr, or an owner of this channel 2. given token does not refer to a valid token ''' auth_user = get_user_from_token(token) channel = get_channel_from_id(channel_id) invited_user = get_user_from_id(u_id) # access error when the token does not refer to a valid token if auth_user is None: raise AccessError(description='Invalid token') # input error when Channel ID is not a valid channel if channel is None: raise InputError(description='Invalid channel_id') # input error when u_id does not refer to a valid user if invited_user is None: raise InputError(description='Invalid u_id') # input error when When user with user id u_id # is already an owner of the channel if invited_user['u_id'] in channel['owner_members']: raise InputError(description='Already an owner') # access error when the authorised user is not # an owner of the flockr, or an owner of this channel if is_user_an_owner(token, channel_id) is False: raise AccessError(description='Not permitted to add') channel['owner_members'].append(u_id) return {}
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. :param token: The token of any Flockr owner :type token: str :param u_id: The user ID of the user whose permissions we want to change :type u_id: int :param permission_id: The ID of the new permission to be set on the user (1 for owner, 2 for member) :type permission_id: int """ # check u_id validity user = get_user_from_id(u_id) if user is None: raise InputError(description=f"Cannot find user with ID of {u_id}") # check permission_id validity if permission_id not in [1, 2]: raise InputError(description="Invalid permission code") # check token validity if get_user_from_token(token) is None: raise AccessError(description="Unauthorised access") # check if token refers to an owner admin = get_user_from_token(token) if admin['permission_id'] != 1: raise AccessError(description="Members cannot modify permissions") # change permission of u_id user to permission_id user['permission_id'] = permission_id return {}
def message_react(token, message_id, react_id): ''' Given a message within a channel the authorised user is part of, add a "react" to \ that particular message Parameters: token - The user's token that was generated from their user id message_id - The id of the message to be reacted to react_id - What type of reaction is shown Returns: An empty dictionary Errors: InputError: Message_id is not a valid message within a channel that the authorised user has joined React_id is not a valid React ID. The only valid react ID the frontend has is 1 Message with ID message_id already contains an active React with ID react_id \ from the authorised user ''' check_token(token) data = get_data() # The only valid react ID the frontend has is 1 if react_id != 1: raise InputError(description="Invalid React ID") if not find_id_in_list(data['messages'], message_id, 'message_id'): raise InputError( description="Message_id is not a valid message within a \ channel that the authorised user has joined") for message in data['messages']: if message['message_id'] == message_id: msg = message u_id = get_user_from_token(token) channel_id = msg['channel_id'] curr_channel = data['channels'][channel_id - 1] if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id'): raise InputError( description="Message_id is not a valid message within a \ channel that the authorised user has joined") # check if user has already reacted for react in msg['react']: if react['u_id'] == u_id: raise InputError( description="User has already reacted to this message") new_react = {'react_id': react_id, 'u_id': u_id} for message in data['messages']: if message['message_id'] == message_id: message['react'].append(new_react) return {}
def message_send(token, channel_id, message): ''' Send a message from authorised_user to the channel specified by channel_id Parameters: token - The user's token that was generated from their user id channel_id - The id the user wishes to message message - The message the user wishes to send Returns: A dictionary containing a message_id Errors: InputError: Message is more than 1000 characters AccessError: The authorised user has not joined the channel they are trying to post to ''' # Check if user is valid check_token(token) # Check if message is too long if len(message) > 1000: raise InputError(description="Message is too long") data = get_data() u_id = get_user_from_token(token) # Find the channel with channel_id curr_channel = data['channels'][channel_id - 1] # Check if user is in this channel if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id') and u_id != 0: raise AccessError(description="User is not in channel") # Get the time when message is sent curr_time = datetime.utcnow() timestamp = curr_time.replace(tzinfo=timezone.utc).timestamp() # Get message id based on the lastest (max) message id message_id = get_max_msg_id() + 1 new_message = { 'u_id': u_id, 'channel_id': channel_id, 'message_id': message_id, 'message': message, 'time_created': timestamp, 'send_later': False, 'react': [], 'is_pinned': False } # insert new message to the start of list data['messages'].insert(0, new_message) return {'message_id': message_id}
def message_react(token, message_id, react_id): ''' This function will add a 'react' to a given channel of which the authorised user is a part (react would only be 1 for now) Args: param1(str): authorised user's token param2(int): id of target message param3(int): react_id (The only valid react ID the frontend has is 1) Returns: It will return an empty dict Raises: InputError: 1. message_id is not a valid message within a channel that the authorised user has joined 2. react_id is not a valid React ID. The only valid react ID the frontend has is 1 3. Message with ID message_id already contains an active React with ID react_id from the authorised user AccessError: given token is invalid ''' auth_user = get_user_from_token(token) msg_info = get_message_info(message_id) # access error when given token is invalid if auth_user is None: raise AccessError(description='Invalid token') # input error when given message_id is invalid if msg_info is None: raise InputError(description='Invalid message_id') channel = msg_info['channel'] ### InputError: User is not part of channel with the message if auth_user['u_id'] not in channel['all_members']: raise InputError(description='User is not a member of channel.') ### InputError: React ID invalid (not 1) if react_id != 1: raise InputError(description='Invalid react_id') ### InputError: React ID already contained by user if auth_user['u_id'] in msg_info['reacts'][0]['u_ids']: raise InputError(description='user has already reacted') ### react to message msg_info['reacts'][0]['u_ids'].append(auth_user['u_id']) return {}
def standup_send(token, channel_id, message): ''' Sending a message to get buffered in the standup queue, assuming a standup is currently active Parameters: token - The user's token that was generated from their user id channel_id - The id of the channel message - The message being sent Returns: A dictionary containing the time the standup will finish and whether a standup is active Errors: InputError: Channel ID is not a valid channel Message is more than 1000 characters An active standup is not currently running in this channel AccessError: The authorised user is not a member of the channel that the message is within ''' check_token(token) data = get_data() # Check if channel_id is valid if not find_id_in_list(data['channels'], channel_id, 'channel_id'): raise InputError(description="Channel ID is not a valid channel") # Check if the message is too long if len(message) > 1000: raise InputError(description="Message is more than 1000 characters") # Check if a standup is already active if not standup_active(token, channel_id)['is_active']: raise InputError(description="An active standup is not currently running in this channel") # Check if the user is in the channel u_id = get_user_from_token(token) curr_channel = data['channels'][channel_id - 1] if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id'): raise AccessError(description="The authorised user is not a member of the \ channel that the message is within") # Appending the packaged message for user in data['users']: if user['u_id'] == u_id: handle_str = user['handle_str'] data['standup']['buffer'].append(handle_str + ': ' + message) data['standup']['message'] = '\n'.join(data['standup']['buffer']) return { }
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 Args: param1(str): authorised user's token param2(int): id of target message param3(int): react_id (The only valid react ID the frontend has is 0) Returns: It will return an empty dict Raises: InputError: 1. message_id is not a valid message within a channel that the authorised user has joined 2. react_id is not a valid React ID 3. Message with ID message_id does not contain an active React with ID react_id AccessError: given token is invalid ''' auth_user = get_user_from_token(token) msg_info = get_message_info(message_id) # access error when given token is invalid if auth_user is None: raise AccessError(description='Invalid token') # input error when given message_id is invalid if msg_info is None: raise InputError(description='Invalid message_id') channel = msg_info['channel'] ### InputError: User is not part of channel with the message if auth_user['u_id'] not in channel['all_members']: raise InputError(description='User is not a member of channel.') ### InputError: React ID invalid (not 1) if react_id != 1: raise InputError(description='Invalid react_id') ### InputError: React ID not containd by user if auth_user['u_id'] not in msg_info['reacts'][0]['u_ids']: raise InputError(description='user hasnt reacted') ### unreact to message msg_info['reacts'][0]['u_ids'].remove(auth_user['u_id']) return {}
def standup_send(token, channel_id, message): ''' This function is for sending a message to get buffered in the standup queue, assuming a standup is currently active. Args: param1(str): request user's token param2(int): the id of target channel param3(str): sent message Returns: It would return an empty dict Raises: InputError: 1. Channel ID is not a valid channel 2. Message is more than 1000 characters 3. An active standup is not currently running in this channel AccessError: 1. given token is invalid 2. The authorised user is not a member of the channel that the message is within ''' user = get_user_from_token(token) channel = get_channel_from_id(channel_id) # access error when given token is invalid if user is None: raise AccessError(description='Invalid token') # input error when given channel_id is invalid if channel is None: raise InputError(description='Invalid channel_id') # input error when An active standup is not currently running in this channel if standup_active(token, channel_id)['is_active'] is False: raise InputError(description='No active standup') # input error when msg is too long if len(message) > 1000: raise InputError(description='Message is too long') # access error when The authorised user is not a member of # the channel that the message is within if channel_id not in user['channels']: raise AccessError(description='Not a member') channel['standup_msg'] += '\n' + user['handle'] + ': ' + message return {}
def user_profile(token, u_id): ''' This function is for showing user's profile. It will return the information of user's file. Args: param1: authorised user's token param2: authorised user's u_id Returns: a dictionary containing profile { 'user': { 'u_id': 1, 'email': '*****@*****.**', 'name_first': 'Hayden', 'name_last': 'Jacobs', 'handle_str': 'hjacobs', 'profile_img_url' : img_url, }, } Raises: InputError: User with u_id is not a valid user AccessError: given token does not refer to a valid user ''' request_user = get_user_from_token(token) target_user = get_user_from_id(u_id) # raise AccessError when given token does not refer to a valid user if request_user is None: raise AccessError(description='Invalid token') # raise InputError when given u_id is not correct if target_user is None: raise InputError(description='Invalid u_id') return { 'user': { 'u_id': target_user['u_id'], 'email': target_user['email'], 'name_first': target_user['name_first'], 'name_last': target_user['name_last'], 'handle_str': target_user['handle'], 'profile_img_url': target_user['profile_img_url'], }, }
def message_pin(token, message_id): ''' This function marks a message as 'pinned' to be given special viewership on the frontend Args: param1(str): authorised user's token param2(int): id of target msg Returns: it will return an empty dict Raises: InputError: 1. message_id is not a valid message 2. Message with ID message_id is already pinned AccessError: 1. The authorised user is not a member of the channel that the message is within 2. The authorised user is not an owner ''' auth_user = get_user_from_token(token) msg_info = get_message_info(message_id) # access error when given token is invalid if auth_user is None: raise AccessError(description='Invalid token') # input error when given message_id is invalid if msg_info is None: raise InputError(description='Invalid message_id') ### AccessError if user is not a member of the channel that the message is within if auth_user['u_id'] not in msg_info['channel']['all_members']: raise AccessError( description='Not a member of the channel that the message is within' ) ### AccessError if user is not an owner of the channel if is_user_an_owner(token, msg_info['channel_id']) is False: raise AccessError(description='User isnt an owner of the channel') ### InputError if message_id is already pinned if msg_info['is_pinned'] is True: raise InputError(description='Message already pinned') ### Pin message msg_info['message']['is_pinned'] = True return {}
def channel_invite(token, channel_id, u_id): ''' This will invite a user (with user id u_id) to join a channel with channel_id. Once invited the user is added to the channel immediately. Args: param1: invitor's token. param2: target channel. param3: invited user's u_id Returns: This will return an empty dictionary. Raises: InputError: 1. channel_id does not refer to a valid channel. 2. u_id does not refer to a valid user. AccessError: 1. the authorised user is not already a member of the channel. 2. given token does not refer to a valid token ''' auth_user = get_user_from_token(token) invited_user = get_user_from_id(u_id) channel = get_channel_from_id(channel_id) # access error when given token does not refer to a valid user if auth_user is None: raise AccessError(description='Invalid Token') # input error when u_id does not refer to a valid user if invited_user is None: raise InputError(description='Invalid u_id') # input error when channel_id does not refer to a valid channel. if channel is None: raise InputError(description='Invalid channel_id') # accesss error when the authorised user is not a member of the channel if auth_user['u_id'] not in channel['all_members']: raise AccessError(description='Not a member') # invited_user is already in channel if invited_user['u_id'] in channel['all_members']: return {} channel['all_members'].append(u_id) invited_user['channels'].append(channel_id) return {}
def channel_removeowner(token, channel_id, u_id): ''' This will remove the user with u_id from the owners of target channel. If u_id refers to the owner of flockr, it will ignore the request. Token refers to one of the owner of target channel. It will return an empty dictionaty. Args: param1: authorised user's token. param2: target channel. param3: the user's u_id who is removed from owners Returns: This will return an empty dictionary. Raises: InputError: 1. Channel ID is not a valid channel 2. When user with user id u_id is not an owner of the channel AccessError: 1. when the authorised user is not an owner of the flockr, or an owner of this channel 2. given token does not refer to a valid token ''' auth_user = get_user_from_token(token) channel = get_channel_from_id(channel_id) removed_user = get_user_from_id(u_id) # access error when given token does not refer to a valid user if auth_user is None: raise AccessError(description='Invalid token') # input error when Channel ID is not a valid channel if channel is None: raise InputError(description='Invalid channel_id') # input error when u_id does not refer to a valid user if removed_user is None: raise InputError(description='Invalid u_id') # input error when user with user id u_id is not an owner of the channel if removed_user['u_id'] not in channel['owner_members']: raise InputError(description='Not a owner of channel') # accesss error when the authorised user is not # an owner of the flockr, or an owner of this channel if is_user_an_owner(token, channel_id) is False: raise AccessError(description='Not permitted to remove') channel['owner_members'].remove(u_id) return {}