[DevExpress Support Team: CLONED FROM T418166: How to upgrade an existing project to the Allow/Deny permission policy (migrate to PermissionPolicyUser and PermissionPolicyRole)]
Here is my scenario:
Other than some SQL contained in RDL (SSRS) reports I do not have any direct references to SecuritySystemUser, so that's not a big deal to take care of.
I have a custom class (User) derived from SecuritySystemUser
I do not wish to change Oid to string values on any references or associations to User so seems the CodeProject solution mostly deals with this.
Questions:
-
How do I handle in a single pass changing my User class to be derived from PermissionPolicyUser wihtout requiring a 2nd build version to be deployed after conversion?
-
What are other considerations of having a custom User class and trying to migrate in ModuleUpdater?
-
I would also like to copy the password, so it does look like part of the CodeProject example would be of benefit for copying just the user objects, especially since I want to preserve the existing Oid values for user objects (not necessarily for roles/permissions) as there are many objects that reference this.
Making some progress. I was able to get User and SystemSecurityUser to convert to PermissionPolicyUser and handle all the references…
However, when it gets to the CopyUser loop, no objects are returned in ObjectSpace.GetObjects<SecuritySystemUser>() even though there is still data there. I don't get any errors and looking at SQL profiler, nothing is hitting the database.
C#// UpdateDatabaseBeforeUpdateSchema
public override void UpdateDatabaseBeforeUpdateSchema() {
base.UpdateDatabaseBeforeUpdateSchema();
if (CurrentDBVersion < new Version("1.0.6450.23803") && CurrentDBVersion > new Version("0.0.0.0")) {
ExecuteNonQueryCommand("ALTER TABLE AuditDataItemPersistent ALTER COLUMN OldValue Nvarchar(MAX)", true);
ExecuteNonQueryCommand("ALTER TABLE AuditDataItemPersistent ALTER COLUMN NewValue Nvarchar(MAX)", true);
}
if (CurrentDBVersion < new Version("1.0.6612.31390") && CurrentDBVersion > new Version("0.0.0.0"))
{
// drop constraint so new PermissionPolicyUser table can be created
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[User] DROP CONSTRAINT [FK_User_Oid]", false);
// SELECT * INTO temp_User FROM [User]
ExecuteNonQueryCommand(@"SELECT * INTO temp_User FROM [User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[Class] NOCHECK CONSTRAINT [FK_Class_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[Client] NOCHECK CONSTRAINT [FK_Client_Staff]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[ClientCase] NOCHECK CONSTRAINT [FK_ClientCase_Counselor]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[ClientViewAudit] NOCHECK CONSTRAINT [FK_ClientViewAudit_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[FollowUp] NOCHECK CONSTRAINT [FK_FollowUp_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[FollowUp] NOCHECK CONSTRAINT [FK_FollowUp_CompletedBy]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[LoginAudit] NOCHECK CONSTRAINT [FK_LoginAudit_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[UsersXLocations] NOCHECK CONSTRAINT [FK_UsersXLocations_Users]", false);
// DELETE from [User]
ExecuteNonQueryCommand(@"DELETE FROM [User]", false);
}
}
C# public override void UpdateDatabaseAfterUpdateSchema() {
base.UpdateDatabaseAfterUpdateSchema();
if (CurrentDBVersion < new Version("1.0.6612.31390") && CurrentDBVersion > new Version("0.0.0.0")) {
// convert SecuritySystem to PermissionPolicy
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[User] NOCHECK CONSTRAINT [FK_User_Oid]", false);
ExecuteNonQueryCommand(@"INSERT INTO PermissionPolicyUser (Oid, UserName, StoredPassword, ChangePasswordOnFirstLogon, IsActive, ObjectType, OptimisticLockField)
SELECT Oid, UserName, StoredPassword, ChangePasswordOnFirstLogon, IsActive, ObjectType, OptimisticLockField
FROM SecuritySystemUser", false);
ExecuteNonQueryCommand(@"INSERT INTO [User] SELECT * from temp_User", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[User] CHECK CONSTRAINT [FK_User_Oid]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[Class] CHECK CONSTRAINT [FK_Class_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[Client] CHECK CONSTRAINT [FK_Client_Staff]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[ClientCase] CHECK CONSTRAINT [FK_ClientCase_Counselor]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[ClientViewAudit] CHECK CONSTRAINT [FK_ClientViewAudit_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[FollowUp] CHECK CONSTRAINT [FK_FollowUp_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[FollowUp] CHECK CONSTRAINT [FK_FollowUp_CompletedBy]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[LoginAudit] CHECK CONSTRAINT [FK_LoginAudit_User]", false);
ExecuteNonQueryCommand(@"ALTER TABLE [dbo].[UsersXLocations] CHECK CONSTRAINT [FK_UsersXLocations_Users]", false);
ExecuteNonQueryCommand(@"DROP TABLE temp_User", false);
// HERE IS THE PROBLEM: NOTHING FOUND IN .GetObjects() for the old types
foreach (SecuritySystemUser securitySystemUser in ObjectSpace.GetObjects<SecuritySystemUser>())
{
CopyUser(securitySystemUser);
}
foreach (SecuritySystemRole securitySystemRole in ObjectSpace.GetObjects<SecuritySystemRole>())
{
CopyRole(securitySystemRole, null);
}
ObjectSpace.CommitChanges();
}
}
I even added this to my module constructor (although I don't believe it's needed)
C#AdditionalExportedTypes.AddRange(new Type[] { typeof(SecuritySystemUser), typeof(SecuritySystemRole) });
So I can log in and I see that it's using the new PermissionPolicyUser object, but I have no roles or permissions
Hello Randy,
The How to upgrade an existing project to the Allow/Deny permission policy (migrate to PermissionPolicyUser and PermissionPolicyRole) article contains only common instructions and recommendations for the migration to the PermissionPolicy classes:
"The main purpose of the following instructions is to simplify the migration as we cannot guarantee that all existing permissions will be converted correctly, because the old classes use different permission mechanisms. Only common scenarios are covered, others may not work, and you would need to manually check if all permissions are converted correctly and update them further yourself in case of any problems."
Also the migration is the complicated process and you can have some issues in unexpected places. Do not forget to make the database backup and thoroughly check the data and permissions settings after the migration.
The most reliable way is to create new PermissionPolicy permissions according to old SecuritySystem permission settings manually and follow the steps in the If you do not need to transfer existing permissions to the new permissions policy part of the migration article:
"invoke the Application Designer for the YourSolutionName.Wxx/WxxApplication.xx file and set the UserType and RoleType properties of the SecurityStrategyComplexcomponent to the PermissionPolicyUser and PermissionPolicyRole values respectively. After that, update your code that creates predefined users, roles and the required permissions as per the Using the Security System help article."
>> no objects are returned in ObjectSpace.GetObjects<SecuritySystemUser>()
Probably the data could be lost while you used direct SQL queries. It is difficult to define the precise cause of this behavior. Try to switch your application back to the SecuritySystem classes, run it and check whether all works fine and the database contains this data.