Beispiel #1
0
        private async Task <Dictionary <string, object> > CompileCloudStatus()
        {
            // We DRY now fam
            var status = await GetConfig(ConfigKeys.CloudConnectStatus);

            var identifier = await GetConfig(ConfigKeys.CloudConnectIdentifier);

            var nodeKey = await GetConfig(ConfigKeys.CloudConnectNodeKey);

            var responseObject = new Dictionary <string, object>
            {
                { "cloud", new Dictionary <string, object>
                  {
                      { "status", bool.Parse(status?.Value) },
                      { "id", identifier?.Value },
                      { "nodeKey", nodeKey?.Value }
                  } },
                {
                    "app", new Dictionary <string, object>
                    {
                        { "version", AppConfig.version },
                        { "restartNeeded", _restartNeeded },
                        { "environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "production" }
                    }
                },
                {
                    "system", new Dictionary <string, object>
                    {
                        { "data", _apm.GetAllDetails() },
                    }
                }
            };

            return(responseObject);
        }
        public void IsSerializable()
        {
            // Instantiate new APM
            var localApm = new Apm();

            // Get the details we need
            var details = localApm.GetAllDetails();

            // Here's what matters, can we serialize it?
            // Printed out too, so we can visually inspect output.
            Console.WriteLine(JsonConvert.SerializeObject(details, Formatting.Indented));
        }
Beispiel #3
0
        Connect(HttpContext httpContext, string nodeKey)
        {
            var errors = new Dictionary <string, object>();

            // Ok, we aren't already connected. Let's go try talking to the backend and set ourselves up.
            var request = new RestRequest("unauth/node", Method.POST)
            {
                RequestFormat = DataFormat.Json
            };

            var generatedPassword = PasswordUtils.GeneratePassword(24, 0);
            var body = new UnauthNodeAddRequest {
                InstallId = _identityProvider.GetGuid().ToString()
            };

            var ownIp = await _ipResolver.Resolve();

            body.Ip = ownIp.ToString();

            body.Port = httpContext.Connection.LocalPort;

            body.Protocol = "http"; // TODO: When HTTPs support lands, use -> httpContext.Request.Protocol.ToLower() which returns things like http/1.1 (needs further parsing);

            body.NodeKey     = nodeKey;
            body.AccessToken = _defaultCloudUserName + ":" + generatedPassword;

            // This is data about *THIS* specific system being contributed to the cloud/CRM.
            body.SystemData = _apm.GetAllDetails();
            body.Version    = AppConfig.version;

            // Ok, we got the user created. Everything is ready, let's send off the request.
            var serializedBody = JsonConvert.SerializeObject(body);

            _logger.LogDebug($"We will be sending: {serializedBody}");

            request.AddParameter("application/json; charset=utf-8", serializedBody, ParameterType.RequestBody);

            // We have to ensure this user actually exists before sending off the request.
            // First, we need to remove any cached representation.
            AuthUtils.ClearUserFromCacheIfExists(_cache, _defaultCloudUserName);

            // Check if the cloud connect user exists already.
            var user = await _db.SingleAsync <User>(x => x.AuthKey == _defaultCloudUserName) ?? new User();

            user.AuthKey        = _defaultCloudUserName;
            user.PasswordSetter = generatedPassword;
            user.EmailAddress   = _defaultCloudUserName + $"@spectero.com";
            user.FullName       = "Spectero Cloud Management User";
            user.Roles          = new List <User.Role> {
                User.Role.SuperAdmin
            };
            user.Source        = User.SourceTypes.SpecteroCloud;
            user.CloudSyncDate = DateTime.Now;
            user.CertKey       = PasswordUtils.GeneratePassword(48, 6);

            var userCertBytes = _cryptoService.IssueUserChain(user.AuthKey, new[] { KeyPurposeID.IdKPClientAuth }, user.CertKey);

            user.Cert = Convert.ToBase64String(userCertBytes);

            // Checks if user existed already, or is being newly created.
            if (user.Id != 0L)
            {
                await _db.UpdateAsync(user);
            }
            else
            {
                user.CreatedDate = DateTime.Now;
                await _db.InsertAsync(user);
            }

            var response = _restClient.Execute(request);


            if (response.ErrorException != null)
            {
                _logger.LogError(response.ErrorException, "CC: Connect attempt to the Spectero Cloud failed!");

                errors.Add(Core.Constants.Errors.FAILED_TO_CONNECT_TO_SPECTERO_CLOUD, response.ErrorMessage);

                await DeleteCloudUserIfExists();

                return(false, errors, HttpStatusCode.ServiceUnavailable, null);
            }

            CloudAPIResponse <Node> parsedResponse = null;

            try
            {
                // Parse after error checking.
                parsedResponse = JsonConvert.DeserializeObject <CloudAPIResponse <Node> >(response.Content);
            }
            catch (JsonException e)

            {
                // The Cloud Backend fed us bogus stuff, let's bail.
                _logger.LogError(e, "CC: Connect attempt to the Spectero Cloud failed!");
                _logger.LogDebug("Cloud API said: " + response.Content);

                errors.Add(Core.Constants.Errors.FAILED_TO_CONNECT_TO_SPECTERO_CLOUD, e.Message);

                await DeleteCloudUserIfExists();

                return(false, errors, HttpStatusCode.ServiceUnavailable, parsedResponse);
            }


            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (response.StatusCode)
            {
            case HttpStatusCode.Created:

                await ConfigUtils.CreateOrUpdateConfig(_db, ConfigKeys.CloudConnectStatus, true.ToString());

                await ConfigUtils.CreateOrUpdateConfig(_db, ConfigKeys.CloudConnectIdentifier, parsedResponse?.result.id.ToString());

                await ConfigUtils.CreateOrUpdateConfig(_db, ConfigKeys.CloudConnectNodeKey, nodeKey);

                break;

            default:
                // Likely a 400 or a 409, just show the response as is.
                errors.Add(Core.Constants.Errors.FAILED_TO_CONNECT_TO_SPECTERO_CLOUD, "");
                errors.Add(Core.Constants.Errors.RESPONSE_CODE, response.StatusCode);
                errors.Add(Core.Constants.Errors.NODE_PERSIST_FAILED, parsedResponse?.errors);

                _logger.LogDebug("Cloud API said: " + response.Content);

                await DeleteCloudUserIfExists();

                return(false, errors, HttpStatusCode.ServiceUnavailable, parsedResponse);
            }

            return(true, errors, HttpStatusCode.OK, parsedResponse);
        }