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

Fixed a serialization issue with PermissionInfo #5943

Closed
Closed
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
53 changes: 32 additions & 21 deletions DNN Platform/Library/Security/Permissions/PermissionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,33 @@ namespace DotNetNuke.Security.Permissions
/// <summary>PermissionInfo provides the Entity Layer for Permissions.</summary>
[Serializable]
public class PermissionInfo : BaseEntityInfo, IPermissionDefinitionInfo
{
/// <inheritdoc cref="IPermissionDefinitionInfo.ModuleDefId" />
{
private int moduleDefId;
private int permissionId;

/// <inheritdoc cref="ModuleDefId" />
[XmlIgnore]
[JsonIgnore]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(IPermissionDefinitionInfo)}.{nameof(IPermissionDefinitionInfo.ModuleDefId)} instead. Scheduled for removal in v11.0.0.")]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(ModuleDefId)} instead. Scheduled for removal in v11.0.0.")]
[CLSCompliant(false)]
public int ModuleDefID
{
get => ((IPermissionDefinitionInfo)this).ModuleDefId;
set => ((IPermissionDefinitionInfo)this).ModuleDefId = value;
get => this.moduleDefId;
set => this.moduleDefId = value;
}

/// <inheritdoc />
[XmlElement("permissioncode")]
public string PermissionCode { get; set; }

/// <inheritdoc cref="IPermissionDefinitionInfo.PermissionID" />
[XmlElement("permissionid")]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(IPermissionDefinitionInfo)}.{nameof(IPermissionDefinitionInfo.PermissionId)} instead. Scheduled for removal in v11.0.0.")]
/// <inheritdoc cref="PermissionId" />
[XmlIgnore]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(PermissionId)} instead. Scheduled for removal in v11.0.0.")]
[CLSCompliant(false)]
public int PermissionID
{
get => ((IPermissionDefinitionInfo)this).PermissionId;
set => ((IPermissionDefinitionInfo)this).PermissionId = value;
get => this.permissionId;
set => this.permissionId = value;
}

/// <inheritdoc />
Expand All @@ -54,25 +59,31 @@ public int PermissionID
/// <inheritdoc />
[XmlIgnore]
[JsonIgnore]
int IPermissionDefinitionInfo.ModuleDefId { get; set; }
public int ModuleDefId
{
get => this.moduleDefId;
set => this.moduleDefId = value;
}

/// <inheritdoc />
[XmlIgnore]
[JsonIgnore]
int IPermissionDefinitionInfo.PermissionId { get; set; }
[XmlElement("permissionid")]
public int PermissionId
{
get => this.permissionId;
set => this.permissionId = value;
}

/// <summary>FillInternal fills a PermissionInfo from a Data Reader.</summary>
/// <param name="dr">The Data Reader to use.</param>
protected override void FillInternal(IDataReader dr)
{
base.FillInternal(dr);

var @this = (IPermissionDefinitionInfo)this;
@this.PermissionId = Null.SetNullInteger(dr["PermissionID"]);
@this.ModuleDefId = Null.SetNullInteger(dr["ModuleDefID"]);
@this.PermissionCode = Null.SetNullString(dr["PermissionCode"]);
@this.PermissionKey = Null.SetNullString(dr["PermissionKey"]);
@this.PermissionName = Null.SetNullString(dr["PermissionName"]);

this.permissionId = Null.SetNullInteger(dr["PermissionID"]);
this.moduleDefId = Null.SetNullInteger(dr["ModuleDefID"]);
this.PermissionCode = Null.SetNullString(dr["PermissionCode"]);
this.PermissionKey = Null.SetNullString(dr["PermissionKey"]);
this.PermissionName = Null.SetNullString(dr["PermissionName"]);
}
}
}
47 changes: 25 additions & 22 deletions DNN Platform/Library/Security/Permissions/PermissionInfoBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,20 @@ public string DisplayName
}
}

