Browse Source

Added background jobs for identity user changes

pull/180/head
Galip Tolga Erdem 3 years ago
parent
commit
37c6f2460d
  1. 60
      services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/IdentityUserDeletionJob.cs
  2. 9
      services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/KeycloakClientOptions.cs
  3. 70
      services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/KeycloakUserCreationJob.cs
  4. 70
      services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/KeycloakUserUpdatingJob.cs
  5. 71
      services/identity/src/EShopOnAbp.IdentityService.Application/EShopIdentityUserAppService.cs
  6. 2
      services/identity/src/EShopOnAbp.IdentityService.Application/EShopOnAbp.IdentityService.Application.csproj
  7. 22
      services/identity/src/EShopOnAbp.IdentityService.Application/IdentityServiceApplicationModule.cs
  8. 6
      services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json

60
services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/IdentityUserDeletionJob.cs

@ -0,0 +1,60 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Keycloak.Net;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
namespace EShopOnAbp.IdentityService.BackgroundJobs;
public class IdentityUserDeletionJob : AsyncBackgroundJob<IdentityUserDeletionArgs>, ITransientDependency
{
private readonly KeycloakClient _keycloakClient;
private readonly KeycloakClientOptions _keycloakOptions;
private readonly ILogger<KeycloakUserCreationJob> _logger;
public IdentityUserDeletionJob(IOptions<KeycloakClientOptions> keycloakOptions,
ILogger<KeycloakUserCreationJob> logger)
{
_logger = logger;
_keycloakOptions = keycloakOptions.Value;
_keycloakClient = new KeycloakClient(
_keycloakOptions.Url,
_keycloakOptions.AdminUserName,
_keycloakOptions.AdminPassword
);
}
public override async Task ExecuteAsync(IdentityUserDeletionArgs args)
{
try
{
var keycloakUser = (await _keycloakClient.GetUsersAsync(_keycloakOptions.RealmName, username: args.UserName))
.First();
if (keycloakUser == null)
{
_logger.LogError($"Keycloak user could not be found to delete! Username:{args.UserName}");
throw new UserFriendlyException($"Keycloak user with the username:{args.UserName} could not be found!");
}
var result = await _keycloakClient.DeleteUserAsync(_keycloakOptions.RealmName, keycloakUser.Id);
if (result)
{
_logger.LogInformation($"Keycloak user with the username:{args.UserName} has been deleted.");
}
}
catch (Exception e)
{
_logger.LogError($"Keycloak user deletion failed! Username:{args.UserName}");
}
}
}
public class IdentityUserDeletionArgs
{
public string UserName { get; set; }
}

9
services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/KeycloakClientOptions.cs

@ -0,0 +1,9 @@
namespace EShopOnAbp.IdentityService.BackgroundJobs;
public class KeycloakClientOptions
{
public string Url { get; set; }
public string AdminUserName { get; set; }
public string AdminPassword { get; set; }
public string RealmName { get; set; }
}

