Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP Nested CRUD with Laravel 4 Nested Destroy & Completion Recursive Destroy

How to prevent the update item method to run from a different list id?

Hi.

Thanks a lot for the course. lovin' it!

Well, you said in the course that when we edit/update an existing item that is related to a list id, we do not need to save it relating to each other.

But we have one problem with that:

If we go to the browser and type todos/16/items/1/edit or todos/17/items/1/edit

and then try to update it, we will have the same effect. Because the item_id=1 will be instantiated no matter which list_id came before it.

The reason for that is that the app only is processing the $item_id, as follows:

    $item = TodoItem::findOrFail($item_id); // HERE
    $item->content = Input::get('content');
    $item->update(); // HERE

which is different from when we create a new item:

$item = new TodoItem();
    $item->content = Input::get('content');
    $todo_list->listItems()->save($item); // HERE: we save the item with the relationship

So my question is, how can I update an item ID preventing the edit page from being accessed through a hacking into the routes names? That is important if I want to stablish lists that are private from the public ones. Otherwise, someone could just access an private item inside a private list, from a public list just trying the following:

todos/{any_public_list_number}/items/1/edit todos/{any_public_list_number}/items/2/edit todos/{any_public_list_number}/items/3/edit *items 1,2 and 3 are private

Thanks beforehand.

Young Sam

1 Answer

If I'm understanding right (end correct me if I'm wrong) there's actually two parts of your question..

1) How do I make sure the right item is updated based on the URL provided? and 2) How do I protect my site from malicious behavior (people editing entries that do not belong to them)?

If that's the case please see my solution(s) below, otherwise please correct me so I can provide a relevant solution.

1) If every list will begin with a number one I suggest you have an additional field aside from id and list_id that way id can remain a unique primary key. Then you can change your select query to something such as the following:

<?php
$item = TodoItem::where('list_id', $list_id)
                ->where('item_number',$item_number)
                ->firstOrFail();
?>

This will become:

"SELECT * FROM todo_items WHERE 'list_id' = 16 AND 'item_number' = 1 LIMIT 1;"

And now you can change the list id and return a different item from a different list.

and

2) To limit people from editing lists that aren't theirs you can use some logic before performing the update:

<?php
$item = TodoItem::where('list_id', $list_id)
                ->where('item_number',$item_number)
                ->firstOrFail();

if ($item->user_id === Auth::user()->id) {
    // Perform your update
}
else {
    echo "You are not allowed to edit items in this list";
    exit;
}
?>

Checking ownership of items to secure your application is a good segway into middleware, which is not covered on Treehouse. Laracasts has a brief but good tutorial on it that you may benefit from.