예제 #1
0
def children_get_delete(child_id):
	if request.method == 'GET':
		verify_content_type(request)
		payload = verify_jwt(request)
		
		child_key = client.key('children', int(child_id))
		single_child = client.get(key=child_key)
		
		# If child does not exist, else return child information
		if single_child == None:
			return json.dumps({"Error": "No child with this child_id exists."}), 404, {'Content-Type':'application/json'} 
		
		# If jwt is not user for child, return error
		if single_child['user_id'] != payload['sub']:
			return json.dumps({'Error': 'You do not have authorization to view this child.'}), 401, {'Content-Type':'application/json'}
				
		single_child['id'] = child_id
		return json.dumps(single_child), 200, {'Content-Type':'application/json'} 
	elif request.method == 'DELETE':
		verify_content_type(request)
		payload = verify_jwt(request)
		
		child_key = client.key('children', int(child_id))
		single_child = client.get(key=child_key)
		
		# If child does not exist, else return child information
		if single_child == None:
			return json.dumps({"Error": "No child with this child_id exists."}), 404, {'Content-Type':'application/json'} 
		
		# If jwt is not user for child, return error
		if single_child['user_id'] != payload['sub']:
			return json.dumps({'Error': 'You do not have authorization to view this child.'}), 401, {'Content-Type':'application/json'}
		
		# If child exists, remove child information from milestones
		for element in single_child['milestones_assigned']:
			milestone_key = client.key('milestones', int(element['id']))
			single_milestone = client.get(key=milestone_key)
			single_milestone['children_id_assigned'].remove(int(child_id))
			client.put(single_milestone)
		
		# Remove child from user list in users entity
		query = client.query(kind='users')
		query.add_filter('user_id', '=', payload['sub'])
		single_user = list(query.fetch())[0]
			
		# Make sure user exists
		if single_user == None:
			return jsonify({"Error": "No user with this user_id exists."}), 404, {'Content-Type':'application/json'} 

		single_user['children'].remove({
			'child_id': int(child_id),
			'self': request.base_url
			}
		)
		
		client.put(single_user)
		
		client.delete(child_key)
		return {}, 204, {'Content-Type':'application/json'} 
예제 #2
0
def get_childs_from_milestone(child_id):
	if request.method == 'GET':
		verify_content_type(request)
		payload = verify_jwt(request)
		
		child_key = client.key('children', int(child_id))
		single_child = client.get(key=child_key)
		
		# If no milestone with id
		if not single_child:
			return json.dumps({'Error': 'No child with this child_id exists.'}), 404, {'Content-Type':'application/json'}
			
		# If jwt is not user for child, return error
		if single_child['user_id'] != payload['sub']:
			return json.dumps({'Error': 'You do not have authorization to view this child.'}), 401, {'Content-Type':'application/json'}
		
		results = []
		
		# Get all milestones information assigned to child
		for milestone in single_child['milestones_assigned']:
			milestone_key = client.key('milestones', int(milestone['id']))
			single_milestone = client.get(key=milestone_key)
			single_milestone['id'] = milestone['id']
			results.append(single_milestone)
			
		return json.dumps(results), 200, {'Content-Type':'application/json'}
예제 #3
0
def userid_icebergs_valid(user_id):
    if request.method == "GET":
        if "application/json" not in request.accept_mimetypes:
            # Failure 406 Not Acceptable
            return status_fail(406, ERR.WRONG_MEDIA_REQUESTED)

        # Display Icebergs with pagination
        user = verify_jwt()
        query = client.query(kind=ICEBERGS)
        query.add_filter("founder", "=", user_id)

        if user == "Error":
            # Return public Icebergs only
            query.add_filter("public", "=", True)

        # Set limit, offset, and iterator
        q_limit = int(request.args.get("limit", 5))
        q_offset = int(request.args.get("offset", 0))
        iterator = query.fetch(limit=q_limit, offset=q_offset)
        results = list(next(iterator.pages))

        if iterator.next_page_token:
            next_offset = q_offset + q_limit
            next_url = (request.base_url + "?limit=" + str(q_limit) +
                        "&offset=" + str(next_offset))
        else:
            next_url = None

        for i in results:
            i["id"] = i.id
            i["self"] = request.url_root + "icebergs/" + str(i.id)

        output = {"icebergs": results}
        if next_url:
            output["next"] = next_url
            return status_success(200,
                                  output=json.dumps(output),
                                  page=next_url)

        # Success 200 OK
        return status_success(200, output=json.dumps(output))

    else:
        # Failure 405 Method Not Allowed
        userid_icebergs_invalid()
