public async Task <Response> TrackSucessRedirectionAsync(LinkTrackingRequest request) { try { using var conn = DbConnection; var lt = new LinkTracking { Id = Guid.NewGuid(), IpAddress = request.IpAddress, LinkId = request.LinkId, RequestTimeUtc = DateTime.UtcNow, UserAgent = request.UserAgent }; const string sqlInsertLt = @"INSERT INTO LinkTracking (Id, IpAddress, LinkId, RequestTimeUtc, UserAgent) VALUES (@Id, @IpAddress, @LinkId, @RequestTimeUtc, @UserAgent)"; await conn.ExecuteAsync(sqlInsertLt, lt); return(new SuccessResponse()); } catch (Exception e) { _logger.LogError(e, e.Message); return(new FailedResponse(e.Message)); } }
public Task TrackSucessRedirectionAsync(LinkTrackingRequest request) { var lt = new LinkTracking { IpAddress = request.IpAddress, LinkId = request.LinkId, RequestTimeUtc = DateTime.UtcNow, UserAgent = request.UserAgent }; return(_connection.InsertAsync(lt)); }
private async Task <IActionResult> PerformTokenRedirection(string token, string ip) { var isValid = _tokenGenerator.TryParseToken(token, out var validatedToken); if (!isValid) { return(BadRequest()); } if (!_cache.TryGetValue(token, out Link linkEntry)) { var flag = await _featureManager.IsEnabledAsync(nameof(FeatureFlags.AllowSelfRedirection)); var link = await _linkForwarderService.GetLinkAsync(validatedToken); if (link is null) { if (string.IsNullOrWhiteSpace(_appSettings.DefaultRedirectionUrl)) { return(NotFound()); } var result = _linkVerifier.Verify(_appSettings.DefaultRedirectionUrl, Url, Request, flag); if (result == LinkVerifyResult.Valid) { return(Redirect(_appSettings.DefaultRedirectionUrl)); } throw new UriFormatException("DefaultRedirectionUrl is not a valid URL."); } if (!link.IsEnabled) { return(BadRequest("This link is disabled.")); } var verifyOriginUrl = _linkVerifier.Verify(link.OriginUrl, Url, Request, flag); switch (verifyOriginUrl) { case LinkVerifyResult.Valid: // cache valid link entity only. if (link.TTL is not null) { _cache.Set(token, link, TimeSpan.FromSeconds(link.TTL.GetValueOrDefault())); } break; case LinkVerifyResult.InvalidFormat: throw new UriFormatException( $"OriginUrl '{link.OriginUrl}' is not a valid URL, link ID: {link.Id}."); case LinkVerifyResult.InvalidLocal: _logger.LogWarning($"Local redirection is blocked. link: {JsonSerializer.Serialize(link)}"); return(BadRequest("Local redirection is blocked")); case LinkVerifyResult.InvalidSelfReference: _logger.LogWarning( $"Self reference redirection is blocked. link: {JsonSerializer.Serialize(link)}"); return(BadRequest("Self reference redirection is blocked")); default: throw new ArgumentOutOfRangeException(); } } linkEntry ??= _cache.Get <Link>(token); var honorDNTFlag = await _featureManager.IsEnabledAsync(nameof(FeatureFlags.HonorDNT)); if (!honorDNTFlag) { return(Redirect(linkEntry.OriginUrl)); } // Check if browser sends "Do Not Track" var dntFlag = Request.Headers["DNT"]; var dnt = !string.IsNullOrWhiteSpace(dntFlag) && dntFlag == "1"; if (dnt) { return(Redirect(linkEntry.OriginUrl)); } try { var req = new LinkTrackingRequest(ip, UserAgent, linkEntry.Id); await _linkForwarderService.TrackSucessRedirectionAsync(req); } catch (Exception e) { // Eat exception, pretend everything is fine // Do not block workflow here _logger.LogError(e.Message, e); } return(Redirect(linkEntry.OriginUrl)); }