Click here to Skip to main content
15,894,343 members
Articles / Web Development / HTML

Gallery Server Pro - An ASP.NET Gallery for Sharing Photos, Video, Audio and Other Media

Rate me:
Please Sign up or sign in to vote.
4.86/5 (131 votes)
18 Oct 2013GPL331 min read 828.6K   539  
Gallery Server Pro is a complete, stable ASP.NET gallery for sharing photos, video, audio and other media. This article presents the overall architecture and major features.
using System;
using GalleryServerPro.Licensing.GspWeb;

namespace GalleryServerPro.Licensing
{
	/// <summary>
	/// Contains functionality for managing the license for Gallery Server Pro.
	/// </summary>
	public static class LicenseManager
	{
		private const string GspDnnProductType = "GspDnnModule";

		/// <summary>
		/// Validates the specified <paramref name="productKey"/> is valid against the specified <paramref name="version"/>.
		/// Inspect the properties of the returned <see cref="ProductKeyEntity"/> for details of the validation results.
		/// </summary>
		/// <param name="productKey">The product key to validate.</param>
		/// <param name="version">The current version of Gallery Server Pro. Example: 2.3.3750</param>
		/// <param name="performWebServiceValidation">if set to <c>true</c> validate the license using a web service invocation
		/// against a server run by Tech Info Systems. This parameter is ignored in stand-alone versions of GSP, since it 
		/// never invokes a web service.</param>
		/// <returns>
		/// Returns a <see cref="ProductKeyEntity"/> with details of the validation results.
		/// </returns>
		public static ProductKeyEntity Validate(string productKey, string version, bool performWebServiceValidation)
		{
			return ValidateProductKey(productKey, version, performWebServiceValidation);
		}

		private static ProductKeyEntity ValidateProductKey(string productKey, string version, bool performWebServiceValidation)
		{
			ProductKeyEntity pk = DecryptAndParseProductKey(productKey);

			pk.ProductType = GspDnnProductType;

			pk = ValidateDecryptedProductKey(pk, version);

			if (performWebServiceValidation)
			{
				pk = ValidateWithWebService(pk);
			}

			return pk;
		}

		private static ProductKeyEntity ValidateDecryptedProductKey(ProductKeyEntity pk, string version)
		{
			if (!pk.KeyIsValid)
				return pk;

			if (String.IsNullOrEmpty(pk.Email) || String.IsNullOrEmpty(pk.LicenseType) || String.IsNullOrEmpty(pk.Version))
			{
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = "Invalid product key";
			}

			pk = ValidateVersion(pk, version);

			pk = ValidateEmail(pk);

			return pk;
		}

		private static ProductKeyEntity ValidateVersion(ProductKeyEntity pk, string version)
		{
			if (!pk.KeyIsValid)
				return pk;

			if (pk.Version.CompareTo(GetMajorMinorVersion(version)) < 0)
			{
				// The application is running a newer version than the product key is valid for.
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = string.Format("Product key is for version {0}, but the application is running version {1} ({2}). Purchase a new product key.", pk.Version, GetMajorMinorVersion(version), version);
			}

			return pk;
		}

		private static ProductKeyEntity ValidateEmail(ProductKeyEntity pk)
		{
			if (!pk.KeyIsValid)
				return pk;

			if (!Email.IsValidEmail(pk.Email))
			{
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = "Product key does not contain a valid e-mail address.";
			}

			return pk;
		}

		private static ProductKeyEntity DecryptAndParseProductKey(string productKey)
		{
			ProductKeyEntity pk = new ProductKeyEntity();
			pk.ProductKey = productKey;

			if (String.IsNullOrEmpty(productKey))
			{
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = "No product key entered.";
				return pk;
			}

			pk.KeyIsValid = true; // Assume it is valid, we'll set to false if any test fails.
			string decryptedProductKey;

			try
			{
				decryptedProductKey = Encrypt.DecryptString(productKey);
			}
			catch (FormatException)
			{
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = "Invalid product key";

				return pk;
			}
			catch (System.Security.Cryptography.CryptographicException)
			{
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = "Invalid product key";

				return pk;
			}

			return PopulateProductKeyEntity(pk, decryptedProductKey);
		}

		private static string GetMajorMinorVersion(string fullVersion)
		{
			// If fullVersion = "2.4.2395", return 2.4.
			string version = String.Empty;
			int versionPartCounter = 0;

			foreach (string versionPart in fullVersion.Split(new char[] { '.' }))
			{
				version += versionPart;
				versionPartCounter++;

				if (versionPartCounter >= 2)
				{
					break;
				}

				version += ".";
			}

			return version;
		}

		private static ProductKeyEntity ValidateWithWebService(ProductKeyEntity pk)
		{
			if (!pk.KeyIsValid)
				return pk;

			Gallery webservice = new GspWeb.Gallery();

			try
			{
				pk = webservice.ValidateProductKey(pk);
			}
			catch (System.Web.Services.Protocols.SoapException) {}
			catch (System.Net.WebException) {}

			return pk;
		}

		private static ProductKeyEntity PopulateProductKeyEntity(ProductKeyEntity pk, string decryptedProductKey)
		{
			if (pk == null)
			{
				throw new ArgumentNullException("pk");
			}

			if (String.IsNullOrEmpty(decryptedProductKey))
			{
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = "Invalid product key. Does not contain expected information.";

				return pk;
			}

			string[] productKeyParts = decryptedProductKey.Split(new char[] { '|' });

			if (productKeyParts.Length == 3)
			{
				pk.Email = productKeyParts[0];
				pk.Version = productKeyParts[1];
				pk.LicenseType = productKeyParts[2];
			}
			else
			{
				pk.KeyIsValid = false;
				pk.KeyInvalidReason = "Invalid product key. Does not contain expected information.";
			}

			return pk;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer (Senior) Tech Info Systems
United States United States
I have nearly 20 years of industry experience in software development, architecture, and Microsoft Office products. My company Tech Info Systems provides custom software development services for corporations, governments, and other organizations. Tech Info Systems is a registered member of the Microsoft Partner Program and I am a Microsoft Certified Professional Developer (MCPD).

I am the creator and lead developer of Gallery Server Pro, a free, open source ASP.NET gallery for sharing photos, video, audio, documents, and other files over the web. It has been developed over several years and has involved thousands of hours. The end result is a robust, configurable, and professional grade gallery that can be integrated into your web site, whether you are a large corporation, small business, professional photographer, or a local church.

Comments and Discussions