def auth_logout(token): ''' Invalidates the user's token and logs them out. Args: token (str) Return: is_success (bool) ''' # verify the user if verify_token(token) is False: return {'is_success': False} # remove the user's token get_tokens().pop(token) return {'is_success': True}
def channel_details(token, channel_id): ''' Given a Channel with ID channel_id that the authorised user is part of, provide basic details about the channel. Args: token (str), channel_id (int) InputError: channel_id is not a valid channel AccessError: authorised user is not part of the channel with channel_id Output: (channel) name, owner_members, all_members ''' data = get_store() # verify the token is valid if verify_token(token) is False: raise AccessError(description="Invalid token") if not data.channels.channel_exists(channel_id): raise InputError(description='Channel does not exist') # check that the authorised user is member of said channel auth_u_id = get_tokens()[token] if not data.user_channel.is_member(auth_u_id, channel_id): raise AccessError( description= "The authorised user is not a member of channel with this channel ID" ) # Create two lists and append details about owner members of the channel and all its members # return the dictionary containing details of the channel return { "name": data.channels.channel_details(channel_id)['name'], "owner_members": data.channel_owners(channel_id), "all_members": data.channel_members(channel_id) }
def flush_standup(channel_id): ''' Input: channel_id (int) Returns: Nothing Purpose: Helper function to concat messages in a standup and send them at once ''' with STANDUP_LOCK: standups = get_standup() try: [to_flush ] = list(filter(lambda x: x['channel_id'] == channel_id, standups)) to_send = '\n'.join(to_flush['messages']) # message is empty.. do not bother if not to_send: standups.remove(to_flush) return # get the token given u_id user_token = get_token(to_flush['u_id']) if user_token is None: # generate a temporary token user_token = generate_token(to_flush['u_id']) get_tokens()[user_token] = to_flush['u_id'] message_send(user_token, channel_id, to_send) auth_logout(user_token) else: message_send(user_token, channel_id, to_send) standups.remove(to_flush) except ValueError: pass
def channel_addowner(token, channel_id, u_id): ''' Promotes user with 'u_id' to an owner of channel with 'channel_id' Args: token (str): of the user authorising this action channel_id (int): of the channel to which to promote the user to owner u_id (int): of the user to be promoted Raises: AccessError: if token invalid if token does not belong to a user with permission to promote InputError: if channel_id does not correspond to a valid channel ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id_invoker = get_tokens()[token] # verify the channel exists if not data.channels.channel_exists(channel_id): raise InputError(description="Invalid channel id") # verify the invoker is either an owner of the channel or an admin if not data.admins.is_admin(u_id_invoker) and \ not data.user_channel.is_owner(u_id_invoker, channel_id): raise AccessError( description="You do not have privileges to add owners") data.user_channel.add_owner(u_id, channel_id)
def user_profile_setname(token, name_first, name_last): ''' Updates the authorised user's first name and last name. Args: token (str): of the user authorising this action name_first (str): user's new first name (1-50 char) name_last (str): user's new last name (1-50 char) Raises: AccessError: if token is invalid InputError: if either name_first or name_last is shorter than 1 char or longer than 50 char ''' # verify token is valid if verify_token(token) is False: raise AccessError(description="Invalid token") # verify that changes to name are allowed if len(name_first) < MIN_NAME_LEN or len(name_last) < MIN_NAME_LEN \ or len(name_first) > MAX_NAME_LEN or len(name_last) > MAX_NAME_LEN: raise InputError( description= "Names must be between 1 and 50 characters long inclusive.") # another verification that names are not just spaces if name_first.isspace() or name_last.isspace(): raise InputError( description="Names cannot exclusively contain whitespaces.") # modify name_first and name_last in the database as per the user's changes u_id = get_tokens()[token] data = get_store() data.users.set_first_name(u_id, name_first) data.users.set_last_name(u_id, name_last)
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. Args: token (str), channel_id (int), u_id (int) InputError: channel ID does not correspond to a valid channel; user ID does not refer to a valid user. AccessError: authorised user is not already a member of channel with channel ID. ''' # verify the validity of the authorised user's token if verify_token(token) is False: raise AccessError(description="Invalid token") # check that channel_id corresponds to a valid channel data = get_store() if not data.channels.channel_exists(channel_id): raise InputError( description="Channel with this channel ID does not exist") # check that the authorised user belongs to this valid channel auth_u_id = get_tokens()[token] if not data.user_channel.is_member(auth_u_id, channel_id): raise AccessError( description="The authorised user is not a member of this channel") # check that u_id corresponds to a valid user if not data.users.user_exists(u_id): raise InputError(description="User ID is not valid") # add the user with u_id into the channel # update the database by adding a link between the user and the channel # checks if user is already apart of the channel data.user_channel.join_channel(u_id, channel_id)
def message_unpin(token, message_id): ''' Unpins the message with ID message_id in the channel that it is in Parameters: valid token (str): of authorised user message_id (int): ID of the message to be unpinned Returns: empty dictionary Raises: InputError: if message with ID message_id is not a valid message, or message is currently unpinned AccessError: if token is invalid, or if authorised user is not a slackr owner nor an admin of the channel in which the message is ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database data = get_store() # getting id of the user u_id = get_tokens()[token] data.unpin(u_id, message_id) return {}
def channel_leave(token, channel_id): ''' Allows a user with 'token' to leave the channel with 'channel_id' Args: token (str), channel_id (int) Raises: AccessError: if token invalid if user with u_id was not a member of the channel in the first place InputError: if channel_id does not correspond to a valid channel Return: an empty dictionary ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id = get_tokens()[token] # verify the channel exists if not data.channels.channel_exists(channel_id): raise InputError(description="Invalid channel id") # verify the user is a member of the channel if not data.user_channel.is_member(u_id, channel_id): raise AccessError(description="Cannot leave channel: not a member") # deleting the user from the channel list data.user_channel.leave_channel(u_id, channel_id) return {}
def message_unreact(token, message_id, react_id): ''' Removes a certain 'react' from a specified message within a channel Parameters: valid token (str): of authorised user message_id (int): ID of the message to be given a react react_id (int): a valid react ID to be removed from the message Raises: InputError: if message with ID message_id is not a valid message or does not exist, or if react_id is not a valid react, or message already has no current react of react_id from the current user AccessError: if token is invalid, or if the user is not part of the channel in which the message exists ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database data = get_store() # getting id of the user u_id = get_tokens()[token] if not data.messages.message_exists(message_id): raise InputError(description='Invalid message ID') channel_id = data.user_message.message_channel(message_id) if not data.user_channel.link_exists(u_id, channel_id): raise InputError( description='Not valid message ID within channel you have joined') data.user_message.unreact(u_id, message_id, react_id) return {}
def auth_login(email, password): ''' Given a registered users' email and password and generates a valid token for the user to remain authenticated. Args: email (str), password (str) Raise: InputError: email entered not valid, email does not belong to a user, password is incorrect Return: Dictionary: u_id (int), token (str) ''' data = get_store() # Ensure user's password matches otherwise raise an error encrypted_pass = hashlib.sha256(password.encode()).hexdigest() u_id = data.users.validate_login(email, encrypted_pass) # check if the user is not already logged in token = get_token(u_id) if token is not None: raise InputError(description='User is already logged on') token = generate_token(u_id) get_tokens()[token] = u_id return {"u_id": u_id, "token": token}
def workspace_reset(): ''' Resets the workspace state. Assumes that the base state of database.p has a Database() instance. ''' # clear the tokens dictionary get_tokens().clear() # clear database.p data = get_store() data.reset() # clear standups with get_lock(): standups = get_standup() standups.clear() with open("database.p", "wb") as database_file: pickle.dump(data, database_file)
def user_remove(token, u_id): ''' Removes a user from slackr Arguments: token and u_id of user to be removed Returns: empty dictionary, but the user is entirely removed. Exceptions: InputError: u_id is not a valid user AccessError: remover is not an admin Assumptions: removing the user means removing all traces of him including his messages ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') data = get_store() # getting id of the user u_id_invoker = get_tokens()[token] # verify the invoker is an admin if not data.admins.is_admin(u_id_invoker): raise AccessError( description="You do not have permission to change permissions") if not data.users.user_exists(u_id): raise InputError(description="Invalid user id") # verify the admin is not removing himself if u_id == u_id_invoker: raise InputError(description='Cannot remove current user') # cannot remove the hangman bot if user_profile(token, u_id)['user']['name_first'] == 'Hangman': raise InputError(description='Cannot remove Hangman B0T') # removing his user details data.users.remove(u_id) # removing all his subscriptions to channels data.user_channel.remove_link_by_user(u_id) # removing all the messages sent by that user data.remove_messages(u_id) # remove the user the token store if he is logged on token = get_token(u_id) if token is not None: get_tokens().pop(token)
def verify_token(token): ''' Checks that the token given is in the TOKENS dictionary as described in server.py Args: token (str) Return: (bool) ''' token_dict = get_tokens() if token not in token_dict.keys(): return False return True
def message_sendlater(token, channel_id, message, time_sent): ''' Sends a message into channel with ID channel_id at a specified time in the future Parameters: valid token (str): of authorised user channel_id (int): the channel into which the message is to be sent message (str): the message to be sent by the authorised user into channel time_sent (float): unix timestamp of a time in the future for message to be sent Returns: dictionary containing: message_id (int): ID assigned to the new message Raises: InputError: if message length is greater than 1000 strings or message is empty, or channel_id is invalid, or time_sent is not a correctly formatted future timestamp AccessError: if token is invalid, or the authorised user is not part of the channel with ID channel_id ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # checking message string is valid if not isinstance(message, str) or len(message) > MAX_MSG_LEN or not message: raise InputError(description='Invalid message') # get database data = get_store() # getting id of the user u_id = get_tokens()[token] # checking channel_id is valid (user is part of) if not data.user_channel.link_exists(u_id, channel_id): raise AccessError( description='You do not have access to send message in this channel' ) # checking time_sent is valid (it is a time in the future) if time_sent < time(): raise InputError(description='Scheduled send time is invalid') # assigning new ID for the message new_id = data.messages.next_id() # the action to be completed at time time_sent sched_thread = Thread(target=run_scheduler, args=(message_send, time_sent, ( token, channel_id, message, ))) # run the schedular (target=message_send, time_sent=time_sent, ) sched_thread.start() return {'message_id': new_id}
def get_token(u_id): ''' Retrieves token given a user id, returns None if the user is logged out FOR AUTH_LOGOUT Args: u_id (int) Return: token (str, None) ''' tokens = get_tokens() for token, logged_uid in tokens.items(): if logged_uid == u_id: return token return None
def message_send(token, channel_id, message): ''' Sends a message into channel with ID channel_id Parameters: valid token (str): of authorised user channel_id (int): the channel into which the message is to be sent message (str): the message to be sent by the authorised user into channel Returns: dictionary containing: message_id (int): ID assigned to the new message Raises: InputError: if message length is greater than 1000 strings or message is empty, or channel_id is invalid AccessError: if token is invalid, or the authorised user is not part of the channel with ID channel_id ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # checking message string is valid if not isinstance(message, str) or len(message) > MAX_MSG_LEN or not message: raise InputError(description='Invalid message') # get database data = get_store() # getting id of the user u_id = get_tokens()[token] # checking channel_id is valid (user is part of) if not data.user_channel.link_exists(u_id, channel_id): raise AccessError( description= 'You do not have access to send messages in this channel') # send the message details = message, time() new_id = data.add_message(u_id, channel_id, details) # Facilitation of Hangman Game hbot_output = hangman(message, channel_id, u_id) if hbot_output is not None: # obtain the token of the hangman bot for the channel we are currently # in hbot_token = data.channels.get_hbot_details(channel_id)[1] message_send(hbot_token, channel_id, hbot_output) return {'message_id': new_id}
def userpermission_change(token, u_id, permission_id): ''' Sets the user's permission to either owner/admin (1) or normal member (2). Args: token (str): of the user authorising this action u_id (int): of the user whose permission is being changed permission_id (int): 1 for owner, 2 for member Raises: AccessError: if token is invalid if the user invoking this action is not an owner/admin of the slackr if the owner/admin attempts to demote themselves to a normal member InputError: if u_id does not correspond to an existent user if permission_id does not correspond to a valid permission ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id_invoker = get_tokens()[token] # verify that u_id is a valid user if not data.users.user_exists(u_id): raise InputError(description="User does not exist") # verify permission_id is valid (1 or 2) if not data.admins.is_valid_permission(permission_id): raise InputError(description="Invalid permission id") # verify the invoker is an admin if not data.admins.is_admin(u_id_invoker): raise AccessError( description="You do not have permission to change permissions") # the admin cannot demote himself if u_id_invoker == u_id and permission_id == SLACKR_MEMBER: raise InputError(description='Cannot demote current user') # set new permissions if permission_id == SLACKR_OWNER: data.admins.add(u_id) else: data.admins.remove(u_id)
def standup_start(token, channel_id, length): ''' Input: channel_id: int, length: int Returns: a dictionary containing the finish time of the standup Raises: InputError, AccessError Start a standup in a given channel ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id = get_tokens()[token] # verify the channel exists if not data.channels.channel_exists(channel_id): raise InputError(description="Invalid channel id") # getting all the standups standups_info = get_standup() # verify there are currently no standups in the channel for standup in standups_info: if standup['channel_id'] == channel_id: raise InputError(description="Active standup already in channel") # verifying length is a float or an integer if not isinstance(length, int) and not isinstance(length, float): raise InputError(description="Invalid length type") # creating a new standup time_finish = time.time() + length with STANDUP_LOCK: standups_info.append({ 'channel_id': channel_id, 'u_id': u_id, 'time_start': time.time(), 'time_finish': time_finish, 'messages': [], }) # schedule flushing the standup running_time = time.time() + length sched_thread = Thread(target=run_scheduler, args=(flush_standup, running_time, (channel_id, ))) #run_scheduler(target=flush_standup, running_time=time.time() + length, args=(channel_id,)) sched_thread.start() return {'time_finish': time_finish}
def channel_removeowner(token, channel_id, u_id): ''' Demote user with 'u_id' from an owner to normal member of channel with 'channel_id' Args: token (str): of the user authorising this action channel_id (int): of the channel to which to demote the user to normal member u_id (int): of the user to be demoted Raises: AccessError: if token invalid if token does not belong to a user with permission to demote if attempting to demote an admin of the slackr InputError: if channel_id does not correspond to a valid channel ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id_invoker = get_tokens()[token] # verify the channel exists if not data.channels.channel_exists(channel_id): raise InputError(description="Invalid channel id") # verify the user to remove is not a Slackr owner # and the remover has valid privileges if not data.admins.is_admin(u_id_invoker) and data.admins.is_admin(u_id): raise AccessError( description="You do not have permission to remove the current user" ) # verify the invoker is either an owner of the channel or slackr if not data.user_channel.is_owner(u_id_invoker, channel_id): raise AccessError( description="You do not have premission to remove the current user" ) # remove the ownership data.user_channel.remove_owner(u_id, channel_id)
def user_profile_sethandle(token, handle_str): ''' Updates the authorised user's handle. Args: token (str): of the user authorising this action handle_str (str): user's new handle Raises: AccessError: if token not valid InputError: if handle_str not between 2 and 20 characters inclusive if handle_str not unique to user ''' # verify the token is valid if verify_token(token) is False: raise AccessError(description="Invalid token") # verify the new handle_str is of the correct length if len(handle_str) < MIN_HANDLE_LEN: raise InputError( description= "handle_str too short - it must be between 2 and 20 characters inclusive" ) if len(handle_str) > MAX_HANDLE_LEN: raise InputError( description= "handle_str too long - - it must be between 2 and 20 characters inclusive" ) u_id = get_tokens()[token] data = get_store() # verify the new handle_str is unique # allow the "change" if the authorised user's new handle_str is identical # to their old one. if data.users.get_handle( u_id) != handle_str and not data.users.handle_unique(handle_str): raise InputError(description="new handle_str not unique to this user") # change the handle_str in the database data.users.set_handle(u_id, handle_str)
def channel_join(token, channel_id): ''' Allows a user with a valid 'token' to join a public channel with 'channel_id' Args: token (str), channel_id (int) Raises: AccessError: if token invalid if the channel is private InputError: if channel_id does not correspond to an existing channel if user with u_id is already a member of the channel Return: an empty dictionary ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id = get_tokens()[token] # verify the channel exists if not data.channels.channel_exists(channel_id): raise InputError(description="Invalid channel id") # verify user is not already a member if data.user_channel.is_member(u_id, channel_id): raise InputError(description="Already a member") # verify the channel is public unless user is a slackr owner if not data.admins.is_admin(u_id) and data.channels.is_private(channel_id): raise AccessError( description="Cannot join channel: channel is private") # ... joining channel: if admin if data.admins.is_admin(u_id): data.user_channel.add_owner(u_id, channel_id) else: data.user_channel.join_channel(u_id, channel_id)
def profile_uploadphoto(token, url, box): ''' Crops a given image from a url and stores it in the database Arguments: token, image url, coordinates to be cropped Returns: nothing, but with url for the cropped image stored in the users details ''' # # verify that the token is valid # if verify_token(token) is False: # raise AccessError(description="Invalid token") # preparing the coordinates x_start, y_start, x_end, y_end = box # getting the image response = requests.get(url) # checking the image url given is valid if response.status_code != OK_STATUS: raise InputError(description='Cannot open image') # getting the image image = Image.open(io.BytesIO(response.content)) # making sure the image type is JPG if image.format != 'JPEG': raise InputError('Invalid image format') # checking the supplied coordinates are valid img_width, img_height = image.size if x_start < 0 or y_start < 0 or \ x_end > img_width or y_end > img_height: raise InputError('Invalid crop coordinates') # crop the image cropped_img = image.crop(box) # get the database data = get_store() # saving the image into the database u_id = get_tokens()[token] # pylint: disable=global-statement cropped_img.save(f"{image_config()['path']}/{u_id}.jpg") data.users.set_image(u_id)
def channels_list(token): ''' Provides users with details of all channels the requesting user is part of Parameter: authorised token Returns: list of channels (and associated details) that the authorised user is part of ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database data = get_store() # getting id of the user # get_tokens() should return a dictionary where token key corresponds to # that user's id u_id = get_tokens()[token] # return details about all channels the user is part of return { 'channels': data.user_channels(u_id) }
def channel_messages(token, channel_id, start): ''' Lists up to 50 messages within 'channel_id', beginning from the message indexed 'start'. Args: token (str): of the user authorising this action channel_id (int): of the channel whose messages require displaying start (int): index of the first message to display Raises: AccessError: if token invalid if authorised user does not hav permission to view the channel's messages InputError: if channel_id does not correspond to a valid channel Return: List of 50 messages from channel with channel_id starting from index 'start', if we reached the end of the list we set the 'end' index to -1 ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id = get_tokens()[token] # verify the channel exists if not data.channels.channel_exists(channel_id): raise InputError(description='Channel does not exist') # verify the user is a member of the channel if not data.user_channel.is_member(u_id, channel_id): raise AccessError( description= "You do not have permission to view this channel's messages") # getting the messages of the channel details = channel_id, start messages, more = data.channel_messages(u_id, details) return { "messages": messages, "start": start, "end": -1 if not more else start + MESSAGE_BLOCK }
def standup_send(token, channel_id, message): ''' Input: A token, a channel id and a message Returns: an empty dictionary if a successful message send to the standup in channel occurred Purpose: buffer a message in the standup to be sent later ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database information data = get_store() # getting id of the user u_id = get_tokens()[token] # verify the channel exists if not data.channels.channel_exists(channel_id): raise InputError(description="Invalid channel id") # verify user is within channel if not data.user_channel.is_member(u_id, channel_id): raise AccessError( description="You do not have permission to send a standup message") # verify message is not more than 1000 characters or not less than 1 if len(message) > MAX_LENGTH or not message: raise InputError(description="Invalid message") # verify there is an active standup # getting all the standups standups = get_standup() with STANDUP_LOCK: try: [standup ] = list(filter(lambda x: x['channel_id'] == channel_id, standups)) standup['messages'].append(message) except ValueError: raise InputError(description="No active standup in this channel")
def message_remove(token, message_id): ''' Removes the message with ID message_id from the channel that it is currently in Parameters: valid token (str): of authorised user message_id (int): ID of the message to be removed Returns: empty dictionary Raises: InputError: if message with ID message_id is not a valid message or does not exist AccessError: if token is invalid, or if authorised user is not a slackr owner nor an admin of the channel in which the message is, and is not the user who sent the original message ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database data = get_store() # getting id of the user u_id = get_tokens()[token] # check whether the message exists if not data.messages.message_exists(message_id): raise InputError(description='Invalid message ID') # check if the user has permissions to remove the message channel_id = data.user_message.message_channel(message_id) if not (data.user_channel.is_owner(u_id, channel_id) or data.admins.is_admin(u_id) or data.user_message.is_sender(message_id, u_id)): raise AccessError( description='You do not have access to delete this message') data.remove_message(message_id) return {}
def search(token, query_str): ''' Searches all channels which invoking user is part of for messages containing the query string. Args: token (str): of the use authorising this action Raises: AccessError: if token is invalid InputError: if query_str is over 1000 char long Returns: Dictionary: containing a list of message dictionaries containing information of each message that contains the query_str - {message_id, u_id, message, time_created, reacts, is_pinned} ''' # verify the token is valid if verify_token(token) is False: raise AccessError(description='Invalid token') data = get_store() auth_u_id = get_tokens()[token] if len(query_str) > 1000: raise InputError( description="query_str over 1000 characaters; too long") # empty query_str returns an empty list if query_str == "": return { 'messages': [] } # find all the channels the user is a part of and search for query_str in # the messages return { 'messages': data.message_search(auth_u_id, query_str) }
def message_edit(token, message_id, message): ''' Edits the message with ID message_id in the channel that it is in Parameters: valid token (str): of authorised user message_id (int): ID of the message to be edited new message (str): to replace the old message Raises: InputError: if message with ID message_id is not a valid message or does not exist AccessError: if token is invalid, or if authorised user is not a slackr owner nor an admin of the channel in which the message is, and is not the user who sent the original message ''' # verify the validity of the token if verify_token(token) is False: raise AccessError(description="Invalid token") # check that the request is being made by a user with the correct # permissions auth_u_id = get_tokens()[token] data = get_store() if has_message_edit_permission(auth_u_id, message_id) is False: raise AccessError( description= "User with this u_id does not have permission to edit this message" ) # delete the message if the message string is empty, # otherwise modify the message accordingly in both # the "Channels" and "Messages" sub-dictionaries if message == "": message_remove(token, message_id) else: data.messages.edit(message_id, message)
def user_profile_setemail(token, email): ''' Updates the authorised user's email address. Args: token (str): of the user authorising this action email (str): user's new email address Raises: AccessError: if token invalid InputError: if email invalid as determined by is_valid_email module if email is already being used by another user ''' # verify that the token is valid if verify_token(token) is False: raise AccessError(description="Invalid token") # InputError if email not valid if is_valid_email(email) is False: raise InputError(description="Input is not a valid email") u_id = get_tokens()[token] data = get_store() # InputError if email not unique # Allow if the user is simply changing their email to their current email # again. if data.users.email_used(email): raise InputError( description="this email is already being used by another user") # Change the user's email in the STORE databas if the above hurdles are # passed data.users.set_email(u_id, email)
def channels_create(token, name, is_public): ''' Input: token, name, is_public status Output: {channel_id}, creates a new channel with the input name and public / private ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database data = get_store() # getting user id from token u_id = get_tokens()[token] # check if name is valid if not isinstance(name, str) or len(name) > 20: raise InputError(description='Invalid channel name') # check if is_public is correct type if not isinstance(is_public, bool): raise InputError(description='Invalid channel status') # creating new channel details = name, is_public new_id = data.add_channel(u_id, details) # CREATING HANGMAN BOT hbot = create_hbot(new_id) # Inform the first user of option to disable hangman game message_send(hbot['token'], new_id, "For owners and admins: \ \nType '/disable game' to disable the hangman game. \nType '/enable game' to re-enable it.") return { 'channel_id': new_id }