예제 #4
0
    def get(self):
        """ takes the jwt and decodes it returning the payload """
        auth_token = request.headers.get('Authorization')
        if not auth_token:
            return {'error': 'no token'}

        # strip out the Bearer part of the token.
        auth_token = str(auth_token).replace('Bearer ', '')

        try:
            payload = verify_jwt(auth_token)
            return {
                'token': auth_token,
                'payload': payload,
            }
        except (jwt.ExpiredSignatureError, jwt.InvalidTokenError) as e:
            app.logger.exception(e)
            return {
                'error': f"{type(e).__name__}:{str(e)}",
                'payload': jwt.decode(auth_token.encode(), verify=False)
            }
예제 #5
0
def children_add_remove_milestone(milestone_id, child_id):
	if request.method == 'PUT':
		verify_content_type(request)
		payload = verify_jwt(request)
		
		milestone_key = client.key('milestones', int(milestone_id))
		single_milestone = client.get(key=milestone_key)
		
		child_key = client.key('children', int(child_id))
		single_child = client.get(key=child_key)
		
		# Check if milestone or child do not exist
		if not single_milestone or not single_child:
			return json.dumps({'Error': 'The specified milestone and/or child does not exist.'}), 404, {'Content-Type':'application/json'}
		
		# If the milestone is already assigned to a child
		for element in single_child['milestones_assigned']:
			if single_milestone.key.id == element['id']:
				return json.dumps({'Error': 'This milestone is already assigned to the child.'}), 403, {'Content-Type':'application/json'}
		
		# Add milestone information to child and add to database
		single_child['milestones_assigned'].append({
			'id': int(milestone_id),
			'self': single_milestone['self']
		})
		
		client.put(single_child)
		
		single_milestone['children_id_assigned'].append(int(child_id))
		
		client.put(single_milestone)
		
		return {}, 204, {'Content-Type':'application/json'}
	elif request.method == 'DELETE':
		verify_content_type(request)
		payload = verify_jwt(request)
		
		milestone_key = client.key('milestones', int(milestone_id))
		single_milestone = client.get(key=milestone_key)
		
		child_key = client.key('children', int(child_id))
		single_child = client.get(key=child_key)
		
		# Check if milestone or child does not exist
		if not single_milestone or not single_child:
			return json.dumps({'Error': 'The specified milestone and/or child does not exist.'}), 404, {'Content-Type':'application/json'}
		
		# If jwt is not user for child, return error
		if single_child['user_id'] != payload['sub']:
			return json.dumps({'Error': 'You do not have authorization to view this child.'}), 401, {'Content-Type':'application/json'}
			
		# If the milestone is not assigned to this child
		if int(child_id) not in single_milestone['children_id_assigned']:
			return json.dumps({'Error': 'No milestone with this milestone_id is assigned to the child with this child_id.'}), 404, {'Content-Type': 'application/json'}
		
		# Delete milestone from child
		single_child['milestones_assigned'].remove({
			'id': int(milestone_id),
			'self': single_milestone['self']
		})
		
		client.put(single_child)

		# Remove children assigned
		single_milestone['children_id_assigned'].remove(int(child_id))
		
		client.put(single_milestone)
		
		return {}, 204, {'Content-Type':'application/json'}
