Content staging - how can I stage role changes but ignore user changes?

Tom Troughton asked on February 17, 2016 13:17

In Kentico 8.2 I have set up staging to push all my changes from dev through UAT to live.

Each of these environments has its own set of users. I assume this is a very common scenario - it doesn't make sense to have production user accounts in dev. Simple example, in dev I want my global admin account to have an empty password but obviously not in UAT and live.

Therefore I've excluded all changes to users from staging using the following implmentation of CMSLoaderAttribute:

    public override void Init()
        StagingEvents.LogTask.Before += LogTask_Before;

    void LogTask_Before(object sender, CMS.Synchronization.StagingLogTaskEventArgs e)
        // Gets the synchronized object
        BaseInfo synchronizedObject = e.Object;

        // Cancels the creation of content staging tasks for the deletion of role objects
        if (synchronizedObject.TypeInfo.ObjectType == CMS.Membership.UserInfo.OBJECT_TYPE)

However, I do want to be able to configure roles in my dev environment and push these roles through the staging process.

The problem is that after synchronising environments I'm finding that the roles in the target instance have had their users removed. Presumably this is because the synchronisation task doesn't know about these users.

So Kentico is not fully separating roles (which for me are part of the application architecture) from users (which are environment-specific). Is there anything I can do about this? I guess what I want to do is synchronise everything about a role except for its user associations. Is this, or something similar, possible?

Recent Answers

Brenden Kehren answered on February 17, 2016 14:21

1 votesVote for this answer Mark as a Correct answer

Tom Troughton answered on February 17, 2016 15:10

@Brenden That would allow me to exclude specific objects, but I don't see how it answers my question. I'm talking about excluding a specific property of a specific object. I want all properties of my roles to synchronise except for their association with users. I assume that's a common challenge since roles are part of application architecture whilst users are not.

0 votesVote for this answer Mark as a Correct answer

Roman Hutnyk answered on February 17, 2016 15:37

It sounds like you need to sync Roles, but avoid syncing Users and User-to-Role. Try this:

UserInfo.TYPEINFO.LogSynchronization = CMS.DataEngine.SynchronizationTypeEnum.None;
UserRoleInfo.TYPEINFO.LogSynchronization = CMS.DataEngine.SynchronizationTypeEnum.None;
1 votesVote for this answer Mark as a Correct answer

Tom Troughton answered on February 18, 2016 12:54 (last edited on February 18, 2016 13:33)

@Roman Thank you for the advice. However, this also doesn't solve the problem. It does mean that adding/removing users to and from a role in dev will not log staging tasks to replicate the change at a staging target, but unfortunately other changes to the role still serialize the entire role object as a staging task, which includes its users. This causes users to be removed from the role when processed on the target server.

I have raised this with Kentico support who have said that there is no solution beyond extensive customisation of source code. Their work-around is to not synchronise roles which I presume means managing roles manually in each environment. This is not acceptable because CMS security is surely one of the most important things that needs to be tested thoroughly and deployed reliably (i.e. via an automated process).

I am currently regarding this as a fundamental flaw in Kentico so I am looking to escalate to Kentico consultants. Failure to separate application architecture (roles) and live data (users) is extremely poor design and I am therefore pushing for a solution. I will update here if I hear anything.

For the record, I've found that this issue is true also when using export packages.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on February 18, 2016 21:40

I'd think that you can use a global handler in combination with the article I provided to exclude anytime a user, user settings or user roles are updated. Anytime a user's roles are updated so is the user object. So simply speaking, check the object type and if it is a user or user settings or even user roles, then don't log that staging event. Users and roles and user roles are all objects according to Kentico so it doesn't matter if one is part of the application architecture or not, perform a check to see what's being updated.

Thinking about this more, you'd need to check for recursiveness and say if it is a specific recursive key, then update a variable, then continue on with the other updates and if that variable is true, then exclude that update event from the staging log.

I believe the answer of "...there is no solution beyond extensive customization of source code..."is not entirely correct. I believe it is possible, although Kentico won't provide you with a solution unless you pay for it (as any consulting company would require) so even though you think it's a shortcoming, I'm willing to bet it can be done without source code and creating a global handler.

1 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.