Пример #1
0
        private string GetToTemporaryFile(ScheduledImportConfig config)
        {
            var secureId = config.SicPasswordSecureId;
            var password = secureId != null?Factory.SecuredData.Read((Guid)secureId) : string.Empty;

            try
            {
                return(Factory.RemoteFileFetcher.GetToTemporaryFile(config.SicUrl, config.SicUsername, password));
            }
            catch (ConnectionException ex)
            {
                var message = $"Scheduled Import '{config.Name}' failed.\nDetails:\n   File: {config.SicUrl} \n   Message: {ex.Message}";
                EventLog.Application.WriteInformation(message);

                SecurityBypassContext.Elevate(() =>
                {
                    CreateFailedImportRunEntity(config, message);
                });

                return(null);
            }
            catch (Exception ex)
            {
                throw GenerateJobException(ex.Message, config);
            }
        }
Пример #2
0
        /// <summary>
        /// A deferred action will not occur until after the current context completes or until we hit a handleDefered.
        /// </summary>
        /// <param name="action"></param>
        public void DeferAction(Action action, bool runBeforeSave = false)
        {
            Action wrappedAction = action;

            if (SecurityBypassContext.IsActive)
            {
                wrappedAction = () => SecurityBypassContext.Elevate(action);
            }

            if (this == _rootContext)
            {
                throw new ArgumentException("action");
            }

            if (HandleDeferred || _parentContext == null)
            {
                var queue = runBeforeSave ? _deferredBeforeActions : _deferredAfterActions;

                queue.Enqueue(wrappedAction);
            }
            else
            {
                _parentContext.DeferAction(wrappedAction, runBeforeSave);
            }
        }
Пример #3
0
        public void Test_Elevate()
        {
            bool elevated;

            elevated = false;
            SecurityBypassContext.Elevate(() => elevated = SecurityBypassContext.IsActive);
            Assert.That(elevated, Is.True, "Not elevated");
        }
Пример #4
0
        public void Test_NoBypassContext()
        {
            bool elevated;

            elevated = false;
            SecurityBypassContext.Elevate(() => elevated = SecurityBypassContext.IsActive);
            Assert.That(elevated, Is.True, "Elevate is not elevated");
            SecurityBypassContext.RunAsUser(() => elevated = SecurityBypassContext.IsActive);
            Assert.That(elevated, Is.False, "RunAsUser is elevated");
        }
Пример #5
0
        /// <summary>
        /// Send the notifications on a background thread.
        /// </summary>
        void SendMessagesInBackground(IRunState context, long notificationId, List <long> userIds, bool waitForReplies)
        {
            context.SetPostRunAction(() =>
            {
                var runId = context.WorkflowRunId;

                WorkflowRunContext.Current.QueueAction(() =>
                                                       SecurityBypassContext.Elevate(() =>
                {
                    var workflowRunner = Factory.Current.Resolve <IWorkflowRunner>();
                    WorkflowRun run    = Entity.Get <WorkflowRun>(runId);;

                    try
                    {
                        var notification = Entity.Get <Notification>(notificationId);
                        var users        = Entity.Get(userIds);

                        Factory.Current.Resolve <INotifier>().Send(notification, users, true);
                        var sends            = notification.SendRecords;
                        var sentWithoutError = sends.Where(r => r.SrErrorMessage == null);

                        // update the notification

                        bool resume = true;
                        if (waitForReplies)
                        {
                            notification             = notification.AsWritable <Notification>();
                            notification.NPendingRun = run;
                            notification.Save();

                            resume = notification.Complete(); // Just in case all the replies were completed while we were sending.
                        }

                        if (resume && run != null)
                        {
                            workflowRunner.ResumeWorkflow(run, new NotifyResumeEvent());
                        }
                    }
                    catch
                    {
                        if (run != null)
                        {
                            workflowRunner.ResumeWorkflow(run, new NotifyResumeFailedEvent());
                        }

                        throw;
                    }
                }));
            });
        }
Пример #6
0
        public void Test_ChangePassword(Func <UserAccount> userAccountFactory, string oldPassword, string newPassword, HttpStatusCode expectedHttpStatusCode, string expectedMessage)
        {
            UserAccount     userAccount;
            HttpWebResponse response;
            HttpError       httpError;

            userAccount = null;
            try
            {
                using (new SecurityBypassContext())
                {
                    userAccount = userAccountFactory();
                }
                using (PlatformHttpRequest loginRequest = new PlatformHttpRequest("data/v1/login/spchangepassword", PlatformHttpMethod.Post,
                                                                                  doNotAuthenticate: true))
                {
                    loginRequest.PopulateBody(new JsonPasswordChangeRequest
                    {
                        Username    = userAccount.Name,
                        OldPassword = oldPassword,
                        NewPassword = newPassword,
                        Tenant      = RequestContext.GetContext().Tenant.Name
                    });

                    response = loginRequest.GetResponse();
                    Assert.That(response, Has.Property("StatusCode").EqualTo(expectedHttpStatusCode));

                    if (expectedMessage != null)
                    {
                        httpError = loginRequest.DeserialiseResponseBody <HttpError>();
                        Assert.That(httpError, Has.Property("Message").EqualTo(expectedMessage));
                    }
                }
            }
            finally
            {
                if (userAccount != null)
                {
                    try
                    {
                        SecurityBypassContext.Elevate(() => Entity.Delete(userAccount));
                    }
                    catch (Exception)
                    {
                        // Ignore errors
                    }
                }
            }
        }
