View Javadoc
1   /**
2    * This file Copyright (c) 2003-2014 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.module.admininterface.dialogs;
35  
36  import info.magnolia.cms.beans.config.ContentRepository;
37  import info.magnolia.cms.core.Content;
38  import info.magnolia.cms.core.ItemType;
39  import info.magnolia.cms.core.MgnlNodeType;
40  import info.magnolia.cms.core.Path;
41  import info.magnolia.cms.gui.dialog.Dialog;
42  import info.magnolia.cms.security.AccessDeniedException;
43  import info.magnolia.module.admininterface.SaveHandler;
44  import info.magnolia.module.admininterface.config.AclTypeConfiguration;
45  import info.magnolia.repository.RepositoryConstants;
46  
47  import java.util.Iterator;
48  
49  import javax.jcr.Node;
50  import javax.jcr.PathNotFoundException;
51  import javax.jcr.RepositoryException;
52  import javax.servlet.http.HttpServletRequest;
53  import javax.servlet.http.HttpServletResponse;
54  
55  import org.apache.commons.lang.StringUtils;
56  import org.slf4j.Logger;
57  import org.slf4j.LoggerFactory;
58  
59  
60  /**
61   * @author Fabrizio Giustina
62   * @version $Id$
63   */
64  public class RolesEditDialog extends ConfiguredDialog {
65  
66      protected static Logger log = LoggerFactory.getLogger("roles dialog"); //$NON-NLS-1$
67  
68      /**
69       * Stable serialVersionUID.
70       */
71      private static final long serialVersionUID = 222L;
72  
73      /**
74       * @param name
75       * @param request
76       * @param response
77       * @param configNode
78       */
79      public RolesEditDialog(String name, HttpServletRequest request, HttpServletResponse response, Content configNode) {
80          super(name, request, response, configNode);
81      }
82  
83      @Override
84      public String getRepository() {
85          String repository = super.getRepository();
86          if (repository == null) {
87              repository = RepositoryConstants.USER_ROLES;
88          }
89          return repository;
90      }
91  
92      /*
93       * (non-Javadoc)
94       * @see info.magnolia.module.admininterface.DialogMVCHandler#createDialog(info.magnolia.cms.core.Content,
95       * info.magnolia.cms.core.Content)
96       */
97      @Override
98      protected Dialog createDialog(Content configNode, Content storageNode) throws RepositoryException {
99  
100         Dialog dialog = super.createDialog(configNode, storageNode);
101 
102         dialog.setJavascriptSources(request.getContextPath() + "/.resources/admin-js/dialogs/pages/rolesACLPage.js"); //$NON-NLS-1$
103         dialog.setCssSources(request.getContextPath() + "/.resources/admin-css/dialogs/pages/rolesEditPage.css"); //$NON-NLS-1$
104         return dialog;
105     }
106 
107     /**
108      * @see info.magnolia.module.admininterface.DialogMVCHandler#configureSaveHandler(info.magnolia.module.admininterface.SaveHandler)
109      */
110     @Override
111     protected void configureSaveHandler(SaveHandler save) {
112         super.configureSaveHandler(save);
113         save.setPath(path);
114     }
115 
116     @Override
117     protected boolean onPostSave(SaveHandler saveControl) {
118         Content role = this.getStorageNode();
119         try {
120             saveACLs(role, "uri");
121 
122             // for each repository
123             Iterator repositoryNames = ContentRepository.getAllRepositoryNames();
124             while (repositoryNames.hasNext()) {
125                 saveACLs(role, (String) repositoryNames.next());
126             }
127 
128             role.save();
129             return true;
130         } catch (RepositoryException re) {
131             log.error("Failed to update role, reverting all transient modifications made for this node", re);
132             try {
133                 role.refresh(false);
134             } catch (RepositoryException e) {
135                 log.error("Failed to revert transient modifications", e);
136             }
137         }
138         return false;
139     }
140 
141     protected void saveACLs(Content role, String repository) throws RepositoryException {
142         // ######################
143         // # acl
144         // ######################
145         // remove existing
146         try {
147             role.delete("acl_" + repository); //$NON-NLS-1$
148         }
149         catch (PathNotFoundException re) {
150             // ignore, not existing
151         }
152         // rewrite
153         Node aclNode = role.createContent("acl_" + repository, ItemType.CONTENTNODE).getJCRNode();
154 
155         String aclValueStr = form.getParameter("acl" + repository + "List"); //$NON-NLS-1$ //$NON-NLS-2$
156         if (StringUtils.isNotEmpty(aclValueStr)) {
157             String[] aclEntries = aclValueStr.split(";"); //$NON-NLS-1$
158             for (int i = 0; i < aclEntries.length; i++) {
159                 String path = StringUtils.EMPTY;
160                 long accessRight = 0;
161                 int accessType = 0;
162 
163                 String[] aclValuePairs = aclEntries[i].split(","); //$NON-NLS-1$
164                 for (int j = 0; j < aclValuePairs.length; j++) {
165                     String[] aclValuePair = aclValuePairs[j].split(":"); //$NON-NLS-1$
166                     String aclName = aclValuePair[0].trim();
167                     String aclValue = StringUtils.EMPTY;
168                     if (aclValuePair.length > 1) {
169                         aclValue = aclValuePair[1].trim();
170                     }
171 
172                     if (aclName.equals("path")) { //$NON-NLS-1$
173                         path = aclValue;
174                     }
175                     else if (aclName.equals("accessType")) { //$NON-NLS-1$
176                         accessType = Integer.valueOf(aclValue).intValue();
177                     }
178                     else if (aclName.equals("accessRight")) { //$NON-NLS-1$
179                         try {
180                             accessRight = Long.parseLong(aclValue);
181                         }
182                         catch (NumberFormatException e) {
183                             accessRight = 0;
184                         }
185                     }
186                 }
187 
188                 if (StringUtils.isNotEmpty(path)) {
189                     if (repository.equalsIgnoreCase("uri")) { //$NON-NLS-1$
190                         // write ACL as is for URI security
191                         accessType = AclTypeConfiguration.TYPE_THIS;
192                     } else if (path.equals("/")) { //$NON-NLS-1$
193                         accessType = AclTypeConfiguration.TYPE_SUBS;
194                         path = StringUtils.EMPTY;
195                     }
196 
197                     path = StringUtils.removeEnd(path, "/");
198 
199                     if ((accessType & AclTypeConfiguration.TYPE_THIS) != 0) {
200                         try {
201                             addPermissionNode(aclNode, accessRight, path, "");
202                         }
203                         catch (Exception e) {
204                             log.error(e.getMessage(), e);
205                         }
206                     }
207 
208                     if ((accessType & AclTypeConfiguration.TYPE_SUBS) != 0) {
209                         try {
210                             addPermissionNode(aclNode, accessRight, path, "/*");
211                         }
212                         catch (Exception e) {
213                             log.error(e.getMessage(), e);
214                         }
215                     }
216                 }
217             }
218         }
219     }
220 
221     private void addPermissionNode(Node acls, long accessRight, String path, String suffix) throws PathNotFoundException, RepositoryException, AccessDeniedException {
222         String newLabel = Path.getUniqueLabel(acls.getSession(), acls.getPath(), "0");
223         Node acl = acls.addNode(newLabel, MgnlNodeType.NT_CONTENTNODE);
224         acl.setProperty("path", path + suffix);
225         acl.setProperty("permissions", accessRight);
226     }
227 }