Skip to content

Commit b3badf7

Browse files
author
Andreas Eriksson
committed
Merge branch 'feature/other-linq-merge' into version-next
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.
2 parents 42c664d + a7feec9 commit b3badf7

File tree

8 files changed

+919
-754
lines changed

8 files changed

+919
-754
lines changed

Rhino.Security.Tests/AuthorizationService_Queries_Fixture.cs

Lines changed: 591 additions & 591 deletions
Large diffs are not rendered by default.

Rhino.Security.Tests/Rhino.Security.Tests.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
</ItemGroup>
1818

1919
<ItemGroup>
20-
<PackageReference Include="LinqKit.Core" Version="1.1.17" />
2120
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
2221
<PackageReference Include="System.Data.SqlClient" Version="4.8.0" />
2322
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.112" />

Rhino.Security/Interfaces/IAuthorizationService.cs

Lines changed: 63 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,109 +6,106 @@
66
namespace Rhino.Security.Interfaces
77
{
88
///<summary>
9-
/// Implementors of this interface are able to answer
10-
/// on authorization questions as well as enhance Criteria
11-
/// queries
9+
/// Implementors of this interface are able to answer
10+
/// on authorization questions as well as enhance Criteria
11+
/// queries
1212
///</summary>
1313
public interface IAuthorizationService
1414
{
1515
/// <summary>
16-
/// Adds the permissions to the criteria query.
16+
/// Adds the permissions to the linq query.
17+
/// </summary>
18+
/// <param name="user">The user.</param>
19+
/// <param name="operation">The operation.</param>
20+
/// <param name="query">The query.</param>
21+
IQueryable<TEntity> AddPermissionsToQuery<TEntity>(IUser user, string operation, IQueryable<TEntity> query) where TEntity : class;
22+
23+
///<summary>
24+
/// Adds the permissions to the linq query for the given usersgroup
25+
///</summary>
26+
///<param name="usersgroup">The usersgroup. Only permissions directly related to this usergroup
27+
/// are taken into account</param>
28+
///<param name="operation">The operation</param>
29+
/// <param name="query">The query.</param>
30+
IQueryable<TEntity> AddPermissionsToQuery<TEntity>(UsersGroup usersgroup, string operation, IQueryable<TEntity> query) where TEntity : class;
31+
32+
/// <summary>
33+
/// Adds the permissions to the criteria query.
1734
/// </summary>
18-
/// <param name = "user">The user.</param>
35+
/// <param name="user">The user.</param>
1936
/// <param name = "operation">The operation.</param>
20-
/// <param name = "criteria">The criteria.</param>
37+
/// <param name="criteria">The criteria.</param>
2138
void AddPermissionsToQuery(IUser user, string operation, ICriteria criteria);
2239

23-
///<summary>
24-
/// Adds the permissions to the criteria query for the given usersgroup
25-
///</summary>
26-
///<param name = "usersgroup">The usersgroup. Only permissions directly related to this usergroup
27-
/// are taken into account</param>
28-
///<param name = "operation">The operation</param>
29-
///<param name = "criteria">The criteria</param>
30-
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, ICriteria criteria);
40+
///<summary>
41+
/// Adds the permissions to the criteria query for the given usersgroup
42+
///</summary>
43+
///<param name="usersgroup">The usersgroup. Only permissions directly related to this usergroup
44+
/// are taken into account</param>
45+
///<param name="operation">The operation</param>
46+
///<param name="criteria">The criteria</param>
47+
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, ICriteria criteria);
3148

3249
/// <summary>
33-
/// Adds the permissions to the criteria query.
50+
/// Adds the permissions to the criteria query.
3451
/// </summary>
35-
/// <param name = "user">The user.</param>
36-
/// <param name = "criteria">The criteria.</param>
37-
/// <param name = "operation">The operation.</param>
52+
/// <param name="user">The user.</param>
53+
/// <param name="criteria">The criteria.</param>
54+
/// <param name="operation">The operation.</param>
3855
void AddPermissionsToQuery(IUser user, string operation, DetachedCriteria criteria);
3956

