def auth_register(email, password, first, last): global data check_email(email) if (len(password) <= 6): # if password is too short raise ValueError(description='Password too short') if (not (1 <= len(first) and len(first) <= 50) ): # if name is not between 1 and 50 characters long raise ValueError( description='first name must be between 1 and 50 characters long') if (not (1 <= len(last) and len(last) <= 50) ): # if name is not between 1 and 50 characters long raise ValueError( description='last name must be between 1 and 50 characters long') handle = first + last if len(handle) > 20: handle = handle[:20] curr = 0 new = 0 for acc in data['accounts']: if acc.email == email: # if email is already registered raise ValueError( description='email already matches an existing account') if acc.handle.startswith(first + last): # Checking exact name repetitions if handle == first + last: # If handle is base concantate case handle += '0' # Add zero on end else: # If NOT base case, take off number on end and add 1 new = int(acc.handle.split(first + last)[1]) + 1 if curr <= new: # If new number is larger replace handle = first + last + str(new) curr = new elif acc.handle == ( first + last )[:20]: # If name is truncate case and is already 20 characters handle += '0' if len( handle ) > 20: # If handle is too long make handle the hexadecimal number of account_count handle = hex(data['account_count']) user_id = data['account_count'] data['account_count'] += 1 handle.lower() token = jwt.encode({'email': email}, password, algorithm='HS256') token = token.decode('utf-8') data['accounts'].append( User(email, password, first, last, handle, token, user_id)) if user_id == 0: data['accounts'][user_id].perm_id = perm_owner return {'u_id': user_id, 'token': token}
def reset_reset(code, password): global data for acc in data['accounts']: if code == acc.reset_code: if len(password) >= 6: acc.password = password acc.reset_code = '' acc.token = '' return {} else: raise ValueError( description='password is too short (min length of 6)') raise ValueError(description='reset code is not valid')
def msg_unreact(token, msg_id, react_id): global data found_msg = find_msg(msg_id) if react_id != 1: raise ValueError(description='Invalid React ID!') elif reaction_exist(found_msg.reactions, react_id) == False: raise ValueError( description= f'This message does not contain an active React with the react ID: {react_id}!' ) # unreact the message if no exceptions raised found_msg.reactions.remove(reaction_exist(found_msg.reactions, react_id)) unreacter = user_from_token(token) unreacter.reacted_msgs.remove(msg_id) return {}
def msg_react(token, msg_id, react_id): global data reacter = user_from_token(token) found_msg = find_msg(msg_id) if react_id != 1: raise ValueError(description='Invalid React ID!') elif reaction_exist(found_msg.reactions, react_id) is not False: raise ValueError( description= f'This message already contains an active React with react ID: {react_id}!' ) # give the message a reaction if no exceptions raised found_msg.reactions.append(Reacts(reacter.u_id, react_id)) found_msg.reacted_user.append(reacter.u_id) reacter.reacted_msgs.append(msg_id) return {}
def send_later(token, msg, chan_id, sent_stamp): # get the number of second of the waiting interval for sending the msg later later_period = sent_stamp - time() if later_period <= 0: raise ValueError(description='Time sent is a value in the past!') # create a new thread apart from the main thread, while other function calls are still allowed send = Timer(later_period, msg_send, (token, msg, chan_id)) send.start()
def find_msg(msg_id): global data message_found = False for chan in data['channels']: for msg in chan.messages: if msg.message_id == msg_id: message_found = True return msg if message_found == False: raise ValueError(description='Message does not exists!')
def find_channel(chan_id): global data channel_found = False for chan in data['channels']: if chan.channel_id == chan_id: channel_found = True return chan if channel_found == False: raise ValueError( description= 'Channel does not exit, please join or create a channel first!')
def msg_unpin(token, msg_id): global data unpinner = user_from_token(token) found_msg = find_msg(msg_id) msg_channel = find_channel(found_msg.in_channel) if check_channel_member(msg_channel, unpinner.u_id) == False: raise AccessError( description= 'You can not unpin the message as you are not a member of the channel' ) elif found_msg.is_pinned == False: raise ValueError(description='The message is already unpinned!') elif not check_slackr_admin(unpinner): raise ValueError( description= 'You can not unpin the message as you are not an Admin of the channel' ) # unpin the message if no exceptions raised found_msg.is_pinned = False return {}
def channel_messages(token, channel_id, start): global data # get the current user curr_user = user_from_token(token) # raise ValueError if channel_id doesn't exist (channel_index) index = channel_index(channel_id) # raise AccessError if authorised user isn't in channel if curr_user.u_id not in data['channels'][index].members: raise AccessError(description = 'authorised user is not in channel') # raise ValueError if start is greater than no. of total messages no_total_messages = len(data['channels'][index].messages) if start > no_total_messages: raise ValueError(description = 'start is greater than no. of total messages') end = -1 list_messages = [] i = start for item in data['channels'][index].messages[i:]: message = {} message['message_id'] = item.message_id message['u_id'] = item.sender message['message'] = item.message message['time_created'] = item.create_time message['is_pinned'] = item.is_pinned message['reacts'] = [] for react in item.reactions: reacter_list = [] reacter_list.append(react.reacter) message['reacts'].append({'react_id': react.react_id, 'u_ids': reacter_list, 'is_this_user_reacted': (curr_user.u_id in item.reacted_user)}) i = i + 1 list_messages.append(message) if i == no_total_messages: end = -1 break if i == (start + 50): end = i break return { 'messages': list_messages, 'start': start, 'end': end }
def auth_login(email, password): global data valid = False i = 0 check_email(email) for counter, acc in enumerate(data['accounts']): if acc.email == email and acc.password == password: i = counter user_id = acc.u_id valid = True if (not (valid)): raise ValueError( description='email and/or password does not match any account') token = jwt.encode({'email': email}, password, algorithm='HS256') data['accounts'][i].token = token.decode('utf-8') return {'u_id': user_id, 'token': token.decode('utf-8')}
def route_user_profile_uploadphoto(): token = request.form.get("token") img_url = request.form.get("img_url") response = requests.get(img_url) # Check if valid url if response.status_code != 200: raise ValueError( description='HTTP status other than 200 returned from img_url') x_start = int(request.form.get("x_start")) y_start = int(request.form.get("y_start")) x_end = int(request.form.get("x_end")) y_end = int(request.form.get("y_end")) host = request.host_url return dumps( user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end, host))
def channel_add_owner(token, channel_id, u_id): global data # raise ValueError if channel_id doesn't exist (channel_index) index = channel_index(channel_id) # check if user with u_id is already owner if user_from_uid(u_id).u_id in data['channels'][index].owners: raise ValueError(description = 'User with u_id is already an owner') # check if authorised user is an owner of this channel if user_from_token(token).u_id not in data['channels'][index].owners: raise AccessError(description = 'Authorised user not an owner of this channel') data['channels'][index].owners.append(u_id) return {}
def channel_remove_owner(token, channel_id, u_id): global data # raise ValueError if channel_id doesn't exist (channel_index) index = channel_index(channel_id) # raise ValueError if u_id is not an owner if u_id not in data['channels'][index].owners: raise ValueError(description = 'u_id is not an owner of the channel') # raise AccessError if token is not an owner of this channel if user_from_token(token).u_id not in data['channels'][index].owners: raise AccessError(description = 'authorised user is not an owner of this channel') data['channels'][index].owners.remove(u_id) return {}
def msg_send(token, msg, chan_id): global data sending_time = datetime.now().replace(tzinfo=timezone.utc).timestamp() sender = user_from_token(token) current_channel = find_channel(chan_id) if len(msg) > 1000: raise ValueError(description='Message is more than 1000 words!') elif check_channel_member(current_channel, sender.u_id) == False: raise AccessError( description= 'You have not joined this channel yet, please join first!') else: # generate an unique id data['message_count'] += 1 msg_id = data['message_count'] # no exceptions raised, then add(send) the message to the current channel current_channel.messages.insert( 0, Mesg(sender.u_id, sending_time, msg, msg_id, chan_id, False)) return {'message_id': msg_id}
def channels_create(token, name, is_public): global data if max_20_characters(name) == False: raise ValueError(description = 'name is more than 20 characters') channel_id = data['channel_count'] data['channel_count'] += 1 data['channels'].append(Channel(name, is_public, channel_id)) index = channel_index(channel_id) acct = user_from_token(token) acct = data['accounts'][0] data['channels'][index].owners.append(acct.u_id) data['channels'][index].members.append(acct.u_id) # add channel to user's list of channels acct.in_channel.append(channel_id) return { 'channel_id': channel_id }
def msg_edit(token, msg_id, new_msg): global data editor = user_from_token(token) found_msg = find_msg(msg_id) msg_channel = find_channel(found_msg.in_channel) # iter3 update: if the new msg is empty, delete the message if new_msg == '': msg_remove(token, msg_id) elif len(new_msg) > 1000: raise ValueError(description='Message is more than 1000 words!') elif found_msg.sender != editor.u_id: raise AccessError( description= 'You do not have the permission to edit this message as you are not the sender!' ) elif not check_channel_owner(msg_channel, editor.u_id): raise AccessError( description= 'You do not have the permission as you are not the owner or admin of this channel or Slackr!' ) # edit the message if no exceptions raiseds found_msg.message = new_msg return {}
def channel_index(channel_id): global data for i, chan in enumerate(data['channels']): if int(chan.channel_id) == int(channel_id): return i raise ValueError(description='channel does not exist')
def check_email(email): regex = '^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$' if (not (re.search(regex, email))): # if not valid email raise ValueError(description='not a valid email') return