Tuesday, May 29, 2007

Custom Workflow , SPWorkflowActivationProperties and "Current user"

Today, I saw an interesting post in one of the newsgroups where someone was looking for a way get the identity of the current logged in user. The user tried getting the current user's Id by SPWorkflowActivationProperties .Web.CurentUser which in normal circumstances make sense but not in the case of the windows workflow. Why? Lets try to break down this problem.

First of all SharePoint is a hosting windows workflow which means its running the windows workflow runtime possibly in the same process as the current web application, however it is NOT necessarily sharing the same session or context, moreover , there is no sequence or direct corelation in the execution of a workflow activity and and a browser session. Also, a workflow activity can be invoked from any external program, it does NOT have to be the current session. E.g. If you are writing a workflow to approve an item, it can be triggered by Outlook, Word, SharePoint or any custom application for that matter.

Why SPWorkflowActivationProperties .Web.CurentUser returns SharePoint/System user ??

The simple answer is SPWeb and SPSite properties of SPWorkFlowActivationProperties are instantiated by the workflow runtime and workflow runtime impersonate the current "Process account" to create SharePoint objects, hence the "SharePoint\System" user

But I want the current logged-in user ?

I think the question should be rephrased, Instead of the currently logged in user, you may want to access the user who last edited one of the list item on which you are executing the workflow. If that's what your use case then there are multiple ways to get it. The simplest way is to use "Modified By" column of SPListItem. All SPListItems has this properties. This will give you the Id of the user who last touched your item in question.

Monday, May 21, 2007

"Policy for web application" and Form Based Authentication (FBA)

The authentication scheme in SharePoint 2007 is very flexible. Out of the box SharePoint supports multiple authentication schemes and also lets you build a custom one. Now every flexible thing comes at a price, The over-flexibility also increases complexity, specially if you start mixing Intranet and Extranet applications with different authentication.

One of the features in SharePoint is called "Policy for Web Application" (Personally I think they could have chosen a better name). What this feature allows you to do is define the top level security for a "web application" in central admin. This is really neat if specially if you are creating a new application and what to give certain groups or users access to an application before creating an Site collection or login into the application. This comes very handy in case of an Form authentication. N

Now, you should be very careful when you add a group in the web application policy screen. The minimum (assertive) access you can give in this screen is "Read all" . Now this literally means "Read all". Any user or group given "Read All" permission will always have "Read" access to all site collections, lists and items in that Application, That's right, even if you break the inheritance model, and put Item level security. And the most annoying thing I found is those users/groups are not visible in the "All People" screen from the site.

So next time, when you planning to use "Policy for Web Application" remember that any user you add here ALWAYS has minimum access to the entire application regardless of your security policies within the site .

Sunday, May 20, 2007

"People Search" and My Site / SSP configuration

When you crawl the Local Office SharePoint Server sites content source and if you are getting the following error, you may want to check your SSP configuration

sps3://SERVERNAME ( MySite Application URL)
Error in PortalCrawl Web Service

What I discovered is while creating a new SSP, I did not create seperate web application for "Mysite" and "SSP Admin" ( as recommended by Microsoft), instead I created a single web application with two site collections - one for MySite and other for SSP admin . Now if you do this, SharePoint is not going to create a root Site Collection ie.. http://SERVERNAME:PORT (my site application) will be empty. This for whatever reasons causes stomach ache for SharePoint Indexer. If you go back and create a dummy Site Collection in the root of My Site Web application and then reindex your content source, the above error will go away ( at least it did for me)

Now, if you are still using SPS 2003 and getting similar error, you may want to check out MS Support article on this


Thursday, May 17, 2007

Different User profile screens

Recently, I was playing with user profiles in SSP and noticed something very strange. When you edit a profile of an admin user (userprofile automatically added by SharePoint) the screen is slightly different than that of a regular user ( Users you import from LDAP or manually inserted).

In case of an admin user, SharePoint automatically populates the MySite URL and shows browse button to import a picture. In case of a regular user both MySite URL and Picture fields are plain text with no picker control.