예제 #6
0
def children_get_post():
	if request.method == 'GET':
		verify_content_type(request)
		payload = verify_jwt(request)
		
		if not payload:
			return json.dumps([]), 200, {'Content-Type':'application/json'} 
		
		query = client.query(kind='children')
		
		# Setting pagination 
		q_limit = 5
		q_offset = int(request.args.get('offset', '0'))
		l_iterator = query.fetch(limit = q_limit, offset = q_offset)

		# Get pages variable and list of children
		pages = l_iterator.pages
		all_children = list(next(pages))
		
		# If more children are on next page set next_url, else no more pages
		if l_iterator.next_page_token:
			next_offset = q_offset + q_limit
			next_url = request.base_url + "?offset=" + str(next_offset)
		else:
			next_url = None
		
		# Set id for each milestone\
		all_children = [e for e in all_children if e['user_id'] == payload['sub']]

		for e in all_children:
			e["id"] = e.key.id
		
		# Format children appropriately 
		all_children_formatted = {
			"children": all_children
		}

		# Set next_url if is not None
		if next_url:
			all_children_formatted['next'] = next_url

		return json.dumps(all_children_formatted), 200, {'Content-Type':'application/json'} 
	elif request.method == 'POST':
		verify_content_type(request)		
		payload = verify_jwt(request)

		body = request.get_json()

		child_required_headers = ['first_name', 'gender', 'birthday']
		
		if not set(child_required_headers).issubset(body.keys()):
			return json.dumps({'Error': 'The request object is missing at least one of the required attributes.'}), 400, {'Content-Type':'application/json'}  
		
		# Set up entity and add to client
		new_child = datastore.Entity(key=client.key('children'))
		new_child.update({
			'first_name': body['first_name'],
			'gender': body['gender'],
			'birthday': body['birthday'],
			'user_id': payload['sub'],
			'milestones_assigned': []
		})
		client.put(new_child)
		
		# Update with self url and return with id
		new_child.update({
			'self': request.base_url + '/' + str(new_child.key.id)
		})
		client.put(new_child)
		
		new_child['id'] = new_child.key.id
		
		# Add child to user account in entity
		query = client.query(kind='users')
		query.add_filter('user_id', '=', payload['sub'])
		single_user = list(query.fetch())[0]
			
		# Make sure user exists
		if single_user == None:
			return jsonify({"Error": "No user with this user_id exists."}), 404, {'Content-Type':'application/json'} 
		
		single_user['children'].append({
			'child_id': new_child.key.id,
			'self': request.base_url + '/' + str(new_child.key.id)
			})
		
		client.put(single_user)
		
		return json.dumps(new_child), 201, {'Content-Type':'application/json'} 
	else:
		return json.dumps({'Error': 'This API does not support this operation.'}), 405, {'Content-Type': 'application/json'}
예제 #7
0
def icebergid_animals_animalid_valid(iceberg_id, animal_id):
    iceberg_key = client.key(ICEBERGS, int(iceberg_id))
    animal_key = client.key(ANIMALS, int(animal_id))
    iceberg = client.get(key=iceberg_key)
    animal = client.get(key=animal_key)

    # Check if Iceberg and Animal exist
    if iceberg is None:
        if animal is None:
            return status_fail(404, ERR.NEITHER_EXISTS)
        return status_fail(404, ERR.NO_ICEBERG)
    if animal is None:
        return status_fail(404, ERR.NO_ANIMAL)

    # Verify user
    user = verify_jwt()
    if user == "Error":
        return status_fail(401, ERR.UNAUTHORIZED)

    # Put an Animal on an Iceberg
    if request.method == "PUT":
        # Check media type
        if "application/json" not in request.content_type:
            # Failure 415 Unsupported Media Type
            return status_fail(415, ERR.WRONG_MEDIA_RECEIVED)

        if animal["home"] is None:
            animal.update({"home": str(iceberg.id)})
        else:
            return status_fail(400, ERR.ANIMAL_ASSIGNED)

        # Add Animal to Iceberg
        if iceberg["inhabitants"] is None:
            iceberg["inhabitants"] = [str(animal.id)]
        else:
            iceberg["inhabitants"].append(str(animal.id))

        client.put(iceberg)
        client.put(animal)

        # Success 303 See Other
        output = iceberg_output(iceberg, client)
        return status_success(303,
                              output=json.dumps(output),
                              location=output["self"])

    # Remove an Animal from an Iceberg
    elif request.method == "DELETE":
        if iceberg["inhabitants"] is None:
            return status_fail(404, ERR.NO_ANIMAL_HERE)

        if "inhabitants" in iceberg.keys():
            if str(animal_id) in iceberg["inhabitants"]:
                iceberg["inhabitants"].remove(str(animal_id))
                if len(iceberg["inhabitants"]) == 0:
                    iceberg["inhabitants"] = None
                animal["home"] = None
                client.put(iceberg)
                client.put(animal)
            else:
                return status_fail(404, ERR.NO_ANIMAL_HERE)

        # Success 204 No Content
        return status_success(204)

    else:
        # Failure 405 Method Not Allowed
        icebergid_animals_animalid_invalid()
