Skip to content

Commit

Permalink
Merge branch 'feature/other-linq-merge' into version-next
Browse files Browse the repository at this point in the history
This implements another way of adding the security enhancements to a Linq query.

This is a cherry-pick of PR hibernating-rhinos#11 on ayende/rhino-security on GitHub
(ayende#11)

After some evaluation I went for Mark Junkers implementation because
it did not depend on LinkKit. Even though I think my implementation
is cleaner and much easier to understand.

I think that a library of this kind should be really easy to use in
an solution and to minimize external dependencies is a worth alot.
  • Loading branch information
whyer committed Jan 8, 2020
2 parents 42c664d + a7feec9 commit b3badf7
Show file tree
Hide file tree
Showing 8 changed files with 919 additions and 754 deletions.
1,182 changes: 591 additions & 591 deletions Rhino.Security.Tests/AuthorizationService_Queries_Fixture.cs

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Rhino.Security.Tests/Rhino.Security.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="LinqKit.Core" Version="1.1.17" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.0" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.112" />
Expand Down
129 changes: 63 additions & 66 deletions Rhino.Security/Interfaces/IAuthorizationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,109 +6,106 @@
namespace Rhino.Security.Interfaces
{
///<summary>
/// Implementors of this interface are able to answer
/// on authorization questions as well as enhance Criteria
/// queries
/// Implementors of this interface are able to answer
/// on authorization questions as well as enhance Criteria
/// queries
///</summary>
public interface IAuthorizationService
{
/// <summary>
/// Adds the permissions to the criteria query.
/// Adds the permissions to the linq query.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="operation">The operation.</param>
/// <param name="query">The query.</param>
IQueryable<TEntity> AddPermissionsToQuery<TEntity>(IUser user, string operation, IQueryable<TEntity> query) where TEntity : class;

///<summary>
/// Adds the permissions to the linq query for the given usersgroup
///</summary>
///<param name="usersgroup">The usersgroup. Only permissions directly related to this usergroup
/// are taken into account</param>
///<param name="operation">The operation</param>
/// <param name="query">The query.</param>
IQueryable<TEntity> AddPermissionsToQuery<TEntity>(UsersGroup usersgroup, string operation, IQueryable<TEntity> query) where TEntity : class;

/// <summary>
/// Adds the permissions to the criteria query.
/// </summary>
/// <param name = "user">The user.</param>
/// <param name="user">The user.</param>
/// <param name = "operation">The operation.</param>
/// <param name = "criteria">The criteria.</param>
/// <param name="criteria">The criteria.</param>
void AddPermissionsToQuery(IUser user, string operation, ICriteria criteria);

///<summary>
/// Adds the permissions to the criteria query for the given usersgroup
///</summary>
///<param name = "usersgroup">The usersgroup. Only permissions directly related to this usergroup
/// are taken into account</param>
///<param name = "operation">The operation</param>
///<param name = "criteria">The criteria</param>
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, ICriteria criteria);
///<summary>
/// Adds the permissions to the criteria query for the given usersgroup
///</summary>
///<param name="usersgroup">The usersgroup. Only permissions directly related to this usergroup
/// are taken into account</param>
///<param name="operation">The operation</param>
///<param name="criteria">The criteria</param>
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, ICriteria criteria);

/// <summary>
/// Adds the permissions to the criteria query.
/// Adds the permissions to the criteria query.
/// </summary>
/// <param name = "user">The user.</param>
/// <param name = "criteria">The criteria.</param>
/// <param name = "operation">The operation.</param>
/// <param name="user">The user.</param>
/// <param name="criteria">The criteria.</param>
/// <param name="operation">The operation.</param>
void AddPermissionsToQuery(IUser user, string operation, DetachedCriteria criteria);

/// <summary>
/// Adds the permissions to the NHibernate Linq IQueryable query.
/// </summary>
/// <param name="user">The user</param>
/// <param name="operation">The operation</param>
/// <param name="query">The NHibernate Linq IQueryable</param>
/// <typeparam name="T">The type of the IQueryable</typeparam>
/// <returns>Queryable with permissions added</returns>
IQueryable<T> AddPermissionsToQuery<T>(IUser user, string operation, IQueryable<T> query);

/// <summary>
/// Adds the permissions to the NHibernate Linq IQueryable query for the given usergorup
/// </summary>
/// <param name="usersgroup">The usergroup</param>
/// <param name="operation">The operation</param>
/// <param name="query">The NHibernate Linq IQueryable</param>
/// <typeparam name="T">The type of the IQueryable</typeparam>
/// <returns>Queryable with permissions added</returns>
IQueryable<T> AddPermissionsToQuery<T>(UsersGroup usersgroup, string operation, IQueryable<T> query);

///<summary>
///<summary>
/// Adds the permissions to the criteria query for the given usersgroup
///</summary>
///<param name = "usersgroup">The usersgroup. Only permissions directly related to this usergroup
/// are taken into account</param>
///<param name = "operation">The operation</param>
///<param name = "criteria">The criteria</param>
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, DetachedCriteria criteria);
///</summary>
///<param name="usersgroup">The usersgroup. Only permissions directly related to this usergroup
/// are taken into account</param>
///<param name="operation">The operation</param>
///<param name="criteria">The criteria</param>
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, DetachedCriteria criteria);

