<commit_before>﻿using System;
using DeviceHive.Core;
using DeviceHive.Core.Mapping;
using DeviceHive.Core.Messaging;
using DeviceHive.Data.Model;
using DeviceHive.WebSockets.Network;
using DeviceHive.WebSockets.Subscriptions;
using Newtonsoft.Json.Linq;
using Ninject;

namespace DeviceHive.WebSockets.Controllers
{
	public class ClientController : ControllerBase
	{
	    #region Private fields

	    private readonly SubscriptionManager _subscriptionManager;
	    private readonly MessageBus _messageBus;

	    #endregion

		#region Constructor

		public ClientController(DataContext dataContext, WebSocketServerBase server,
			JsonMapperManager jsonMapperManager,
			[Named("DeviceNotification")] SubscriptionManager subscriptionManager,
			MessageBus messageBus) :
			base(dataContext, server, jsonMapperManager)
		{
			_subscriptionManager = subscriptionManager;
			_messageBus = messageBus;
		}

		#endregion

		#region Properties

		private User CurrentUser
		{
			get { return (User) Connection.Session["user"]; }
			set { Connection.Session["user"] = value; }
		}

		#endregion

		#region Methods

		#region Actions

		protected override void InvokeActionImpl()
		{
			if (CurrentUser == null && ActionName != "authenticate")
				return;

			switch (ActionName)
			{
				case "authenticate":
					Authenticate();
					break;

				case "command/insert":
					InsertDeviceCommand();
					break;

				case "command/update":
					UpdateDeviceCommand();
					break;

				case "notification/subscribe":
					SubsrcibeToDeviceNotifications();
					break;

				case "notification/unsubscribe":
					UnsubsrcibeFromDeviceNotifications();
					break;
			}
		}		
		
		private void Authenticate()
		{
			var login = (string) ActionArgs["login"];
			var password = (string) ActionArgs["password"];

			var user = DataContext.User.Get(login);
			if (user == null || !user.IsValidPassword(password))
				throw new WebSocketRequestException("Invalid login or password");

			CurrentUser = user;
			SendSuccessResponse();
		}

		private void InsertDeviceCommand()
		{
			var deviceGuid = Guid.Parse((string) ActionArgs["deviceGuid"]);
			var commandObj = (JObject) ActionArgs["device"];

			var device = DataContext.Device.Get(deviceGuid);
			if (device == null) // todo: check that user has access to this device
				throw new WebSocketRequestException("Device not found");

			var command = CommandMapper.Map(commandObj);
			command.Device = device;
			// todo: command validation

			DataContext.DeviceCommand.Save(command);
			_messageBus.Notify(new DeviceCommandAddedMessage(deviceGuid, command.ID));
			
			commandObj = CommandMapper.Map(command);
			SendResponse(new JProperty("command", commandObj));
		}

		private void UpdateDeviceCommand()
		{
		    var deviceGuid = Guid.Parse((string) ActionArgs["deviceGuid"]);
		    var commandId = (int) ActionArgs["commandId"];
            var commandObj = (JObject)ActionArgs["device"];

            var device = DataContext.Device.Get(deviceGuid);
            if (device == null) // todo: check that user has access to this device
                throw new WebSocketRequestException("Device not found");

            var command = DataContext.DeviceCommand.Get(commandId);
            if (command == null || command.DeviceID != device.ID)
                throw new WebSocketRequestException("Device command not found");

            CommandMapper.Apply(command, commandObj);
		    command.Device = device;
            // todo: command validation

            DataContext.DeviceCommand.Save(command);

            commandObj = CommandMapper.Map(command);
            SendResponse(new JProperty("command", commandObj));
		}

		private void SubsrcibeToDeviceNotifications()
		{
			var deviceGuids = ParseDeviceGuids();
			foreach (var deviceGuid in deviceGuids)
				_subscriptionManager.Subscribe(Connection, deviceGuid);

			SendSuccessResponse();
		}

		private void UnsubsrcibeFromDeviceNotifications()
		{
			var deviceGuids = ParseDeviceGuids();
			foreach (var deviceGuid in deviceGuids)
				_subscriptionManager.Unsubscribe(Connection, deviceGuid);

			SendSuccessResponse();
		}

		#endregion

		#region Notification handling

		public void HandleDeviceNotification(Guid deviceGuid, int notificationId)
		{
			var notification = DataContext.DeviceNotification.Get(notificationId);
			var connections = _subscriptionManager.GetConnections(deviceGuid);

			foreach (var connection in connections)
				Notify(connection, notification);
		}

        public void CleanupNotifications(WebSocketConnectionBase connection)
        {
            _subscriptionManager.Cleanup(connection);
        }

		private void Notify(WebSocketConnectionBase connection, DeviceNotification notification)
		{
			// todo: check connection user and his access to the device

			SendResponse(connection, "notification/notify",
				new JProperty("notification", NotificationMapper.Map(notification)));
		}

		#endregion

        #region Helper methods

        #endregion

        #endregion
    }
}<commit_msg>User access to device checking added<commit_after>﻿using System;
using System.Linq;
using DeviceHive.Core;
using DeviceHive.Core.Mapping;
using DeviceHive.Core.Messaging;
using DeviceHive.Data.Model;
using DeviceHive.WebSockets.Network;
using DeviceHive.WebSockets.Subscriptions;
using Newtonsoft.Json.Linq;
using Ninject;

