135 lines
5.8 KiB
C#
135 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Security.Claims;
|
|
using System.Text.Json;
|
|
using Oqtane.Models;
|
|
using Oqtane.Shared;
|
|
|
|
namespace Oqtane.Security
|
|
{
|
|
public class UserSecurity
|
|
{
|
|
public static bool IsAuthorized(User user, string roles)
|
|
{
|
|
var permissions = new List<Permission>();
|
|
foreach (var role in roles.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
|
{
|
|
permissions.Add(new Permission("", role, true));
|
|
}
|
|
return IsAuthorized(user, permissions);
|
|
}
|
|
|
|
public static bool IsAuthorized(User user, string permissionName, List<Permission> permissionList)
|
|
{
|
|
return IsAuthorized(user, permissionList.Where(item => item.PermissionName == permissionName).ToList());
|
|
}
|
|
|
|
public static bool IsAuthorized(User user, List<Permission> permissionList)
|
|
{
|
|
bool authorized = false;
|
|
if (permissionList != null && permissionList.Any())
|
|
{
|
|
if (user == null)
|
|
{
|
|
authorized = IsAuthorized(-1, "", permissionList); // user is not authenticated but may have access to resource
|
|
}
|
|
else
|
|
{
|
|
authorized = IsAuthorized(user.UserId, user.Roles, permissionList);
|
|
}
|
|
|
|
}
|
|
return authorized;
|
|
}
|
|
|
|
private static bool IsAuthorized(int userId, string roles, List<Permission> permissionList)
|
|
{
|
|
bool isAuthorized = false;
|
|
|
|
if (permissionList != null && permissionList.Any())
|
|
{
|
|
// check if denied first
|
|
isAuthorized = !permissionList.Where(item => !item.IsAuthorized && (
|
|
(item.UserId == null && (
|
|
(item.RoleName == RoleNames.Everyone) ||
|
|
(item.RoleName == RoleNames.Unauthenticated && userId == -1) ||
|
|
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.RoleName))) ||
|
|
(item.UserId != null && item.UserId.Value == userId))).Any();
|
|
|
|
if (isAuthorized)
|
|
{
|
|
// then check if authorized
|
|
isAuthorized = permissionList.Where(item => item.IsAuthorized && (
|
|
(item.UserId == null && (
|
|
(item.RoleName == RoleNames.Everyone) ||
|
|
(item.RoleName == RoleNames.Unauthenticated && userId == -1) ||
|
|
roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(item.RoleName))) ||
|
|
(item.UserId != null && item.UserId.Value == userId))).Any();
|
|
}
|
|
}
|
|
|
|
return isAuthorized;
|
|
}
|
|
|
|
public static bool ContainsRole(string roles, string roleName)
|
|
{
|
|
return roles.Split(';', StringSplitOptions.RemoveEmptyEntries).Contains(roleName);
|
|
}
|
|
|
|
public static bool ContainsRole(List<Permission> permissions, string permissionName, string roleName)
|
|
{
|
|
return permissions.Any(item => item.PermissionName == permissionName && item.RoleName == roleName);
|
|
}
|
|
|
|
public static bool ContainsUser(List<Permission> permissions, string permissionName, int userId)
|
|
{
|
|
return permissions.Any(item => item.PermissionName == permissionName && item.UserId == userId);
|
|
}
|
|
|
|
public static ClaimsIdentity CreateClaimsIdentity(Alias alias, User user, List<UserRole> userroles)
|
|
{
|
|
user.Roles = "";
|
|
foreach (UserRole userrole in userroles)
|
|
{
|
|
user.Roles += userrole.Role.Name + ";";
|
|
}
|
|
if (user.Roles != "") user.Roles = ";" + user.Roles;
|
|
return CreateClaimsIdentity(alias, user);
|
|
}
|
|
|
|
public static ClaimsIdentity CreateClaimsIdentity(Alias alias, User user)
|
|
{
|
|
ClaimsIdentity identity = new ClaimsIdentity(Constants.AuthenticationScheme);
|
|
if (alias != null && user != null && !user.IsDeleted)
|
|
{
|
|
identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
|
|
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()));
|
|
identity.AddClaim(new Claim(Constants.SiteKeyClaimType, alias.SiteKey));
|
|
if (ContainsRole(user.Roles, RoleNames.Host))
|
|
{
|
|
// host users are site admins by default
|
|
identity.AddClaim(new Claim(ClaimTypes.Role, RoleNames.Host));
|
|
identity.AddClaim(new Claim(ClaimTypes.Role, RoleNames.Admin));
|
|
identity.AddClaim(new Claim(ClaimTypes.Role, RoleNames.Registered));
|
|
}
|
|
foreach (string role in user.Roles.Split(';', StringSplitOptions.RemoveEmptyEntries))
|
|
{
|
|
if (!identity.Claims.Any(item => item.Type == ClaimTypes.Role && item.Value == role))
|
|
{
|
|
identity.AddClaim(new Claim(ClaimTypes.Role, role));
|
|
}
|
|
}
|
|
identity.AddClaim(new Claim(Constants.SecurityStampClaimType, user.SecurityStamp));
|
|
}
|
|
return identity;
|
|
}
|
|
|
|
[Obsolete("IsAuthorized(User user, string permissionName, string permissions) is deprecated. Use IsAuthorized(User user, string permissionName, List<Permission> permissionList) instead", false)]
|
|
public static bool IsAuthorized(User user, string permissionName, string permissions)
|
|
{
|
|
return IsAuthorized(user, JsonSerializer.Deserialize<List<Permission>>(permissions).Where(item => item.PermissionName == permissionName).ToList());
|
|
}
|
|
}
|
|
}
|