/// <inheritdoc cref="IPermissionInfo.RoleId" />
[XmlElement("roleid")]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(IPermissionInfo)}.{nameof(IPermissionInfo.RoleId)} instead. Scheduled for removal in v11.0.0.")]
/// <inheritdoc cref="RoleId" />
[XmlIgnore]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(RoleId)} instead. Scheduled for removal in v11.0.0.")]
[CLSCompliant(false)]
public int RoleID
{
get
{
return ((IPermissionInfo)this).RoleId;
return this.roleId;
}

set
{
((IPermissionInfo)this).RoleId = value;
this.roleId = value;
}
}

Expand All @@ -107,19 +108,20 @@ public string RoleName
}
}

/// <inheritdoc cref="IPermissionInfo.UserId" />
[XmlElement("userid")]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(IPermissionInfo)}.{nameof(IPermissionInfo.UserId)} instead. Scheduled for removal in v11.0.0.")]
/// <inheritdoc cref="UserId"/>
[XmlIgnore]
[Obsolete($"Deprecated in DotNetNuke 9.13.1. Use {nameof(UserId)} instead. Scheduled for removal in v11.0.0.")]
[CLSCompliant(false)]
public int UserID
{
get
{
return ((IPermissionInfo)this).UserId;
return this.userId;
}

set
{
((IPermissionInfo)this).UserId = value;
this.userId = value;
}
}

Expand All @@ -139,14 +141,16 @@ public string Username
}

/// <inheritdoc />
int IPermissionInfo.RoleId
[XmlElement("roleid")]
public int RoleId
{
get => this.roleId;
set => this.roleId = value;
}