40-
/// <summary>
41-
/// Adds the permissions to the NHibernate Linq IQueryable query.
42-
/// </summary>
43-
/// <param name="user">The user</param>
44-
/// <param name="operation">The operation</param>
45-
/// <param name="query">The NHibernate Linq IQueryable</param>
46-
/// <typeparam name="T">The type of the IQueryable</typeparam>
47-
/// <returns>Queryable with permissions added</returns>
48-
IQueryable<T> AddPermissionsToQuery<T>(IUser user, string operation, IQueryable<T> query);
49-
50-
/// <summary>
51-
/// Adds the permissions to the NHibernate Linq IQueryable query for the given usergorup
52-
/// </summary>
53-
/// <param name="usersgroup">The usergroup</param>
54-
/// <param name="operation">The operation</param>
55-
/// <param name="query">The NHibernate Linq IQueryable</param>
56-
/// <typeparam name="T">The type of the IQueryable</typeparam>
57-
/// <returns>Queryable with permissions added</returns>
58-
IQueryable<T> AddPermissionsToQuery<T>(UsersGroup usersgroup, string operation, IQueryable<T> query);
59-
60-
///<summary>
57+
///<summary>
6158
/// Adds the permissions to the criteria query for the given usersgroup
62-
///</summary>
63-
///<param name = "usersgroup">The usersgroup. Only permissions directly related to this usergroup
64-
/// are taken into account</param>
65-
///<param name = "operation">The operation</param>
66-
///<param name = "criteria">The criteria</param>
67-
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, DetachedCriteria criteria);
59+
///</summary>
60+
///<param name="usersgroup">The usersgroup. Only permissions directly related to this usergroup
61+
/// are taken into account</param>
62+
///<param name="operation">The operation</param>
63+
///<param name="criteria">The criteria</param>
64+
void AddPermissionsToQuery(UsersGroup usersgroup, string operation, DetachedCriteria criteria);
6865

6966
/// <summary>
70-
/// Determines whether the specified user is allowed to perform the specified
71-
/// operation on the entity
67+
/// Determines whether the specified user is allowed to perform the specified
68+
/// operation on the entity
7269
/// </summary>
73-
/// <typeparam name = "TEntity">The type of the entity.</typeparam>
74-
/// <param name = "user">The user.</param>
75-
/// <param name = "entity">The entity.</param>
76-
/// <param name = "operation">The operation.</param>
70+
/// <typeparam name="TEntity">The type of the entity.</typeparam>
71+
/// <param name="user">The user.</param>
72+
/// <param name="entity">The entity.</param>
73+
/// <param name="operation">The operation.</param>
7774
/// <returns>
7875
/// <c>true</c> if the specified user is allowed; otherwise, <c>false</c>.
7976
/// </returns>
8077
bool IsAllowed<TEntity>(IUser user, TEntity entity, string operation) where TEntity : class;
8178

8279
/// <summary>
83-
/// Determines whether the specified user is allowed to perform the
84-
/// specified operation on the entity.
80+
/// Determines whether the specified user is allowed to perform the
81+
/// specified operation on the entity.
8582
/// </summary>
86-
/// <param name = "user">The user.</param>
87-
/// <param name = "operation">The operation.</param>
83+
/// <param name="user">The user.</param>
84+
/// <param name="operation">The operation.</param>
8885
/// <returns>
8986
/// <c>true</c> if the specified user is allowed; otherwise, <c>false</c>.
9087
/// </returns>
9188
bool IsAllowed(IUser user, string operation);
9289

9390
/// <summary>
94-
/// Gets the authorization information for the specified user and operation,
95-
/// allows to easily understand why a given operation was granted / denied.
91+
/// Gets the authorization information for the specified user and operation,
92+
/// allows to easily understand why a given operation was granted / denied.
9693
/// </summary>
97-
/// <param name = "user">The user.</param>
98-
/// <param name = "operation">The operation.</param>
94+
/// <param name="user">The user.</param>
95+
/// <param name="operation">The operation.</param>
9996
/// <returns></returns>
10097
AuthorizationInformation GetAuthorizationInformation(IUser user, string operation);
10198

10299
/// <summary>
103-
/// Gets the authorization information for the specified user and operation on the
104-
/// given entity, allows to easily understand why a given operation was granted / denied.
100+
/// Gets the authorization information for the specified user and operation on the
101+
/// given entity, allows to easily understand why a given operation was granted / denied.
105102
/// </summary>
106-
/// <typeparam name = "TEntity">The type of the entity.</typeparam>
107-
/// <param name = "user">The user.</param>
108-
/// <param name = "entity">The entity.</param>
109-
/// <param name = "operation">The operation.</param>
103+
/// <typeparam name="TEntity">The type of the entity.</typeparam>
104+
/// <param name="user">The user.</param>
105+
/// <param name="entity">The entity.</param>
106+
/// <param name="operation">The operation.</param>
110107
/// <returns></returns>
111108
AuthorizationInformation GetAuthorizationInformation<TEntity>(IUser user, TEntity entity, string operation)
112109
where TEntity : class;
113-
}
110+
}
114111
}

