11// Copyright (c) SimpleIdServer. All rights reserved.
22// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
33using Duende . IdentityServer . EntityFramework . DbContexts ;
4- using Microsoft . AspNetCore . Identity ;
54using Microsoft . EntityFrameworkCore ;
65using Microsoft . IdentityModel . Tokens ;
76using SimpleIdServer . IdServer . Api . Authorization . ResponseTypes ;
109using SimpleIdServer . IdServer . Config ;
1110using SimpleIdServer . IdServer . Domains ;
1211using SimpleIdServer . IdServer . Stores ;
13- using System . IdentityModel . Tokens . Jwt ;
1412using DPoPTokenExpirationValidationMode = Duende . IdentityServer . Models . DPoPTokenExpirationValidationMode ;
1513using DuendeAccessTokenType = Duende . IdentityServer . Models . AccessTokenType ;
1614using DuendeApiResource = Duende . IdentityServer . EntityFramework . Entities . ApiResource ;
1917using DuendeIdentityResource = Duende . IdentityServer . EntityFramework . Entities . IdentityResource ;
2018namespace SimpleIdServer . IdServer . Migrations . Duende ;
2119
22- public class DuendeMigrationService : IMigrationService
20+ public class DuendeMigrationService : BaseMicrosoftIdentityMigrationService
2321{
24- public string Name => Constants . Name ;
2522 private readonly ConfigurationDbContext _configurationDbcontext ;
26- private readonly ApplicationDbContext _applicationDbcontext ;
2723 private readonly IScopeRepository _scopeRepository ;
2824
2925 public DuendeMigrationService (
3026 ConfigurationDbContext configurationDbcontext ,
3127 ApplicationDbContext applicationDbcontext ,
32- IScopeRepository scopeRepository )
28+ IScopeRepository scopeRepository ) : base ( applicationDbcontext )
3329 {
3430 _configurationDbcontext = configurationDbcontext ;
35- _applicationDbcontext = applicationDbcontext ;
3631 _scopeRepository = scopeRepository ;
3732 }
3833
39- public Task < int > NbApiScopes ( CancellationToken cancellationToken )
34+ public override string Name => Constants . Name ;
35+
36+ public override Task < int > NbApiScopes ( CancellationToken cancellationToken )
4037 {
4138 return _configurationDbcontext . ApiScopes . CountAsync ( cancellationToken ) ;
4239 }
4340
44- public async Task < List < Scope > > ExtractApiScopes ( ExtractParameter parameter , CancellationToken cancellationToken )
41+ public override async Task < List < Scope > > ExtractApiScopes ( ExtractParameter parameter , CancellationToken cancellationToken )
4542 {
4643 var scopes = await _configurationDbcontext . ApiScopes
4744 . Include ( c => c . UserClaims )
@@ -51,12 +48,12 @@ public async Task<List<Scope>> ExtractApiScopes(ExtractParameter parameter, Canc
5148 return scopes . Select ( Map ) . ToList ( ) ;
5249 }
5350
54- public Task < int > NbIdentityScopes ( CancellationToken cancellationToken )
51+ public override Task < int > NbIdentityScopes ( CancellationToken cancellationToken )
5552 {
5653 return _configurationDbcontext . IdentityResources . CountAsync ( cancellationToken ) ;
5754 }
5855
59- public async Task < List < Scope > > ExtractIdentityScopes ( ExtractParameter parameter , CancellationToken cancellationToken )
56+ public override async Task < List < Scope > > ExtractIdentityScopes ( ExtractParameter parameter , CancellationToken cancellationToken )
6057 {
6158 var scopes = await _configurationDbcontext . IdentityResources
6259 . Include ( c => c . UserClaims )
@@ -66,12 +63,12 @@ public async Task<List<Scope>> ExtractIdentityScopes(ExtractParameter parameter,
6663 return scopes . Select ( Map ) . ToList ( ) ;
6764 }
6865
69- public Task < int > NbApiResources ( CancellationToken cancellationToken )
66+ public override Task < int > NbApiResources ( CancellationToken cancellationToken )
7067 {
7168 return _configurationDbcontext . ApiResources . CountAsync ( cancellationToken ) ;
7269 }
7370
74- public async Task < List < ApiResource > > ExtractApiResources ( ExtractParameter parameter , CancellationToken cancellationToken )
71+ public override async Task < List < ApiResource > > ExtractApiResources ( ExtractParameter parameter , CancellationToken cancellationToken )
7572 {
7673 var apiResources = await _configurationDbcontext . ApiResources
7774 . Include ( c => c . UserClaims )
@@ -88,12 +85,12 @@ public async Task<List<ApiResource>> ExtractApiResources(ExtractParameter parame
8885 } ) . ToList ( ) ;
8986 }
9087
91- public Task < int > NbClients ( CancellationToken cancellationToken )
88+ public override Task < int > NbClients ( CancellationToken cancellationToken )
9289 {
9390 return _configurationDbcontext . Clients . CountAsync ( cancellationToken ) ;
9491 }
9592
96- public async Task < List < Client > > ExtractClients ( ExtractParameter parameter , CancellationToken cancellationToken )
93+ public override async Task < List < Client > > ExtractClients ( ExtractParameter parameter , CancellationToken cancellationToken )
9794 {
9895 var clients = await _configurationDbcontext . Clients
9996 . Include ( c => c . RedirectUris )
@@ -105,49 +102,16 @@ public async Task<List<Client>> ExtractClients(ExtractParameter parameter, Cance
105102 . AsNoTracking ( )
106103 . ToListAsync ( ) ;
107104 var allScopeNames = clients . SelectMany ( c => c . AllowedScopes . Select ( s => s . Scope ) ) . Distinct ( ) . ToList ( ) ;
105+ allScopeNames . Add ( DefaultScopes . OpenIdScope . Name ) ;
108106 var allScopes = await _scopeRepository . GetByNames ( allScopeNames , cancellationToken ) ;
109107 return clients . Select ( c =>
110108 {
111- var filteredScopes = allScopes . Where ( s => c . AllowedScopes . All ( cs => cs . Scope == s . Name ) ) . ToList ( ) ;
109+ var clientType = ResolveClientType ( c ) ;
110+ var filteredScopes = allScopes . Where ( s => c . AllowedScopes . All ( cs => cs . Scope == s . Name ) || ( s . Name == DefaultScopes . OpenIdScope . Name && clientType != ClientTypes . MACHINE ) ) . ToList ( ) ;
112111 return Map ( c , filteredScopes ) ;
113112 } ) . ToList ( ) ;
114113 }
115114
116- public Task < int > NbGroups ( CancellationToken cancellationToken )
117- {
118- return _applicationDbcontext . Roles . CountAsync ( cancellationToken ) ;
119- }
120-
121- public async Task < List < Group > > ExtractGroups ( ExtractParameter parameter , CancellationToken cancellationToken )
122- {
123- var allGroups = await _applicationDbcontext . Roles . Skip ( parameter . StartIndex ) . Take ( parameter . Count ) . ToListAsync ( cancellationToken ) ;
124- return allGroups . Select ( Map ) . ToList ( ) ;
125- }
126-
127- public Task < int > NbUsers ( CancellationToken cancellationToken )
128- {
129- return _applicationDbcontext . Users . CountAsync ( cancellationToken ) ;
130- }
131-
132- public async Task < List < User > > ExtractUsers ( ExtractParameter parameter , CancellationToken cancellationToken )
133- {
134- var users = await _applicationDbcontext . Users . Skip ( parameter . StartIndex ) . Take ( parameter . Count ) . ToListAsync ( cancellationToken ) ;
135- var allUserIds = users . Select ( u => u . Id ) . ToList ( ) ;
136- var allUserClaims = await _applicationDbcontext . UserClaims . Where ( c => allUserIds . Contains ( c . UserId ) ) . ToListAsync ( cancellationToken ) ;
137- var allUserRoles = await _applicationDbcontext . UserRoles . Where ( c => allUserIds . Contains ( c . UserId ) ) . ToListAsync ( cancellationToken ) ;
138- var allUserRoleIds = allUserRoles . Select ( ur => ur . RoleId ) . Distinct ( ) . ToList ( ) ;
139- var extractedUsers = new List < User > ( ) ;
140- foreach ( var user in users )
141- {
142- var userClaims = allUserClaims . Where ( c => c . UserId == user . Id ) . Select ( Map ) . ToList ( ) ;
143- var userRoles = allUserRoles . Where ( ur => ur . UserId == user . Id ) . Select ( ur => ur . RoleId ) . ToList ( ) ;
144- var extractedUser = Map ( user , userClaims , userRoles ) ;
145- extractedUsers . Add ( extractedUser ) ;
146- }
147-
148- return extractedUsers ;
149- }
150-
151115 private static Scope Map ( DuendeApiScope scope )
152116 {
153117 var lst = DefaultClaimMappers . All ;
@@ -274,29 +238,6 @@ private static Client Map(DuendeClient client, List<Scope> scopes)
274238 result . UpdateClientName ( client . ClientName , IdServer . Constants . DefaultLanguage ) ;
275239 result . UpdateClientUri ( client . ClientUri , IdServer . Constants . DefaultLanguage ) ;
276240 result . UpdateLogoUri ( client . LogoUri , IdServer . Constants . DefaultLanguage ) ;
277- /*
278- AllowPlainTextPkce
279- EnableLocalLogin
280- RequireRequestObject
281- AllowedIdentityTokenSigningAlgorithms
282- AccessTokenLifetime
283- AllowOfflineAccess
284- AllowAccessTokensViaBrowser
285- Enabled
286- ProtocolType
287- RequireClientSecret
288- Description
289- AllowRememberConsent
290- AlwaysIncludeUserClaimsInIdToken
291- IdentityProviderRestrictions
292- IncludeJwtId
293- Claims
294- AlwaysSendClientClaims
295- ClientClaimsPrefix
296- ClientCorsOrigin
297- ClientProperty
298- UserCodeType
299- */
300241 return result ;
301242 }
302243
@@ -367,88 +308,6 @@ private static List<ClientSecret> ResolveClientSecrets(DuendeClient client)
367308 } ) . ToList ( ) ;
368309 }
369310
370- private static UserClaim Map ( IdentityUserClaim < string > userClaim )
371- {
372- return new UserClaim
373- {
374- Id = Guid . NewGuid ( ) . ToString ( ) ,
375- Name = userClaim . ClaimType ,
376- Value = userClaim . ClaimValue ,
377- UserId = userClaim . UserId
378- } ;
379- }
380-
381- private static Group Map ( IdentityRole identityRole )
382- {
383- return new Group
384- {
385- Id = identityRole . Id ,
386- Name = identityRole . Name ,
387- Source = Constants . Name ,
388- FullPath = identityRole . Name ,
389- Description = identityRole . NormalizedName ,
390- CreateDateTime = DateTime . UtcNow ,
391- UpdateDateTime = DateTime . UtcNow
392- } ;
393- }
394-
395- private static User Map ( ApplicationUser applicationUser , List < UserClaim > userClaims , List < string > groupIds )
396- {
397- var result = new User
398- {
399- Id = applicationUser . Id ,
400- Source = Constants . Name ,
401- Name = applicationUser . UserName ,
402- Email = applicationUser . Email ,
403- UnblockDateTime = applicationUser . LockoutEnd == null ? null : applicationUser . LockoutEnd . Value . UtcDateTime ,
404- NbLoginAttempt = applicationUser . AccessFailedCount ,
405- EmailVerified = applicationUser . EmailConfirmed ,
406- Credentials = new List < UserCredential >
407- {
408- new UserCredential
409- {
410- Id = Guid . NewGuid ( ) . ToString ( ) ,
411- Value = applicationUser . PasswordHash ,
412- CredentialType = UserCredential . PWD ,
413- IsActive = true ,
414- HashAlg = PasswordHashAlgs . Microsoft
415- }
416- } ,
417- CreateDateTime = DateTime . UtcNow ,
418- UpdateDateTime = DateTime . UtcNow
419- } ;
420- result . Status = result . IsBlocked ( ) ? UserStatus . BLOCKED : UserStatus . ACTIVATED ;
421- var claims = new List < UserClaim > ( ) ;
422- var filteredClaims = userClaims . Where ( c => c . UserId == applicationUser . Id ) ;
423- claims . AddRange ( filteredClaims ) ;
424- if ( ! string . IsNullOrWhiteSpace ( applicationUser . PhoneNumber ) && ! claims . Any ( c => c . Type == JwtRegisteredClaimNames . PhoneNumber ) )
425- {
426- claims . Add ( new UserClaim
427- {
428- Id = Guid . NewGuid ( ) . ToString ( ) ,
429- Name = JwtRegisteredClaimNames . PhoneNumber ,
430- Value = applicationUser . PhoneNumber
431- } ) ;
432- }
433-
434- if ( ! claims . Any ( c => c . Type == JwtRegisteredClaimNames . PhoneNumberVerified ) )
435- {
436- claims . Add ( new UserClaim
437- {
438- Id = Guid . NewGuid ( ) . ToString ( ) ,
439- Name = JwtRegisteredClaimNames . PhoneNumberVerified ,
440- Value = applicationUser . PhoneNumberConfirmed . ToString ( ) . ToLowerInvariant ( )
441- } ) ;
442- }
443-
444- result . OAuthUserClaims = claims ;
445- result . Groups = groupIds . Select ( groupId => new GroupUser
446- {
447- GroupsId = groupId
448- } ) . ToList ( ) ;
449- return result ;
450- }
451-
452311 private static ClientTypes ResolveClientType ( DuendeClient client )
453312 {
454313 var grantTypes = client . AllowedGrantTypes . Select ( g => g . GrantType ) . ToList ( ) ;
0 commit comments