/// <summary>
/// Determines whether the specified user is allowed to perform the specified
/// operation on the entity
/// Determines whether the specified user is allowed to perform the specified
/// operation on the entity
/// </summary>
/// <typeparam name = "TEntity">The type of the entity.</typeparam>
/// <param name = "user">The user.</param>
/// <param name = "entity">The entity.</param>
/// <param name = "operation">The operation.</param>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <param name="user">The user.</param>
/// <param name="entity">The entity.</param>
/// <param name="operation">The operation.</param>
/// <returns>
/// <c>true</c> if the specified user is allowed; otherwise, <c>false</c>.
/// </returns>
bool IsAllowed<TEntity>(IUser user, TEntity entity, string operation) where TEntity : class;

/// <summary>
/// Determines whether the specified user is allowed to perform the
/// specified operation on the entity.
/// Determines whether the specified user is allowed to perform the
/// specified operation on the entity.
/// </summary>
/// <param name = "user">The user.</param>
/// <param name = "operation">The operation.</param>
/// <param name="user">The user.</param>
/// <param name="operation">The operation.</param>
/// <returns>
/// <c>true</c> if the specified user is allowed; otherwise, <c>false</c>.
/// </returns>
bool IsAllowed(IUser user, string operation);

/// <summary>
/// Gets the authorization information for the specified user and operation,
/// allows to easily understand why a given operation was granted / denied.
/// Gets the authorization information for the specified user and operation,
/// allows to easily understand why a given operation was granted / denied.
/// </summary>
/// <param name = "user">The user.</param>
/// <param name = "operation">The operation.</param>
/// <param name="user">The user.</param>
/// <param name="operation">The operation.</param>
/// <returns></returns>
AuthorizationInformation GetAuthorizationInformation(IUser user, string operation);

