Compare commits

..
10 Commits
Author SHA1 Message Date
saherelm ccae6137fb last ... 2026-07-26 21:20:22 +03:30
saherelm 1b32632a83 last ... 2026-06-12 23:50:06 +03:30
saherelm f296f0eb7a Update Lang Version to 12 ... 2026-06-12 02:13:43 +03:30
saherelm ab714c9894 last ... 2026-05-27 16:10:41 +03:30
saherelm 7799188db9 last ... 2026-05-22 20:24:03 +03:30
saherelm cb64a8dac9 last ... 2026-05-08 03:43:29 +03:30
saherelm 8182f98b3c refactor csproj ... 2026-04-14 16:33:02 +03:30
saherelm d9b33de198 last ... 2025-12-23 18:24:31 +03:30
saherelm 6a2618a3c4 adding bio, coverImage and openToSearch Fields Support for User/UserProfile and Update User ... 2025-12-23 16:34:57 +03:30
saherelm 23e68de1ef last ... 2025-12-23 00:07:55 +03:30
8 changed files with 389 additions and 87 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
namespace xIdentityModels.DI {
public static class XDIHelperExtension { }
public static partial class XDIHelperExtension { }
}
+18
View File
@@ -84,6 +84,24 @@ namespace xIdentityModels.Dtos {
NullValueHandling = NullValueHandling.Ignore)]
public XGender Gender { get; set; }
[JsonProperty (
"bio",
Required = Required.Default,
NullValueHandling = NullValueHandling.Ignore)]
public string Bio { get; set; }
[JsonProperty (
"coverImage",
Required = Required.Default,
NullValueHandling = NullValueHandling.Ignore)]
public string CoverImage { get; set; }
[JsonProperty (
"openToSearch",
Required = Required.Default,
NullValueHandling = NullValueHandling.Ignore)]
public bool OpenToSearch { get; set; }
[JsonProperty (
"friendshipInfo",
Required = Required.Default,
+198 -2
View File
@@ -1,3 +1,199 @@
namespace xIdentityModels.Extensions {
public static class xIdentityModelsExtensions { }
using System.Collections.Generic;
using System.Linq;
using xCommons.Extensions;
using xIdentityModels.Configurations;
using xIdentityModels.Constants;
using xIdentityModels.Dtos;
using xIdentityModels.Models;
namespace xIdentityModels.Extensions
{
public static class xIdentityModelsExtensions
{
/// <summary>
/// Converts a User Entity to Profile Dto ...
/// </summary>
/// <param name="source"></param>
/// <param name="isAdmin"></param>
/// <param name="isSameUser"></param>
/// <param name="roles"></param>
/// <param name="friendship"></param>
/// <param name="profileConfig"></param>
/// <returns></returns>
public static XUserProfileDto ToXProfileDto(
this XUser source,
bool isAdmin = false,
bool isSameUser = false,
IEnumerable<string> roles = null,
XFriendshipInfoDto friendship = null,
XIdentityProfile profileConfig = null
)
{
//
XUserProfileDto result = null;
//
if (roles == null)
{
roles = new List<string>();
}
//
// Prepare Dto ...
if (!source.IsNullOrDefault())
{
//
result = new XUserProfileDto
{
Bio = source.Bio,
UserId = source.Id,
Email = source.Email,
Roles = roles.ToList(),
Avatar = source.Avatar,
IsEnable = source.IsEnable,
IsBanned = source.IsBanned,
UserName = source.UserName,
LastName = source.LastName,
FriendshipInfo = friendship,
FirstName = source.FirstName,
LastLogin = source.LastLogin,
CoverImage = source.CoverImage,
PhoneNumber = source.PhoneNumber,
DateOfBirth = source.DateOfBirth,
CreationDate = source.CreationDate,
OpenToSearch = source.OpenToSearch,
Gender = (XGender)(int)source.Gender,
EmailConfirmed = source.EmailConfirmed,
PhoneNumberConfirmed = source.PhoneNumberConfirmed,
Avatars = source.Avatars.Select(pfi =>
{
//
return new XProfileImageDto
{
Id = pfi.Id,
Name = pfi.Name,
Path = pfi.Path,
Thumb = pfi.Thumb,
ThumbPath = pfi.ThumbPath,
CreationDate = pfi.CreationDate
};
}).ToList(),
};
}
//
// Apply Profiling Configuration ...
//
bool isPassed = false;
//
// Handle Friendship ...
isPassed = !isSameUser;
if (!isPassed)
{
result.FriendshipInfo = null;
}
//
// Handle Email Info ...
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsEmail);
if (!isPassed)
{
result.Email = string.Empty;
result.EmailConfirmed = false;
}
//
// Handle PhoneNumber Info ...
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsPhoneNumber);
if (!isPassed)
{
source.PhoneNumber = string.Empty;
source.PhoneNumberConfirmed = false;
}
//
// Handle Last Login ...
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsLastLogin);
if (!isPassed)
{
result.LastLogin = null;
}
//
// Handle Date Of Birth ...
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsDateOfBirth);
if (!isPassed)
{
result.DateOfBirth = null;
}
//
// Handle Creation Date ...
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsCreationDate);
if (!isPassed)
{
result.CreationDate = null;
}
//
// Handle Roles ...
isPassed = isAdmin || isSameUser || (!profileConfig.IsNullOrDefault() && profileConfig.ContainsRoles);
if (!isPassed)
{
result.Roles = new List<string>();
}
//
return result;
}
/// <summary>
/// Check Specified User Has Access to Provided Roles ...
/// </summary>
/// <param name="source"></param>
/// <param name="roles"></param>
/// <returns></returns>
public static bool HasAccess(
this XUserClaimsInfoDto source,
string[] roles
)
{
//
var result =
!source.IsNullOrDefault() &&
source.Roles
.Any(r => roles
.Any(ar => r.ToNormalString()
.Contains(ar.ToNormalString())));
//
return result;
}
/// <summary>
/// Check Specified User Contains Specified UserSelectByParam or not ...
/// </summary>
/// <param name="source"></param>
/// <param name="userSelectByParam"></param>
/// <returns></returns>
public static bool ContainsUserSelectByParam(
this XUser source,
string userSelectByParam
)
{
//
var result =
!source.IsNull() &&
!userSelectByParam.IsNullOrEmpty() &&
(source.Id == userSelectByParam ||
source.Email.ToNormalString() == userSelectByParam.ToNormalString() ||
source.UserName.ToNormalString() == userSelectByParam.ToNormalString() ||
source.PhoneNumber.ToNormalString() == userSelectByParam.ToNormalString());
//
return result;
}
}
}
+3
View File
@@ -18,5 +18,8 @@ namespace xIdentityModels.Models {
public ICollection<string> Roles { get; set; } = new HashSet<string> ();
public bool? IsEnable { get; set; }
public bool? IsBanned { get; set; }
public string Bio { get; set; }
public string CoverImage { get; set; }
public bool OpenToSearch { get; set; }
}
}
+75 -21
View File
@@ -9,8 +9,10 @@ using xExceptions.Constants;
using xIdentityModels.Constants;
using xModels.Base;
namespace xIdentityModels.Models {
public class XUserClaimsInfoDto : XBaseDto {
namespace xIdentityModels.Models
{
public class XUserClaimsInfoDto : XBaseDto
{
//
#region Properties ...
public string AccessToken { get; }
@@ -28,6 +30,9 @@ namespace xIdentityModels.Models {
public bool IsEnabled { get; }
public bool EmailConfirmed { get; }
public bool PhoneNumberConfirmed { get; }
public string Bio { get; set; }
public string CoverImage { get; set; }
public bool OpenToSearch { get; set; }
public long? ExpiredOn { get; }
public long? AuthenticatedOn { get; }
public DateTime? BrithDate { get; }
@@ -46,11 +51,13 @@ namespace xIdentityModels.Models {
string refreshToken,
long expiresAt,
IEnumerable<Claim> claims
) {
)
{
//
// refreshToken.IsNullOrEmpty ()
if (claims.IsNull() ||
accessToken.IsNullOrEmpty ()) {
accessToken.IsNullOrEmpty())
{
XException.InvalidArgs.Throw();
}
@@ -61,7 +68,9 @@ namespace xIdentityModels.Models {
ExpiresAt = expiresAt;
//
if (!claims.IsNull ()) {
if (!claims.IsNull())
{
//
UserId = claims.FirstOrDefault(c => c.Type == XCustomClaims.UserId)?.Value ?? "";
UserName = claims.FirstOrDefault(c => c.Type == XCustomClaims.UserName)?.Value ?? "";
FirstName = claims.FirstOrDefault(c => c.Type == XCustomClaims.FirstName)?.Value ?? "";
@@ -70,22 +79,48 @@ namespace xIdentityModels.Models {
Email = claims.FirstOrDefault(c => c.Type == XCustomClaims.Email)?.Value ?? null;
PhoneNumber = claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumber)?.Value ?? null;
//
Bio = claims.FirstOrDefault(c => c.Type == XCustomClaims.Bio)?.Value ?? null;
CoverImage = claims.FirstOrDefault(c => c.Type == XCustomClaims.CoverImage)?.Value ?? null;
//
var openToSearchStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.OpenToSearch)?.Value ?? null;
if (openToSearchStr.IsNullOrEmpty())
{
OpenToSearch = false;
}
else
{
//
var openToSearch = false;
bool.TryParse(openToSearchStr, out openToSearch);
//
OpenToSearch = openToSearch;
}
//
// Handle Gender ...
var genders = ObjectHelper.ToEnumerableKeys<XGender>();
var genderStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.Gender).Value ?? null;
if (genderStr.IsNullOrEmpty ()) {
if (genderStr.IsNullOrEmpty())
{
Gender = XGender.Male;
} else {
}
else
{
Gender = genderStr.GetValue<XGender>();
}
//
// Handle IsBanned ...
var isBannedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.IsBanned).Value ?? null;
if (isBannedStr.IsNullOrEmpty ()) {
if (isBannedStr.IsNullOrEmpty())
{
IsBanned = false;
} else {
}
else
{
//
var isBanned = false;
Boolean.TryParse(isBannedStr, out isBanned);
@@ -97,9 +132,12 @@ namespace xIdentityModels.Models {
//
// Handle IsEnabled ...
var isEnabledStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.IsEnabled).Value ?? null;
if (isEnabledStr.IsNullOrEmpty ()) {
if (isEnabledStr.IsNullOrEmpty())
{
IsEnabled = false;
} else {
}
else
{
//
var isEnabled = false;
Boolean.TryParse(isEnabledStr, out isEnabled);
@@ -111,9 +149,12 @@ namespace xIdentityModels.Models {
//
// Handle Email Confirmed ...
var emailConfirmedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.EmailVerified).Value ?? null;
if (emailConfirmedStr.IsNullOrEmpty ()) {
if (emailConfirmedStr.IsNullOrEmpty())
{
EmailConfirmed = false;
} else {
}
else
{
//
var emailConfirmed = false;
Boolean.TryParse(emailConfirmedStr, out emailConfirmed);
@@ -125,9 +166,12 @@ namespace xIdentityModels.Models {
//
// Handle PhoneNumber Confirmed ...
var phoneNumberConfirmedStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumberVerified).Value ?? null;
if (phoneNumberConfirmedStr.IsNullOrEmpty ()) {
if (phoneNumberConfirmedStr.IsNullOrEmpty())
{
PhoneNumberConfirmed = false;
} else {
}
else
{
//
var phoneNumberConfirmed = false;
Boolean.TryParse(phoneNumberConfirmedStr, out phoneNumberConfirmed);
@@ -139,9 +183,12 @@ namespace xIdentityModels.Models {
//
// Handle ExpiredOn ...
var expiredOnStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.ExpiredOn).Value ?? null;
if (expiredOnStr.IsNullOrEmpty ()) {
if (expiredOnStr.IsNullOrEmpty())
{
ExpiredOn = null;
} else {
}
else
{
//
long expiredOn = 0;
long.TryParse(expiredOnStr, out expiredOn);
@@ -153,9 +200,12 @@ namespace xIdentityModels.Models {
//
// Handle AuthenticatedOn ...
var authenticatedOnStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.AuthenticatedOn).Value ?? null;
if (authenticatedOnStr.IsNullOrEmpty ()) {
if (authenticatedOnStr.IsNullOrEmpty())
{
AuthenticatedOn = null;
} else {
}
else
{
//
long authenticatedOn = 0;
long.TryParse(authenticatedOnStr, out authenticatedOn);
@@ -167,9 +217,12 @@ namespace xIdentityModels.Models {
//
// Handle BrithDate ...
var brithDateStr = claims.FirstOrDefault(c => c.Type == XCustomClaims.BrithDate)?.Value ?? "";
if (brithDateStr.IsNullOrEmpty ()) {
if (brithDateStr.IsNullOrEmpty())
{
// BrithDate = null;
} else {
}
else
{
//
DateTime bDate;
DateTime.TryParse(brithDateStr, out bDate);
@@ -179,6 +232,7 @@ namespace xIdentityModels.Models {
}
//
// Collections ...
Issuers = claims.Where(c => c.Type == XCustomClaims.Issuer)?
.Select(c => c.Value) ?? new HashSet<string>();
Audiences = claims.Where(c => c.Type == XCustomClaims.Audience)?
+20 -3
View File
@@ -6,11 +6,13 @@ using Microsoft.AspNetCore.Identity;
using xIdentityModels.Constants;
using xIdentityModels.Navigations;
namespace xIdentityModels {
namespace xIdentityModels
{
/// <summary>
/// represnt a User of System
/// </summary>
public partial class XUser : IdentityUser {
public partial class XUser : IdentityUser
{
//
#region Properties ...
/// <summary>
@@ -71,6 +73,21 @@ namespace xIdentityModels {
/// <value>user's Gender</value>
[Required]
public XGender Gender { get; set; }
/// <summary>
/// User Biography ...
/// </summary>
/// <value></value>
public string Bio { get; set; }
/// <summary>
/// User Bio Cover Image ...
/// </summary>
/// <value></value>
public string CoverImage { get; set; }
/// <summary>
/// Can Discover User ...
/// </summary>
/// <value></value>
public bool OpenToSearch { get; set; }
#endregion
//
@@ -82,12 +99,12 @@ namespace xIdentityModels {
/// <returns>a Collection of all assigned Devices to User</returns>
[InverseProperty("User")]
public virtual ICollection<XDevice> Devices { get; set; } = new HashSet<XDevice>();
[InverseProperty ("User")]
/// <summary>
/// User's Avatars
/// </summary>
/// <typeparam name="XProfileImage"><see>XProfileImage</see></typeparam>
/// <returns>a Collection of all assigned Avatars to User</returns>
[InverseProperty("User")]
public virtual ICollection<XProfileImage> Avatars { get; set; } = new HashSet<XProfileImage>();
/// <summary>
/// User's Followers
+2 -1
View File
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!-- <add key="megan" value="https://hub.megan.ir/nuget/index.json" /> -->
<add key="nuget" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="baget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" />
<add key="baget" value="https://nuget.saherelmhub.ir/v3/index.json" protocolVersion="3" disableTLSCertificateValidation="true" />
</packageSources>
</configuration>
+18 -5
View File
@@ -2,11 +2,13 @@
<!-- Runtime Definition -->
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>xDashboard.xIdentityModels</PackageId>
<Version>1.0.0</Version>
<LangVersion>12.0</LangVersion>
<Authors>Hadi Khazaee Asl</Authors>
<Company>SaherElm IT Center</Company>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>xDashboard.xIdentityModels</PackageId>
<Description>
it is a Part of xDashboard on SaherElm IT Center which provides all required identity models
</Description>
@@ -17,20 +19,31 @@
<!-- Icon Handling -->
<ItemGroup>
<None Include="../../Resources/Images/favicon.png" Link="icon.png" Pack="true" PackagePath="\icon.png" />
<None Include="../../Resources/Images/favicon.png" Link="icon.png" Pack="true"
PackagePath="\icon.png" />
</ItemGroup>
<!-- Local Modules -->
<ItemGroup>
<!-- <PackageReference Include="xDashboard.xModels" Version="1.0.0" /> -->
</ItemGroup>
<!-- Local Dependencies -->
<ItemGroup>
<ProjectReference Include="../xModels/xModels.csproj" />
</ItemGroup>
<!-- Nuget Package Dependencies -->
<!-- Dependencies -->
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.6.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.6.0" />
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="5.0.2" />
</ItemGroup>
<!-- For XML Documentation Support -->
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
</Project>