Esempio n. 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);
            }
        }
        /// <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);
            }
        }
Esempio n. 3
0
        bool EvaluateForwardTriggers(IResourceTriggerFilterPolicyCache policyCache, IEntity entity, IEnumerable <long> changedFields, IEnumerable <long> changedRels, IEnumerable <long> changedRevRels, List <Action> postSaveActions)
        {
            using (Profiler.Measure("ResourceTriggerFilterEventTarget.EvaluateForwardTriggers"))
            {
                var typeId = entity.TypeIds.FirstOrDefault();

                if (typeId != 0)
                {
                    List <ResourceTriggerFilterDef> policies;
                    if (policyCache.TypePolicyMap.TryGetValue(typeId, out policies))
                    {
                        if (policies.Any())
                        {
                            // we match on type
                            var allChanges = changedFields.Union(changedRels).Union(changedRevRels);

                            //
                            // Check if our entity matches any of the fields and rels
                            foreach (var policy in policies)
                            {
                                if (policy == null)
                                {
                                    continue; // assert false
                                }
                                var watchedFields = policyCache.PolicyToFieldsMap[policy.Id];
                                if (!watchedFields.Any() || watchedFields.Intersect(allChanges).Any())
                                {
                                    var handler = policyCache.PolicyTypeHandlerMap[policy.TypeIds.First()];

                                    if (handler != null)
                                    {
                                        var isNew = entity.IsTemporaryId;

                                        bool result = false;
                                        SecurityBypassContext.RunAsUser(() =>
                                        {
                                            if (handler.OnBeforeSave(policy, entity, isNew, changedFields, changedRels, changedRevRels))
                                            {
                                                result = true;
                                            }
                                            else
                                            {
                                                AddWrappedPostSaveAction(postSaveActions, () => handler.OnAfterSave(policy, entity, isNew, changedFields, changedRels, changedRevRels));
                                            }
                                        });

                                        if (result)
                                        {
                                            return(true);        // We failed, so bug out
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Is there an access rule for the specified type(s) that includes the requested permission? E.g. create.
        /// </summary>
        /// <param name="entityType">
        /// The <see cref="EntityType"/> to check. This cannot be null.
        /// </param>
        /// <param name="permission">The permission being sought.</param>
        /// <param name="user"> The user requesting access. This cannot be null. </param>
        /// <returns>
        /// True if the user can create entities of that type, false if not.
        /// </returns>
        private bool CheckTypeAccess(EntityType entityType, EntityRef permission, EntityRef user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (entityType == null)
            {
                throw new ArgumentNullException(nameof(entityType));
            }

            List <EntityType> entityTypesToCheck;
            bool result;

            using (new SecurityBypassContext())
                using (Profiler.MeasureAndSuppress("SecuresFlagEntityAccessControlChecker.CheckTypeAccess"))
                {
                    // Check if the type itself can be created
                    using (MessageContext messageContext = new MessageContext(EntityAccessControlService.MessageName))
                    {
                        messageContext.Append(() => "Checking access rules first:");

                        IDictionary <long, bool> resultAsDict     = null;
                        List <EntityType>        entityTypeAsList = new List <EntityType> {
                            entityType
                        };
                        SecurityBypassContext.RunAsUser(() =>
                                                        resultAsDict = Checker.CheckTypeAccess(entityTypeAsList, permission, user));

                        result = resultAsDict [entityType.Id];

                        if (result)
                        {
                            return(result);
                        }
                    }

                    // Walk graph to get list of types to check
                    entityTypesToCheck = ReachableTypes(entityType.ToEnumerable( ), true, false)
                                         .Select(walkStep => walkStep.Node)
                                         .Where(et => et != entityType) // skip root type.
                                         .ToList( );

                    result = CheckTypeAccessRelatedTypesImpl(entityType, permission, user, entityTypesToCheck);
                    if (!result)
                    {
                        return(false);
                    }

                    // Register cache invalidations
                    using (CacheContext cacheContext = CacheContext.GetContext( ))
                    {
                        cacheContext.EntityTypes.Add(WellKnownAliases.CurrentTenant.Relationship);
                        cacheContext.FieldTypes.Add(WellKnownAliases.CurrentTenant.SecuresFrom, WellKnownAliases.CurrentTenant.SecuresTo, WellKnownAliases.CurrentTenant.SecuresFromReadOnly, WellKnownAliases.CurrentTenant.SecuresToReadOnly);
                    }
                }

            return(result);
        }
Esempio n. 5
0
        public void Test_Elevate()
        {
            bool elevated;

            elevated = false;
            SecurityBypassContext.Elevate(() => elevated = SecurityBypassContext.IsActive);
            Assert.That(elevated, Is.True, "Not elevated");
        }
Esempio n. 6
0
        public void Test_RunAsUser()
        {
            bool elevated;

            elevated = false;
            SecurityBypassContext.RunAsUser(() => elevated = SecurityBypassContext.IsActive);
            Assert.That(elevated, Is.False, "Elevated");
        }
Esempio n. 7
0
        /// <summary>
        /// Get the value of an access control field.
        /// </summary>
        /// <param name="entityId">The entityId</param>
        /// <param name="fieldId">The fieldId</param>
        /// <returns>A A typed value.</returns>
        internal static TypedValue TryGetAccessControlField(long entityId, IEntityRef fieldId)
        {
            var value = new TypedValue {
                Type = DatabaseType.BoolType
            };

            if (entityId < 1)
            {
                throw new ArgumentNullException("entityId");
            }

            if (fieldId == null || fieldId.Namespace != "core")
            {
                throw new ArgumentException("fieldId: invalid namespace");
            }

            switch (fieldId.Alias)
            {
            case "canCreateType":
            {
                var entityType = Entity.Get <EntityType>(entityId);

                if (entityType == null)
                {
                    throw new InvalidOperationException("Assert false: attempted to load an entity as an EntityType which is not a type.");
                }

                SecurityBypassContext.RunAsUser(() => {
                        value.Value = AccessControlService.CanCreate(entityType);
                    });
                break;
            }

            case "canModify":
            {
                SecurityBypassContext.RunAsUser(() => {
                        value.Value = AccessControlService.Check(entityId, new[] { Permissions.Modify });
                    });
                break;
            }

            case "canDelete":
            {
                SecurityBypassContext.RunAsUser(() => {
                        value.Value = AccessControlService.Check(entityId, new[] { Permissions.Delete });
                    });
                break;
            }

            default:
            {
                // return null value
                break;
            }
            }
            return(value);
        }
        /// <summary>
        /// Perform a create using the provided update action. To be used for testing.
        /// </summary>
        /// <param name="resType"></param>
        /// <param name="updateAction"></param>
        public static IEntity PerformCreate(EntityType resType, Action <IEntity> updateAction)
        {
            try
            {
                IEntity newEntity = null;

                SecurityBypassContext.RunAsUser(() =>
                {
                    newEntity = Entity.Create(resType);

                    var provider  = Factory.Current.Resolve <IEntityDefaultsDecoratorProvider>();
                    var decorator = provider.GetDefaultsDecorator(resType.Id);
                    // Do per-entity work
                    decorator.SetDefaultValues(newEntity.ToEnumerable());
                });

                updateAction(newEntity);


                SecurityBypassContext.RunAsUser(() =>
                {
                    newEntity.Save();
                });

                return(newEntity);
            }
            catch (ValidationException ex)
            {
                string message = ex.FieldName != null?string.Format("{0}: {1}", ex.FieldName, ex.Message) : ex.Message;

                throw new WorkflowRunException(message, ex);
            }
            catch (CardinalityViolationException ex)
            {
                throw new WorkflowRunException(ex.Message, ex);
            }
            catch (DuplicateKeyException ex)
            {
                throw new WorkflowRunException(ex.Message, ex);
            }
            catch (InvalidCastException ex)
            {
                throw new WorkflowRunException("Incorrect data type", ex);
            }
            catch (SqlException ex)
            {
                if (ex.Number == 547)
                {
                    throw new CreateInvalidReferenceException(ex);
                }
                else
                {
                    throw;
                }
            }
        }
Esempio n. 9
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");
        }
Esempio n. 10
0
        /// <summary>
        /// Update all the the provided expressions.
        /// </summary>
        private Dictionary <WfExpression, object> ResolveExpressions(IRunState context, ICollection <WfExpression> expressions)
        {
            Dictionary <WfExpression, object> result = null;

            // evaluate the expressions and update the targeted values
            SecurityBypassContext.RunAsUser(() =>
            {
                result = expressions.ToDictionary(e => e, e => EvaluateExpression(context, e));
            });

            return(result);
        }
        /// <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;
                    }
                }));
            });
        }
Esempio n. 12
0
        bool OnBeforeRelsThisEnd(IEnumerable <IEntity> entities, List <Action> postSaveActions)
        {
            using (Profiler.Measure("ResourceTriggerFilterEventTarget.OnBeforeDelete OnBeforeRelsThisEnd"))
            {
                var _policy = Factory.ResourceTriggerFilterPolicyCache;

                foreach (var entity in entities)
                {
                    var typeId = entity.TypeIds.FirstOrDefault();

                    if (typeId != 0)
                    {
                        var policies = _policy.TypePolicyMap[typeId];
                        if (policies != null)
                        {
                            foreach (var policy in policies)
                            {
                                var handler = _policy.PolicyTypeHandlerMap[policy.TypeIds.First()];

                                if (handler != null)
                                {
                                    var isNew = entity.IsTemporaryId;

                                    bool result = false;
                                    SecurityBypassContext.RunAsUser(() =>
                                    {
                                        if (handler.OnBeforeDelete(policy, entity))
                                        {
                                            result = true;
                                        }
                                        else
                                        {
                                            postSaveActions.Add(() => handler.OnAfterDelete(policy, entity));
                                        }
                                    });

                                    if (result)
                                    {
                                        return(true);        // We failed, so bug out
                                    }
                                }
                            }
                        }
                    }
                }

                return(false);
            }
        }
        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.
                    }
                }
            }
        }
