def message_unreact(token, message_id, react_id): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] # Valid react_id (Only 1 is currently valid) if react_id != 1: raise ValueError("not a valid react_id") # search through channel/list, then channel messages to find the correct message i = 0 #print(channels['channels'][i]['channel_id']) while i < len(data["channels"]): j = 0 if u_id in data["channels"][i]["membersUID"]: while j < len(data["channels"][i]["messages"]): if message_id == data["channels"][i]["messages"][j]["message_id"]: if data["channels"][i]["messages"][j]["reacts"][0]['is_this_user_reacted'] == False: raise ValueError( "You haven't reacted to this message with this reaction") data["channels"][i]["messages"][j]["reacts"][0]['is_this_user_reacted'] = False data["channels"][i]["messages"][j]["reacts"][0]['u_ids'].remove(u_id) storage.dump_data_store(data) return j += 1 i += 1 # check react id's raise ValueError("Not a valid message in a channel that the user is apart of")
def message_unpin(token, message_id): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] # if the token owner is an owner or an admin (p_id 1 and 2) # (search through all users for permission level) # look through all channels the user is apart of #print(channels['channels'][i]['channel_id']) i = 0 while i < len(data["channels"]): j = 0 while j < len(data["channels"][i]["messages"]): if message_id == data["channels"][i]["messages"][j]["message_id"]: if u_id in data["channels"][i]["ownersUID"]: if data["channels"][i]["messages"][j]["is_pinned"] == False: raise ValueError( "This message is already pinned") data["channels"][i]["messages"][j]["is_pinned"] = False storage.dump_data_store(data) return if u_id in data["channels"][i]["membersUID"]: raise ValueError("User isn't an admin") raise errors.AccessError("User isn't a member of the channel the message is in") j += 1 i += 1 raise ValueError("message_id isn't a valid message") pass
def standup_start(token, channel_id): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] i = 0 while i < len(data["channels"]): if data["channels"][i]["channelID"] == channel_id: # check if currently running a stand_up if data["channels"][i]["standup_time"] >= datetime.datetime.now(): raise ValueError("This channel already has a standup started") elif u_id not in data["channels"][i]["membersUID"]: raise errors.AccessError( "This user isn't a member of the channel") else: # return time + 15 mins time = datetime.datetime.now() + datetime.timedelta(minutes=15) data["channels"][i]["standup_time"] = time storage.dump_data_store(data) return time i += 1 raise ValueError("Channel ID is not a valid channel")
def message_send(token, channel_id, text): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] # check the message <= 1000 characters if len(text) > 1000: raise ValueError("Message is more than 1000 characters") # check if user is an admin, owner or a member of the channel channel_deats = channel_utils.channel_details(token, channel_id) if u_id not in channel_deats['all_members']: raise errors.AccessError( "The user isn't authorised to post in this channel") # generate a message_id, and post it message = message_create(u_id, text, datetime.now()) # put the message onto a channel for channel in data['channels']: if channel['channelID'] == channel_id: break channel['messages'].insert(0, message) storage.dump_data_store(data) return message['message_id']
def standup_send(token, channel_id, message): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] # check the message <= 1000 characters if len(message) > 1000: raise ValueError("Message is more than 1000 characters.") i = 0 while i < len(data["channels"]): if data["channels"][i]["channelID"] == channel_id: # check if currently running a stand_up if data["channels"][i]["standup_time"] <= datetime.datetime.now(): raise ValueError("This channel doesn't have a standup") elif u_id not in data["channels"][i]["membersUID"]: raise errors.AccessError( "This user isn't a member of the channel") else: timesent = data["channels"][i]["standup_time"] message_utils.message_sendlater(token, channel_id, message, timesent) return i += 1 raise ValueError("Channel ID is not a valid channel")
def search(token, query_str): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] if len(query_str) > 1000: raise ValueError("Messages cannot be more than 1000 characters") messages = [] # find the channels the user is apart of. i = 0 #print(channels['channels'][i]['channel_id']) while i < len(data["channels"]): j = 0 if u_id in data["channels"][i]["membersUID"]: while j < len(data["channels"][i]["messages"]): if query_str in data["channels"][i]["messages"][j]["message"]: messages.append(data["channels"][i]["messages"][j]) j += 1 i += 1 return messages
def message_remove(token, message_id): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] # find message through channel/list, then channel messages to find the correct message i = 0 while i < len(data["channels"]): j = 0 if u_id in data["channels"][i]["membersUID"]: while j < len(data["channels"][i]["messages"]): if message_id == data["channels"][i]["messages"][j]["message_id"]: if (u_id not in data["channels"][i]['ownersUID']) and \ (u_id not in data["channels"][i]["messages"][j]['u_id']): raise ValueError( "Neither the original poster of this message or an owner") del data["channels"][i]["messages"][j] storage.dump_data_store(data) return j += 1 i += 1 raise errors.AccessError("Message_id isn't in any channel you have access too") pass
def message_sendlater(token, channel_id, message, time_sent): data = channel_utils.get_data() # Check valid token if authentication.decode_token(token) == None: raise ValueError("Invalid token provided.") u_id = authentication.decode_token(token)["u_id"] # check the message <= 1000 characters if len(message) > 1000: raise ValueError("Message is more than 1000 characters.") # check if user is an admin, owner or a member of the channel channel_deats = channel_utils.channel_details(token, channel_id) if u_id not in channel_deats['all_members']: raise errors.AccessError( "The user isn't authorised to post in this channel.") # time in the future if time_sent < datetime.now(): raise ValueError("Time sent is in the past.") # generate a message_id, and set to post at correct time message = message_create(u_id, message, time_sent) # put the message into the channel for channel in data['channels']: if channel['channelID'] == channel_id: break channel['messages'].insert(0, message) # HOW TO DO TIME? storage.dump_data_store(data) return message['message_id']
def user_profile_setname(token, name_first, name_last): user_index = 0 index = 0 new_info = {} user_data = get_user_data() decoded_token = authentication.decode_token(token) if decoded_token is None: raise errors.AccessError u_id = decoded_token["u_id"] # check the length of the firstname and lastname # change the name for the profile with the specified token if not (authentication.is_valid_first_name(name_first) and authentication.is_valid_last_name(name_last)): raise ValueError for user in user_data: if u_id == user['u_id']: index = user_index new_info['u_id'] = user['u_id'] new_info['handle_str'] = user['handle_str'] new_info['first_name'] = name_first new_info['last_name'] = name_last new_info['email'] = user['email'] new_info['hashed_password'] = user['hashed_password'] user_index = user_index + 1 update_pickle(index, new_info) return {}
def test_decode_token(): """ Tests decoding tokens """ storage.clear_data_store() # test for valid token decode token = authentication.generate_token(100) res = authentication.decode_token( token, check_expiry=False) assert "u_id" in res and res["u_id"] == 100 # test for tampered token signature decode token = authentication.generate_token(100) token = token[:-2] + "AA" assert authentication.decode_token(token, check_expiry=False) is None
def user_profile_sethandle(token, handle_str): user_index = 0 index = 0 new_info = {} user_data = get_user_data() decoded_token = authentication.decode_token(token) if decoded_token is None: raise errors.AccessError u_id = decoded_token["u_id"] # remove leading and trailing whitespace handle_str = handle_str.strip() # check the handle is not in use: for user in user_data: if user['handle_str'] == handle_str: raise ValueError("This handle already exists") if u_id == user['u_id']: if len(handle_str) >= 3 and len( handle_str) <= 20 and not handle_str.isspace(): index = user_index new_info['u_id'] = user['u_id'] new_info['handle_str'] = handle_str new_info['first_name'] = user['first_name'] new_info['last_name'] = user['last_name'] new_info['email'] = user['email'] new_info['hashed_password'] = user['hashed_password'] else: raise ValueError("Invalid handle") user_index = user_index + 1 update_pickle(index, new_info) return {}
def test_message_unreact(): storage.clear_data_store() # set up user dic1 = authentication.auth_register('*****@*****.**', 'password1', 'Bob', 'James') token1 = dic1['token'] # creat a valid channel in the name of user1 dic = channel_utils.channels_create(token1, 'name', False) channel_id_valid = dic['channel_id'] # message to be unreacted message = "unReact to me :)" message_id = message_utils.message_send(token1, channel_id_valid, message) # Setting the message to have been reacted to by token1 with a react_id 1 react_id = 1 message_utils.message_react(token1, message_id, react_id) # Everything valid. token = token1 react_id = 1 message_utils.message_unreact(token, message_id, react_id) # Prove that it worked channel = channel_utils.get_channel(channel_id_valid) u_id = authentication.decode_token(token)["u_id"] assert channel['messages'][0]['reacts'] == [{'is_this_user_reacted': False, \ 'react_id': 1, 'u_ids': []}] # message_id isn't a valid message within a channel that the user has joined # VALUE ERROR token = token1 message_id = -99 react_id = 1 with pytest.raises(ValueError): message_utils.message_unreact(token, message_id, react_id) # react id isn't valid # VALUE ERROR token = token1 react_id = -99 with pytest.raises(ValueError): message_utils.message_unreact(token, message_id, react_id) # message with id message_id does not contain an active react with given id # VALUE ERROR token = token1 react_id = 1 with pytest.raises(ValueError): message_utils.message_unreact(token, message_id, react_id) # Invalid token token = "Invalidtoken" react_id = 1 with pytest.raises(ValueError): message_utils.message_unreact(token, message_id, react_id)
def admin_userpermission_change(token, u_id, permission_id): """ Changes the permission level for a user """ # check for valid users decoded_token = authentication.decode_token(token) if decoded_token is None: raise errors.AccessError("Not a valid user") # check for valid permission_id if not permission_id in set(perm.value for perm in SlackrPermissions): raise ValueError("Not a valid permission_id") admin_id = decoded_token["u_id"] data = authentication.get_auth_store() user_to_change = None # Get user and admin levels for user_index, user in enumerate(data["users"]): if user["u_id"] == admin_id: admin = user if user["u_id"] == u_id: user_to_change = user_index # check if user exists if user_to_change is None: raise ValueError("Unknown user to modify") # check if modifying their own permissions (to avoid getting stuck with no one with permissions) if admin["u_id"] == data["users"][user_to_change]["u_id"]: raise ValueError("Can't modify own permissions") # check if level is either admin or owner if admin["permission_id"] not in VALID_ADMIN_LEVELS: raise errors.AccessError("Not a valid owner or admin") # check if is another owner if modifying an owner if (admin["permission_id"] != SlackrPermissions.OWNER.value and data["users"][user_to_change]["permission_id"] == SlackrPermissions.OWNER.value): raise errors.AccessError("Admins cannot change a owner's permission") data["users"][user_to_change]["permission_id"] = permission_id storage.dump_data_store(data) return True
def test_auth_logout(): """ Tests logout """ storage.clear_data_store() # test a simple logout email = "*****@*****.**" first_name = "test" last_name = "test" password = "******" user = authentication.auth_register(email, password, first_name, last_name) token = user["token"] assert authentication.auth_logout(token) # Should return None because token is expired assert authentication.decode_token(user["token"]) is None # test logout invalid token assert not authentication.auth_logout("invalid")
def user_profile_setemail(token, email): regex = r'^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$' user_index = 0 index = 0 new_info = {} user_data = get_user_data() decoded_token = authentication.decode_token(token) if decoded_token is None: raise errors.AccessError u_id = decoded_token["u_id"] # remove trailing and leading whitespace email = email.strip() # check the email is not in use: for user in user_data: if user['email'] == email: raise ValueError("Email address taken") # pass the regualar expression # and the string in search() method if u_id == user['u_id']: if re.search(regex, email): index = user_index new_info['u_id'] = user['u_id'] new_info['handle_str'] = user['handle_str'] new_info['first_name'] = user['first_name'] new_info['last_name'] = user['last_name'] new_info['email'] = email new_info['hashed_password'] = user['hashed_password'] else: raise ValueError("Not a valid Email") user_index = user_index + 1 update_pickle(index, new_info) return {}
def test_message_send(): storage.clear_data_store() # set up user dic1 = authentication.auth_register('*****@*****.**', 'password1', 'Bob', 'James') token1 = dic1['token'] # creat a valid channel in the name of user1 dic = channel_utils.channels_create(token1, 'name', False) channel_id_valid = dic['channel_id'] # Value error when message too long # VALUE ERROR token = token1 channel_id = channel_id_valid message = "0123456789" * 101 with pytest.raises(ValueError): message_utils.message_send(token, channel_id, message) # Invalid token. token = "InvalidToken" channel_id = channel_id_valid message = "Valid message" with pytest.raises(ValueError): message_utils.message_send(token, channel_id, message) # Channel_id doesn't exist. token = token1 channel_id = -1 message = "Valid message" with pytest.raises(ValueError): message_utils.message_send(token, channel_id, message) # set up another channel, which the original user doesn't have access too dic2 = authentication.auth_register('*****@*****.**', 'password2', 'Bobby', 'Jamesy') token2 = dic2['token'] # creat a valid channel in the name of user1 dic_a = channel_utils.channels_create(token2, 'matth', False) channel_id_valid1 = dic_a['channel_id'] # User lacks access to current channel trying to post in. token = token1 channel_id = channel_id_valid1 message = "Valid message" with pytest.raises(errors.AccessError): message_utils.message_send(token, channel_id, message) # Everything Valid token = token1 channel_id = channel_id_valid message = "Valid message" message_id = message_utils.message_send(token, channel_id, message) u_id = authentication.decode_token(token)["u_id"] channel = channel_utils.get_channel(channel_id) assert channel['messages'][0]['message_id'] == message_id assert channel['messages'][0]['u_id'] == u_id assert channel['messages'][0]['message'] == "Valid message" assert channel['messages'][0]['reacts'] == [{ 'react_id': 1, 'u_ids': [], 'is_this_user_reacted': False }] assert channel['messages'][0]['is_pinned'] == False # send a second message message = "Second message" token = token1 message_id2 = message_utils.message_send(token, channel_id, message) channel = channel_utils.get_channel(channel_id) assert channel['messages'][0]['message_id'] == message_id2 assert channel['messages'][1]['message_id'] == message_id
def test_message_sendlater(): storage.clear_data_store() # set up user dic1 = authentication.auth_register('*****@*****.**', 'password1', 'Bob', 'James') token1 = dic1['token'] # creat a valid channel in the name of user1 dic = channel_utils.channels_create(token1, 'name', False) channel_id_valid = dic['channel_id'] # Everything valid. token = token1 channel_id = channel_id_valid message = "Valid message." time_sent = datetime(2019, 10, 31, 10, 10) message_id = message_utils.message_sendlater(token, channel_id, message, time_sent) # Prove it worked u_id = authentication.decode_token(token)["u_id"] channel = channel_utils.get_channel(channel_id) assert channel['messages'][0]['message_id'] == message_id # Token invaid token = "NotValid" channel_id = channel_id_valid message = "Valid message." time_sent = datetime(2019, 10, 31, 10, 10) with pytest.raises(ValueError): message_utils.message_sendlater(token, channel_id, message, time_sent) # The channel which the message is getting posted too doesn't exist # VALUE ERROR token = token1 channel_id = -12 message = "Valid message." time_sent = datetime(2019, 10, 31, 10, 10) # use channel_list with pytest.raises(ValueError): message_utils.message_sendlater(token, channel_id, message, time_sent) # set up another channel, which the original user doesn't have access too dic2 = authentication.auth_register('*****@*****.**', 'password2', 'Bobby', 'Jamesy') token2 = dic2['token'] # creat a valid channel in the name of user1 dic_a = channel_utils.channels_create(token2, 'name', False) channel_id_valid1 = dic_a['channel_id'] # User lacks access to current channel trying to post in. token = token1 channel_id = channel_id_valid1 message = "Valid message" time_sent = datetime(2019, 10, 31, 10, 10) with pytest.raises(errors.AccessError): message_utils.message_sendlater(token, channel_id, message, time_sent) # Message is too long (over 1000 characters). # VALUE ERROR token = token1 channel_id = channel_id_valid message = "0123456789" * 101 time_sent = datetime(2019, 10, 31, 10, 10) with pytest.raises(ValueError): message_utils.message_sendlater(token, channel_id, message, time_sent) # Time sent is in the past # VALUE ERROR token = token1 channel_id = channel_id_valid message = "Valid message." time_sent = datetime(2019, 8, 31, 10, 10) with pytest.raises(ValueError): message_utils.message_sendlater(token, channel_id, message, time_sent) pass