ASP.NET CORE MVC How can i limit what a UserId can edit through making href links dissapear on the html page based on their UserId

To mention, upon creating a new product, the UseId of the current logged in user will be dynamically added to the database.

However, im trying to find a way to make the <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> link to dissapear(refer to template below) if the UserId of the current logged in user doesnt match that UserId of the item.

Ive tried to follow this post however i dont think this makes any links dissapear.
ASP.NET MVC Attribute to only let user edit his/her own content

Model

public class Product
    {
        public int Id { get; set; }
        public string UserId { get; set; }
        public V8User User { get; set; }
        public string Name { get; set; }
        public Double Price { get; set; }
        public string Photo { get; set; }

    }```
    

Snippet of the controller

    // GET: Products/Edit/5
    public async Task<IActionResult> Edit(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var product = await _context.Product.FindAsync(id);
        if (product == null)
        {
            return NotFound();
        }
        ViewData["UserId"] = new SelectList(_context.Set<V8User>(), "Id", "Id", product.UserId);
        return View(product);

      
    }



    // POST: Products/Edit/5
    // To protect from overposting attacks, enable the specific properties you want to bind to, for 
    // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, [Bind("Id,UserId,Name,Price,Photo")] Product product)
    {
        if (id != product.Id)
        {
            return NotFound();
        }

        if (ModelState.IsValid)
        {
            try
            {
                _context.Update(product);
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ProductExists(product.Id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return RedirectToAction(nameof(Index));
        }
        ViewData["UserId"] = new SelectList(_context.Set<V8User>(), "Id", "Id", product.UserId);
        return View(product);
    }```

Template(Index.cshtml)
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.User)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Photo)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.UserId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Photo)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

First, you should get the userId of current logged in user. Then in the page decide whether to hide Edit link

@if(currentUserId == @item.Id)
{
    <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
}

Method 2

The answer to your verbatim question is that you cannot. Hiding links from a user will not prevent them from simply plugging in product IDs into urls they can see and gaining access to items that they should not.

You should add UserId validation in your Edit methods.

Regards your Edit(POST) method, why trust the UserId being submitted and allow it to replace the UserId of the Product item? Perhaps instead use it to perform validation against a lookup of the actual Product.UserId and make sure somebody is not trying to submit bad data.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x