001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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     */
016    package org.kuali.kfs.sys.web.servlet;
017    
018    import java.io.BufferedInputStream;
019    import java.io.BufferedOutputStream;
020    import java.io.File;
021    import java.io.FileInputStream;
022    import java.io.FileOutputStream;
023    import java.io.IOException;
024    import java.io.InputStream;
025    import java.io.InputStreamReader;
026    import java.io.Reader;
027    import java.io.StringWriter;
028    import java.util.ArrayList;
029    import java.util.List;
030    
031    import javax.servlet.ServletException;
032    import javax.servlet.UnavailableException;
033    import javax.servlet.http.HttpServlet;
034    import javax.servlet.http.HttpServletRequest;
035    import javax.servlet.http.HttpServletResponse;
036    
037    import org.apache.commons.fileupload.FileItemIterator;
038    import org.apache.commons.fileupload.FileItemStream;
039    import org.apache.commons.fileupload.FileUploadException;
040    import org.apache.commons.fileupload.servlet.ServletFileUpload;
041    import org.apache.commons.lang.StringUtils;
042    import org.kuali.kfs.sys.FinancialSystemModuleConfiguration;
043    import org.kuali.kfs.sys.context.SpringContext;
044    import org.kuali.rice.kim.bo.entity.KimPrincipal;
045    import org.kuali.rice.kim.bo.entity.dto.KimPrincipalInfo;
046    import org.kuali.rice.kim.bo.impl.KimAttributes;
047    import org.kuali.rice.kim.bo.types.dto.AttributeSet;
048    import org.kuali.rice.kim.service.KIMServiceLocator;
049    import org.kuali.rice.kim.util.KimConstants;
050    import org.kuali.rice.kns.bo.ModuleConfiguration;
051    import org.kuali.rice.kns.service.KualiModuleService;
052    import org.kuali.rice.kns.service.ModuleService;
053    import org.kuali.rice.kns.util.GlobalVariables;
054    import org.kuali.rice.kns.util.KNSConstants;
055    
056    public class BatchFileUploadServlet extends HttpServlet {
057        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BatchFileUploadServlet.class);
058    
059        protected void checkAuthorization( HttpServletRequest request ) {
060            boolean authorized = false;
061    //        String principalName = GlobalVariables.getUserSession().getPrincipalName();
062            String principalName = KIMServiceLocator.getIdentityManagementService().getAuthenticatedPrincipalName(request);
063            LOG.info("Logged In User: " + principalName);
064            if ( StringUtils.isNotBlank(principalName) ) {
065                KimPrincipal principal = KIMServiceLocator.getIdentityManagementService().getPrincipalByPrincipalName( principalName );
066                if ( principal != null ) {
067    //        if ( StringUtils.isNotBlank(principalName) ) {
068    //            KimPrincipalInfo principal = KIMServiceLocator.getIdentityManagementService().getPrincipalByPrincipalName(principalName);
069    //            if ( principal != null ) {
070                    String principalId = principal.getPrincipalId();
071                    AttributeSet permissionDetails = new AttributeSet();
072                    permissionDetails.put( KimAttributes.DOCUMENT_TYPE_NAME, "GLCP");
073                    authorized = KIMServiceLocator.getIdentityManagementService().isAuthorizedByTemplateName( principalId, KNSConstants.KUALI_RICE_SYSTEM_NAMESPACE, KimConstants.PermissionTemplateNames.INITIATE_DOCUMENT, permissionDetails, null );
074                    if ( !authorized ) {
075                        permissionDetails.put( KimAttributes.DOCUMENT_TYPE_NAME, "LLCP");
076                        authorized = KIMServiceLocator.getIdentityManagementService().isAuthorizedByTemplateName( principalId, KNSConstants.KUALI_RICE_SYSTEM_NAMESPACE, KimConstants.PermissionTemplateNames.INITIATE_DOCUMENT, permissionDetails, null );
077                    }
078                }
079            }
080            if ( !authorized ) {
081                throw new RuntimeException( "You must be able to initiate the GLCP or LLCP documents to use this page.  (Backdoor users are not recognized.)" );
082            }
083        }
084        
085        @Override
086        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
087            checkAuthorization(request);
088            request.setAttribute("directories", getBatchDirectories());
089            request.getRequestDispatcher("/WEB-INF/jsp/batchFileUpload.jsp").forward(request, response);
090        }
091    
092        @Override
093        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
094            checkAuthorization(request);
095            ServletFileUpload upload = new ServletFileUpload();
096    
097            String destPath = null;
098            String fileName = null;
099            String tempDir = System.getProperty("java.io.tmpdir");
100            // Parse the request
101            try {
102                FileItemIterator iter = upload.getItemIterator(request);
103                while (iter.hasNext()) {
104                    FileItemStream item = iter.next();
105                    fileName = item.getName();
106                    LOG.info("Processing Item: " + item.getFieldName());
107                    if (item.isFormField()) {
108                        if (item.getFieldName().equals("uploadDir")) {
109                            Reader str = new InputStreamReader(item.openStream());
110                            StringWriter sw = new StringWriter();
111                            char buf[] = new char[100];
112                            int len;
113                            while ((len = str.read(buf)) > 0) {
114                                sw.write(buf, 0, len);
115                            }
116                            destPath = sw.toString();
117                        }
118                    } else {
119                        InputStream stream = item.openStream();
120                        fileName = item.getName();
121                        LOG.info("Uploading to Directory: " + tempDir );
122                        // Process the input stream
123                        FileOutputStream fos = new FileOutputStream(new File(tempDir, fileName));
124                        BufferedOutputStream bos = new BufferedOutputStream(fos, 1024 * 1024);
125                        byte buf[] = new byte[10240];
126                        int len;
127                        while ((len = stream.read(buf)) > 0) {
128                            bos.write(buf, 0, len);
129                        }
130                        bos.close();
131                        stream.close();
132                    }
133                }
134                LOG.info("Copying to Directory: " + destPath);
135                
136                if ( !getBatchDirectories().contains(destPath) ) {
137                    new File(tempDir, fileName).delete();
138                    throw new RuntimeException( "Illegal Attempt to upload to an unauthorized path: '" + destPath + "'" );
139                }
140                
141                BufferedInputStream bis = new BufferedInputStream( new FileInputStream( new File(tempDir, fileName) ) ); 
142                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(destPath, fileName)), 1024 * 1024);
143                byte buf[] = new byte[10240];
144                int len;
145                while ((len = bis.read(buf)) > 0) {
146                    bos.write(buf, 0, len);
147                }
148                bos.close();
149                bis.close();
150            }
151            catch (FileUploadException ex) {
152                LOG.error("Problem Uploading file", ex);
153            }
154            if (fileName != null) {
155                request.setAttribute("message", "Successfully uploaded " + fileName + " to " + destPath);
156            }
157            else {
158                request.setAttribute("message", "Upload Failed");
159            }
160            doGet(request, response);
161        }
162    
163        protected List<String> getBatchDirectories() {
164            List<String> dirs = new ArrayList<String>();
165            for (ModuleService moduleService : SpringContext.getBean(KualiModuleService.class).getInstalledModuleServices()) {
166                ModuleConfiguration moduleConfiguration = moduleService.getModuleConfiguration();
167                if (moduleConfiguration instanceof FinancialSystemModuleConfiguration) {
168                    List<String> batchFileDirectories = ((FinancialSystemModuleConfiguration) moduleConfiguration).getBatchFileDirectories();
169                    for (String batchFileDirectoryName : batchFileDirectories) {
170                        String directory = new File(batchFileDirectoryName).getAbsolutePath();
171                        if ( new File( directory, "originEntry" ).isDirectory() ) {
172                            dirs.add( new File( directory, "originEntry" ).getAbsolutePath() );
173                        }
174                    }
175                }
176            }
177            return dirs;
178        }
179    
180    }