Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated created datetime to utc #784

Merged
merged 6 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 82 additions & 77 deletions src/Authorization/Helpers/EventLogHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
#nullable enable

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel.Tokens.Jwt;
Expand Down Expand Up @@ -33,29 +35,26 @@
/// <param name="contextRespsonse">the http context response</param>
/// <param name="currentDateTime">the current date time</param>
/// <returns></returns>
public static AuthorizationEvent MapAuthorizationEventFromContextRequest(XacmlContextRequest contextRequest, HttpContext context, XacmlContextResponse contextRespsonse, DateTime currentDateTime)
public static AuthorizationEvent MapAuthorizationEventFromContextRequest(XacmlContextRequest contextRequest, HttpContext context, XacmlContextResponse contextRespsonse, DateTimeOffset currentDateTime)
{
AuthorizationEvent authorizationEvent = null;
if (contextRequest != null)
(string resource, string instanceId, int? resourcePartyId) = GetResourceAttributes(contextRequest);
(int? userId, int? partyId, string org, int? orgNumber, string? sessionId) = GetSubjectInformation(contextRequest);
AuthorizationEvent authorizationEvent = new AuthorizationEvent
{
authorizationEvent = new AuthorizationEvent();
(string resource, string instanceId, int? resourcePartyId) = GetResourceAttributes(contextRequest);
(int? userId, int? partyId, string org, int? orgNumber, string? sessionId) = GetSubjectInformation(contextRequest);
authorizationEvent.SessionId = sessionId;
authorizationEvent.Created = currentDateTime;
authorizationEvent.Resource = resource;
authorizationEvent.SubjectUserId = userId;
authorizationEvent.SubjectOrgCode = org;
authorizationEvent.SubjectOrgNumber = orgNumber;
authorizationEvent.InstanceId = instanceId;
authorizationEvent.SubjectParty = partyId;
authorizationEvent.ResourcePartyId = resourcePartyId;
authorizationEvent.Operation = GetActionInformation(contextRequest);
authorizationEvent.TimeToDelete = authorizationEvent.Created.AddYears(3);
authorizationEvent.IpAdress = GetClientIpAddress(context);
authorizationEvent.ContextRequestJson = JsonSerializer.Serialize(contextRequest);
authorizationEvent.Decision = contextRespsonse.Results?.FirstOrDefault()?.Decision;
}
SessionId = sessionId,
Created = currentDateTime,
Resource = resource,
SubjectUserId = userId,
SubjectOrgCode = org,
SubjectOrgNumber = orgNumber,
InstanceId = instanceId,
SubjectParty = partyId,
ResourcePartyId = resourcePartyId,
Operation = GetActionInformation(contextRequest),
IpAdress = GetClientIpAddress(context),
ContextRequestJson = JsonSerializer.Serialize(contextRequest),
Decision = contextRespsonse.Results?.FirstOrDefault()?.Decision,
};

return authorizationEvent;
}
Expand All @@ -73,36 +72,39 @@
string org = string.Empty;
string app = string.Empty;

foreach (XacmlContextAttributes attr in request.Attributes.Where(attr => attr.Category.OriginalString.Equals(XacmlConstants.MatchAttributeCategory.Resource)))
if (request != null)
{
foreach (XacmlAttribute xacmlAtr in attr.Attributes)
foreach (XacmlContextAttributes attr in request.Attributes.Where(attr => attr.Category.OriginalString.Equals(XacmlConstants.MatchAttributeCategory.Resource)))
{
if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.ResourceRegistry))
{
resource = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.AppAttribute))
{
app = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.OrgAttribute))
foreach (XacmlAttribute xacmlAtr in attr.Attributes)
{
org = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.InstanceAttribute))
{
instanceId = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.PartyAttribute))
{
resourcePartyId = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.ResourceRegistry))
{
resource = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.AppAttribute))
{
app = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.OrgAttribute))
{
org = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.InstanceAttribute))
{
instanceId = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.PartyAttribute))
{
resourcePartyId = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
}
}
}
}
}

resource = string.IsNullOrEmpty(resource) ? $"app_{org}_{app}" : resource;
return (resource, instanceId, resourcePartyId);
Expand All @@ -113,44 +115,47 @@
/// </summary>
/// <param name="request">The requestId</param>
/// <returns></returns>
public static (int? UserId, int? PartyId, string Org, int? OrgNumber, string? sessionId) GetSubjectInformation(XacmlContextRequest request)
public static (int? UserId, int? PartyId, string Org, int? OrgNumber, string? SessionId) GetSubjectInformation(XacmlContextRequest request)
{
int? userId = null;
int? partyId = null;
string org = string.Empty;
int? orgNumber = null;
string? sessionId = null;

foreach (XacmlContextAttributes attr in request.Attributes.Where(attr => attr.Category.OriginalString.Equals(XacmlConstants.MatchAttributeCategory.Subject)))
if (request != null)
{
foreach (XacmlAttribute xacmlAtr in attr.Attributes)
foreach (XacmlContextAttributes attr in request.Attributes.Where(attr => attr.Category.OriginalString.Equals(XacmlConstants.MatchAttributeCategory.Subject)))
{
if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute))
foreach (XacmlAttribute xacmlAtr in attr.Attributes)
{
userId = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.PartyAttribute))
{
partyId = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.OrgAttribute))
{
org = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.OrgNumberAttribute))
{
orgNumber = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.SessionIdAttribute))
{
sessionId = xacmlAtr.AttributeValues.First().Value;
if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.UserAttribute))
{
userId = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.PartyAttribute))
{
partyId = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.OrgAttribute))
{
org = xacmlAtr.AttributeValues.First().Value;
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.OrgNumberAttribute))
{
orgNumber = Convert.ToInt32(xacmlAtr.AttributeValues.First().Value);
}

