1- namespace RutaHttpModule
1+ using System . Collections . Concurrent ;
2+
3+ namespace RutaHttpModule
24{
35 using System ;
46 using System . Diagnostics ;
@@ -30,6 +32,9 @@ public sealed class RutaModule : IHttpModule
3032 /// </summary>
3133 private readonly ITraceSource traceSource ;
3234
35+ private readonly ConcurrentDictionary < string , ( string login , string name , string email , string [ ] groups ) > cache =
36+ new ConcurrentDictionary < string , ( string login , string name , string email , string [ ] groups ) > ( ) ;
37+
3338 /// <summary>
3439 /// Initializes a new instance of the a <see cref="RutaModule"/> object
3540 /// </summary>
@@ -135,28 +140,55 @@ private void HandleAuthorizeRequestInternal(IRutaHttpContext context)
135140 traceSource . TraceEvent ( TraceEventType . Information , 0 , "No username in context" ) ;
136141 return ;
137142 }
138-
139- var userInformation = this . adInteraction . GetUserInformation ( userName ) ;
140- if ( string . IsNullOrWhiteSpace ( userInformation . login ) )
143+
144+ ( string loginToSend , string name , string email , string [ ] groupsToSend ) = this . GetUserInformation ( userName ) ;
145+ if ( loginToSend == null || name == null || email == null )
141146 {
142- traceSource . TraceEvent ( TraceEventType . Information , 0 , "No user information in context " ) ;
147+ traceSource . TraceEvent ( TraceEventType . Information , 0 , "No data available " ) ;
143148 return ;
144149 }
145150
146- traceSource . TraceEvent ( TraceEventType . Information , 0 , "Set headers" ) ;
151+ if ( groupsToSend == null )
152+ {
153+ groupsToSend = new string [ 0 ] ;
154+ }
147155
148- string loginToSend = ApplyUserSettings ( userInformation . login ) ;
149- string [ ] groupsToSend = userInformation . groups . Where ( group => ! string . IsNullOrWhiteSpace ( group ) )
150- . Select ( ApplyGroupSettings )
151- . ToArray ( ) ;
156+ traceSource . TraceEvent ( TraceEventType . Information , 0 , "Set headers" ) ;
152157
153158 context . RemoveRequestHeader ( "Authorization" ) ; // Remove the authorzation header since we are in charge of authentication
154159 context . AddRequestHeader ( this . settings . LoginHeader , loginToSend ) ;
155- context . AddRequestHeader ( this . settings . NameHeader , userInformation . name ) ;
156- context . AddRequestHeader ( this . settings . EmailHeader , userInformation . email ) ;
160+ context . AddRequestHeader ( this . settings . NameHeader , name ) ;
161+ context . AddRequestHeader ( this . settings . EmailHeader , email ) ;
157162 context . AddRequestHeader ( this . settings . GroupsHeader , string . Join ( "," , groupsToSend ) ) ;
158163 }
159164
165+ private ( string login , string name , string email , string [ ] groups ) GetUserInformation ( string userName )
166+ {
167+ if ( this . cache . TryGetValue ( userName , out var cachedValues ) )
168+ {
169+ traceSource . TraceEvent ( TraceEventType . Information , 0 , "Returning cached data." ) ;
170+ return cachedValues ;
171+ }
172+
173+ var userInformation = this . adInteraction . GetUserInformation ( userName ) ;
174+ if ( string . IsNullOrWhiteSpace ( userInformation . login ) )
175+ {
176+ traceSource . TraceEvent ( TraceEventType . Information , 0 , "No user information in context" ) ;
177+ return ( null , null , null , null ) ;
178+ }
179+
180+ traceSource . TraceEvent ( TraceEventType . Information , 0 , "Bulding header results and caching" ) ;
181+
182+ string loginToSend = ApplyUserSettings ( userInformation . login ) ;
183+ string [ ] groupsToSend = userInformation . groups . Where ( group => ! string . IsNullOrWhiteSpace ( group ) )
184+ . Select ( ApplyGroupSettings )
185+ . ToArray ( ) ;
186+
187+ this . cache . TryAdd ( userName , ( loginToSend , userInformation . name , userInformation . email , groupsToSend ) ) ;
188+
189+ return ( loginToSend , userInformation . name , userInformation . email , groupsToSend ) ;
190+ }
191+
160192 /// <summary>
161193 /// Returns a copy of the <paramref name="group"/> object adjusted as necessary based on
162194 /// the settings (DowncaseGroups and AppendString).
@@ -181,19 +213,11 @@ private void HandleAuthorizeRequestInternal(IRutaHttpContext context)
181213 /// </summary>
182214 /// <param name="source">A <see cref="String"/> on which the action should be performed.</param>
183215 /// <returns>The modified version of <paramref name="source"/>.</returns>
184- private string AppendIfNeeded ( string source )
185- {
186- if ( string . IsNullOrWhiteSpace ( this . settings . AppendString ) )
187- {
188- return source ;
189- }
190-
191- return $ "{ source } { this . settings . AppendString } ";
192- }
216+ private string AppendIfNeeded ( string source ) => string . IsNullOrWhiteSpace ( this . settings . AppendString ) ? source : $ "{ source } { this . settings . AppendString } ";
193217
194218 /// <summary>
195219 /// Returns a copy of the <paramref name="source"/> object converted to lowercase
196- /// using the casing rules of the invariant culture if indicated by <paramref name="applyDowncase "/>.
220+ /// using the casing rules of the invariant culture if indicated by <paramref name="applyLowercase "/>.
197221 /// In all other cases <paramref name="source"/> will be returned.
198222 /// </summary>
199223 /// <param name="source">A <see cref="String"/> on which the action should be performed.</param>
0 commit comments