@@ -134,12 +134,40 @@ public List<IdentityMapData> GetUsersInSourceMappedToTarget(TfsProcessor process
134134 var sourceUsers = GetUsersListFromServer ( processor . Source . GetService < IGroupSecurityService > ( ) ) ;
135135 Log . LogInformation ( $ "TfsUserMappingTool::GetUsersInSourceMappedToTarget Loading identities from target server") ;
136136 var targetUsers = GetUsersListFromServer ( processor . Target . GetService < IGroupSecurityService > ( ) ) ;
137- return sourceUsers . Select ( sUser => new IdentityMapData { Source = sUser , Target = targetUsers . SingleOrDefault ( tUser => tUser . FriendlyName == sUser . FriendlyName ) } ) . ToList ( ) ;
137+
138+ if ( Options . MatchUsersByEmail )
139+ {
140+ Log . LogInformation ( "TfsUserMappingTool::GetUsersInSourceMappedToTarget "
141+ + "Matching users between source and target by email is enabled. In no match by email is found, "
142+ + "matching by display name will be used." ) ;
143+ }
144+
145+ List < IdentityMapData > identityMap = [ ] ;
146+ foreach ( var sourceUser in sourceUsers )
147+ {
148+ IdentityItemData targetUser = null ;
149+ if ( Options . MatchUsersByEmail && ! string . IsNullOrEmpty ( sourceUser . MailAddress ) )
150+ {
151+ var candidates = targetUsers
152+ . Where ( tu => tu . MailAddress . Equals ( sourceUser . MailAddress , StringComparison . OrdinalIgnoreCase ) )
153+ . ToList ( ) ;
154+ if ( candidates . Count == 1 )
155+ {
156+ // If there are more than one user with the same email address, we can't be sure which one is
157+ // the correct one, so mapping will match either by display name, or will be skipped and
158+ // exported for manual mapping.
159+ targetUser = candidates [ 0 ] ;
160+ }
161+ }
162+ targetUser ??= targetUsers . SingleOrDefault ( x => x . DisplayName == sourceUser . DisplayName ) ;
163+ identityMap . Add ( new IdentityMapData { Source = sourceUser , Target = targetUser } ) ;
164+ }
165+ return identityMap ;
138166 }
139167 else
140168 {
141169 Log . LogWarning ( "TfsUserMappingTool is disabled in settings. You may have users in the source that are not mapped to the target. " ) ;
142- return null ;
170+ return [ ] ;
143171 }
144172 }
145173
0 commit comments