1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.kim.impl.jaxb;
17  
18  import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
19  
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Set;
23  
24  import javax.xml.bind.UnmarshalException;
25  
26  import org.apache.commons.lang.StringUtils;
27  import org.joda.time.DateTime;
28  import org.kuali.rice.core.api.criteria.QueryByCriteria;
29  import org.kuali.rice.core.api.membership.MemberType;
30  import org.kuali.rice.core.util.jaxb.NameAndNamespacePair;
31  import org.kuali.rice.kim.api.group.GroupContract;
32  import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
33  import org.kuali.rice.kim.api.permission.PermissionContract;
34  import org.kuali.rice.kim.api.role.Role;
35  import org.kuali.rice.kim.api.role.RoleContract;
36  import org.kuali.rice.kim.api.role.RoleMember;
37  import org.kuali.rice.kim.api.role.RoleMemberContract;
38  import org.kuali.rice.kim.api.role.RoleService;
39  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  public final class RoleXmlUtil {
51      
52      private RoleXmlUtil() {}
53  
54      
55  
56  
57  
58  
59  
60  
61  
62      static String validateAndPersistNewRole(RoleXmlDTO newRole) throws UnmarshalException {
63          if (newRole == null) {
64              throw new IllegalArgumentException("Cannot persist a null role");
65          }
66          
67          
68          validateAndPrepareRole(newRole);
69  
70          Role.Builder builder = Role.Builder.create();
71          builder.setActive(newRole.getActive());
72          builder.setDescription(newRole.getRoleDescription());
73          builder.setId(newRole.getRoleId());
74          builder.setKimTypeId(newRole.getKimTypeId());
75          builder.setName(newRole.getRoleName());
76          builder.setNamespaceCode(newRole.getNamespaceCode());
77  
78          
79          Role role = KimApiServiceLocator.getRoleService().createRole(builder.build());
80  
81          
82          newRole.setAlreadyPersisted(true);
83          
84          return role.getId();
85      }
86      
87      
88  
89  
90  
91  
92  
93  
94  
95      static String validateAndPersistNewRoleMember(RoleMemberXmlDTO newRoleMember) throws UnmarshalException {
96          
97          if (newRoleMember == null) {
98              throw new IllegalArgumentException("Cannot persist a null role member");
99          }
100         
101         
102         validateRoleIdAndRoleNameForMember(newRoleMember);
103         
104         
105         validateMemberIdentity(newRoleMember);
106         
107         
108         if (newRoleMember.getActiveFromDate() != null && newRoleMember.getActiveToDate() != null &&
109                 newRoleMember.getActiveFromDate().compareTo(newRoleMember.getActiveToDate()) > 0) {
110             throw new UnmarshalException("Cannot create a role member whose activeFromDate occurs after its activeToDate");
111         }
112         
113         
114         if (newRoleMember.getQualifications() == null) {
115             newRoleMember.setQualifications(new HashMap<String, String>());
116         }
117 
118         RoleMember.Builder builder = RoleMember.Builder.create(newRoleMember.getRoleId(), newRoleMember.getRoleIdAsMember(),
119                 newRoleMember.getMemberId(), newRoleMember.getMemberType(),
120                 newRoleMember.getActiveFromDate() == null ? null : new DateTime(newRoleMember.getActiveFromDate().getMillis()),
121                 newRoleMember.getActiveToDate() == null ? null : new DateTime(newRoleMember.getActiveToDate().getMillis()),
122                 newRoleMember.getQualifications(), null, null);
123 
124         
125         RoleMemberContract newMember = KimApiServiceLocator.getRoleService().createRoleMember(builder.build());
126         
127         return newMember.getId();
128     }
129     
130     
131 
132 
133 
134 
135 
136 
137     static void validateAndPersistNewRolePermission(RolePermissionXmlDTO newRolePermission) throws UnmarshalException {
138         if (newRolePermission == null) {
139             throw new IllegalArgumentException("newRolePermission cannot be null");
140         }
141         
142         
143         validateAndPrepareRolePermission(newRolePermission);
144         
145         
146         KimApiServiceLocator.getRoleService().assignPermissionToRole(newRolePermission.getPermissionId(), newRolePermission.getRoleId());
147     }
148     
149     
150 
151 
152 
153 
154 
155 
156     static void removeRoleMembers(String roleId, Set<String> existingRoleMemberIds) {
157         if (StringUtils.isBlank(roleId)) {
158             throw new IllegalArgumentException("roleId cannot be blank");
159         } else if (existingRoleMemberIds == null) {
160             throw new IllegalArgumentException("existingRoleMemberIds cannot be null");
161         }
162         RoleService roleUpdateService = KimApiServiceLocator.getRoleService();
163         RoleContract role = KimApiServiceLocator.getRoleService().getRole(roleId);
164         if (role == null) {
165             throw new IllegalArgumentException("Cannot remove role members for role with ID \"" + roleId + "\" because that role does not exist");
166         }
167         
168         
169         List<RoleMember> roleMembers = KimApiServiceLocator.getRoleService().findRoleMembers(
170                 QueryByCriteria.Builder.fromPredicates(equal("roleId", roleId))).getResults();
171         if (roleMembers != null && !roleMembers.isEmpty()) {
172             for (RoleMemberContract roleMember : roleMembers) {
173                 if (!existingRoleMemberIds.contains(roleMember.getId())) {
174                     
175                     MemberType memberType = roleMember.getType();
176                     if (MemberType.PRINCIPAL.equals(memberType)) {
177                         roleUpdateService.removePrincipalFromRole(roleMember.getMemberId(), role.getNamespaceCode(), role.getName(),
178                                 (roleMember.getAttributes() != null) ? roleMember.getAttributes() : new HashMap<String, String>());
179                     } else if (MemberType.GROUP.equals(memberType)) {
180                         roleUpdateService.removeGroupFromRole(roleMember.getMemberId(), role.getNamespaceCode(), role.getName(),
181                                 (roleMember.getAttributes() != null) ? roleMember.getAttributes() :new HashMap<String, String>());
182                     } else if (MemberType.ROLE.equals(memberType)) {
183                         roleUpdateService.removeRoleFromRole(roleMember.getMemberId(), role.getNamespaceCode(), role.getName(),
184                                 (roleMember.getAttributes() != null) ? roleMember.getAttributes() : new HashMap<String, String>());
185                     }
186                 }
187             }
188         }
189     }
190     
191     
192 
193 
194     private static void validateAndPrepareRole(RoleXmlDTO newRole) throws UnmarshalException {
195         
196         if (StringUtils.isBlank(newRole.getRoleName()) || StringUtils.isBlank(newRole.getNamespaceCode())) {
197             throw new UnmarshalException("Cannot create or override a role with a blank name or a blank namespace");
198         } else if (StringUtils.isBlank(newRole.getKimTypeId())) {
199             throw new UnmarshalException("Cannot create or override a role without specikfying a KIM type");
200         } else if (StringUtils.isBlank(newRole.getRoleDescription())) {
201             throw new UnmarshalException("Cannot create or override a role with a blank description");
202         }
203         
204         
205         String matchingId = KimApiServiceLocator.getRoleService().getRoleIdByNamespaceCodeAndName(
206                 newRole.getNamespaceCode(), newRole.getRoleName());
207         if (StringUtils.isNotBlank(matchingId)) {
208             newRole.setRoleId(matchingId);
209         }
210     }
211     
212     
213 
214 
215     private static void validateRoleIdAndRoleNameForMember(RoleMemberXmlDTO newRoleMember) throws UnmarshalException {
216         
217         if (newRoleMember instanceof RoleMemberXmlDTO.OutsideOfRole) {
218             RoleMemberXmlDTO.OutsideOfRole standaloneMember = (RoleMemberXmlDTO.OutsideOfRole) newRoleMember;
219             if (standaloneMember.getRoleNameAndNamespace() != null) {
220                 
221                 String existingId = KimApiServiceLocator.getRoleService().getRoleIdByNamespaceCodeAndName(
222                         standaloneMember.getRoleNamespaceCode(), standaloneMember.getRoleName());
223                 if (StringUtils.isBlank(existingId)) {
224                     throw new UnmarshalException("Cannot create role member for role with name \"" + standaloneMember.getRoleName() + "\" and namespace \"" +
225                             standaloneMember.getRoleNamespaceCode() + "\" because such a role does not exist");
226                 }
227                 
228                 
229                 if (StringUtils.isBlank(standaloneMember.getRoleId())) {
230                     standaloneMember.setRoleId(existingId);
231                 } else if (!standaloneMember.getRoleId().equals(existingId)) {
232                     throw new UnmarshalException("Cannot create role member for role with ID \"" + standaloneMember.getRoleId() + "\", name \"" +
233                             standaloneMember.getRoleName() + "\", and namespace \"" + standaloneMember.getRoleNamespaceCode() +
234                                     "\" because the existing role with the same name and namespace has an ID of \"" + existingId + "\" instead");
235                 }
236             } else if (StringUtils.isBlank(standaloneMember.getRoleId())) {
237                 throw new UnmarshalException("Cannot create role member without providing the role ID or role name + namespace that the member belongs to");
238             } else if (KimApiServiceLocator.getRoleService().getRole(standaloneMember.getRoleId()) == null) {
239                 throw new UnmarshalException("Cannot create role member for the role with ID \"" + standaloneMember.getRoleId() + "\" because that role does not exist");
240             }
241         }
242         
243         
244         if (StringUtils.isBlank(newRoleMember.getRoleId())) {
245             throw new UnmarshalException("Cannot create role member without providing the role ID or role name + namespace that the member belongs to");
246         }
247     }
248     
249     
250 
251 
252     private static void validateMemberIdentity(RoleMemberXmlDTO newRoleMember) throws UnmarshalException {
253         
254         MemberType memberType = newRoleMember.getMemberType();
255         if (memberType == null) {
256             throw new UnmarshalException("Cannot create a role member with no member principal/group/role identification information specified");
257         }
258         
259         
260         if (StringUtils.isNotBlank(newRoleMember.getMemberId())) {
261             if (MemberType.PRINCIPAL.equals(memberType)) {
262                 
263                 if (KimApiServiceLocator.getIdentityService().getPrincipal(newRoleMember.getPrincipalId()) == null) {
264                     throw new UnmarshalException("Cannot create principal role member with principal ID \"" +
265                             newRoleMember.getPrincipalId() + "\" because such a person does not exist");
266                 }
267             } else if (MemberType.GROUP.equals(memberType)) {
268                 
269                 if (KimApiServiceLocator.getGroupService().getGroup(newRoleMember.getGroupId()) == null) {
270                     throw new UnmarshalException("Cannot create group role member with group ID \"" +
271                             newRoleMember.getGroupId() + "\" because such a group does not exist");
272                 }
273             } else if (MemberType.ROLE.equals(memberType)) {
274                 
275                 if (newRoleMember.getRoleId().equals(newRoleMember.getRoleIdAsMember())) {
276                     throw new UnmarshalException("The role with ID \"" + newRoleMember.getRoleIdAsMember() + "\" cannot be made a member of itself");
277                 } else if (KimApiServiceLocator.getRoleService().getRole(newRoleMember.getRoleIdAsMember()) == null) {
278                     throw new UnmarshalException("Cannot use role with ID \"" + newRoleMember.getRoleIdAsMember() +
279                             "\" as a role member because such a role does not exist");
280                 }
281             }
282         }
283         
284         
285         if (StringUtils.isNotBlank(newRoleMember.getMemberName())) {
286             if (MemberType.PRINCIPAL.equals(memberType)) {
287                 
288                 PrincipalContract tempPrincipal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(newRoleMember.getPrincipalName());
289                 if (tempPrincipal == null) {
290                     throw new UnmarshalException("Cannot create principal role member with principal name \"" +
291                             newRoleMember.getPrincipalName() + "\" because such a person does not exist");
292                 } else if (StringUtils.isBlank(newRoleMember.getPrincipalId())) {
293                     
294                     newRoleMember.setPrincipalId(tempPrincipal.getPrincipalId());
295                 } else if (!newRoleMember.getPrincipalId().equals(tempPrincipal.getPrincipalId())) {
296                     throw new UnmarshalException("Cannot create principal role member with principal ID \"" + newRoleMember.getPrincipalId() +
297                             "\" and principal name \"" + newRoleMember.getPrincipalName() + "\" because the principal with that name has an ID of \"" +
298                                     tempPrincipal.getPrincipalId() + "\" instead");
299                 }
300             } else if (MemberType.GROUP.equals(memberType)) {
301                 
302                 NameAndNamespacePair groupNameAndNamespace = newRoleMember.getGroupName();
303                 GroupContract tempGroup = KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(
304                         groupNameAndNamespace.getNamespaceCode(), groupNameAndNamespace.getName());
305                 if (tempGroup == null) {
306                     throw new UnmarshalException("Cannot create group role member with namespace \"" + groupNameAndNamespace.getNamespaceCode() +
307                             "\" and name \"" + groupNameAndNamespace.getName() + "\" because such a group does not exist");
308                 } else if (StringUtils.isBlank(newRoleMember.getGroupId())) {
309                     
310                     newRoleMember.setGroupId(tempGroup.getId());
311                 } else if (!newRoleMember.getGroupId().equals(tempGroup.getId())) {
312                     throw new UnmarshalException("Cannot create group role member with ID \"" + newRoleMember.getGroupId() + "\", namespace \"" +
313                             groupNameAndNamespace.getNamespaceCode() + "\", and name \"" + groupNameAndNamespace.getName() +
314                                     "\" because the group with that namespace and name has an ID of \"" + tempGroup.getId() + "\" instead");
315                 }
316             } else if (MemberType.ROLE.equals(memberType)) {
317                 
318                 NameAndNamespacePair roleNameAndNamespace = newRoleMember.getRoleNameAsMember();
319                 RoleContract tempRole = KimApiServiceLocator.getRoleService().getRoleByNamespaceCodeAndName(
320                         roleNameAndNamespace.getNamespaceCode(), roleNameAndNamespace.getName());
321                 if (tempRole == null) {
322                     throw new UnmarshalException("Cannot use role with namespace \"" + roleNameAndNamespace.getNamespaceCode() +
323                             "\" and name \"" + roleNameAndNamespace.getName() + "\" as a role member because such a role does not exist");
324                 } else if (newRoleMember.getRoleId().equals(tempRole.getId())) {
325                     throw new UnmarshalException("The role with namespace \"" + roleNameAndNamespace.getNamespaceCode() +
326                             "\" and name \"" + roleNameAndNamespace.getName() + "\" cannot be made a member of itself");
327                 } else if (StringUtils.isBlank(newRoleMember.getRoleId())) {
328                     
329                     newRoleMember.setRoleIdAsMember(tempRole.getId());
330                 } else if (!newRoleMember.getRoleId().equals(tempRole.getId())) {
331                     throw new RuntimeException("Cannot use role with ID \"" + newRoleMember.getRoleId() + "\", namespace \"" +
332                             roleNameAndNamespace.getNamespaceCode() + "\", and name \"" + roleNameAndNamespace.getName() +
333                                     "\" as a role member because the role with that namespace and name has an ID of \"" +
334                                             tempRole.getId() + "\" instead");
335                 }
336             }
337         }
338         
339         
340         if (StringUtils.isBlank(newRoleMember.getMemberId())) {
341             throw new RuntimeException("Cannot create a role member with no member principal/group/role identification information specified");
342         }
343         
344     }
345     
346     
347 
348 
349     private static void validateAndPrepareRolePermission(RolePermissionXmlDTO newRolePermission) throws UnmarshalException {
350         
351         
352         if (newRolePermission instanceof RolePermissionXmlDTO.OutsideOfRole) {
353             RolePermissionXmlDTO.OutsideOfRole standaloneRolePerm = (RolePermissionXmlDTO.OutsideOfRole) newRolePermission;
354             if (standaloneRolePerm.getRoleNameAndNamespace() != null) {
355                 
356                 String tempRoleId = KimApiServiceLocator.getRoleService().getRoleIdByNamespaceCodeAndName(
357                         standaloneRolePerm.getRoleNamespaceCode(), standaloneRolePerm.getRoleName());
358                 if (StringUtils.isBlank(tempRoleId)) {
359                     throw new UnmarshalException("Cannot assign permission to role with namespace \"" + standaloneRolePerm.getRoleNamespaceCode() +
360                             "\" and name \"" + standaloneRolePerm.getRoleName() + "\" because that role does not exist");
361                 } else if (StringUtils.isBlank(standaloneRolePerm.getRoleId())) {
362                     
363                     standaloneRolePerm.setRoleId(standaloneRolePerm.getRoleId());
364                 } else if (!standaloneRolePerm.getRoleId().equals(tempRoleId)) {
365                     throw new UnmarshalException("Cannot assign permission to role with ID \"" + standaloneRolePerm.getRoleId() + "\", namespace \"" +
366                             standaloneRolePerm.getRoleNamespaceCode() + "\", and name \"" + standaloneRolePerm.getRoleName() +
367                                     "\" because the existing role with that name and namespace has an ID of \"" + tempRoleId + "\" instead");
368                 }
369             } else if (StringUtils.isBlank(standaloneRolePerm.getRoleId())) {
370                 throw new UnmarshalException(
371                         "Cannot assign permission to role without providing the role ID or role name + namespace that the permission is assigned to");
372             } else if (KimApiServiceLocator.getRoleService().getRole(standaloneRolePerm.getRoleId()) == null) {
373                 throw new UnmarshalException("Cannot assign permission to role with ID \"" + standaloneRolePerm.getRoleId() +
374                         "\" because that role does not exist");
375             }
376         }
377         
378         
379         if (StringUtils.isBlank(newRolePermission.getRoleId())) {
380             throw new UnmarshalException("Cannot assign permission to role without providing the role ID or role name + namespace that the permission is assigned to");
381         }
382         
383         
384         if (newRolePermission.getPermissionNameAndNamespace() != null) {
385             PermissionContract permission = KimApiServiceLocator.getPermissionService().findPermByNamespaceCodeAndName(
386                     newRolePermission.getPermissionNamespaceCode(), newRolePermission.getPermissionName());
387             if (permission == null) {
388                 throw new UnmarshalException("Cannot get role assigned to permission with namespace \"" + newRolePermission.getPermissionNamespaceCode() +
389                         "\" and name \"" + newRolePermission.getPermissionName() + "\" because that permission does not exist");
390             } else if (StringUtils.isBlank(newRolePermission.getPermissionId())) {
391                 
392                 newRolePermission.setPermissionId(permission.getId());
393             } else if (!newRolePermission.getPermissionId().equals(permission.getId())) {
394                 throw new UnmarshalException("Cannot get role assigned to permission with ID \"" + newRolePermission.getPermissionId() + "\", namespace \"" +
395                         newRolePermission.getPermissionNamespaceCode() + "\", and name \"" + newRolePermission.getPermissionName() +
396                                 "\" because the existing permission with that name and namespace has an ID of \"" + permission.getId() + "\" instead");
397             }
398         } else if (StringUtils.isBlank(newRolePermission.getPermissionId())) {
399             throw new UnmarshalException("Cannot assign permission to role without specifying the ID or name and namespace of the permission to assign");
400         } else if (KimApiServiceLocator.getPermissionService().getPermission(newRolePermission.getPermissionId()) == null) {
401             throw new UnmarshalException("Cannot get role assigned to permission with ID \"" + newRolePermission.getPermissionId() +
402                     "\" because that permission does not exist");
403         }
404     }
405     
406 }