public async Task <IActionResult> EndpointLoginByNameAsync(string name, CancellationToken ct)
        {
            var endpoint = await _endpointService.GetEndpointByNameAsync(name, _userInfoService.UserId, ct);

            if (endpoint == null)
            {
                var client = new EndpointClientEntity
                {
                    ClientId   = _userInfoService.ClientId,
                    ClientType = _userInfoService.ClientType
                };

                var owner = new EndpointOwnerEntity
                {
                    IdentityId = _userInfoService.UserId,
                    OwnerName  = _userInfoService.Name
                };

                var hubConnection = new HubConnectionEntity
                {
                    ConnectionId = "",
                    Connected    = false
                };

                endpoint = await _endpointService.CreateEndpointAsync(name, client, owner, hubConnection, ct);

                if (endpoint == null)
                {
                    return(BadRequest(new ApiError("Cannot login, device cannot be created")));
                }
            }

            var endpointViewModel = Mapper.Map <EndpointViewModel>(endpoint);

            if (!Request.GetEtagHandler().NoneMatch(endpointViewModel))
            {
                return(StatusCode(304, endpointViewModel));
            }

            return(Ok(endpointViewModel));
        }
        public async Task <EndpointEntity> CreateEndpointAsync(string name,
                                                               EndpointClientEntity client,
                                                               EndpointOwnerEntity owner,
                                                               HubConnectionEntity hubConnection,
                                                               CancellationToken ct)
        {
            var endpoint = await _context.Endpoints.FirstOrDefaultAsync(
                r => (r.Owner.IdentityId == owner.IdentityId && r.Name == name),
                ct);

            /* Endpoint already exists so return null to indicate we failed to create new endpoint. */
            if (endpoint != null)
            {
                return(null);
            }

            var existingClient = await _context.Clients.FirstOrDefaultAsync(
                r => (r.ClientId == client.ClientId && r.ClientType == client.ClientType),
                ct);

            /* Ensure client exist */
            if (existingClient == null)
            {
                _context.Clients.Add(client);
            }

            var existingOwner = await _context.Owners.FirstOrDefaultAsync(
                r => (r.IdentityId == owner.IdentityId && r.OwnerName == owner.OwnerName),
                ct);

            /* Ensure owner exist */
            if (existingOwner == null)
            {
                _context.Owners.Add(owner);
            }

            if (existingClient == null || existingOwner == null)
            {
                var createdNavigationPropertiesResult = await _context.SaveChangesAsync(ct);

                if (createdNavigationPropertiesResult < 1)
                {
                    return(null);
                }

                if (existingClient == null)
                {
                    existingClient = await _context.Clients.FirstOrDefaultAsync(
                        r => (r.ClientId == client.ClientId && r.ClientType == client.ClientType),
                        ct);
                }

                if (existingOwner == null)
                {
                    existingOwner = await _context.Owners.FirstOrDefaultAsync(
                        r => (r.IdentityId == owner.IdentityId && r.OwnerName == owner.OwnerName),
                        ct);
                }
            }

            endpoint = new EndpointEntity
            {
                Name          = name,
                Description   = "No description.",
                Client        = existingClient,
                Owner         = existingOwner,
                HubConnection = hubConnection
            };

            _context.Endpoints.Add(endpoint);

            var created = await _context.SaveChangesAsync(ct);

            if (created < 1)
            {
                return(null);
            }

            /* Everything should be up to date now, so let's try again and return the endpoint. */
            endpoint = await _context.Endpoints
                       .Where(r => r.Name == name && r.Owner.IdentityId == existingOwner.IdentityId)
                       .Include(r => r.Owner)
                       .Include(r => r.Client)
                       .FirstOrDefaultAsync();

            return(endpoint);
        }