Esempio n. 15
0
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var ResourceToUpdateKey = GetArgumentKey("setChoiceActivityResourceArgument");
            var ValueKey            = GetArgumentKey("setChoiceActivityValueArgument");
            var FieldKey            = GetArgumentKey("setChoiceActivityFieldArgument");
            var replaceExistingKey  = GetArgumentKey("setChoiceActivityReplaceExisting");

            var choiceToUpdateRef = (IEntity)inputs[FieldKey];
            var resId             = (IEntity)inputs[ResourceToUpdateKey];
            var valueId           = (IEntity)inputs[ValueKey];

            bool replaceExisting = false;

            object replaceExistingObj;

            if (inputs.TryGetValue(replaceExistingKey, out replaceExistingObj))
            {
                replaceExisting = (bool?)replaceExistingObj ?? false;
            }

            var relationship = choiceToUpdateRef.As <Relationship>();

            SecurityBypassContext.RunAsUser(() =>
            {
                var resource = resId.AsWritable();    // Does not have to be a writeable copy because we are only manipulating relationships.

                var cardinality = relationship.Cardinality_Enum ?? CardinalityEnum_Enumeration.ManyToMany;

                replaceExisting =
                    replaceExisting
                    ||
                    cardinality == CardinalityEnum_Enumeration.OneToOne
                    ||
                    cardinality == CardinalityEnum_Enumeration.ManyToOne;


                var relCollection = resource.GetRelationships(choiceToUpdateRef, Direction.Forward);        // you can't have a reverse choice field.

                if (replaceExisting)
                {
                    relCollection.Clear();
                }

                relCollection.Add(valueId);

                resource.Save();
            });
        }
