Wednesday, January 28, 2009

Integrate SharePoint Security with Line of Business (LOB) application

We have a legacy line of business web application. The application provides working platforms for various subscribers. We want to migrate the application to use SharePoint as its front-end and so to leverage SharePoint's site provisioning capability as well as other cool features such as customizable web part pages, survey/task list and so on.

As to security, the LOB has its own set of permissions, groups and users. All of them are stored in its custom database tables. SharePoint has its own concept of users, groups, permissions and permission levels. How to implement a security architecture to cover both of them? Before answering this question, we need to choose where to store all the LOB data. Should we store all of them in sharepoint lists/libraries? It is an easy decision because the LOB has a too complex relational database for SharePoint to handle. The CAML query and Search provided by SharePoint are more like a Meta data search facility, which are not very helpful for handling relational/transactional data. So, most of the transactional relational data should stay in the LOB database and the sharepoint security won't apply to those data. Therefore, we need to implement a security architecture to cover both sharepoint data and the LOB data. Essentially, the security architecture should allow to assign both sharepoint and custom permission to users. For example, We can say "User ABC" can "view web part" pages and "make purchase of product XYZ".

The overall architecture is as the following:

1: Use out-of-box ASP.NET form authentication's SQL membership and SQL role provider. (Notice, we choose not to create a custom security providers.)

2: Create database tables in the LOB database to map a ASP.NET form user to LOB permissions such as make "purchase of product XYZ".

3: Create custom sharepoint admin pages for managing ASP.NET users, roles and assigning both sharepoint permission levels and LOB permissions to them. 

The code logic behind those admin pages is straightforward. For example, The logic flow to create an user group and assign permissions to the group is as the following:

1: Use ASP.NET role API to create an ASP.NET role. (ASP.NET role is basically a user group)

2: Use SharePoint object model API to map the ASP.NET role to a SharePoint User.

3: Assign the corresponding Permission Levels to the SharePoint User.

4: To assign LOB permissions to the ASP.NET role, use LINQ to SQL (the latest ASP.NET 3.5 dataaccess API) to update the LOB tables

The whole process is straightforward and simple as long as you have a clear understanding on ASP.NET form security and SharePoint Security.

Some of the key points that help to come to the design are:

1: ASP.NET role provider is essentially "Membership Group". It is not responsible for mapping a "Membership Group" to "Security Permissions". A Membership Group determines who are in the group. It does not know what permissions the group has.

2: SharePoint Permission Levels are "Permission Group".

3: LOB have its own permissions.

4: The security architecture is to Reuse the "Membership Group" feature from ASP.NET role provider and use custom coding to map the ASP.NET role to SharePoint permission levels and LOB permissions.

It is often confusing about different terminologies such as group, role, permission level and so on. Try to translate those terminologies into a common language such as Permission, Permission Group and Membership Group. Distinguishing Permission Group from Membership Group and understanding the process to assign Permissions/Permission Groups to Membership Group  are very important.

Tuesday, January 27, 2009

How to work around the issue with “No Printers are installed” exception when using ComponentOne C1PrintDocument?

When using the ComponentOne C1.C1PrintDocument.C1PrintDocument to generate and print PDF file, if you received “No printers are installed” exception. It has something to do with the way you set the PrinterSettings. You would think the following codes are the same. But the first one would throw "No printers are installed" exception.

System.Drawing.Printing.PrinterSettings settings = new System.Drawing.Printing.PrinterSettings();
settings.PrinterName = printerIdentifier;
settings.Copies = numberOfCopies;
c1PrintDocument1.Print(settings, false);

So use the following instead.




c1PrintDocument1.PageSettings.PrinterSettings.PrinterName = printerIdentifier;
c1PrintDocument1.PageSettings.PrinterSettings.Copies = numberOfCopies;
c1PrintDocument1.Print(false);

It also happens when trying to set the margins.

Friday, January 23, 2009

