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.model.control.security.server.logic;
018
019import com.echothree.control.user.security.common.spec.SecurityRoleUniversalSpec;
020import com.echothree.model.control.core.common.ComponentVendors;
021import com.echothree.model.control.core.common.EntityTypes;
022import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
023import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
024import com.echothree.model.control.security.common.exception.MissingRequiredSecurityRoleGroupNameException;
025import com.echothree.model.control.security.common.exception.UnknownDefaultSecurityRoleException;
026import com.echothree.model.control.security.common.exception.UnknownSecurityRoleNameException;
027import com.echothree.model.control.security.server.control.SecurityControl;
028import com.echothree.model.control.selector.server.control.SelectorControl;
029import com.echothree.model.data.party.server.entity.Party;
030import com.echothree.model.data.security.server.entity.SecurityRole;
031import com.echothree.model.data.security.server.entity.SecurityRoleGroup;
032import com.echothree.util.common.exception.BaseException;
033import com.echothree.util.common.message.ExecutionErrors;
034import com.echothree.util.server.control.BaseLogic;
035import com.echothree.util.server.message.ExecutionErrorAccumulator;
036import com.echothree.util.server.persistence.EntityPermission;
037import com.echothree.util.server.persistence.Session;
038import com.echothree.util.server.validation.ParameterUtils;
039import javax.enterprise.context.ApplicationScoped;
040import javax.enterprise.inject.spi.CDI;
041import javax.inject.Inject;
042
043@ApplicationScoped
044public class SecurityRoleLogic
045        extends BaseLogic {
046
047    @Inject
048    protected SecurityControl securityControl;
049
050    @Inject
051    protected SecurityRoleGroupLogic securityRoleGroupLogic;
052    
053    protected SecurityRoleLogic() {
054        super();
055    }
056
057    public static SecurityRoleLogic getInstance() {
058        return CDI.current().select(SecurityRoleLogic.class).get();
059    }
060
061    public SecurityRole getSecurityRoleByName(final Class<? extends BaseException> unknownSecurityRoleGroupException, final ExecutionErrors unknownSecurityRoleGroupExecutionError,
062            final Class<? extends BaseException>  unknownSecurityRoleException, final ExecutionErrors unknownSecurityRoleExecutionError,
063            final ExecutionErrorAccumulator eea, final String securityRoleGroupName, final String securityRoleName) {
064        var securityRoleGroup = securityRoleGroupLogic.getSecurityRoleGroupByName(unknownSecurityRoleGroupException, unknownSecurityRoleGroupExecutionError,
065                eea, securityRoleGroupName, EntityPermission.READ_ONLY);
066        SecurityRole securityRole = null;
067
068        if(eea == null || !eea.hasExecutionErrors()) {
069            securityRole = getSecurityRoleByName(unknownSecurityRoleException, unknownSecurityRoleExecutionError, eea,
070                    securityRoleGroup, securityRoleName);
071        }
072
073        return securityRole;
074    }
075
076    public SecurityRole getSecurityRoleByName(final Class<? extends BaseException> unknownException, final ExecutionErrors unknownExecutionError,
077            final ExecutionErrorAccumulator eea, final SecurityRoleGroup securityRoleGroup, final String securityRoleName, EntityPermission entityPermission) {
078        var securityRole = securityControl.getSecurityRoleByName(securityRoleGroup, securityRoleName, entityPermission);
079
080        if(securityRole == null) {
081            handleExecutionError(unknownException, eea, unknownExecutionError.name(), securityRoleGroup.getLastDetail().getSecurityRoleGroupName(),
082                    securityRoleName);
083        }
084
085        return securityRole;
086    }
087
088    public SecurityRole getSecurityRoleByName(final Class<? extends BaseException> unknownException, final ExecutionErrors unknownExecutionError,
089            final ExecutionErrorAccumulator eea, final SecurityRoleGroup securityRoleGroup, final String securityRoleName) {
090        return getSecurityRoleByName(unknownException, unknownExecutionError, eea, securityRoleGroup, securityRoleName, EntityPermission.READ_ONLY);
091    }
092
093    public SecurityRole getSecurityRoleByNameForUpdate(final Class<? extends BaseException> unknownException, final ExecutionErrors unknownExecutionError,
094            final ExecutionErrorAccumulator eea, final SecurityRoleGroup securityRoleGroup, final String securityRoleName) {
095        return getSecurityRoleByName(unknownException, unknownExecutionError, eea, securityRoleGroup, securityRoleName, EntityPermission.READ_WRITE);
096    }
097
098    public SecurityRole getSecurityRoleByName(final ExecutionErrorAccumulator eea, final SecurityRoleGroup securityRoleGroup, final String securityRoleName,
099            final EntityPermission entityPermission) {
100        return getSecurityRoleByName(UnknownSecurityRoleNameException.class, ExecutionErrors.UnknownSecurityRoleName,
101                eea, securityRoleGroup, securityRoleName, entityPermission);
102    }
103
104    public SecurityRole getSecurityRoleByName(final ExecutionErrorAccumulator eea, final SecurityRoleGroup securityRoleGroup, final String securityRoleName) {
105        return getSecurityRoleByName(UnknownSecurityRoleNameException.class, ExecutionErrors.UnknownSecurityRoleName,
106                eea, securityRoleGroup, securityRoleName);
107    }
108
109    public SecurityRole getSecurityRoleByNameForUpdate(final ExecutionErrorAccumulator eea, final SecurityRoleGroup securityRoleGroup, final String securityRoleName) {
110        return getSecurityRoleByNameForUpdate(UnknownSecurityRoleNameException.class, ExecutionErrors.UnknownSecurityRoleName,
111                eea, securityRoleGroup, securityRoleName);
112    }
113
114    public SecurityRole getSecurityRoleByName(final ExecutionErrorAccumulator eea, final String securityRoleGroupName, final String securityRoleName,
115            final EntityPermission entityPermission) {
116        var securityRoleGroup = securityRoleGroupLogic.getSecurityRoleGroupByName(eea, securityRoleGroupName);
117        SecurityRole securityRole = null;
118
119        if(eea == null || !eea.hasExecutionErrors()) {
120            securityRole = getSecurityRoleByName(UnknownSecurityRoleNameException.class, ExecutionErrors.UnknownSecurityRoleName,
121                    eea, securityRoleGroup, securityRoleName, entityPermission);
122        }
123
124        return securityRole;
125    }
126
127    public SecurityRole getSecurityRoleByName(final ExecutionErrorAccumulator eea, final String securityRoleGroupName, final String securityRoleName) {
128        return getSecurityRoleByName(eea, securityRoleGroupName, securityRoleName, EntityPermission.READ_ONLY);
129    }
130
131    public SecurityRole getSecurityRoleByNameForUpdate(final ExecutionErrorAccumulator eea, final String securityRoleGroupName, final String securityRoleName) {
132        return getSecurityRoleByName(eea, securityRoleGroupName, securityRoleName, EntityPermission.READ_WRITE);
133    }
134
135    public SecurityRole getSecurityRoleByUniversalSpec(final ExecutionErrorAccumulator eea, final SecurityRoleUniversalSpec universalSpec,
136            final boolean allowDefault, final EntityPermission entityPermission) {
137        var securityRoleGroupName = universalSpec.getSecurityRoleGroupName();
138        var securityRoleName = universalSpec.getSecurityRoleName();
139        var nameParameterCount= ParameterUtils.getInstance().countNonNullParameters(securityRoleGroupName, securityRoleName);
140        var possibleEntitySpecs= EntityInstanceLogic.getInstance().countPossibleEntitySpecs(universalSpec);
141        SecurityRole securityRole = null;
142
143        if(nameParameterCount < 3 && possibleEntitySpecs == 0) {
144            SecurityRoleGroup securityRoleGroup = null;
145
146            if(securityRoleGroupName != null) {
147                securityRoleGroup = securityRoleGroupLogic.getSecurityRoleGroupByName(eea, securityRoleGroupName);
148            } else {
149                handleExecutionError(MissingRequiredSecurityRoleGroupNameException.class, eea, ExecutionErrors.MissingRequiredSecurityRoleGroupName.name());
150            }
151
152            if(!eea.hasExecutionErrors()) {
153                if(securityRoleName == null) {
154                    if(allowDefault) {
155                        securityRole = securityControl.getDefaultSecurityRole(securityRoleGroup, entityPermission);
156
157                        if(securityRole == null) {
158                            handleExecutionError(UnknownDefaultSecurityRoleException.class, eea, ExecutionErrors.UnknownDefaultSecurityRole.name());
159                        }
160                    } else {
161                        handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
162                    }
163                } else {
164                    securityRole = getSecurityRoleByName(eea, securityRoleGroup, securityRoleName, entityPermission);
165                }
166            }
167        } else if(nameParameterCount == 0 && possibleEntitySpecs == 1) {
168            var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, universalSpec,
169                    ComponentVendors.ECHO_THREE.name(), EntityTypes.SecurityRole.name());
170
171            if(!eea.hasExecutionErrors()) {
172                securityRole = securityControl.getSecurityRoleByEntityInstance(entityInstance, entityPermission);
173            }
174        } else {
175            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
176        }
177
178        return securityRole;
179    }
180
181    public SecurityRole getSecurityRoleByUniversalSpec(final ExecutionErrorAccumulator eea, final SecurityRoleUniversalSpec universalSpec,
182            boolean allowDefault) {
183        return getSecurityRoleByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY);
184    }
185
186    public SecurityRole getSecurityRoleByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final SecurityRoleUniversalSpec universalSpec,
187            boolean allowDefault) {
188        return getSecurityRoleByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE);
189    }
190    
191    public boolean hasSecurityRole(final Party party, final SecurityRole securityRole) {
192        var result = false;
193
194        if(party != null) {
195            var partySecurityRole = securityControl.getPartySecurityRole(party, securityRole);
196
197            if(partySecurityRole != null) {
198                var securityRolePartyType = securityControl.getSecurityRolePartyType(securityRole, party.getLastDetail().getPartyType());
199
200                if(securityRolePartyType == null) {
201                    result = true;
202                } else {
203                    var partySelector = securityRolePartyType.getPartySelector();
204
205                    if(partySelector != null) {
206                        var selectorControl = Session.getModelController(SelectorControl.class);
207
208                        if(selectorControl.getSelectorParty(partySelector, party) != null) {
209                            result = true;
210                        }
211                    }
212                }
213            }
214        }
215        
216        return result;
217    }
218
219    public boolean hasSecurityRoleUsingNames(final ExecutionErrorAccumulator eea, final Party party, final String securityRoleGroupName,
220            final String securityRoleName) {
221        var securityRole = getSecurityRoleByName(eea, securityRoleGroupName, securityRoleName);
222        var result = false;
223        
224        if(!hasExecutionErrors(eea)) {
225            result = hasSecurityRole(party, securityRole);
226        }
227        
228        return result;
229    }
230    
231}