private static void ChangePasswordInternal(User user, string newPassword) { var hashedPassword = Crypto.GenerateSaltedHash(newPassword, Constants.PBKDF2HashAlgorithmId); user.PasswordHashAlgorithm = Constants.PBKDF2HashAlgorithmId; user.HashedPassword = hashedPassword; }
public virtual User GeneratePasswordResetToken(string usernameOrEmail, int tokenExpirationMinutes) { if (String.IsNullOrEmpty(usernameOrEmail)) { throw new ArgumentNullException("usernameOrEmail"); } if (tokenExpirationMinutes < 1) { throw new ArgumentException( "Token expiration should give the user at least a minute to change their password", "tokenExpirationMinutes"); } var user = FindByEmailAddress(usernameOrEmail); if (user == null) { return(null); } if (!user.Confirmed) { throw new InvalidOperationException(Strings.UserIsNotYetConfirmed); } if (!String.IsNullOrEmpty(user.PasswordResetToken) && !user.PasswordResetTokenExpirationDate.IsInThePast()) { return(user); } user.PasswordResetToken = Crypto.GenerateToken(); user.PasswordResetTokenExpirationDate = DateTime.UtcNow.AddMinutes(tokenExpirationMinutes); UserRepository.CommitChanges(); return(user); }
public virtual User FindByUsernameOrEmailAddressAndPassword(string usernameOrEmail, string password) { // TODO: validate input var user = FindByUsername(usernameOrEmail) ?? FindByEmailAddress(usernameOrEmail); if (user == null) { return(null); } if (!Crypto.ValidateSaltedHash(user.HashedPassword, password, user.PasswordHashAlgorithm)) { return(null); } else if (!user.PasswordHashAlgorithm.Equals(Constants.PBKDF2HashAlgorithmId, StringComparison.OrdinalIgnoreCase)) { // If the user can be authenticated and they are using an older password algorithm, migrate them to the current one. ChangePasswordInternal(user, password); UserRepository.CommitChanges(); } return(user); }
public async Task <Organization> AddOrganizationAsync(string username, string emailAddress, User adminUser) { if (!ContentObjectService.LoginDiscontinuationConfiguration.AreOrganizationsSupportedForUser(adminUser)) { throw new EntityException(String.Format(CultureInfo.CurrentCulture, Strings.Organizations_NotInDomainWhitelist, adminUser.Username)); } var existingUserWithIdentity = EntitiesContext.Users .FirstOrDefault(u => u.Username == username || u.EmailAddress == emailAddress); if (existingUserWithIdentity != null) { if (existingUserWithIdentity.Username.Equals(username, StringComparison.OrdinalIgnoreCase)) { throw new EntityException(Strings.UsernameNotAvailable, username); } if (string.Equals(existingUserWithIdentity.EmailAddress, emailAddress, StringComparison.OrdinalIgnoreCase)) { throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress); } } var organization = new Organization(username) { EmailAllowed = true, UnconfirmedEmailAddress = emailAddress, EmailConfirmationToken = Crypto.GenerateToken(), NotifyPackagePushed = true, CreatedUtc = DateTimeProvider.UtcNow, Members = new List <Membership>() }; var membership = new Membership { Organization = organization, Member = adminUser, IsAdmin = true }; organization.Members.Add(membership); adminUser.Organizations.Add(membership); OrganizationRepository.InsertOnCommit(organization); if (string.IsNullOrEmpty(GetAzureActiveDirectoryCredentialTenant(adminUser))) { throw new EntityException(String.Format(CultureInfo.CurrentCulture, Strings.Organizations_AdminAccountDoesNotHaveTenant, adminUser.Username)); } if (!await SubscribeOrganizationToTenantPolicy(organization, adminUser, commitChanges: false)) { throw new EntityException(Strings.DefaultUserSafeExceptionMessage); } await EntitiesContext.SaveChangesAsync(); return(organization); }
public virtual User Create( string username, string password, string emailAddress) { // TODO: validate input // TODO: consider encrypting email address with a public key, and having the background process that send messages have the private key to decrypt var existingUser = FindByUsername(username); if (existingUser != null) { throw new EntityException(Strings.UsernameNotAvailable, username); } var existingUsers = FindAllByEmailAddress(emailAddress); if (existingUsers.AnySafe()) { throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress); } var hashedPassword = Crypto.GenerateSaltedHash(password, Constants.PBKDF2HashAlgorithmId); var apiKey = Guid.NewGuid(); var newUser = new User(username) { ApiKey = apiKey, EmailAllowed = true, UnconfirmedEmailAddress = emailAddress, EmailConfirmationToken = Crypto.GenerateToken(), HashedPassword = hashedPassword, PasswordHashAlgorithm = Constants.PBKDF2HashAlgorithmId, CreatedUtc = DateTime.UtcNow, Roles = new List <Role> { RoleRepository.GetEntity(2) } }; // Add a credential for the password and the API Key newUser.Credentials.Add(CredentialBuilder.CreateV1ApiKey(apiKey)); newUser.Credentials.Add(new Credential(CredentialTypes.Password.Pbkdf2, newUser.HashedPassword)); if (!Config.ConfirmEmailAddresses) { newUser.ConfirmEmailAddress(); } newUser.Roles.Add(RoleRepository.GetEntity(2)); UserRepository.InsertOnCommit(newUser); UserRepository.CommitChanges(); return(newUser); }
public async Task <Organization> AddOrganizationAsync(string username, string emailAddress, User adminUser) { var existingUserWithIdentity = EntitiesContext.Users .FirstOrDefault(u => u.Username == username || u.EmailAddress == emailAddress); if (existingUserWithIdentity != null) { if (existingUserWithIdentity.Username.Equals(username, StringComparison.OrdinalIgnoreCase)) { throw new EntityException(Strings.UsernameNotAvailable, username); } if (string.Equals(existingUserWithIdentity.EmailAddress, emailAddress, StringComparison.OrdinalIgnoreCase)) { throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress); } } var organization = new Organization(username) { EmailAllowed = true, UnconfirmedEmailAddress = emailAddress, EmailConfirmationToken = Crypto.GenerateToken(), NotifyPackagePushed = true, CreatedUtc = DateTimeProvider.UtcNow, Members = new List <Membership>() }; if (!Config.ConfirmEmailAddresses) { organization.ConfirmEmailAddress(); } var membership = new Membership { Organization = organization, Member = adminUser, IsAdmin = true }; organization.Members.Add(membership); adminUser.Organizations.Add(membership); OrganizationRepository.InsertOnCommit(organization); await SubscribeOrganizationToTenantPolicyIfTenantIdIsSupported(organization, adminUser, commitChanges : false); await Auditing.SaveAuditRecordAsync(new UserAuditRecord(organization, AuditedUserAction.AddOrganization, membership)); await EntitiesContext.SaveChangesAsync(); return(organization); }
public virtual User Create( string username, string password, string emailAddress) { // TODO: validate input // TODO: consider encrypting email address with a public key, and having the background process that send messages have the private key to decrypt var existingUser = FindByUsername(username); if (existingUser != null) { throw new EntityException(Strings.UsernameNotAvailable, username); } existingUser = FindByEmailAddress(emailAddress); if (existingUser != null) { throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress); } var hashedPassword = Crypto.GenerateSaltedHash(password, Constants.PBKDF2HashAlgorithmId); var newUser = new User( username, hashedPassword) { ApiKey = Guid.NewGuid(), EmailAllowed = true, UnconfirmedEmailAddress = emailAddress, EmailConfirmationToken = Crypto.GenerateToken(), PasswordHashAlgorithm = Constants.PBKDF2HashAlgorithmId, CreatedUtc = DateTime.UtcNow }; if (!Config.ConfirmEmailAddresses) { newUser.ConfirmEmailAddress(); } UserRepository.InsertOnCommit(newUser); UserRepository.CommitChanges(); return(newUser); }
public virtual User FindByUsernameAndPassword(string username, string password) { // TODO: validate input var user = FindByUsername(username); if (user == null) { return(null); } if (!Crypto.ValidateSaltedHash(user.HashedPassword, password, user.PasswordHashAlgorithm)) { return(null); } return(user); }
public async Task RequestTransformToOrganizationAccount(User accountToTransform, User adminUser) { accountToTransform = accountToTransform ?? throw new ArgumentNullException(nameof(accountToTransform)); adminUser = adminUser ?? throw new ArgumentNullException(nameof(adminUser)); // create new or update existing request if (accountToTransform.OrganizationMigrationRequest == null) { accountToTransform.OrganizationMigrationRequest = new OrganizationMigrationRequest(); } ; accountToTransform.OrganizationMigrationRequest.NewOrganization = accountToTransform; accountToTransform.OrganizationMigrationRequest.AdminUser = adminUser; accountToTransform.OrganizationMigrationRequest.ConfirmationToken = Crypto.GenerateToken(); accountToTransform.OrganizationMigrationRequest.RequestDate = DateTime.UtcNow; await UserRepository.CommitChangesAsync(); }
public void UpdateProfile(User user, string emailAddress, bool emailAllowed) { if (user == null) { throw new ArgumentNullException("user"); } if (emailAddress != user.EmailAddress) { var existingUser = FindByEmailAddress(emailAddress); if (existingUser != null && existingUser.Key != user.Key) { throw new EntityException(Strings.EmailAddressBeingUsed, emailAddress); } user.UnconfirmedEmailAddress = emailAddress; user.EmailConfirmationToken = Crypto.GenerateToken(); } user.EmailAllowed = emailAllowed; UserRepository.CommitChanges(); }
public PackageOwnerRequest CreatePackageOwnerRequest(PackageRegistration package, User currentOwner, User newOwner) { var existingRequest = FindExistingPackageOwnerRequest(package, newOwner); if (existingRequest != null) { return(existingRequest); } var newRequest = new PackageOwnerRequest { PackageRegistrationKey = package.Key, RequestingOwnerKey = currentOwner.Key, NewOwnerKey = newOwner.Key, ConfirmationCode = Crypto.GenerateToken(), RequestDate = DateTime.UtcNow }; _packageOwnerRequestRepository.InsertOnCommit(newRequest); _packageOwnerRequestRepository.CommitChanges(); return(newRequest); }
private User AuthenticatePassword(string password, User user) { if (user == null) { return(null); } // Check for a credential var creds = user.Credentials .Where(c => c.Type.StartsWith( CredentialTypes.Password.Prefix, StringComparison.OrdinalIgnoreCase)).ToList(); bool valid; if (creds.Count > 0) { valid = ValidatePasswordCredential(creds, password); if (valid && (creds.Count > 1 || !creds.Any(c => String.Equals( c.Type, CredentialTypes.Password.Pbkdf2, StringComparison.OrdinalIgnoreCase)))) { MigrateCredentials(user, creds, password); } } else { valid = Crypto.ValidateSaltedHash( user.HashedPassword, password, user.PasswordHashAlgorithm); } return(valid ? user : null); }
private Package CreatePackageFromNuGetPackage(PackageRegistration packageRegistration, INupkg nugetPackage, User user) { var package = packageRegistration.Packages.SingleOrDefault(pv => pv.Version == nugetPackage.Metadata.Version.ToString()); if (package != null) { throw new EntityException( "A package with identifier '{0}' and version '{1}' already exists.", packageRegistration.Id, package.Version); } var now = DateTime.UtcNow; var packageFileStream = nugetPackage.GetStream(); package = new Package { // Version must always be the exact string from the nuspec, which ToString will return to us. // However, we do also store a normalized copy for looking up later. Version = nugetPackage.Metadata.Version.ToString(), NormalizedVersion = nugetPackage.Metadata.Version.ToNormalizedString(), Description = nugetPackage.Metadata.Description, ReleaseNotes = nugetPackage.Metadata.ReleaseNotes, HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = Crypto.GenerateHash(packageFileStream.ReadAllBytes()), PackageFileSize = packageFileStream.Length, Created = now, Language = nugetPackage.Metadata.Language, LastUpdated = now, Published = now, Copyright = nugetPackage.Metadata.Copyright, FlattenedAuthors = nugetPackage.Metadata.Authors.Flatten(), IsPrerelease = !nugetPackage.Metadata.IsReleaseVersion(), Listed = true, PackageRegistration = packageRegistration, RequiresLicenseAcceptance = nugetPackage.Metadata.RequireLicenseAcceptance, Summary = nugetPackage.Metadata.Summary, Tags = PackageHelper.ParseTags(nugetPackage.Metadata.Tags), Title = nugetPackage.Metadata.Title, User = user, }; package.IconUrl = nugetPackage.Metadata.IconUrl.ToEncodedUrlStringOrNull(); package.LicenseUrl = nugetPackage.Metadata.LicenseUrl.ToEncodedUrlStringOrNull(); package.ProjectUrl = nugetPackage.Metadata.ProjectUrl.ToEncodedUrlStringOrNull(); package.MinClientVersion = nugetPackage.Metadata.MinClientVersion.ToStringOrNull(); #pragma warning disable 618 // TODO: remove Package.Authors completely once prodution services definitely no longer need it foreach (var author in nugetPackage.Metadata.Authors) { package.Authors.Add(new PackageAuthor { Name = author }); } #pragma warning restore 618 var supportedFrameworks = GetSupportedFrameworks(nugetPackage).Select(fn => fn.ToShortNameOrNull()).ToArray(); if (!supportedFrameworks.AnySafe(sf => sf == null)) { foreach (var supportedFramework in supportedFrameworks) { package.SupportedFrameworks.Add(new PackageFramework { TargetFramework = supportedFramework }); } } foreach (var dependencySet in nugetPackage.Metadata.DependencySets) { if (dependencySet.Dependencies.Count == 0) { package.Dependencies.Add( new PackageDependency { Id = null, VersionSpec = null, TargetFramework = dependencySet.TargetFramework.ToShortNameOrNull() }); } else { foreach (var dependency in dependencySet.Dependencies.Select(d => new { d.Id, d.VersionSpec, dependencySet.TargetFramework })) { package.Dependencies.Add( new PackageDependency { Id = dependency.Id, VersionSpec = dependency.VersionSpec == null ? null : dependency.VersionSpec.ToString(), TargetFramework = dependency.TargetFramework.ToShortNameOrNull() }); } } } package.FlattenedDependencies = package.Dependencies.Flatten(); return(package); }
public async Task <MembershipRequest> AddMembershipRequestAsync(Organization organization, string memberName, bool isAdmin) { organization = organization ?? throw new ArgumentNullException(nameof(organization)); var membership = FindMembershipByUsername(organization, memberName); if (membership != null) { throw new EntityException(string.Format(CultureInfo.CurrentCulture, Strings.AddMember_AlreadyAMember, memberName)); } var request = FindMembershipRequestByUsername(organization, memberName); if (request != null) { // If there is already an existing request, return it. // If the existing request grants collaborator but we are trying to create a request that grants admin, update the request to grant admin. request.IsAdmin = isAdmin || request.IsAdmin; await EntitiesContext.SaveChangesAsync(); return(request); } if (Regex.IsMatch(memberName, GalleryConstants.EmailValidationRegex, RegexOptions.None, GalleryConstants.EmailValidationRegexTimeout)) { throw new EntityException(Strings.AddMember_NameIsEmail); } var member = FindByUsername(memberName); if (member == null) { throw new EntityException(string.Format(CultureInfo.CurrentCulture, Strings.AddMember_UserNotFound, memberName)); } if (!member.Confirmed) { throw new EntityException(string.Format(CultureInfo.CurrentCulture, Strings.AddMember_UserNotConfirmed, memberName)); } if (member is Organization) { throw new EntityException(string.Format(CultureInfo.CurrentCulture, Strings.AddMember_UserIsOrganization, memberName)); } // Ensure that the new member meets the AAD tenant policy for this organization. var policyResult = await SecurityPolicyService.EvaluateOrganizationPoliciesAsync( SecurityPolicyAction.JoinOrganization, organization, member); if (policyResult != SecurityPolicyResult.SuccessResult) { throw new EntityException(policyResult.ErrorMessage); } request = new MembershipRequest() { Organization = organization, NewMember = member, IsAdmin = isAdmin, ConfirmationToken = Crypto.GenerateToken(), RequestDate = DateTime.UtcNow, }; organization.MemberRequests.Add(request); await EntitiesContext.SaveChangesAsync(); return(request); }
private Package CreatePackageFromNuGetPackage(PackageRegistration packageRegistration, INupkg nugetPackage) { var package = packageRegistration.Packages.SingleOrDefault(pv => pv.Version == nugetPackage.Metadata.Version.ToString()); if (package != null) { throw new EntityException( "A package with identifier '{0}' and version '{1}' already exists.", packageRegistration.Id, package.Version); } var now = DateTime.UtcNow; var packageFileStream = nugetPackage.GetStream(); package = new Package { Version = nugetPackage.Metadata.Version.ToString(), Description = nugetPackage.Metadata.Description, ReleaseNotes = nugetPackage.Metadata.ReleaseNotes, RequiresLicenseAcceptance = nugetPackage.Metadata.RequireLicenseAcceptance, HashAlgorithm = Constants.Sha512HashAlgorithmId, Hash = Crypto.GenerateHash(packageFileStream.ReadAllBytes()), PackageFileSize = packageFileStream.Length, Created = now, Language = nugetPackage.Metadata.Language, LastUpdated = now, Published = now, Copyright = nugetPackage.Metadata.Copyright, IsPrerelease = !nugetPackage.Metadata.IsReleaseVersion(), Listed = true, PackageRegistration = packageRegistration, Summary = nugetPackage.Metadata.Summary, Tags = nugetPackage.Metadata.Tags, Title = nugetPackage.Metadata.Title, }; package.IconUrl = nugetPackage.Metadata.IconUrl.ToStringOrNull(); package.LicenseUrl = nugetPackage.Metadata.LicenseUrl.ToStringOrNull(); package.ProjectUrl = nugetPackage.Metadata.ProjectUrl.ToStringOrNull(); package.MinClientVersion = nugetPackage.Metadata.MinClientVersion.ToStringOrNull(); foreach (var author in nugetPackage.Metadata.Authors) { package.Authors.Add(new PackageAuthor { Name = author }); } var supportedFrameworks = GetSupportedFrameworks(nugetPackage).Select(fn => fn.ToShortNameOrNull()).ToArray(); if (!supportedFrameworks.AnySafe(sf => sf == null)) { foreach (var supportedFramework in supportedFrameworks) { package.SupportedFrameworks.Add(new PackageFramework { TargetFramework = supportedFramework }); } } foreach (var dependencySet in nugetPackage.Metadata.DependencySets) { if (dependencySet.Dependencies.Count == 0) { package.Dependencies.Add( new PackageDependency { Id = null, VersionSpec = null, TargetFramework = dependencySet.TargetFramework.ToShortNameOrNull() }); } else { foreach (var dependency in dependencySet.Dependencies.Select(d => new { d.Id, d.VersionSpec, dependencySet.TargetFramework })) { package.Dependencies.Add( new PackageDependency { Id = dependency.Id, VersionSpec = dependency.VersionSpec == null ? null : dependency.VersionSpec.ToString(), TargetFramework = dependency.TargetFramework.ToShortNameOrNull() }); } } } package.FlattenedAuthors = package.Authors.Flatten(); package.FlattenedDependencies = package.Dependencies.Flatten(); return(package); }