Admin User Profile Screen ( http://server/ssp/admin/_layouts/ProfAdminEdit.aspxdmin/_layouts/ProfAdminEdit.aspx)

Regular User

Its a minor difference but I am not able to figure out why?? I like the admin UI. Not sure why SharePoint team decided to implement it differently. I am curious to know, If anyone has any idea, please share with me

Sunday, May 06, 2007

When SharePoint 2007 "Restore" fails

If you are a developer, "backup" and "restore" are not something you spell every often, most of the time we leave it up to the IT to take care of such jobs

Recently, I had to move one of demo web applications to a different machine. Well, I could have ghosted the whole image and restore it on other side then it stuck me that may be I can take a backup of my web application from the current machine and restore it on the new machine.

The backup process was smooth. SharePoint created a folder structure with all necessary .bak files. While restoring on the other machine, I ran into some issues. The restore process started fine but then I saw some errors in the restore.log file in my backup folder.

[5/6/2007 8:35:11 PM]: Error: Object WSS_Content_37a0332fb0794e7eb29b164e68d16910 failed in event OnPostRestore. For more information, see the error log located in the backup directory. SPException: Cannot attach database to Web application. Use the command line tool or Central Administration pages to attach the database manually to the proper Web Application.[5/6/2007 8:35:11 PM]: Debug: at Microsoft.SharePoint.Administration.SPContentDatabase.OnPostRestore(Object sender, SPRestoreInformation args)

When I checked the SQL server, it did attach the content database however because of the above error it failed to join my web application entry to the content database. Also, because the restore process abrupted, it did not created the IIS web application on the new machine. To resolve this issue, I had to do the following

1) From Central Admin Applications Add Content Database screen --> Add the newly atttached content database. By default, this screen will show values from backup machine

2) Next, I had to restart the Windows SharePoint Services Web Application" Service . This service is responsible for creating IIS application on local web -front end and also to keep in sync with other servers in the farm.

After this, I was able to see my old application on the new machine. I had to copy my aspx customization from \_layout folder, some features and legacy COM controls to the new machine.

When not to use SharePoint Designer (AKA Microsoft FrontPage)

SharePoint designer is a great tool to edit SharePoint sites and pages without detail knowledge of ASP.NET or HTML. But like everything else in life this is not the perfect tool for everything, specially if you are modifying an aspx or a master page from "_layouts" folder.

In SharePoint the relative path to the page is represented using tilda (~) sign e.g. ~/_layouts/simple.master, which means the ~ will be replaced at runtime with appropriate site name. This is where the problem begin, when you open a page which is on a file systel e.g. _layout folder, SharePoint tries to resolve all relative path to the site (thinking its a "Ghosted" page) and end up replacing with "_layouts" . You don't get any error until you start using that page. At runtime, SharePoint will try to resolve all path to "absolute" _layout folder - which does not exists, as oppose to a relative ~/_layouts path . Wish there was a better way to handle this. I ended up editing these page the old fashied way - e.g. Notepad . Hopefully in SharePoint 2007 Service Pack1 this might get resolved.

Things to keep in mind when implementing Custom Authentication Provider for SharePoint 2007

Recently I had to implement a custom authentication provider for one of my clients. From the surface, it looked easy since SharePoint 2007 is an ASP.NET 2.0 application so all you need to do is implement - MembershipProvider and RoleProvider. Well, that part was easy but the hard part was to figure out how SharePoint make calls to your custom provider, which calls need to be optimised, what data can be cached.

Here are some findings

1) RoleProvider : Although this is optional, you are better of implementing this one. One biggest problem I ran into without implementing this one was "Admin" user, How do you add a user to Admin role? and Without a admin user, how to login and add other users ? Chicken and Egg problem. Though via Central admin you can give a user full access to a virtual user but when you try to login into your application(site), SharePoint will throw "Access denied" error

2)User Lookup and Addressbook : Anywhere in SharePoint, when you click these two icons , They call your Custom Authentication Provider. Interestingly both these button call the FindUsersByEmail method. If you are expecting a wildcard user search, the default wildchar character SharePoint usages is %, though this can be replaced to a different character by modifying your Authentication provider entry in web.config file

3) Editing Master Page : One problem I ran to was that I had to update default master page, Because I was using CustomAuthentication Provider, I could not open it directly from SharePoint designer ( though there is a way to achieve this - e.g. persistent cookie) I had to edit it the old fashioned way aka - Notepad. Well I made couple of syntax errors but I forgot to test it locally and directly check-in via "Masterpages Gallery" - Bomb!, I could not get my default page to load, It keep giving me - "Resource not found" ASP.NET generic error. I could not see any error either in SharePoint log or in Event log. The only way I could roll it back was by changing my authentication provider back to "Windows" and then loading my master page in "SharePoint designer". I wish there was a better way to do this.

I am still having fun with it. I will post more findings later. If you are looking for how to implement an custom authentication provider, here is a great MSDN article