Hi,
I have an HTTP interface which looks for user roles.
There is one special case: If the database is empty, then the first user gets automatically created with an admin role. This check is by design not thread-safe. Therefore I created a static object which serves as lock. See the code below:
public class UserManagement : Controller { private readonly QlcContext _dbContext; private readonly ILogger<UserManagement> _logger; private static Object userRoleCheckLock = new Object(); public UserManagement(QlcContext dbContext, ILogger<UserManagement> logger) { _dbContext = dbContext; _logger = logger; } [HttpGet] [Route("GetRole")] public IActionResult GetRole(string user) { if (String.IsNullOrEmpty(user)) { _logger.LogError("Missing user parameter"); return BadRequest("Missing user parameter"); } QlcUser foundUser; lock (userRoleCheckLock) { foundUser = _dbContext.QlcUser.SingleOrDefault(u => string.Equals(u.Name, user, StringComparison.InvariantCultureIgnoreCase)); if (foundUser == null) { // If the user table is empty, then the first user which logs in, is admin else it is an normal user bool isAdmin = _dbContext.QlcUser.Count() == 0; Role role = isAdmin ? Role.Admin : Role.User; foundUser = new QlcUser { Name = user, Role = role }; Log(Severity.TRACE, $"Database user table is empty. Creating first user '{user}' with the role '{foundUser.RoleDisplayName}'", user); _dbContext.QlcUser.Add(foundUser); _dbContext.SaveChanges(); } } return Ok(foundUser.Role); } private void Log(Severity severity, string message, string requestor) { AuditTrail auditTrail = new AuditTrail( severity, DateTime.UtcNow, requestor, message); _dbContext.AuditTrail.Add(auditTrail); _dbContext.SaveChanges(); } }
The problem is, that I get regularly crashes with this code. The complete ASP.Net app crashes without any exceptions and without any log! How is this possible? Shouldn't this work?!
Thx in advance for answers!
Best regards,
Stefano