예제 #8
0
def icebergs_valid():
    # Create an Iceberg
    if request.method == "POST":
        # Verify user
        user = verify_jwt()
        if user == "Error":
            return status_fail(401, ERR.UNAUTHORIZED)

        # Check media type
        if "application/json" not in request.content_type:
            # Failure 415 Unsupported Media Type
            return status_fail(415, ERR.WRONG_MEDIA_RECEIVED)
        if "application/json" not in request.accept_mimetypes:
            # Failure 406 Not Acceptable
            return status_fail(406, ERR.WRONG_MEDIA_REQUESTED)

        # Check if request is missing any of the required attributes
        content = request.get_json()
        if ("name" not in content.keys() or "area" not in content.keys()
                or "shape" not in content.keys()
                or "public" not in content.keys()):
            # Failure 400 Bad Request
            return status_fail(400, ERR.MISSING_ATTRIBUTE)

        # Validate request
        if not valid_alphanum(content["name"], 50):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_NAME)
        if not valid_int(content["area"], 8000):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_AREA)
        if not valid_shape(content["shape"]):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_SHAPE)
        if not valid_public(content["public"]):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_PUBLIC)

        # Ensure that the name of an Iceberg is unique across all Icebergs
        query = client.query(kind=ICEBERGS)
        results = list(query.fetch())
        for i in results:
            if i["name"] == content["name"]:
                # Failure 403 Forbidden
                return status_fail(403, ERR.NAME_EXISTS)

        # Update Iceberg
        iceberg = datastore.Entity(key=client.key(ICEBERGS))
        iceberg.update({
            "name": content["name"],
            "area": content["area"],
            "shape": content["shape"],
            "inhabitants": None,
            "public": content["public"],
            "founder": user
        })
        client.put(iceberg)

        # Success 201 Created
        output = iceberg_output(iceberg, client)
        return status_success(201,
                              output=json.dumps(output),
                              location=output["self"])

    # List all Icebergs
    elif request.method == "GET":
        if "application/json" not in request.accept_mimetypes:
            # Failure 406 Not Acceptable
            return status_fail(406, ERR.WRONG_MEDIA_REQUESTED)

        # Display Icebergs with pagination
        query = client.query(kind=ICEBERGS)
        user = verify_jwt()

        if user == "Error":
            # Return all public Icebergs
            query = query.add_filter("public", '=', True)
        else:
            # Return all Icebergs whose founder matches the user
            query = query.add_filter("founder", '=', user)

        # Set limit, offset, and iterator
        q_limit = int(request.args.get("limit", 5))
        q_offset = int(request.args.get("offset", 0))
        iterator = query.fetch(limit=q_limit, offset=q_offset)
        results = list(next(iterator.pages))

        if iterator.next_page_token:
            next_offset = q_offset + q_limit
            next_url = (request.base_url + "?limit=" + str(q_limit) +
                        "&offset=" + str(next_offset))
        else:
            next_url = None

        for i in results:
            i["id"] = i.id
            i["self"] = request.url_root + "icebergs/" + str(i.id)

        output = {"icebergs": results}
        if next_url:
            output["next"] = next_url
            return status_success(200,
                                  output=json.dumps(output),
                                  page=next_url)

        # Success 200 OK
        return status_success(200, output=json.dumps(output))

    else:
        # Failure 405 Method Not Allowed
        icebergs_invalid()
