From 8cf4e35c12fdbd161222151272cfcc1d5f97214f Mon Sep 17 00:00:00 2001 From: axunonb Date: Wed, 16 Aug 2023 13:50:36 +0200 Subject: [PATCH] Don't throw for missing tournament id in database * Match, Ranking and TeamApplication controllers don't throw, when a tournament id from TenantContext does not exist in the database * GetCurrentUserId() from AbstractController returns null, if the ClaimTypes.NameIdentifier is missing --- League/Controllers/AbstractController.cs | 5 +++-- League/Controllers/Match.cs | 27 ++++++++++++++++++------ League/Controllers/Ranking.cs | 5 +++-- League/Controllers/TeamApplication.cs | 13 ++++-------- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/League/Controllers/AbstractController.cs b/League/Controllers/AbstractController.cs index 04ec065b..5304ef98 100644 --- a/League/Controllers/AbstractController.cs +++ b/League/Controllers/AbstractController.cs @@ -33,9 +33,10 @@ protected JsonResult JsonResponseRedirect(string? redirectUrl) /// Gets the of the current user /// as integer. [NonAction] - protected long GetCurrentUserId() + protected long? GetCurrentUserId() { - return long.Parse(User.Claims.First(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier).Value); + var userId = User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; + return long.TryParse(userId, out var id) ? id : null; } /// diff --git a/League/Controllers/Match.cs b/League/Controllers/Match.cs index 2a1f1781..f8f54e60 100644 --- a/League/Controllers/Match.cs +++ b/League/Controllers/Match.cs @@ -84,9 +84,12 @@ public IActionResult Index() [HttpGet("[action]")] public async Task Fixtures(CancellationToken cancellationToken) { + var tournament = await GetPlanTournament(cancellationToken); + if (tournament == null) return NotFound(); + var model = new FixturesViewModel(_timeZoneConverter) { - Tournament = await GetPlanTournament(cancellationToken), + Tournament = tournament, PlannedMatches = await _appDb.MatchRepository.GetPlannedMatchesAsync( new PredicateExpression(PlannedMatchFields.TournamentId == _tenantContext.TournamentContext.MatchPlanTournamentId), cancellationToken), // try to use the browser cookie @@ -203,11 +206,12 @@ public async Task PublicCalendar(long? team, long? round, Cancell [HttpGet("[action]")] public async Task Results(CancellationToken cancellationToken) { + var tournament = await GetResultTournament(cancellationToken); + if (tournament == null) return NotFound(); + var model = new ResultsViewModel(_timeZoneConverter) { - Tournament = - await _appDb.TournamentRepository.GetTournamentAsync(new PredicateExpression(TournamentFields.Id == _tenantContext.TournamentContext.MatchResultTournamentId), - cancellationToken), + Tournament = tournament, CompletedMatches = await _appDb.MatchRepository.GetCompletedMatchesAsync( new PredicateExpression(CompletedMatchFields.TournamentId == _tenantContext.TournamentContext.MatchResultTournamentId), cancellationToken), // try to use the browser cookie @@ -565,6 +569,17 @@ private static MatchEntity FillMatchEntity(PlannedMatchRow currentData) return null; } + private async Task GetResultTournament(CancellationToken cancellationToken) + { + var tournament = + await _appDb.TournamentRepository.GetTournamentAsync(new PredicateExpression(TournamentFields.Id == _tenantContext.TournamentContext.MatchResultTournamentId), cancellationToken); + + if (tournament != null) return tournament; + + _logger.LogCritical("{name} '{id}' does not exist. User ID '{currentUser}'.", nameof(_tenantContext.TournamentContext.MatchResultTournamentId), _tenantContext.TournamentContext.MatchPlanTournamentId, GetCurrentUserId()); + return null; + } + private async Task GetEnterResultViewModel(MatchEntity match, CancellationToken cancellationToken) { match.Sets.RemovedEntitiesTracker = new EntityCollection(); @@ -646,7 +661,7 @@ private void SendFixtureNotification(long matchId) Parameters = { CultureInfo = CultureInfo.DefaultThreadCurrentUICulture ?? CultureInfo.CurrentCulture, - ChangedByUserId = GetCurrentUserId(), + ChangedByUserId = GetCurrentUserId() ?? throw new InvalidOperationException("Current user ID must not be null"), MatchId = matchId, } }); @@ -663,7 +678,7 @@ private void SendResultNotification(in MatchEntity match) Parameters = { CultureInfo = CultureInfo.DefaultThreadCurrentUICulture ?? CultureInfo.CurrentCulture, - ChangedByUserId = GetCurrentUserId(), + ChangedByUserId = GetCurrentUserId() ?? throw new InvalidOperationException("Current user ID must not be null"), Match = match, } }); diff --git a/League/Controllers/Ranking.cs b/League/Controllers/Ranking.cs index f129e3fa..613df1ab 100644 --- a/League/Controllers/Ranking.cs +++ b/League/Controllers/Ranking.cs @@ -63,7 +63,8 @@ await _appDb.TournamentRepository.GetTournamentAsync(new PredicateExpression(Tou if (model.Tournament == null) { - throw new Exception($"{nameof(_tenantContext.TournamentContext.MatchResultTournamentId)} '{_tenantContext.TournamentContext.MatchResultTournamentId}' does not exist"); + _logger.LogCritical("{name} '{id}' does not exist. User ID '{currentUser}'.", nameof(_tenantContext.TournamentContext.MatchPlanTournamentId), _tenantContext.TournamentContext.MatchResultTournamentId, GetCurrentUserId()); + return NotFound(); } return View(Views.ViewNames.Ranking.Table, model); @@ -71,7 +72,7 @@ await _appDb.TournamentRepository.GetTournamentAsync(new PredicateExpression(Tou catch (Exception e) { _logger.LogCritical(e, "Error when creating the ranking table"); - throw; + return NotFound(); } } diff --git a/League/Controllers/TeamApplication.cs b/League/Controllers/TeamApplication.cs index b6145240..d93639fd 100644 --- a/League/Controllers/TeamApplication.cs +++ b/League/Controllers/TeamApplication.cs @@ -525,7 +525,7 @@ public async Task Confirm(bool done, CancellationToken cancellati TeamId = teamInRoundEntity.TeamId, IsNewApplication = isNewApplication, RoundId = teamInRoundEntity.RoundId, - RegisteredByUserId = GetCurrentUserId(), + RegisteredByUserId = GetCurrentUserId() ?? throw new InvalidOperationException("Current user ID must not be null"), UrlToEditApplication = TenantLink.ActionLink(nameof(EditTeam), nameof(TeamApplication), new { teamId = teamInRoundEntity.TeamId }, scheme: Request.Scheme, host: Request.Host) ?? string.Empty } }); @@ -697,11 +697,6 @@ private async Task GetNewSessionModel(CancellationToken var previousTournament = await _appDb.TournamentRepository.GetTournamentAsync( new PredicateExpression(TournamentFields.NextTournamentId == _tenantContext.TournamentContext.ApplicationTournamentId), cancellationToken); - if (previousTournament == null) - { - _logger.LogCritical("No tournament found for ID '{ApplicationTournamentId}'", _tenantContext.TournamentContext.ApplicationTournamentId); - throw new InvalidOperationException($"No tournament found for ID '{_tenantContext.TournamentContext.ApplicationTournamentId}'"); - } return new ApplicationSessionModel { @@ -709,7 +704,7 @@ private async Task GetNewSessionModel(CancellationToken Team = new TeamEditorComponentModel {HtmlFieldPrefix = nameof(ApplicationSessionModel.Team), IsNew = true}, Venue = new VenueEditorComponentModel {HtmlFieldPrefix = nameof(ApplicationSessionModel.Venue), IsNew = true}, TournamentName = teamApplicationTournament.Name, - PreviousTournamentId = previousTournament.Id + PreviousTournamentId = previousTournament?.Id }; } @@ -741,7 +736,7 @@ private async Task AddManagerToTeamEntity(TeamEntity teamEntity, CancellationTok { var mot = teamEntity.ManagerOfTeams.AddNew(); mot.Team = teamEntity; - mot.UserId = GetCurrentUserId(); + mot.UserId = GetCurrentUserId() ?? throw new InvalidOperationException("Current user ID must not be null"); } else { @@ -752,7 +747,7 @@ private async Task AddManagerToTeamEntity(TeamEntity teamEntity, CancellationTok { mot = teamEntity.ManagerOfTeams.AddNew(); mot.TeamId = teamEntity.Id; - mot.UserId = GetCurrentUserId(); + mot.UserId = GetCurrentUserId() ?? throw new InvalidOperationException("Current user ID must not be null"); } } }