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