def decorated_f(*args, **kwargs): try: auth_header = request.headers['Authorization'] token = auth_header.split(" ")[1] auth.verify_token(token) except (KeyError, IndexError, jwt.InvalidTokenError): # invalid token return {'message': 'Access denied'}, 403 # valid token, continue to route return f(*args, **kwargs)
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 get_player(tag): key = app.config['SECRET_KEY'] token = request.headers['Authorization'].split('Bearer ')[1] if token is None or check_token(token, key) is False or verify_token( token, key) is False: return "Not authorized", 403 return get_individual_info(fetch_player_by_tag(tag))
def handle_request(request): request_type = request.path_info.replace('/', '') if request_type not in routes: print "Cannot find request handler: " + request_type return HttpResponseNotFound('404 not found') route = routes[request_type] print "Request " + request_type if request.FILES: params = request.POST.copy() params['file'] = request.FILES else: params = parse_body(request) if route.requires_auth: if 'HTTP_AUTHORIZATION' not in request.META: return HttpResponse( json.dumps({ 'result': False, 'message': 'Missing Auth Token' })) username = auth.verify_token(request.META['HTTP_AUTHORIZATION']) if username is None: return HttpResponse( json.dumps({ 'result': False, 'message': 'Invalid Token' })) params['username'] = username response = route.handler(params) return HttpResponse(json.dumps(response))
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 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 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 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 test(): token = request.get_data() jsonRequest = json.loads(token) if auth.verify_token(jsonRequest.get('accessToken')) == 1: return 'token success', 200 else: return 'token error', 402
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 user_profile(token, u_id): ''' Returns profile information about the specified user; specifically, u_id, email, name_first, name_last, handle_str, profile_img_url Args: token (str): of the user authorising this action u_id (int): user ID of the user whose profile information is being sought Raises: AccessError: if token is invalid Returns: dictionary: a dictionary containing the 'user' dictionary, which contains u_id, email, name_first, name_last, handle_str, profile_img_url ''' # check validity of user's token if verify_token(token) is False: raise AccessError(description="Invalid token") # check that the u_id of the user whose information the authorised user # wants to access is valid data = get_store() return {'user': data.users.user_details(u_id)}
def groupstate(authtoken): """Calculates the groups state, and returns it as a json-string""" group = auth.verify_token(authtoken) if group is None: return None database = sqlite3.connect('database.sqlite3') status = database.execute( ('SELECT count(),' ' strftime("%s", datetime(min(submittime), "+10 minute"))' ' FROM badkeys WHERE' ' groupname=:groupname AND ' ' submittime > datetime("now", "-10 minute")'), { "groupname": group }).fetchone() returnvalue = { "group": group, "points": get_all_points(), "remain_guess": 3 - status[0], "time_to_new_guess": int(status[1]) if (type(status[1]) == str) else None } return json.dumps(returnvalue)
def claim_share_qr(authtoken): groupinfo = auth.verify_token(request, extra_data=True) if groupinfo is None: raise HTTPError("Bad Authtoken") newtoken = auth.create_authtoken(groupinfo["name"], generate_time=groupinfo["authtime"]) return newtoken
def is_token_valid(): incoming = request.get_json() is_valid = verify_token(incoming["token"]) if is_valid: return jsonify(token_is_valid=True) else: return jsonify(token_is_valid=False), 403
def API_add_note(): user_id = int(verify_token(request.form["token"])) note = Notes(user_id=user_id, title=request.form['title'], note=request.form["note"]) push_model(note) return json.dumps({"state": "ok"})
def API_get_notes(): user_id = int(verify_token(request.form["token"])) notes = [] notes_iterator = get_session().query(Notes).filter_by( user_id=user_id).all() for note in notes_iterator: notes.append({"title": note.title, "message": note.note}) return json.dumps({"state": "ok", "notes": notes})
def API_logout(): user_id = verify_token(request.form["token"]) if (user_id is None): return json.dumps({"state": "error", "message": "Invalid token"}) remove_token(request.form["token"]) session.pop('token', None) return json.dumps({"state": "ok", "message": ""})
def API_add_visit(): user_id = int(verify_token(request.form["token"])) visit = Visit(scheduled_for=dateutil.parser.parse(request.form["date"]), note=request.form["title"], user_id=user_id) push_model(visit) return json.dumps({"state": "ok"})
def API_hello(): user_id = int(verify_token(request.form["token"])) print("api: hello->user_id is: " + str(user_id)) should_mood_update = False mood_value = None moods = [] has_upcoming_visit = False upcoming_visit_date = None user = get_session().query(User).filter_by(id=user_id).all()[0] try: # TODO: Make this line shorter latest_seven_moods = get_session().query(Mood).filter_by( user_id=user_id).order_by(desc(Mood.created_at)).limit(7).all() latest_mood = latest_seven_moods[0] if latest_mood.created_at < datetime.datetime.now( ) - datetime.timedelta(hours=24): should_mood_update = True for mood in latest_seven_moods: moods.append({ "value": mood.mood, "time": mood.created_at.isoformat() }) mood_value = latest_mood.mood next_visits = get_session().query(Visit).filter_by( user_id=user_id).order_by(desc( Visit.scheduled_for)).limit(1).all() if len(next_visits) > 0: next_visit = next_visits[0] if next_visit.scheduled_for > datetime.datetime.now( ) - datetime.timedelta(hours=24): has_upcoming_visit = True upcoming_visit_date = next_visit.scheduled_for.isoformat() except Exception as inst: should_mood_update = True print("api: Error happened in /api/hello - " + str(inst)) avatar_hash = hashlib.md5(user.email.encode()) return json.dumps({ "update_mood": should_mood_update, "latest_mood_value": mood_value, "moods": moods, "fullname": user.fullname, "avatar_hash": avatar_hash.hexdigest(), "has_upcoming_visit": has_upcoming_visit, "next_upcoming_visit": upcoming_visit_date })
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 authorized(self): token = self.get_token() if token is None: log.error("Request not authorized, no token provided") return False try: result = auth.verify_token(token) except Exception: log.exception("Request not authorized, exception raised") return False return result
def API_get_moods(): user_id = int(verify_token(request.form["token"])) moods = [] latest_moods = get_session().query(Mood).filter_by( user_id=user_id).order_by(desc(Mood.created_at)).limit( int(request.form["timeperiod"])).all() for mood in latest_moods: moods.append({"value": mood.mood, "time": mood.created_at.isoformat()}) return json.dumps({"state": "ok", "moods": moods})
def submitkey(authtoken, key): """Verifies a key, and submits it. Returns the groups status""" group = auth.verify_token(authtoken) if group is None: raise HTTPError("Invalid Authtoken, please relogin", 401) group_status = json.loads(groupstate(authtoken)) if int(group_status['remain_guess']) < 1: raise HTTPError(groupstate(authtoken), 403) key = cleanstring(key) database = sqlite3.connect('database.sqlite3') submitted = database.execute(('SELECT count() FROM claims' ' WHERE groupname=:groupname AND key=:key'), { "groupname": group, "key": key }).fetchone()[0] if submitted != 0: raise HTTPError(groupstate(authtoken), 410) badkey = database.execute(('SELECT count() FROM badkeys' ' WHERE groupname=:groupname AND key=:key'), { "groupname": group, "key": key }).fetchone()[0] if badkey != 0: raise HTTPError(groupstate(authtoken), 410) keyexist = database.execute( 'SELECT count() FROM keys WHERE LOWER(key)=:key', { 'key': key }).fetchone()[0] if keyexist == 0: database.execute( 'INSERT INTO badkeys(groupname, key) values(:groupname, :key)', { 'groupname': group, 'key': key }) database.commit() raise HTTPError(groupstate(authtoken), 400) database.execute( 'INSERT INTO claims(groupname, key) values(:groupname, :key)', { 'groupname': group, 'key': key }) database.commit() return groupstate(authtoken)
def API_get_visits(): user_id = int(verify_token(request.form["token"])) visits = [] visits_iterator = get_session().query(Visit).filter_by( user_id=user_id).all() for visit in visits_iterator: visits.append({ "date": visit.scheduled_for.isoformat(), "note": visit.note }) return json.dumps({"state": "ok", "visits": visits})
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 users_all(token): ''' Lists all users on the slackr Args: token (str) Raises: AccessError if token is invalid Returns: a dictionary containing a list of all users and their associated details - u_id, email, name_first, name_last, handle_str ''' # verify the token is valid if verify_token(token) is False: raise AccessError(description="invalid token") # return a dictionary which contains one key, "users", which is itself a list of dictionaries # containing types u_id, email, name_first, name_last, handle_str data = get_store() return {"users": data.users.all()}
def channels_listall(token): ''' Provides users with details of all channels existing in Slackr Parameter: token Returns: list of ALL channels in Slackr ''' # verify the user if verify_token(token) is False: raise AccessError(description='Invalid token') # get database data = get_store() # return all existing channels all_channels = data.channels.all() return { 'channels': all_channels }