Ejemplo n.º 1
0
        /// <inheritdoc />
        public async Task <BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            IBridgeHandler bridgeHandler = null;

            for (var i = 0; bridgeHandler == null && i < 30; ++i)
            {
                // There's a miniscule time period where we could potentially receive a bridge request and not have the registration ready when we launch DD
                // This is a stopgap
                Task delayTask = Task.CompletedTask;
                lock (bridgeHandlers)
                    if (!bridgeHandlers.TryGetValue(parameters.AccessIdentifier, out bridgeHandler))
                    {
                        delayTask = asyncDelayer.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
                    }

                await delayTask.ConfigureAwait(false);
            }

            if (bridgeHandler == null)
            {
                lock (bridgeHandlers)
                    if (!bridgeHandlers.TryGetValue(parameters.AccessIdentifier, out bridgeHandler))
                    {
                        logger.LogWarning("Recieved invalid bridge request with accees identifier: {0}", parameters.AccessIdentifier);
                        return(null);
                    }
            }

            return(await bridgeHandler.ProcessBridgeRequest(parameters, cancellationToken).ConfigureAwait(false));
        }
Ejemplo n.º 2
0
 /// <inheritdoc />
 public Task <BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
 {
     if (parameters == null)
     {
         throw new ArgumentNullException(nameof(parameters));
     }
        /// <inheritdoc />
        public async Task <BridgeResponse> ProcessBridgeRequest(BridgeParameters parameters, CancellationToken cancellationToken)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            var response = new BridgeResponse();

            switch (parameters.CommandType)
            {
            case BridgeCommandType.ChatSend:
                if (parameters.ChatMessage == null)
                {
                    return new BridgeResponse
                           {
                               ErrorMessage = "Missing chatMessage field!"
                           }
                }
                ;

                if (parameters.ChatMessage.ChannelIds == null)
                {
                    return new BridgeResponse
                           {
                               ErrorMessage = "Missing channelIds field in chatMessage!"
                           }
                }
                ;

                if (parameters.ChatMessage.ChannelIds.Any(channelIdString => !UInt64.TryParse(channelIdString, out var _)))
                {
                    return new BridgeResponse
                           {
                               ErrorMessage = "Invalid channelIds in chatMessage!"
                           }
                }
                ;

                if (parameters.ChatMessage.Text == null)
                {
                    return new BridgeResponse
                           {
                               ErrorMessage = "Missing message field in chatMessage!"
                           }
                }
                ;

                await chat.SendMessage(
                    parameters.ChatMessage.Text,
                    parameters.ChatMessage.ChannelIds.Select(UInt64.Parse),
                    cancellationToken).ConfigureAwait(false);

                break;

            case BridgeCommandType.Prime:
                var oldPrimeTcs = primeTcs;
                primeTcs = new TaskCompletionSource <object>();
                oldPrimeTcs.SetResult(null);
                break;

            case BridgeCommandType.Kill:
                logger.LogInformation("Bridge requested process termination!");
                TerminationWasRequested = true;
                process.Terminate();
                break;

            case BridgeCommandType.PortUpdate:
                lock (synchronizationLock)
                {
                    if (!parameters.CurrentPort.HasValue)
                    {
                        /////UHHHH
                        logger.LogWarning("DreamDaemon sent new port command without providing it's own!");
                        return(new BridgeResponse
                        {
                            ErrorMessage = "Missing stringified port as data parameter!"
                        });
                    }

                    var currentPort = parameters.CurrentPort.Value;

                    if (!nextPort.HasValue)
                    {
                        reattachInformation.Port = parameters.CurrentPort.Value;                                 // not ready yet, so what we'll do is accept the random port DD opened on for now and change it later when we decide to
                    }
                    else
                    {
                        // nextPort is ready, tell DD to switch to that
                        // if it fails it'll kill itself
                        response.NewPort         = nextPort.Value;
                        reattachInformation.Port = nextPort.Value;
                        nextPort = null;

                        // we'll also get here from SetPort so complete that task
                        var tmpTcs = portAssignmentTcs;
                        portAssignmentTcs = null;
                        tmpTcs.SetResult(true);
                    }

                    portClosedForReboot = false;
                }

                break;

            case BridgeCommandType.Startup:
                apiValidationStatus = ApiValidationStatus.BadValidationRequest;
                if (parameters.Version == null)
                {
                    return new BridgeResponse
                           {
                               ErrorMessage = "Missing dmApiVersion field!"
                           }
                }
                ;

                DMApiVersion = parameters.Version;
                switch (parameters.MinimumSecurityLevel)
                {
                case DreamDaemonSecurity.Ultrasafe:
                    apiValidationStatus = ApiValidationStatus.RequiresUltrasafe;

                    break;

                case DreamDaemonSecurity.Safe:
                    apiValidationStatus = ApiValidationStatus.RequiresSafe;
                    break;

                case DreamDaemonSecurity.Trusted:
                    apiValidationStatus = ApiValidationStatus.RequiresTrusted;
                    break;

                case null:
                    return(new BridgeResponse
                    {
                        ErrorMessage = "Missing minimumSecurityLevel field!"
                    });

                default:
                    return(new BridgeResponse
                    {
                        ErrorMessage = "Invalid minimumSecurityLevel!"
                    });
                }

                response.RuntimeInformation = reattachInformation.RuntimeInformation;

                // Load custom commands
                chatTrackingContext.CustomCommands = parameters.CustomCommands;
                break;

            case BridgeCommandType.Reboot:
                if (ClosePortOnReboot)
                {
                    chatTrackingContext.Active = false;
                    response.NewPort           = 0;
                    portClosedForReboot        = true;
                }

                var oldRebootTcs = rebootTcs;
                rebootTcs = new TaskCompletionSource <object>();
                oldRebootTcs.SetResult(null);
                break;

            case null:
                response.ErrorMessage = "Missing commandType!";
                break;

            default:
                response.ErrorMessage = "Requested commandType not supported!";
                break;
            }

            return(response);
        }