Tuesday, January 22, 2013

How to Associate CUG with DAM asset in CQ / WEM

Use Case: You want to secure DAM content.

Pre requisite: http://dev.day.com/docs/en/cq/current/howto/create_apply_cug.html

Current Issue: There is no way to configure CUG OOTB on DAM resource.

Solution:

In order for CUG to work we need to have following properties for DAM asset,
  1. Enabled - cq:cugEnabled
  2. Login Page - cq:cugLoginPage
  3. Principals - cq:cugPrincipals
  4. Realm - cq:cugRealm
For this we have to customize the DAM Asset Editors forms. 

These are stored in a node structure under /libs/dam/content/asseteditors

For example at /libs/dam/content/asseteditors/application/pdf/formitems is for PDFs,
/libs/dam/content/asseteditors/image/jpeg/formitems is for JPEGs.

First, we need to create the necessary folder structure:

curl -u admin:admin -Fjcr:primaryType=sling:Folder http://localhost:4502/apps/dam

curl -u admin:admin -Fjcr:primaryType=sling:Folder http://localhost:4502/apps/dam/content/asseteditors/application/pdf

curl -u admin:admin -Fjcr:primaryType=sling:Folder http://localhost:4502/apps/dam/content/asseteditors/image/jpeg

curl -u admin:admin -Fjcr:primaryType=sling:Folder http://localhost:4502/apps/dam/content/asseteditors/image/tiff


Then we can copy the nodes from libs:

curl -u admin:admin -F:operation=copy -F:dest=/apps/dam/content/asseteditors/ http://localhost:4502/libs/dam/content/asseteditors/formitems

curl -u admin:admin -F:operation=copy -F:dest=/apps/dam/content/asseteditors/application/pdf/ http://localhost:4502/libs/dam/content/asseteditors/application/pdf/formitems

curl -u admin:admin -F:operation=copy -F:dest=/apps/dam/content/asseteditors/image/ http://localhost:4502/libs/dam/content/asseteditors/image/formitems

curl -u admin:admin -F:operation=copy -F:dest=/apps/dam/content/asseteditors/image/jpeg/ http://localhost:4502/libs/dam/content/asseteditors/image/jpeg/formitems

curl -u admin:admin -F:operation=copy -F:dest=/apps/dam/content/asseteditors/image/tiff/ http://localhost:4502/libs/dam/content/asseteditors/image/tiff/formitems


For the CUG to be properly created, these properties must be set on the protected item’s jcr:content node. By default, the form fields on a DAM Asset Editor form are set on thejcr:content/metadata node, so we need to use a relative path like ../cq:cugEnabled in the form field definition to set the proeprty on the correct node.

However, when the form is rendered, the data used to populate the form fields will only contain the metadata node. As a result, a custom beforeloadcontent listener must be created.

 Then we have to add properties for CUG in DAM.

curl commands to create the fields for the image editor:

curl -u admin:admin "-FfieldLabel=CUG Enabled" -FinputValue=true -Fjcr:primaryType=cq:Widget -Fname=../cq:cugEnabled -Ftype=checkbox -Fxtype=selection "-Flisteners/beforeloadcontent=function(field, record, path) { var targetField=field.getName().replace('../','');  var jcrContentPath=path + '/jcr:content'; var response = CQ.utils.HTTP.get(jcrContentPath +'.json'); eval('var data ='+response.responseText); field.setValue(data[targetField]); return false; }" http://localhost:4502/apps/dam/content/asseteditors/image/formitems/cugEnabled


curl -u admin:admin "-FfieldLabel=CUG Login Page" -Fjcr:primaryType=cq:Widget -Fname=../cq:cugLoginPage -Fxtype=pathfield "-Fsuffix=.html" "-Flisteners/beforeloadcontent=function(field, record, path) { var targetField=field.getName().replace('../','');  var jcrContentPath=path + '/jcr:content'; var response = CQ.utils.HTTP.get(jcrContentPath +'.json'); eval('var data ='+response.responseText); field.setValue(data[targetField]); return false; }" http://localhost:4502/apps/dam/content/asseteditors/image/formitems/cugLoginPage


curl -u admin:admin "-FfieldLabel=CUG Admitted Groups" -Fjcr:primaryType=cq:Widget -Fname=../cq:cugPrincipals -Fxtype=multifield -FfieldConfig/displayField=principal -FfieldConfig/filter=groups -FfieldConfig/xtype=authselection "-Flisteners/beforeloadcontent=function(field, record, path) { var targetField=field.getName().replace('../','');  var jcrContentPath=path + '/jcr:content'; var response = CQ.utils.HTTP.get(jcrContentPath +'.json'); eval('var data ='+response.responseText); field.setValue(data[targetField]); return false; }" http://localhost:4502/apps/dam/content/asseteditors/image/formitems/cugPrincipals