Пример #7
0
        public void Test_InvalidLogin(Func <UserAccount> userAccountFactory, string password, HttpStatusCode expectedHttpStatusCode, string expectedMessage)
        {
            UserAccount     userAccount;
            HttpWebResponse response;
            HttpError       httpError;

            userAccount = null;
            try
            {
                using (new SecurityBypassContext())
                {
                    userAccount = userAccountFactory();
                }
                using (PlatformHttpRequest loginRequest = new PlatformHttpRequest("data/v1/login/spsignin", PlatformHttpMethod.Post,
                                                                                  doNotAuthenticate: true))
                {
                    loginRequest.PopulateBody(new JsonLoginCredential
                    {
                        Username   = userAccount.Name,
                        Password   = password,
                        Tenant     = RequestContext.GetContext().Tenant.Name,
                        Persistent = false
                    });

                    response = loginRequest.GetResponse();
                    Assert.That(response, Has.Property("StatusCode").EqualTo(expectedHttpStatusCode));

                    if (expectedMessage != null)
                    {
                        httpError = loginRequest.DeserialiseResponseBody <HttpError>();
                        Assert.That(httpError, Has.Property("Message").EqualTo(expectedMessage));
                    }
                }
            }
            finally
            {
                if (userAccount != null)
                {
                    try
                    {
                        SecurityBypassContext.Elevate(() => Entity.Delete(userAccount));
                    }
                    catch (Exception)
                    {
                        // Do nothing on an error. This is just clean up code.
                    }
                }
            }
        }
Пример #8
0
        public void Test_OneBypassContext()
        {
            bool elevated;

            elevated = false;
            using (new SecurityBypassContext())
            {
                Assert.That(SecurityBypassContext.IsActive, Is.True, "Not active");

                SecurityBypassContext.Elevate(() => elevated = SecurityBypassContext.IsActive);
                Assert.That(elevated, Is.True, "Elevate is not elevated");

                SecurityBypassContext.RunAsUser(() => elevated = SecurityBypassContext.IsActive);
                Assert.That(elevated, Is.False, "RunAsUser is elevated");
            }
        }
Пример #9
0
        /// <summary>
        ///     Begin task to import spreadsheet data.
        /// </summary>
        /// <param name="importSettings">The settings of the import.</param>
        /// <returns>Returns the ID of the import run.</returns>
        public long StartImport(ImportSettings importSettings)
        {
            // Validate
            if (importSettings == null)
            {
                throw new ArgumentNullException(nameof(importSettings));
            }
            if (string.IsNullOrEmpty(importSettings.FileToken))
            {
                throw new ArgumentException("importSettings.FileToken");
            }

            // Load the config
            ImportConfig importConfig = SecurityBypassContext.ElevateIf(
                importSettings.SuppressSecurityCheckOnImportConfig,
                () => _entityRepository.Get <ImportConfig>(importSettings.ImportConfigId));

            if (importConfig == null)
            {
                throw new ArgumentException("importSettings.ImportConfigId");
            }

            // Create a new import run
            ImportRun importRun = CreateImportRunEntity(importConfig, importSettings);

            SecurityBypassContext.Elevate(importRun.Save);

            long importRunId = importRun.Id;

            try
            {
                _asyncRunner.Start(() => _importRunWorker.StartImport(importRunId));
            }
            catch
            {
                // Async operation failed to start
                // (This is not reached if the import itself fails)
                importRun.ImportRunStatus_Enum = WorkflowRunState_Enumeration.WorkflowRunFailed;
                importRun.ImportMessages       = "Failed to start importer.";
                SecurityBypassContext.Elevate(importRun.Save);
                throw;
            }

            return(importRun.Id);
        }
Пример #10
0
        /// <summary>
        /// Process the request.
        /// </summary>
        /// <remarks>
        /// Assumes that user context has already been set.
        /// </remarks>
        /// <param name="request"></param>
        /// <param name="endpoint"></param>
        /// <returns></returns>
        public ConnectorResponse HandleRequest(ConnectorRequest request, ApiResourceEndpoint endpoint)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            if (endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }

            // Get resource mapping object
            ApiResourceMapping mapping = GetResourceMapping(endpoint);

            // Disable triggers if applicable
            bool disableTriggers;

            using (new SecurityBypassContext())
            {
                disableTriggers = mapping.MappingSuppressWorkflows == true;
            }

            using (new WorkflowRunContext {
                DisableTriggers = disableTriggers
            })
            {
                // Handle verbs
                if (request.Verb == ConnectorVerb.Post && SecurityBypassContext.Elevate(() => endpoint.EndpointCanCreate == true))
                {
                    return(HandlePost(request, mapping));
                }

                if (request.Verb == ConnectorVerb.Put && SecurityBypassContext.Elevate(() => endpoint.EndpointCanUpdate == true))
                {
                    return(HandlePut(request, mapping));
                }

                if (request.Verb == ConnectorVerb.Delete && SecurityBypassContext.Elevate(() => endpoint.EndpointCanDelete == true))
                {
                    return(HandleDelete(request, mapping));
                }

                return(new ConnectorResponse(HttpStatusCode.MethodNotAllowed));
            }
        }
