Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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();
        }
Example #7
0
        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();
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }