Exemple #1
0
        /// <summary>
        /// Get a policy decision for a particular securable
        /// </summary>
        public PolicyGrantType GetPolicyDecision(IPrincipal principal, object securable)
        {
            if (principal == null)
            {
                throw new ArgumentNullException(nameof(principal));
            }
            else if (securable == null)
            {
                throw new ArgumentNullException(nameof(securable));
            }

            // Get the user object from the principal
            var pip = ApplicationContext.Current.PolicyInformationService;

            // Policies
            var securablePolicies = pip.GetActivePolicies(securable);

            // Most restrictive
            PolicyGrantType decision = PolicyGrantType.Grant;

            foreach (var pol in securablePolicies)
            {
                var securablePdp = this.GetPolicyOutcome(principal, pol.Policy.Oid);

                if (securablePdp < decision)
                {
                    decision = securablePdp;
                }
            }

            return(decision);
        }
        /// <summary>
        /// Demand the permission
        /// </summary>
        public void Demand()
        {
            var pdp = ApplicationContext.Current.PolicyDecisionService;

            // Non system principals must be authenticated
            if (this.m_principal?.Identity?.IsAuthenticated == false || this.m_principal == null)
            {
                throw new PolicyViolationException(this.m_policyId, PolicyGrantType.Deny);
            }

            PolicyGrantType action = PolicyGrantType.Deny;

            if (pdp == null)             // No way to verify
            {
                action = PolicyGrantType.Deny;
            }
            else if (pdp != null)
            {
                action = pdp.GetPolicyOutcome(this.m_principal, this.m_policyId);
            }

            this.m_traceSource.TraceInfo("Policy Enforce: {0}({1}) = {2}", this.m_principal?.Identity?.Name, this.m_policyId, action);

            if (action != PolicyGrantType.Grant)
            {
                throw new PolicyViolationException(this.m_policyId, action);
            }
        }
