Skip to content

Instantly share code, notes, and snippets.

@jasondentler
Created June 28, 2013 19:54
Show Gist options
  • Save jasondentler/5887566 to your computer and use it in GitHub Desktop.
Save jasondentler/5887566 to your computer and use it in GitHub Desktop.
namespace DWH.Security
{
public static class Constants
{
public const string ActionPrefix = "PERM-";
public const string CommunityPrefix = "PERM-COMM-";
public const string ProjectPrefix = "PERM-PROJ-";
public const string DivisionPrefix = "PERM-DIV-";
public const string MarketPrefix = "PERM-MKT-";
public const string AreaPrefix = "PERM-AREA-";
}
}
using System.Security.Principal;
namespace DWH.Security
{
public interface IPrincipalProvider
{
IPrincipal GetCurrent();
}
}
namespace DWH.Security
{
public enum ScopeLevel
{
Community,
Project,
Division,
Market,
Area
}
}
using System;
using System.Diagnostics.Contracts;
using System.Linq;
namespace DWH.Security
{
public class SecurityProvider
{
private readonly IPrincipalProvider _principalProvider;
private readonly Action _onGuardUnauthorized;
public SecurityProvider(IPrincipalProvider principalProvider, Action onGuardUnauthorized)
{
if (principalProvider == null) throw new ArgumentNullException("principalProvider");
if (onGuardUnauthorized == null) throw new ArgumentNullException("onGuardUnauthorized");
Contract.EndContractBlock();
_principalProvider = principalProvider;
_onGuardUnauthorized = onGuardUnauthorized;
}
public void Require(string action)
{
if (!IsAuthorized(action))
_onGuardUnauthorized();
}
public void Require(string action, ScopeLevel scopeLevel, string scope)
{
if (!IsAuthorized(action, scopeLevel, scope))
_onGuardUnauthorized();
}
public bool IsAuthorized(string action)
{
if (action == null) throw new ArgumentNullException("action");
Contract.EndContractBlock();
return IsAuthorized(ActionToRole(action));
}
public bool IsAuthorized(string action, ScopeLevel scopeLevel, string scope)
{
if (action == null) throw new ArgumentNullException("action");
if (scope == null) throw new ArgumentNullException("scope");
Contract.EndContractBlock();
var actionRole = ActionToRole(action);
var scopeRole = ScopeToRole(scopeLevel, scope);
return IsAuthorized(actionRole, scopeRole);
}
private string ActionToRole(string action)
{
return Constants.ActionPrefix + action;
}
private string ScopeToRole(ScopeLevel scopeLevel, string scope)
{
switch (scopeLevel)
{
case ScopeLevel.Community:
return CommunityToRole(scope);
case ScopeLevel.Project:
return ProjectToRole(scope);
case ScopeLevel.Division:
return DivisionToRole(scope);
case ScopeLevel.Market:
return MarketToRole(scope);
case ScopeLevel.Area:
return AreaToRole(scope);
default:
throw new ArgumentException(string.Format("ScopeLevel {0} is not supported.", scopeLevel),
"scopeLevel");
}
}
private string CommunityToRole(string community)
{
return Constants.CommunityPrefix + community;
}
private string ProjectToRole(string project)
{
return Constants.ProjectPrefix + project;
}
private string DivisionToRole(string division)
{
return Constants.DivisionPrefix + division;
}
private string MarketToRole(string market)
{
return Constants.MarketPrefix + market;
}
private string AreaToRole(string area)
{
return Constants.AreaPrefix + area;
}
private bool IsAuthorized(params string[] requiredRoles)
{
if (requiredRoles == null) throw new ArgumentNullException("requiredRoles");
Contract.EndContractBlock();
Contract.Requires(Contract.ForAll(requiredRoles, r => r != null));
var user = _principalProvider.GetCurrent();
if (user == null) return false;
return requiredRoles.All(user.IsInRole);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment