Monday, May 26, 2008

Gallery Server Pro API Documentation Released

I have been adding XML comments to my C# code for almost as long as I have been using C#. XML comments are a great help as you code, because they show up in Intellisense to remind you about important details of your methods and properties.

But until now, I have never gotten around to building a help document from those comments. Well, that time has finally arrived. I spent the last few days playing with Sandcastle and the Sandcastle Help File Builder. Most of that time I spent going through all my comments and adding tags and filling in a few missing comments here and there.

If you are a developer modifying the Gallery Server Pro source code, this document can help you wrap your head around the namespaces and classes.

Download the Gallery Server Pro API Documentation. Note: You may have to unblock the CHM file. If the file does not display content, right-click the file, choose properties, and then click Unblock.

Tuesday, May 20, 2008

How To: Integrate Gallery Server Pro with Active Directory

You can configure Gallery Server Pro to use your existing accounts in Active Directory. Woo HOO! Crack open the Skittle-brau and pretzels!

Gallery Server Pro uses the ASP.NET Membership Provider model to manage users and roles. By default, it is configured to store this data in a SQL Server database. However, you can take advantage of an entirely different data store through the use of alternate membership providers such as ActiveDirectoryMembershipProvider or even one you write yourself. In this article I'll describe how to modify a default installation of Gallery Server Pro to use Active Directory for user management.

