Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Password Rule Managing Library

3.55/5 (5 votes)
12 Mar 2018CPOL4 min read 6.3K   94  
This article describes a library which helps manage a collection of password rules for ensuring that a given password passes such rules for acceptance purposes.

Introduction

This project includes a password rule manager which aggregates individual password rules, each rule in its own class, into a PasswordRules class that contains methods and properties for verifying a given password's acceptance of such rules.

The PasswordRules class has the capability to accept a particular set of password rules from its caller, and then verifies the caller's sent password against such rules, responding back to the caller with the status of the password, be it the success or failure.

In my particular situation, I found it helpful to create a subclass of it containing what I considered to be a standard set of rules, but you may create your own, or multiple sets of rules aggregated into their own classes for your specific needs, or even leave out the subclass idea if you only have one set of rules to maintain. For instance, notice the PasswordRulesUsedForTesting class contained within the UnitTestProject. It specifically is used for testing for which I wanted different collections of password rules per various testing needs. I wanted the class to accept whatever its caller required, thereby making it dynamic in nature.

Background

Maybe you've had the same experience as me and have had to struggle with individual applications handling their password rules, each with an entirely different code technique for doing so. Unnecessary code variation increases the difficulty of effectively managing source code. Because of this, I wanted to unify as much code as I could, but also recognize the fact that different applications may require a different set of password rules (possibly for such reasons as differing regulatory requirements per an application, etc.) So, I had to balance the need to unify with the need to handle specific differences.

I achieved this balance of concerns through creating a class library which provides common methods and properties to all via a standard class, and this class can be subclassed with separate constructors containing different sets of password rules.

There is nothing particularly novel about the implementation of the individual password rules but rather the focus of this class library is on the effective aggregation of rules into a class whose methods and properties concerning password validation can be shared across many applications.

Tech Details

The source code exists within a Visual Studio solution named PasswordRuleManager and when compiled, provides a class library as the DLL named as such (the interface DLL is included). I used Visual Studio Professional 2017 with the .NET Framework 4.6.1 for each of the projects within the solution. I also used MS Test for the unit tests (existing within its own unit test project) which provides for a nice way of demonstrating the code, as well as, testing it.

Using the Code

The Visual Studio PasswordRuleManager solution is split into three projects. The core implementation of the class methods are contained within a project named CoreDistributable and contains their PasswordRules and PasswordRulesStandardSet classes. The interfaces are stored within a project named CoreDistributable.Interfaces, and the unit tests are stored within a test project named UnitTestProject.

Why don't we begin our explanation of the code through observing the methods and properties of the PasswordRules class? Then, we'll look at one of the unit tests to demonstrate a practical usage of it.

From the below code segment, you can see that the PasswordRuleList property can be populated by the PasswordRules caller that instantiates it. This allows for the dynamic aggregation of all needed password rules into a single instance.

Also notice that invoking the method VerifyAllRulesForCurrentPassword not only returns a boolean value informing the caller whether the currently provided password passes all rules but also populates the BrokenRulesOfPassword property which lists the specific broken rules.

The property AggregrateMessage is optional. I included this property as a courtesy in the class in order to provide a ready-formatted message that can be used by the object's caller. Obviously, you can have each application (as the caller) format its own message, but I thought it would be helpful to provide it in with the PasswordRules class as an example usage.

C#
public class PasswordRules : IPasswordRules
{
	public List<IPasswordRule> PasswordRuleList { get; } = new List<IPasswordRule>();

	public string CurrentPassword { get; set; }

	public bool VerifyAllRulesForCurrentPassword()
	{
		PasswordRuleList.ForEach(p =>
		{
			p.CurrentPassword = CurrentPassword;

			if (!p.VerifyRuleForCurrentPassword())
			{
				BrokenRulesOfPassword.Add(p);
			}
		});

		return !BrokenRulesOfPassword.Any();
	}

	public List<IPasswordRule> BrokenRulesOfPassword { get; } = new List<IPasswordRule>();

	public string AggregateMessage
	{
		get
		{
			var failureMsg = new StringBuilder();
			BrokenRulesOfPassword.ForEach(p =>
			{
				failureMsg.AppendLine(p.FailureMessage);
			});

			return failureMsg.ToString();
		}
	}
}

Now that we're reviewed the methods and properties of the main class, let us look at an example taken from one of the unit tests. Below is an example in which we pretend that the caller requests to know whether a password is valid, and the manager class discovers that the password violates a rule, specifically that the password is too short.

C#
[TestClass]
public class TestPasswordAgainstRulesCollection
{
	[TestMethod]
	public void Test_Containing1Member_BadPassword()
	{
		var passwordRules = CollectionsUsedForTesting.CreateCollectionContaining1Member();
		passwordRules.CurrentPassword = "1234567";

		Assert.IsFalse(passwordRules.VerifyAllRulesForCurrentPassword());
		Assert.IsTrue(passwordRules.BrokenRulesOfPassword.Count == 1);
		Assert.IsInstanceOfType(passwordRules.BrokenRulesOfPassword[0], 
                                        typeof(PasswordMinLengthRule));
		StringAssert.Contains(passwordRules.AggregateMessage, 
                     "A password must meet the minimum length requirement of 8 characters");
	}

Points of Interest

The creation of the PasswordRulesStandardSet class was only a suggestion in this project whose example use is relevant should you desire to assign different classes to various sets of password rules. If all of your applications use the same set of rules, then this class is not needed and you can remove it.

The individual password rules are grouped within a folder named IndividualRules within the CoreDistributable project. Even if you have different sets of password rules needed for various applications, I would still suggest that you keep the totality of all of your password rules within this folder.

Included as one of the solution items is a text file named PasswordRuleManagerNotes which contains credits for the implementation of some of the individual password rules.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)