Reputation: 1057
I'm developing a simple site using ASP.NET MVC 5 and I have some issue with editing a model.
Say, the model is as follows:
public class Model
{
public string Login { get; set; }
public string Password { get; set; }
}
I have two different user roles, for example, Admin and User. Now I'd like User to be able to edit only Login, whilst Admin should be able to edit both properties. I'm using pretty standard edit approach, something like this:
[HttpGet]
public ActionResult Edit(int id)
{
return View(FindModel(id));
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Model model)
{
if (ModelState.IsValid)
{
UpdateModel(model);
return RedirectToAction("Index");
}
return View(model);
}
The ideas I have:
I can show the Password text field only if a user is Admin so that User won't be able to change it. However, as far as I know, MVC binding uses the id (or name, probably) of an element to bind it to a model, so User will be able to manually create a field for password modifying HTML directly and then send the data to the controller.
I can create two different Models for Admin and User, say UserModel
and AdminModel
, two different actions in controller, and depending on the role of a user, I will create different submit buttons for User and Admin. So, User will click on 'EditUser' button and UserModel
won't even content Password, therefore making it not so easy to forge the password.
I can check if the pass was changed and the user is User, an error will be shown.
Other solution is to simply divide editing into two actions: edit login and edit password separately.
Could anyone give any ideas as to how to solve this and whether or not I need to protect the application from such forgery?
Upvotes: 0
Views: 2555
Reputation: 54628
There are a LOT of way to do this. To keep the code DRY I would do something like:
public class EditLoginVM
{
public bool CanEditPassword { get; set; }
public string Login { get; set; }
public string Password { get; set; }
}
In the view:
@if (Model.CanEditPassword )
{
// Show Password Textbox blah blah :)
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditLoginVM model)
{
if (ModelState.IsValid)
{
var updateModel = new Model();
updateModel.Login = model.Login;
if (/* user is admin, don't use EditLoginVM.IsAdmin!!!! */)
{
model.Password = model.Password;
}
UpdateModel(model);
return RedirectToAction("Index");
}
model.CanEditPassword = /* reset it just in case of overposting */;
return View(model);
}
Upvotes: 2