2016 lines
64 KiB
C#
2016 lines
64 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xModels.Dtos;
|
|
using xIds.Extensions;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityHelper;
|
|
using xIdentityHelper.Extensions;
|
|
using xDataService.Extensions;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Retrieve Actions ...
|
|
/// <summary>
|
|
/// Retrieve User Profile
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="forceCheckRequestedUser">specify check requested user's identifier not empty
|
|
/// and throw exception if it is, default true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> GetUserProfileAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
bool forceCheckRequestedUser = true,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
if (forceCheckRequestedUser)
|
|
{
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam);
|
|
}
|
|
else
|
|
{
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
}
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
var isAdmin = false;
|
|
var isSameUser = false;
|
|
if (forceCheckRequestedUser &&
|
|
!requestedUserSelectByParam.IsNullOrEmpty())
|
|
{
|
|
//
|
|
var xRequestedUser = await ValidateUserExistsAndRetrieve(
|
|
requestedUserSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
isSameUser = xUser.Id == xRequestedUser.Id;
|
|
|
|
//
|
|
var xRequestUserRoleNames = await GetRoleNamesAsync(
|
|
userSelectByParam: requestedUserSelectByParam,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
isAdmin = xRequestUserRoleNames.Contains(XUserRole.Admin.GetStringValue());
|
|
}
|
|
|
|
//
|
|
var roleNames = await GetRoleNamesAsync(
|
|
userSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
var xFriendshipInfo =
|
|
requestedUserSelectByParam.IsNullOrEmpty()
|
|
? null
|
|
: await GetFriendshipInfo(
|
|
requestedUserSelectByParam,
|
|
userSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies
|
|
);
|
|
|
|
//
|
|
var result = xUser.ToXProfileDto(
|
|
isAdmin: isAdmin,
|
|
roles: roleNames,
|
|
isSameUser: isSameUser,
|
|
friendship: xFriendshipInfo,
|
|
profileConfig: Configuration.Policy.Profile
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Collection of User Profiles
|
|
/// </summary>
|
|
/// <param name="ids">a collection of user identifiers</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="forceCheckRequestedUser">specify check requested user's identifier not empty
|
|
/// and throw exception if it is, default true</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not, default is true</param>
|
|
/// <param name="checkIsBanned">check user is banned or not, default is true</param>
|
|
/// <returns>an collection of <see>XUserProfileDto</see> instances</returns>
|
|
public async Task<IEnumerable<XUserProfileDto>> GetUserProfilesAsync(
|
|
ICollection<string> ids,
|
|
string requestedUserSelectByParam,
|
|
bool forceCheckRequestedUser = true,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
if (forceCheckRequestedUser)
|
|
{
|
|
ValidationProvider.NotEmpty(requestedUserSelectByParam);
|
|
}
|
|
ValidationProvider.NotZeroChilds(ids);
|
|
|
|
//
|
|
var result = new List<XUserProfileDto>();
|
|
foreach (var id in ids)
|
|
{
|
|
//
|
|
var xProfile = await GetUserProfileAsync(
|
|
id,
|
|
requestedUserSelectByParam,
|
|
checkIsBanned: checkIsBanned,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
forceCheckRequestedUser: forceCheckRequestedUser
|
|
);
|
|
result.Add(xProfile);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query User Profiles
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryUsers(
|
|
string requestedUserSelectByParam,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
// Since in Resourceable Entities we have to Search on Locales
|
|
// we Must Implement Senario Custom ...
|
|
var totalEntities = GetUsersDbSet()
|
|
.ToList()
|
|
.Where(u => !u.ContainsUserSelectByParam(requestedUserSelectByParam))
|
|
.Select(u => u.Id)
|
|
.ToList();
|
|
|
|
//
|
|
var items = await GetUserProfilesAsync(
|
|
totalEntities,
|
|
requestedUserSelectByParam,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
forceCheckRequestedUser: false
|
|
);
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<XUserProfileDto>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query In Roles User Profiles
|
|
/// </summary>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="role">an string which represent user role</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <param name="forceRole">if it's true the user must has exact role, otherwise top level users also listed, default is false</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XUserProfileDto</see></returns>
|
|
public async Task<XQueryResult<XUserProfileDto>> QueryInRoleUsers(
|
|
string requestedUserSelectByParam,
|
|
string role,
|
|
XQuery query,
|
|
bool forceRole = false
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull() || role.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check Role Exists ...
|
|
var isExistsRole = await IsRoleExistsAsync(role);
|
|
if (!isExistsRole)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
#region Select Users Based on Specific Roles ...
|
|
var selectedUsers = new List<string>();
|
|
var usersEnumerator = GetUsersDbSet(query.ContainsDetail).AsAsyncEnumerable();
|
|
await
|
|
foreach (var user in usersEnumerator)
|
|
{
|
|
//
|
|
if (user.ContainsUserSelectByParam(requestedUserSelectByParam))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Set Default Value is True ...
|
|
var isInRole = false;
|
|
|
|
//
|
|
// if Force Role ...
|
|
if (forceRole)
|
|
{
|
|
isInRole = await UserManager.IsInRoleAsync(user, role);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Select User Top Role ...
|
|
var userRoles = await GetRoleNamesAsync(
|
|
checkIsBanned: false,
|
|
userSelectByParam: user.Id,
|
|
checkCanLoginPolicies: false
|
|
);
|
|
isInRole = userRoles.HasRolePermissions(role);
|
|
}
|
|
|
|
//
|
|
if (isInRole)
|
|
{
|
|
selectedUsers.Add(user.Id);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
var items = await GetUserProfilesAsync(
|
|
selectedUsers,
|
|
requestedUserSelectByParam,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
forceCheckRequestedUser: false
|
|
);
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<XUserProfileDto>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query Specified User's Profile Images
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="query">how to filter results based on <see>XQuery</see> structure</param>
|
|
/// <returns>an instance of <see>XQueryResult</see> of <see>XProfileImage</see></returns>
|
|
public async Task<XQueryResult<XProfileImage>> QueryAvatars(
|
|
string userSelectByParam,
|
|
XQuery query
|
|
)
|
|
{
|
|
//
|
|
// Validation ...
|
|
if (query.IsNull())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Normalize ...
|
|
query = query.NormalizeQuery(DataConfiguration.ToXDataServiceConfig());
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true
|
|
);
|
|
|
|
//
|
|
var items = query.ContainsDetail ?
|
|
DbContext.Avatars
|
|
.Include(pf => pf.User)
|
|
.AsEnumerable() :
|
|
DbContext.Avatars
|
|
.AsEnumerable();
|
|
items = items
|
|
.Where(pfi => pfi.UserId == xUser.Id);
|
|
|
|
//
|
|
var totalItemsCount = items.Count();
|
|
|
|
//
|
|
// Apply Filter ...
|
|
if (!query.Filter.IsNullOrEmpty())
|
|
{
|
|
//
|
|
items = items
|
|
.ApplyFilter(query.Filter);
|
|
}
|
|
int filteredItemsCount = items.Count();
|
|
|
|
//
|
|
// Count Pages ...
|
|
var totalPagesCount = query.CountPages(totalItemsCount);
|
|
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
|
|
|
//
|
|
// Apply Paging and Sorting ...
|
|
if (totalItemsCount > 0 &&
|
|
filteredItemsCount > 0)
|
|
{
|
|
//
|
|
// Apply Sorting ...
|
|
items = items
|
|
.ToList()
|
|
.ApplySorting(
|
|
query.SortBy,
|
|
query.IsAscending
|
|
);
|
|
|
|
//
|
|
// Apply Paging ...
|
|
items = items
|
|
.ToList()
|
|
.ApplyPaging(
|
|
query.Page,
|
|
query.PageSize
|
|
);
|
|
}
|
|
|
|
//
|
|
// Generate Result Object ...
|
|
// Query = query,
|
|
var result = new XQueryResult<XProfileImage>
|
|
{
|
|
Items = items,
|
|
Page = query.Page,
|
|
PageSize = query.PageSize,
|
|
TotalPages = totalPagesCount,
|
|
TotalItems = totalItemsCount,
|
|
TotalFilteredPages = filteredPagesCount,
|
|
TotalFilteredItems = filteredItemsCount
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check specific user Confirmed Email or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsConfirmedEmail(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
return xUser.EmailConfirmed;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ceck specific user Confirmed Mobile or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsConfirmedMobile(
|
|
string userSelectByParam
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
return xUser.PhoneNumberConfirmed;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Update Actions ...
|
|
/// <summary>
|
|
/// Update User Profile (FirstName/LastName/DateOfBirth) ...
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> ProfileUpdateAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
XProfileUpdateRequest model
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam);
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
var xRequestedUser = await ValidateUserExistsAndRetrieve(
|
|
requestedUserSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
await ValidateUserForDangerousAction(xUser, xRequestedUser);
|
|
|
|
//
|
|
// FirstName ...
|
|
if (!model.FirstName.IsNullOrEmpty())
|
|
{
|
|
xUser.FirstName = model.FirstName;
|
|
}
|
|
|
|
//
|
|
// Last Name ...
|
|
if (!model.LastName.IsNullOrEmpty())
|
|
{
|
|
xUser.LastName = model.LastName;
|
|
}
|
|
|
|
//
|
|
// Date of Birth ...
|
|
if (model.DateOfBirth.HasValue)
|
|
{
|
|
xUser.DateOfBirth = model.DateOfBirth.Value;
|
|
}
|
|
|
|
//
|
|
// Bio ...
|
|
xUser.Bio = model.Bio;
|
|
|
|
//
|
|
// Cover Image ...
|
|
xUser.CoverImage = model.CoverImage;
|
|
|
|
//
|
|
// Open To Search ...
|
|
xUser.OpenToSearch = model.OpenToSearch;
|
|
|
|
//
|
|
var updateResult = await UpdateUserAsync(xUser);
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, requestedUserSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update User Profile
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="requestedUserSelectByParam">requested user's identifier</param>
|
|
/// <param name="model">user update info, an instance of <see>XProfileUpdateRequest</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> FullProfileUpdateAsync(
|
|
string userSelectByParam,
|
|
string requestedUserSelectByParam,
|
|
XProfileUpdateRequest model
|
|
)
|
|
{
|
|
//
|
|
// Data Validation ...
|
|
ValidationProvider.NotEmpty(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam);
|
|
ValidationProvider.NotNull(model);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
var xRequestedUser = await ValidateUserExistsAndRetrieve(
|
|
requestedUserSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
forceAdmin: false
|
|
);
|
|
|
|
//
|
|
await ValidateUserForDangerousAction(xUser, xRequestedUser);
|
|
|
|
//
|
|
#region Fill User with Models Value ...
|
|
//
|
|
// FirstName ...
|
|
xUser.FirstName = !model.FirstName.IsNullOrEmpty() ?
|
|
model.FirstName :
|
|
xUser.FirstName;
|
|
//
|
|
// LastName ...
|
|
xUser.LastName = !model.LastName.IsNullOrEmpty() ?
|
|
model.LastName :
|
|
xUser.LastName;
|
|
|
|
//
|
|
// Email ...
|
|
xUser.Email = !model.Email.IsNullOrEmpty() ?
|
|
model.Email :
|
|
xUser.Email;
|
|
|
|
//
|
|
// EmailConfirmed ...
|
|
if (model.EmailConfirmed.HasValue)
|
|
{
|
|
xUser.EmailConfirmed = model.EmailConfirmed.Value;
|
|
}
|
|
|
|
//
|
|
// PhoneNumber ...
|
|
xUser.PhoneNumber = !model.PhoneNumber.IsNullOrEmpty() ?
|
|
model.PhoneNumber :
|
|
xUser.PhoneNumber;
|
|
|
|
//
|
|
// PhoneNumberConfirmed ,,,
|
|
if (model.PhoneNumberConfirmed.HasValue)
|
|
{
|
|
xUser.PhoneNumberConfirmed = model.PhoneNumberConfirmed.Value;
|
|
}
|
|
|
|
//
|
|
// DateOfBirth ...
|
|
if (model.DateOfBirth.HasValue)
|
|
{
|
|
xUser.DateOfBirth = model.DateOfBirth.Value;
|
|
}
|
|
|
|
//
|
|
// CreationDate ...
|
|
if (model.CreationDate.HasValue)
|
|
{
|
|
xUser.CreationDate = model.CreationDate.Value;
|
|
}
|
|
|
|
//
|
|
// LastLogin ...
|
|
if (model.LastLogin.HasValue)
|
|
{
|
|
xUser.LastLogin = model.LastLogin.Value;
|
|
}
|
|
|
|
//
|
|
// Avatar ...
|
|
xUser.Avatar = !model.Avatar.IsNullOrEmpty() ?
|
|
model.Avatar :
|
|
xUser.Avatar;
|
|
|
|
//
|
|
// Gender ...
|
|
if (model.Gender.HasValue)
|
|
{
|
|
xUser.Gender = model.Gender.Value;
|
|
}
|
|
|
|
//
|
|
// IsEnable ...
|
|
if (model.IsEnable.HasValue)
|
|
{
|
|
xUser.IsEnable = model.IsEnable.Value;
|
|
}
|
|
|
|
//
|
|
// IsBanned ...
|
|
if (model.IsBanned.HasValue)
|
|
{
|
|
xUser.IsBanned = model.IsBanned.Value;
|
|
}
|
|
|
|
//
|
|
// Bio ...
|
|
xUser.Bio = model.Bio;
|
|
|
|
//
|
|
// Cover Image ...
|
|
xUser.CoverImage = model.CoverImage;
|
|
|
|
//
|
|
// Open To Search ...
|
|
xUser.OpenToSearch = model.OpenToSearch;
|
|
#endregion
|
|
|
|
//
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Handle Roles ...
|
|
|
|
//
|
|
// Remove User from All Roles ...
|
|
if (xUser.Roles.HasChild())
|
|
{
|
|
//
|
|
var roleNames = await GetRoleNamesAsync(
|
|
xUser.Id,
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false
|
|
);
|
|
|
|
//
|
|
foreach (var role in roleNames)
|
|
{
|
|
//
|
|
var isRoleExists = await IsRoleExistsAsync(role);
|
|
if (isRoleExists)
|
|
{
|
|
//
|
|
var isInRole = await UserManager.IsInRoleAsync(xUser, role);
|
|
if (!isInRole)
|
|
{
|
|
//
|
|
var removeRoleResult = await UserManager.RemoveFromRoleAsync(xUser, role);
|
|
if (!removeRoleResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Roles and Add to Exists ...
|
|
if (model.Roles.HasChild())
|
|
{
|
|
//
|
|
// Check Exists Roles for Add ...
|
|
foreach (var role in model.Roles)
|
|
{
|
|
//
|
|
var isRoleExists = await IsRoleExistsAsync(role);
|
|
if (isRoleExists)
|
|
{
|
|
//
|
|
var isInRole = await UserManager.IsInRoleAsync(xUser, role);
|
|
if (!isInRole)
|
|
{
|
|
//
|
|
var addToRoleResult = await UserManager.AddToRoleAsync(xUser, role);
|
|
if (!addToRoleResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(
|
|
userSelectByParam,
|
|
requestedUserSelectByParam,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Request For Actions ...
|
|
/// <summary>
|
|
/// Request Mobile Confirm
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="mobileNumber">mobile number which need to confirm</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestConfirmMobile(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string mobileNumber = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
MobileNumber = mobileNumber
|
|
};
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
context.UserName = user.UserName;
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password,
|
|
false,
|
|
XException.ActionFailed.ToException());
|
|
|
|
//
|
|
ValidationProvider.MobileNumber(user.PhoneNumber);
|
|
if (!mobileNumber.IsNullOrEmpty() &&
|
|
user.PhoneNumber == mobileNumber &&
|
|
user.PhoneNumberConfirmed)
|
|
{
|
|
XException.MobileInUsed.Throw();
|
|
}
|
|
|
|
//
|
|
if (mobileNumber.IsNullOrEmpty())
|
|
{
|
|
mobileNumber = user.PhoneNumber;
|
|
}
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var request = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.RequestMobileVerificationCode,
|
|
context,
|
|
forceRenewToken: true
|
|
);
|
|
|
|
//
|
|
Logger.LogInformation($"ActionRequest: {request.ToJSON()}");
|
|
|
|
//
|
|
// Call Confirm Method of Registration ...
|
|
var result = await RequestMobileVerificationCode(
|
|
lang,
|
|
device,
|
|
request.Token,
|
|
mobileNumber,
|
|
checkMobileInUse: false);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Email Confirma
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="emailAddress">email address which need to confirm</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestConfirmEmail(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string emailAddress = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
Email = emailAddress
|
|
};
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
context.UserName = user.UserName;
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password,
|
|
false,
|
|
XException.ActionFailed.ToException());
|
|
|
|
//
|
|
ValidationProvider.EmailAddress(user.Email);
|
|
if (!emailAddress.IsNullOrEmpty() &&
|
|
user.Email == emailAddress &&
|
|
user.EmailConfirmed)
|
|
{
|
|
XException.EmailInUsed.Throw();
|
|
}
|
|
|
|
//
|
|
if (emailAddress.IsNullOrEmpty())
|
|
{
|
|
emailAddress = user.Email;
|
|
context.Email = user.Email;
|
|
}
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var request = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.RequestEmailVerificationCode,
|
|
context,
|
|
forceRenewToken: true
|
|
);
|
|
|
|
//
|
|
// Call Confirm Method of Registration ...
|
|
var result = await RequestEmailVerificationCode(
|
|
lang,
|
|
device,
|
|
request.Token,
|
|
emailAddress,
|
|
checkEmailInUse: false);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Reset Password
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> RequestResetPassword(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.AddUrl(returnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
Email = user.Email,
|
|
UserName = user.UserName
|
|
};
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleCleanUserTokens(user);
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
user.Email,
|
|
XAction.RequestResetPassword,
|
|
context
|
|
);
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetResetPasswordMessage(
|
|
lang,
|
|
user.Email,
|
|
result.Token,
|
|
returnUrl);
|
|
|
|
//
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request Registration Confrirm
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task RequestConfirmRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.AddUrl(returnUrl)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Validate user and Retrieve it ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: true,
|
|
ignoreDisabledUser: true);
|
|
|
|
//
|
|
// Prepare Request Context ...
|
|
var context = new XActionRequestContext
|
|
{
|
|
Lang = lang,
|
|
Device = device,
|
|
Email = user.Email
|
|
};
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password,
|
|
false,
|
|
XException.ActionFailed.ToException());
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
user.Email,
|
|
XAction.Finish,
|
|
context
|
|
);
|
|
|
|
//
|
|
// Prepare XMessage Instance ...
|
|
var xMessage = GetRegistrationConfirmMessage(
|
|
lang,
|
|
user.Email,
|
|
result.Token,
|
|
returnUrl);
|
|
|
|
//
|
|
// Send Message ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Password Actions ...
|
|
/// <summary>
|
|
/// Change Password
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="password">user's password</param>
|
|
/// <param name="newPassword">user's new password</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task ChangePassword(
|
|
string lang,
|
|
XDevice device,
|
|
string userSelectByParam,
|
|
string password,
|
|
string newPassword,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
userSelectByParam,
|
|
password,
|
|
newPassword,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Password Unique ...
|
|
if (password == newPassword)
|
|
{
|
|
XException.PasswordsSame.Throw();
|
|
}
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
await ValidateUserAndPassword(
|
|
userSelectByParam,
|
|
password);
|
|
|
|
//
|
|
// Check Password Policies ...
|
|
await ValidatePasswordPolicies(user, newPassword);
|
|
|
|
//
|
|
// Clean All User Tokens ...
|
|
await HandleCleanUserTokens(user);
|
|
|
|
//
|
|
// Try to Change User Password ...
|
|
var passwordResetResult = await UserManager
|
|
.ChangePasswordAsync(
|
|
user,
|
|
password,
|
|
newPassword);
|
|
|
|
//
|
|
// Check Result ...
|
|
if (!passwordResetResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetPasswordChangedMessage(
|
|
lang,
|
|
user.Email,
|
|
returnUrl,
|
|
throwException: false
|
|
);
|
|
|
|
//
|
|
// Send Message ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset User Password
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="newPassword">user's new password</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task ResetPassword(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string newPassword,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
actionToken,
|
|
newPassword,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
|
|
//
|
|
// Get User Identifier ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
|
|
//
|
|
// Validate and Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
// Check Password Policies ...
|
|
await ValidatePasswordPolicies(user, newPassword);
|
|
|
|
//
|
|
// Clean All User Tokens ...
|
|
await HandleCleanUserTokens(user);
|
|
|
|
//
|
|
// Try to Remove User Password ...
|
|
var removePasswordResult = await UserManager.RemovePasswordAsync(user);
|
|
if (!removePasswordResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// try to Add New Password ...
|
|
var passwordResetResult = await UserManager.AddPasswordAsync(user, newPassword);
|
|
if (!passwordResetResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Message ...
|
|
var xMessage = GetPasswordChangedMessage(
|
|
lang,
|
|
user.Email,
|
|
returnUrl);
|
|
|
|
//
|
|
// Send Message ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Profile Image Actions ...
|
|
/// <summary>
|
|
/// Add Profile Image to a User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="file">an specific File to upload, <see>IFormFile</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> AddAvatar(
|
|
string userSelectByParam,
|
|
IFormFile file
|
|
)
|
|
{
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
// Handle Saving File and Attach it to User ...
|
|
var saveResult = await StorageProvider.HandleProfileImageSave(file);
|
|
|
|
//
|
|
var xProfileImage = new XProfileImage
|
|
{
|
|
UserId = xUser.Id,
|
|
Name = saveResult.FileName,
|
|
Path = saveResult.FilePath,
|
|
Thumb = saveResult.Thmbnail,
|
|
ThumbPath = saveResult.ThmbnailPath,
|
|
CreationDate = DateTime.UtcNow
|
|
};
|
|
|
|
//
|
|
xUser.Avatars.Add(xProfileImage);
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
xUser.Avatar = xProfileImage.ThumbPath;
|
|
updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Collection of Profile Images to a User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="files">a collection of Files to upload, <see>IFormFileCollection</see></param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> AddAvatars(
|
|
string userSelectByParam,
|
|
IFormFileCollection files
|
|
)
|
|
{
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
foreach (var file in files)
|
|
{
|
|
//
|
|
// Handle Saving File and Attach it to User ...
|
|
var saveResult = await StorageProvider.HandleProfileImageSave(file);
|
|
|
|
//
|
|
var xProfileImage = new XProfileImage
|
|
{
|
|
UserId = xUser.Id,
|
|
Name = saveResult.FileName,
|
|
Path = saveResult.FilePath,
|
|
Thumb = saveResult.Thmbnail,
|
|
ThumbPath = saveResult.ThmbnailPath,
|
|
CreationDate = DateTime.UtcNow
|
|
};
|
|
|
|
//
|
|
xUser.Avatars.Add(xProfileImage);
|
|
}
|
|
|
|
//
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Specific Profie Image as Current Profile Image
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="id">an integer which reperesent AvatarId to set as current Avatar</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> SetAvatar(
|
|
string userSelectByParam,
|
|
int id
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
var xProfileImage = xUser.Avatars.FirstOrDefault(pf => pf.Id == id);
|
|
if (xProfileImage.IsNull())
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
xUser.Avatar = xProfileImage.ThumbPath;
|
|
var updateResult = await UpdateUserAsync(
|
|
xUser,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
if (!updateResult.Succeeded)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Collection of User's Profile Images
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="ids">a comma seperated list of avatarIds to remove</param>
|
|
/// <returns>an instance of <see>XUserProfileDto</see></returns>
|
|
public async Task<XUserProfileDto> RemoveAvatar(
|
|
string userSelectByParam,
|
|
ICollection<int> ids
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
var xUser = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false,
|
|
ignoreDisabledUser: true,
|
|
exception: XException.NotFound.ToException()
|
|
);
|
|
|
|
//
|
|
var xProfileImages = xUser.Avatars
|
|
.Where(pf => ids.Contains(pf.Id));
|
|
if (xProfileImages.HasChild())
|
|
{
|
|
//
|
|
xUser.Avatars = xUser.Avatars
|
|
.Except(xProfileImages)
|
|
.ToList();
|
|
|
|
//
|
|
// Creat a List of Physical Files to Remove ...
|
|
var xFilePathsForRemove = xProfileImages.Select(pf => pf.Thumb).ToList();
|
|
xFilePathsForRemove.AddRange(xProfileImages.Select(pf => pf.Name));
|
|
|
|
//
|
|
StorageProvider.DeleteFiles(
|
|
xFilePathsForRemove,
|
|
forceFileExists: false);
|
|
|
|
//
|
|
var isCurrentProfileImage = xProfileImages.Any(pfi => pfi.ThumbPath == xUser.Avatar);
|
|
if (isCurrentProfileImage)
|
|
{
|
|
xUser.Avatar = "";
|
|
}
|
|
|
|
//
|
|
await UpdateUserAsync(xUser);
|
|
}
|
|
|
|
//
|
|
var result = await GetUserProfileAsync(userSelectByParam, userSelectByParam);
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Confirmations ...
|
|
/// <summary>
|
|
/// Confirm Registration
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="returnUrl">redirection url</param>
|
|
/// <returns></returns>
|
|
public async Task ConfirmRegistration(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string returnUrl
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(
|
|
lang,
|
|
actionToken,
|
|
returnUrl)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
if (request.Action != XAction.Finish)
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(
|
|
request,
|
|
forceNotNull: true);
|
|
|
|
//
|
|
// Validate user and Retrieve it ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
ignoreDisabledUser: true,
|
|
checkIsBanned: true);
|
|
|
|
//
|
|
// Make User Enabled ...
|
|
var xMessage = GetRegistrationFinishedMessage(
|
|
lang,
|
|
user.Email,
|
|
returnUrl);
|
|
|
|
//
|
|
user.IsEnable = true;
|
|
user.EmailConfirmed = true;
|
|
|
|
//
|
|
await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
// Remove Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
//
|
|
// Remove All Prevoius Requests ...
|
|
await HandleRemoveExistsTokens(user.Id);
|
|
|
|
//
|
|
await RemoveVerificationCodeRequestByDevice(device);
|
|
|
|
//
|
|
// Send Mail ...
|
|
try
|
|
{
|
|
await MessageProvider.SendMailAsync(xMessage);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Mobile Number
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="verificationCode">recieved verification code</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> ConfirmMobileNumber(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string verificationCode
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(lang, actionToken, verificationCode)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
ValidationProvider.MobileNumber(request.Context.MobileNumber);
|
|
|
|
//
|
|
// Validate two Device Must Same ...
|
|
ValidateRequestAndGiveDevices(device, request.Context.Device);
|
|
|
|
//
|
|
// Check XActionRequest Action Must be Request Mobile Validation ...
|
|
if (request.Action != XAction.RequestMobileVerificationCode)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
|
|
//
|
|
// since device must Requested before,
|
|
// Retrieve XVerification instance by Verification Code from Db
|
|
// and Validate it ...
|
|
XVerificationRequest xVerificationRequest = await ValidateAndRetrieveVerificationRequest(verificationCode);
|
|
|
|
//
|
|
// Check User Added To Db or Not ...
|
|
// var isUserExists = await IsUserExistsAsync(userSelectByParam);
|
|
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
|
|
if (isAddedUser)
|
|
{
|
|
//
|
|
// Validate User Exists and Retireve User Object ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
// Update Exists User's Mobile Confirmation ...
|
|
user.PhoneNumberConfirmed = true;
|
|
|
|
//
|
|
// Save Changes to Db ...
|
|
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
|
|
|
|
//
|
|
request.Context.UserId = user.Id;
|
|
}
|
|
|
|
//
|
|
// Update Request Context MobileNumber Verification Code
|
|
// and it's Confirmation Status ...
|
|
request.Context.MobileVerificationCode = verificationCode;
|
|
request.Context.MobileVerified = true;
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.ConfirmMobileNumber,
|
|
request.Context,
|
|
forceCheckUserExists: isAddedUser
|
|
);
|
|
|
|
//
|
|
// Remove Previous Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
try
|
|
{
|
|
//
|
|
// Remove XVerificationRequest instance from Db ...
|
|
await RemoveVerificationRequest(verificationCode);
|
|
}
|
|
catch { }
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm Email Address
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="actionToken">a token which approved user action</param>
|
|
/// <param name="verificationCode">recieved verification code</param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
public async Task<XActionResponse> ConfirmEmailAddress(
|
|
string lang,
|
|
XDevice device,
|
|
string actionToken,
|
|
string verificationCode
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
await ValidationProvider
|
|
.GroupValidationBuilder()
|
|
.AddNotEmpty(lang, actionToken, verificationCode)
|
|
.AddNotNull(device)
|
|
.ValidateGroupAsync();
|
|
|
|
//
|
|
// Check Device Validation ...
|
|
await ValidateDeviceForActions(device);
|
|
|
|
//
|
|
// Get Related Token to Registration Hash and Validate it,
|
|
// then Parse XActionRequest Instance from Token ...
|
|
var request = await ValidateAndParseActionHash(actionToken);
|
|
ValidationProvider.EmailAddress(request.Context.Email);
|
|
|
|
//
|
|
// Validate two Device Must Same ...
|
|
ValidateRequestAndGiveDevices(device, request.Context.Device);
|
|
|
|
//
|
|
// Check XActionRequest Action Must be Request Mobile Validation ...
|
|
if (request.Action != XAction.RequestEmailVerificationCode)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// Extract UserSelectByParam from XActionRequest ...
|
|
var userSelectByParam = GetUserSelectByParam(request);
|
|
|
|
//
|
|
// since device must Requested before,
|
|
// Retrieve XVerification instance by Verification Code from Db
|
|
// and Validate it ...
|
|
XVerificationRequest xVerificationRequest = await ValidateAndRetrieveVerificationRequest(verificationCode);
|
|
|
|
//
|
|
// Check User Added To Db or Not ...
|
|
var isAddedUser = !request.Context.UserId.IsNullOrEmpty();
|
|
if (isAddedUser)
|
|
{
|
|
//
|
|
// Validate User Exists and Retireve User Object ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false);
|
|
|
|
//
|
|
// Update Exists User's Email Confirmation ...
|
|
user.EmailConfirmed = true;
|
|
|
|
//
|
|
// Save Changes to Db ...
|
|
await UpdateUserAsync(user, checkCanLoginPolicies: false, checkIsBanned: false);
|
|
|
|
//
|
|
request.Context.UserId = user.Id;
|
|
}
|
|
|
|
//
|
|
// Update Request Context Email Address Verification Code
|
|
// and it's Confirmation Status ...
|
|
request.Context.EmailVerificationCode = verificationCode;
|
|
request.Context.EmailVerified = true;
|
|
|
|
//
|
|
// Prepare New Token Result ,
|
|
// by Requesting an Action ...
|
|
var result = await ActionRequest(
|
|
lang,
|
|
device,
|
|
userSelectByParam,
|
|
XAction.ConfirmEmailAddress,
|
|
request.Context,
|
|
forceCheckUserExists: isAddedUser
|
|
);
|
|
|
|
//
|
|
// Remove Previous Token ...
|
|
await RemoveTokenByHash(actionToken);
|
|
|
|
//
|
|
// Remove XVerificationRequest instance from Db ...
|
|
await RemoveVerificationRequest(verificationCode);
|
|
|
|
//
|
|
// Return Result ...
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
} |