public ExternalGroupResult Read(IUser user, CancellationToken cancellationToken)
        {
            if (!configurationStore.GetIsEnabled() ||
                !configurationStore.GetAreSecurityGroupsEnabled())
            {
                return(new ExternalGroupResult(DirectoryServicesAuthentication.ProviderName, "Not enabled"));
            }
            if (user.Username == User.GuestLogin)
            {
                return(new ExternalGroupResult(DirectoryServicesAuthentication.ProviderName, "Not valid for Guest user"));
            }
            if (user.Identities.All(p => p.IdentityProviderName != DirectoryServicesAuthentication.ProviderName))
            {
                return(new ExternalGroupResult(DirectoryServicesAuthentication.ProviderName, "No identities matching this provider"));
            }

            // if the user has multiple, unique identities assigned then the group list should be the distinct union of the groups from
            // all of the identities
            var wasAbleToRetrieveSomeGroups = false;
            var newGroups    = new HashSet <string>();
            var adIdentities = user.Identities.Where(p => p.IdentityProviderName == DirectoryServicesAuthentication.ProviderName);

            foreach (var adIdentity in adIdentities)
            {
                var samAccountName = adIdentity.Claims[IdentityCreator.SamAccountNameClaimType].Value;

                var result = groupLocator.GetGroupIdsForUser(samAccountName, cancellationToken);
                if (result.WasAbleToRetrieveGroups)
                {
                    foreach (var groupId in result.GroupsIds.Where(g => !newGroups.Contains(g)))
                    {
                        newGroups.Add(groupId);
                    }
                    wasAbleToRetrieveSomeGroups = true;
                }
                else
                {
                    log.WarnFormat("Couldn't retrieve groups for samAccountName {0}", samAccountName);
                }
            }

            if (!wasAbleToRetrieveSomeGroups)
            {
                log.ErrorFormat("Couldn't retrieve groups for user {0}", user.Username);
                return(new ExternalGroupResult(DirectoryServicesAuthentication.ProviderName, $"Couldn't retrieve groups for user {user.Username}"));
            }

            return(new ExternalGroupResult(DirectoryServicesAuthentication.ProviderName, newGroups.Select(g => g).ToArray()));
        }
Esempio n. 2
0
        public HashSet <string> EnsureExternalSecurityGroupsAreUpToDate(IUser user, bool forceRefresh = false)
        {
            if (!configurationStore.GetIsEnabled() || !configurationStore.GetAreSecurityGroupsEnabled() || string.IsNullOrWhiteSpace(user.ExternalId))
            {
                return(new HashSet <string>());
            }

            // We will retrieve the user's external groups when they initially log in.  We can also refresh
            // them in the background periodically.  This is to cater for environments where the group
            // membership is managed outside of Octopus Deploy, e.g. Active Directory, and we need to balance
            // performance vs keeping the group list up to date.
            if (forceRefresh || expiryChecker.ShouldFetchExternalGroups(user))
            {
                try
                {
                    var result = groupLocator.GetGroupIdsForUser(user.ExternalId);
                    if (!result.WasAbleToRetrieveGroups)
                    {
                        return(new HashSet <string>());
                    }

                    var newGroups = new HashSet <string>(result.GroupsIds, StringComparer.OrdinalIgnoreCase);
                    userStore.UpdateUsersExternalGroups(user, newGroups);
                    return(newGroups);
                }
                catch (Exception ex)
                {
                    LogWarning(user, ex, "foreground loading");
                }
            }
            else if (expiryChecker.ShouldFetchExternalGroupsInBackground(user))
            {
                RefreshMemberExternalSecurityGroups(user);
            }
            return(new HashSet <string>());
        }