View Javadoc
1   /**
2    * Copyright 2005-2016 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                  if (model.isCanEditView() == null) {
90                      boolean canEditView = authorizer.canEditView(view, model, user);
91                      if (canEditView) {
92                          canEditView = presentationController.canEditView(view, model);
93                      }
94                      view.setReadOnly(Boolean.valueOf(!canEditView));
95                      model.setCanEditView(Boolean.valueOf(canEditView));
96                  } else {
97                      view.setReadOnly(!model.isCanEditView());
98                  }
99              }
100         }
101 
102         // perform group authorization and presentation logic
103         else if (component instanceof Group) {
104             Group group = (Group) component;
105 
106             // if group is not hidden, do authorization for viewing the group
107             if (!group.isHidden()) {
108                 boolean canViewGroup = authorizer.canViewGroup(view, model, group, group.getId(), user);
109                 if (canViewGroup) {
110                     canViewGroup = presentationController.canViewGroup(view, model, group, group.getId());
111                 }
112                 group.setHidden(!canViewGroup);
113                 group.setRender(canViewGroup);
114             }
115 
116             // if group is editable, do authorization for editing the group
117             if (!Boolean.TRUE.equals(group.getReadOnly())) {
118                 boolean canEditGroup = authorizer.canEditGroup(view, model, group, group.getId(), user);
119                 if (canEditGroup) {
120                     canEditGroup = presentationController.canEditGroup(view, model, group, group.getId());
121                 }
122                 group.setReadOnly(!canEditGroup);
123             }
124         }
125 
126         // perform field authorization and presentation logic
127         else if (component instanceof Field && !(component instanceof ActionField)) {
128             Field field = (Field) component;
129 
130             String propertyName = null;
131             if (field instanceof DataBinding) {
132                 propertyName = ((DataBinding) field).getPropertyName();
133             }
134 
135             // if field is not hidden, do authorization for viewing the field
136             if (!field.isHidden()) {
137                 boolean canViewField = authorizer.canViewField(view, model, field, propertyName, user);
138                 if (canViewField) {
139                     canViewField = presentationController.canViewField(view, model, field, propertyName);
140                 }
141                 field.setHidden(!canViewField);
142                 field.setRender(canViewField);
143             }
144 
145             // if field is not readOnly, check edit authorization
146             if (!Boolean.TRUE.equals(field.getReadOnly())) {
147                 // check field edit authorization
148                 boolean canEditField = authorizer.canEditField(view, model, field, propertyName, user);
149                 if (canEditField) {
150                     canEditField = presentationController.canEditField(view, model, field, propertyName);
151                 }
152                 field.setReadOnly(!canEditField);
153             }
154 
155             // if field is not already required, invoke presentation logic to determine if it should be
156             if ((field.getRequired() == null) || !field.getRequired().booleanValue()) {
157                 // boolean fieldIsRequired = 
158                 presentationController.fieldIsRequired(view, model, field, propertyName);
159             }
160 
161             if (field instanceof DataField) {
162                 DataField dataField = (DataField) field;
163 
164                 // check for masking and mask authorization
165                 boolean canUnmaskValue = authorizer.canUnmaskField(view, model, dataField, dataField.getPropertyName(),
166                         user);
167                 boolean canPartiallyUnmaskValue = authorizer.canPartialUnmaskField(view, model, dataField,
168                         dataField.getPropertyName(), user);
169                 boolean isMasked = isMaskField(dataField);
170                 boolean isPartialMask = isPartialMaskField(dataField);
171 
172                 if (isMasked && !canUnmaskValue)  {
173                     dataField.setApplyMask(true);
174                     dataField.setMaskFormatter(dataField.getDataFieldSecurity().getAttributeSecurity().
175                             getMaskFormatter());
176                 }
177                 else if(isMasked && canUnmaskValue)  {
178                     // do not mask
179                 }
180                 else if (isPartialMask && !canPartiallyUnmaskValue ) {
181                     dataField.setApplyMask(true);
182                     dataField.setMaskFormatter(
183                             dataField.getDataFieldSecurity().getAttributeSecurity().getPartialMaskFormatter());
184                 }
185             }
186         }
187 
188         // perform action authorization and presentation logic
189         else if (component instanceof ActionField || component instanceof Action) {
190             Action action = null;
191             if (component instanceof ActionField) {
192                 action = ((ActionField) component).getAction();
193             } else {
194                 action = (Action) component;
195             }
196 
197             boolean canTakeAction = authorizer.canPerformAction(view, model, action, action.getActionEvent(),
198                     action.getId(), user);
199             if (canTakeAction) {
200                 canTakeAction = presentationController.canPerformAction(view, model, action, action.getActionEvent(),
201                         action.getId());
202             }
203             action.setRender(canTakeAction);
204         }
205 
206         // perform widget authorization and presentation logic
207         else if (component instanceof Widget) {
208             Widget widget = (Widget) component;
209 
210             // if widget is not hidden, do authorization for viewing the widget
211             if (!widget.isHidden()) {
212                 boolean canViewWidget = authorizer.canViewWidget(view, model, widget, widget.getId(), user);
213                 if (canViewWidget) {
214                     canViewWidget = presentationController.canViewWidget(view, model, widget, widget.getId());
215                 }
216                 widget.setHidden(!canViewWidget);
217                 widget.setRender(canViewWidget);
218             }
219 
220             // if widget is not readOnly, check edit authorization
221             if (!Boolean.TRUE.equals(widget.getReadOnly())) {
222                 boolean canEditWidget = authorizer.canEditWidget(view, model, widget, widget.getId(), user);
223                 if (canEditWidget) {
224                     canEditWidget = presentationController.canEditWidget(view, model, widget, widget.getId());
225                 }
226                 widget.setReadOnly(!canEditWidget);
227             }
228         }
229     }
230 
231     /**
232      *
233      */
234     private boolean isMaskField(DataField field) {
235         if (field.getDataFieldSecurity() == null) {
236             return false;
237         }
238 
239         // check mask authz flag is set
240         AttributeSecurity attributeSecurity = field.getDataFieldSecurity().getAttributeSecurity();
241         if (attributeSecurity == null || !attributeSecurity.isMask()) {
242             return false;
243         }
244 
245         return true;
246     }
247 
248     /**
249      *
250      */
251     private boolean isPartialMaskField(DataField field) {
252         if (field.getDataFieldSecurity() == null) {
253             return false;
254         }
255 
256         // check partial mask authz flag is set
257         AttributeSecurity attributeSecurity = field.getDataFieldSecurity().getAttributeSecurity();
258         if (attributeSecurity == null || !attributeSecurity.isPartialMask()) {
259             return false;
260         }
261 
262         return true;
263     }
264 
265 }