if (xacmlAtr.AttributeId.OriginalString.Equals(AltinnXacmlConstants.MatchAttributeIdentifiers.SessionIdAttribute))
{
sessionId = xacmlAtr.AttributeValues.First().Value;
}
}
}
}
}

return (userId, partyId, org, orgNumber, sessionId);
}
Expand All @@ -164,17 +169,17 @@
{
string actionId = string.Empty;

foreach (XacmlContextAttributes attr in request.Attributes.Where(attr => attr.Category.OriginalString.Equals(XacmlConstants.MatchAttributeCategory.Action)))
if (request != null)
{
foreach (XacmlAttribute xacmlAtr in attr.Attributes)
foreach (XacmlContextAttributes attr in request.Attributes.Where(attr => attr.Category.OriginalString.Equals(XacmlConstants.MatchAttributeCategory.Action)))
{
if (xacmlAtr.AttributeId.OriginalString.Equals(XacmlConstants.MatchAttributeIdentifiers.ActionId))
foreach (XacmlAttribute xacmlAtr in attr.Attributes.Where(attr => attr.AttributeId.OriginalString.Equals(XacmlConstants.MatchAttributeIdentifiers.ActionId, StringComparison.Ordinal)))
{
actionId = xacmlAtr.AttributeValues.First().Value;
}
}
}

return actionId;
}

Expand All @@ -185,8 +190,8 @@
/// <returns></returns>
public static string GetClientIpAddress(HttpContext context)
{
string[] clientIpList = context?.Request?.Headers?.GetCommaSeparatedValues("x-forwarded-for");

Check warning on line 193 in src/Authorization/Helpers/EventLogHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Converting null literal or possible null value to non-nullable type.

Check warning on line 193 in src/Authorization/Helpers/EventLogHelper.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Converting null literal or possible null value to non-nullable type.

Check warning on line 193 in src/Authorization/Helpers/EventLogHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze

Converting null literal or possible null value to non-nullable type.
return clientIpList?.Length > 0 ? clientIpList[0] : null;

Check warning on line 194 in src/Authorization/Helpers/EventLogHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

Possible null reference return.

Check warning on line 194 in src/Authorization/Helpers/EventLogHelper.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Possible null reference return.

Check warning on line 194 in src/Authorization/Helpers/EventLogHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze

Possible null reference return.
}
}
}
23 changes: 10 additions & 13 deletions src/Authorization/Models/EventLog/AuthorizationEvent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
#nullable enable

using System;
using Altinn.Authorization.ABAC.Xacml;

namespace Altinn.Platform.Authorization.Models.EventLog
Expand All @@ -14,9 +16,9 @@ public class AuthorizationEvent
public string? SessionId { get; set; }

/// <summary>
/// Date, time of the authorization event. Set by producer of logevents
/// Date and time of the authorization event. Set by producer of logevents
/// </summary>
public DateTime Created { get; set; }
public DateTimeOffset? Created { get; set; }

/// <summary>
/// The userid for the user that requested authorization
Expand All @@ -26,7 +28,7 @@ public class AuthorizationEvent
/// <summary>
/// The org code for the org that requested authorization
/// </summary>
public string SubjectOrgCode { get; set; }
public string? SubjectOrgCode { get; set; }

/// <summary>
/// The org number for the org that requested authorization
Expand All @@ -46,22 +48,17 @@ public class AuthorizationEvent
/// <summary>
/// The Main resource Id (app, external resource +)
/// </summary>
public string Resource { get; set; }
public string? Resource { get; set; }

/// <summary>
/// Instance Id when applicable
/// </summary>
public string InstanceId { get; set; }
public string? InstanceId { get; set; }

/// <summary>
/// Type of operation
/// </summary>
public string Operation { get; set; }

/// <summary>
/// Duration of log retention
/// </summary>
public DateTime TimeToDelete { get; set; }
public required string Operation { get; set; }

/// <summary>
/// The Ip adress of the calling party
Expand All @@ -71,7 +68,7 @@ public class AuthorizationEvent
/// <summary>
/// The enriched context request
/// </summary>
public string ContextRequestJson { get; set; }
public required string ContextRequestJson { get; set; }

