Example #1
0
        /// <summary>
        /// Changes the users password.
        /// </summary>
        /// <param name="userName">The username of the user.</param>
        /// <param name="newPassword">The new password of the user.</param>
        /// <param name="principal">The authentication principal (the user that is changing the password).</param>
        public void ChangePassword(string userName, string newPassword, System.Security.Principal.IPrincipal principal)
        {
            try
            {
                // The principal must change their own password or must have the changepassword credential
                if (!userName.Equals(principal.Identity.Name, StringComparison.InvariantCultureIgnoreCase))
                {
                    new PolicyPermission(System.Security.Permissions.PermissionState.Unrestricted, PermissionPolicyIdentifiers.ChangePassword).Demand();
                }
                else if (!principal.Identity.IsAuthenticated)
                {
                    throw new InvalidOperationException("Unauthenticated principal cannot change user password");
                }

                // Get the user's identity
                var securityUserService = ApplicationContext.Current.GetService <ISecurityRepositoryService>();
                var localIdp            = ApplicationContext.Current.GetService <IOfflineIdentityProviderService>();
                if (localIdp?.IsLocalUser(userName) == true) // User is a local user, so we only change password on local
                {
                    localIdp.ChangePassword(userName, newPassword, principal);
                }
                else
                {
                    using (AmiServiceClient client = new AmiServiceClient(ApplicationContext.Current.GetRestClient("ami")))
                    {
                        Guid userId = Guid.Empty;
                        if (principal.Identity.Name.ToLowerInvariant() == userName.ToLowerInvariant())
                        {
                            var subjectClaim = (principal as IClaimsPrincipal).FindFirst(SanteDBClaimTypes.Sid);
                            if (subjectClaim != null)
                            {
                                userId = Guid.Parse(subjectClaim.Value);
                            }
                        }

                        // User ID not found - lookup
                        if (userId == Guid.Empty)
                        {
                            // User service is null
                            var securityUser = securityUserService.GetUser(userName);
                            if (securityUser == null)
                            {
                                var tuser = client.GetUsers(o => o.UserName == userName).CollectionItem.OfType <SecurityUserInfo>().FirstOrDefault();
                                if (tuser == null)
                                {
                                    throw new ArgumentException(string.Format("User {0} not found", userName));
                                }
                                else
                                {
                                    userId = tuser.Entity.Key.Value;
                                }
                            }
                            else
                            {
                                userId = securityUser.Key.Value;
                            }
                        }

                        // Use the current configuration's credential provider
                        var user = new SecurityUserInfo(new SecurityUser()
                        {
                            Key      = userId,
                            UserName = userName,
                            Password = newPassword
                        })
                        {
                            PasswordOnly = true
                        };

                        // Set the credentials
                        client.Client.Credentials = ApplicationContext.Current.Configuration.GetServiceDescription("ami").Binding.Security.CredentialProvider.GetCredentials(principal);

                        client.UpdateUser(userId, user);

                        // Change locally
                        var userInfo = localIdp?.GetIdentity(userName);
                        if (userInfo != null)
                        {
                            localIdp?.ChangePassword(userName, newPassword, principal);
                        }

                        // Audit - Local IDP has alerted this already
                        AuditUtil.AuditSecurityAttributeAction(new object[] { user.ToIdentifiedData() }, true, new string[] { "password" });
                    }
                }
            }
            catch (Exception e)
            {
                this.m_tracer.TraceError("Error changing password for user {0} : {1}", userName, e);
                throw;
            }
        }