Exemple #3
0
        /// <summary>
        /// Throws a <see cref="T:System.Security.SecurityException" /> at run time if the security requirement is not met.
        /// </summary>
        /// <exception cref="System.UnauthorizedAccessException">
        /// </exception>
        public void Demand()
        {
            // PDP is different here, it is local off the claims identity
            if (this.principal?.Identity?.IsAuthenticated == false || this.principal == null)
            {
                throw new UnauthorizedAccessException($"Policy {this.policyId} was denied");
            }

            PolicyGrantType action          = PolicyGrantType.Deny;
            var             claimsPrincipal = this.principal as ClaimsPrincipal;

            if (claimsPrincipal == null)             // No way to verify
            {
                action = PolicyGrantType.Deny;
            }
            else if (claimsPrincipal is ClaimsPrincipal && claimsPrincipal.HasClaim(c => c.Type == Constants.OpenIzGrantedPolicyClaim && c.Value == this.policyId || this.policyId.StartsWith(String.Format("{0}.", c.Value))))
            {
                action = PolicyGrantType.Grant;
            }

            this.traceSource.TraceInfo("Policy Enforce: {0}({1}) = {2}", this.principal?.Identity?.Name, this.policyId, action);

            if (action != PolicyGrantType.Grant)
            {
                throw new UnauthorizedAccessException($"Policy {this.policyId} was denied with reason : {action}");
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="PolicyViolationException"/> class.
 /// </summary>
 /// <param name="policyId">Policy identifier.</param>
 /// <param name="outcome">Outcome.</param>
 /// <param name="principal">The principal that the action was attempted as</param>
 public PolicyViolationException(IPrincipal principal, string policyId, PolicyGrantType outcome)
 {
     this.PolicyId       = policyId;
     this.PolicyDecision = principal.Identity.Name == "ANONYMOUS" ? PolicyGrantType.Elevate : outcome;
     this.Principal      = principal;
     try
     {
         this.m_policyName = ApplicationServiceContext.Current.GetService <IPolicyInformationService>()?.GetPolicy(policyId)?.Name;
     }
     catch { }
 }
Exemple #5
0
 /// <summary>
 /// Note supported
 /// </summary>
 public void AddPolicies(object securable, PolicyGrantType rule, IPrincipal principal, params string[] policyOids)
 {
     try
     {
         using (var client = this.GetClient())
             foreach (var itm in policyOids)
             {
                 client.Client.Post <SecurityPolicyInfo, SecurityPolicyInfo>($"{securable.GetType().Name}/{(securable as IIdentifiedEntity).Key}/policy", new SecurityPolicyInfo()
                 {
                     Oid   = itm,
                     Grant = rule
                 });
             }
     }
     catch (Exception e)
     {
         throw new RemoteOperationException($"Error attaching policy {String.Join(";", policyOids)} to {securable}", e);
     }
 }
        /// <summary>
        /// Get a policy decision
        /// </summary>
        public PolicyDecision GetPolicyDecision(IPrincipal principal, object securable)
        {
            if (principal == null)
            {
                throw new ArgumentNullException(nameof(principal));
            }
            else if (securable == null)
            {
                throw new ArgumentNullException(nameof(securable));
            }
            // We need to get the active policies for this
            var pip = ApplicationServiceContext.Current.GetService <IPolicyInformationService>();
            IEnumerable <IPolicyInstance> securablePolicies = pip.GetActivePolicies(securable),
                                          principalPolicies = pip.GetActivePolicies(principal);

            List <PolicyDecisionDetail> details = new List <PolicyDecisionDetail>();
            var retVal = new PolicyDecision(securable, details);

            foreach (var pol in securablePolicies)
            {
                // Get most restrictive from principal
                var             rules = principalPolicies.Where(p => p.Policy.Oid.StartsWith(pol.Policy.Oid)).Select(o => o.Rule);
                PolicyGrantType rule  = PolicyGrantType.Deny;
                if (rules.Any())
                {
                    rule = rules.Min();
                }

                // Rule for elevate can only be made when the policy allows for it & the principal is allowed
                if (rule == PolicyGrantType.Elevate &&
                    (!pol.Policy.CanOverride ||
                     principalPolicies.Any(o => o.Policy.Oid == PermissionPolicyIdentifiers.ElevateClinicalData && o.Rule == PolicyGrantType.Grant)))
                {
                    rule = PolicyGrantType.Deny;
                }

                details.Add(new PolicyDecisionDetail(pol.Policy.Oid, rule));
            }

            return(retVal);
        }
Exemple #7
0
 /// <summary>
 /// Creates a new policy instance with the specified policy and grant
 /// </summary>
 public SecurityPolicyInstance(SecurityPolicy policy, PolicyGrantType grantType)
 {
     this.Policy    = policy;
     this.GrantType = grantType;
 }
Exemple #8
0
        /// <summary>
        /// Adds the specified policies to the specified object
        /// </summary>
        /// <param name="securable">The securible to which the policy is to be added</param>
        /// <param name="rule">The rule to apply to the securable</param>
        /// <param name="policyOids">The policy OIDs to apply</param>
        public void AddPolicies(object securable, PolicyGrantType rule, IPrincipal principal, params string[] policyOids)
        {
            using (DataContext context = this.m_configuration.Provider.GetWriteConnection())
            {
                IDbTransaction tx = null;
                try
                {
                    context.Open();
                    tx = context.BeginTransaction();
                    foreach (var oid in policyOids)
                    {
                        var policy = context.FirstOrDefault <DbSecurityPolicy>(p => p.Oid == oid);
                        if (policy == null)
                        {
                            throw new KeyNotFoundException($"Policy {oid} not found");
                        }

                        // Add
                        if (securable is SecurityRole)
                        {
                            var sr = securable as SecurityRole;
                            new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.AssignPolicy, principal).Demand();
                            // Delete the existing role
                            context.Delete <DbSecurityRolePolicy>(o => o.PolicyKey == policy.Key && o.SourceKey == sr.Key);
                            context.Insert(new DbSecurityRolePolicy()
                            {
                                SourceKey = sr.Key.Value,
                                GrantType = (int)rule,
                                PolicyKey = policy.Key
                            });
                        }
                        else if (securable is SecurityApplication)
                        {
                            var sa = securable as SecurityApplication;
                            new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.AssignPolicy, principal).Demand();
                            // Delete the existing role
                            context.Delete <DbSecurityApplicationPolicy>(o => o.PolicyKey == policy.Key && o.SourceKey == sa.Key);
                            context.Insert(new DbSecurityApplicationPolicy()
                            {
                                SourceKey = sa.Key.Value,
                                GrantType = (int)rule,
                                PolicyKey = policy.Key
                            });
                        }
                        else if (securable is SecurityDevice)
                        {
                            var sd = securable as SecurityDevice;
                            // Delete the existing role
                            new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.AssignPolicy, principal).Demand();
                            context.Delete <DbSecurityDevicePolicy>(o => o.PolicyKey == policy.Key && o.SourceKey == sd.Key);
                            context.Insert(new DbSecurityDevicePolicy()
                            {
                                SourceKey = sd.Key.Value,
                                GrantType = (int)rule,
                                PolicyKey = policy.Key
                            });
                        }
                        else if (securable is Entity)
                        {
                            // Must either have write, must be the patient or must be their dedicated provider
                            if (securable is Patient)
                            {
                                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.WriteClinicalData, principal).Demand();
                            }
                            else if (securable is Material || securable is ManufacturedMaterial)
                            {
                                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.WriteMaterials, principal).Demand();
                            }
                            else if (securable is Place || securable is Organization || securable is Provider)
                            {
                                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.WritePlacesAndOrgs, principal).Demand();
                            }
                            else
                            {
                                new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.AssignPolicy, principal).Demand();
                            }

                            var ent      = securable as Entity;
                            var existing = context.FirstOrDefault <DbEntitySecurityPolicy>(e => e.SourceKey == ent.Key && e.PolicyKey == policy.Key && e.ObsoleteVersionSequenceId == null);
                            if (existing != null)
                            {
                                // Set obsolete to null if rule is DENY
                                existing.ObsoleteVersionSequenceId = null;
                                context.Update(existing);
                            }
                            context.Insert(new DbEntitySecurityPolicy()
                            {
                                EffectiveVersionSequenceId = ent.VersionSequence.Value,
                                PolicyKey = policy.Key,
                                SourceKey = ent.Key.Value
                            });
                        }
                        else if (securable is Act)
                        {
                            new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.WriteClinicalData, principal).Demand();

                            var act      = securable as Act;
                            var existing = context.FirstOrDefault <DbActSecurityPolicy>(e => e.SourceKey == act.Key && e.PolicyKey == policy.Key && e.ObsoleteVersionSequenceId == null);

                            if (existing != null)
                            {
                                // Set obsolete to null if rule is DENY
                                existing.ObsoleteVersionSequenceId = null;
                                context.Update(existing);
                            }
                            context.Insert(new DbActSecurityPolicy()
                            {
                                EffectiveVersionSequenceId = act.VersionSequence.Value,
                                PolicyKey = policy.Key,
                                SourceKey = act.Key.Value
                            });
                        }
                        else
                        {
                            throw new NotSupportedException($"Policies are not supported for {securable}");
                        }
                    }
                    tx.Commit();
                }
                catch (Exception e)
                {
                    tx.Rollback();
                    this.m_traceSource.TraceEvent(EventLevel.Error, "Error adding policies to {0}: {1}", securable, e);
                    throw;
                }
            }
        }
