View Javadoc

1   /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.student.common.ui.server.gwt;
17  
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.LinkedHashMap;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.UUID;
24  
25  import org.apache.log4j.Logger;
26  import org.kuali.rice.kim.api.permission.Permission;
27  import org.kuali.rice.kim.api.permission.PermissionService;
28  import org.kuali.student.common.ui.client.service.SecurityRpcService;
29  import org.kuali.student.common.ui.client.service.exceptions.OperationFailedException;
30  import org.kuali.student.common.util.security.SecurityUtils;
31  import org.kuali.student.r1.common.rice.StudentIdentityConstants;
32  import org.kuali.student.r1.common.rice.authorization.PermissionType;
33  
34  import com.google.gwt.user.server.rpc.RemoteServiceServlet;
35  
36  /**
37   * This provides security RPC services to the GWT Application.  It should be noted that this
38   * does not provide true client authorization as these calls can be easily manipulated by the
39   * end user.  These calls are to be used to solely hide application components for
40   * users which are not privileged to view them and the check is merely for visual display.
41   * 
42   * The real security checks are performed via security checks on the data RPC get/save
43   * operations as well as masking/hiding of data returned to the browser.
44   * 
45   * @author Kuali Student Team
46   *
47   */
48  public class SecurityRpcGwtServlet extends RemoteServiceServlet implements SecurityRpcService{
49  
50  	final Logger LOG = Logger.getLogger(SecurityRpcGwtServlet.class);
51  	
52  	private static final long serialVersionUID = 1L;
53      
54  	private PermissionService permissionService;
55         
56  	@Override
57      public String getPrincipalUsername(){
58      	return SecurityUtils.getCurrentPrincipalName();
59      }
60  
61  	@Override
62      public HashMap<String, Boolean> getScreenPermissions(ArrayList<String> screens) throws OperationFailedException {
63          HashMap<String, Boolean> screenPermissions = new HashMap<String, Boolean>();
64          try
65          {
66              for (String screenName : screens) {
67                  boolean hasAccess = hasScreenPermission(screenName);
68                  screenPermissions.put(screenName, hasAccess);
69              }
70  
71              return screenPermissions;
72          } catch (Exception ex) {
73              // Log exception 
74              ex.printStackTrace();
75              throw new RuntimeException(ex);
76          }
77      }
78  	 
79  	@Override
80      public HashMap<String, Boolean> getPermissions(ArrayList<String> permissionNames) throws OperationFailedException {
81          String principalId = SecurityUtils.getCurrentPrincipalId();
82          try
83          {
84              LOG.debug("Retreiving permissions for permission name: " + permissionNames + " for " + principalId);
85  
86              //FIXME: Is there a way to retrieve multiple permissions at once instead of calling isAuthorized multiple times?
87              Map<String, String> permDetails = new LinkedHashMap<String, String>();
88              HashMap<String, Boolean> permissions = new HashMap<String, Boolean>();
89              for (String permissionName : permissionNames) {
90                  boolean hasAccess = getPermissionService().isAuthorized(principalId, "KS-SYS", permissionName,
91                          permDetails);
92                  permissions.put(permissionName, hasAccess);
93              }
94  
95              return permissions;
96          } catch (Exception ex) {
97              // Log exception 
98              ex.printStackTrace();
99              throw new RuntimeException(ex);
100         }
101     }
102 	
103 	@Override
104     public Boolean hasScreenPermission(String screenName) throws OperationFailedException {
105         try
106         {
107             String principalId = SecurityUtils.getCurrentPrincipalId();
108 
109             LOG.debug("Retreiving screen permission " + screenName + " for " + principalId);
110 
111             Map<String, String> permDetails = new LinkedHashMap<String, String>();
112             permDetails.put(StudentIdentityConstants.SCREEN_COMPONENT, screenName);
113             boolean hasAccess = false;
114             hasAccess = getPermissionService().isAuthorizedByTemplate(principalId,
115                     PermissionType.USE_SCREEN.getPermissionNamespace(),
116                     PermissionType.USE_SCREEN.getPermissionTemplateName(), permDetails,
117                     permDetails);
118 
119             LOG.debug(principalId + " access : " + hasAccess);
120 
121             return hasAccess;
122         } catch (Exception ex) {
123             // Log exception 
124             ex.printStackTrace();
125             throw new RuntimeException(ex);
126         }
127     }
128 	
129 	
130 	@Override
131     public Boolean hasPermissionByPermissionName(String permissionName) throws OperationFailedException {
132         String principalId = SecurityUtils.getCurrentPrincipalId();
133         try
134         {
135             LOG.debug("Retreiving permissions for permission name: " + permissionName + " for " + principalId);
136 
137             //TODO: Do we need to worry about permission details when checking by permission name
138             Map<String, String> permDetails = new LinkedHashMap<String, String>();
139             boolean hasAccess = false;
140             hasAccess = getPermissionService().isAuthorized(principalId, "KS-SYS", permissionName, permDetails);
141 
142             LOG.debug(principalId + " access : " + hasAccess);
143 
144             return hasAccess;
145         } catch (Exception ex) {
146             // Log exception 
147             ex.printStackTrace();
148             throw new RuntimeException(ex);
149         }
150     }
151 
152 	/**
153 	 * This will return all permissions assigned to this user.
154 	 * 
155 	 * TODO: Need to determine if permission details are required.   
156 	 */
157 	@Override
158     public ArrayList<String> getPermissionsByType(PermissionType permissionType) throws OperationFailedException {
159         ArrayList<String> matchingPermissions = new ArrayList<String>();
160         try
161         {
162             String principalId = SecurityUtils.getCurrentPrincipalId();
163 
164             LOG.debug("Retreiving permissions for template: " + permissionType.getPermissionTemplateName() + " for "
165                     + principalId);
166 
167             Map<String, String> permDetails = new LinkedHashMap<String, String>();
168             List<Permission> permissions = permissionService.getAuthorizedPermissionsByTemplate(
169                     principalId, permissionType.getPermissionNamespace(), permissionType.getPermissionTemplateName(),
170                     permDetails, permDetails);
171 
172             // Null check required in case web service method returns empty list, 
173             // SOAP messages return empty list as null  by default
174             if (permissions !=null){
175                 for (Permission permissionInfo:permissions){
176                     matchingPermissions.add(permissionInfo.getName());
177                 }
178             }
179 
180             return matchingPermissions;
181         } catch (Exception ex) {
182             // Log exception 
183             ex.printStackTrace();
184             throw new RuntimeException(ex);
185         }
186     }
187 	
188 	/**
189      * This will return all permissions assigned to this user.
190      * 
191      * TODO: Need to determine if permission details are required.   
192      */
193     @Override
194     public ArrayList<String> getPermissionsByType(PermissionType permissionType, HashMap<String, String> attributes)
195             throws OperationFailedException {
196         ArrayList<String> matchingPermissions = new ArrayList<String>();
197         //AttributeSet attributeSet = new AttributeSet(attributes);
198         try
199         {
200             String principalId = SecurityUtils.getCurrentPrincipalId();
201 
202             LOG.debug("Retreiving permissions for template: " + permissionType.getPermissionTemplateName() + " for "
203                     + principalId + " with details: " + attributes != null ? attributes.toString() : "null");
204 
205             List<Permission> permissions = (List<Permission>) getPermissionService()
206                     .getAuthorizedPermissionsByTemplate(
207                             principalId, permissionType.getPermissionNamespace(),
208                             permissionType.getPermissionTemplateName(), attributes, attributes);
209 
210             // Null check required in case web service method returns empty list, 
211             // SOAP messages return empty list as null  by default
212             if (permissions !=null){
213                 for (Permission permissionInfo:permissions){
214                     matchingPermissions.add(permissionInfo.getName());
215                 }
216             }
217 
218             return matchingPermissions;
219         } catch (Exception ex) {
220             // Log exception 
221             ex.printStackTrace();
222             throw new RuntimeException(ex);
223         }
224     }
225 	
226 	public void setPermissionService(PermissionService permissionService) {
227 		this.permissionService = permissionService;
228 	}
229 
230 	public PermissionService getPermissionService()throws OperationFailedException{
231 		if(permissionService==null){
232         	throw new OperationFailedException("Permission Service is unavailable");
233         }
234 
235 		return permissionService;
236 	}
237 
238     protected Map<String, String> getQualification(String idType, String id, String docType) {
239         try
240         {
241             Map<String, String> qualification = new LinkedHashMap<String, String>();
242             qualification.put(StudentIdentityConstants.DOCUMENT_TYPE_NAME, docType);
243             qualification.put(idType, id);
244             //Put in a random number to avoid this request from being cached. Might want to do this only for specific templates to take advantage of caching
245             qualification.put("RAND_NO_CACHE", UUID.randomUUID().toString());
246             return qualification;
247         } catch (Exception ex) {
248             // Log exception 
249             ex.printStackTrace();
250             throw new RuntimeException(ex);
251         }
252     }
253 
254 }