Пример #1
0
        /// <summary>
        /// On subscribe, set API keys with push capability to expire in <see cref="PushKeysExpirationInDays" /> days.
        /// </summary>
        /// <param name="context"></param>
        public async Task OnSubscribeAsync(UserSecurityPolicySubscriptionContext context)
        {
            var pushKeys = context.User.Credentials.Where(c =>
                                                          CredentialTypes.IsApiKey(c.Type) &&
                                                          (
                                                              c.Scopes.Count == 0 ||
                                                              c.Scopes.Any(s =>
                                                                           s.AllowedAction.Equals(NuGetScopes.PackagePush, StringComparison.OrdinalIgnoreCase) ||
                                                                           s.AllowedAction.Equals(NuGetScopes.PackagePushVersion, StringComparison.OrdinalIgnoreCase)
                                                                           ))
                                                          );

            var expires     = DateTime.UtcNow.AddDays(PushKeysExpirationInDays);
            var expireTasks = new List <Task>();

            foreach (var key in pushKeys)
            {
                if (!key.Expires.HasValue || key.Expires > expires)
                {
                    expireTasks.Add(_auditing.SaveAuditRecordAsync(
                                        new UserAuditRecord(context.User, AuditedUserAction.ExpireCredential, key)));

                    key.Expires = expires;
                }
            }
            await Task.WhenAll(expireTasks);

            _diagnostics.Information($"Expiring {pushKeys.Count()} keys with push capability for user '{context.User.Username}'.");
        }
Пример #2
0
 private static CredentialKind GetCredentialKind(string type)
 {
     if (CredentialTypes.IsApiKey(type))
     {
         return(CredentialKind.Token);
     }
     else if (CredentialTypes.IsPassword(type))
     {
         return(CredentialKind.Password);
     }
     return(CredentialKind.External);
 }
Пример #3
0
        private bool IsRevocable(ApiKeyViewModel apiKeyViewModel)
        {
            if (apiKeyViewModel == null)
            {
                return(false);
            }
            if (apiKeyViewModel.HasExpired)
            {
                return(false);
            }
            if (!CredentialTypes.IsApiKey(apiKeyViewModel.Type))
            {
                return(false);
            }

            return(true);
        }
Пример #4
0
        public bool IsActiveApiKeyCredential(Credential credential)
        {
            if (credential == null)
            {
                return(false);
            }
            if (!CredentialTypes.IsApiKey(credential.Type))
            {
                return(false);
            }
            if (IsCredentialExpiredOrNonScopedApiKeyNotUsedInLastDays(credential))
            {
                return(false);
            }
            if (credential.RevocationSourceKey != null)
            {
                return(false);
            }

            return(true);
        }
Пример #5
0
        private async Task <AuthenticatedUser> AuthenticateInternal(Func <Credential, Credential> matchCredential, Credential credential)
        {
            if (credential.Type.StartsWith(CredentialTypes.Password.Prefix, StringComparison.OrdinalIgnoreCase))
            {
                // Password credentials cannot be used this way.
                throw new ArgumentException(Strings.PasswordCredentialsCannotBeUsedHere, nameof(credential));
            }

            using (_trace.Activity("Authenticate Credential: " + credential.Type))
            {
                var matched = matchCredential(credential);

                if (matched == null)
                {
                    _trace.Information("No user matches credential of type: " + credential.Type);

                    await Auditing.SaveAuditRecordAsync(
                        new FailedAuthenticatedOperationAuditRecord(null,
                                                                    AuditedAuthenticatedOperationAction.FailedLoginNoSuchUser,
                                                                    attemptedCredential : credential));

                    return(null);
                }

                if (matched.User is Organization)
                {
                    _trace.Information($"Cannot authenticate organization account '{matched.User.Username}'.");

                    await Auditing.SaveAuditRecordAsync(
                        new FailedAuthenticatedOperationAuditRecord(null,
                                                                    AuditedAuthenticatedOperationAction.FailedLoginUserIsOrganization,
                                                                    attemptedCredential : credential));

                    return(null);
                }

                if (matched.HasExpired)
                {
                    _trace.Verbose("Credential of type '" + matched.Type + "' for user '" + matched.User.Username + "' has expired on " + matched.Expires.Value.ToString("O", CultureInfo.InvariantCulture));

                    return(null);
                }

                if (CredentialTypes.IsApiKey(matched.Type) &&
                    !matched.IsScopedApiKey() &&
                    !matched.HasBeenUsedInLastDays(_config.ExpirationInDaysForApiKeyV1))
                {
                    // API key credential was last used a long, long time ago - expire it
                    await Auditing.SaveAuditRecordAsync(
                        new UserAuditRecord(matched.User, AuditedUserAction.ExpireCredential, matched));

                    matched.Expires = _dateTimeProvider.UtcNow;
                    await Entities.SaveChangesAsync();

                    _trace.Verbose(
                        "Credential of type '" + matched.Type
                        + "' for user '" + matched.User.Username
                        + "' was last used on " + matched.LastUsed.Value.ToString("O", CultureInfo.InvariantCulture)
                        + " and has now expired.");

                    return(null);
                }

                // update last used timestamp
                matched.LastUsed = _dateTimeProvider.UtcNow;
                await Entities.SaveChangesAsync();

                _trace.Verbose("Successfully authenticated '" + matched.User.Username + "' with '" + matched.Type + "' credential");

                return(new AuthenticatedUser(matched.User, matched));
            }
        }