Esempio n. 16
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");
            }
        }
Esempio n. 17
0
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var typeRefKey   = GetArgumentKey("getResourcesResourceType");
            var reportRefKey = GetArgumentKey("getResourcesReport");
            var listKey      = GetArgumentKey("getResourcesList");
            var firstKey     = GetArgumentKey("getResourcesFirst");
            var countKey     = GetArgumentKey("getResourcesCount");

            object     o;
            EntityType resourceType = null;
            IEntity    reportRef    = null;

            if (inputs.TryGetValue(typeRefKey, out o))
            {
                if (o != null)
                {
                    resourceType = ((IEntity)o).As <EntityType>();
                }
            }

            if (inputs.TryGetValue(reportRefKey, out o))
            {
                if (o != null)
                {
                    reportRef = (IEntity)o;
                }
            }

            if (resourceType == null && reportRef == null)
            {
                throw new WorkflowRunException("Get Resources must have one of either the Type or Report parameters specified.");
            }


            IEnumerable <IEntity> list = null;

            SecurityBypassContext.RunAsUser(() =>
            {
                list = reportRef != null ? GetListFromReport(context, reportRef) : GetListFromType(resourceType);
            });

            context.SetArgValue(ActivityInstance, listKey, list);
            context.SetArgValue(ActivityInstance, firstKey, list.FirstOrDefault());
            context.SetArgValue(ActivityInstance, countKey, list.Count());
        }
