Skip to content

Commit

Permalink
Introduce PackageRegistrationAuditRecord
Browse files Browse the repository at this point in the history
  • Loading branch information
maartenba committed Jun 17, 2016
1 parent 3b5f924 commit d1d291b
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 54 deletions.
2 changes: 0 additions & 2 deletions src/NuGetGallery.Core/Auditing/PackageAuditAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public enum PackageAuditAction
Created,
Listed,
Unlisted,
AddOwner,
RemoveOwner,
Edit,
UndoEdit
}
Expand Down
51 changes: 5 additions & 46 deletions src/NuGetGallery.Core/Auditing/PackageAuditRecord.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;

namespace NuGetGallery.Auditing
{
Expand Down Expand Up @@ -34,58 +30,21 @@ public PackageAuditRecord(string id, string version, string hash, DataTable pack
public PackageAuditRecord(Package package, PackageAuditAction action, string reason)
: this(package.PackageRegistration.Id, package.Version, package.Hash, null, null, action, reason)
{
PackageRecord = ConvertToDataTable(package);
RegistrationRecord = ConvertToDataTable(package.PackageRegistration);
PackageRecord = DataTableUtility.ConvertToDataTable(package);
RegistrationRecord = DataTableUtility.ConvertToDataTable(package.PackageRegistration);
}

public PackageAuditRecord(Package package, PackageAuditAction action)
: this(package.PackageRegistration.Id, package.Version, package.Hash, null, null, action, null)
{
PackageRecord = ConvertToDataTable(package);
RegistrationRecord = ConvertToDataTable(package.PackageRegistration);
PackageRecord = DataTableUtility.ConvertToDataTable(package);
RegistrationRecord = DataTableUtility.ConvertToDataTable(package.PackageRegistration);
}

public PackageAuditRecord(PackageRegistration packageRegistration, PackageAuditAction action, string reason)
: this(packageRegistration.Id, "0.0", null, null, null, action, reason)
{
RegistrationRecord = ConvertToDataTable(packageRegistration);
}


public override string GetPath()
{
return $"{Id}/{NuGetVersionNormalizer.Normalize(Version)}"
.ToLowerInvariant();
}

private static DataTable ConvertToDataTable<T>(T instance)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable() { Locale = CultureInfo.CurrentCulture };

List<object> values = new List<object>();
for (int i = 0; i < properties.Count; i++)
{
var propertyDescriptor = properties[i];
var propertyType = Nullable.GetUnderlyingType(propertyDescriptor.PropertyType) ?? propertyDescriptor.PropertyType;
if (!IsComplexType(propertyType))
{
table.Columns.Add(propertyDescriptor.Name, propertyType);
values.Add(propertyDescriptor.GetValue(instance) ?? DBNull.Value);
}
}

table.Rows.Add(values.ToArray());

return table;
}

private static bool IsComplexType(Type type)
{
if (type.IsSubclassOf(typeof(ValueType)) || type == typeof(string))
{
return false;
}
return true;
}
}
}
11 changes: 11 additions & 0 deletions src/NuGetGallery.Core/Auditing/PackageRegistrationAuditAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace NuGetGallery.Auditing
{
public enum PackageRegistrationAuditAction
{
AddOwner,
RemoveOwner
}
}
33 changes: 33 additions & 0 deletions src/NuGetGallery.Core/Auditing/PackageRegistrationAuditRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Data;

namespace NuGetGallery.Auditing
{
public class PackageRegistrationAuditRecord : AuditRecord<PackageRegistrationAuditAction>
{
public string Id { get; set; }
public DataTable RegistrationRecord { get; set; }

public string Reason { get; set; }

public PackageRegistrationAuditRecord(string id, DataTable registrationRecord, PackageRegistrationAuditAction action, string reason)
: base(action)
{
Id = id;
RegistrationRecord = registrationRecord;
Reason = reason;
}

public PackageRegistrationAuditRecord(PackageRegistration packageRegistration, PackageRegistrationAuditAction action, string reason)
: this(packageRegistration.Id, DataTableUtility.ConvertToDataTable(packageRegistration), action, reason)
{
}

public override string GetPath()
{
return $"{Id}".ToLowerInvariant();
}
}
}
45 changes: 45 additions & 0 deletions src/NuGetGallery.Core/DataTableUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;

