예제 #1
0
        protected override Task <AuthenticationTicket> AuthenticateCoreAsync()
        {
            var apiKey = Request.Headers[Options.ApiKeyHeaderName];

            if (!String.IsNullOrEmpty(apiKey))
            {
                // Get the user
                var authUser = Auth.Authenticate(CredentialBuilder.CreateV1ApiKey(apiKey));
                if (authUser != null)
                {
                    // Set the current user
                    Context.Set(Constants.CurrentUserOwinEnvironmentKey, authUser);

                    return(Task.FromResult(
                               new AuthenticationTicket(
                                   AuthenticationService.CreateIdentity(
                                       authUser.User,
                                       AuthenticationTypes.ApiKey,
                                       new Claim(NuGetClaims.ApiKey, apiKey)),
                                   new AuthenticationProperties())));
                }
                else
                {
                    Logger.WriteWarning("No match for API Key!");
                }
            }
            else
            {
                Logger.WriteVerbose("No API Key Header found in request.");
            }
            return(Task.FromResult <AuthenticationTicket>(null));
        }
예제 #2
0
            public async Task GivenMatchingApiKey_ItSetsUserInOwinEnvironment()
            {
                // Arrange
                Guid apiKey = Guid.NewGuid();
                var  user   = new User()
                {
                    Username = "******", EmailAddress = "*****@*****.**"
                };
                TestableApiKeyAuthenticationHandler handler = await TestableApiKeyAuthenticationHandler.CreateAsync(new ApiKeyAuthenticationOptions()
                {
                    RootPath = "/api"
                });

                handler.OwinContext.Request.Path = "/api/v2/packages";
                handler.OwinContext.Request.Headers.Set(
                    Constants.ApiKeyHeaderName,
                    apiKey.ToString().ToLowerInvariant());
                handler.MockAuth.SetupAuth(CredentialBuilder.CreateV1ApiKey(apiKey), user);

                // Act
                await handler.InvokeAuthenticateCoreAsync();

                // Assert
                var authUser = Assert.IsType <AuthenticatedUser>(
                    handler.OwinContext.Environment[Constants.CurrentUserOwinEnvironmentKey]);

                Assert.Same(user, authUser.User);
            }
예제 #3
0
        public virtual async Task <bool> ChangePassword(User user, string oldPassword, string newPassword)
        {
            var hasPassword = user.Credentials.Any(
                c => c.Type.StartsWith(CredentialTypes.Password.Prefix, StringComparison.OrdinalIgnoreCase));
            Credential _;

            if (hasPassword && !ValidatePasswordCredential(user.Credentials, oldPassword, out _))
            {
                // Invalid old password!
                return(false);
            }

            // Replace/Set password credential
            var passwordCredential = CredentialBuilder.CreatePbkdf2Password(newPassword);

            await ReplaceCredentialInternal(user, passwordCredential);

            // Expire existing API keys
            var apiKeyCredential = CredentialBuilder.CreateV1ApiKey(Guid.NewGuid(), TimeSpan.FromDays(_config.ExpirationInDaysForApiKeyV1));

            await ReplaceCredentialInternal(user, apiKeyCredential);

            // Save changes
            await Entities.SaveChangesAsync();

            return(true);
        }
예제 #4
0
            public async Task GivenMatchingApiKey_ItReturnsTicketWithUserNameAndRoles()
            {
                // Arrange
                Guid apiKey = Guid.NewGuid();
                var  user   = new User()
                {
                    Username = "******", EmailAddress = "*****@*****.**"
                };
                TestableApiKeyAuthenticationHandler handler = await TestableApiKeyAuthenticationHandler.CreateAsync(new ApiKeyAuthenticationOptions()
                {
                    RootPath = "/api"
                });

                handler.OwinContext.Request.Path = "/api/v2/packages";
                handler.OwinContext.Request.Headers.Set(
                    Constants.ApiKeyHeaderName,
                    apiKey.ToString().ToLowerInvariant());
                handler.MockAuth.SetupAuth(CredentialBuilder.CreateV1ApiKey(apiKey), user);

                // Act
                var ticket = await handler.InvokeAuthenticateCoreAsync();

                // Assert
                Assert.NotNull(ticket);
                Assert.Equal(apiKey.ToString().ToLower(), ticket.Identity.GetClaimOrDefault(NuGetClaims.ApiKey));
            }
예제 #5
0
            public void GivenInvalidApiKeyCredential_ItReturnsNull()
            {
                // Arrange
                var service = Get <AuthenticationService>();

                // Act
                var result = service.Authenticate(CredentialBuilder.CreateV1ApiKey());

                // Assert
                Assert.Null(result);
            }
예제 #6
0
        public virtual async Task <AuthenticatedUser> Register(string username, string emailAddress, Credential credential)
        {
            if (_config.FeedOnlyMode)
            {
                throw new FeedOnlyModeException(FeedOnlyModeException.FeedOnlyModeError);
            }

            var existingUser = Entities.Users
                               .FirstOrDefault(u => u.Username == username || u.EmailAddress == emailAddress);

            if (existingUser != null)
            {
                if (String.Equals(existingUser.Username, username, StringComparison.OrdinalIgnoreCase))
                {
                    throw new EntityException(Strings.UsernameNotAvailable, username);
                }
                else
                {
                    throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress);
                }
            }

            var apiKey  = Guid.NewGuid();
            var newUser = new User(username)
            {
                EmailAllowed            = true,
                UnconfirmedEmailAddress = emailAddress,
                EmailConfirmationToken  = CryptographyService.GenerateToken(),
                NotifyPackagePushed     = true,
                CreatedUtc = DateTime.UtcNow
            };

            // Add a credential for the password and the API Key
            newUser.Credentials.Add(CredentialBuilder.CreateV1ApiKey(apiKey, TimeSpan.FromDays(_config.ExpirationInDaysForApiKeyV1)));
            newUser.Credentials.Add(credential);

            if (!_config.ConfirmEmailAddresses)
            {
                newUser.ConfirmEmailAddress();
            }

            // Write an audit record
            await Auditing.SaveAuditRecord(new UserAuditRecord(newUser, AuditedUserAction.Register));

            Entities.Users.Add(newUser);
            await Entities.SaveChangesAsync();

            return(new AuthenticatedUser(newUser, credential));
        }
예제 #7
0
            public void GivenMatchingApiKeyCredential_ItReturnsTheUserAndMatchingCredential()
            {
                // Arrange
                var service = Get <AuthenticationService>();
                var cred    = Fakes.User.Credentials.Single(
                    c => String.Equals(c.Type, CredentialTypes.ApiKeyV1, StringComparison.OrdinalIgnoreCase));

                // Act
                // Create a new credential to verify that it's a value-based lookup!
                var result = service.Authenticate(CredentialBuilder.CreateV1ApiKey(Guid.Parse(cred.Value)));

                // Assert
                Assert.NotNull(result);
                Assert.Same(Fakes.User, result.User);
                Assert.Same(cred, result.CredentialUsed);
            }
예제 #8
0
        public virtual AuthenticatedUser Register(string username, string password, string emailAddress)
        {
            var existingUser = Entities.Users
                               .FirstOrDefault(u => u.Username == username || u.EmailAddress == emailAddress);

            if (existingUser != null)
            {
                if (String.Equals(existingUser.Username, username, StringComparison.OrdinalIgnoreCase))
                {
                    throw new EntityException(Strings.UsernameNotAvailable, username);
                }
                else
                {
                    throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress);
                }
            }

            var hashedPassword = CryptographyService.GenerateSaltedHash(password, Constants.PBKDF2HashAlgorithmId);

            var apiKey  = Guid.NewGuid();
            var newUser = new User(username)
            {
                ApiKey                  = apiKey,
                EmailAllowed            = true,
                UnconfirmedEmailAddress = emailAddress,
                EmailConfirmationToken  = CryptographyService.GenerateToken(),
                HashedPassword          = hashedPassword,
                PasswordHashAlgorithm   = Constants.PBKDF2HashAlgorithmId,
                CreatedUtc              = DateTime.UtcNow
            };

            // Add a credential for the password and the API Key
            var passCred = new Credential(CredentialTypes.Password.Pbkdf2, newUser.HashedPassword);

            newUser.Credentials.Add(CredentialBuilder.CreateV1ApiKey(apiKey));
            newUser.Credentials.Add(passCred);

            if (!Config.ConfirmEmailAddresses)
            {
                newUser.ConfirmEmailAddress();
            }

            Entities.Users.Add(newUser);
            Entities.SaveChanges();

            return(new AuthenticatedUser(newUser, passCred));
        }
예제 #9
0
            public void GivenMultipleMatchingCredentials_ItThrows()
            {
                // Arrange
                var service  = Get <AuthenticationService>();
                var entities = Get <IEntitiesContext>();
                var cred     = CredentialBuilder.CreateV1ApiKey();

                cred.Key = 42;
                var creds = entities.Set <Credential>();

                creds.Add(cred);
                creds.Add(CredentialBuilder.CreateV1ApiKey(Guid.Parse(cred.Value)));

                // Act
                var ex = Assert.Throws <InvalidOperationException>(() => service.Authenticate(CredentialBuilder.CreateV1ApiKey(Guid.Parse(cred.Value))));

                // Assert
                Assert.Equal(String.Format(
                                 CultureInfo.CurrentCulture,
                                 Strings.MultipleMatchingCredentials,
                                 cred.Type,
                                 cred.Key), ex.Message);
            }
예제 #10
0
        public Fakes()
        {
            User = new User("testUser")
            {
                Key          = 42,
                EmailAddress = "*****@*****.**",
                Credentials  = new List <Credential>
                {
                    CredentialBuilder.CreatePbkdf2Password(Password),
                    CredentialBuilder.CreateV1ApiKey(Guid.Parse("519e180e-335c-491a-ac26-e83c4bd31d65"),
                                                     ExpirationForApiKeyV1)
                }
            };

            ShaUser = new User("testShaUser")
            {
                Key          = 42,
                EmailAddress = "*****@*****.**",
                Credentials  = new List <Credential>
                {
                    CredentialBuilder.CreateSha1Password(Password),
                    CredentialBuilder.CreateV1ApiKey(Guid.Parse("b9704a41-4107-4cd2-bcfa-70d84e021ab2"),
                                                     ExpirationForApiKeyV1)
                }
            };

            Admin = new User("testAdmin")
            {
                Key          = 43,
                EmailAddress = "*****@*****.**",
                Credentials  = new List <Credential> {
                    CredentialBuilder.CreatePbkdf2Password(Password)
                },
                Roles = new List <Role> {
                    new Role {
                        Name = Constants.AdminRoleName
                    }
                }
            };

            Owner = new User("testPackageOwner")
            {
                Key         = 44,
                Credentials = new List <Credential> {
                    CredentialBuilder.CreatePbkdf2Password(Password)
                },
                EmailAddress = "*****@*****.**" //package owners need confirmed email addresses, obviously.
            };

            Package = new PackageRegistration
            {
                Id     = "FakePackage",
                Owners = new List <User> {
                    Owner
                },
                Packages = new List <Package>
                {
                    new Package {
                        Version = "1.0"
                    },
                    new Package {
                        Version = "2.0"
                    }
                }
            };
        }