001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.control.user.authentication.server.command;
018
019import com.echothree.control.user.authentication.common.form.SetPasswordForm;
020import com.echothree.model.control.customer.server.control.CustomerControl;
021import com.echothree.model.control.employee.server.control.EmployeeControl;
022import com.echothree.model.control.party.common.PartyTypes;
023import com.echothree.model.control.party.server.control.PartyControl;
024import com.echothree.model.control.party.server.logic.PartyLogic;
025import com.echothree.model.control.party.server.logic.PasswordStringPolicyLogic;
026import com.echothree.model.control.user.common.UserConstants;
027import com.echothree.model.control.vendor.server.control.VendorControl;
028import com.echothree.model.data.party.server.entity.Party;
029import com.echothree.util.common.command.BaseResult;
030import com.echothree.util.common.message.ExecutionErrors;
031import com.echothree.util.common.validation.FieldDefinition;
032import com.echothree.util.common.validation.FieldType;
033import com.echothree.util.server.persistence.Session;
034import java.util.Arrays;
035import java.util.Collections;
036import java.util.List;
037import javax.enterprise.context.RequestScoped;
038
039@RequestScoped
040public class SetPasswordCommand
041        extends BaseLoginCommand<SetPasswordForm> {
042    
043    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
044    
045    static {
046        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
047                new FieldDefinition("PartyName", FieldType.ENTITY_NAME, false, null, null),
048                new FieldDefinition("EmployeeName", FieldType.ENTITY_NAME, false, null, null),
049                new FieldDefinition("CustomerName", FieldType.ENTITY_NAME, false, null, null),
050                new FieldDefinition("VendorName", FieldType.ENTITY_NAME, false, null, null),
051                new FieldDefinition("OldPassword", FieldType.STRING, false, 1L, 40L),
052                new FieldDefinition("NewPassword1", FieldType.STRING, true, 1L, 40L),
053                new FieldDefinition("NewPassword2", FieldType.STRING, true, 1L, 40L)
054                ));
055    }
056    
057    /** Creates a new instance of SetPasswordCommand */
058    public SetPasswordCommand() {
059        super(null, FORM_FIELD_DEFINITIONS);
060    }
061    
062    @Override
063    protected BaseResult execute() {
064        var partyName = form.getPartyName();
065        var employeeName = form.getEmployeeName();
066        var customerName = form.getCustomerName();
067        var vendorName = form.getVendorName();
068        var parameterCount = (partyName == null ? 0 : 1) + (employeeName == null ? 0 : 1) + (customerName == null ? 0 : 1) + (vendorName == null ? 0 : 1);
069        
070        if(parameterCount < 2) {
071            var userControl = getUserControl();
072            var self = getParty();
073            Party party = null;
074            
075            if(partyName != null) {
076                var partyControl = Session.getModelController(PartyControl.class);
077                
078                party = partyControl.getPartyByName(partyName);
079                if(party == null) {
080                    addExecutionError(ExecutionErrors.UnknownPartyName.name(), partyName);
081                }
082            } else if(employeeName != null) {
083                var employeeControl = Session.getModelController(EmployeeControl.class);
084                var partyEmployee = employeeControl.getPartyEmployeeByName(employeeName);
085                
086                if(partyEmployee != null) {
087                    party = partyEmployee.getParty();
088                } else {
089                    addExecutionError(ExecutionErrors.UnknownEmployeeName.name(), employeeName);
090                }
091            } else if(customerName != null) {
092                var customerControl = Session.getModelController(CustomerControl.class);
093                var customer = customerControl.getCustomerByName(customerName);
094                
095                if(customer != null) {
096                    party = customer.getParty();
097                } else {
098                    addExecutionError(ExecutionErrors.UnknownCustomerName.name(), customerName);
099                }
100            } else if(vendorName != null) {
101                var vendorControl = Session.getModelController(VendorControl.class);
102                var vendor = vendorControl.getVendorByName(vendorName);
103                
104                if(vendor != null) {
105                    party = vendor.getParty();
106                } else {
107                    addExecutionError(ExecutionErrors.UnknownVendorName.name(), vendorName);
108                }
109            } else {
110                party = self;
111            }
112            
113            if(!hasExecutionErrors()) {
114                if(party != null) {
115                    PartyLogic.getInstance().checkPartyType(this, party, PartyTypes.EMPLOYEE.name(), PartyTypes.CUSTOMER.name(),
116                            PartyTypes.VENDOR.name());
117
118                    if(!hasExecutionErrors()) {
119                        var userLoginPasswordType = userControl.getUserLoginPasswordTypeByName(UserConstants.UserLoginPasswordType_STRING);
120                        var userLoginPassword = userControl.getUserLoginPassword(party, userLoginPasswordType);
121
122                        if(userLoginPassword != null) {
123                            var newPassword1 = form.getNewPassword1();
124                            var newPassword2 = form.getNewPassword2();
125
126                            if(newPassword1.equals(newPassword2)) {
127                                var userLoginStatus = userControl.getUserLoginStatusForUpdate(party);
128                                var oldPassword = form.getOldPassword();
129
130                                if(oldPassword != null) {
131                                    if(!checkPasswords(userLoginStatus, oldPassword, party, false)) {
132                                        addExecutionError(ExecutionErrors.IncorrectPassword.name());
133                                    }
134                                } else if(party.equals(self)) {
135                                    addExecutionError(ExecutionErrors.MissingOldPassword.name());
136                                }
137
138                                if(!hasExecutionErrors()) {
139                                    var userLoginPasswordStringValue = userControl.getUserLoginPasswordStringValueForUpdate(userLoginPassword);
140                                    var partyTypePasswordStringPolicy = PasswordStringPolicyLogic.getInstance().checkStringPassword(session,
141                                            getUserVisit(), this, party, userLoginPassword, userLoginPasswordStringValue, newPassword1);
142
143                                    if(!hasExecutionErrors()) {
144                                        var changingForSelf = self.equals(party);
145
146                                        userLoginPasswordStringValue.setPassword(newPassword1);
147                                        userLoginPasswordStringValue.setChangedTime(session.START_TIME_LONG);
148                                        userLoginPasswordStringValue.setWasReset(!changingForSelf);
149
150                                        userControl.updateUserLoginPasswordStringFromValue(userLoginPasswordStringValue, self.getPrimaryKey());
151
152                                        userLoginStatus.setExpiredCount(0);
153                                        userLoginStatus.setForceChange(changingForSelf ? false : partyTypePasswordStringPolicy == null? false
154                                                : partyTypePasswordStringPolicy.getLastDetail().getForceChangeAfterReset());
155                                    }
156                                }
157                            } else {
158                                addExecutionError(ExecutionErrors.MismatchedPasswords.name());
159                            }
160                        } else {
161                            addExecutionError(ExecutionErrors.UnknownUserLoginPassword.name());
162                        }
163                    }
164                } else {
165                    addExecutionError(ExecutionErrors.UnknownParty.name());
166                }
167            }
168        } else {
169            addExecutionError(ExecutionErrors.InvalidParameterCount.name());
170        }
171        
172        return null;
173    }
174    
175}