/// <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}'."); }
private static CredentialKind GetCredentialKind(string type) { if (CredentialTypes.IsApiKey(type)) { return(CredentialKind.Token); } else if (CredentialTypes.IsPassword(type)) { return(CredentialKind.Password); } return(CredentialKind.External); }
private bool IsRevocable(ApiKeyViewModel apiKeyViewModel) { if (apiKeyViewModel == null) { return(false); } if (apiKeyViewModel.HasExpired) { return(false); } if (!CredentialTypes.IsApiKey(apiKeyViewModel.Type)) { return(false); } return(true); }
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); }
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)); } }