3

I'm implementing workflow for page. I want to associate workflow definition to structure group to start workflow, but I have a problem about security rights.

There are following users.

  • User A : Administrator who have 'Workflow Management' right.
  • User B : Editor who does not have 'Workflow Management' right.

On my implementation, User B creates structure group. But User B cannot asscociate workflow definition to structure group because he doesn't have 'Workflow Management' right. I made event system that associate workflow definition to structure group when it's saved, but same problem occured(Tridion says 'You do not have permission to perform this action'). My event system code looks like this.I try to run my program by "administrator" user.

public void Subscribe()
{
    EventSystem.Subscribe<StructureGroup, SaveEventArgs>(SetWorkflowToSG, EventPhases.Initiated);
}

private void SetWorkflowToSG(StructureGroup sg, SaveEventArgs args, EventPhases phase)
{
    Session session = new Session("administrator");

    ProcessDefinition pd = (ProcessDefinition)session.GetObject("tcm:5-21-131074");
    sg.PageProcess = pd;

}

How can I achive my requirement that User B creates structure group and associtate workflow definition to it?

Following answers, I modified source code. It works fine.

public void Subscribe()
{
    Subscriptions.Add(EventSystem.Subscribe<StructureGroup, SaveEventArgs>(SetWorkflowToSG, EventPhases.TransactionCommitted));
}

private void SetWorkflowToSG(StructureGroup sg, SaveEventArgs args, EventPhases phase)
{
    //To avoid infinite loop, check value in Session.ContextData
    if(!sg.Session.ContextData.ContainsKey("isTriggeredByEvent")){
        Session newSession = new Session("administrator");

        StructureGroup newSg = (StructureGroup)newSession.GetObject(sg.Id);
        ProcessDefinition pd = (ProcessDefinition)newSession.GetObject("tcm:5-21-131074");
        newSg.PageProcess = pd;

        //Add value to Session.ContextData
        newSg.Session.ContextData.Add(new KeyValuePair<string, object>("isTriggeredByEvent", true));

        newSg.Save();
        newSession.Dispose();
    }
}

Regards,

  • I tried using the above code to set the workflow for the Structure Group, It's working for first time. If I tried updating and saving the same Structure Group it's showing " You don't have enough permission to do that". – Target Jan 11 '17 at 11:16
5

The reason why you still get a permission denied error in your example is that your StructureGroup object is still in the original user's Session and not in your "administrator" Session; you do obtain the ProcessDefinition in that Session, but for the security check, it's the Session of the SG object that matters.

In your case, the StructureGroup object is the subject of the event and you can't change the Session of an existing object (fortunately!). You could implement a transaction committed event handler instead which gets the SG in a privileged Session and do an additional Save in the event handler.

Furthermore, please ensure that you Dispose any Session that you create!

As Nuno pointed out, impersonation in event handlers is tricky in general; depending on the host that triggered the event, it may work or not and you may have to configure additional impersonation users to make it work in all scenarios.

  • It works when getting structure group object by new session in transaction committed event and save it. But it causes infinite loop because it trigger save event again.To avoid the infinite loop I added flag to Session.ContextData.I couldn't pass flag by EventArgs.ContextVarialbe or EventStack. And at least my case, it works even if new session is not 'NT AUTHORITY\NETWORK SERVICE'.I added new source code to first question. – Hirokazu Shikata Feb 20 '15 at 2:49
  • Good. Instead of using Session Context Data, you could also test whether the Process Definition is already set (that would also prevent overwriting a value set by a user that does have WF management rights). Furthermore, use the C# using statement to ensure the Session gets disposed even in case of an eception. – Rick Pannekoek Feb 20 '15 at 16:21
  • I tried using the above code to set the workflow for the Structure Group, It's working for first time. If I tried updating and saving the same Structure Group it's showing " You don't have enough permission to do that". – Target Jan 11 '17 at 11:18
1

This is actually a very challenging thing to do (I know, I've worked on this problem a few times). In the next release we're addressing this problem with process elevation rights, but for now this is the only way I could come up with an answer.

The main challenge you have is that Impersonating another user can only be done by users listed in your "Impersonation Users" list in Tridion configuration. Typically, only the "Network Service" account is allowed to impersonate another user. Therefore, when your event system is executing - using the account of the user that triggered the event - your call for a new session as Administrator will not work, because the current user is not a valid impersonation user.

I've worked around this before by writing a small WebService that runs in the CM website under the "Network Service" account, and I call this webservice from the Event System, passing on the URIs of the Structure Group and workflow process I want to associate with it. Then, in the WebService I impersonate an administrator account and set these properties.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.