public async Task ResetsPasswordForValidToken(bool forgot) { var cred = new Credential("foo", "bar") { User = new User("foobar") }; GetMock<AuthenticationService>() .Setup(u => u.ResetPasswordWithToken("user", "token", "newpwd")) .CompletesWith(cred); var controller = GetController<UsersController>(); var model = new PasswordResetViewModel { ConfirmPassword = "******", NewPassword = "******" }; var result = await controller.ResetPassword("user", "token", model, forgot) as RedirectToRouteResult; Assert.NotNull(result); GetMock<AuthenticationService>() .Verify(u => u.ResetPasswordWithToken("user", "token", "newpwd")); }
private async Task<ActionResult> RemoveCredential(User user, Credential cred, string message) { if (cred == null) { TempData["Message"] = Strings.NoCredentialToRemove; return RedirectToAction("Account"); } // Count credentials and make sure the user can always login if (!String.Equals(cred.Type, CredentialTypes.ApiKeyV1, StringComparison.OrdinalIgnoreCase) && CountLoginCredentials(user) <= 1) { TempData["Message"] = Strings.CannotRemoveOnlyLoginCredential; } else { await AuthService.RemoveCredential(user, cred); // Notify the user of the change MessageService.SendCredentialRemovedNotice(user, cred); TempData["Message"] = message; } return RedirectToAction("Account"); }
private void ReplaceCredentialInternal(User user, Credential credential) { // Find the credentials we're replacing, if any var creds = user.Credentials .Where(cred => cred.Type == credential.Type) .ToList(); foreach (var cred in creds) { user.Credentials.Remove(cred); CredentialRepository.DeleteOnCommit(cred); } user.Credentials.Add(credential); }
public void WillListThePackageIfApiKeyBelongsToAnOwnerUsingAuthorizeCredential() { // Arrange var apiKey = Guid.NewGuid(); var owner = new Credential { User = new User { Key = 1 } }; var package = new Package { PackageRegistration = new PackageRegistration { Owners = new[] { new User(), owner.User } } }; var controller = new TestableApiController(); controller.MockPackageService.Setup(x => x.FindPackageByIdAndVersion(It.IsAny<string>(), It.IsAny<string>(), true)).Returns(package); controller.MockUserService .Setup(x => x.AuthenticateCredential( CredentialTypes.ApiKeyV1, apiKey.ToString().ToLowerInvariant())) .Returns(owner); // Act var result = controller.PublishPackage(apiKey.ToString(), "theId", "1.0.42"); // Assert ResultAssert.IsEmpty(result); controller.MockPackageService.Verify(x => x.MarkPackageListed(package, It.IsAny<bool>())); controller.MockIndexingService.Verify(i => i.UpdatePackage(package)); }
/// <summary> /// Determines whether a credential is supported from the user interface. For forward compatibility, /// this version supports only the credentials below and ignores any others. /// </summary> /// <param name="credential"></param> /// <returns></returns> public static bool IsViewSupportedCredential(this Credential credential) { return(SupportedCredentialTypes.Any(credType => string.Compare(credential.Type, credType, StringComparison.OrdinalIgnoreCase) == 0) || credential.Type.StartsWith(ExternalPrefix, StringComparison.OrdinalIgnoreCase)); }
public void ReplaceCredential(User user, Credential credential) { ReplaceCredentialInternal(user, credential); UserRepository.CommitChanges(); }
public void TrackNewCredentialCreated(User user, Credential credential) { TrackMetricForAccountActivity(Events.CredentialAdded, user, credential); }
private static bool CredentialKeyMatches(int?credentialKey, Credential c) { return(credentialKey == null || credentialKey == 0 || c.Key == credentialKey); }
public override async Task RemoveCredential(User user, Credential credential) { await Task.Yield(); user.Credentials.Remove(credential); }
public void TrackNewUserRegistrationEvent(User user, Credential credential) { TrackMetricForAccountActivity(Events.NewUserRegistration, user, credential); }
public override async Task AddCredential(User user, Credential credential) { await Task.Yield(); user.Credentials.Add(credential); }
private async Task <HttpStatusCodeWithBodyResult> VerifyPackageKeyInternalAsync(User user, Credential credential, string id, string version) { // Verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version, semVerLevelKey: SemVerLevelKey.SemVer2); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Verify)); string[] requestedActions; if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { requestedActions = new[] { NuGetScopes.PackageVerify }; } else { requestedActions = new[] { NuGetScopes.PackagePush, NuGetScopes.PackagePushVersion }; } var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.VerifyPackage, package.PackageRegistration, requestedActions); if (!apiScopeEvaluationResult.IsSuccessful()) { return(GetHttpResultFromFailedApiScopeEvaluation(apiScopeEvaluationResult, id, version)); } return(null); }
public static IReturnsResult <AuthenticationService> SetupAuth(this Mock <AuthenticationService> self, Credential cred, User user) { if (CredentialTypes.IsApiKey(cred.Type)) { return(self.Setup(us => us.Authenticate(It.Is <string>(c => string.Equals(c, cred.Value, StringComparison.Ordinal)))) .Returns(Task.FromResult(user == null ? null : new AuthenticatedUser(user, cred)))); } else { return(self.Setup(us => us.Authenticate(It.Is <Credential>(c => string.Equals(c.Type, cred.Type, StringComparison.OrdinalIgnoreCase) && string.Equals(c.Value, cred.Value, StringComparison.Ordinal)))) .Returns(Task.FromResult(user == null ? null : new AuthenticatedUser(user, cred)))); } }
public void SendCredentialAddedNotice(User user, Credential added) { SendCredentialChangeNotice( user, added, Strings.Emails_CredentialAdded_Body, Strings.Emails_CredentialAdded_Subject); }
public void TrackUserLogin(User user, Credential credential, bool wasMultiFactorAuthenticated) { TrackMetricForAccountActivity(Events.CredentialUsed, user, credential, wasMultiFactorAuthenticated); }
public void ReplacesExistingCredentialIfOneWithSameTypeExistsForUser() { // Arrange var frozenCred = new Credential("foo", "bar"); var existingCred = new Credential("baz", "bar"); var newCred = new Credential("baz", "boz"); var users = new List<User>() { new User("foo") { Credentials = new List<Credential>() { existingCred, frozenCred } } }; var service = new TestableUserService(); service.MockUserRepository.HasData(users); // Act service.ReplaceCredential("foo", newCred); // Assert Assert.Equal(2, users[0].Credentials.Count); Assert.Equal(new[] { frozenCred, newCred }, users[0].Credentials.ToArray()); service.MockCredentialRepository .Verify(x => x.DeleteOnCommit(existingCred)); service.MockUserRepository.VerifyCommitted(); }
private static string GetRegistrationMethod(Credential cred) { return(cred?.Type ?? ""); }
/// <summary> /// Determines whether a credential is supported (internal or from the UI). For forward compatibility, /// this version supports only the credentials below and ignores any others. /// </summary> /// <param name="credential"></param> /// <returns></returns> public static bool IsSupportedCredential(this Credential credential) { return(credential.IsViewSupportedCredential() || IsPackageVerificationApiKey(credential.Type)); }
private async Task <HttpStatusCodeWithBodyResult> VerifyPackageKeyInternalAsync(User user, Credential credential, string id, string version) { // Verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version, semVerLevelKey: SemVerLevelKey.SemVer2); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Verify)); if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { // Secure path: verify that verification key matches package scope. if (!HasAnyScopeThatAllows(package.PackageRegistration, NuGetScopes.PackageVerify)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } else { // Insecure path: verify that API key is legacy or matches package scope. if (!HasAnyScopeThatAllows(package.PackageRegistration, NuGetScopes.PackagePush, NuGetScopes.PackagePushVersion)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } return(null); }
public void ReplaceCredential(string userName, Credential credential) { var user = UserRepository .GetAll() .Include(u => u.Credentials) .SingleOrDefault(u => u.Username == userName); if (user == null) { throw new InvalidOperationException(Strings.UserNotFound); } ReplaceCredential(user, credential); }
public static bool IsApiKey(this Credential c) { return(c?.Type?.StartsWith(ApiKey.Prefix, StringComparison.OrdinalIgnoreCase) ?? false); }
private static bool ValidatePasswordCredential(Credential cred, string password) { Func<string, Credential, bool> validator; if (!_validators.TryGetValue(cred.Type, out validator)) { return false; } return validator(password, cred); }
public static bool IsType(this Credential c, string type) { return(c?.Type?.Equals(type, StringComparison.OrdinalIgnoreCase) ?? false); }
public void WillUseUserFromAuthenticateCredentialOverFindByApiKey() { var apiKey = Guid.NewGuid(); var owner = new Credential() { User = new User { Key = 1 } }; var nonOwner = new User() { ApiKey = apiKey }; var package = new Package { PackageRegistration = new PackageRegistration { Owners = new[] { new User(), owner.User } } }; var controller = new TestableApiController(); controller.MockPackageService.Setup(x => x.FindPackageByIdAndVersion(It.IsAny<string>(), It.IsAny<string>(), true)).Returns(package); controller.MockUserService.Setup(x => x.FindByApiKey(apiKey)).Returns(nonOwner); controller.MockUserService .Setup(x => x.AuthenticateCredential( CredentialTypes.ApiKeyV1, apiKey.ToString().ToLowerInvariant())) .Returns(owner); ResultAssert.IsEmpty(controller.DeletePackage(apiKey.ToString(), "theId", "1.0.42")); controller.MockPackageService.Verify(x => x.MarkPackageUnlisted(package, true)); controller.MockIndexingService.Verify(i => i.UpdatePackage(package)); }
/// <summary> /// Determines whether a credential is supported from the user interface. For forward compatibility, /// this version supports only the credentials below and ignores any others. /// </summary> /// <param name="credential"></param> /// <returns></returns> public static bool IsViewSupportedCredential(this Credential credential) { return (SupportedCredentialTypes.Any(credType => credential.IsType(credType)) || credential.IsExternal()); }
public void WillFailIfUserFromAuthenticateCredentialIsNotOwner() { // Arrange var apiKey = Guid.NewGuid(); var nonOwner = new Credential { User = new User { Key = 1 } }; var owner = new User(); var package = new Package { PackageRegistration = new PackageRegistration { Owners = new[] { new User(), owner } } }; var controller = new TestableApiController(); controller.MockPackageService.Setup(x => x.FindPackageByIdAndVersion(It.IsAny<string>(), It.IsAny<string>(), true)).Returns(package); controller.MockUserService.Setup(x => x.FindByApiKey(apiKey)).Returns(owner); controller.MockUserService .Setup(x => x.AuthenticateCredential( CredentialTypes.ApiKeyV1, apiKey.ToString().ToLowerInvariant())) .Returns(nonOwner); // Act var result = controller.PublishPackage(apiKey.ToString(), "theId", "1.0.42"); // Assert ResultAssert.IsStatusCode( result, HttpStatusCode.Forbidden, String.Format(Strings.ApiKeyNotAuthorized, "publish")); controller.MockPackageService.Verify(x => x.MarkPackageListed(package, It.IsAny<bool>()), Times.Never()); }
public static bool IsScopedApiKey(this Credential credential) { return(IsApiKey(credential.Type) && credential.Scopes != null && credential.Scopes.Any()); }
public async Task SendsPasswordAddedMessageWhenForgotFalse() { var cred = new Credential("foo", "bar") { User = new User("foobar") }; GetMock<AuthenticationService>() .Setup(u => u.ResetPasswordWithToken("user", "token", "newpwd")) .CompletesWith(cred); var controller = GetController<UsersController>(); var model = new PasswordResetViewModel { ConfirmPassword = "******", NewPassword = "******" }; await controller.ResetPassword("user", "token", model, forgot: false); GetMock<IMessageService>() .Verify(m => m.SendCredentialAddedNotice(cred.User, cred)); }
/// <summary> /// Should only be used in the rare cases where you are testing an action that /// does NOT use AppController.GetCurrentUser()! In those cases, use /// TestExtensionMethods.SetCurrentUser(AppController, User) instead. /// </summary> public static void SetOwinContextCurrentUser(this AppController self, User user, Credential credential = null) { if (user == null) { self.OwinContext.Request.User = null; return; } ClaimsIdentity identity = null; if (credential != null) { identity = AuthenticationService.CreateIdentity( user, AuthenticationTypes.ApiKey, new Claim(NuGetClaims.ApiKey, credential.Value), new Claim(NuGetClaims.Scope, JsonConvert.SerializeObject(credential.Scopes, Formatting.None))); } else { if (string.IsNullOrEmpty(user.Username)) { user.Username = "******"; } identity = AuthenticationService.CreateIdentity( user, AuthenticationTypes.External); } var principal = new ClaimsPrincipal(identity); var mock = Mock.Get(self.HttpContext); mock.Setup(c => c.Request.IsAuthenticated).Returns(true); mock.Setup(c => c.User).Returns(principal); self.OwinContext.Request.User = principal; }
private async Task<ActionResult> RemoveCredential(User user, Credential cred, string message) { // Count login credentials if (CountLoginCredentials(user) <= 1) { TempData["Message"] = Strings.CannotRemoveOnlyLoginCredential; } else if (cred != null) { await AuthService.RemoveCredential(user, cred); // Notify the user of the change MessageService.SendCredentialRemovedNotice(user, cred); TempData["Message"] = message; } return RedirectToAction("Account"); }
public static void SetCurrentUser(this AppController self, User user, Credential credential = null) { self.SetOwinContextCurrentUser(user, credential); self.SetCurrentUserOwinEnvironmentKey(user); }
private void SendCredentialChangeNotice(User user, Credential changed, string bodyTemplate, string subjectTemplate) { // What kind of credential is this? var credViewModel = AuthService.DescribeCredential(changed); string name = credViewModel.AuthUI == null ? credViewModel.TypeCaption : credViewModel.AuthUI.AccountNoun; string body = String.Format( CultureInfo.CurrentCulture, bodyTemplate, name); string subject = String.Format( CultureInfo.CurrentCulture, subjectTemplate, Config.GalleryOwner.DisplayName, name); SendSupportMessage(user, body, subject); }
public static bool HasCredential(this User user, Credential credential) { return(user.Credentials.Any(cred => cred.Matches(credential))); }