/// <summary>
/// Decision for the authorization request
Expand Down
2 changes: 1 addition & 1 deletion src/Authorization/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;

Check warning on line 1 in src/Authorization/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze

Refactor this top-level file to reduce its Cognitive Complexity from 30 to the 15 allowed. (https://rules.sonarsource.com/csharp/RSPEC-3776)
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
Expand Down Expand Up @@ -127,7 +127,7 @@
{
string basePath = Directory.GetParent(Directory.GetCurrentDirectory()).FullName;

logger.LogInformation($"Program // Loading Configuration from basePath={basePath}");

Check warning on line 130 in src/Authorization/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze

Don't use string interpolation in logging message templates. (https://rules.sonarsource.com/csharp/RSPEC-2629)

config.SetBasePath(basePath);
string configJsonFile1 = $"{basePath}/altinn-appsettings/altinn-dbsettings-secret.json";
Expand All @@ -138,7 +138,7 @@
configJsonFile2 = "/app/appsettings.json";
}

logger.LogInformation($"Loading configuration file: '{configJsonFile1}'");

Check warning on line 141 in src/Authorization/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze

Don't use string interpolation in logging message templates. (https://rules.sonarsource.com/csharp/RSPEC-2629)
config.AddJsonFile(configJsonFile1, optional: true, reloadOnChange: true);

logger.LogInformation($"Loading configuration file2: '{configJsonFile2}'");
Expand Down Expand Up @@ -240,7 +240,7 @@
services.AddTransient<ISigningCredentialsResolver, SigningCredentialsResolver>();
services.AddSingleton<IEventsQueueClient, EventsQueueClient>();
services.AddSingleton<IEventLog, EventLogService>();
services.AddSingleton<ISystemClock, SystemClock>();
services.TryAddSingleton(TimeProvider.System);
GeneralSettings generalSettings = config.GetSection("GeneralSettings").Get<GeneralSettings>();
services.AddAuthentication(JwtCookieDefaults.AuthenticationScheme)
.AddJwtCookie(JwtCookieDefaults.AuthenticationScheme, options =>
Expand Down Expand Up @@ -281,7 +281,7 @@

if (!string.IsNullOrEmpty(applicationInsightsConnectionString))
{
services.AddSingleton(typeof(ITelemetryChannel), new ServerTelemetryChannel() { StorageFolder = "/tmp/logtelemetry" });

Check warning on line 284 in src/Authorization/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze

Make sure publicly writable directories are used safely here. (https://rules.sonarsource.com/csharp/RSPEC-5443)
services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions
{
ConnectionString = applicationInsightsConnectionString
Expand All @@ -291,7 +291,7 @@
services.AddApplicationInsightsTelemetryProcessor<IdentityTelemetryFilter>();
services.AddSingleton<ITelemetryInitializer, CustomTelemetryInitializer>();

logger.LogInformation("Startup // ApplicationInsightsConnectionString = {applicationInsightsConnectionString}", applicationInsightsConnectionString);

Check warning on line 294 in src/Authorization/Program.cs

View workflow job for this annotation

GitHub Actions / Analyze

Use PascalCase for named placeholders. (https://rules.sonarsource.com/csharp/RSPEC-6678)
}

services.AddMvc(options =>
Expand Down
13 changes: 7 additions & 6 deletions src/Authorization/Services/Implementation/EventLogService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -20,17 +21,17 @@ namespace Altinn.Platform.Authorization.Services.Implementation
public class EventLogService : IEventLog
{
private readonly IEventsQueueClient _queueClient;
private readonly ISystemClock _systemClock;
private readonly TimeProvider _timeProvider;

/// <summary>
/// Instantiation for event log servcie
/// </summary>
/// <param name="queueClient">queue client to store event in event log</param>
/// <param name="systemClock">handler for datetime service</param>
public EventLogService(IEventsQueueClient queueClient, ISystemClock systemClock)
/// <param name="timeProvider">handler for datetime service</param>
public EventLogService(IEventsQueueClient queueClient, TimeProvider timeProvider)
{
_queueClient = queueClient;
_systemClock = systemClock;
_timeProvider = timeProvider;
}

/// <summary>
Expand All @@ -53,7 +54,7 @@ public async Task CreateAuthorizationEvent(IFeatureManager featureManager, Xacml
options.Converters.Add(new JsonStringEnumConverter());
if (await featureManager.IsEnabledAsync(FeatureFlags.AuditLog))
{
AuthorizationEvent authorizationEvent = EventLogHelper.MapAuthorizationEventFromContextRequest(contextRequest, context, contextResponse, _systemClock.UtcNow.DateTime);
AuthorizationEvent authorizationEvent = EventLogHelper.MapAuthorizationEventFromContextRequest(contextRequest, context, contextResponse, _timeProvider.GetUtcNow());

if (authorizationEvent != null)
{
Expand Down
Loading
Loading