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); } }
/// <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); } }
public void Test_Elevate() { bool elevated; elevated = false; SecurityBypassContext.Elevate(() => elevated = SecurityBypassContext.IsActive); Assert.That(elevated, Is.True, "Not elevated"); }
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"); }
/// <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; } })); }); }
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 } } } }
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. } } } }
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"); } }
/// <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); }
/// <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)); } }
/// <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); } }
public void Test_Elevate_NullAction() { Assert.That(() => SecurityBypassContext.Elevate(null), Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("action")); }
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(); }); } }