1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sec.document;
17
18 import java.util.Collection;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.kuali.ole.sec.businessobject.SecurityDefinition;
26 import org.kuali.ole.sec.businessobject.SecurityModel;
27 import org.kuali.ole.sec.businessobject.SecurityModelDefinition;
28 import org.kuali.ole.sec.businessobject.SecurityModelMember;
29 import org.kuali.ole.sec.businessobject.SecurityPrincipal;
30 import org.kuali.ole.sys.OLEConstants;
31 import org.kuali.ole.sys.context.SpringContext;
32 import org.kuali.rice.core.api.membership.MemberType;
33 import org.kuali.rice.kew.api.exception.WorkflowException;
34 import org.kuali.rice.kim.api.group.GroupService;
35 import org.kuali.rice.kim.api.role.Role;
36 import org.kuali.rice.kim.api.role.RoleMember;
37 import org.kuali.rice.kim.api.role.RoleService;
38 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
39 import org.kuali.rice.kns.document.MaintenanceDocument;
40 import org.kuali.rice.krad.bo.DocumentHeader;
41 import org.kuali.rice.krad.service.BusinessObjectService;
42 import org.kuali.rice.krad.service.DocumentService;
43 import org.kuali.rice.krad.util.KRADConstants;
44 import org.springframework.util.ObjectUtils;
45
46
47
48
49
50
51 public class SecurityModelMaintainableImpl extends AbstractSecurityModuleMaintainable {
52 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SecurityModelMaintainableImpl.class);
53
54
55
56
57 @Override
58 public void doRouteStatusChange(DocumentHeader documentHeader) {
59 super.doRouteStatusChange(documentHeader);
60
61 if (documentHeader.getWorkflowDocument().isProcessed()) {
62 DocumentService documentService = SpringContext.getBean(DocumentService.class);
63 try {
64 MaintenanceDocument document = (MaintenanceDocument) documentService.getByDocumentHeaderId(documentHeader.getDocumentNumber());
65 SecurityModel oldSecurityModel = (SecurityModel) document.getOldMaintainableObject().getBusinessObject();
66 SecurityModel newSecurityModel = (SecurityModel) document.getNewMaintainableObject().getBusinessObject();
67
68 boolean newMaintenanceAction = getMaintenanceAction().equalsIgnoreCase(KRADConstants.MAINTENANCE_NEW_ACTION) || getMaintenanceAction().equalsIgnoreCase(KRADConstants.MAINTENANCE_COPY_ACTION);
69
70 Role modelRole = createOrUpdateModelRole(newSecurityModel);
71 assignOrUpdateModelMembershipToDefinitionRoles(modelRole, oldSecurityModel, newSecurityModel, newMaintenanceAction);
72 assignOrUpdateModelMembers(modelRole, newSecurityModel);
73
74 if (!newSecurityModel.isActive()) {
75 inactivateModelRole(modelRole);
76 }
77 }
78 catch (WorkflowException e) {
79 LOG.error("caught exception while handling handleRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
80 throw new RuntimeException("caught exception while handling handleRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
81 }
82 }
83 }
84
85
86
87
88
89
90
91 protected Role createOrUpdateModelRole(SecurityModel newSecurityModel) {
92 RoleService roleService = KimApiServiceLocator.getRoleService();
93
94
95 Role modelRole = roleService.getRoleByNamespaceCodeAndName(OLEConstants.CoreModuleNamespaces.ACCESS_SECURITY, newSecurityModel.getName());
96
97 if ( modelRole != null ) {
98
99
100 Role.Builder updatedRole = Role.Builder.create(modelRole);
101 updatedRole.setActive(true);
102 updatedRole.setDescription(newSecurityModel.getDescription());
103 modelRole = roleService.updateRole(updatedRole.build());
104 } else {
105 String roleId = OLEConstants.CoreModuleNamespaces.ACCESS_SECURITY+"-"+newSecurityModel.getId();
106 Role.Builder newRole = Role.Builder.create();
107 newRole.setId(roleId);
108 newRole.setName(newSecurityModel.getName());
109 newRole.setNamespaceCode(OLEConstants.CoreModuleNamespaces.ACCESS_SECURITY);
110 newRole.setDescription(newSecurityModel.getDescription());
111 newRole.setKimTypeId(getDefaultRoleTypeId());
112 newRole.setActive(true);
113 modelRole = roleService.createRole(newRole.build());
114 }
115 newSecurityModel.setRoleId(modelRole.getId());
116 return modelRole;
117 }
118
119
120
121
122
123
124 protected void inactivateModelRole(Role modelRole) {
125 RoleService roleService = KimApiServiceLocator.getRoleService();
126
127 if ( modelRole != null ) {
128 Role.Builder updatedRole = Role.Builder.create(modelRole);
129 updatedRole.setActive(false);
130 KimApiServiceLocator.getRoleService().updateRole(updatedRole.build());
131 }
132 }
133
134
135
136
137
138
139
140
141
142 protected void assignOrUpdateModelMembershipToDefinitionRoles(Role modelRole, SecurityModel oldSecurityModel, SecurityModel newSecurityModel, boolean newMaintenanceAction) {
143 RoleService roleService = KimApiServiceLocator.getRoleService();
144
145 if ( modelRole == null ) {
146 LOG.error( "Model Role does not exist for SecurityModel: " + newSecurityModel );
147 throw new RuntimeException("Model Role does not exist for SecurityModel: " + newSecurityModel );
148 }
149
150 for (SecurityModelDefinition securityModelDefinition : newSecurityModel.getModelDefinitions()) {
151 SecurityDefinition securityDefinition = securityModelDefinition.getSecurityDefinition();
152
153 Role definitionRole = roleService.getRole(securityDefinition.getRoleId());
154
155 if ( definitionRole == null ) {
156 LOG.error( "Definition Role does not exist for SecurityModelDefinition: " + securityDefinition );
157 throw new RuntimeException("Definition Role does not exist for SecurityModelDefinition: " + securityDefinition );
158 }
159
160 RoleMember modelRoleMembership = null;
161 if (!newMaintenanceAction) {
162 SecurityModelDefinition oldSecurityModelDefinition = null;
163 for (SecurityModelDefinition modelDefinition : oldSecurityModel.getModelDefinitions()) {
164 if ( ObjectUtils.nullSafeEquals(modelDefinition.getModelDefinitionId(), securityModelDefinition.getModelDefinitionId()) ) {
165 oldSecurityModelDefinition = modelDefinition;
166 break;
167 }
168 }
169
170 if (oldSecurityModelDefinition != null) {
171 modelRoleMembership = getRoleMembershipForMemberType(definitionRole.getId(),
172 modelRole.getId(), MemberType.ROLE.getCode(),
173 getRoleQualifiersFromSecurityModelDefinition(oldSecurityModelDefinition));
174 }
175 }
176
177
178 boolean membershipActive = newSecurityModel.isActive() && securityModelDefinition.isActive();
179
180
181
182 if (modelRoleMembership != null) {
183 if (!membershipActive) {
184 roleService.removeRoleFromRole(modelRoleMembership.getMemberId(), definitionRole.getNamespaceCode(), definitionRole.getName(), modelRoleMembership.getAttributes());
185 }
186 }
187
188
189 if (membershipActive) {
190 if ( modelRoleMembership == null ) {
191 modelRoleMembership = roleService.assignRoleToRole(modelRole.getId(), definitionRole.getNamespaceCode(), definitionRole.getName(), getRoleQualifiersFromSecurityModelDefinition(securityModelDefinition));
192 } else {
193 RoleMember.Builder updatedRoleMember = RoleMember.Builder.create(modelRoleMembership);
194 updatedRoleMember.setActiveToDate(null);
195 updatedRoleMember.setAttributes(getRoleQualifiersFromSecurityModelDefinition(securityModelDefinition));
196 modelRoleMembership = roleService.updateRoleMember(updatedRoleMember.build());
197 }
198 }
199 }
200 }
201
202
203
204
205
206
207 protected void assignOrUpdateModelMembers( Role modelRole, SecurityModel securityModel) {
208 if (modelRole == null) {
209
210 String error = "Data problem with access security. KIM Role backing the security model is missing. SecurityModel: " + securityModel;
211 LOG.error(error);
212 throw new RuntimeException(error);
213 }
214
215 for (SecurityModelMember modelMember : securityModel.getModelMembers()) {
216 updateSecurityModelRoleMember(modelRole, modelMember, modelMember.getMemberTypeCode(), modelMember.getMemberId(), new HashMap<String, String>(0));
217
218 createPrincipalSecurityRecords(modelMember.getMemberId(), modelMember.getMemberTypeCode());
219 }
220 }
221
222
223
224
225
226
227
228
229 protected void createPrincipalSecurityRecords(String memberId, String memberTypeCode) {
230 Collection<String> principalIds = new HashSet<String>();
231
232 if (MemberType.PRINCIPAL.getCode().equals(memberTypeCode)) {
233 principalIds.add(memberId);
234 }
235 else if (MemberType.ROLE.getCode().equals(memberTypeCode)) {
236 Role roleInfo = KimApiServiceLocator.getRoleService().getRole(memberId);
237 Collection<String> rolePrincipalIds = KimApiServiceLocator.getRoleService().getRoleMemberPrincipalIds(roleInfo.getNamespaceCode(), roleInfo.getName(), null);
238 principalIds.addAll(rolePrincipalIds);
239 }
240 else if (MemberType.GROUP.getCode().equals(memberTypeCode)) {
241 List<String> groupPrincipalIds = KimApiServiceLocator.getGroupService().getMemberPrincipalIds(memberId);
242 principalIds.addAll(groupPrincipalIds);
243 }
244
245 BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
246 for (String principalId : principalIds) {
247 SecurityPrincipal securityPrincipal = businessObjectService.findBySinglePrimaryKey(SecurityPrincipal.class, principalId);
248 if (securityPrincipal == null) {
249 SecurityPrincipal newSecurityPrincipal = new SecurityPrincipal();
250 newSecurityPrincipal.setPrincipalId(principalId);
251
252 businessObjectService.save(newSecurityPrincipal);
253 }
254 }
255 }
256
257
258
259
260
261
262
263
264 protected boolean isDefinitionInModel(String definitionName, SecurityModel securityModel) {
265 for (SecurityModelDefinition securityModelDefinition : securityModel.getModelDefinitions()) {
266 if (StringUtils.equalsIgnoreCase(definitionName, securityModelDefinition.getSecurityDefinition().getName())) {
267 return true;
268 }
269 }
270
271 return false;
272 }
273
274
275
276
277
278
279
280 @Override
281 public void processAfterCopy(MaintenanceDocument document, Map<String, String[]> parameters) {
282 SecurityModel securityModel = (SecurityModel) document.getNewMaintainableObject().getBusinessObject();
283 securityModel.setRoleId("");
284
285 super.processAfterCopy(document, parameters);
286 }
287
288
289 }