001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 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.user.server.control.UserControl;
028import com.echothree.model.control.vendor.server.control.VendorControl;
029import com.echothree.model.data.customer.server.entity.Customer;
030import com.echothree.model.data.employee.server.entity.PartyEmployee;
031import com.echothree.model.data.party.server.entity.Party;
032import com.echothree.model.data.party.server.entity.PartyTypePasswordStringPolicy;
033import com.echothree.model.data.user.common.pk.UserVisitPK;
034import com.echothree.model.data.user.server.entity.UserLoginPassword;
035import com.echothree.model.data.user.server.entity.UserLoginPasswordType;
036import com.echothree.model.data.user.server.entity.UserLoginStatus;
037import com.echothree.model.data.user.server.value.UserLoginPasswordStringValue;
038import com.echothree.model.data.vendor.server.entity.Vendor;
039import com.echothree.util.common.message.ExecutionErrors;
040import com.echothree.util.common.validation.FieldDefinition;
041import com.echothree.util.common.validation.FieldType;
042import com.echothree.util.common.command.BaseResult;
043import com.echothree.util.server.persistence.Session;
044import java.util.Arrays;
045import java.util.Collections;
046import java.util.List;
047
048public class SetPasswordCommand
049        extends BaseLoginCommand<SetPasswordForm> {
050    
051    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
052    
053    static {
054        FORM_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
055                new FieldDefinition("PartyName", FieldType.ENTITY_NAME, false, null, null),
056                new FieldDefinition("EmployeeName", FieldType.ENTITY_NAME, false, null, null),
057                new FieldDefinition("CustomerName", FieldType.ENTITY_NAME, false, null, null),
058                new FieldDefinition("VendorName", FieldType.ENTITY_NAME, false, null, null),
059                new FieldDefinition("OldPassword", FieldType.STRING, false, 1L, 40L),
060                new FieldDefinition("NewPassword1", FieldType.STRING, true, 1L, 40L),
061                new FieldDefinition("NewPassword2", FieldType.STRING, true, 1L, 40L)
062                ));
063    }
064    
065    /** Creates a new instance of SetPasswordCommand */
066    public SetPasswordCommand(UserVisitPK userVisitPK, SetPasswordForm form) {
067        super(userVisitPK, form, null, FORM_FIELD_DEFINITIONS);
068    }
069    
070    @Override
071    protected BaseResult execute() {
072        String partyName = form.getPartyName();
073        String employeeName = form.getEmployeeName();
074        String customerName = form.getCustomerName();
075        String vendorName = form.getVendorName();
076        var parameterCount = (partyName == null ? 0 : 1) + (employeeName == null ? 0 : 1) + (customerName == null ? 0 : 1) + (vendorName == null ? 0 : 1);
077        
078        if(parameterCount < 2) {
079            UserControl userControl = getUserControl();
080            Party self = getParty();
081            Party party = null;
082            
083            if(partyName != null) {
084                var partyControl = Session.getModelController(PartyControl.class);
085                
086                party = partyControl.getPartyByName(partyName);
087                if(party == null) {
088                    addExecutionError(ExecutionErrors.UnknownPartyName.name(), partyName);
089                }
090            } else if(employeeName != null) {
091                var employeeControl = Session.getModelController(EmployeeControl.class);
092                PartyEmployee partyEmployee = employeeControl.getPartyEmployeeByName(employeeName);
093                
094                if(partyEmployee != null) {
095                    party = partyEmployee.getParty();
096                } else {
097                    addExecutionError(ExecutionErrors.UnknownEmployeeName.name(), employeeName);
098                }
099            } else if(customerName != null) {
100                var customerControl = Session.getModelController(CustomerControl.class);
101                Customer customer = customerControl.getCustomerByName(customerName);
102                
103                if(customer != null) {
104                    party = customer.getParty();
105                } else {
106                    addExecutionError(ExecutionErrors.UnknownCustomerName.name(), customerName);
107                }
108            } else if(vendorName != null) {
109                var vendorControl = Session.getModelController(VendorControl.class);
110                Vendor vendor = vendorControl.getVendorByName(vendorName);
111                
112                if(vendor != null) {
113                    party = vendor.getParty();
114                } else {
115                    addExecutionError(ExecutionErrors.UnknownVendorName.name(), vendorName);
116                }
117            } else {
118                party = self;
119            }
120            
121            if(!hasExecutionErrors()) {
122                if(party != null) {
123                    PartyLogic.getInstance().checkPartyType(this, party, PartyTypes.EMPLOYEE.name(), PartyTypes.CUSTOMER.name(),
124                            PartyTypes.VENDOR.name());
125
126                    if(!hasExecutionErrors()) {
127                        UserLoginPasswordType userLoginPasswordType = userControl.getUserLoginPasswordTypeByName(UserConstants.UserLoginPasswordType_STRING);
128                        UserLoginPassword userLoginPassword = userControl.getUserLoginPassword(party, userLoginPasswordType);
129
130                        if(userLoginPassword != null) {
131                            String newPassword1 = form.getNewPassword1();
132                            String newPassword2 = form.getNewPassword2();
133
134                            if(newPassword1.equals(newPassword2)) {
135                                UserLoginStatus userLoginStatus = userControl.getUserLoginStatusForUpdate(party);
136                                String oldPassword = form.getOldPassword();
137
138                                if(oldPassword != null) {
139                                    if(!checkPasswords(userLoginStatus, oldPassword, party, false)) {
140                                        addExecutionError(ExecutionErrors.IncorrectPassword.name());
141                                    }
142                                } else if(party.equals(self)) {
143                                    addExecutionError(ExecutionErrors.MissingOldPassword.name());
144                                }
145
146                                if(!hasExecutionErrors()) {
147                                    UserLoginPasswordStringValue userLoginPasswordStringValue = userControl.getUserLoginPasswordStringValueForUpdate(userLoginPassword);
148                                    PartyTypePasswordStringPolicy partyTypePasswordStringPolicy = PasswordStringPolicyLogic.getInstance().checkStringPassword(session,
149                                            getUserVisit(), this, party, userLoginPassword, userLoginPasswordStringValue, newPassword1);
150
151                                    if(!hasExecutionErrors()) {
152                                        boolean changingForSelf = self.equals(party);
153
154                                        userLoginPasswordStringValue.setPassword(newPassword1);
155                                        userLoginPasswordStringValue.setChangedTime(session.START_TIME_LONG);
156                                        userLoginPasswordStringValue.setWasReset(!changingForSelf);
157
158                                        userControl.updateUserLoginPasswordStringFromValue(userLoginPasswordStringValue, self.getPrimaryKey());
159
160                                        userLoginStatus.setExpiredCount(0);
161                                        userLoginStatus.setForceChange(changingForSelf ? Boolean.FALSE : partyTypePasswordStringPolicy == null? Boolean.FALSE
162                                                : partyTypePasswordStringPolicy.getLastDetail().getForceChangeAfterReset());
163                                    }
164                                }
165                            } else {
166                                addExecutionError(ExecutionErrors.MismatchedPasswords.name());
167                            }
168                        } else {
169                            addExecutionError(ExecutionErrors.UnknownUserLoginPassword.name());
170                        }
171                    }
172                } else {
173                    addExecutionError(ExecutionErrors.UnknownParty.name());
174                }
175            }
176        } else {
177            addExecutionError(ExecutionErrors.InvalidParameterCount.name());
178        }
179        
180        return null;
181    }
182    
183}