70
services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/KeycloakUserCreationJob.cs

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Keycloak.Net;
using Keycloak.Net.Models.Users;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
namespace EShopOnAbp.IdentityService.BackgroundJobs;
public class KeycloakUserCreationJob : AsyncBackgroundJob<IdentityUserCreationArgs>, ITransientDependency
{
private readonly KeycloakClient _keycloakClient;
private readonly KeycloakClientOptions _keycloakOptions;
private readonly ILogger<KeycloakUserCreationJob> _logger;
public KeycloakUserCreationJob(IOptions<KeycloakClientOptions> keycloakOptions,
ILogger<KeycloakUserCreationJob> logger)
{
_logger = logger;
_keycloakOptions = keycloakOptions.Value;
_keycloakClient = new KeycloakClient(
_keycloakOptions.Url,
_keycloakOptions.AdminUserName,
_keycloakOptions.AdminPassword
);
}
public override async Task ExecuteAsync(IdentityUserCreationArgs args)
{
var keycloakUser = new User
{
Email = args.Email,
UserName = args.UserName,
FirstName = args.Name,
LastName = args.Surname,
Enabled = true,
Credentials = new List<Credentials>()
{
new() { Type = "password", Value = args.Password }
}
};
try
{
var result = await _keycloakClient.CreateUserAsync(_keycloakOptions.RealmName, keycloakUser);
if (result)
{
_logger.LogInformation($"Keycloak user with the username:{args.UserName} has been created.");
}
}
catch (Exception e)
{
_logger.LogError($"Keycloak user creation with the Username:{args.UserName} has been failed!");
throw;
}
}
}
public class IdentityUserCreationArgs
{
public string Email { get; set; }
public string UserName { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Password { get; set; }
}

70
services/identity/src/EShopOnAbp.IdentityService.Application/BackgroundJobs/KeycloakUserUpdatingJob.cs

@ -0,0 +1,70 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Keycloak.Net;
using Keycloak.Net.Models.Users;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
namespace EShopOnAbp.IdentityService.BackgroundJobs;
public class KeycloakUserUpdatingJob : AsyncBackgroundJob<IdentityUserUpdatingArgs>, ITransientDependency
{
private readonly KeycloakClient _keycloakClient;
private readonly KeycloakClientOptions _keycloakOptions;
private readonly ILogger<KeycloakUserCreationJob> _logger;
public KeycloakUserUpdatingJob(IOptions<KeycloakClientOptions> keycloakOptions, ILogger<KeycloakUserCreationJob> logger)
{
_logger = logger;
_keycloakOptions = keycloakOptions.Value;
_keycloakClient = new KeycloakClient(
_keycloakOptions.Url,
_keycloakOptions.AdminUserName,
_keycloakOptions.AdminPassword
);
}
public override async Task ExecuteAsync(IdentityUserUpdatingArgs args)
{
try
{
var keycloakUser = (await _keycloakClient.GetUsersAsync(_keycloakOptions.RealmName, username: args.UserName))
.First();
if (keycloakUser == null)
{
_logger.LogError($"Keycloak user could not be found to update! Username:{args.UserName}");
throw new UserFriendlyException($"Keycloak user with the username:{args.UserName} could not be found!");
}
keycloakUser.UserName = args.UserName;
keycloakUser.Email = args.Email;
keycloakUser.FirstName = args.Name;
keycloakUser.LastName = args.Surname;
keycloakUser.EmailVerified = args.EmailConfirmed;
var result = await _keycloakClient.UpdateUserAsync(_keycloakOptions.RealmName, keycloakUser.Id, keycloakUser);
if (result)
{
_logger.LogInformation($"Keycloak user with the username:{args.UserName} has been updated.");
}
}
catch (Exception e)
{
_logger.LogError($"Keycloak user updating failed! Username:{args.UserName}");
}
}
}
public class IdentityUserUpdatingArgs
{
public string Email { get; set; }
public string UserName { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public bool EmailConfirmed { get; set; }
}

71
services/identity/src/EShopOnAbp.IdentityService.Application/EShopIdentityUserAppService.cs

@ -0,0 +1,71 @@
using System;
using System.Threading.Tasks;
using EShopOnAbp.IdentityService.BackgroundJobs;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace EShopOnAbp.IdentityService;
[ExposeServices(typeof(IdentityUserAppService), typeof(IIdentityUserAppService))]
public class EShopIdentityUserAppService : IdentityUserAppService
{
private readonly IBackgroundJobManager _backgroundJobManager;
private readonly IIdentityUserRepository _userRepository;
public EShopIdentityUserAppService(
IdentityUserManager userManager,
IIdentityUserRepository userRepository,
IIdentityRoleRepository roleRepository,
IOptions<IdentityOptions> identityOptions, IBackgroundJobManager backgroundJobManager) : base(userManager,
userRepository,
roleRepository,
identityOptions)
{
_backgroundJobManager = backgroundJobManager;
_userRepository = userRepository;
}
public override async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
{
var createdUser = await base.CreateAsync(input);
await _backgroundJobManager.EnqueueAsync(new IdentityUserCreationArgs
{
Email = createdUser.Email,
UserName = createdUser.UserName,
Name = createdUser.Name,
Surname = createdUser.Surname,
Password = input.Password
});
return createdUser;
}
public override async Task<IdentityUserDto> UpdateAsync(Guid id, IdentityUserUpdateDto input)
{
var updatedUser = await base.UpdateAsync(id, input);
await _backgroundJobManager.EnqueueAsync(new IdentityUserUpdatingArgs
{
Email = updatedUser.Email,
UserName = updatedUser.UserName,
Name = updatedUser.Name,
Surname = updatedUser.Surname,
EmailConfirmed = updatedUser.EmailConfirmed
});
return updatedUser;
}
public override async Task DeleteAsync(Guid id)
{
var user = await _userRepository.FindAsync(id);
await base.DeleteAsync(id);
await _backgroundJobManager.EnqueueAsync(new IdentityUserDeletionArgs
{
UserName = user.UserName
});
}
}

2
services/identity/src/EShopOnAbp.IdentityService.Application/EShopOnAbp.IdentityService.Application.csproj

@ -11,7 +11,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Identity.Application" Version="7.0.0" />
<PackageReference Include="Keycloak.Net.Core" Version="1.0.20" />
</ItemGroup>
</Project>

22
services/identity/src/EShopOnAbp.IdentityService.Application/IdentityServiceApplicationModule.cs

@ -1,5 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using EShopOnAbp.IdentityService.BackgroundJobs;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;
@ -8,17 +10,29 @@ namespace EShopOnAbp.IdentityService
[DependsOn(
typeof(IdentityServiceDomainModule),
typeof(IdentityServiceApplicationContractsModule),
typeof(AbpIdentityApplicationModule)
)]
typeof(AbpIdentityApplicationModule),
typeof(AbpBackgroundJobsModule)
)]
public class IdentityServiceApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.Services.AddAutoMapperObjectMapper<IdentityServiceApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<IdentityServiceApplicationModule>(validate: true);
});
Configure<KeycloakClientOptions>(options =>
{
options.Url = configuration["Keycloak:url"];
options.AdminUserName = configuration["Keycloak:adminUsername"];
options.AdminPassword = configuration["Keycloak:adminPassword"];
options.RealmName = configuration["Keycloak:realmName"];
}
);
}
}
}
}

6
services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/appsettings.json

@ -9,6 +9,12 @@
"SwaggerClientId": "WebGateway_Swagger",
"SwaggerClientSecret": "1q2w3e*"
},
"Keycloak": {
"url": "http://localhost:8080",
"adminUsername": "admin",
"adminPassword": "1q2w3E*",
"realmName": "master"
},
"Logging": {
"LogLevel": {
"Default": "Information",

Loading…
Cancel
Save