Files
xSaherElmIds/Providers/XIdentityManager/XIdentityManager+Device.cs
T
2026-03-22 14:08:25 +03:30

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
}
}