Esempio n. 18
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));
            }
        }
Esempio n. 19
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);
        }
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var resourceToDeleteKey = GetArgumentKey("deleteActivityResourceArgument");

            var res = (IEntity)inputs[resourceToDeleteKey];

            if (res == null)
            {
                throw new WorkflowRunException_Internal("No record provided.", null);
            }

            SecurityBypassContext.RunAsUser(() =>
            {
                Entity.Delete(res.Id);
            });

            context.RemoveReference(res.Id);
        }
        private bool CheckTypeAccessRelatedTypesImpl(EntityType entityType, EntityRef permission, EntityRef user, List <EntityType> entityTypesToCheck)
        {
            bool result = false;

            using (MessageContext messageContext = new MessageContext(EntityAccessControlService.MessageName))
            {
                IDictionary <long, bool> canAccessTypes;
                string message;

                // Allow access if the user has access to any of the related types
                if (entityTypesToCheck.Count == 0)
                {
                    messageContext.Append(() => "No entity types found to check.");
                    return(false);
                }

                // Check whether the user has access to the given types
                canAccessTypes = null;
                SecurityBypassContext.RunAsUser(() =>
                                                canAccessTypes = Checker.CheckTypeAccess(
                                                    entityTypesToCheck.ToList( ),
                                                    permission,
                                                    user));

                message = string.Format(
                    "Checking security relationship(s) to see whether user can create entities of type '{0}': ",
                    entityType.Name ?? entityType.Id.ToString( ));

                if (canAccessTypes.Any(kvp => kvp.Value))
                {
                    messageContext.Append(() => string.Format(
                                              "{0} Allowed due to create access to entity type(s) '{1}'",
                                              message,
                                              canAccessTypes.Select(kvp => entityTypesToCheck.First(et => et.Id == kvp.Key).Name ?? kvp.Key.ToString( ))));

                    result = true;
                }
                else
                {
                    messageContext.Append(() => $"{message} Denied");
                }
            }
            return(result);
        }
Esempio n. 22
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);
            }
        }
        /// <summary>
        /// Perform a update using the provided update action. To be used for testing.
        /// </summary>
        /// <param name="entityToUpdate"></param>
        /// <param name="updateAction"></param>
        public static void PerformUpdate(IEntity entityToUpdate, Action <IEntity> updateAction)
        {
            try
            {
                updateAction(entityToUpdate);

                SecurityBypassContext.RunAsUser(() =>
                {
                    entityToUpdate.Save();
                });
            }
            catch (EDC.ReadiNow.Model.ValidationException ex)
            {
                string message = ex.FieldName != null?string.Format("{0}: {1}", ex.FieldName, ex.Message) : ex.Message;

                throw new WorkflowRunException(message, ex);
            }
            catch (CardinalityViolationException ex)
            {
                throw new WorkflowRunException(ex.Message, ex);
            }
            catch (DuplicateKeyException ex)
            {
                throw new WorkflowRunException(ex.Message, ex);
            }
            catch (InvalidCastException ex)
            {
                throw new WorkflowRunException("Incorrect data type", ex);
            }
            catch (SqlException ex)
            {
                if (ex.Number == 547)
                {
                    throw new UpdateInvalidReferenceException(ex);
                }
                else
                {
                    throw;
                }
            }
        }