Note: Due to differences in behavior between SqlMembershipProvider and ActiveDirectoryMembershipProvider, a few tweaks to the code behind for the Manage Users page is required. These changes will be included in the next release. Until then, you can replace the contents of manageusers.aspx.cs with this version (you'll need to recompile).

 

Step 1: Configure basic AD integration

The first step in Active Directory configuration is to modify the web.config file in the root of the Gallery Server Pro application. Add a connection string to AD:

<connectionStrings>
    <add name="GalleryServerDbConnection" connectionString="Data Source=(local);Initial Catalog=GalleryServerPro2;Integrated Security=true;Application Name=Gallery Server Pro" />
    <add name="ADConnection" connectionString="LDAP://192.168.1.1/CN=users,DC=mydomain,DC=techinfosystems,DC=com"/>
</connectionStrings>

The value 192.168.1.1 is the IP address of the domain controller. You can also specify the Fully Qualified Domain Name (ex. mydomain.techinfosystems.com), the Relative Distinguished Name (ex. godzilla if that is the name of your DC); or for more redundancy you can specify just the domain name (ex. mydomain).  Which ever you choose just be sure you can ping it.

The next step is to comment out the existing membership configuration by adding <!-- to the beginning and --> to the end, like this:

<!--<membership defaultProvider="SqlMembershipProvider">
  <providers>
    <clear/>
    <add applicationName="Gallery Server Pro" connectionStringName="GalleryServerDbConnection" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="2" requiresQuestionAndAnswer="false" passwordFormat="Clear" enablePasswordReset="true" enablePasswordRetrieval="true" requiresUniqueEmail="false" maxInvalidPasswordAttempts="50" passwordAttemptWindow="10" name="SqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider"/>
  </providers>
</membership>-->

Now add the new membership info for Active Directory:

<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
  <providers>
    <add name="AspNetActiveDirectoryMembershipProvider"
          type="System.Web.Security.ActiveDirectoryMembershipProvider,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
                connectionStringName="ADConnection"
                enableSearchMethods="true"/>
  </providers>
</membership>

The version number must match the one installed on your web server, so update it as needed. Some examples I saw on the internet used 2.0.3600.0 instead of 2.0.0.0. Make sure the connection string name matches the name you specified in the connection string definition. The enableSearchMethods attribute is required so that Gallery Server Pro can retrieve a list of all users on the user management page.

Now, at this point you should be able to log on to Gallery Server with your domain account, but you will receive the following message:

insufficient_permission_380x269

This is because your user account is not a member of any roles in Gallery Server Pro. Recall that when you installed Gallery Server Pro, a role named GlobalAdmin was created with administrative permission. Now you need to add one or more AD users to this role. But how do you do this when no one has authorization to perform this task?

If you are using IIS 7, the answer is easy. Open up IIS Manager, navigate to the Gallery Server Pro web app, and click .NET Users. A list of your AD users appears. Double click the one that you want to be the administrator, and add the user to the GlobalAdmin role in the dialog box. The next time you log on to Gallery Server Pro you will have administrative access.

For IIS 6 and earlier users, the task is a bit more difficult because those versions don't provide a means for accessing the users. However, all versions of Visual Studio 2005 and higher - including the free Express versions - provide the Web Site Administration Tool, which allows you to edit the roles for users. Using this tool is beyond the scope of this document, but online information can be found.

At this point you should be able to log on using your AD account. Use the syntax user@fully_qualified_domain_name, such as Roger@mydomain.techinfosystems.com. Later I'll show you how can get change it to just the username.

 

Step 2: Create, edit and delete AD accounts within Gallery Server Pro

Once you are logged on as an administrator, you can go to the Manage Users page and add the remaining AD accounts to appropriate roles. If the IIS user account does not have permission to make changes to AD, you may receive an error like this when you click Save changes:

general_access_denied_error_AD_integration 

You will get this error because the IIS worker process does not have permission to modify AD data. To get around this, you have two choices:

1. Specify a domain account in web.config that has the necessary permission. Open web.config and add connectionUsername and connectionPassword attributes to the provider definition, like this:

<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
  <providers>
    <add name="AspNetActiveDirectoryMembershipProvider"
      type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
        connectionStringName="ADConnection"
        enableSearchMethods="true"
        connectionUsername="RMartin"
        connectionPassword="mypassword"/>
  </providers>
</membership>

Note that putting an AD account name and password in a plain text file is a security risk. If you go this route, I HIGHLY recommend you encrypt the web.config file. Here are two links where you can learn more:

How To: Encrypt Configuration Sections in ASP.NET 2.0 Using DPAPI
http://msdn.microsoft.com/en-us/library/ms998280.aspx

Video: How Do I: Encrypt My Web.Config File?
http://weblogs.asp.net/scottgu/archive/2006/01/09/434893.aspx

2. Specify an account for the IIS worker process that has the necessary AD permission. I prefer this over the first solution.

Once the permissions are sorted out, you have the potential to create, edit and delete users. Remember that adding a user creates a new account in Active Directory and deleting an account removes it! Obviously this can be abused in a way that affects your entire domain, so use caution. For this reason, you may actually prefer to revert to read-only permissions and handle role membership via IIS 7 Manager (or the Web Site Administration Tool for IIS 5-6).

 

Options

Log on with simple username instead of fully qualified name

Your users might not be thrilled with to have to log on with the syntax user@fully_qualified_domain_name, such as Roger@mydomain.techinfosystems.com. If you want to log on with just a username, add the attributeMapUsername to the membership configuration:

<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
  <providers>
    <add name="AspNetActiveDirectoryMembershipProvider"
      type="System.Web.Security.ActiveDirectoryMembershipProvider,System.Web, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
      connectionStringName="ADConnection"
      enableSearchMethods="true"
      attributeMapUsername="sAMAccountName"/>
  </providers>
</membership>

By setting attributeMapUsername to sAMAccountName, you can log on with just the username, such as 'Roger' in the previous example.

Additional provider options

The AspNetActiveDirectoryMembershipProvider provider includes several attributes I haven't mentioned. These attributes configure various logon and password options. Be sure to check them out if you want more control.

 

Caveats

Can't use Windows groups

If you are using AD, you probably use Windows groups to control permissions. You may have a Marketing group whose members have read/write access to the marketing shared folder but read only access to the Development and Engineering folders. Wouldn't it be nice if you could map albums in Gallery Server to your groups, so that the Marketing users would have control over the Marketing album, Developers have the Dev album, and so on?

On the surface, it seems we can just use the WindowsTokenRoleProvider instead of the SqlRoleProvider. However, if one tries this, the following error occurs during application startup:

"The configured Role Provider (WindowsTokenRoleProvider) relies upon Windows authentication to determine the groups that the user is allowed to be a member of. ASP.NET Role Manager cannot be used to manage Windows users and groups. Please use the SQLRoleProvider if you would like to support custom user/role assignment."

This error is generated when Gallery Server Pro tries to get a list of all roles with the Roles.GetAllRoles() method, and the WindowsTokenRoleProvider does not support it. Unfortunately, Gallery Server cannot do its job unless it can get a list of the roles, so for the time being we cannot take advantage of the Windows groups. If anyone discovers a way around this, let us know.

Can't auto-logon users

Back in my classic ASP days I built an intranet app that automatically recognized the Windows account the user was logged on with. No separate logon inside the web app was required. For reasons I don't understand, I cannot accomplish the same thing with ASP.NET Membership. Sure, you can disable anonymous authentication, enable Windows authentication, and turn on impersonation in web.config. Doing this *does* allow Gallery Server Pro to automatically log on users, but it doesn't think the user is in any roles, and there doesn't seem to be any way to configure roles for the user. Let us know if you know a way around this.

Can't reset or change password on other accounts

I didn't spend much time investigating this, but it appears you can't use Gallery Server Pro to reset or change another user's password. I received error messages when I tried. You *can*, however, change your own password by clicking the My account link in the top right corner and then clicking Change password.

Thursday, May 15, 2008

Gallery Server Pro Roadmap

I recently put together my development roadmap and wanted to publish it to keep everyone in the loop. Many of the new features came from your suggestions in the Features Request forum. Keep 'em coming!

There are no guarantees that I will stay on schedule or that the final features and bug fixes will match what I have here, but this is my best guess at the moment. I welcome help from anyone who wants to lend a hand - feel free to tackle any of these issues or brainstorm your own improvements. Just make sure you coordinate with me so we don't step on each other's toes.

The number by each item is my internal tracking number. Refer to this if you contact me about one of them.

Version 2.1 (due August 2008)

New features

  • Create SQLite provider and make it the default data store. This removes the dependence on SQL Server and will greatly simplify the installation process as well as reduce hosting costs. Users can still use SQL Server if they wish. (#81)
  • Enable data backup and restore functionality. This will allow easier migration from one server to another as well as between SQL Server and SQLite. (#50)
  • Add support for playing video and audio with Silverlight, including those hosted on Silverlight Streaming. (#77)
  • Add support for playing videos hosted on YouTube. (#78)
  • Consolidate language resource files into the minimum possible number of files. This will allow for easier translation. (#80)
  • Allow real-time feedback of upload progress under IIS 7.0 Integrated Pipeline mode. Currently it works only in IIS 6 and IIS 7 Classic mode. (#83)
  • Make it easier for users to financially contribute to Gallery Server Pro. (#84)
  • Ability to run under .NET 3.5 without MS Ajax 1.0 installed. (Not sure if this is possible without switching to requiring the .NET 3.5 runtime, which I am not going to do.) (#85)

Bug fixes

  • Adding an album to a parent album that has just been deleted causes InvalidAlbumException. (bug# 78)
  • Synchronizing video and audio files does not update the original width and height values. (bug# 80)
  • Image metadata is sometimes extracted as the text "System.Int64[]". (bug# 87)
  • An album title with a trailing period or space causes an exception. (bug# 90)
  • Fade effect causes white specs in black areas of photo in IE. (bug# 91)
  • Cannot manage users when passwords are encrypted. (bug# 94)
  • Out of memory error when adding very large images. (bug# 95)
  • Apostrophe in user name or role causes edit user/edit role dialog failure. (bug# 97)
  • File lock not released in certain circumstances (bug# 98)
  • Incomplete error information if an exception occurs when adding a user (bug# 99)
  • Adding a user sometimes never returns from "Communicating with server..." message (bug# 100)
  • Cannot manage users with ActiveDirectory provider (bug# 101) (See thread for workaround.)
  • Album stats count hidden albums (bug# 102)
  • URL occasionally incorrectly calculated when installed as root application (bug# 103)
  • User cannot change password if e-mail functionality is not configured (bug# 104)
  • User cannot change e-mail address on account (bug# 105)
  • Certain images that previously synchronized fail during subsequent synchronizations (bug# 106)
  • Dialog window with the text "true" sometimes appears when clicking the Show metadata toobar icon (bug# 107)

 

Version 2.2 (due December 2008)

New features

  • Wrap Gallery Server into one or more user controls. This will allow much easier integration of Gallery Server Pro into existing web sites. (#92)

 

Version 2.3 (due 2009)

New features

  • Add virtual album support (# 90)
  • Increase robustness of synchronization (# 111)
  • Add more sorting options (# 91)
  • Allow metadata to be edited (# 89)
  • Allow users to comment on media objects (# 95)
  • Allow users to self register user accounts (# 96)
  • Retain log of web errors that can be reviewed in Site Admin area (# 97)
  • View log of user and gallery activity (# 98)
  • Allow album ownership as an alternative to role-based access (# 99)
  • Make it easier to view relationship between users and roles (# 102)
  • Add checkbox on "Delete hi-res images" page to allow recursive deletions (#8)
  • Add quota per user (#27)
  • Fix unintuitive checking/unchecking of albums in treeview (#28)
  • Let user see album view while viewing individual media object (#33)
  • Provide option to discard original image during upload (#36)
  • Improve upload progress bar to include zip file extraction progress (#38)
  • Make thumbnailPath and optimizedPath optional fields in galleryserverpro.config (#48)
  • Allow user to specify media object location during install wizard (#51)
  • Add a config setting that controls the "Remember Me?" checkbox on the login page (#52)
  • Tweak the spacing on the Password tab in Edit User dialog (#53)
  • Allow album date start, date end, date added, date last modified to be searchable (#58)
  • Allow deleting multiple albums from the Delete objects page (# 66)
  • Allow paging of thumbnails on album view page (#70)
  • Allow install wizard to install a second gallery in same database (# 71)
  • Allow relative references to outside the web folder for media objects (# 72)
  • Add option so user always downloads original image rather than displayed image (# 73)
  • Do not include file extension in caption when using filename in media object caption (# 74)
  • Prevent user from specifying a subfolder of the media objects directory for thumbnails/optimized. (# 75)
  • Extract thumbnail image from Shockwave Flash file (# 79)
  • Decrease time it takes to delete albums and media objects (# 86)
  • Allow user to download multiple objects in a single ZIP file (# 87)
  • Add additional information to metadata list, such as file name, file size, data uploaded, etc. (# 88)
  • Extract GPS coordinates from media objects and offer mapping service (# 94)
  • Add slide show duration setting to Site admin section (# 100)
  • Add ability to view recently added media objects (# 105)
  • Improve workflow of assigning thumbnail image (# 106)
  • Add ability to start a slide show from the album view (# 109)
  • Add role permission "Edit child albums" (# 110)

 

Version X.X (who knows when I can get to this)

  • Create client utility that provides an improved UI for copying media objects to server. One feature it could have is to create optimized images on the client and upload those instead of the originals. This could be a great project for one of you developers out there!

- Roger

Wednesday, May 7, 2008

The blog is born

I have wanted to add a blog to this web site for quite a while, but was stymied by the amount of work it would take to code it up. But several weeks ago I read about accessing a blog through an API that is created elsewhere, so I thought I would give it a whirl. I created a blog on Windows Live Spaces and grabbed the RSS feed that it generated. Then I created a web page on www.galleryserverpro.com with an XmlDataSource pointing to the RSS feed and a Repeater that used the XmlDataSource for its data.

Now I can create blog entries through any means supported by Live Spaces (their web tool, Windows Liver Writer, etc.) and the entry automatically appears on the Gallery Server Pro web site. Cool. I am not sure how to handle comments at the moment or what happens as dozens of entries pile up; let's start with basic blog functionality and go from there.

-Roger