001/* 002 * Copyright 2023 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.web.usermanagement; 017 018import java.io.File; 019import java.io.FileInputStream; 020import java.io.IOException; 021import java.nio.charset.StandardCharsets; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.avalon.framework.parameters.Parameters; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.cocoon.acting.ServiceableAction; 029import org.apache.cocoon.environment.ObjectModelHelper; 030import org.apache.cocoon.environment.Redirector; 031import org.apache.cocoon.environment.Request; 032import org.apache.cocoon.environment.SourceResolver; 033import org.apache.cocoon.servlet.multipart.Part; 034import org.apache.cocoon.servlet.multipart.PartOnDisk; 035import org.apache.cocoon.servlet.multipart.RejectedPart; 036import org.apache.commons.io.FilenameUtils; 037import org.apache.commons.io.IOUtils; 038import org.apache.commons.io.input.BOMInputStream; 039import org.quartz.SchedulerException; 040 041import org.ametys.core.cocoon.JSonReader; 042import org.ametys.core.user.CurrentUserProvider; 043import org.ametys.plugins.core.schedule.Scheduler; 044import org.ametys.web.WebHelper; 045 046/** 047 * Import user to invit from a CSV or text file. 048 */ 049public class ImportInvitationsAction extends ServiceableAction 050{ 051 private static final String[] _ALLOWED_EXTENSIONS = new String[] {"txt", "csv"}; 052 private Scheduler _scheduler; 053 private CurrentUserProvider _currentUserProvider; 054 055 @Override 056 public void service(ServiceManager smanager) throws ServiceException 057 { 058 super.service(smanager); 059 _scheduler = (Scheduler) smanager.lookup(Scheduler.ROLE); 060 _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE); 061 } 062 063 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 064 { 065 Request request = ObjectModelHelper.getRequest(objectModel); 066 067 Part part = (Part) request.get("file"); 068 if (part instanceof RejectedPart) 069 { 070 request.setAttribute(JSonReader.OBJECT_TO_READ, Map.of("success", false, "error", "rejected-file")); 071 return EMPTY_MAP; 072 } 073 074 PartOnDisk uploadedFilePart = (PartOnDisk) part; 075 File uploadedFile = (uploadedFilePart != null) ? uploadedFilePart.getFile() : null; 076 String filename = (uploadedFilePart != null) ? uploadedFilePart.getFileName().toLowerCase() : null; 077 078 if (!FilenameUtils.isExtension(filename, _ALLOWED_EXTENSIONS)) 079 { 080 request.setAttribute(JSonReader.OBJECT_TO_READ, Map.of("success", false, "error", "invalid-extension")); 081 return EMPTY_MAP; 082 } 083 084 try (FileInputStream fileIS = new FileInputStream(uploadedFile); 085 BOMInputStream bomIS = new BOMInputStream(fileIS)) 086 { 087 List<String> guestLines = IOUtils.readLines(bomIS, StandardCharsets.UTF_8); 088 089 String populationAndUserDirectory = request.getParameter("userDirectory"); 090 String[] split = populationAndUserDirectory.split("#"); 091 String populationId = split[0]; 092 String userDirectoryId = split[1]; 093 String siteName = WebHelper.getSiteName(request); 094 095 boolean resendInvitation = "true".equals(request.getParameter("resendInvitations")); 096 097 // Schedule the sending of invitations 098 _scheduler.scheduleJob(new SendInvitationsRunnable(guestLines, siteName, populationId, userDirectoryId, resendInvitation, _currentUserProvider.getUser())); 099 100 } 101 catch (IOException e) 102 { 103 getLogger().error("Failed to read file to send invitations from CSV file", e); 104 request.setAttribute(JSonReader.OBJECT_TO_READ, Map.of("success", false, "error", "file-error")); 105 return EMPTY_MAP; 106 } 107 catch (SchedulerException e) 108 { 109 getLogger().error("An exception occurred while trying to schedule the sending of invitations", e); 110 request.setAttribute(JSonReader.OBJECT_TO_READ, Map.of("success", false, "error", "schedule-error")); 111 return EMPTY_MAP; 112 } 113 114 request.setAttribute(JSonReader.OBJECT_TO_READ, Map.of("success", true)); 115 return EMPTY_MAP; 116 } 117 118}