Rhino.Security/Linq/LinqExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public static IQueryable<T> AddPermissions<T>(
2222
this IQueryable<T> query,
2323
IAuthorizationService authorizationService,
2424
IUser user,
25-
string operation)
25+
string operation) where T : class
2626
{
2727
var queryWithPermissions = authorizationService.AddPermissionsToQuery(user, operation, query);
2828
return queryWithPermissions;
@@ -41,7 +41,7 @@ public static IQueryable<T> AddPermissions<T>(
4141
this IQueryable<T> query,
4242
IAuthorizationService authorizationService,
4343
UsersGroup usersGroup,
44-
string operation)
44+
string operation) where T : class
4545
{
4646
var queryWithPermissions = authorizationService.AddPermissionsToQuery(usersGroup, operation, query);
4747
return queryWithPermissions;

Rhino.Security/Rhino.Security.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
</ItemGroup>
4040

4141
<ItemGroup>
42-
<PackageReference Include="LinqKit.Core" Version="1.1.8" />
4342
<PackageReference Include="NHibernate" Version="5.2.0" />
4443
<PackageReference Include="CommonServiceLocator" Version="2.0.5" />
4544
</ItemGroup>

Rhino.Security/Security.cs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,34 @@ namespace Rhino.Security
1414
/// <summary>
1515
/// This class allows to configure the security system
1616
/// </summary>
17-
public class Security
17+
public static class Security
1818
{
1919
private static readonly MethodInfo getSecurityKeyMethod = typeof (Security).GetMethod(
2020
"GetSecurityKeyPropertyInternal", BindingFlags.NonPublic | BindingFlags.Static);
2121

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

25+
private static string _userTypeIdPropName = null;
26+
private static Type _userTypeForIdPropName = null;
27+
28+
/// <summary>
29+
/// Gets the ID property name for the given user type
30+
/// </summary>
31+
/// <param name="session">The session to be used for the class metadata lookup.</param>
32+
/// <returns>The ID property name.</returns>
33+
internal static string GetUserTypeIdPropertyName(NHibernate.ISession session)
34+
{
35+
if (_userTypeIdPropName == null || _userTypeForIdPropName != Security.UserType)
36+
_userTypeIdPropName = session.SessionFactory.GetClassMetadata(Security.UserType).IdentifierPropertyName;
37+
return _userTypeIdPropName;
38+
}
39+
40+
/// <summary>
41+
/// The type of the IUser implementation.
42+
/// </summary>
43+
public static Type UserType { get; private set; }
44+
2545
/// <summary>
2646
/// Extracts the key from the specified entity.
2747
/// </summary>
@@ -36,7 +56,7 @@ public static Guid ExtractKey<TEntity>(TEntity entity)
3656
return extractor.GetSecurityKeyFor(entity);
3757
}
3858

39-
/// <summary>
59+
/// <summary>
4060
/// Extracts the key from the specified entity using the given object.
4161
/// </summary>
4262
/// <param name="entity">The entity.</param>
@@ -104,16 +124,17 @@ internal static string GetSecurityKeyPropertyInternal<TEntity>()
104124
return ServiceLocator.Current.GetInstance<IEntityInformationExtractor<TEntity>>().SecurityKeyPropertyName;
105125
}
106126

107-
///<summary>
108-
/// Setup NHibernate to include Rhino Security configuration
109-
///</summary>
110-
public static void Configure<TUserType>(Configuration cfg, SecurityTableStructure securityTableStructure)
111-
where TUserType : IUser
112-
{
113-
cfg.AddAssembly(typeof (IUser).Assembly);
114-
new SchemaChanger(cfg, securityTableStructure).Change();
115-
new UserMapper(cfg, typeof(TUserType)).Map();
127+
///<summary>
128+
/// Setup NHibernate to include Rhino Security configuration
129+
///</summary>
130+
public static void Configure<TUserType>(Configuration cfg, SecurityTableStructure securityTableStructure)
131+
where TUserType : IUser
132+
{
133+
UserType = typeof(TUserType);
134+
cfg.AddAssembly(typeof (IUser).Assembly);
135+
new SchemaChanger(cfg, securityTableStructure).Change();
136+
new UserMapper(cfg, typeof(TUserType)).Map();
116137
cfg.SetListener(ListenerType.PreDelete, new DeleteEntityEventListener());
117-
}
138+
}
118139
}
119140
}

0 commit comments

Comments
 (0)