552 lines
17 KiB
C#
552 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xCommons.Helpers;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Constants;
|
|
using xIdentityModels.Dtos;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Generators ...
|
|
/// <summary>
|
|
/// Generate a Random Number ...
|
|
/// </summary>
|
|
/// <returns>a long value</returns>
|
|
private long GenerateRandom()
|
|
{
|
|
return new Random().Next(100000, 999999);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region UserSelectBy Actions ...
|
|
/// <summary>
|
|
/// Retrieve UserSelectByType based on Given Info
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">a user identifier</param>
|
|
/// <param name="forceUserSelectByParamNotEmpty">a boolean value which specify the identifier
|
|
/// must be specific and not empty, default is true</param>
|
|
/// <param name="forceUserSelectByTypeMustSpecified">a boolean value which specify the type
|
|
/// must be specific, default is false</param>
|
|
/// <returns>a member of <see>XUserSelectBy</see></returns>
|
|
private XUserSelectBy GetUserSelectByType(
|
|
string userSelectByParam,
|
|
bool forceUserSelectByParamNotEmpty = true,
|
|
bool forceUserSelectByTypeMustSpecified = false
|
|
)
|
|
{
|
|
//
|
|
if (forceUserSelectByParamNotEmpty)
|
|
{
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
}
|
|
|
|
//
|
|
var result = XUserSelectBy.NotSpecified;
|
|
var normalizedString = userSelectByParam.ToNormalString();
|
|
if (userSelectByParam.IsValidEmail())
|
|
{
|
|
//
|
|
// Find User by Email ...
|
|
result = XUserSelectBy.Email;
|
|
}
|
|
else if (userSelectByParam.IsValidMobileNumber())
|
|
{
|
|
//
|
|
// Find User by Mobile Number ...
|
|
result = XUserSelectBy.MobileNumber;
|
|
}
|
|
else if (userSelectByParam.IsGuid())
|
|
{
|
|
//
|
|
// Find User By it's ID ...
|
|
result = XUserSelectBy.ID;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// UserName ...
|
|
result = XUserSelectBy.Username;
|
|
}
|
|
|
|
//
|
|
if (forceUserSelectByTypeMustSpecified &&
|
|
result == XUserSelectBy.NotSpecified)
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve UserSelectByParam based on XUser Object
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
|
|
/// and throw exception if it is empty, default is true</param>
|
|
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
|
|
/// exclude them from result, default is null</param>
|
|
/// <returns>a user identifier</returns>
|
|
private string GetUserSelectByParam(
|
|
XUser user,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(user);
|
|
|
|
//
|
|
var id = user.Id;
|
|
var userName = user.UserName;
|
|
var email = user.Email;
|
|
var phoneNumber = user.PhoneNumber;
|
|
|
|
//
|
|
if (excludes != null)
|
|
{
|
|
if (excludes.Contains(XUserSelectBy.ID))
|
|
{
|
|
id = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Email))
|
|
{
|
|
email = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.MobileNumber))
|
|
{
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Username))
|
|
{
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
var selectByParam =
|
|
id.IsNullOrEmpty() ?
|
|
userName.IsNullOrEmpty() ?
|
|
email.IsNullOrEmpty() ?
|
|
phoneNumber.IsNullOrEmpty() ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check result ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve UserSelectByParam based on <see>XActionRequestContext</see> instance
|
|
/// </summary>
|
|
/// <param name="context">an instance of <see>XActionRequestContext</see></param>
|
|
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
|
|
/// and throw exception if it is empty, default is true</param>
|
|
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
|
|
/// exclude them from result, default is null</param>
|
|
/// <returns>a user identifier</returns>
|
|
private string GetUserSelectByParam(
|
|
XActionRequestContext context,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(context);
|
|
|
|
//
|
|
// Generate User SelectBy ...
|
|
var id = context.UserId;
|
|
var userName = context.UserName;
|
|
var email = context.Email;
|
|
var phoneNumber = context.MobileNumber;
|
|
|
|
//
|
|
if (excludes != null)
|
|
{
|
|
//
|
|
if (excludes.Contains(XUserSelectBy.ID))
|
|
{
|
|
id = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Email))
|
|
{
|
|
email = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.MobileNumber))
|
|
{
|
|
phoneNumber = null;
|
|
}
|
|
if (excludes.Contains(XUserSelectBy.Username))
|
|
{
|
|
userName = null;
|
|
}
|
|
}
|
|
|
|
var selectByParam =
|
|
id.IsNullOrEmpty() ?
|
|
userName.IsNullOrEmpty() ?
|
|
email.IsNullOrEmpty() ?
|
|
phoneNumber.IsNullOrEmpty() ? null : phoneNumber : email : userName : id;
|
|
|
|
//
|
|
// Check param ...
|
|
if (forceNotNull &&
|
|
selectByParam.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
return selectByParam;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve UserSelectByParam based on <see>XActionRequestToken</see> instance
|
|
/// </summary>
|
|
/// <param name="request">an instance of <see>XActionRequestToken</see> which
|
|
/// provides required informations</param>
|
|
/// <param name="forceNotNull">a boolean value which specify the identifier must nut empty,
|
|
/// and throw exception if it is empty, default is true</param>
|
|
/// <param name="excludes">a collection of <see>XUserSelectBy</see> members which
|
|
/// exclude them from result, default is null</param>
|
|
/// <returns>a user identifier</returns>
|
|
private string GetUserSelectByParam(
|
|
XActionRequestToken request,
|
|
bool forceNotNull = true,
|
|
ICollection<XUserSelectBy> excludes = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(request);
|
|
|
|
//
|
|
// Generate User SelectBy ...
|
|
return GetUserSelectByParam(
|
|
context: request.Context,
|
|
forceNotNull: forceNotNull,
|
|
excludes: excludes
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Available UserSelectByParams from given XUser
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <returns></returns>
|
|
private ICollection<string> GenerateUserSelectByParams(
|
|
XUser user
|
|
)
|
|
{
|
|
//
|
|
if (user == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var result = new List<string> {
|
|
user.Id,
|
|
user.UserName,
|
|
user.PhoneNumber,
|
|
user.Email,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Required XUserSelectByTypes
|
|
/// </summary>
|
|
/// <param name="ignores">a collection of <see>XUserSelectBy</see> members which
|
|
/// ignored in result</param>
|
|
/// <returns>a collection of available <see>XUserSelectBy</see> members</returns>
|
|
private ICollection<XUserSelectBy> GenerateUserSelectByExcludes(
|
|
ICollection<XUserSelectBy> ignores
|
|
)
|
|
{
|
|
//
|
|
var result = ObjectHelper
|
|
.ToEnumerableValues<XUserSelectBy>()
|
|
.Except(ignores);
|
|
|
|
//
|
|
return result.ToList();
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region XAction Actions ...
|
|
/// <summary>
|
|
/// Retrieve Action Result Response based on XToken
|
|
/// </summary>
|
|
/// <param name="xToken">an instance of <see>XToken</see></param>
|
|
/// <returns>an instance of <see>XActionResponse</see></returns>
|
|
private XActionResponse GetActionResultResponse(
|
|
XToken xToken
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider.NotNull(xToken);
|
|
ValidationProvider.NotEmpty(xToken.Hash, xToken.Token);
|
|
|
|
//
|
|
ValidateToken(xToken.Token);
|
|
|
|
//
|
|
var expDate = GetTokenExpirationDate(xToken.Token);
|
|
ValidationProvider.NotNull(expDate);
|
|
|
|
//
|
|
// Generate Result class ...
|
|
var result = new XActionResponse
|
|
{
|
|
Token = xToken.Hash,
|
|
Expiration = expDate
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region XIdentityMessage Actions ...
|
|
/// <summary>
|
|
/// Prepare Message Provider and Check it's State
|
|
/// </summary>
|
|
/// <param name="lang">specify destination language</param>
|
|
private void HandleMessageProviderPreperation(
|
|
string lang
|
|
)
|
|
{
|
|
//
|
|
ValidationProvider
|
|
.NotEmpty(lang);
|
|
|
|
//
|
|
// Prepare Identity Messages ...
|
|
// the PrepareMessageMethod check IsReady of Helper automatically ...
|
|
IdentityMessageProvider.PrepareMessages(lang);
|
|
|
|
//
|
|
// Check Message Provider ...
|
|
var isMessageProviderReady = MessageProvider.IsReady(true);
|
|
if (!isMessageProviderReady)
|
|
{
|
|
XException.MessageServiceInitialFailed.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Friendship Actions ...
|
|
/// <summary>
|
|
/// Check Follow Request Sent Before
|
|
/// from dest to source
|
|
/// </summary>
|
|
/// <param name="source">an instance of <see>XUser</see></param>
|
|
/// <param name="dest">an instance of <see>XUser</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsFollowRequested(
|
|
XUser source,
|
|
XUser dest
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
var result = source.Followings.Any(f => f.DestId == dest.Id);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check Follow Request Sent Before
|
|
/// from dest to source
|
|
/// </summary>
|
|
/// <param name="source">an instance of <see>XUser</see></param>
|
|
/// <param name="dest">an instance of <see>XUser</see></param>
|
|
/// <param name="state">a member of <see>XFriendshipState</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsFollowRequested(
|
|
XUser source,
|
|
XUser dest,
|
|
XFriendshipState state
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotNull(source, dest);
|
|
|
|
//
|
|
var result = source.Followings
|
|
.Any(f =>
|
|
f.DestId == dest.Id &&
|
|
f.State == state);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts to XFriendDto ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <returns></returns>
|
|
private async Task<XFriendDto> ToDto(XFriendshipFollower entity)
|
|
{
|
|
//
|
|
XFriendDto result = null;
|
|
|
|
//
|
|
if (entity.IsNull())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Dest User Profile ...
|
|
var profile = await GetUserProfileAsync(
|
|
userSelectByParam: entity.DestId,
|
|
requestedUserSelectByParam: entity.UserId,
|
|
forceCheckRequestedUser: false,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
// Preparing Result ...
|
|
result = new XFriendDto
|
|
{
|
|
UserId = profile.UserId,
|
|
Avatar = profile.Avatar,
|
|
Username = profile.UserName,
|
|
Lastname = profile.LastName,
|
|
Firstname = profile.FirstName,
|
|
Type = XFriendshipType.Follower,
|
|
State = profile.FriendshipInfo.FollowerState,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts to XFriendDto ...
|
|
/// </summary>
|
|
/// <param name="entity"></param>
|
|
/// <returns></returns>
|
|
private async Task<XFriendDto> ToDto(XFriendshipFollowing entity)
|
|
{
|
|
//
|
|
XFriendDto result = null;
|
|
|
|
//
|
|
if (entity.IsNull())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Dest User Profile ...
|
|
var profile = await GetUserProfileAsync(
|
|
checkIsBanned: false,
|
|
checkCanLoginPolicies: false,
|
|
forceCheckRequestedUser: false,
|
|
userSelectByParam: entity.DestId,
|
|
requestedUserSelectByParam: entity.UserId
|
|
);
|
|
|
|
//
|
|
// Preparing Result ...
|
|
result = new XFriendDto
|
|
{
|
|
UserId = profile.UserId,
|
|
Avatar = profile.Avatar,
|
|
Username = profile.UserName,
|
|
Lastname = profile.LastName,
|
|
Firstname = profile.FirstName,
|
|
Type = XFriendshipType.Following,
|
|
State = profile.FriendshipInfo.FollowingState,
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region User Profile ...
|
|
/// <summary>
|
|
/// Count User's Page
|
|
/// </summary>
|
|
/// <param name="pageSize">an integer value which represent page size</param>
|
|
/// <returns>an inetger value which represent pages count</returns>
|
|
public async Task<int> UserPagesCount(
|
|
int pageSize
|
|
)
|
|
{
|
|
//
|
|
int count = await UserManager.Users.CountAsync();
|
|
int pagesCount = count / pageSize;
|
|
|
|
//
|
|
if (count % pageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
return pagesCount;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Count Avatar's Page
|
|
/// </summary>
|
|
/// <param name="pageSize">an integer value which represent page size</param>
|
|
/// <returns>an inetger value which represent pages count</returns>
|
|
public async Task<int> ProfileImagePagesCount(
|
|
int pageSize
|
|
)
|
|
{
|
|
//
|
|
int count = await DbContext.Avatars.CountAsync();
|
|
int pagesCount = count / pageSize;
|
|
|
|
//
|
|
if (count % pageSize > 0)
|
|
{
|
|
pagesCount++;
|
|
}
|
|
|
|
//
|
|
return pagesCount;
|
|
}
|
|
#endregion
|
|
}
|
|
} |