Custom SharePoint Designer Workflow Activity For Document Encryption!

Module #17: Custom Activities Lab #3

 

 

Course:           Advanced SharePoint Development

Estimated Time to Complete:  60 minutes

Objectives:

·        Create a custom workflow activity for SharePoint Designer

Operating Notes:  

·        None

Deliverables:

·        None

 

Overview:         Let’s create our own custom workflow using SharePoint Designer

Exercise 1 – Create a Custom Activity

Purpose:         Create a custom activity to be used by SharePoint Designer

Result:           
Custom Activity

Task 1 – Create a Project

  1. Open Visual Studio
  2. Select the File->New->Project
  3. Select Visual C#
  4. For template, select Workflow project type.
  5. Select the Workflow Activity Library template.
  6. For Location, type C:asp
  7. For Name, type CustomActivities
  8. Click OK
  9. Rename Activity1.cs to EncryptDocument.cs
  10. Right click the project, select Add Reference
  11. Add the following references:
    • C:program filescommon filesmicrosoft sharedweb server extenstionsisapiMicrosoft.SharePoint.dll
    • C:program filescommon filesmicrosoft sharedweb server extenstionsisapiMicrosoft.SharePoint.WorkflowActions.dll
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Common.dll
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Security.Cryptography.dll
  12. Right click the EncryptDocument shape, select View Code
  13. Add the following using statements for the Workflow code:
    • using Microsoft.SharePoint;
    • using Microsoft.SharePoint.Workflow;
    • using Microsoft.SharePoint.WorkflowActions;
  14. Since we are going to use Enterprise library to do our encryption, add the following using statements:
    • using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
    • using Microsoft.Practices.EnterpriseLibrary.Security;
    • using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;
  15. Add the following Execute method:


protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

        {

            SPSite site = (SPSite)__Context.Site;

            SPWeb web = (SPWeb)__Context.Web;

            this.ListId.Trim();

            this.ListId.ToLower();

            Guid listGUID = new Guid(this.ListId);

            SPList list = web.Lists[listGUID];

            SPListItem item = list.GetItemById(this.ListItem);

 

            SPFile file = item.File;

            byte[] bytes = file.OpenBinary();

 

            //encrypt the file

            IConfigurationSource source = new SystemConfigurationSource();

            SymmetricCryptoProviderFactory factory = new SymmetricCryptoProviderFactory(source);

            ISymmetricCryptoProvider provider = factory.CreateDefault();

 

            byte[] encryptedByteArray = provider.Encrypt(bytes);           

            file.SaveBinary(encryptedByteArray);

            file.Update();

 

            return ActivityExecutionStatus.Closed;

        }       

 

  1. Add the following property, this will provide access to the workflow context back to our code:


public static DependencyProperty __ContextProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(EncryptDocument));

 

        [Description("Workflow Context")]

        [Category("Context")]

        [ValidationOption(ValidationOption.Required)]

        [Browsable(true)]

        [DesignerSerializationVisib
ility(DesignerSerializationVisibility.Visible)]

        public WorkflowContext __Context

        {

            get

            {

                return ((WorkflowContext)(base.GetValue(EncryptDocument.__ContextProperty)));

            }

            set

            {

                base.SetValue(EncryptDocument.__ContextProperty, value);

            }

        }

 

  1. Add the following ListId property:


public static DependencyProperty ListIdProperty = System.Workflow.ComponentModel.DependencyProperty.Register("ListId", typeof(string), typeof(EncryptDocument));

 

        [Description("This is the description which appears in the Property Browser")]

        [Category("This is the category which will be displayed in the Property Browser")]

        [ValidationOption(ValidationOption.Required)]

        [Browsable(true)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

        public string ListId

        {

            get

            {

                return ((string)(base.GetValue(EncryptDocument.ListIdProperty)));

            }

            set

            {

                base.SetValue(EncryptDocument.ListIdProperty, value);

            }

        }

 

  1. Add the following ListItem property:


public static DependencyProperty ListItemProperty = System.Workflow.ComponentModel.DependencyProperty.Register("ListItem", typeof(int), typeof(EncryptDocument));

 

        [Description("This is the description which appears in the Property Browser")]

        [Category("This is the category which will be dis
played in the Property Browser")]

        [ValidationOption(ValidationOption.Required)]

        [Browsable(true)]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

        public int ListItem

        {

            get

            {

                return ((int)(base.GetValue(EncryptDocument.ListItemProperty)));

            }

            set

            {

                base.SetValue(EncryptDocument.ListItemProperty, value);

            }

        }

 

 

  1. Add another Activity, name this one DecryptDocument
  2. Add the same using statements (steps 13,14) and the same properties (steps 16,17,18)
  3. Add the following Execute method:


protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

        {

            SPSite site = (SPSite)__Context.Site;

            SPWeb web = (SPWeb)__Context.Web;

            this.ListId.Trim();

            this.ListId.ToLower();

            Guid listGUID = new Guid(this.ListId);

            SPList list = web.Lists[listGUID];

            SPListItem item = list.GetItemById(this.ListItem);

 

            SPFile file = item.File;

            byte[] bytes = file.OpenBinary();

 

            //encrypt the file

            IConfigurationSource source = new SystemConfigurationSource();

            SymmetricCryptoProviderFactory factory = new SymmetricCryptoProviderFactory(source);

            ISymmetricCryptoProvider provider = factory.CreateDefault();

 

            byte[] encryptedByteArray = provider.Decrypt(bytes);

            file.SaveBinary(
encryptedByteArray);

            file.Update();

 

            return ActivityExecutionStatus.Closed;

        }

 

  1.  

 

Task 2 – Strong Name the assembly

  1. In the Solution Explorer, Right Click on Properties
  2. Click the Signing tab
  3. Check the checkbox, Sign the Assembly
  4. Select the New option from the Drop down below
  5. For Filename, type DocumentEncryption
  6. Uncheck the “Protect my key file with a password” option
  7. Compile the project

Task 3 – Copy to the GAC

  1. Copy the EncryptDocument.dll to the C:windowsassembly directory
  2. Copy the Enterprise Library dlls to the GAC as well
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Common.dll
    • C:Program FilesMicrosoft Enterprise Library 3.1 – May 2007BinMicrosoft.Practices.EnterpriseLibrary.Security.Cryptography.dll

Task 4 – Modify the web.config file

  1. Open web.config file in the C:inetpubwwwrootwssvirtualdirectories100 directory
  2. Add the following element to the System.Workflow.ComponentModel.WorkflowCompiler element:


<authorizedType

   Assembly="CustomActivities,Version=1.0.0.0,Culture=neutral,PublicKeyToken=[YOUR PUBLICKEYTOKEN]"

    Namespace="CustomActivities"

    TypeName="*"

    Authorized="True" />

 

  1. Save and close the web.config file
  2. Open Enterprise Library Configuration tool (shortcut on the desktop)
  3. From EntLib, open the web.config file
  4. Right click the “C:inetpub…” node, select New->Cryptography Application Block
  5. Right Click the Symmetric Providers node, select New->Symmetric algorithm provider
  6. Select DESCryptoServiceProvider
  7. Click Ok
  8. In the Cryptographic Key Wizard dialog, Click Next
  9. Click Generate
  10. Click Next
  11. Save the key file to the c:inetpubwwwrootwssvirtualdirectories100 directory, call it EncryptIt
  12. Click Save
  13. Click Next
  14. Select Machine Mode
  15. Click Finish
  16. Click the Cryptography Application Block node
  17. For DefaultSymmetricCryptoProvider, select the DESCryptoServiceProvider
  18. Save the web.config file

Task 5 – Create an ACTIONS file

  1. Create a file in C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATE1033Workflow called ENCRYPT.ACTIONS
  2. Copy the following to the file:


<?xml version="1.0" encoding="utf-8"?>

<WorkflowInfo Language="en-us">

  <Actions>

<Action

    Name="Encrypt a document/item"

    ClassName="CustomActivities.EncryptDocument"

    Assembly="CustomActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[PUBLICKEYTOKEN]"

    AppliesTo="all"

    Category="Encryption">

    <RuleDesigner Sentence="Encrypt %1 Item">

              <FieldBind Field="ListId,ListItem,ItemProperties" Text="this list" Id="1" DesignerType="UpdateListItem" />

         </RuleDesigner>

         <Parameters>

              <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" />

              <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" />

              <Parameter Name="ListItem" Type="System.Int32, mscorlib" Direction="In" />

              <Parameter Name="ItemProperties" Type="System.Collections.Hashtable, mscorlib" Direction="In" />

         </Parameters>

</Action>

<Action

    Name="Decrypt a document/item"

    ClassName="CustomActivities.DecryptDocument"

    Assembly="CustomActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=[PUBLICKEYTOKEN]"

    AppliesTo="all"

    Category="Encryption">

    <RuleDesigner Sentence="Decrypt %1 Item">

              <FieldBind Field="ListId,ListItem,ItemProperties" Text="this list" Id="1" DesignerType="UpdateListItem" />

         </RuleDesigner>

         <Parameters>

              <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" />

              <Parameter Name="ListId" Type="System.String, mscorlib" Direction="In" />

              <Parameter Name="ListItem&
quot; Type="System.Int32, mscorlib" Direction="In" />

              <Parameter Name="ItemProperties" Type="System.Collections.Hashtable, mscorlib" Direction="In" />

         </Parameters>

</Action>

  </Actions>

</WorkflowInfo>

 

Task 6 – Create a workflow to use the Encryption action

  1. Reset IIS
  2. Open SharePoint Designer 2007
  3. Open your site (http://loclhost:100)
  4. Select File->New->Workflow menu command.
  5. For Name, type “Encrypt It”, select Shared Documents from the dropdown
  6. Click Next
  7. Click Actions, select the More Actions
  8. Click the dropdown for the Select a Category and choose “Encryption”
  9. In the Choose an Action box, select the “Encrypt a document/item” activity
  10. Click Add.
  11. Click on “this” option in the Action
  12. From the Choose List Item dialog box, select the “Current Item” option
  13. Click OK
  14. Click Finish

Task 7 – Run the workflow

  1. Add an item to the document library
  2. Right click the JavaScript dropdown, select workflows
  3. Click Encrypt It

Task 8 – Try to open the document

  1. Click the document, Word should fail to open it…it is encrypted!!!

Task 9 – Create a workflow to use the Decryption action

  1. In SharePoint Designer 2007, select File->New->Workflow menu command.
  2. For Name, type “Decrypt It”, select Shared Documents from the dropdown
  3. Click Next
  4. Click Actions, select the More Actions
  5. Click the dropdown for the Select a Category and choose “Encryption”
  6. In the Choose an Action box, select the “Decrypt a document/item” activity
  7. Click Add.
  8. Click on “this” option in the Action
  9. From the Choose List Item dialog box, select the “Current Item” option
  10. Click OK
  11. Click Finish

Task 10 – Run the workflow

  1. Add an item to the document library
  2. Right click the JavaScript dropdown, select workflows
  3. Click Decrypt It

Task 11 – Try to open the document

  1. Click the document, Word will open…it is decrypted!!!