/// <summary>
        /// Check if a user is subscribed to one or more security policies.
        /// </summary>
        public bool IsSubscribed(User user, IUserSecurityPolicySubscription subscription)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (subscription == null)
            {
                throw new ArgumentNullException(nameof(subscription));
            }

            var subscribed = FindPolicies(user, subscription);
            var required   = subscription.Policies;

            return(required.All(rp => subscribed.Any(sp => sp.Equals(rp))));
        }
        /// <summary>
        /// Check if a user is subscribed to one or more security policies.
        /// </summary>
        public bool IsSubscribed(User user, IUserSecurityPolicySubscription subscription)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (subscription == null)
            {
                throw new ArgumentNullException(nameof(subscription));
            }

            var subscribed = FindPolicies(user, subscription);
            var required   = subscription.Policies;

            return(required.All(rp =>
                                subscribed.Any(sp =>
                                               string.Equals(sp.Name, rp.Name, StringComparison.OrdinalIgnoreCase) &&
                                               string.Equals(sp.Subscription, rp.Subscription, StringComparison.OrdinalIgnoreCase))));
        }
        /// <summary>
        /// Unsubscribe a user from one or more security policies.
        /// </summary>
        public async Task UnsubscribeAsync(User user, IUserSecurityPolicySubscription subscription, bool commitChanges = true)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (subscription == null)
            {
                throw new ArgumentNullException(nameof(subscription));
            }

            var matches = FindPolicies(user, subscription).ToList();

            if (matches.Any())
            {
                foreach (var policy in matches)
                {
                    user.SecurityPolicies.Remove(policy);

                    EntitiesContext.UserSecurityPolicies.Remove(policy);
                }

                await subscription.OnUnsubscribeAsync(new UserSecurityPolicySubscriptionContext(this, user));

                await Auditing.SaveAuditRecordAsync(
                    new UserAuditRecord(user, AuditedUserAction.UnsubscribeFromPolicies, subscription.Policies));

                if (commitChanges)
                {
                    await EntitiesContext.SaveChangesAsync();
                }

                Diagnostics.Information($"User is now unsubscribed from '{subscription.SubscriptionName}'.");
            }
            else
            {
                Diagnostics.Information($"User is already unsubscribed from '{subscription.SubscriptionName}'.");
            }
        }
        /// <summary>
        /// Subscribe a user to one or more security policies.
        /// </summary>
        /// <returns>True if user was subscribed, false if not (i.e., was already subscribed).</returns>
        public async Task <bool> SubscribeAsync(User user, IUserSecurityPolicySubscription subscription, bool commitChanges = true)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            if (subscription == null)
            {
                throw new ArgumentNullException(nameof(subscription));
            }

            if (IsSubscribed(user, subscription))
            {
                Diagnostics.Information($"User is already subscribed to '{subscription.SubscriptionName}'.");

                return(false);
            }
            else
            {
                foreach (var policy in subscription.Policies)
                {
                    user.SecurityPolicies.Add(new UserSecurityPolicy(policy));
                }

                await subscription.OnSubscribeAsync(new UserSecurityPolicySubscriptionContext(this, user));

                await Auditing.SaveAuditRecordAsync(
                    new UserAuditRecord(user, AuditedUserAction.SubscribeToPolicies, subscription.Policies));

                if (commitChanges)
                {
                    await EntitiesContext.SaveChangesAsync();
                }

                Diagnostics.Information($"User is now subscribed to '{subscription.SubscriptionName}'.");

                return(true);
            }
        }
        public SecurityPolicyService(
            IEntitiesContext entitiesContext,
            IAuditingService auditing,
            IDiagnosticsService diagnostics,
            IAppConfiguration configuration,
            Lazy <IUserService> userService,
            Lazy <IPackageOwnershipManagementService> packageOwnershipManagementService,
            MicrosoftTeamSubscription microsoftTeamSubscription = null)
        {
            EntitiesContext = entitiesContext ?? throw new ArgumentNullException(nameof(entitiesContext));
            Auditing        = auditing ?? throw new ArgumentNullException(nameof(auditing));

            if (diagnostics == null)
            {
                throw new ArgumentNullException(nameof(diagnostics));
            }

            Diagnostics                        = diagnostics.SafeGetSource(nameof(SecurityPolicyService));
            Configuration                      = configuration ?? throw new ArgumentNullException(nameof(configuration));
            DefaultSubscription                = new DefaultSubscription();
            MicrosoftTeamSubscription          = microsoftTeamSubscription;
            _packageOwnershipManagementService = packageOwnershipManagementService ?? throw new ArgumentNullException(nameof(packageOwnershipManagementService));
            _userService                       = userService ?? throw new ArgumentNullException(nameof(userService));
        }
 /// <summary>
 /// Find user security policies which belong to a subscription.
 /// </summary>
 private static IEnumerable <UserSecurityPolicy> FindPolicies(User user, IUserSecurityPolicySubscription subscription)
 {
     return(user.SecurityPolicies.Where(s => s.Subscription.Equals(subscription.SubscriptionName, StringComparison.OrdinalIgnoreCase)));
 }
 public Task UnsubscribeAsync(User user, IUserSecurityPolicySubscription subscription, bool commitChanges = true)
 {
     throw new NotImplementedException();
 }
 public bool IsSubscribed(User user, IUserSecurityPolicySubscription subscription)
 {
     throw new NotImplementedException();
 }