namespace NuGetGallery
{
public static class DataTableUtility
{
public static DataTable ConvertToDataTable<T>(T instance)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable() { Locale = CultureInfo.CurrentCulture };

List<object> values = new List<object>();
for (int i = 0; i < properties.Count; i++)
{
var propertyDescriptor = properties[i];
var propertyType = Nullable.GetUnderlyingType(propertyDescriptor.PropertyType) ?? propertyDescriptor.PropertyType;
if (!IsComplexType(propertyType))
{
table.Columns.Add(propertyDescriptor.Name, propertyType);
values.Add(propertyDescriptor.GetValue(instance) ?? DBNull.Value);
}
}

table.Rows.Add(values.ToArray());

return table;
}

private static bool IsComplexType(Type type)
{
if (type.IsSubclassOf(typeof(ValueType)) || type == typeof(string))
{
return false;
}
return true;
}
}
}
3 changes: 3 additions & 0 deletions src/NuGetGallery.Core/NuGetGallery.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,14 @@
<Compile Include="Auditing\CredentialAuditRecord.cs" />
<Compile Include="Auditing\PackageAuditAction.cs" />
<Compile Include="Auditing\PackageAuditRecord.cs" />
<Compile Include="Auditing\PackageRegistrationAuditAction.cs" />
<Compile Include="Auditing\PackageRegistrationAuditRecord.cs" />
<Compile Include="Auditing\UserAuditAction.cs" />
<Compile Include="Auditing\UserAuditRecord.cs" />
<Compile Include="CoreConstants.cs" />
<Compile Include="CredentialTypes.cs" />
<Compile Include="Completion.cs" />
<Compile Include="DataTableUtility.cs" />
<Compile Include="DisposableAction.cs" />
<Compile Include="Entities\Credential.cs" />
<Compile Include="Entities\CuratedFeed.cs" />
Expand Down
6 changes: 4 additions & 2 deletions src/NuGetGallery/Services/PackageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ public async Task AddPackageOwnerAsync(PackageRegistration package, User user)
await _packageOwnerRequestRepository.CommitChangesAsync();
}

await _auditingService.SaveAuditRecord(new PackageAuditRecord(package, PackageAuditAction.AddOwner, $"Added owner: {user.Username}"));
await _auditingService.SaveAuditRecord(
new PackageRegistrationAuditRecord(package, PackageRegistrationAuditAction.AddOwner, $"Added owner: {user.Username}"));
}

public async Task RemovePackageOwnerAsync(PackageRegistration package, User user)
Expand All @@ -270,7 +271,8 @@ public async Task RemovePackageOwnerAsync(PackageRegistration package, User user
package.Owners.Remove(user);
await _packageRepository.CommitChangesAsync();

await _auditingService.SaveAuditRecord(new PackageAuditRecord(package, PackageAuditAction.RemoveOwner, $"Removed owner: {user.Username}"));
await _auditingService.SaveAuditRecord(
new PackageRegistrationAuditRecord(package, PackageRegistrationAuditAction.RemoveOwner, $"Removed owner: {user.Username}"));
}

public async Task MarkPackageListedAsync(Package package, bool commitChanges = true)
Expand Down
8 changes: 4 additions & 4 deletions tests/NuGetGallery.Facts/Services/PackageServiceFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ public async Task WritesAnAuditRecord()
await service.AddPackageOwnerAsync(package, pendingOwner);

// Assert
Assert.True(auditingService.WroteRecord<PackageAuditRecord>(ar =>
ar.Action == PackageAuditAction.AddOwner
Assert.True(auditingService.WroteRecord<PackageRegistrationAuditRecord>(ar =>
ar.Action == PackageRegistrationAuditAction.AddOwner
&& ar.Id == package.Id));
}
}
Expand Down Expand Up @@ -1907,8 +1907,8 @@ public async Task WritesAnAuditRecord()
await service.RemovePackageOwnerAsync(package, ownerToRemove);

// Assert
Assert.True(auditingService.WroteRecord<PackageAuditRecord>(ar =>
ar.Action == PackageAuditAction.RemoveOwner
Assert.True(auditingService.WroteRecord<PackageRegistrationAuditRecord>(ar =>
ar.Action == PackageRegistrationAuditAction.RemoveOwner
&& ar.Id == package.Id));
}
}
Expand Down

0 comments on commit d1d291b

Please sign in to comment.