481 lines
14 KiB
C#
481 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xIdentityModels;
|
|
using xIdentityModels.Extensions;
|
|
using xIdentityModels.Models;
|
|
using xIdentityModels.Navigations;
|
|
using xIds.Extensions;
|
|
|
|
namespace xIds.Providers
|
|
{
|
|
public partial class XIdentityManager
|
|
{
|
|
//
|
|
#region Device Actions ...
|
|
/// <summary>
|
|
/// Check a Device Exists or Not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsDeviceExistsAsync(
|
|
XDevice device
|
|
)
|
|
{
|
|
return await DbContext.Devices
|
|
.AnyAsync(d => d.IsSameAs(device));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add new Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XDevice</see></returns>
|
|
public async Task<XDevice> AddDeviceAsync(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var isDeviceExists = await IsDeviceExistsAsync(device);
|
|
if (isDeviceExists)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
//
|
|
await DbContext.Devices
|
|
.AddAsync(device);
|
|
|
|
await DbContext.SaveChangesAsync();
|
|
|
|
return device;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XDevice</see></returns>
|
|
public Task<XDevice> GetDeviceAsync(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
return DbContext.Devices
|
|
.FirstOrDefaultAsync(d =>
|
|
d.IsSameAs(device));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a List of User Related Devices
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a collection of <see>XDevice</see> instances which related to user</returns>
|
|
public async Task<ICollection<XDevice>> GetUserDevices(
|
|
string userSelectByParam,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate ARgs ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
|
|
//
|
|
// Validate And Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
|
|
//
|
|
// Check User Devices ...
|
|
if (!user.Devices.HasChild())
|
|
{
|
|
return new List<XDevice>();
|
|
}
|
|
|
|
//
|
|
return user.Devices;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Device is Exists in User's Devices or not
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public bool IsDeviceRelateDToUser(
|
|
XUser user,
|
|
XDevice device
|
|
)
|
|
{
|
|
if (!user.Devices.HasChild())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = user.Devices.Any(d => d.IsSameAs(device));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines a Device is Exists in User's Devices or not
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsDeviceRelateDToUser(
|
|
string userSelectByParam,
|
|
XDevice device,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
var userDevices = await GetUserDevices(
|
|
userSelectByParam,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
if (!userDevices.HasChild())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var result = userDevices.Any(d => d.IsSameAs(device));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Device to a User Related Devices
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> AddUserRelatedDevice(
|
|
XUser user,
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var isExists = user.Devices.Any(d =>
|
|
d.IsSameAs(device));
|
|
if (isExists)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//
|
|
user.Devices.Add(device);
|
|
try
|
|
{
|
|
var result = await UpdateUserAsync(user);
|
|
return result.Succeeded;
|
|
}
|
|
catch
|
|
{
|
|
throw XException.ActionFailed.ToException();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a Device to a User
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> AddUserRelatedDevice(
|
|
string userSelectByParam,
|
|
XDevice device,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
// Check Device Related ...
|
|
var isDeviceRelatedToUser = await IsDeviceRelateDToUser(
|
|
userSelectByParam,
|
|
device,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned);
|
|
if (isDeviceRelatedToUser)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// Retrieve User ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
|
|
//
|
|
// Add User Device ...
|
|
user.Devices.Add(device);
|
|
|
|
//
|
|
var result = await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
return result.Succeeded;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Device from a User Related Devices List
|
|
/// </summary>
|
|
/// <param name="user">an instance of <see>XUser</see></param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> RemoveUserRelatedDevice(
|
|
XUser user,
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var isRelated = IsDeviceRelateDToUser(user, device);
|
|
if (!isRelated)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//
|
|
var instanse = user.Devices
|
|
.FirstOrDefault(d =>
|
|
d.IsSameAs(device));
|
|
|
|
//
|
|
user.Devices.Remove(instanse);
|
|
|
|
//
|
|
var result = await UpdateUserAsync(
|
|
user,
|
|
checkCanLoginPolicies: false,
|
|
checkIsBanned: false
|
|
);
|
|
|
|
//
|
|
return result.Succeeded;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a Device from a User Devices
|
|
/// </summary>
|
|
/// <param name="userSelectByParam">user identifier</param>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <param name="checkCanLoginPolicies">check a user can log in in system or not</param>
|
|
/// <param name="checkIsBanned">check user is banned or not</param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> RemoveUserRelatedDevice(
|
|
string userSelectByParam,
|
|
XDevice device,
|
|
bool checkCanLoginPolicies = true,
|
|
bool checkIsBanned = true
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidationProvider.NotEmpty(userSelectByParam);
|
|
ValidationProvider.NotNull(device);
|
|
|
|
//
|
|
// Validate user exists and Retrieve it based on userselectbyparam ...
|
|
var user = await ValidateUserExistsAndRetrieve(
|
|
userSelectByParam,
|
|
containDetails: true,
|
|
checkCanLoginPolicies: checkCanLoginPolicies,
|
|
checkIsBanned: checkIsBanned
|
|
);
|
|
|
|
//
|
|
return await RemoveUserRelatedDevice(
|
|
user,
|
|
device
|
|
);
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Banned Device Actions ...
|
|
/// <summary>
|
|
/// Check a Device is exists in Banned Devices or not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
public async Task<bool> IsBannedDeviceExists(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = false;
|
|
var bannedDeviceEnumerable = DbContext.BannedDevices.AsAsyncEnumerable();
|
|
await
|
|
foreach (var bannedDevice in bannedDeviceEnumerable)
|
|
{
|
|
//
|
|
if (bannedDevice.Device.IsSameAs(device))
|
|
{
|
|
//
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find First Banned Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XDevice</see></returns>
|
|
public async Task<XBannedDevice> BannedDeviceFindOne(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = await DbContext.BannedDevices
|
|
.FirstOrDefaultAsync(bd =>
|
|
bd.Device.IsSameAs(device)
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove Banned Device
|
|
/// </summary>
|
|
/// <param name="model">an instance of <see>XBannedDevice</see></param>
|
|
/// <returns></returns>
|
|
public async Task BannedDeviceRemove(
|
|
XBannedDevice model
|
|
)
|
|
{
|
|
//
|
|
var isExists = await IsBannedDeviceExists(model.Device);
|
|
if (!isExists)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
var item = await BannedDeviceFindOne(model.Device);
|
|
if (item == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
DbContext.BannedDevices.Remove(item);
|
|
await DbContext.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a Device is Banned or not
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private async Task<bool> IsDeviceBanned(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = await IsBannedDeviceExists(device);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Specific Banned Device
|
|
/// </summary>
|
|
/// <param name="device">an instance of <see>XDevice</see></param>
|
|
/// <returns>an instance of <see>XBannedDevice</see></returns>
|
|
private async Task<XBannedDevice> GetBannedDevice(
|
|
XDevice device
|
|
)
|
|
{
|
|
//
|
|
var result = await BannedDeviceFindOne(device);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Is a Banned Device passed Banning Time
|
|
/// </summary>
|
|
/// <param name="bannedDevice">an instance of <see>XBannedDevice</see></param>
|
|
/// <returns>a boolean value</returns>
|
|
private bool IsDelayTimePassed(
|
|
XBannedDevice bannedDevice
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (bannedDevice == null ||
|
|
Configuration == null)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var isPassed = bannedDevice
|
|
.IsDelayTimePassed(Configuration.BannedDeviceTimeout);
|
|
|
|
//
|
|
return isPassed;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Passed Time from Banning Time of specific Device
|
|
/// </summary>
|
|
/// <param name="bannedDevice">an instance of <see>XBannedDevice</see></param>
|
|
/// <returns>an instance of <see>DateTime</see> which represent Passed Time</returns>
|
|
private DateTime GetPassedTime(
|
|
XBannedDevice bannedDevice
|
|
)
|
|
{
|
|
//
|
|
var result = bannedDevice.BannedOn
|
|
.AddSeconds(Configuration.BannedDeviceTimeout);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
} |