/// <inheritdoc />
int IPermissionInfo.UserId
[XmlElement("userid")]
public int UserId
{
get => this.userId;
set => this.userId = value;
Expand All @@ -159,22 +163,21 @@ protected override void FillInternal(IDataReader dr)
// Call the base classes fill method to populate base class properties
base.FillInternal(dr);

var @this = (IPermissionInfo)this;
@this.UserId = Null.SetNullInteger(dr["UserID"]);
@this.Username = Null.SetNullString(dr["Username"]);
@this.DisplayName = Null.SetNullString(dr["DisplayName"]);
if (@this.UserId == Null.NullInteger)
this.userId = Null.SetNullInteger(dr["UserID"]);
this.username = Null.SetNullString(dr["Username"]);
this.displayName = Null.SetNullString(dr["DisplayName"]);
if (this.userId == Null.NullInteger)
{
@this.RoleId = Null.SetNullInteger(dr["RoleID"]);
@this.RoleName = Null.SetNullString(dr["RoleName"]);
this.roleId = Null.SetNullInteger(dr["RoleID"]);
this.roleName = Null.SetNullString(dr["RoleName"]);
}
else
{
@this.RoleId = int.Parse(Globals.glbRoleNothing);
@this.RoleName = string.Empty;
this.roleId = int.Parse(Globals.glbRoleNothing);
this.roleName = string.Empty;
}

@this.AllowAccess = Null.SetNullBoolean(dr["AllowAccess"]);
this.allowAccess = Null.SetNullBoolean(dr["AllowAccess"]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@
<Compile Include="Providers\Membership\MembershipProviderTests.cs" />
<Compile Include="Providers\Permissions\PermissionTests.cs" />
<Compile Include="RetryableActionTests.cs" />
<Compile Include="Security\Permissions\PermissionInfoBaseTests.cs" />
<Compile Include="Security\Permissions\PermissionInfoTests.cs" />
<Compile Include="Security\Permissions\PermissionProviderTests.cs" />
<Compile Include="Security\PortalSecurity\PortalSecurityTest.cs" />
<Compile Include="Services\ClientCapability\FacebookRequestControllerTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace DotNetNuke.Tests.Core.Security.Permissions
{
using DotNetNuke.Common.Utilities;
using DotNetNuke.Security.Permissions;
using NUnit.Framework;

[TestFixture]
public class PermissionInfoBaseTests
{
[Test]
public void SerializesXMLProperly()
{
// Arrange
var derived = new DerivedPermissionInfo
{
AllowAccess = true,
DisplayName = "Test Name",
RoleID = 123,
RoleName = "Test Role",
UserID = 234,
Username = "Test User",
};

// Act
var xml = XmlUtils.Serialize(derived);

// Assert
Assert.IsNotNull(xml);
Assert.True(xml.Contains("allowaccess"));
Assert.True(xml.Contains("displayname"));
Assert.True(xml.Contains("roleid"));
Assert.True(xml.Contains("rolename"));
Assert.True(xml.Contains("userid"));
Assert.True(xml.Contains("username"));
}
}

public class DerivedPermissionInfo : PermissionInfoBase
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace DotNetNuke.Tests.Core.Security.Permissions
{
using System;
using System.IO;
using System.Text;

using DotNetNuke.Abstractions.Security.Permissions;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Security.Permissions;
using NUnit.Framework;

[TestFixture]
public class PermissionInfoTests
{
[Test]
public void SerializesJson_IncluddingObsoleteProperties()
{
// Arrange
var permissionInfo = new PermissionInfo
{
ModuleDefID = 123,
PermissionCode = "test",
PermissionID = 456,
PermissionKey = "testKey",
PermissionName = "testName",
};

// Act
var json = Json.Serialize(permissionInfo);

// Assert
Assert.NotNull(json);
Assert.False(json.Contains(nameof(permissionInfo.ModuleDefId)));
Assert.True(json.Contains(nameof(permissionInfo.PermissionCode)));
Assert.True(json.Contains(nameof(permissionInfo.PermissionID))); // old obsolete casing.
Assert.True(json.Contains(nameof(permissionInfo.PermissionId))); // new casing.
Assert.True(json.Contains(nameof(permissionInfo.PermissionKey)));
Assert.False(json.Contains(nameof(permissionInfo.PermissionName)));
}

[Test]
public void DeserializesJson_Properly()
{
// Arrange
var json = "{\"PermissionCode\":\"test\",\"PermissionID\":456,\"PermissionKey\":\"testKey\"}";

// Act
var permissionInfo = Json.Deserialize<PermissionInfo>(json);

// Assert
Assert.NotNull(permissionInfo);
Assert.AreEqual("test", permissionInfo.PermissionCode);
Assert.AreEqual(456, permissionInfo.PermissionID);
Assert.AreEqual(456, ((IPermissionDefinitionInfo)permissionInfo).PermissionId);
Assert.AreEqual("testKey", permissionInfo.PermissionKey);
}

[Test]
public void SerializesXml_IncludesObsoleteProperties()
{
// Arrange
var permissionInfo = new PermissionInfo
{
ModuleDefID = 123,
PermissionCode = "test",
PermissionID = 456,
PermissionKey = "testKey",
PermissionName = "testName",
};
// Act
var xml = XmlUtils.Serialize(permissionInfo);

// Assert
Assert.NotNull(xml);
Assert.False(xml.IndexOf("moduledefid", StringComparison.OrdinalIgnoreCase) >= 0);
Assert.True(xml.Contains("permissioncode"));
Assert.True(xml.Contains("permissionid"));
Assert.True(xml.Contains("permissionkey"));
Assert.False(xml.IndexOf("permissionname", StringComparison.OrdinalIgnoreCase) >= 0);
}

[Test]
public void Deserializes_Properly()
{
// Arrange
var xml = "<PermissionInfo><permissioncode>test</permissioncode><permissionid>456</permissionid><permissionkey>testKey</permissionkey></PermissionInfo>";
var stream = new MemoryStream();
var writer = new StreamWriter(stream, Encoding.UTF8);
writer.Write(xml);
writer.Flush();
stream.Position = 0;

// Act
var permissionInfo = (PermissionInfo)XmlUtils.Deserialize(stream, typeof(PermissionInfo));

// Assert
Assert.NotNull(permissionInfo);
Assert.AreEqual("test", permissionInfo.PermissionCode);
Assert.AreEqual(456, permissionInfo.PermissionID);
Assert.AreEqual(456, ((IPermissionDefinitionInfo)permissionInfo).PermissionId);
Assert.AreEqual("testKey", permissionInfo.PermissionKey);
}
}
}