Esempio n. 24
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();
                });
            }
        }
 /// <summary>
 /// Executed before each test is run
 /// </summary>
 /// <param name="testDetails">
 /// Provides details about the test that is going to be run.
 /// </param>
 public override void BeforeTest(TestDetails testDetails)
 {
     _securityBypassContext = new SecurityBypassContext();
 }
 /// <summary>
 ///     Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 public void Dispose()
 {
     _securityBypassContext.Dispose();
     _securityBypassContext = null;
 }
        /// <summary>
        /// Update a workflow using a update action. This will take care of handling paused instances by cloning.
        /// </summary>
        /// <param name="workflowId"></param>
        /// <param name="updateAction"></param>
        /// <returns>True if the workflow needed to be clones</returns>
        public static bool Update(long workflowId, Action updateAction)
        {
            using (new SecurityBypassContext(true))
            {
                Workflow clone    = null;
                var      original = Entity.Get <Workflow>(workflowId);

                if (original == null)
                {
                    throw new WebArgumentException("The provided Workflow Id is not a workflow");
                }

                if (original.WfNewerVersion != null)
                {
                    throw new WebArgumentException("This Workflow is not the latest version so cannot be updated");
                }

                using (var databaseContext = DatabaseContext.GetContext(true))
                {
                    var havePausedInstances            = original.RunningInstances.Any(r => r.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunPaused);
                    IDictionary <long, long> clonedIds = null;

                    if (havePausedInstances)
                    {
                        // clone the workflow (Need to save because the clone occurs in the DB)
                        clone     = original.Clone <Workflow>();
                        clonedIds = clone.Save();

                        // There seems to be a bug in entity clone that means you can't remove solution till after it has been saved.
                        clone            = clone.AsWritable <Workflow>();
                        clone.InSolution = null;

                        // Fix up the version linking - again we can't seem to do it as a single save.
                        var originalWfOlderVersionId = original.WfOlderVersion != null ? original.WfOlderVersion.Id : -1;

                        original = original.AsWritable <Workflow>();
                        original.WfOlderVersion = clone;
                        original.Save();

                        if (originalWfOlderVersionId != -1)
                        {
                            clone.WfOlderVersion = Entity.Get <Workflow>(originalWfOlderVersionId);
                        }

                        clone.Save();
                    }

                    SecurityBypassContext.RunAsUser(updateAction);

                    original = original.AsWritable <Workflow>();

                    original.WorkflowUpdateHash = _randGen.Next().ToString(CultureInfo.InvariantCulture);     // ideally this should be a hash of only the important aspects of the workflow
                    original.WorkflowVersion    = (original.WorkflowVersion ?? 1) + 1;

                    if (havePausedInstances)
                    {
                        original.WfOlderVersion = clone;
                        WorkflowRunHelper.MoveRuns(original, clone, clonedIds);
                    }

                    original.Save();    // This will also save the close

                    databaseContext.CommitTransaction();

                    return(havePausedInstances);
                }
            }
        }
