Files
cms_thermo_active/Thermo.Active/Attributes/SignalRAuthorizeAttribute.cs
T
2021-03-23 10:48:17 +01:00

150 lines
7.2 KiB
C#

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Microsoft.AspNet.SignalR.Owin;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using Thermo.Active.Config;
using Thermo.Active.Database.Controllers;
using Thermo.Active.Model.DatabaseModels;
using Thermo.Active.Utils;
using static Thermo.Active.Config.ServerConfig;
using static Thermo.Active.Listeners.SignalRStaticObjects;
using static Thermo.Active.Model.Constants;
namespace Thermo.Active.Attributes
{
public class SignalRAuthorizeAttribute : AuthorizeAttribute
{
public string FunctionAccess;
public ACTIONS Action;
public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
{
string token = request.QueryString["Authorization"];
using (SessionsController sessionsController = new SessionsController())
{
// Find user session on this machine
SessionModel session = sessionsController.FindSessionByToken(token);
if (session == null)
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | AuthorizeHubConnection | session == null");
return false;
}
}
return base.AuthorizeHubConnection(hubDescriptor, request);
}
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
var connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
var request = hubIncomingInvokerContext.Hub.Context.Request;
var token = request.QueryString.Get("Authorization");
if (!string.IsNullOrEmpty(token))
{
// check authorization
if (!CheckAuthorization(FunctionAccess, token, out int machineId, out int userId))
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | AuthorizeHubMethodInvocation | CheckAuthorization == false");
return false;
}
var claims = new ClaimsIdentity(AUTHENTICATION_TYPE);
claims.AddClaim(new Claim(USER_ID_KEY, userId.ToString()));
claims.AddClaim(new Claim(MACHINE_ID_KEY, machineId.ToString()));
Dictionary<string, object> _DCI = new Dictionary<string, object>();
_DCI.Add("server.User", claims as IPrincipal);
hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(_DCI), connectionId);
return true;
}
return false;
}
private bool CheckAuthorization(string functionName, string token, out int machineId, out int userId)
{
machineId = userId = 0;
using (SessionsController sessionsController = new SessionsController())
{
// Find user session on this machine
SessionModel session = sessionsController.FindSessionByToken(token);
if (session == null)
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | CheckAuthorization | session == null");
return false;
}
// Check if the machine is the same where the user logged in
if (session.MachineUser.MachineId != MachineConfig.MachineId)
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | CheckAuthorization | session.MachineUser.MachineId != MachineConfig.MachineId | " + session.MachineUser.MachineId + "," + MachineConfig.MachineId);
return false;
}
machineId = session.MachineUser.MachineId;
userId = session.MachineUser.UserId;
MachineUserModel machineUser = new MachineUserModel();
using (MachinesUsersController machineUsersController = new MachinesUsersController())
{
// Find machineUser data and joined to user data, role data, machine data
machineUser = machineUsersController.FindByIdWithData(session.MachineUserId);
}
using (FunctionsAccessController acController = new FunctionsAccessController())
{
// Read from db function levels
FunctionAccessModel functionAccess = acController.FindEnabledFunctionByName(functionName);
if (functionAccess != null && ServerConfigController.CheckAreaStatus(functionAccess.Area))
{
if (Action == ACTIONS.READ)
{ // Check read permissions
if (functionAccess.ReadLevelMin > machineUser.Role.Level)
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | CheckAuthorization | functionAccess.ReadLevelMin > machineUser.Role.Level | " + functionAccess.ReadLevelMin + "," + machineUser.Role.Level);
return false; // Not authorized
}
}
else
{ // Check write permissions
if (functionAccess.WriteLevelMin > machineUser.Role.Level)
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | CheckAuthorization | functionAccess.WriteLevelMin > machineUser.Role.Level | " + functionAccess.WriteLevelMin + "," + machineUser.Role.Level);
return false; // Not authorized
}
}
// Check if PLC bit exists
if (functionAccess.PlcId != 0)
{
// Check if functionality is enabled by PLC
var functionalityIsEnabled = LastRuntimeFunctionality.Where(x => x.Name == functionName).FirstOrDefault();
if (functionalityIsEnabled == null || functionalityIsEnabled.Enabled == false)
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | CheckAuthorization | functionalityIsEnabled == null || functionalityIsEnabled.Enabled == false | " + functionalityIsEnabled + "," + functionalityIsEnabled.Enabled);
return false; // Not authorized
}
}
}
else
{
ThermoActiveLogger.LogError($"SignalRAuthorizeAttribute | CheckAuthorization | functionAccess != null && ServerConfigController.CheckAreaStatus(functionAccess.Area) | " + functionAccess + "," + functionAccess.Area);
return false;
}
// Authorized
ThermoActiveLogger.LogInfo($"SignalRAuthorizeAttribute | CheckAuthorization | Authorized | ");
return true;
}
}
}
}
}