curl -u admin:admin "-FfieldLabel=CUG Realm" -Fjcr:primaryType=cq:Widget -Fname=../cq:cugRealm -Fxtype=textfield "-Flisteners/beforeloadcontent=function(field, record, path) { var targetField=field.getName().replace('../','');  var jcrContentPath=path + '/jcr:content'; var response = CQ.utils.HTTP.get(jcrContentPath +'.json'); eval('var data ='+response.responseText); field.setValue(data[targetField]); return false; }" http://localhost:4502/apps/dam/content/asseteditors/image/formitems/cugRealm

This will also need to be run for the generic, PDF, JPEG, and TIFF forms.




After that you can test
  1. Go to http://localhost:4502/, log in, and go to the DAM Admin.
  2. Open the Asset Editor for an image.

  1. Enable CUG for the asset and at least specify one group.
  2. Activate the asset.

Now you can go to /system/console/cug on your publish instance (e.g. http://localhost:4503/system/console/cug) and see that the CUG was successfully created on the publish instance. 



Note: This might not work in CQ5.6 due to some changes in how composite field work. Please do following to fix that issue

* Remove all the listener node created for cugRealm,cugPrincipals,cugLoginPage,cugEnabled 
* Install the simple workaround patch from here
* Clear the browser cache and verify. 


Special Thanks to Justin and Adobe to provide this information.

Sunday, January 13, 2013

How to publish Code / Component in CQ

Use Case: You want to publish your code to publish instance.

Solution: There are multiple ways to do this,

1) Package Manager (Recommended):

  • Go to package manager through <HOST>:<PORT>/crx/packmgr/index.jsp
  • Click on Create package. Give Package name and filter

  • Once package is created, Click on Edit, Click on filter and select filter for your code. Usually it is /apps/<Your code>, /etc/design/<your code>, Some custom code.

  • Then click ok and click on build package.
  • Once package is build you can click on more and then replicate.

  • If you don't have replicate option (If you are using CQ version less than 5.5), Then download that package and install it in all publish instance.
  • You can also use curl command to install package on publish instance
  • Curl command will look like this 
curl -f -u <USERNAME>:<PASSWORD> -F name=<Package Name> -F file=@<Location of downloaded file in file system> -F install=true http://<HOST>:<PORT>/crx/packmgr/service.jsp"/>

Advantage:
  • You can manage each package
  • Can uninstall package to go to previous revision
  • Can migrate package from any environment to any environment
Disadvantage:
  • Manually build package every time


2) Using Tree activation
  • Go to welcome page -> tools -> replication -> Activate Tree -> double click

  • Select root path as your code path. First select /apps/<Your code> then /etc/design/<Your Design>

  • Then click on Activate
Advantage:
  • Simple. You just have to select tree you want to activate
Disadvantage:
  • Version not supported, Hence you can not revert back to previous code.

3) Using file System

  • You can also put your code package (Created using package manager in author) to install directory under /crx-quickstart (If directory does not exist then create one)
  • This method will require restart of your CQ instance and usually not recommended.
Advantage:
  • Useful if you have very large package
  • Delay installation till restart. Usually helpful in production deployment.
Disadvantage:
  • Restart required
  • package needs to be kept on each publish instance manually.

4) Using CRXDE light (For Only one file change, Only available after CQ5.5)

  • If you want to do some quick developement in your local then you can use CRXDE to replicate code as well. 

Advantage:
  • Useful of you are doing local development and quickly change result of "Single" file in publish.
  • Simple
Disadvantage:
  • You can activate only single file
  • No versioning and no revert back

5) Using build script (Recommended in Project)

You can use either Maven or Ant or any build system to build and install code to any environment you want.

If you are using Maven then you can do something like this


If you are using Ant then you can do something like this

<target name="package-apps-etc">
    <mkdir dir="${target.dir}"/>
<zip destfile="${target.dir}/${build.package.name}">
    <zipfileset dir="${home.dir}/jcr_root" excludes="**/.vlt,**/*.svn" prefix="jcr_root"/>
    <zipfileset dir="${home.dir}/META-INF" prefix="META-INF"/>
    </zip>
  </target>

<target name="local-install-apps-etc-publish" depends="package-apps-etc">
<exec executable="curl" failonerror="true">
  <arg line="-f -u admin:admin -F name=citrix-package -F file=@target/citrix-package.zip -F install=true http://localhost:4503/crx/packmgr/service.jsp"/>
  </exec>
  </target>

You can automate these script using any Continuous build system (Bamboo or Jenkins or any)

Advantage:
  • Structured
  • Can modify based on need
Disadvantage:
  • Complex
  • May need additional resource


Each project has different requirement, Hence way package deployed is also different. Any suggestion or new way to do this is welcome.