Esempio n. 28
0
        bool OnBeforeRelsOtherEnds(IEnumerable <IEntity> entities, List <Action> postSaveActions)
        {
            using (Profiler.Measure("ResourceTriggerFilterEventTarget.OnBeforeDelete OnBeforeRelsOtherEnds"))
            {
                var policyCache = Factory.ResourceTriggerFilterPolicyCache;

                foreach (var entity in entities)
                {
                    //
                    // Get the filtered list of relationships that could possibly apply to some of the related entities
                    //
                    var filteredRels = GetRelsWithPotentialPolicies(policyCache, entity).ToList();

                    if (!filteredRels.Any())
                    {
                        continue;
                    }

                    // Prefill the cache
                    var requestString = string.Join(",", filteredRels.Select(r => (r.Item2 == Direction.Reverse ? "-#" : "#") + r.Item1.Id + ".id"));
                    BulkPreloader.Preload(new EntityRequest(entity.Id, requestString));

                    //
                    // Check each entity on the other end of the filtered rels t see if any policies apply
                    foreach (var relDir in filteredRels)
                    {
                        var rel       = relDir.Item1;
                        var direction = relDir.Item2;

                        var relInstances = entity.GetRelationships(rel, direction);

                        foreach (var otherEntity in relInstances)
                        {
                            var otherType = otherEntity.TypeIds.First();

                            var policies = policyCache.TypePolicyMap[otherType].Where(p => p.UpdatedRelationshipsToTriggerOn.Contains(rel, EntityIdEqualityComparer <Relationship> .Instance));

                            foreach (var policy in policies)
                            {
                                var handler = policyCache.PolicyTypeHandlerMap[policy.TypeIds.First()];

                                bool result = false;
                                SecurityBypassContext.RunAsUser(() =>
                                {
                                    if (handler.OnBeforeReverseRemove(policy, rel.Id, direction.Reverse(), otherEntity, entity))
                                    {
                                        result = true;
                                    }
                                    else
                                    {
                                        AddWrappedPostSaveAction(postSaveActions, () => handler.OnAfterReverseRemove(policy, rel.Id, direction.Reverse(), otherEntity, entity));
                                    }
                                });

                                if (result)
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
                return(false);
            }
        }
Esempio n. 29
0
 public void Test_RunAsUser_NullAction()
 {
     Assert.That(() => SecurityBypassContext.RunAsUser(null),
                 Throws.TypeOf <ArgumentNullException>().And.Property("ParamName").EqualTo("action"));
 }
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var OriginKey          = GetArgumentKey("setRelationshipActivityOriginArgument");
            var DestinationKey     = GetArgumentKey("setRelationshipActivityDestinationArgument");
            var RelationshipKey    = GetArgumentKey("setRelationshipActivityRelationshipArgument");
            var replaceExistingKey = GetArgumentKey("setRelationshipActivityReplaceExisting");
            var isReverseKey       = GetArgumentKey("setRelationshipActivityIsReverse");

            var originRef       = (IEntity)inputs[OriginKey];
            var relationshipRef = (IEntity)inputs[RelationshipKey];

            IEntity destinationRef = null;

            object destinationRefObj;

            if (inputs.TryGetValue(DestinationKey, out destinationRefObj))
            {
                destinationRef = (IEntity)destinationRefObj;
            }

            bool replaceExisting = false;

            object replaceExistingObj;

            if (inputs.TryGetValue(replaceExistingKey, out replaceExistingObj))
            {
                replaceExisting = (bool?)replaceExistingObj ?? false;
            }

            var direction = Direction.Forward;

            object isReverseObj;

            if (inputs.TryGetValue(isReverseKey, out isReverseObj))
            {
                direction = ((bool?)isReverseObj ?? false) ? Direction.Reverse : Direction.Forward;
            }


            var relationship = relationshipRef.As <Relationship>();

            SecurityBypassContext.RunAsUser(() =>
            {
                var origin = originRef.AsWritable <Entity>();

                var cardinality = relationship.Cardinality_Enum ?? CardinalityEnum_Enumeration.ManyToMany;

                replaceExisting =
                    replaceExisting
                    ||
                    cardinality == CardinalityEnum_Enumeration.OneToOne
                    ||
                    (direction == Direction.Forward && cardinality == CardinalityEnum_Enumeration.ManyToOne)
                    ||
                    (direction == Direction.Reverse && cardinality == CardinalityEnum_Enumeration.OneToMany)
                ;

                var relCollection = origin.GetRelationships(relationshipRef, direction);

                if (replaceExisting)
                {
                    relCollection.Clear();
                }

                if (destinationRef != null)
                {
                    relCollection.Add(destinationRef);
                }

                origin.Save();
            });
        }