Exemple #9
0
        internal static void AssignPolicy(PolicyAssignParms parms)
        {
            // Identify the grant type
            PolicyGrantType grant = PolicyGrantType.Deny;

            if (!String.IsNullOrEmpty(parms.GrantType))
            {
                if (Int32.TryParse(parms.GrantType, out int grantParm))
                {
                    grant = (PolicyGrantType)grantParm;
                }
                else if (!Enum.TryParse <PolicyGrantType>(parms.GrantType, out grant))
                {
                    throw new InvalidOperationException($"Can't understand {parms.GrantType}");
                }
            }

            List <SecurityPolicyInfo> policies = null;

            if (parms.Policy?.Count > 0)
            {
                policies = parms.Policy.OfType <String>().Select(o => m_client.GetPolicies(r => r.Oid == o).CollectionItem.FirstOrDefault()).OfType <SecurityPolicy>().Select(o => new SecurityPolicyInfo()
                {
                    CanOverride = false,
                    Grant       = grant,
                    Oid         = o.Oid,
                    Name        = o.Name,
                    Policy      = o
                }).ToList();
            }

            if (parms.Policy == null || policies.Count() != parms.Policy.Count)
            {
                throw new InvalidOperationException("Could not find one or more policies");
            }

            var policyGrant = String.Join(";", policies.Select(o => o.Name));

            // Apply to roles?
            if (parms.Role != null)
            {
                foreach (var r in parms.Role)
                {
                    var role = m_client.Query <SecurityRole>(o => o.Name == r, 0, 1, out int _).CollectionItem.FirstOrDefault() as SecurityRoleInfo;
                    if (role == null)
                    {
                        throw new KeyNotFoundException($"Role {r} not found");
                    }
                    policies.ForEach(o => m_client.Client.Post <SecurityPolicyInfo, SecurityPolicyInfo>($"SecurityRole/{role.Entity.Key}/policy", o));
                    Console.WriteLine("{2}: {1} TO {0}", r, policyGrant, grant);
                }
            }

            // Apply to devices?
            if (parms.Device != null)
            {
                foreach (var d in parms.Device)
                {
                    var device = m_client.Query <SecurityDevice>(o => o.Name == d, 0, 1, out int _).CollectionItem.FirstOrDefault() as SecurityDeviceInfo;
                    if (device == null)
                    {
                        throw new KeyNotFoundException($"Device {d} not found");
                    }
                    policies.ForEach(o => m_client.Client.Post <SecurityPolicyInfo, SecurityPolicyInfo>($"SecurityDevice/{device.Entity.Key}/policy", o));
                    Console.WriteLine("{2}: {1} TO {0}", d, policyGrant, grant);
                }
            }
            // Apply to devices?
            if (parms.Application != null)
            {
                foreach (var a in parms.Application)
                {
                    var application = m_client.Query <SecurityApplication>(o => o.Name == a, 0, 1, out int _).CollectionItem.FirstOrDefault() as SecurityApplicationInfo;
                    if (application == null)
                    {
                        throw new KeyNotFoundException($"Application {a} not found");
                    }
                    policies.ForEach(o => m_client.Client.Post <SecurityPolicyInfo, SecurityPolicyInfo>($"SecurityApplication/{application.Entity.Key}/policy", o));
                    Console.WriteLine("{2}: {1} TO {0}", a, policyGrant, grant);
                }
            }
        }
