Reputation: 11
I created a scaffold based on one of my tables. I'm now trying to figure out how to allow the user to only view/edit data that is the same as their userID.
Right now it displays all the data from that table and allows for editing of all users. I need to be able to limit it to only the user that is currently logged in.
Please let me know if I can give any more details.
Controller
public class ClientViewStaffController : Controller
{
private TpsEntities db = new TpsEntities();
// GET: ClientViewStaff
public ActionResult Index()
{
return View(db.staffTables.ToList());
}
// GET: ClientViewStaff/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
staffTable staffTable = db.staffTables.Find(id);
if (staffTable == null)
{
return HttpNotFound();
}
return View(staffTable);
}
// GET: ClientViewStaff/Create
public ActionResult Create()
{
return View();
}
// POST: ClientViewStaff/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "staffID,staffFirstName,staffLastName,staffTitle,staffAddress,staffCity,staffState,staffZip,staffExperience,staffEducation,desiredSalary,staffProfession,staffAvailibity,staffPhoto,staffEmail,staffPhoneNum,userID")] staffTable staffTable)
{
if (ModelState.IsValid)
{
db.staffTables.Add(staffTable);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(staffTable);
}
// GET: ClientViewStaff/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
staffTable staffTable = db.staffTables.Find(id);
if (staffTable == null)
{
return HttpNotFound();
}
return View(staffTable);
}
// POST: ClientViewStaff/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "staffID,staffFirstName,staffLastName,staffTitle,staffAddress,staffCity,staffState,staffZip,staffExperience,staffEducation,desiredSalary,staffProfession,staffAvailibity,staffPhoto,staffEmail,staffPhoneNum,userID")] staffTable staffTable)
{
if (ModelState.IsValid)
{
db.Entry(staffTable).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(staffTable);
}
// GET: ClientViewStaff/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
staffTable staffTable = db.staffTables.Find(id);
if (staffTable == null)
{
return HttpNotFound();
}
return View(staffTable);
}
// POST: ClientViewStaff/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
staffTable staffTable = db.staffTables.Find(id);
db.staffTables.Remove(staffTable);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
View (Index.cshtml)
<table class="table">
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
@Html.DisplayNameFor(model => model.staffState)
</th>
<th>
@Html.DisplayNameFor(model => model.staffExperience)
</th>
<th>
@Html.DisplayNameFor(model => model.staffEducation)
</th>
<th>
@Html.DisplayNameFor(model => model.desiredSalary)
</th>
<th>
@Html.DisplayNameFor(model => model.staffProfession)
</th>
<th>
@Html.DisplayNameFor(model => model.staffAvailibity)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.staffFirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.staffLastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.staffState)
</td>
<td>
@Html.DisplayFor(modelItem => item.staffExperience)
</td>
<td>
@Html.DisplayFor(modelItem => item.staffEducation)
</td>
<td>
@Html.DisplayFor(modelItem => item.desiredSalary)
</td>
<td>
@Html.DisplayFor(modelItem => item.staffProfession)
</td>
<td>
@Html.DisplayFor(modelItem => item.staffAvailibity)
</td>
<td>
@Html.ActionLink("Details", "Details", new { id = item.staffID }) |
</td>
</tr>
}
View (Details.cshtml)
<div>
<h4>Staff View</h4>
<hr />
<dl class="dl-horizontal">
<dt>
First Name
</dt>
<dd>
@Html.DisplayFor(model => model.staffFirstName)
</dd>
<dt>
Last Name
</dt>
<dd>
@Html.DisplayFor(model => model.staffLastName)
</dd>
<dt>
Title
</dt>
<dd>
@Html.DisplayFor(model => model.staffTitle)
</dd>
<dt>
Address
</dt>
<dd>
@Html.DisplayFor(model => model.staffAddress)
</dd>
<dt>
City
</dt>
<dd>
@Html.DisplayFor(model => model.staffCity)
</dd>
<dt>
State
</dt>
<dd>
@Html.DisplayFor(model => model.staffState)
</dd>
<dt>
Zip Code
</dt>
<dd>
@Html.DisplayFor(model => model.staffZip)
</dd>
<dt>
Experience
</dt>
<dd>
@Html.DisplayFor(model => model.staffExperience)
</dd>
<dt>
Education
</dt>
<dd>
@Html.DisplayFor(model => model.staffEducation)
</dd>
<dt>
Salary
</dt>
<dd>
@Html.DisplayFor(model => model.desiredSalary)
</dd>
<dt>
Profession
</dt>
<dd>
@Html.DisplayFor(model => model.staffProfession)
</dd>
<dt>
Availability
</dt>
<dd>
@Html.DisplayFor(model => model.staffAvailibity)
</dd>
<dt>
Photo
</dt>
<dd>
@Html.DisplayFor(model => model.staffPhoto)
</dd>
<dt>
Email
</dt>
<dd>
@Html.DisplayFor(model => model.staffEmail)
</dd>
<dt>
Phone Number
</dt>
<dd>
@Html.DisplayFor(model => model.staffPhoneNum)
</dd>
<dt>
User ID
</dt>
<dd>
@Html.DisplayFor(model => model.userID)
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.staffID }) |
@Html.ActionLink("Back to List", "Index")
</p>
Upvotes: 1
Views: 4968
Reputation: 5550
I think your missing something about entity framework in combination with Linq aka Linq-to-entities.
Your can write queries against your ef model using Linq. For details see MSDN.
What your basically doing is writing a query in c# and entity framework will convert this query to a sql select statement and run this against your database.
Using this approach your question becomes real simple. Just write a query which fits your needs. Something like this could work
public IEnumerable<> FetchData(string userId)
{
return (
from item in this.db.staffTables
where item.UserId == userId
select item
).ToArray();
}
A far better approach would be to hide your entity framework model from your controller and use a repository in between. The repository would typically implement four functions: GetData()', 'Create()', 'Update()
and Delete()
. In each method you would check if the user is authorized for the action to perform or return only data that the user is authorized to get.
Upvotes: 1
Reputation: 4668
Decorate your Edit action with [Authorize] attribute
[Authorize]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
staffTable staffTable = db.staffTables.Find(id);
if (staffTable == null)
{
return HttpNotFound();
}
return View(staffTable);
}
Then hide your edit action for non-logged in users.
First add @using Microsoft.AspNet.Identity
to top of your view and then use below code on view.
@if (Request.IsAuthenticated)
{
@Html.ActionLink("Edit", "Edit", new { id = Model.staffID })
}
Edited for comment
As you know that anything you need to restrict non-authenticated users (non-logged in), you have to use [Authorize] attribute as I mentioned.
You didn't mentioned what you exactly restrict access in your question.
If you want to restrict access all your content to the non authenticate user, then add [Authorize] attribute to your controller as below.
[Authorize]
public class ClientViewStaffController : Controller
{
}
Then all the actions restricted for logged in users only. Is that what you looking for?
Upvotes: 1
Reputation: 11340
You can implement something like this in the Edit, Details
GET action.
var loggedInUser = GetUserId(HttpContext.Current.User.Identity.Name);
if (id != loggedInUser)
{
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
}
You can also abstract this away from the controller and put in an Action Filter. Action filters in ASP.NET MVC are C# attributes that separate specific concerns such as security.
Upvotes: 1