View Javadoc
1   /*
2    * Copyright (C) 2003-2007 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.ecm.webui.core;
18  
19  import java.security.AccessControlException;
20  import java.util.ArrayList;
21  import java.util.Collections;
22  import java.util.Comparator;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  
29  import javax.jcr.AccessDeniedException;
30  import javax.jcr.Node;
31  import javax.jcr.RepositoryException;
32  
33  import org.exoplatform.commons.utils.LazyPageList;
34  import org.exoplatform.commons.utils.ListAccess;
35  import org.exoplatform.commons.utils.ListAccessImpl;
36  import org.exoplatform.ecm.webui.core.bean.PermissionBean;
37  import org.exoplatform.ecm.webui.utils.PermissionUtil;
38  import org.exoplatform.ecm.webui.utils.Utils;
39  import org.exoplatform.services.jcr.access.AccessControlEntry;
40  import org.exoplatform.services.jcr.access.PermissionType;
41  import org.exoplatform.services.jcr.core.ExtendedNode;
42  import org.exoplatform.services.security.IdentityConstants;
43  import org.exoplatform.web.application.ApplicationMessage;
44  import org.exoplatform.webui.application.WebuiRequestContext;
45  import org.exoplatform.webui.core.UIApplication;
46  import org.exoplatform.webui.core.UIContainer;
47  import org.exoplatform.webui.core.UIGrid;
48  import org.exoplatform.webui.event.Event;
49  import org.exoplatform.webui.event.EventListener;
50  
51  public abstract class UIPermissionInfoBase extends UIContainer {
52  
53    protected static final String FIELD_NAME = "fieldName";
54    
55    protected static final String FIELD_VALUE = "fieldValue";
56    
57    protected static final String EDIT_ACTION = "Edit";
58    
59    private static final String PERMISSION_ADD_NODE_ACTION = "addNode";
60    
61    public static String[] PERMISSION_BEAN_FIELD = 
62      {"usersOrGroups", PermissionType.READ, PERMISSION_ADD_NODE_ACTION, PermissionType.REMOVE};
63  
64    private static String[] PERMISSION_ACTION = {"Delete"} ;
65    
66    private int sizeOfListPermission = 0;
67  
68    public UIPermissionInfoBase() throws Exception {
69      UIGrid uiGrid = createUIComponent(UIPermissionInfoGrid.class, null, "PermissionInfo") ;
70      addChild(uiGrid) ;
71      uiGrid.getUIPageIterator().setId("PermissionInfoIterator");
72      uiGrid.configure("usersOrGroups", PERMISSION_BEAN_FIELD, PERMISSION_ACTION) ;
73    }
74    
75    public abstract Node getCurrentNode() throws Exception;
76  
77    public int getSizeOfListPermission() {
78      return sizeOfListPermission;
79    }
80    public void setSizeOfListPermission(int sizeOfListPermission) {
81      this.sizeOfListPermission = sizeOfListPermission;
82    }
83  
84    public void updateGrid(int currentPage) throws Exception {
85      List<PermissionBean> permBeans = new ArrayList<>();
86      ExtendedNode node = (ExtendedNode) this.getCurrentNode();
87      Map<String, List<String>> permsMap = this.getPermissionsMap(node);
88    
89      Set<String> keys = permsMap.keySet();
90      Iterator<String> keysIter = keys.iterator() ;
91      int iSystemOwner = 0;
92      //TODO Utils.getExoOwner(node) has exception return SystemIdentity.SYSTEM
93      String owner = IdentityConstants.SYSTEM ;
94      if(getExoOwner(node) != null) owner = getExoOwner(node);
95      if (owner.equals(IdentityConstants.SYSTEM)) iSystemOwner = -1;
96      PermissionBean permOwnerBean = new PermissionBean();
97      if(!permsMap.containsKey(owner)) {
98        permOwnerBean.setUsersOrGroups(owner);
99        permOwnerBean.setRead(true) ;
100       permOwnerBean.setAddNode(true) ;
101       permOwnerBean.setRemove(true) ;
102       permBeans.add(permOwnerBean);
103     }
104 
105     while (keysIter.hasNext()) {
106       String userOrGroup = keysIter.next();
107       PermissionBean permBean = new PermissionBean();
108       permBean.setUsersOrGroups(userOrGroup);
109       // owner always has full right even if it has been modified in GUI
110       if (owner.equals(userOrGroup)) {
111         permBean.setRead(true);
112         permBean.setAddNode(true);
113         permBean.setRemove(true);
114       } else {
115         List<String> permissions = permsMap.get(userOrGroup);
116         for (String perm : permissions) {
117           if (PermissionType.READ.equals(perm))
118             permBean.setRead(true);
119           else if (PermissionType.ADD_NODE.equals(perm))
120             permBean.setAddNode(true);
121           else if (PermissionType.REMOVE.equals(perm))
122             permBean.setRemove(true);
123         }
124       }
125       permBeans.add(permBean);
126       sizeOfListPermission = permBeans.size() + iSystemOwner;
127     }
128     UIGrid uiGrid = findFirstComponentOfType(UIGrid.class);
129     
130     // Sort by user/group
131     Collections.sort(permBeans, new PermissionBeanComparator());
132     
133     ListAccess<PermissionBean> permList = new ListAccessImpl<>(PermissionBean.class,
134                                                                              permBeans);
135     LazyPageList<PermissionBean> dataPageList = new LazyPageList<>(permList, 10);
136     uiGrid.getUIPageIterator().setPageList(dataPageList);
137     if (currentPage > uiGrid.getUIPageIterator().getAvailablePage())
138       uiGrid.getUIPageIterator().setCurrentPage(uiGrid.getUIPageIterator().getAvailablePage());
139     else
140       uiGrid.getUIPageIterator().setCurrentPage(currentPage);
141   }
142   
143   protected String  getExoOwner(Node node) throws Exception {
144     return Utils.getNodeOwner(node) ;
145   }
146   
147   /**
148    * Get permission Map of specific node.
149    * 
150    * @param node
151    * @return
152    * @throws RepositoryException
153    */
154   private Map<String, List<String>> getPermissionsMap(ExtendedNode node) throws RepositoryException {
155     Map<String, List<String>> permsMap = new HashMap<>();
156     Iterator<AccessControlEntry> permissionEntriesIter = node.getACL().getPermissionEntries().iterator();
157     while(permissionEntriesIter.hasNext()) {
158       AccessControlEntry accessControlEntry = permissionEntriesIter.next();
159       String currentIdentity = accessControlEntry.getIdentity();
160       String currentPermission = accessControlEntry.getPermission();
161       List<String> currentPermissionsList = permsMap.get(currentIdentity);
162       if(!permsMap.containsKey(currentIdentity)) {
163         permsMap.put(currentIdentity, null) ;
164       }
165       if(currentPermissionsList == null) currentPermissionsList = new ArrayList<>() ;
166       if(!currentPermissionsList.contains(currentPermission)) {
167         currentPermissionsList.add(currentPermission) ;
168       }
169       permsMap.put(currentIdentity, currentPermissionsList) ;
170     }
171 
172     return permsMap;
173   }
174   
175   public List<PermissionBean> getPermBeans() {
176     return new ArrayList<>();
177   }
178 
179   public static class EditActionListener extends EventListener<UIPermissionInfoBase> {
180     public void execute(Event<UIPermissionInfoBase> event) throws Exception {
181       UIPermissionInfoBase uiPermissionInfo = event.getSource();
182       UIApplication uiApp = uiPermissionInfo.getAncestorOfType(UIApplication.class);
183       WebuiRequestContext requestContext = event.getRequestContext();
184       ExtendedNode node = (ExtendedNode)uiPermissionInfo.getCurrentNode();
185       
186       // Get selected user/Group
187       String userOrGroupId = requestContext.getRequestParameter(OBJECTID);
188       // Changed permission value
189       String selectedPermission = requestContext.getRequestParameter(FIELD_NAME);
190       String selectedPermissionValue = requestContext.getRequestParameter(FIELD_VALUE);
191       
192       if (node == null) {
193         List<PermissionBean> perBeans = uiPermissionInfo.getPermBeans();
194         for (PermissionBean perm : perBeans) {
195           if (perm.getUsersOrGroups().equals(userOrGroupId)) {
196             if (PermissionType.READ.equals(selectedPermission) && !perm.isAddNode() && !perm.isRemove()) {
197               if (Boolean.FALSE.toString().equals(selectedPermissionValue)) {
198                   uiApp.addMessage(new ApplicationMessage("UIPermissionForm.msg.checkbox-require", null,
199                                                           ApplicationMessage.WARNING));
200                   return;
201               }
202               perm.setRead("true".equals(selectedPermissionValue));
203             } else if (PERMISSION_ADD_NODE_ACTION.equals(selectedPermission) || 
204                         PermissionType.SET_PROPERTY.equals(selectedPermission)) {
205               perm.setAddNode("true".equals(selectedPermissionValue));
206               if (perm.isAddNode()) perm.setRead(true); 
207             } else if (PermissionType.REMOVE.equals(selectedPermission)) {
208               perm.setRemove("true".equals(selectedPermissionValue));
209               if (perm.isRemove()) perm.setRead(true);
210             }
211           }
212         }
213         event.getRequestContext().addUIComponentToUpdateByAjax(uiPermissionInfo);
214         return;
215       }
216 
217       if (!node.isCheckedOut()) {
218         uiApp.addMessage(new ApplicationMessage("UIActionBar.msg.node-checkedin", null,
219             ApplicationMessage.WARNING));
220         return;
221       }
222       
223       // Current node permissions
224       Map<String, List<String>> permsMap = uiPermissionInfo.getPermissionsMap(node);
225       // Current user/group permissions
226       List<String> identityPermissions = permsMap.get(userOrGroupId);
227       //
228       org.exoplatform.wcm.webui.Utils.addLockToken(node);
229       try {
230         // Change permission
231         if (PermissionUtil.canChangePermission(node)) {
232           if (node.canAddMixin("exo:privilegeable")){
233             node.addMixin("exo:privilegeable");
234             node.setPermission(Utils.getNodeOwner(node),PermissionType.ALL);
235           }
236           if (Boolean.valueOf(selectedPermissionValue)) {
237             if (PERMISSION_ADD_NODE_ACTION.equals(selectedPermission)) {
238               identityPermissions.add(PermissionType.SET_PROPERTY);
239               identityPermissions.add(PermissionType.ADD_NODE);
240             } else {
241               identityPermissions.add(selectedPermission);
242             }
243           } else {
244             // Do not allow remove when only one permission type exist
245             if (identityPermissions.size() == 1) {
246               uiApp.addMessage(new ApplicationMessage("UIPermissionForm.msg.checkbox-require", null,
247                                                       ApplicationMessage.WARNING));
248               return;
249             }
250             if (PERMISSION_ADD_NODE_ACTION.equals(selectedPermission)) {
251               identityPermissions.remove(PermissionType.SET_PROPERTY);
252               identityPermissions.remove(PermissionType.ADD_NODE);
253             } else if (PermissionType.REMOVE.equals(selectedPermission)) {
254               identityPermissions.remove(selectedPermission);
255             }
256           }
257           node.setPermission(userOrGroupId, identityPermissions.toArray(new String[identityPermissions.size()]));
258         }
259         
260         UIPermissionFormBase uiPermissionForm =
261             uiPermissionInfo.getAncestorOfType(UIPermissionManagerBase.class).getChild(UIPermissionFormBase.class);
262         uiPermissionForm.updateSymlinks(node);
263         node.getSession().save();
264         uiPermissionInfo.updateGrid(uiPermissionInfo.getChild(UIGrid.class).getUIPageIterator().getCurrentPage());
265         event.getRequestContext().addUIComponentToUpdateByAjax(uiPermissionInfo);
266       } catch (AccessDeniedException | AccessControlException e) {
267         uiApp.addMessage(new ApplicationMessage("UIPermissionForm.msg.access-denied", null, ApplicationMessage.WARNING));
268       }
269     }
270   }
271 
272   public class PermissionBeanComparator implements Comparator<PermissionBean> {
273     public int compare(PermissionBean o1, PermissionBean o2) throws ClassCastException {
274       try {
275         String name1 = o1.getUsersOrGroups();
276         String name2 = o2.getUsersOrGroups();
277         return name1.compareToIgnoreCase(name2);
278       } catch(Exception e) {
279         return 0;
280       }
281     }
282   }
283 }
284