add a UserManager to simplify user creation, improve response validation in ServiceBase, allow Section component to support parameter changes
This commit is contained in:
parent
df0f562817
commit
c0f4cd2097
|
@ -40,19 +40,10 @@
|
|||
[Parameter]
|
||||
public string Expanded { get; set; } // optional - will default to false if not provided
|
||||
|
||||
protected override void OnInitialized()
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
_heading = (!string.IsNullOrEmpty(Heading)) ? Heading : Name;
|
||||
_heading = !string.IsNullOrEmpty(Heading) ? Localize(nameof(Heading), Heading) : Localize(nameof(Name), Name);
|
||||
_expanded = (!string.IsNullOrEmpty(Expanded)) ? Expanded.ToLower() : "false";
|
||||
if (_expanded == "true") { _show = "show"; }
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
base.OnParametersSet();
|
||||
|
||||
_heading = !string.IsNullOrEmpty(Heading)
|
||||
? Localize(nameof(Heading), Heading)
|
||||
: Localize(nameof(Name), Name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Models;
|
||||
|
@ -105,7 +106,7 @@ namespace Oqtane.Services
|
|||
protected async Task GetAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().GetAsync(uri);
|
||||
CheckResponse(response);
|
||||
CheckResponse(response, uri);
|
||||
}
|
||||
|
||||
protected async Task<string> GetStringAsync(string uri)
|
||||
|
@ -139,7 +140,7 @@ namespace Oqtane.Services
|
|||
protected async Task<T> GetJsonAsync<T>(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
if (CheckResponse(response, uri) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
return await response.Content.ReadFromJsonAsync<T>();
|
||||
}
|
||||
|
@ -150,7 +151,7 @@ namespace Oqtane.Services
|
|||
protected async Task PutAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().PutAsync(uri, null);
|
||||
CheckResponse(response);
|
||||
CheckResponse(response, uri);
|
||||
}
|
||||
|
||||
protected async Task<T> PutJsonAsync<T>(string uri, T value)
|
||||
|
@ -161,7 +162,7 @@ namespace Oqtane.Services
|
|||
protected async Task<TResult> PutJsonAsync<TValue, TResult>(string uri, TValue value)
|
||||
{
|
||||
var response = await GetHttpClient().PutAsJsonAsync(uri, value);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
if (CheckResponse(response, uri) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
var result = await response.Content.ReadFromJsonAsync<TResult>();
|
||||
return result;
|
||||
|
@ -172,7 +173,7 @@ namespace Oqtane.Services
|
|||
protected async Task PostAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().PostAsync(uri, null);
|
||||
CheckResponse(response);
|
||||
CheckResponse(response, uri);
|
||||
}
|
||||
|
||||
protected async Task<T> PostJsonAsync<T>(string uri, T value)
|
||||
|
@ -183,7 +184,7 @@ namespace Oqtane.Services
|
|||
protected async Task<TResult> PostJsonAsync<TValue, TResult>(string uri, TValue value)
|
||||
{
|
||||
var response = await GetHttpClient().PostAsJsonAsync(uri, value);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
if (CheckResponse(response, uri) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
var result = await response.Content.ReadFromJsonAsync<TResult>();
|
||||
return result;
|
||||
|
@ -195,11 +196,16 @@ namespace Oqtane.Services
|
|||
protected async Task DeleteAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().DeleteAsync(uri);
|
||||
CheckResponse(response);
|
||||
CheckResponse(response, uri);
|
||||
}
|
||||
|
||||
private bool CheckResponse(HttpResponseMessage response)
|
||||
private bool CheckResponse(HttpResponseMessage response, string uri)
|
||||
{
|
||||
if (!response.RequestMessage.RequestUri.AbsolutePath.StartsWith("/api/"))
|
||||
{
|
||||
Console.WriteLine($"Request: {uri} Not Mapped To A Controller Method");
|
||||
return false;
|
||||
}
|
||||
if (response.IsSuccessStatusCode) return true;
|
||||
if (response.StatusCode != HttpStatusCode.NoContent && response.StatusCode != HttpStatusCode.NotFound)
|
||||
{
|
||||
|
|
|
@ -29,13 +29,14 @@ namespace Oqtane.Controllers
|
|||
private readonly ITenantManager _tenantManager;
|
||||
private readonly INotificationRepository _notifications;
|
||||
private readonly IFolderRepository _folders;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly ISiteRepository _sites;
|
||||
private readonly IUserPermissions _userPermissions;
|
||||
private readonly IJwtManager _jwtManager;
|
||||
private readonly ISyncManager _syncManager;
|
||||
private readonly ILogManager _logger;
|
||||
|
||||
public UserController(IUserRepository users, IUserRoleRepository userRoles, UserManager<IdentityUser> identityUserManager, SignInManager<IdentityUser> identitySignInManager, ITenantManager tenantManager, INotificationRepository notifications, IFolderRepository folders, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, ISyncManager syncManager, ILogManager logger)
|
||||
public UserController(IUserRepository users, IUserRoleRepository userRoles, UserManager<IdentityUser> identityUserManager, SignInManager<IdentityUser> identitySignInManager, ITenantManager tenantManager, INotificationRepository notifications, IFolderRepository folders, IUserManager userManager, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, ISyncManager syncManager, ILogManager logger)
|
||||
{
|
||||
_users = users;
|
||||
_userRoles = userRoles;
|
||||
|
@ -44,6 +45,7 @@ namespace Oqtane.Controllers
|
|||
_tenantManager = tenantManager;
|
||||
_notifications = notifications;
|
||||
_folders = folders;
|
||||
_userManager = userManager;
|
||||
_sites = sites;
|
||||
_userPermissions = userPermissions;
|
||||
_jwtManager = jwtManager;
|
||||
|
@ -141,8 +143,28 @@ namespace Oqtane.Controllers
|
|||
{
|
||||
if (ModelState.IsValid && user.SiteId == _tenantManager.GetAlias().SiteId)
|
||||
{
|
||||
var User = await CreateUser(user);
|
||||
return User;
|
||||
bool allowregistration;
|
||||
if (_userPermissions.IsAuthorized(User, user.SiteId, EntityNames.User, -1, PermissionNames.Write, RoleNames.Admin))
|
||||
{
|
||||
user.EmailConfirmed = true;
|
||||
allowregistration = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
user.EmailConfirmed = false;
|
||||
allowregistration = _sites.GetSite(user.SiteId).AllowRegistration;
|
||||
}
|
||||
|
||||
if (allowregistration)
|
||||
{
|
||||
user = await _userManager.AddUser(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(user.SiteId, LogLevel.Error, this, LogFunction.Create, "User Registration Is Not Enabled For Site. User Was Not Added {User}", user);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -153,99 +175,6 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<User> CreateUser(User user)
|
||||
{
|
||||
User newUser = null;
|
||||
|
||||
bool verified;
|
||||
bool allowregistration;
|
||||
if (_userPermissions.IsAuthorized(User, user.SiteId, EntityNames.User, -1, PermissionNames.Write, RoleNames.Admin))
|
||||
{
|
||||
verified = true;
|
||||
allowregistration = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
verified = false;
|
||||
allowregistration = _sites.GetSite(user.SiteId).AllowRegistration;
|
||||
}
|
||||
|
||||
if (allowregistration)
|
||||
{
|
||||
bool succeeded;
|
||||
string errors = "";
|
||||
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
|
||||
if (identityuser == null)
|
||||
{
|
||||
identityuser = new IdentityUser();
|
||||
identityuser.UserName = user.Username;
|
||||
identityuser.Email = user.Email;
|
||||
identityuser.EmailConfirmed = verified;
|
||||
var result = await _identityUserManager.CreateAsync(identityuser, user.Password);
|
||||
succeeded = result.Succeeded;
|
||||
if (!succeeded)
|
||||
{
|
||||
errors = string.Join(", ", result.Errors.Select(e => e.Description));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = await _identitySignInManager.CheckPasswordSignInAsync(identityuser, user.Password, false);
|
||||
succeeded = result.Succeeded;
|
||||
if (!succeeded)
|
||||
{
|
||||
errors = "Password Not Valid For User";
|
||||
}
|
||||
verified = succeeded;
|
||||
}
|
||||
|
||||
if (succeeded)
|
||||
{
|
||||
user.LastLoginOn = null;
|
||||
user.LastIPAddress = "";
|
||||
newUser = _users.AddUser(user);
|
||||
_syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, newUser.UserId, SyncEventActions.Create);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(user.SiteId, LogLevel.Error, this, LogFunction.Create, "Unable To Add User {Username} - {Errors}", user.Username, errors);
|
||||
}
|
||||
|
||||
if (newUser != null)
|
||||
{
|
||||
if (!verified)
|
||||
{
|
||||
string token = await _identityUserManager.GenerateEmailConfirmationTokenAsync(identityuser);
|
||||
string url = HttpContext.Request.Scheme + "://" + _tenantManager.GetAlias().Name + "/login?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
||||
string body = "Dear " + user.DisplayName + ",\n\nIn Order To Complete The Registration Of Your User Account Please Click The Link Displayed Below:\n\n" + url + "\n\nThank You!";
|
||||
var notification = new Notification(user.SiteId, newUser, "User Account Verification", body);
|
||||
_notifications.AddNotification(notification);
|
||||
}
|
||||
else
|
||||
{
|
||||
string url = HttpContext.Request.Scheme + "://" + _tenantManager.GetAlias().Name;
|
||||
string body = "Dear " + user.DisplayName + ",\n\nA User Account Has Been Successfully Created For You. Please Use The Following Link To Access The Site:\n\n" + url + "\n\nThank You!";
|
||||
var notification = new Notification(user.SiteId, newUser, "User Account Notification", body);
|
||||
_notifications.AddNotification(notification);
|
||||
}
|
||||
|
||||
newUser.Password = ""; // remove sensitive information
|
||||
_logger.Log(user.SiteId, LogLevel.Information, this, LogFunction.Create, "User Added {User}", newUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
user.Password = ""; // remove sensitive information
|
||||
_logger.Log(user.SiteId, LogLevel.Error, this, LogFunction.Create, "Unable To Add User {User}", user);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(user.SiteId, LogLevel.Error, this, LogFunction.Create, "User Registration Is Not Enabled For Site. User Was Not Added {User}", user);
|
||||
}
|
||||
|
||||
return newUser;
|
||||
}
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize]
|
||||
|
|
|
@ -73,13 +73,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
|
||||
internal static IServiceCollection AddOqtaneTransientServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IDBContextDependencies, DBContextDependencies>();
|
||||
services.AddTransient<ITenantManager, TenantManager>();
|
||||
services.AddTransient<IAliasAccessor, AliasAccessor>();
|
||||
services.AddTransient<IUserPermissions, UserPermissions>();
|
||||
services.AddTransient<ITenantResolver, TenantResolver>();
|
||||
services.AddTransient<IJwtManager, JwtManager>();
|
||||
|
||||
// repositories
|
||||
services.AddTransient<IModuleDefinitionRepository, ModuleDefinitionRepository>();
|
||||
services.AddTransient<IThemeRepository, ThemeRepository>();
|
||||
services.AddTransient<IAliasRepository, AliasRepository>();
|
||||
|
@ -95,7 +89,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.AddTransient<IPermissionRepository, PermissionRepository>();
|
||||
services.AddTransient<ISettingRepository, SettingRepository>();
|
||||
services.AddTransient<ILogRepository, LogRepository>();
|
||||
services.AddTransient<ILogManager, LogManager>();
|
||||
services.AddTransient<ILocalizationManager, LocalizationManager>();
|
||||
services.AddTransient<IJobRepository, JobRepository>();
|
||||
services.AddTransient<IJobLogRepository, JobLogRepository>();
|
||||
|
@ -104,11 +97,21 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.AddTransient<IFileRepository, FileRepository>();
|
||||
services.AddTransient<ISiteTemplateRepository, SiteTemplateRepository>();
|
||||
services.AddTransient<ISqlRepository, SqlRepository>();
|
||||
services.AddTransient<IUpgradeManager, UpgradeManager>();
|
||||
services.AddTransient<ILanguageRepository, LanguageRepository>();
|
||||
services.AddTransient<IVisitorRepository, VisitorRepository>();
|
||||
services.AddTransient<IUrlMappingRepository, UrlMappingRepository>();
|
||||
|
||||
// managers
|
||||
services.AddTransient<IDBContextDependencies, DBContextDependencies>();
|
||||
services.AddTransient<ITenantManager, TenantManager>();
|
||||
services.AddTransient<IAliasAccessor, AliasAccessor>();
|
||||
services.AddTransient<IUserPermissions, UserPermissions>();
|
||||
services.AddTransient<ITenantResolver, TenantResolver>();
|
||||
services.AddTransient<IJwtManager, JwtManager>();
|
||||
services.AddTransient<ILogManager, LogManager>();
|
||||
services.AddTransient<IUpgradeManager, UpgradeManager>();
|
||||
services.AddTransient<IUserManager, UserManager>();
|
||||
|
||||
// obsolete - replaced by ITenantManager
|
||||
services.AddTransient<ITenantResolver, TenantResolver>();
|
||||
|
||||
|
|
10
Oqtane.Server/Infrastructure/Interfaces/IUserManager.cs
Normal file
10
Oqtane.Server/Infrastructure/Interfaces/IUserManager.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System.Threading.Tasks;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface IUserManager
|
||||
{
|
||||
Task<User> AddUser(User user);
|
||||
}
|
||||
}
|
109
Oqtane.Server/Infrastructure/UserManager.cs
Normal file
109
Oqtane.Server/Infrastructure/UserManager.cs
Normal file
|
@ -0,0 +1,109 @@
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class UserManager : IUserManager
|
||||
{
|
||||
private readonly IUserRepository _users;
|
||||
private readonly UserManager<IdentityUser> _identityUserManager;
|
||||
private readonly SignInManager<IdentityUser> _identitySignInManager;
|
||||
private readonly ITenantManager _tenantManager;
|
||||
private readonly INotificationRepository _notifications;
|
||||
private readonly IFolderRepository _folders;
|
||||
private readonly ISyncManager _syncManager;
|
||||
private readonly ILogManager _logger;
|
||||
|
||||
public UserManager(IUserRepository users, UserManager<IdentityUser> identityUserManager, SignInManager<IdentityUser> identitySignInManager, ITenantManager tenantManager, INotificationRepository notifications, IFolderRepository folders, ISyncManager syncManager, ILogManager logger)
|
||||
{
|
||||
_users = users;
|
||||
_identityUserManager = identityUserManager;
|
||||
_identitySignInManager = identitySignInManager;
|
||||
_tenantManager = tenantManager;
|
||||
_notifications = notifications;
|
||||
_folders = folders;
|
||||
_syncManager = syncManager;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<User> AddUser(User user)
|
||||
{
|
||||
User User = null;
|
||||
var alias = _tenantManager.GetAlias();
|
||||
bool succeeded = false;
|
||||
string errors = "";
|
||||
|
||||
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
|
||||
if (identityuser == null)
|
||||
{
|
||||
identityuser = new IdentityUser();
|
||||
identityuser.UserName = user.Username;
|
||||
identityuser.Email = user.Email;
|
||||
identityuser.EmailConfirmed = user.EmailConfirmed;
|
||||
var result = await _identityUserManager.CreateAsync(identityuser, user.Password);
|
||||
succeeded = result.Succeeded;
|
||||
if (!succeeded)
|
||||
{
|
||||
errors = string.Join(", ", result.Errors.Select(e => e.Description));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = await _identitySignInManager.CheckPasswordSignInAsync(identityuser, user.Password, false);
|
||||
succeeded = result.Succeeded;
|
||||
if (!succeeded)
|
||||
{
|
||||
errors = "Password Not Valid For User";
|
||||
}
|
||||
user.EmailConfirmed = succeeded;
|
||||
}
|
||||
|
||||
if (succeeded)
|
||||
{
|
||||
user.LastLoginOn = null;
|
||||
user.LastIPAddress = "";
|
||||
User = _users.AddUser(user);
|
||||
_syncManager.AddSyncEvent(alias.TenantId, EntityNames.User, User.UserId, SyncEventActions.Create);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(user.SiteId, LogLevel.Error, this, LogFunction.Create, "Unable To Add User {Username} - {Errors}", user.Username, errors);
|
||||
}
|
||||
|
||||
if (User != null)
|
||||
{
|
||||
if (!user.EmailConfirmed)
|
||||
{
|
||||
string token = await _identityUserManager.GenerateEmailConfirmationTokenAsync(identityuser);
|
||||
string url = alias.Protocol + "://" + alias.Name + "/login?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
||||
string body = "Dear " + user.DisplayName + ",\n\nIn Order To Complete The Registration Of Your User Account Please Click The Link Displayed Below:\n\n" + url + "\n\nThank You!";
|
||||
var notification = new Notification(user.SiteId, User, "User Account Verification", body);
|
||||
_notifications.AddNotification(notification);
|
||||
}
|
||||
else
|
||||
{
|
||||
string url = alias.Protocol + "://" + alias.Name;
|
||||
string body = "Dear " + user.DisplayName + ",\n\nA User Account Has Been Successfully Created For You. Please Use The Following Link To Access The Site:\n\n" + url + "\n\nThank You!";
|
||||
var notification = new Notification(user.SiteId, User, "User Account Notification", body);
|
||||
_notifications.AddNotification(notification);
|
||||
}
|
||||
|
||||
User.Password = ""; // remove sensitive information
|
||||
_logger.Log(user.SiteId, LogLevel.Information, this, LogFunction.Create, "User Added {User}", User);
|
||||
}
|
||||
else
|
||||
{
|
||||
user.Password = ""; // remove sensitive information
|
||||
_logger.Log(user.SiteId, LogLevel.Error, this, LogFunction.Create, "Unable To Add User {User}", user);
|
||||
}
|
||||
|
||||
return User;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -99,5 +99,11 @@ namespace Oqtane.Models
|
|||
{
|
||||
get => "Users\\" + UserId.ToString() + "\\";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Information if this user's email address is confirmed (set during user creation)
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public bool EmailConfirmed { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user