예제 #9
0
def icebergid_valid(iceberg_id):
    iceberg_key = client.key(ICEBERGS, int(iceberg_id))
    iceberg = client.get(key=iceberg_key)

    # No Iceberg with this iceberg_id exists
    if iceberg is None:
        # Failure 404 Not Found
        return status_fail(404, ERR.NO_ICEBERG)

    # Verify user
    user = verify_jwt()
    if user == "Error":
        return status_fail(401, ERR.UNAUTHORIZED)

    # Get an Iceberg
    if request.method == "GET":
        if iceberg["founder"] != user and iceberg["public"] is False:
            return status_fail(403, ERR.NO_PERMISSION)

        if "application/json" in request.accept_mimetypes:
            # Success 200 OK
            output = iceberg_output(iceberg, client)
            return status_success(200, output=json.dumps(output))
        elif "text/html" in request.accept_mimetypes:
            # Success 200 OK
            output = iceberg_output(iceberg, client)
            conversion = json2html.convert(json=json.dumps(output))
            return status_success(200, output=conversion, mime="text/html")
        else:
            # Failure 406 Not Acceptable
            return status_fail(406, ERR.WRONG_MEDIA_REQUESTED)

    # Edit an Iceberg
    elif request.method == "PUT":
        if iceberg["founder"] != user:
            return status_fail(403, ERR.NO_PERMISSION)

        # Check media type
        if "application/json" not in request.content_type:
            # Failure 415 Unsupported Media Type
            return status_fail(415, ERR.WRONG_MEDIA_RECEIVED)
        if "application/json" not in request.accept_mimetypes:
            # Failure 406 Not Acceptable
            return status_fail(406, ERR.WRONG_MEDIA_REQUESTED)

        # Check if request is missing any of the required attributes
        content = request.get_json()
        if ("name" not in content.keys() or "area" not in content.keys()
                or "shape" not in content.keys()
                or "public" not in content.keys()):
            # Failure 400 Bad Request
            return status_fail(400, ERR.MISSING_ATTRIBUTE)

        # Validate request
        if not valid_alphanum(content["name"], 50):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_NAME)
        if not valid_int(content["area"], 8000):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_AREA)
        if not valid_shape(content["shape"]):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_SHAPE)
        if not valid_public(content["public"]):
            # Failure 400 Bad Request
            return status_fail(400, ERR.INVALID_PUBLIC)

        # Ensure that the name of an Iceberg is unique across all Icebergs
        query = client.query(kind=ICEBERGS)
        results = list(query.fetch())
        for i in results:
            if i["name"] == content["name"]:
                # Failure 403 Forbidden
                return status_fail(403, ERR.NAME_EXISTS)

        # Update Iceberg
        iceberg.update({
            "name": content["name"],
            "area": content["area"],
            "shape": content["shape"],
            "public": content["public"]
        })
        client.put(iceberg)

        # Success 303 See Other
        output = iceberg_output(iceberg, client)
        return status_success(303,
                              output=json.dumps(output),
                              location=output["self"])

    # Edit an Iceberg
    elif request.method == "PATCH":
        if iceberg["founder"] != user:
            return status_fail(403, ERR.NO_PERMISSION)

        # Check media type
        if "application/json" not in request.content_type:
            # Failure 415 Unsupported Media Type
            return status_fail(415, ERR.WRONG_MEDIA_RECEIVED)
        if "application/json" not in request.accept_mimetypes:
            # Failure 406 Not Acceptable
            return status_fail(406, ERR.WRONG_MEDIA_REQUESTED)

        # Check if request contains any of the object attributes
        content = request.get_json()
        if "name" in content.keys():
            # Validate name
            if not valid_alphanum(content["name"], 50):
                # Failure 400 Bad Request
                return status_fail(400, ERR.INVALID_NAME)
            # Ensure that the name of an Iceberg is unique across all Icebergs
            query = client.query(kind=ICEBERGS)
            results = list(query.fetch())
            for i in results:
                if i["name"] == content["name"]:
                    # Failure 403 Forbidden
                    return status_fail(403, ERR.NAME_EXISTS)
            iceberg.update({"name": content["name"]})
        if "area" in content.keys():
            # Validate area
            if not valid_int(content["area"], 8000):
                # Failure 400 Bad Request
                return status_fail(400, ERR.INVALID_AREA)
            iceberg.update({"area": content["area"]})
        if "shape" in content.keys():
            # Validate shape
            if not valid_shape(content["shape"]):
                # Failure 400 Bad Request
                return status_fail(400, ERR.INVALID_SHAPE)
            iceberg.update({"shape": content["shape"]})
        if "public" in content.keys():
            # Validate public
            if not valid_public(content["public"]):
                # Failure 400 Bad Request
                return status_fail(400, ERR.INVALID_PUBLIC)
            iceberg.update({"public": content["public"]})
        client.put(iceberg)

        # Success 303 See Other
        output = iceberg_output(iceberg, client)
        return status_success(303,
                              output=json.dumps(output),
                              location=output["self"])

    # Delete an Iceberg
    elif request.method == "DELETE":
        # JWT is valid but iceberg_id is founded by someone else
        if iceberg["founder"] != user:
            return status_fail(403, ERR.NO_PERMISSION)

        # Remove Animals from Iceberg if applicable
        query = client.query(kind=ANIMALS)
        results = list(query.fetch())
        for a in results:
            if a["home"] == iceberg_id:
                a.update({"home": None})
                client.put(a)

        # Success 204 No Content
        client.delete(iceberg_key)
        return status_success(204)

    else:
        # Failure 405 Method Not Allowed
        icebergid_invalid()