Trying to build out an exception if move.UserId does not equal currentUserId then Redirect to Action else if move.UserId does equal currentUserId return View.
See code here:
public ActionResult Details(int id)
{
MembershipUser currentUser = Membership.GetUser();
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
Move move = db.Moves.Where(m => m.UserId == currentUserId)
.FirstOrDefault();
if (currentUser != null && currentUser.ProviderUserKey != null && currentUser.IsApproved)
{
if (move.UserId == currentUserId)
{
return View(move);
}
}
return RedirectToAction("Oops", new RouteValueDictionary(
new { controller = "Account", action = "Oops", area = "", id = UrlParameter.Optional }));
}
I would like to tie it to the url which will bring back Move/(int) so that if the user modifies this to an (int) that returns a move where move.UserId != currentUserId then they also redirect. Currently they can modify Url to obtain other’s moves.
MyController
public ViewResult Index()
{
if (User.Identity.IsAuthenticated)
{
MembershipUser currentUser = Membership.GetUser();
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
if (currentUser != null && currentUser.ProviderUserKey != null && currentUser.IsApproved)
{
var results = db.Moves.Where(move => move.UserId == currentUserId)
.ToList();
return View(results);
}
}
return View(db.Moves.ToList());
}
[ClientValidation]
public ActionResult Details(Move move)
{
return View(move);
}
MyView
@model MovinMyStuff.Domain.Entities.Move
@{
ViewBag.Title = "Details";
}
<div>
@Html.DisplayFor(model => model.StartCity),
@Html.DisplayFor(model => model.StartState)
@Html.DisplayFor(model => model.StartZip) -
@Html.DisplayFor(model => model.EndCity),
@Html.DisplayFor(model => model.EndState)
@Html.DisplayFor(model => model.EndZip)
</div>
<fieldset>
<div class="job-details">
@Html.HiddenFor(model => model.MoveId)
@Html.HiddenFor(model => model.UserId)
<ul class="distance">
<li>
<div>
Distance</div>
</li>
<li>1,978.6 Miles</li>
</ul>
<ul class="address-wrapper">
<li>
<ul class="address from">
<li>
<div>
From</div>
</li>
<li><span>Address: </span>
@Html.DisplayFor(model => model.StartStreetNumber)
@Html.DisplayFor(model => model.StartStreetName)
</li>
...
</fieldset>
The first thing to test is whether the LINQ query returned a Move. If it didn’t it means that the user is trying to display a move that doesn’t belong to him, because in your query you have a
.Whereclause which restricts to the current user moves only.Right now you’re gonna get a NullReferenceException.
So:
Obviously if you need to repeat this logic in many controller actions it is worth writing a custom Authorize attribute:
And here’s how this custom Authorize attribute might look like:
Now you have managed to separate the concerns and externalize the authorization logic into a custom authorization attribute. Your controller no longer needs to be polluted with such code.