Пример #11
0
        /// <summary>
        /// Given a text expression and runtimeArgs, evaluate the expression.
        /// Expressions must be compatible with DataColumn.Expression. the result is cast to T
        /// </summary>
        public object EvaluateExpression(WfExpression expression)
        {
            using (Profiler.Measure("RunStateBase.EvaluateExpression"))
            {
                ExprType targetType = null;

                SecurityBypassContext.Elevate(() => targetType = Metadata.GetExpressionType(expression));

                var result = expression.EvaluateExpression(this);

                // force any lists to be resolved to prevent lazy evaluation in a different security context and get rid of the nulls
                if (targetType.IsList && result != null)
                {
                    result = ((IEnumerable <IEntity>)result).Where(e => e != null).ToList <IEntity>();
                }

                return(result);
            }
        }
Пример #12
0
 public void Test_Elevate_NullAction()
 {
     Assert.That(() => SecurityBypassContext.Elevate(null),
                 Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("action"));
 }
Пример #13
0
        public override void Execute(EntityRef scheduledItemRef)
        {
            string logMessage = null;
            bool   failed     = true;

            var scheduledExportConfig = Entity.Get <ScheduledExportConfig>(scheduledItemRef, ScheduledExportConfig.Name_Field);

            if (scheduledExportConfig == null)
            {
                throw GenerateJobException("Unexpected error, ScheduleItemRef is not a ScheduledExportConfig.", null);
            }



            try
            {
                var report = scheduledExportConfig.SecReport;

                if (report == null)
                {
                    throw new ExpectedErrorCondition("Failed to import, no report configuration provided.");
                }

                var url = scheduledExportConfig.SicUrl;

                if (String.IsNullOrEmpty(url))
                {
                    throw new ExpectedErrorCondition("Failed to export, no FTP address provided.");
                }

                var username = scheduledExportConfig.SicUsername;

                if (String.IsNullOrEmpty(username))
                {
                    throw new ExpectedErrorCondition("Failed to export, no username provided.");
                }

                var secureId = scheduledExportConfig.SicPasswordSecureId;
                var password = secureId != null?Factory.SecuredData.Read((Guid)secureId) : string.Empty;

                var format = scheduledExportConfig.SecFileType_Enum;

                if (format == null)
                {
                    throw new ExpectedErrorCondition("Failed to export, no file format type provided.");
                }

                var fileformat = ConvertFileFormat(format);

                var exportInterface = Factory.Current.Resolve <IExportDataInterface>();

                var exportInfo = exportInterface.ExportData(report.Id, new ExportSettings {
                    Format = fileformat, TimeZone = null                                                                         /* UTC */
                });

                var fileFetcher = Factory.Current.Resolve <IRemoteFileFetcher>();

                fileFetcher.PutFromTemporaryFile(exportInfo.FileHash, url, username, password);

                logMessage = "Success";
                failed     = false;
            }


            catch (ExpectedErrorCondition ex)
            {
                logMessage = ex.Message;
                // expected exception swallowed, log message generated in finally
            }
            catch (ConnectionException ex)
            {
                logMessage = ex.Message;
                // expected exception swallowed, log message generated in finally
            }
            catch (PlatformSecurityException ex)
            {
                logMessage = ex.Message;
                // expected exception swallowed, log message generated in finally
            }
            catch (JobExecutionException ex)
            {
                EventLog.Application.WriteError("StartImportJob.Execute: Unexpected exception thrown: {0}", ex);

                logMessage = "Failed with an internal error.";
                throw;
            }

            catch (Exception ex)
            {
                EventLog.Application.WriteError("StartImportJob.Execute: Unexpected exception thrown: {0}", ex);
                logMessage = "Failed with an internal error.";
                throw GenerateJobException("Unexpected exception when performing scheduled import.", scheduledExportConfig);
            }
            finally
            {
                EventLog.Application.WriteTrace($"{scheduledExportConfig.Id} {(failed ? "Fail" : "Success")}: {logMessage}");

                SecurityBypassContext.Elevate(() =>
                {
                    var logEntry = new TenantLogEntry
                    {
                        Name                  = $"Schedule Export: {scheduledExportConfig.Name ?? "[Unnamed]"}",
                        Description           = logMessage,
                        LogEntrySeverity_Enum = failed ? LogSeverityEnum_Enumeration.ErrorSeverity : LogSeverityEnum_Enumeration.InformationSeverity,
                        LogEventTime          = DateTime.Now
                    };
                    logEntry.GetRelationships("core:secRunLog", Direction.Reverse).Add(scheduledExportConfig);
                    logEntry.Save();
                });
            }
        }