{"id":2494,"date":"2013-01-27T06:40:15","date_gmt":"2013-01-27T06:40:15","guid":{"rendered":"https:\/\/www.wapshere.com\/missmiis\/?p=2494"},"modified":"2013-01-27T11:50:42","modified_gmt":"2013-01-27T11:50:42","slug":"r2-authorization-after-action","status":"publish","type":"post","link":"https:\/\/www.wapshere.com\/missmiis\/r2-authorization-after-action","title":{"rendered":"R2 Authorization after Action"},"content":{"rendered":"<p>R2 introduced a new property to the UpdateResourceActivity, CreateResourceActivity and DeleteResourceActivity classes called &#8220;ApplyAuthorizationPolicyProperty&#8221;. Setting this to &#8220;true&#8221; in your custom activity allows an Authorization activity to be triggered by an Action workflow.<\/p>\n<p>I have finally had an opportunity to try this out.<\/p>\n<p><!--more--><\/p>\n<h2>My Use Case<\/h2>\n<p>I&#8217;m developing a solution based around Services, Roles and Entitlements. Services have one or more Roles, and you need an Entitlement specific to a Service-Role combo to get access to it. Depending on the Service there are different requirements for approvals and notifications.<\/p>\n<p>A number of the Services have a training requirement and this should be\u00c2\u00a0the final approval step in the process. Here&#8217;s how it might go:<\/p>\n<ol>\n<li>User requests an entitlement,\n<ol type=\"a\">\n<li>Manager must approve,<\/li>\n<\/ol>\n<\/li>\n<li>Entitlement is created with Training set to &#8220;Requested&#8221;,\n<ol type=\"a\">\n<li>Workflow triggers to update Training to &#8220;Done&#8221;,\n<ul>\n<li>Trainer must approve,<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/li>\n<li>Entitlement now active with Training=&#8221;Done&#8221;.<\/li>\n<\/ol>\n<p>Before R2 that &#8220;Trainer must approver&#8221; step wasn&#8217;t possible, at least not without some <a href=\"https:\/\/www.wapshere.com\/missmiis\/authorization-after-an-action\">externally-triggered PowerShell trickery<\/a>. Now we can do it, but you will have to write a custom activity to do your equivalent of my step 2a above.<\/p>\n<h2>Custom Update Activity<\/h2>\n<p>To demonstrate this functionality I wrote a very simple\u00c2\u00a0activity that uses\u00c2\u00a0the UpdateResourceActivity to set a value.<\/p>\n<p style=\"text-align: center;\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 <img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2013\/01\/CustomUpdate.jpg\" width=\"719\" height=\"144\" \/><\/p>\n<p>\u00c2\u00a0There is only one code activity and then the UpdateResourceActivity.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2013\/01\/R2-WF.jpg\" width=\"181\" height=\"211\" \/><\/p>\n<p>Here&#8217;s the code activity:<\/p>\n<pre>    Private Sub InitializeUpdateActivity_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs)\r\n        '' Get containing Workflow\r\n        Dim containingWorkflow As SequentialWorkflow = Nothing\r\n        If Not SequentialWorkflow.TryGetContainingWorkflow(Me, containingWorkflow) Then\r\n            Throw New InvalidOperationException(\"Could not get parent workflow!\")\r\n        End If\r\n\r\n        Me.updateResourceActivity1.UpdateParameters = New UpdateRequestParameter() {New UpdateRequestParameter(Me.Attribute, UpdateMode.Modify, Me.Value)}\r\n        Me.updateResourceActivity1_ActorId1 = containingWorkflow.ActorId\r\n        Me.updateResourceActivity1_ResourceId1 = containingWorkflow.TargetId\r\n\r\n        If Me.AuthZAfterAction = True Then Me.updateResourceActivity1_ApplyAuthorizationPolicy1 = True\r\n\r\n    End Sub<\/pre>\n<p>The important bit is setting the ApplyAuthorizationPolicy property to True.<\/p>\n<p>In case you want to see them here are links to the full Activity and UI code:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.wapshere.com\/missmiis\/code-snippets\/customupdate\">CustomUpdate.vb<\/a><\/li>\n<li><a href=\"https:\/\/www.wapshere.com\/missmiis\/code-snippets\/customupdateui\">CustomUpdateUI.vb<\/a><\/li>\n<\/ul>\n<h2>Policy Objects to Create<\/h2>\n<p>Sets:<\/p>\n<ul>\n<li>&#8220;Entitlements where Training is Requested&#8221;<\/li>\n<li>&#8220;Entitlements where Training is Done&#8221;<\/li>\n<\/ul>\n<p>Workflow Definitions:<\/p>\n<ul>\n<li>Action: &#8220;Set Training to Done&#8221;. Uses my CustomUpdate activity as pictured above, with &#8220;Allow Authorization&#8221; ticked.<\/li>\n<li>AuthZ: &#8220;Get Trainer Approval&#8221;. Just a standard Approval activity.<\/li>\n<\/ul>\n<p>MPR &#8220;Entitlement Workflow: Initiate training request&#8221;<\/p>\n<ul>\n<li>Type = Transition In\u00c2\u00a0<\/li>\n<li>Transition Set = &#8220;Entitlements where Training is Requested&#8221;<\/li>\n<li>Action WF =\u00c2\u00a0&#8220;Set Training to Done&#8221;<\/li>\n<\/ul>\n<p>MPR &#8220;Entitlement Workflow: Get trainer approval&#8221;:<\/p>\n<ul>\n<li>Type = Request<\/li>\n<li>Requestor = &#8220;All People&#8221;<\/li>\n<li>Operation = Modify<\/li>\n<li>Target before set =&#8221;Entitlements where Training is Requested&#8221;<\/li>\n<li>Target after set = &#8220;Entitlements where Training is Done&#8221;<\/li>\n<li>AuthZ WF = &#8220;Get Trainer Approval&#8221;<\/li>\n<\/ul>\n<h2>The Results<\/h2>\n<p>To\u00c2\u00a0test\u00c2\u00a0that I really can have an approval after an action all I need do\u00c2\u00a0is edit an existing entitlement and set Training to &#8220;Requested&#8221;:<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: black 1px solid;\" alt=\"\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2013\/01\/R2-set-entitlement-to-requested.jpg\" width=\"572\" height=\"380\" border=\"1\" \/><\/p>\n<p>Looking at the Requests log I can see that a couple of things have happened straight away:<\/p>\n<ul>\n<li>My request to change the value to &#8220;Requested&#8221; is Post-Processing,<\/li>\n<li>There is a new request to change the value to &#8220;Done&#8221; which is &#8220;Authorizing&#8221;, and<\/li>\n<li>An approval has been created.<\/li>\n<\/ul>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2013\/01\/R2-approval-triggered.jpg\" width=\"825\" height=\"100\" \/><\/p>\n<p>Going back to check the entitlement &#8211; the expected value of &#8220;Requested&#8221; is the currently committed value.<\/p>\n<p>The approver responsible for saying when training is done just has to approve the pending request:<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2013\/01\/R2-approve.jpg\" width=\"801\" height=\"290\" \/><\/p>\n<p>Once that is complete the entitlement object now shows a correct training status of &#8220;Done&#8221;.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" alt=\"\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2013\/01\/R2-done.jpg\" width=\"486\" height=\"385\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>So there we have it<\/h2>\n<p>It looks like it is now possible to trigger an approval from a change being made by an action workflow.<\/p>\n<p>I still need to try out a few other things &#8211; like whether it makes any difference if the Sync Engine made the change &#8211; but so far it looks promising.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>R2 introduced a new property to the UpdateResourceActivity, CreateResourceActivity and DeleteResourceActivity classes called &#8220;ApplyAuthorizationPolicyProperty&#8221;. Setting this to &#8220;true&#8221; in your custom activity allows an Authorization activity to be triggered by an Action workflow. I have finally had an opportunity to try this out.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[60,30,45],"tags":[],"class_list":["post-2494","post","type-post","status-publish","format-standard","hentry","category-fim-2010-r2","category-vbnet","category-workflow"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pkp1o-Ee","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts\/2494","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/comments?post=2494"}],"version-history":[{"count":14,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts\/2494\/revisions"}],"predecessor-version":[{"id":2516,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts\/2494\/revisions\/2516"}],"wp:attachment":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/media?parent=2494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/categories?post=2494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/tags?post=2494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}