/// <summary>
/// Gets the authorization information for the specified user and operation on the
/// given entity, allows to easily understand why a given operation was granted / denied.
/// Gets the authorization information for the specified user and operation on the
/// given entity, allows to easily understand why a given operation was granted / denied.
/// </summary>
/// <typeparam name = "TEntity">The type of the entity.</typeparam>
/// <param name = "user">The user.</param>
/// <param name = "entity">The entity.</param>
/// <param name = "operation">The operation.</param>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <param name="user">The user.</param>
/// <param name="entity">The entity.</param>
/// <param name="operation">The operation.</param>
/// <returns></returns>
AuthorizationInformation GetAuthorizationInformation<TEntity>(IUser user, TEntity entity, string operation)
where TEntity : class;
}
}
}
4 changes: 2 additions & 2 deletions Rhino.Security/Linq/LinqExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static IQueryable<T> AddPermissions<T>(
this IQueryable<T> query,
IAuthorizationService authorizationService,
IUser user,
string operation)
string operation) where T : class
{
var queryWithPermissions = authorizationService.AddPermissionsToQuery(user, operation, query);
return queryWithPermissions;
Expand All @@ -41,7 +41,7 @@ public static IQueryable<T> AddPermissions<T>(
this IQueryable<T> query,
IAuthorizationService authorizationService,
UsersGroup usersGroup,
string operation)
string operation) where T : class
{
var queryWithPermissions = authorizationService.AddPermissionsToQuery(usersGroup, operation, query);
return queryWithPermissions;
Expand Down
1 change: 0 additions & 1 deletion Rhino.Security/Rhino.Security.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="LinqKit.Core" Version="1.1.8" />
<PackageReference Include="NHibernate" Version="5.2.0" />
<PackageReference Include="CommonServiceLocator" Version="2.0.5" />
</ItemGroup>
Expand Down
45 changes: 33 additions & 12 deletions Rhino.Security/Security.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,34 @@ namespace Rhino.Security
/// <summary>
/// This class allows to configure the security system
/// </summary>
public class Security
public static class Security
{
private static readonly MethodInfo getSecurityKeyMethod = typeof (Security).GetMethod(
"GetSecurityKeyPropertyInternal", BindingFlags.NonPublic | BindingFlags.Static);

private static readonly Dictionary<Type, Func<string>> GetSecurityKeyPropertyCache =
new Dictionary<Type, Func<string>>();

private static string _userTypeIdPropName = null;
private static Type _userTypeForIdPropName = null;

/// <summary>
/// Gets the ID property name for the given user type
/// </summary>
/// <param name="session">The session to be used for the class metadata lookup.</param>
/// <returns>The ID property name.</returns>
internal static string GetUserTypeIdPropertyName(NHibernate.ISession session)
{
if (_userTypeIdPropName == null || _userTypeForIdPropName != Security.UserType)
_userTypeIdPropName = session.SessionFactory.GetClassMetadata(Security.UserType).IdentifierPropertyName;
return _userTypeIdPropName;
}

/// <summary>
/// The type of the IUser implementation.
/// </summary>
public static Type UserType { get; private set; }

/// <summary>
/// Extracts the key from the specified entity.
/// </summary>
Expand All @@ -36,7 +56,7 @@ public static Guid ExtractKey<TEntity>(TEntity entity)
return extractor.GetSecurityKeyFor(entity);
}

/// <summary>
/// <summary>
/// Extracts the key from the specified entity using the given object.
/// </summary>
/// <param name="entity">The entity.</param>
Expand Down Expand Up @@ -104,16 +124,17 @@ internal static string GetSecurityKeyPropertyInternal<TEntity>()
return ServiceLocator.Current.GetInstance<IEntityInformationExtractor<TEntity>>().SecurityKeyPropertyName;
}

///<summary>
/// Setup NHibernate to include Rhino Security configuration
///</summary>
public static void Configure<TUserType>(Configuration cfg, SecurityTableStructure securityTableStructure)
where TUserType : IUser
{
cfg.AddAssembly(typeof (IUser).Assembly);
new SchemaChanger(cfg, securityTableStructure).Change();
new UserMapper(cfg, typeof(TUserType)).Map();
///<summary>
/// Setup NHibernate to include Rhino Security configuration
///</summary>
public static void Configure<TUserType>(Configuration cfg, SecurityTableStructure securityTableStructure)
where TUserType : IUser
{
UserType = typeof(TUserType);
cfg.AddAssembly(typeof (IUser).Assembly);
new SchemaChanger(cfg, securityTableStructure).Change();
new UserMapper(cfg, typeof(TUserType)).Map();
cfg.SetListener(ListenerType.PreDelete, new DeleteEntityEventListener());
}
}
}
}
Loading

0 comments on commit b3badf7

Please sign in to comment.