namespace DeviceHive.WebSockets.Controllers
{
	public class ClientController : ControllerBase
	{
	    #region Private fields

	    private readonly SubscriptionManager _subscriptionManager;
	    private readonly MessageBus _messageBus;

	    #endregion

		#region Constructor

		public ClientController(DataContext dataContext, WebSocketServerBase server,
			JsonMapperManager jsonMapperManager,
			[Named("DeviceNotification")] SubscriptionManager subscriptionManager,
			MessageBus messageBus) :
			base(dataContext, server, jsonMapperManager)
		{
			_subscriptionManager = subscriptionManager;
			_messageBus = messageBus;
		}

		#endregion

		#region Properties

		private User CurrentUser
		{
			get { return (User) Connection.Session["user"]; }
			set { Connection.Session["user"] = value; }
		}

		#endregion

		#region Methods

		#region Actions

		protected override void InvokeActionImpl()
		{
			if (CurrentUser == null && ActionName != "authenticate")
				return;

			switch (ActionName)
			{
				case "authenticate":
					Authenticate();
					break;

				case "command/insert":
					InsertDeviceCommand();
					break;

				case "command/update":
					UpdateDeviceCommand();
					break;

				case "notification/subscribe":
					SubsrcibeToDeviceNotifications();
					break;

				case "notification/unsubscribe":
					UnsubsrcibeFromDeviceNotifications();
					break;
			}
		}		
		
		private void Authenticate()
		{
			var login = (string) ActionArgs["login"];
			var password = (string) ActionArgs["password"];

			var user = DataContext.User.Get(login);
			if (user == null || !user.IsValidPassword(password))
				throw new WebSocketRequestException("Invalid login or password");

			CurrentUser = user;
			SendSuccessResponse();
		}

		private void InsertDeviceCommand()
		{
			var deviceGuid = Guid.Parse((string) ActionArgs["deviceGuid"]);
			var commandObj = (JObject) ActionArgs["device"];

			var device = DataContext.Device.Get(deviceGuid);
			if (device == null || !IsNetworkAccessible(device.NetworkID))
				throw new WebSocketRequestException("Device not found");

			var command = CommandMapper.Map(commandObj);
			command.Device = device;
			// todo: command validation

			DataContext.DeviceCommand.Save(command);
			_messageBus.Notify(new DeviceCommandAddedMessage(deviceGuid, command.ID));
			
			commandObj = CommandMapper.Map(command);
			SendResponse(new JProperty("command", commandObj));
		}

		private void UpdateDeviceCommand()
		{
		    var deviceGuid = Guid.Parse((string) ActionArgs["deviceGuid"]);
		    var commandId = (int) ActionArgs["commandId"];
            var commandObj = (JObject)ActionArgs["device"];

            var device = DataContext.Device.Get(deviceGuid);
            if (device == null || !IsNetworkAccessible(device.NetworkID))
                throw new WebSocketRequestException("Device not found");

            var command = DataContext.DeviceCommand.Get(commandId);
            if (command == null || command.DeviceID != device.ID)
                throw new WebSocketRequestException("Device command not found");

            CommandMapper.Apply(command, commandObj);
		    command.Device = device;
            // todo: command validation

            DataContext.DeviceCommand.Save(command);

            commandObj = CommandMapper.Map(command);
            SendResponse(new JProperty("command", commandObj));
		}

		private void SubsrcibeToDeviceNotifications()
		{
			var deviceGuids = ParseDeviceGuids();
			foreach (var deviceGuid in deviceGuids)
				_subscriptionManager.Subscribe(Connection, deviceGuid);

			SendSuccessResponse();
		}

		private void UnsubsrcibeFromDeviceNotifications()
		{
			var deviceGuids = ParseDeviceGuids();
			foreach (var deviceGuid in deviceGuids)
				_subscriptionManager.Unsubscribe(Connection, deviceGuid);

			SendSuccessResponse();
		}

		#endregion

		#region Notification handling

		public void HandleDeviceNotification(Guid deviceGuid, int notificationId)
		{
			var notification = DataContext.DeviceNotification.Get(notificationId);
		    var device = DataContext.Device.Get(deviceGuid);
			var connections = _subscriptionManager.GetConnections(deviceGuid);

			foreach (var connection in connections)
				Notify(connection, notification, device);
		}

        public void CleanupNotifications(WebSocketConnectionBase connection)
        {
            _subscriptionManager.Cleanup(connection);
        }

		private void Notify(WebSocketConnectionBase connection, DeviceNotification notification, Device device)
		{
		    var user = (User) connection.Session["user"];
            if (user == null || !IsNetworkAccessible(device.NetworkID, user))
                return;

			SendResponse(connection, "notification/notify",
				new JProperty("notification", NotificationMapper.Map(notification)));
		}

		#endregion

        #region Helper methods

        private bool IsNetworkAccessible(int networkId, User user = null)
        {
            if (user == null)
                user = CurrentUser;

            if (user.Role == (int) UserRole.Administrator)
                return true;

            var userNetworks = DataContext.UserNetwork.GetByUser(user.ID);
            return userNetworks.Any(un => un.NetworkID == networkId);
        }

        #endregion

        #endregion
    }
}
{'fraction_non_alphanumeric': 0.09379400995211717, 'fraction_numerical': 0.0, 'mean_word_length': 3.5894011202068072, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6743286', 'n_tokens_mistral': 3261, 'n_tokens_neox': 2749, 'n_words': 674}