View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.uif.lifecycle.model;
17  
18  import org.kuali.rice.kim.api.identity.Person;
19  import org.kuali.rice.krad.datadictionary.AttributeSecurity;
20  import org.kuali.rice.krad.uif.component.Component;
21  import org.kuali.rice.krad.uif.component.DataBinding;
22  import org.kuali.rice.krad.uif.container.Group;
23  import org.kuali.rice.krad.uif.element.Action;
24  import org.kuali.rice.krad.uif.field.ActionField;
25  import org.kuali.rice.krad.uif.field.DataField;
26  import org.kuali.rice.krad.uif.field.Field;
27  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle;
28  import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTaskBase;
29  import org.kuali.rice.krad.uif.view.View;
30  import org.kuali.rice.krad.uif.view.ViewAuthorizer;
31  import org.kuali.rice.krad.uif.view.ViewModel;
32  import org.kuali.rice.krad.uif.view.ViewPresentationController;
33  import org.kuali.rice.krad.uif.widget.Widget;
34  import org.kuali.rice.krad.util.GlobalVariables;
35  
36  /**
37   * Apply authorization and presentation logic for the component.
38   * 
39   * @author Kuali Rice Team (rice.collab@kuali.org)
40   */
41  public class ApplyAuthAndPresentationLogicTask extends ViewLifecycleTaskBase<Component> {
42  
43      /**
44       * Default constructor.
45       */
46      public ApplyAuthAndPresentationLogicTask() {
47          super(Component.class);
48      }
49  
50      /**
51       * Invokes the view's configured {@link ViewAuthorizer} and {@link ViewPresentationController}
52       * to set state of the component
53       * 
54       * <p>
55       * The following authorization is done here: Fields: edit, view, required, mask, and partial
56       * mask Groups: edit and view Actions: take action
57       * </p>
58       * 
59       * <p>
60       * Note additional checks are also done for fields that are part of a collection group. This
61       * authorization is found in {@link org.kuali.rice.krad.uif.container.CollectionGroupBuilder}
62       * </p>
63       * 
64       * @see org.kuali.rice.krad.uif.lifecycle.ViewLifecycleTaskBase#performLifecycleTask()
65       */
66      @Override
67      protected void performLifecycleTask() {
68          ViewModel model = (ViewModel) ViewLifecycle.getModel();
69          Component component = (Component) getElementState().getElement();
70          View view = ViewLifecycle.getView();
71          ViewPresentationController presentationController = view.getPresentationController();
72          ViewAuthorizer authorizer = view.getAuthorizer();
73  
74          // if user session is not established cannot perform authorization
75          if (GlobalVariables.getUserSession() == null) {
76              return;
77          }
78  
79          Person user = GlobalVariables.getUserSession().getPerson();
80  
81          // if component not flagged for render no need to check auth and controller logic
82          if (!component.isRender()) {
83              return;
84          }
85  
86          // check top level view edit authorization
87          if (component instanceof View) {
88              if (!Boolean.TRUE.equals(view.getReadOnly())) {
89                  boolean canEditView = authorizer.canEditView(view, model, user);
90                  if (canEditView) {
91                      canEditView = presentationController.canEditView(view, model);
92                  }
93                  view.setReadOnly(!canEditView);
94              }
95          }
96  
97          // perform group authorization and presentation logic
98          else if (component instanceof Group) {
99              Group group = (Group) component;
100 
101             // if group is not hidden, do authorization for viewing the group
102             if (!group.isHidden()) {
103                 boolean canViewGroup = authorizer.canViewGroup(view, model, group, group.getId(), user);
104                 if (canViewGroup) {
105                     canViewGroup = presentationController.canViewGroup(view, model, group, group.getId());
106                 }
107                 group.setHidden(!canViewGroup);
108                 group.setRender(canViewGroup);
109             }
110 
111             // if group is editable, do authorization for editing the group
112             if (!Boolean.TRUE.equals(group.getReadOnly())) {
113                 boolean canEditGroup = authorizer.canEditGroup(view, model, group, group.getId(), user);
114                 if (canEditGroup) {
115                     canEditGroup = presentationController.canEditGroup(view, model, group, group.getId());
116                 }
117                 group.setReadOnly(!canEditGroup);
118             }
119         }
120 
121         // perform field authorization and presentation logic
122         else if (component instanceof Field && !(component instanceof ActionField)) {
123             Field field = (Field) component;
124 
125             String propertyName = null;
126             if (field instanceof DataBinding) {
127                 propertyName = ((DataBinding) field).getPropertyName();
128             }
129 
130             // if field is not hidden, do authorization for viewing the field
131             if (!field.isHidden()) {
132                 boolean canViewField = authorizer.canViewField(view, model, field, propertyName, user);
133                 if (canViewField) {
134                     canViewField = presentationController.canViewField(view, model, field, propertyName);
135                 }
136                 field.setHidden(!canViewField);
137                 field.setRender(canViewField);
138             }
139 
140             // if field is not readOnly, check edit authorization
141             if (!Boolean.TRUE.equals(field.getReadOnly())) {
142                 // check field edit authorization
143                 boolean canEditField = authorizer.canEditField(view, model, field, propertyName, user);
144                 if (canEditField) {
145                     canEditField = presentationController.canEditField(view, model, field, propertyName);
146                 }
147                 field.setReadOnly(!canEditField);
148             }
149 
150             // if field is not already required, invoke presentation logic to determine if it should be
151             if ((field.getRequired() == null) || !field.getRequired().booleanValue()) {
152                 // boolean fieldIsRequired = 
153                 presentationController.fieldIsRequired(view, model, field, propertyName);
154             }
155 
156             if (field instanceof DataField) {
157                 DataField dataField = (DataField) field;
158 
159                 // check for masking and mask authorization
160                 boolean canUnmaskValue = authorizer.canUnmaskField(view, model, dataField, dataField.getPropertyName(),
161                         user);
162                 boolean canPartiallyUnmaskValue = authorizer.canPartialUnmaskField(view, model, dataField,
163                         dataField.getPropertyName(), user);
164                 boolean isMasked = isMaskField(dataField);
165                 boolean isPartialMask = isPartialMaskField(dataField);
166 
167                 if (isMasked && !canUnmaskValue)  {
168                     dataField.setApplyMask(true);
169                     dataField.setMaskFormatter(dataField.getDataFieldSecurity().getAttributeSecurity().
170                             getMaskFormatter());
171                 }
172                 else if(isMasked && canUnmaskValue)  {
173                     // do not mask
174                 }
175                 else if (isPartialMask && !canPartiallyUnmaskValue ) {
176                     dataField.setApplyMask(true);
177                     dataField.setMaskFormatter(
178                             dataField.getDataFieldSecurity().getAttributeSecurity().getPartialMaskFormatter());
179                 }
180             }
181         }
182 
183         // perform action authorization and presentation logic
184         else if (component instanceof ActionField || component instanceof Action) {
185             Action action = null;
186             if (component instanceof ActionField) {
187                 action = ((ActionField) component).getAction();
188             } else {
189                 action = (Action) component;
190             }
191 
192             boolean canTakeAction = authorizer.canPerformAction(view, model, action, action.getActionEvent(),
193                     action.getId(), user);
194             if (canTakeAction) {
195                 canTakeAction = presentationController.canPerformAction(view, model, action, action.getActionEvent(),
196                         action.getId());
197             }
198             action.setRender(canTakeAction);
199         }
200 
201         // perform widget authorization and presentation logic
202         else if (component instanceof Widget) {
203             Widget widget = (Widget) component;
204 
205             // if widget is not hidden, do authorization for viewing the widget
206             if (!widget.isHidden()) {
207                 boolean canViewWidget = authorizer.canViewWidget(view, model, widget, widget.getId(), user);
208                 if (canViewWidget) {
209                     canViewWidget = presentationController.canViewWidget(view, model, widget, widget.getId());
210                 }
211                 widget.setHidden(!canViewWidget);
212                 widget.setRender(canViewWidget);
213             }
214 
215             // if widget is not readOnly, check edit authorization
216             if (!Boolean.TRUE.equals(widget.getReadOnly())) {
217                 boolean canEditWidget = authorizer.canEditWidget(view, model, widget, widget.getId(), user);
218                 if (canEditWidget) {
219                     canEditWidget = presentationController.canEditWidget(view, model, widget, widget.getId());
220                 }
221                 widget.setReadOnly(!canEditWidget);
222             }
223         }
224     }
225 
226     /**
227      *
228      */
229     private boolean isMaskField(DataField field) {
230         if (field.getDataFieldSecurity() == null) {
231             return false;
232         }
233 
234         // check mask authz flag is set
235         AttributeSecurity attributeSecurity = field.getDataFieldSecurity().getAttributeSecurity();
236         if (attributeSecurity == null || !attributeSecurity.isMask()) {
237             return false;
238         }
239 
240         return true;
241     }
242 
243     /**
244      *
245      */
246     private boolean isPartialMaskField(DataField field) {
247         if (field.getDataFieldSecurity() == null) {
248             return false;
249         }
250 
251         // check partial mask authz flag is set
252         AttributeSecurity attributeSecurity = field.getDataFieldSecurity().getAttributeSecurity();
253         if (attributeSecurity == null || !attributeSecurity.isPartialMask()) {
254             return false;
255         }
256 
257         return true;
258     }
259 
260 }