001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.webcontentio; 017 018import java.io.InputStream; 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023 024import org.ametys.core.authentication.token.AuthenticationTokenManager; 025import org.ametys.core.cocoon.ActionResultGenerator; 026import org.ametys.core.right.RightsException; 027import org.ametys.core.user.UserIdentity; 028import org.ametys.plugins.repository.AmetysRepositoryException; 029import org.ametys.web.repository.page.SitemapElement; 030import org.ametys.web.repository.site.Site; 031import org.ametys.web.repository.site.SiteManager; 032import org.ametys.web.repository.sitemap.Sitemap; 033import org.apache.avalon.framework.context.ContextException; 034import org.apache.avalon.framework.context.Contextualizable; 035import org.apache.avalon.framework.parameters.Parameters; 036import org.apache.avalon.framework.service.ServiceException; 037import org.apache.avalon.framework.service.ServiceManager; 038import org.apache.cocoon.Constants; 039import org.apache.cocoon.acting.ServiceableAction; 040import org.apache.cocoon.environment.Context; 041import org.apache.cocoon.environment.ObjectModelHelper; 042import org.apache.cocoon.environment.Redirector; 043import org.apache.cocoon.environment.Request; 044import org.apache.cocoon.environment.SourceResolver; 045import org.apache.cocoon.servlet.multipart.Part; 046import org.apache.commons.lang.StringUtils; 047 048/** 049 * Action to import a content from an input stream received through a POST request. 050 */ 051public class ImportContentAction extends ServiceableAction implements Contextualizable 052{ 053 private AuthenticationTokenManager _authenticationManager; 054 private ContentIOManager _contentIOManager; 055 private SiteManager _siteManager; 056 057 private Context _context; 058 059 @Override 060 public void contextualize(org.apache.avalon.framework.context.Context context) throws ContextException 061 { 062 _context = (Context) context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); 063 } 064 065 @Override 066 public void service(ServiceManager smanager) throws ServiceException 067 { 068 super.service(smanager); 069 070 _authenticationManager = (AuthenticationTokenManager) manager.lookup(AuthenticationTokenManager.ROLE); 071 _contentIOManager = (ContentIOManager) manager.lookup(ContentIOManager.ROLE); 072 _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE); 073 } 074 075 @Override 076 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 077 { 078 Request request = ObjectModelHelper.getRequest(objectModel); 079 List<String> error = new ArrayList<>(); 080 Boolean success = true; 081 082 if (!"POST".equals(request.getMethod())) 083 { 084 success = false; 085 error.add("Only POST methods are allowed."); 086 getLogger().warn("Only POST methods are allowed."); 087 } 088 089 Object content = request.get("content"); 090 if (content == null) 091 { 092 success = false; 093 error.add("No content provided. The parameter 'content' is mandatory."); 094 getLogger().warn("No content provided. The parameter 'content' is mandatory."); 095 } 096 097 String authenticationToken = (String) request.get("key"); 098 if (authenticationToken == null) 099 { 100 success = false; 101 error.add("No API key provided. The parameter 'key' is mandatory."); 102 getLogger().warn("No API key provided. The parameter 'key' is mandatory."); 103 } 104 105 UserIdentity user = _authenticationManager.validateToken(authenticationToken); 106 if (user == null) 107 { 108 success = false; 109 error.add("The API key provided is invalid, please check the value of the parameter 'key'."); 110 getLogger().warn("The API key provided is invalid, please check the value of the parameter 'key'."); 111 } 112 113 String siteName = parameters.getParameter("site"); 114 String sitemapName = parameters.getParameter("sitemap"); 115 String path = parameters.getParameter("path"); 116 boolean extern = parameters.getParameterAsBoolean("extern", false); 117 118 SitemapElement rootPage = getPageFromPath(siteName, sitemapName, path); 119 120 if (rootPage == null) 121 { 122 success = false; 123 error.add("Unable to retrieve the parent page, the specified path was not found."); 124 getLogger().warn("Unable to retrieve the parent page, the specified path was not found."); 125 } 126 127 if (success && content instanceof Part) 128 { 129 Part part = (Part) content; 130 131 InputStream is = part.getInputStream(); 132 String contentName = part.getUploadName(); 133 String mimeType = _context.getMimeType(contentName); 134 135 try 136 { 137 _contentIOManager.importContent(is, mimeType, contentName, user, rootPage, extern); 138 } 139 catch (RightsException e) 140 { 141 success = false; 142 error.add("Insufficient rights to create a content."); 143 getLogger().warn("Insufficient rights to create a content."); 144 } 145 } 146 147 Map<String, Object> mapResult = new HashMap<>(); 148 mapResult.put("success", success); 149 if (!success) 150 { 151 mapResult.put("error", error); 152 } 153 154 request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, mapResult); 155 156 return EMPTY_MAP; 157 } 158 159 private SitemapElement getPageFromPath(String siteName, String sitemapName, String path) 160 { 161 Site site = null; 162 Sitemap sitemap = null; 163 164 try 165 { 166 site = _siteManager.getSite(siteName); 167 sitemap = site.getSitemap(sitemapName); 168 } 169 catch (AmetysRepositoryException e) 170 { 171 getLogger().warn("Unable to retrieve the site or sitemap.", e); 172 return null; 173 } 174 175 if (StringUtils.isEmpty(path) || "/".equals(path)) 176 { 177 return sitemap; 178 } 179 180 String pathCleaned = path; 181 if (pathCleaned.startsWith("/")) 182 { 183 pathCleaned = pathCleaned.substring(1); 184 } 185 if (pathCleaned.endsWith("/")) 186 { 187 pathCleaned = pathCleaned.substring(0, path.length() - 1); 188 } 189 190 String[] pagesName = pathCleaned.split("/"); 191 192 SitemapElement page = sitemap; 193 for (int i = 0; i < pagesName.length; i++) 194 { 195 if (StringUtils.isEmpty(pagesName[i])) 196 { 197 return null; 198 } 199 200 page = page.getChild(pagesName[i]); 201 202 if (page == null) 203 { 204 return null; 205 } 206 } 207 208 return page; 209 210 } 211}