ScientificReport
UserProfileController.cs
Go to the documentation of this file.
1 using System;
2 using System.Linq;
3 using System.Threading.Tasks;
4 using Microsoft.AspNetCore.Authorization;
5 using Microsoft.AspNetCore.Identity;
6 using Microsoft.AspNetCore.Mvc;
7 using Microsoft.Extensions.Localization;
13 
14 namespace ScientificReport.Controllers
15 {
16  [Authorize(Roles = UserProfileRole.Any)]
17  public class UserProfileController : Controller
18  {
19  private readonly UserManager<UserProfile> _userManager;
20  private readonly SignInManager<UserProfile> _signInManager;
21  private readonly RoleManager<UserProfileRole> _roleManager;
22 
23  private readonly IUserProfileService _userProfileService;
24  private readonly IDepartmentService _departmentService;
25  private readonly IStringLocalizer<UserProfileController> _localizer;
26 
28  UserManager<UserProfile> usrMgr,
29  SignInManager<UserProfile> signInManager,
30  RoleManager<UserProfileRole> roleManager,
31  IUserProfileService userProfileService,
32  IDepartmentService departmentService,
33  IStringLocalizer<UserProfileController> localizer
34  )
35  {
36  _userManager = usrMgr;
37  _signInManager = signInManager;
38  _roleManager = roleManager;
39  _userProfileService = userProfileService;
40  _departmentService = departmentService;
41  _localizer = localizer;
42  }
43 
44  // GET: UserProfile/Index
45  [HttpGet]
46  [Authorize(Roles = UserProfileRole.HeadOfDepartmentOrAdmin)]
47  public IActionResult Index(UserProfileIndexModel model)
48  {
49  model.UserProfiles = _userProfileService.Filter(model, User, PageHelpers.IsAdmin(User));
50  model.Departments = _departmentService.GetAll();
51  model.Count = _userProfileService.GetCount();
52  return View(model);
53  }
54 
55  // GET: UserProfile/Details/{id}
56  [HttpGet]
57  public async Task<IActionResult> Details(Guid? id)
58  {
59  if (id == null)
60  {
61  return NotFound();
62  }
63 
64  var userProfile = _userProfileService.GetById(id.Value);
65  if (userProfile == null)
66  {
67  return NotFound();
68  }
69 
70  var department = _departmentService.Get(d => d.Staff.Contains(userProfile));
71 
72  var fullPositionTitle = "";
73  if (await _userManager.IsInRoleAsync(userProfile, UserProfileRole.Administrator))
74  {
75  fullPositionTitle = _localizer["Administrator"] + ", ";
76  }
77  fullPositionTitle += _localizer[userProfile.Position] + (department != null
78  ? " " + _localizer["of department"] + " \"" + department.Title + "\""
79  : "");
80 
81  var detailsModel = new UserDetailsModel
82  {
83  User = userProfile,
84  FullPositionTitle = fullPositionTitle
85  };
86 
87  if (!PageHelpers.IsAdmin(User))
88  {
89  var currentUser = _userProfileService.Get(User);
90  if (PageHelpers.IsHeadOfDepartment(User))
91  {
92  if (department == null || !_departmentService.UserWorksInDepartment(currentUser, userProfile.Id))
93  {
94  return Forbid();
95  }
96  }
97  }
98 
99  return View(detailsModel);
100  }
101 
102  // GET: UserProfile/Edit/{id}
103  [HttpGet]
104  public async Task<IActionResult> Edit(Guid? id) {
105  if (id == null)
106  {
107  return NotFound();
108  }
109  var user = _userProfileService.GetById(id.Value);
110  if (user != null)
111  {
112  var currentUser = _userProfileService.Get(User);
113  if (!PageHelpers.IsAdmin(User))
114  {
115  if (PageHelpers.IsHeadOfDepartment(User))
116  {
117  if (!_departmentService.UserWorksInDepartment(currentUser, user.Id))
118  {
119  return Forbid();
120  }
121  }
122  else if (PageHelpers.IsTeacher(User) && currentUser.Id != user.Id)
123  {
124  return Forbid();
125  }
126  }
127 
128  return View(new UserProfileEditModel
129  {
130  UserId = user.Id,
131  FirstName = user.FirstName,
132  MiddleName = user.MiddleName,
133  LastName = user.LastName,
134  BirthYear = user.BirthYear,
135  GraduationYear = user.GraduationYear,
136  ScientificDegree = user.ScientificDegree,
137  YearDegreeGained = user.YearDegreeGained,
138  AcademicStatus = user.AcademicStatus,
139  YearDegreeAssigned = user.YearDegreeAssigned,
140  PhoneNumber = user.PhoneNumber,
141  IsApproved = user.IsApproved,
142  IsActive = user.IsActive,
143  UserName = user.UserName,
144  Email = user.Email,
145  Sex = user.Sex,
146  IsSelfEditing = currentUser.Id == user.Id,
147  AllRoles = _roleManager.Roles.ToList(),
148  UserRoles = await _userManager.GetRolesAsync(user),
149  IsHeadOfDepartment = await _userProfileService.IsInRoleAsync(user, UserProfileRole.HeadOfDepartment, _userManager)
150  });
151  }
152 
153  return RedirectToAction("Index");
154  }
155 
156  // POST: UserProfile/Edit/{id}
157  [HttpPost]
158  public IActionResult Edit(Guid? id, UserProfileEditModel model)
159  {
160  if (!ModelState.IsValid)
161  {
162  return View(model);
163  }
164 
165  if (id == null)
166  {
167  return NotFound();
168  }
169 
170  if (_userProfileService.UserExists(id.Value))
171  {
172  var user = _userProfileService.GetById(id.Value);
173  var currentUser = _userProfileService.Get(User);
174  if (PageHelpers.IsAdmin(User) || PageHelpers.IsTeacher(User) && currentUser.Id == user.Id || PageHelpers.IsHeadOfDepartment(User) && _departmentService.UserWorksInDepartment(currentUser, user.Id))
175  {
176  user.FirstName = model.FirstName;
177  user.MiddleName = model.MiddleName;
178  user.LastName = model.LastName;
179 
180  if (model.BirthYear > 1900)
181  {
182  user.BirthYear = model.BirthYear;
183  }
184 
185  if (model.GraduationYear > 1900)
186  {
187  user.GraduationYear = model.GraduationYear;
188  }
189 
190  if (model.ScientificDegree != null)
191  {
192  user.ScientificDegree = model.ScientificDegree;
193  user.YearDegreeGained = model.YearDegreeGained;
194  }
195 
196  if (model.AcademicStatus != null)
197  {
198  user.AcademicStatus = model.AcademicStatus;
199  user.YearDegreeAssigned = model.YearDegreeAssigned;
200  }
201 
202  user.Sex = model.Sex;
203 
204  user.PhoneNumber = model.PhoneNumber;
205  if (PageHelpers.IsAdminOrHead(User) && currentUser.Id != id.Value)
206  {
207  user.IsApproved = model.IsApproved;
208  user.IsActive = model.IsActive;
209  }
210 
211  user.UserName = model.UserName;
212  user.Email = model.Email;
213 
214  _userProfileService.UpdateItem(user);
215  }
216  else
217  {
218  return Forbid();
219  }
220  }
221  else
222  {
223  return NotFound();
224  }
225 
226  return PageHelpers.IsAdminOrHead(User) ? RedirectToAction("Index") : RedirectToAction("Details", "UserProfile", new { id = id.Value});
227  }
228 
229  // POST: UserProfile/AddUserToAdministration/{userId}
230  [HttpPost]
231  [Authorize(Roles = UserProfileRole.Administrator)]
232  public async Task<IActionResult> AddUserToAdministration(Guid? id, [FromBody] UserProfileUpdateRolesRequest request)
233  {
234  if (id == null)
235  {
236  return NotFound();
237  }
238 
239  if (request.RoleName.Equals(UserProfileRole.Teacher) ||
240  request.RoleName.Equals(UserProfileRole.HeadOfDepartment))
241  {
242  return Json(new {Success = false});
243  }
244 
245  var userExists = _userProfileService.UserExists(id.Value);
246  if (userExists)
247  {
248  var user = _userProfileService.GetById(id.Value);
249  if (await _userProfileService.IsInRoleAsync(user, UserProfileRole.HeadOfDepartment, _userManager))
250  {
251  return Json(ApiResponse.Fail);
252  }
253 
254  if (!await _userProfileService.IsInRoleAsync(user, request.RoleName, _userManager))
255  {
256  await _userProfileService.AddToRoleAsync(user, request.RoleName, _userManager);
257  }
258  }
259 
260  return Json(new {Success = userExists});
261  }
262 
263  // POST: UserProfile/RemoveUserFromAdministration/{userId}
264  [HttpPost]
265  [Authorize(Roles = UserProfileRole.Administrator)]
266  public async Task<IActionResult> RemoveUserFromAdministration(Guid? id, [FromBody] UserProfileUpdateRolesRequest request)
267  {
268  if (id == null)
269  {
270  return NotFound();
271  }
272 
273  var userExists = _userProfileService.UserExists(id.Value);
274  if (userExists)
275  {
276  var user = _userProfileService.GetById(id.Value);
277  if (await _userProfileService.IsInRoleAsync(user, request.RoleName, _userManager))
278  {
279  if (user.UserName != User.Identity.Name)
280  {
281  await _userProfileService.RemoveFromRoleAsync(user, request.RoleName, _userManager);
282  if (request.RoleName == UserProfileRole.HeadOfDepartment)
283  {
284  _userProfileService.UpdateItem(user);
285  }
286  }
287  else
288  {
289  return Json(ApiResponse.Fail);
290  }
291  }
292  else
293  {
294  return Json(ApiResponse.Fail);
295  }
296  }
297 
298  return Json(new
299  {
300  Success = userExists
301  });
302  }
303 
304  // POST: UserProfile/Delete/{id}
305  [HttpPost]
306  [Authorize(Roles = UserProfileRole.Administrator)]
307  public IActionResult Delete(Guid? id)
308  {
309  if (id == null)
310  {
311  return NotFound();
312  }
313 
314  if (!_userProfileService.UserExists(id.Value))
315  {
316  return NotFound();
317  }
318 
319  var currentUser = _userProfileService.Get(User);
320  if (currentUser.Id != id.Value)
321  {
322  if (!PageHelpers.IsAdmin(User) && PageHelpers.IsHeadOfDepartment(User))
323  {
324  if (!_departmentService.UserWorksInDepartment(currentUser, id.Value))
325  {
326  return Forbid();
327  }
328  }
329 
330  _userProfileService.DeleteById(id.Value);
331  }
332  return RedirectToAction("Index");
333  }
334 
335  // POST: UserProfile/SetActive/{id}?active={true/false}
336  [HttpPost]
337  [Authorize(Roles = UserProfileRole.HeadOfDepartmentOrAdmin)]
338  public IActionResult SetActive(Guid? id, bool isActive)
339  {
340  if (id == null)
341  {
342  return NotFound();
343  }
344 
345  if (!_userProfileService.UserExists(id.Value))
346  {
347  return NotFound();
348  }
349 
350  var currentUser = _userProfileService.Get(User);
351  if (currentUser.Id != id.Value)
352  {
353  if (!PageHelpers.IsAdmin(User) && PageHelpers.IsHeadOfDepartment(User))
354  {
355  if (!_departmentService.UserWorksInDepartment(currentUser, id.Value))
356  {
357  return Forbid();
358  }
359  }
360 
361  _userProfileService.SetActiveById(id.Value, isActive);
362  }
363 
364  return RedirectToAction("Index");
365  }
366 
367  // GET: UserProfile/Register
368  [HttpGet]
369  [AllowAnonymous]
370  public IActionResult Register()
371  {
372  // .Select(d => new SelectItem(d.Title, d.Id.ToString()))
373  var departments = _departmentService.GetAll();
374  return View(new RegisterModel
375  {
376  Departments = departments
377  });
378  }
379 
380  // POST: UserProfile/Register
381  [HttpPost]
382  [AllowAnonymous]
383  [ValidateAntiForgeryToken]
384  public async Task<IActionResult> Register(RegisterModel model) {
385  if (!ModelState.IsValid)
386  {
387  model.Departments = _departmentService.GetAll();
388  return View(model);
389  }
390 
391  if (_userProfileService.Get(usr => usr.UserName == model.UserName) != null)
392  {
393  ModelState.AddModelError(string.Empty, _localizer["User already exists"]);
394  return BadRequest();
395  }
396 
397  var user = new UserProfile {
398  UserName = model.UserName,
399  Email = model.Email,
400  FirstName = model.FirstName,
401  LastName = model.LastName,
402  MiddleName = model.MiddleName,
403  Position = UserProfileRole.Teacher,
404  IsApproved = false,
405  IsActive = true,
406  Sex = UserProfile.SexValue.None,
407  PhoneNumber = model.PhoneNumber
408  };
409  if (model.Password.Equals(model.PasswordRepeat))
410  {
411  var result = await _userManager.CreateAsync(user, model.Password);
412  if (result.Succeeded)
413  {
414  var createdUser = _userProfileService.Get(u => u.UserName == user.UserName);
415  var addUserToRoleResult = await _userProfileService.AddToRoleAsync(
416  createdUser, UserProfileRole.Teacher, _userManager
417  );
418  if (addUserToRoleResult.Succeeded)
419  {
420  var department = _departmentService.GetById(model.SelectedDepartmentId);
421  if (department != null)
422  {
423  department.Staff.Add(createdUser);
424  _departmentService.UpdateItem(department);
425  return RedirectToAction("Index");
426  }
427  }
428 
429  AddErrorsFromResult(addUserToRoleResult);
430  }
431 
432  AddErrorsFromResult(result);
433  }
434  else
435  {
436  ModelState.AddModelError(string.Empty, _localizer["Password confirmation failed"]);
437  }
438 
439  model.Departments = _departmentService.GetAll();
440  return View(model);
441  }
442 
443  // GET: UserProfile/Login
444  [HttpGet]
445  [AllowAnonymous]
446  public IActionResult Login()
447  {
448  if (User.Identity.IsAuthenticated)
449  {
450  return Redirect("/");
451  }
452 
453  return View();
454  }
455 
456  // POST: UserProfile/Login
457  [HttpPost]
458  [AllowAnonymous]
459  [ValidateAntiForgeryToken]
460  public async Task<IActionResult> Login(LoginModel model)
461  {
462  if (ModelState.IsValid)
463  {
464  var user = _userProfileService.Get(usr => usr.UserName == model.UserName);
465  if (user != null)
466  {
467  if (!user.IsApproved)
468  {
469  ModelState.AddModelError(string.Empty, _localizer["Account is not approved yet"]);
470  return View(model);
471  }
472 
473  if (user.IsActive)
474  {
475  var result = await _signInManager.PasswordSignInAsync(
476  user.UserName, model.Password, model.RememberMe, false
477  );
478  if (result.Succeeded)
479  {
480  return Redirect(model.ReturnUrl);
481  }
482  }
483  }
484  }
485 
486  ModelState.AddModelError(string.Empty, _localizer["Incorrect login or password"]);
487  return View(model);
488  }
489 
490  // GET: UserProfile/Logout
491  [HttpGet]
492  [AllowAnonymous]
493  public async Task<IActionResult> Logout()
494  {
495  await _signInManager.SignOutAsync();
496  return Redirect("/");
497  }
498 
499  [HttpGet]
500  [Authorize(Roles = UserProfileRole.Any)]
501  public IActionResult ChangePassword()
502  {
503  var currentUser = _userManager.GetUserAsync(HttpContext.User);
504  if (currentUser == null)
505  {
506  return NotFound();
507  }
508 
509  return View(new ChangePasswordModel
510  {
511  Id = currentUser.Result.Id
512  });
513  }
514 
515  [HttpPost]
516  [Authorize(Roles = UserProfileRole.Any)]
517  public async Task<IActionResult> ChangePassword(ChangePasswordModel model)
518  {
519  if (model.Id == null)
520  {
521  return NotFound();
522  }
523 
524  var user = _userProfileService.GetById(model.Id.Value);
525  if (user == null)
526  {
527  return NotFound();
528  }
529 
530  if (!ModelState.IsValid)
531  {
532  return View(model);
533  }
534 
535  var error = await _userProfileService.ChangePassword(
536  user, model.OldPassword, model.NewPassword, model.NewPasswordRepeat, _userManager
537  );
538 
539  if (error == null)
540  {
541  return Redirect("/");
542  }
543 
544  ModelState.AddModelError(string.Empty, error);
545  return View(model);
546  }
547 
548  private void AddErrorsFromResult(IdentityResult result)
549  {
550  foreach (var error in result.Errors)
551  {
552  ModelState.AddModelError(string.Empty, error.Description);
553  }
554  }
555  }
556 }
IActionResult Edit(Guid?id, UserProfileEditModel model)
IActionResult SetActive(Guid?id, bool isActive)
async Task< IActionResult > Login(LoginModel model)
IActionResult Index(UserProfileIndexModel model)
async Task< IActionResult > RemoveUserFromAdministration(Guid?id, [FromBody] UserProfileUpdateRolesRequest request)
async Task< IActionResult > Register(RegisterModel model)
IEnumerable< DAL.Entities.Department > Departments
async Task< IActionResult > AddUserToAdministration(Guid?id, [FromBody] UserProfileUpdateRolesRequest request)
async Task< IActionResult > ChangePassword(ChangePasswordModel model)
UserProfileController(UserManager< UserProfile > usrMgr, SignInManager< UserProfile > signInManager, RoleManager< UserProfileRole > roleManager, IUserProfileService userProfileService, IDepartmentService departmentService, IStringLocalizer< UserProfileController > localizer)
IEnumerable< DAL.Entities.UserProfile.UserProfile > UserProfiles
DAL.Entities.UserProfile.UserProfile.SexValue Sex