def message_react(token, message_id, react_id): users = unbox('users', {}) channels = unbox('channels', {}) messages = unbox('messages', {}) auth = users[str(decode(token)['u_id'])] message = messages[str(message_id)] channel = channels[str(message['channel_id'])] if auth['u_id'] not in channel['all_members']: raise AccessError("Unauthorised") if react_id not in [1]: raise ValueError(f"Invalid ID: react_id - {react_id}") reacts = message['reacts'] if str(react_id) in reacts and auth['u_id'] in reacts[str( react_id)]['u_ids']: raise ValueError("React already exists") if str(react_id) in reacts: reacts[str(react_id)]['u_ids'].append(auth['u_id']) else: reacts[str(react_id)] = {'react_id': react_id, 'u_ids': [auth['u_id']]} message['reacts'] = reacts messages[str(message_id)] = message box('messages', messages) return {}
def message_unreact(token, message_id, react_id): users = unbox('users', {}) channels = unbox('channels', {}) messages = unbox('messages', {}) auth = users[str(decode(token)['u_id'])] message = messages[str(message_id)] channel = channels[str(message['channel_id'])] if auth['u_id'] not in channel['all_members']: raise AccessError("Unauthorised") if react_id not in [1]: raise ValueError(f"Invalid ID: react_id - {react_id}") reacts = messages[str(message_id)]['reacts'] if str(react_id) not in reacts or auth['u_id'] not in reacts[str(react_id)]['u_ids']: raise ValueError("React doesn't exist") messages[str(message_id)]['reacts'][str(react_id)]['u_ids'].remove(auth['u_id']) box('messages', messages) return {}
def search(token, query_str): users = unbox('users', {}) channels = unbox('channels', {}) messages = unbox('messages', {}) auth = users[str(decode(token)['u_id'])] their_channels = [ int(id) for id in channels if auth['u_id'] in channels[id]['all_members'] ] # A dictionary {'messages' : [ list of messages ]} # Line 38 contains conditional expression to check message satisfies search criteria return { 'messages': [{ 'message_id': m['message_id'], 'u_id': m['u_id'], 'message': m['message'], 'time_created': m['time_created'], 'reacts': [{ 'react_id': r['react_id'], 'u_ids': r['u_ids'], 'is_this_user_reacted': (auth['u_id'] in r['u_ids']) } for r in m['reacts'].values()], 'is_pinned': m['is_pinned'] } for m in messages.values() if m['channel_id'] in their_channels and query_str in m['message']] }
def channels_create(token, name, is_public): users = unbox('users', {}) channels = unbox('channels', {}) auth = users[str(decode(token)['u_id'])] if auth['permission_id'] == 3: raise AccessError("Unauthorised") if len(name) > 20: raise ValueError("Invalid name (too long)") channel_id = 0 if len(channels) == 0 else max([int(id) for id in channels]) + 1 channels[str(channel_id)] = { 'channel_id': channel_id, 'name': name, 'is_public': is_public, 'all_members': [auth['u_id']], 'owner_members': [auth['u_id']] } box('channels', channels) return {'channel_id': channel_id}
def message_send(token, channel_id, message): users = unbox('users', {}) channels = unbox('channels', {}) messages = unbox('messages', {}) auth = users[str(decode(token)['u_id'])] channel = channels[str(channel_id)] if auth['u_id'] not in channel['all_members']: raise AccessError("Unauthorised") if not (1 <= len(message) <= 1000): raise ValueError("Message is either too long or too short") message_id = 0 if len(messages) == 0 else max([int(id) for id in messages]) + 1 messages[str(message_id)] = { 'message_id': message_id, 'channel_id': channel_id, 'u_id': auth['u_id'], 'message': message, 'time_created': int(time.time()), 'reacts': {}, 'is_pinned': False } box('messages', messages) return {'message_id': message_id}
def user_profiles_uploadphoto(token, img_url, x_start, y_start, x_end, y_end): if img_url[-4:] != '.jpg' and img_url[-5:] != '.jpeg': raise ValueError(f"Invalid url: '{img_url}'") identifier = str(uuid.uuid4()) PROFILE_IMG_URL = unbox('url_base', '') + '/user/profiles/photo/' + identifier + '.jpg' FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../utility/storage/' + identifier + '.jpg') try: urllib.request.urlretrieve(img_url, FILE) except Exception: raise ValueError(f"Cannot retrieve image: '{img_url}'") try: img = Image.open(FILE) cropped = img.crop((x_start, y_start, x_end, y_end)) cropped.save(FILE) except Exception: os.remove(FILE) raise ValueError("Cannot crop image") users = unbox('users', []) users[str(decode(token)['u_id'])]['profile_img_url'] = PROFILE_IMG_URL box('users', users) return {}
def channels_list(token): users = unbox('users', {}) channels = unbox('channels', {}) auth = users[str(decode(token)['u_id'])] return { 'channels': [{ 'channel_id': channels[id]['channel_id'], 'name': channels[id]['name'] } for id in channels if auth['u_id'] in channels[id]['all_members']] }
def test_auth_passwordreset_reset_success(): box('users', {"1" : { "u_id": 1, "email": "*****@*****.**", 'password' : HASH } }) box('email_to_u_id', { "*****@*****.**" : 1}) box('handle_to_u_id', {"janecitizen" : 1}) box('reset_code_to_u_id', {"abcde" : 1}) auth_passwordreset_reset.auth_passwordreset_reset("abcde", NEW_PASSWORD) reset_code_to_u_id = unbox('reset_code_to_u_id', {}) user = unbox('users')['1'] assert not reset_code_to_u_id and user['password'] == NEW_HASH
def auth_register(email, password, name_first, name_last): email_to_u_id = unbox('email_to_u_id', {}) handle_to_u_id = unbox('handle_to_u_id', {}) users = unbox('users', {}) if not re.search('^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$', email): raise ValueError(f"Invalid email: '{email}'") if email in email_to_u_id: raise ValueError("Email already in use") if len(password) < 6: raise ValueError("Invalid password") if not (1 < len(name_first) < 50): raise ValueError("First name too short") if not (1 < len(name_last) < 50): raise ValueError("Last name too short") handle_str = name_first.lower() + name_last.lower() if len(handle_str) > 20: handle_str = handle_str[0:20] if handle_str in handle_to_u_id: handle_str = handle_str + str(len(handle_to_u_id)) u_id = 0 if not users else max([int(id) for id in users]) + 1 handle_to_u_id[handle_str] = u_id email_to_u_id[email] = u_id profile_img_url = unbox('url_base', '') + '/user/profiles/photo/default.jpg' users[str(u_id)] = { 'u_id': u_id, 'email': email, 'password': hashlib.sha256(password.encode()).hexdigest(), 'permission_id': 1 if u_id == 0 else 3, 'profile_img_url': profile_img_url, 'name_first': name_first, 'name_last': name_last, 'handle_str': handle_str } box('handle_to_u_id', handle_to_u_id) box('email_to_u_id', email_to_u_id) box('users', users) return auth_login.auth_login(email, password)
def test_channel_addowner_success(): box('tokens', [TOKEN]) box('users', { "1": { "u_id": 1, "permission_id": 1 }, "2": { "u_id": 2, "permission_id": 1 } }) box( 'channels', { "1": { 'channel_id': 1, 'name': "1st", 'is_public': True, 'all_members': [0, 1], 'owner_members': [0, 1] } }) channel_addowner.channel_addowner(TOKEN, 1, 2) channels = unbox('channels') assert 2 in channels["1"]['owner_members']
def test_message_react_success_1(): box('tokens', [TOKEN]) box('users', {"1": {"u_id": 1, "permission_id": 1}}) box( 'channels', { "1": { 'channel_id': 1, 'name': "1st", 'is_public': True, 'all_members': [1], 'owner_members': [1] } }) box( 'messages', { '0': { 'message_id': 0, 'channel_id': 1, 'u_id': 1, 'message': "hello, world!", 'time_created': time.asctime(), 'reacts': {}, 'is_pinned': False } }) message_react.message_react(TOKEN, 0, 1) messages = unbox('messages') assert messages['0']['reacts'] == {'1': {'react_id': 1, 'u_ids': [1]}}
def channels_listall(token): return { 'channels': [{ 'channel_id': c['channel_id'], 'name': c['name'] } for c in unbox('channels', {}).values()] }
def test_channel_leave_success_1(): box('tokens', [TOKEN]) box('users', { "1": { "u_id": 1, "permission_id": 1 }, "2": { "u_id": 2, "permission_id": 1 } }) box( 'channels', { "1": { 'channel_id': 1, 'name': "1st", 'is_public': True, 'all_members': [0, 1], 'owner_members': [0] } }) channel_leave.channel_leave(TOKEN, 1) channels = unbox('channels') assert 1 not in channels["1"]['all_members'] and 1 not in channels['1'][ 'owner_members']
def test_message_sendlater_success_1(): box('tokens', [TOKEN]) box('users', {"1": {"u_id": 1, "permission_id": 1}}) box( 'channels', { "1": { 'channel_id': 1, 'name': "1st", 'is_public': True, 'all_members': [1], 'owner_members': [1] } }) box('messages', {}) timmyboywontyoucomewithme = int(time.time()) + 3 assert message_sendlater.message_sendlater(TOKEN, 1, "Oh Boy", timmyboywontyoucomewithme) == { 'message_id': 0 } time.sleep(4) messages = unbox('messages') assert messages['0'] == { 'message_id': 0, 'channel_id': 1, 'u_id': 1, 'message': "Oh Boy", 'time_created': timmyboywontyoucomewithme, 'reacts': {}, 'is_pinned': False }
def test_user_profile_sethandle_success(): box('tokens', [TOKEN]) box('users', {"1": USER}) box('email_to_u_id', {"*****@*****.**": 1}) box('handle_to_u_id', {"janecitizen": 1}) user_profile_sethandle.user_profile_sethandle(TOKEN, "koolkid") users = unbox('users', {}) user = users['1'] handle_table = unbox('handle_to_u_id', {}) assert "koolkid" in handle_table and "janecitizen" not in handle_table assert handle_table["koolkid"] == 1 assert user['handle_str'] == "koolkid"
def channel_details(token, channel_id): users = unbox('users', {}) channels = unbox('channels', {}) auth = users[str(decode(token)['u_id'])] channel = channels[str(channel_id)] if auth['u_id'] not in channel['all_members']: raise AccessError("Unauthorised") return {'name' : channel['name'], 'owner_members': [{'u_id': u['u_id'], 'name_first': u['name_first'], 'name_last': u['name_last'], 'profile_img_url': u['profile_img_url']} for u in [users[str(id)] for id in channel['owner_members']]], 'all_members': [{'u_id': u['u_id'], 'name_first': u['name_first'], 'name_last': u['name_last'], 'profile_img_url': u['profile_img_url']} for u in [users[str(id)] for id in channel['all_members']]]}
def test_message_send_success_1(): box('tokens', [TOKEN]) box('users', {"1": {"u_id": 1, "permission_id": 1}}) box( 'channels', { "1": { 'channel_id': 1, 'name': "1st", 'is_public': True, 'all_members': [1], 'owner_members': [1] } }) box('messages', {}) assert message_send.message_send(TOKEN, 1, "Oh Boy") == {'message_id': 0} messages = unbox('messages') assert messages['0'] == { 'message_id': 0, 'channel_id': 1, 'u_id': 1, 'message': "Oh Boy", 'time_created': int(time.time()), 'reacts': {}, 'is_pinned': False }
def standup_active(token, channel_id): channel_id_to_time_finish = unbox('channel_id_to_time_finish', {}) is_active = (str(channel_id) in channel_id_to_time_finish) time_finish = None if not is_active else channel_id_to_time_finish[str( channel_id)] return {'is_active': is_active, 'time_finish': time_finish}
def message_remove(token, message_id): users = unbox('users', {}) channels = unbox('channels', {}) messages = unbox('messages', {}) auth = users[str(decode(token)['u_id'])] message = messages[str(message_id)] channel = channels[str(message['channel_id'])] if message['u_id'] != auth['u_id'] and auth['permission_id'] == 3 and auth[ 'u_id'] not in channel['owner_members']: raise AccessError("Unauthorised") del messages[str(message_id)] box('messages', messages) return {}
def _delay(token, channel_id): channel_id_to_time_finish = unbox('channel_id_to_time_finish', {}) channel_id_to_messages = unbox('channel_id_to_messages', {}) users = unbox('users', {}) message = "\n".join([ users[str(m['u_id'])]['handle_str'] + ': ' + m['message'] for m in channel_id_to_messages[str(channel_id)] ]) message_send.message_send(token, channel_id, message) del channel_id_to_time_finish[str(channel_id)] del channel_id_to_messages[str(channel_id)] box('channel_id_to_time_finish', channel_id_to_time_finish) box('channel_id_to_messages', channel_id_to_messages)
def channel_messages(token, channel_id, start): users = unbox('users', {}) channels = unbox('channels', {}) messages = unbox('messages', {}) auth = users[str(decode(token)['u_id'])] channel = channels[str(channel_id)] if auth['u_id'] not in channel['all_members']: raise AccessError("Unauthorised") messages = [{ 'message_id': m['message_id'], 'u_id': m['u_id'], 'time_created': m['time_created'], 'reacts': [{ 'react_id': r['react_id'], 'u_ids': r['u_ids'], 'is_this_user_reacted': (auth['u_id'] in r['u_ids']) } for r in m['reacts'].values()], 'is_pinned': m['is_pinned'], 'message': m['message'] } for m in sorted( [m for m in messages.values() if m['channel_id'] == channel_id], key=lambda k: k['time_created'])] count = len(messages) if start > count: raise ValueError("Requesting out of range messages") end = -1 if count - start < 50 else start + 50 return { 'messages': messages[start:] if end == -1 else messages[start:end - 1], 'start': start, 'end': end }
def channel_leave(token, channel_id): users = unbox('users', {}) channels = unbox('channels', {}) auth = users[str(decode(token)['u_id'])] channel = channels[str(channel_id)] if auth['u_id'] in channel['all_members']: channel['all_members'].remove(auth['u_id']) if auth['u_id'] in channel['owner_members']: channel['owner_members'].remove(auth['u_id']) channels[str(channel_id)] = channel box('channels', channels) return {}
def auth_passwordreset_request(email): email_to_u_id = unbox('email_to_u_id', {}) reset_code_to_u_id = unbox('reset_code_to_u_id', {}) if email not in email_to_u_id: raise ValueError(f"Invalid Email: '{email}'") reset_code = hashlib.sha256( (email + str(int(time.time()))).encode()).hexdigest()[:8] reset_code_to_u_id[reset_code] = email_to_u_id[email] box('reset_code_to_u_id', reset_code_to_u_id) mail( email, "Slackr: Password Reset", f"Please enter the following code to reset your password: {reset_code}" ) return {}
def user_profile(token, u_id): user = unbox('users', {})[str(u_id)] return { 'email': user['email'], 'name_first': user['name_first'], 'name_last': user['name_last'], 'handle_str': user['handle_str'], 'profile_img_url': user['profile_img_url'] }
def auth_logout(token): tokens = unbox('tokens', []) is_success = False if token in tokens: is_success = True tokens.remove(token) return {'is_success': is_success}
def test_auth_login_success(): box('tokens', []) box('users', {"1" : { "u_id": 1, "email": "*****@*****.**", 'password' : HASH } }) box('email_to_u_id', {"*****@*****.**" : 1}) junk = auth_login.auth_login("*****@*****.**", PASSWORD) tokens = unbox('tokens', []) assert junk['token'] in tokens
def users_all(token): return { 'users': [{ 'u_id': u['u_id'], 'email': u['email'], 'name_first': u['name_first'], 'name_last': u['name_last'], 'handle_str': u['handle_str'], 'profile_img_url': u['profile_img_url'] } for u in unbox('users', {}).values()] }
def auth_passwordreset_reset(reset_code, new_password): users = unbox('users', {}) reset_code_to_u_id = unbox('reset_code_to_u_id', {}) if reset_code not in reset_code_to_u_id: raise ValueError(f"Invalid reset code: '{reset_code}'") if len(new_password) < 6: raise ValueError("Invalid new password") user = users[str(reset_code_to_u_id[reset_code])] del reset_code_to_u_id[reset_code] user['password'] = hashlib.sha256(new_password.encode()).hexdigest() users[user['u_id']] = user box('reset_code_to_u_id', reset_code_to_u_id) box('users', users) return {}
def channel_join(token, channel_id): users = unbox('users', {}) channels = unbox('channels', {}) auth = users[str(decode(token)['u_id'])] channel = channels[str(channel_id)] if auth['u_id'] in channel['all_members']: raise ValueError("Already a member") if auth['permission_id'] == 3 and not channel['is_public']: raise AccessError("Unauthorised") channel['all_members'].append(auth['u_id']) channels[str(channel_id)] = channel box('channels', channels) return {}
def message_unpin(token, message_id): users = unbox('users', {}) channels = unbox('channels', {}) messages = unbox('messages', {}) auth = users[str(decode(token)['u_id'])] message = messages[str(message_id)] channel = channels[str(message['channel_id'])] if not message['is_pinned']: raise ValueError("Message is not pinned") if auth['permission_id'] == 3 and auth['u_id'] not in channel[ 'owner_members']: raise AccessError("Unauthorised") message['is_pinned'] = False messages[str(message_id)] = message box('messages', messages) return {}