Exemple #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OpenIZ.Mobile.Core.Exceptions.PolicyViolationException"/> class.
 /// </summary>
 /// <param name="policy">Policy.</param>
 /// <param name="outcome">Outcome.</param>
 public PolicyViolationException(IPolicy policy, PolicyGrantType outcome)
 {
     this.Policy         = policy;
     this.PolicyId       = policy.Oid;
     this.PolicyDecision = outcome;
 }
Exemple #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OpenIZ.Mobile.Core.Exceptions.PolicyViolationException"/> class.
 /// </summary>
 /// <param name="policyId">Policy identifier.</param>
 /// <param name="outcome">Outcome.</param>
 public PolicyViolationException(string policyId, PolicyGrantType outcome)
 {
     this.PolicyId       = policyId;
     this.PolicyDecision = outcome;
 }
 /// <summary>
 /// Constructs a new instance of the policy instance
 /// </summary>
 public GenericPolicyInstance(IPolicy policy, PolicyGrantType rule)
 {
     this.Policy = policy;
     this.Rule   = rule;
 }
Exemple #13
0
 /// <summary>
 /// Creates a new policy decision outcome
 /// </summary>
 public PolicyDecisionDetail(String policyId, PolicyGrantType outcome)
 {
     this.PolicyId = policyId;
     this.Outcome  = outcome;
 }