How to author Movie/Flash in SharePoint Publishing Site with minimum coding

Displaying Movie content is a common requirement in a Publishing Site. The typical behavior is as the following:

In Authoring/Edit Mode, content authors can choose which movies to display.

In Display Mode, end users will see the movie or just a link to the movie, clicking the link will pop up a dialog to show the movie.

The behavior is very similar to the out of box “RichLinkField” (Publishing Hyperlink). Actually, they have the exact same Edit Mode behavior. The only difference is that “Publishing Hyperlink” will render Anchor link in display Mode whereas Displaying Movie needs to render different HTML segment depending on how to play movie.

So, instead of building a custom SharePoint Field Type, we just need to build a custom SharePoint field control, which inherits from out-of-box “RichLinkField” class and overrides “RenderFieldForDisplay” method. The field control will present the same Edit Mode behavior as Publishing Hyperlink while in Display model; it renders the HTML/JavaScript for displaying Movie.

The approach is very simple and effective. It demonstrates the power of SharePoint’s extensibility.

How to implement complex Menus/Breadcrumbs/Navigation structure in a SharePoint environment?

It is natural to try to use out-of-box components such as navigation providers, site map data sources and menu controls. However, it is very often  true for a complex content management SharePoint project that the out-of-box features are not enough. There are typically two reasons

1.       The logical structure is different from what out-of-box could envisioned or

2.       The custom CSS/JSScript involved is just too complex to be expressed in configuration parameter on out-of-box menu controls.

Notice, typically SharePoint developers do not have control on those factors since, for a complex project, web designs typically come from third party companies specialized in web design.

The solution, which proves to be successfully in several projects, is to use a XML file to define the site structure and use DataFormWebPart (Data View Web Part) to generate the HTML/CSS/Java script for the menus and even breadcrumb.

In the XML file (Site Map), each node may have an attribute for the URL to the page and some other Meta data attributes to help generate menus. For example, if a node should be only visible for certain groups of user, you can add an attribute to the node to specify the groups. Adding Meta data in the XML file is an extensible approach since you can add a new attribute easily. It is also a maintainable approach due to its centralized nature. Adding Meta data in publishing page content type is an alternative. However, it is decentralized and typically difficult to maintain.

With the XML file defining the complex logic structure, all you need to do is to convert it to HTML/CSS/JavaScript. Then, both problems mentioned earlier are solved. XSLT is the perfect candidate for this convertion and therefore DataFormWebPart can be used. In a publishing web site, you can simply put the XML file in style library and use DataFormWebPart to get its content. To this end,  a solid understanding of DataFormWebPart is a necessary. This is not a DataFormWebPart tutorial. Here are a few concepts you can use to quiz how well you understand DataViewWebPart.

1.       How to define a SPDataSource to query data from a list by Name.

2.       SPDataSource supports two modes of Query. Which are they?

3.       How to define an aggregate data source.

4.       How to use PostBack parameter binding.

5.       How to use a control parameter binding.

6.       How to reuse XSLT in two fashions, utility and framework.

If answers are “yes” to all of them and you also have good SharePoint designer experience, you are definitely ready to consider DataFromWebPart as an important part of your SharePoint site architecture.

Notice, item 6, “how to reuse XSLT in two fashions”, is crucial if your XSLT code exceeds a few hundred lines. With DataFormWebPart, you can use XSLT “import” to reuse the templates/variables from other XSLT files. (I have seen some blog saying it is not possible, which is not correct.). You can achieve “FrameWork” like reuse based on the following feature of XSLT:

A template will override the ones with the same name but defined before it. For example, you can have a XSLT file “FA” defined a template “TA”, which invokes template “TB”. You can provide a default implementation for “TB” in “FA”. Another XSLT file “FB” can import “FA” and provide a different implementation of “TB”.

“Framework” style reuse is very powerful. It is just like the “virtual” function in object oriented programming.