Files
Berufsschule_HAM/src/Controllers/HomeController.cs

202 lines
7.2 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Berufsschule_HAM.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
using Berufsschule_HAM.Services;
using ElmahCore;
using Berufsschule_HAM.Exceptions;
using Microsoft.AspNetCore.Authorization;
using Berufsschule_HAM.Helpers;
[ApiExplorerSettings(IgnoreApi = true)]
[Route("[controller]")]
public class HomeController : Controller
{
private readonly LdapService _ldap;
public HomeController(LdapService ldap)
{
_ldap = ldap ?? throw new ArgumentNullException(nameof(ldap));
}
[Authorize]
[HttpGet("Index")]
[HttpGet("/")]
public ActionResult Index()
{
return View();
}
[Authorize(Roles = "CanManageAssets")]
[HttpGet("Assets")]
public async Task<IActionResult> Assets()
{
IEnumerable<AssetModel> assets = await _ldap.ListDeviceAsync();
List<AssetsTableViewModel> assetsTableViewModels = [];
foreach (AssetModel asset in assets)
{
assetsTableViewModels.Add(new()
{
AssetCn = asset.Cn,
AssetName = asset.Name,
LocationName = asset.Location,
UserUID = asset.Owner?.Split('=')[1],
});
}
return View(new HomeIndexViewModel() { AssetsTableViewModels = assetsTableViewModels });
}
[Authorize(Roles = "CanInventorize")]
[HttpGet("Inventory")]
public ActionResult Inventory()
{
return View();
}
[Authorize(Roles = "CanManageLocations")]
[HttpGet("Locations")]
public async Task<ActionResult> LocationsAsync()
{
IEnumerable<LocationModel> locations = await _ldap.ListLocationsAsync();
List<LocationTableViewModel> LocationsTableViewModels = [];
foreach (LocationModel location in locations)
{
LocationsTableViewModels.Add(new()
{
LocationID = location.Location,
LocationName = location.Description?.Location ?? "",
RoomNumber = location.Description?.RoomNumber ?? "",
Seat = location.Description?.Seat ?? ""
});
}
return View(new LocationsIndexViewModel() { LocationTableViewModels = LocationsTableViewModels });
}
[Authorize(Roles = "CanManageUsers")]
[HttpGet("Users")]
public async Task<ActionResult> UsersAsync()
{
IEnumerable<UserModel> users = await _ldap.ListUsersAsync([.. _ldap.UsersAttributes.Where(attr => attr != "jpegPhoto" && attr != "userPassword")]);
List<UserTableViewModel> UserTableViewModels = [];
foreach (UserModel user in users)
{
UserTableViewModels.Add(new()
{
Name = user.Cn ?? "",
Surname = user.Sn ?? "",
Title = user.Title ?? "",
Uid = user.Uid,
Description = user.Description ?? new() {Address = new(), BirthDate = "", Workplace = "", Groups = []}
});
}
return View(new UsersIndexViewModel() { UserTableViewModels = UserTableViewModels });
}
[Authorize(Roles = "CanManageUsers")]
[HttpGet("UserPhoto")]
[ResponseCache(Duration = 3600, Location = ResponseCacheLocation.Any, VaryByQueryKeys = new[] { "uid", "size" })]
public async Task<IActionResult> UserPhotoAsync(string uid, int? size)
{
Task<AdminSettingsModel> adminSettingsModelTask = _ldap.GetAdminSettingsModelAsync();
UserModel? user = await _ldap.GetUserByUidAsync(uid, _ldap.UsersAttributes);
if (user is null || user.JpegPhoto is null || user.JpegPhoto == "")
{
return File(ImageHelper.GetDefaultUserImage(size ?? 48), "image/webp");
}
if (size is null)
{
return File(Convert.FromBase64String(user.JpegPhoto), "image/webp");
}
if (size is not null)
{
AdminSettingsModel adminSettingsModel = await adminSettingsModelTask;
size = Math.Min((int)size, adminSettingsModel.MaxDownloadableUserImageSize);
}
byte[] encodedFile = ImageHelper.ResizeAndConvertToWebp(user.JpegPhoto, size ?? 32);
return File(encodedFile, "image/webp");
}
[Authorize(Roles = "CanManageGroups")]
[HttpGet("Groups")]
public async Task<ActionResult> GroupsAsync()
{
IEnumerable<GroupModel> groups = await _ldap.ListGroupsAsync();
return View(new GroupsIndexViewModel(groups));
}
[HttpPost("Login")]
public async Task<ActionResult> Login(string username, string password)
{
var authenticationResult = await _ldap.AuthenticateUser(username, password);
if (authenticationResult.Success)
{
List<Claim> claims =
[
new(ClaimTypes.Name, username)
];
HashSet<string> roles = [];
foreach (string groupCn in authenticationResult.UserModel?.Description?.Groups ?? [])
{
GroupModel group = await _ldap.GetGroupByCnAsync(groupCn, _ldap.GroupsAttributes);
foreach (GroupPermission permission in group.Permissions)
{
roles.Add(permission.ToString());
}
}
foreach (string role in roles)
{
claims.Add(new(ClaimTypes.Role, role));
}
var claimsIdentity = new ClaimsIdentity(
claims,
CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(300)
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return RedirectToAction("Index", "Home");
}
switch (authenticationResult.AuthenticationState)
{
case UserNotAuthenticatedReason.InvalidCredentials:
return View(new LoginViewModel() { ErrorText = "Invalid login credentials" });
case UserNotAuthenticatedReason.UserLockedOut:
return View(new LoginViewModel() { ErrorText = "Your account has been locked. Wait a few minutes or ask an administrator to unlock you" });
case UserNotAuthenticatedReason.UserNotAuthorized:
return View(new LoginViewModel() { ErrorText = "You are not authorized for login. Ask an administrator to authorize you." });
default:
await HttpContext.RaiseError(new HellFrozeOverException());
return View(new LoginViewModel() { ErrorText = "Hell froze over. Make a screenshot and send it to an administrator." });
}
}
[HttpGet("Login")]
public ActionResult Login()
{
return View(new LoginViewModel());
}
[HttpGet("Logout")]
public ActionResult Logout()
{
HttpContext.SignOutAsync();
return RedirectToAction("Index", "Home");
}
[HttpGet("AccessDenied")]
public ActionResult AccessDenied()
{
return View();
}
}