Exemple #14
0
 /// <summary>
 /// Effective policy instance
 /// </summary>
 public EffectivePolicyInstance(IPolicy policy, PolicyGrantType rule, IPrincipal forPrincipal)
 {
     this.Policy      = new EffectivePolicy(policy.Key, policy.Oid, policy.Name, policy.CanOverride);
     this.Rule        = rule;
     this.m_securable = forPrincipal;
 }
Exemple #15
0
 /// <summary>
 /// Create a policy from policy instance
 /// </summary>
 public AdoSecurityPolicyInstance(IPolicy policyInstance, PolicyGrantType rule)
 {
     this.Policy = policyInstance;
     this.Rule   = rule;
 }
Exemple #16
0
        /// <summary>
        /// Add the specified policies to the specified securable
        /// </summary>
        public void AddPolicies(object securable, PolicyGrantType rule, IPrincipal principal, params string[] policyOids)
        {
            var conn = this.CreateConnection();

            using (conn.Lock())
            {
                // First resolve identities
                if (securable is IDeviceIdentity)
                {
                    var did = securable as IDeviceIdentity;
                    var dbd = conn.Table <DbSecurityDevice>().Where(o => o.PublicId == did.Name).ToList();
                    securable = dbd.Select(o => new SecurityDevice()
                    {
                        Key  = o.Key,
                        Name = o.PublicId
                    }).FirstOrDefault();
                    if (securable == null)
                    {
                        throw new KeyNotFoundException($"Device identity {did.Name} not found");
                    }
                }
                else if (securable is Act)
                {
                    throw new NotSupportedException("Policies should be assigned to ACTS via the IRepositoryService<Act>");
                }
                else if (securable is Entity)
                {
                    throw new NotSupportedException("Policies should be assigned to ENTITIES via the IRepositoryService<Entity>");
                }
                byte[] key = (securable as IdentifiedData)?.Key.Value.ToByteArray();

                // Delete existing policy oids
                foreach (var oid in policyOids)
                {
                    // Get the policy
                    var policy = conn.Table <DbSecurityPolicy>().Where(p => p.Oid == oid).ToList().FirstOrDefault();
                    if (policy == null)
                    {
                        throw new KeyNotFoundException($"Policy {oid} not found");
                    }

                    if (securable is SecurityDevice)
                    {
                        conn.Table <DbSecurityDevicePolicy>().Delete(o => o.DeviceId == key && o.PolicyId == policy.Uuid);
                    }
                    else if (securable is SecurityRole)
                    {
                        conn.Table <DbSecurityRolePolicy>().Delete(o => o.RoleId == key && o.PolicyId == policy.Uuid);
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("Invalid type", nameof(securable));
                    }

                    if (securable is SecurityDevice)
                    {
                        conn.Insert(new DbSecurityDevicePolicy()
                        {
                            DeviceId  = key,
                            GrantType = (int)rule,
                            PolicyId  = policy.Key.ToByteArray(),
                            Key       = Guid.NewGuid()
                        });
                    }
                    else if (securable is SecurityRole)
                    {
                        conn.Insert(new DbSecurityRolePolicy()
                        {
                            RoleId    = key,
                            GrantType = (int)rule,
                            PolicyId  = policy.Key.ToByteArray(),
                            Key       = Guid.NewGuid()
                        });
                    }
                }
            }
        }