| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License") + you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openmeetings.webservice; |
| |
| import static org.apache.openmeetings.webservice.Constants.TNS; |
| |
| import java.io.InputStream; |
| import java.util.List; |
| import java.util.Optional; |
| import java.util.Set; |
| |
| import javax.jws.WebMethod; |
| import javax.jws.WebParam; |
| import javax.jws.WebService; |
| import javax.ws.rs.Consumes; |
| import javax.ws.rs.DELETE; |
| import javax.ws.rs.GET; |
| import javax.ws.rs.POST; |
| import javax.ws.rs.Path; |
| import javax.ws.rs.PathParam; |
| import javax.ws.rs.Produces; |
| import javax.ws.rs.QueryParam; |
| import javax.ws.rs.core.MediaType; |
| |
| import org.apache.cxf.feature.Features; |
| import org.apache.cxf.jaxrs.ext.multipart.Multipart; |
| import org.apache.openmeetings.core.data.file.FileProcessor; |
| import org.apache.openmeetings.db.dto.basic.ServiceResult; |
| import org.apache.openmeetings.db.dto.basic.ServiceResult.Type; |
| import org.apache.openmeetings.db.dto.file.FileExplorerObject; |
| import org.apache.openmeetings.db.dto.file.FileItemDTO; |
| import org.apache.openmeetings.db.entity.file.FileItem; |
| import org.apache.openmeetings.db.entity.user.User; |
| import org.apache.openmeetings.db.entity.user.User.Right; |
| import org.apache.openmeetings.db.util.AuthLevelUtil; |
| import org.apache.openmeetings.util.process.ProcessResultList; |
| import org.apache.openmeetings.webservice.error.InternalServiceException; |
| import org.apache.openmeetings.webservice.error.ServiceException; |
| import org.apache.openmeetings.webservice.schema.FileExplorerObjectWrapper; |
| import org.apache.openmeetings.webservice.schema.FileItemDTOListWrapper; |
| import org.apache.openmeetings.webservice.schema.FileItemDTOWrapper; |
| import org.apache.openmeetings.webservice.schema.ServiceResultWrapper; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.stereotype.Service; |
| |
| import io.swagger.v3.oas.annotations.Operation; |
| import io.swagger.v3.oas.annotations.Parameter; |
| import io.swagger.v3.oas.annotations.media.Content; |
| import io.swagger.v3.oas.annotations.media.Schema; |
| import io.swagger.v3.oas.annotations.responses.ApiResponse; |
| import io.swagger.v3.oas.annotations.tags.Tag; |
| |
| /** |
| * |
| * Contains methods to import and upload files into the Files section of the |
| * conference room and the personal drive of any USER |
| * |
| * @author sebawagner |
| * |
| */ |
| @Service("fileWebService") |
| @WebService(serviceName="org.apache.openmeetings.webservice.FileWebService", targetNamespace = TNS) |
| @Features(features = "org.apache.cxf.ext.logging.LoggingFeature") |
| @Produces({MediaType.APPLICATION_JSON}) |
| @Tag(name = "FileService") |
| @Path("/file") |
| public class FileWebService extends BaseWebService { |
| private static final Logger log = LoggerFactory.getLogger(FileWebService.class); |
| |
| @Autowired |
| private FileProcessor fileProcessor; |
| |
| /** |
| * deletes files or folders based on it id |
| * |
| * @param sid |
| * The SID of the User. This SID must be marked as logged in |
| * @param id |
| * the id of the file or folder |
| * @return {@link ServiceResult} with result type |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @DELETE |
| @Path("/{id}") |
| @Operation( |
| description = "deletes files or folders based on it id", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "ServiceResult with result type", |
| content = @Content(schema = @Schema(implementation = ServiceResultWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public ServiceResult delete( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @QueryParam("sid") @WebParam(name="sid") String sid |
| , @Parameter(required = true, description = "the id of the file or folder") @PathParam("id") @WebParam(name="id") Long id |
| ) throws ServiceException |
| { |
| FileItem f = fileDao.get(id); |
| return performCall(sid, sd -> { |
| Long userId = sd.getUserId(); |
| Set<Right> rights = getRights(userId); |
| return AuthLevelUtil.hasWebServiceLevel(rights) |
| || (AuthLevelUtil.hasUserLevel(rights) && userId.equals(f.getOwnerId())); |
| } |
| , sd -> { |
| if (f == null) { |
| return new ServiceResult("Bad id", Type.ERROR); |
| } |
| fileDao.delete(f); |
| return new ServiceResult("Deleted", Type.SUCCESS); |
| }); |
| } |
| |
| /** |
| * |
| * deletes a file by its external Id and type |
| * |
| * @param sid |
| * The SID of the User. This SID must be marked as logged in |
| * @param externalType |
| * the externalType |
| * @param externalId |
| * the id of the file or folder |
| * @return {@link ServiceResult} with result type |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @DELETE |
| @Path("/{externaltype}/{externalid}") |
| @Operation( |
| description = "deletes a file by its external Id and type", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "ServiceResult with result type", |
| content = @Content(schema = @Schema(implementation = ServiceResultWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public ServiceResult deleteExternal( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @WebParam(name="sid") @QueryParam("sid") String sid |
| , @Parameter(required = true, description = "the externalType") @WebParam(name="externaltype") @PathParam("externaltype") String externalType |
| , @Parameter(required = true, description = "the id of the file or folder") @WebParam(name="externalid") @PathParam("externalid") String externalId |
| ) throws ServiceException |
| { |
| return performCall(sid, User.Right.SOAP, sd -> { |
| FileItem f = fileDao.get(externalId, externalType); |
| fileDao.delete(f); |
| return new ServiceResult("Deleted", Type.SUCCESS); |
| }); |
| } |
| |
| /** |
| * to add a folder to the private drive, set parentId = 0 and isOwner to 1/true and |
| * externalUserId/externalUserType to a valid USER |
| * |
| * @param sid |
| * The SID of the User. This SID must be marked as logged in |
| * @param file |
| * the The file attributes to be added |
| * @param stream |
| * the The file to be added |
| * @return - Object created |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @WebMethod |
| @POST |
| @Consumes(MediaType.MULTIPART_FORM_DATA) |
| @Path("/") |
| @Operation( |
| description = "to add a folder to the private drive, set parentId = 0 and isOwner to 1/true and\n" |
| + " externalUserId/externalUserType to a valid USER", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "Object created", |
| content = @Content(schema = @Schema(implementation = FileItemDTOWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public FileItemDTO add( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @WebParam(name="sid") @QueryParam("sid") String sid |
| , @Parameter(required = true, description = "the The file attributes to be added") @Multipart(value = "file", type = MediaType.APPLICATION_JSON) @WebParam(name="file") FileItemDTO file |
| , @Parameter(required = true, description = "the The file to be added") @Multipart(value = "stream", type = MediaType.APPLICATION_OCTET_STREAM, required = false) @WebParam(name="stream") InputStream stream |
| ) throws ServiceException |
| { |
| return performCall(sid, User.Right.SOAP, sd -> { |
| FileItem f = file == null ? null : file.get(); |
| if (f == null || f.getId() != null) { |
| throw new InternalServiceException("Bad id"); |
| } |
| f.setInsertedBy(sd.getUserId()); |
| if (stream != null) { |
| try { |
| ProcessResultList result = fileProcessor.processFile(f, stream, Optional.empty()); |
| if (result.hasError()) { |
| throw new ServiceException(result.getLogMessage()); |
| } |
| } catch (Exception e) { |
| throw new InternalServiceException(e.getMessage()); |
| } |
| } else { |
| f = fileDao.update(f); |
| } |
| return new FileItemDTO(f); |
| }); |
| } |
| |
| /** |
| * Get all files by external type |
| * |
| * @param sid |
| * The SID of the User. This SID must be marked as logged in |
| * @param externalType |
| * External type for file listing |
| * @return - the list of files for given external type |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @WebMethod |
| @GET |
| @Path("/{externaltype}") |
| @Operation( |
| description = "Get all files by external type", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "the list of files for given external type", |
| content = @Content(schema = @Schema(implementation = FileItemDTOListWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public List<FileItemDTO> getAllExternal( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @WebParam(name="sid") @QueryParam("sid") String sid |
| , @Parameter(required = true, description = "External type for file listing") @WebParam(name="externaltype") @PathParam("externaltype") String externalType |
| ) throws ServiceException |
| { |
| log.debug("getAllExternal::externalType {}", externalType); |
| return performCall(sid, User.Right.SOAP, sd -> FileItemDTO.list(fileDao.getExternal(externalType))); |
| } |
| |
| /** |
| * Get a File Explorer Object by a given ROOM |
| * |
| * @param sid |
| * The SID of the User. This SID must be marked as logged in |
| * @param roomId |
| * ROOM Id |
| * @return - File Explorer Object by a given ROOM |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @WebMethod |
| @GET |
| @Path("/room/{id}") |
| @Operation( |
| description = "Get a File Explorer Object by a given ROOM", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "File Explorer Object by a given ROOM", |
| content = @Content(schema = @Schema(implementation = FileExplorerObjectWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public FileExplorerObject getRoom( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @WebParam(name="sid") @QueryParam("sid") String sid |
| , @Parameter(required = true, description = "ROOM Id") @WebParam(name="id") @PathParam("id") long roomId |
| ) throws ServiceException |
| { |
| log.debug("getRoom::roomId {}", roomId); |
| return performCall(sid, User.Right.SOAP, sd -> { |
| FileExplorerObject fileExplorerObject = new FileExplorerObject(); |
| |
| // Home File List |
| List<FileItem> fList = fileDao.getByOwner(sd.getUserId()); |
| fileExplorerObject.setUser(fList, fileDao.getSize(fList)); |
| |
| // Public File List |
| List<FileItem> rList = fileDao.getByRoom(roomId); |
| fileExplorerObject.setRoom(rList, fileDao.getSize(rList)); |
| |
| return fileExplorerObject; |
| }); |
| } |
| |
| /** |
| * |
| * Get list of {@link FileItemDTO} by parent |
| * |
| * @param sid |
| * SID The SID of the User. This SID must be marked as logged in |
| * @param parentId |
| * the parent folder id |
| * @param roomId |
| * the room id |
| * @return - list of file explorer items |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @WebMethod |
| @GET |
| @Path("/room/{id}/{parent}") |
| @Operation( |
| description = "Get list of FileItemDTO by parent", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "list of file explorer items", |
| content = @Content(schema = @Schema(implementation = FileItemDTOListWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public List<FileItemDTO> getRoomByParent( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @WebParam(name="sid") @QueryParam("sid") String sid |
| , @Parameter(required = true, description = "the parent folder id") @WebParam(name="id") @PathParam("id") long roomId |
| , @Parameter(required = true, description = "the room id") @WebParam(name="parent") @PathParam("parent") long parentId |
| ) throws ServiceException |
| { |
| log.debug("getRoomByParent {}", parentId); |
| return performCall(sid, User.Right.ROOM, sd -> { |
| List<FileItem> list; |
| if (parentId < 0) { |
| if (parentId == -1) { |
| list = fileDao.getByOwner(sd.getUserId()); |
| } else { |
| list = fileDao.getByRoom(roomId); |
| } |
| } else { |
| list = fileDao.getByParent(parentId); |
| } |
| return FileItemDTO.list(list); |
| }); |
| } |
| |
| /** |
| * |
| * update a file or folder name |
| * |
| * @param sid |
| * SID The SID of the User. This SID must be marked as logged in |
| * @param id |
| * file or folder id |
| * @param name |
| * new file or folder name |
| * @return - resulting file object |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @WebMethod |
| @POST |
| @Path("/rename/{id}/{name}") |
| @Operation( |
| description = "update a file or folder name", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "resulting file object", |
| content = @Content(schema = @Schema(implementation = FileItemDTOWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public FileItemDTO rename( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @WebParam(name="sid") @QueryParam("sid") String sid |
| , @Parameter(required = true, description = "file or folder id") @WebParam(name="id") @PathParam("id") long id |
| , @Parameter(required = true, description = "new file or folder name") @WebParam(name="name") @PathParam("name") String name |
| ) throws ServiceException |
| { |
| log.debug("rename {}", id); |
| return performCall(sid, User.Right.SOAP, sd -> { |
| FileItem f = fileDao.rename(id, name); |
| return f == null ? null : new FileItemDTO(f); |
| }); |
| } |
| |
| /** |
| * move a file or folder |
| * |
| * @param sid |
| * SID The SID of the User. This SID must be marked as logged in |
| * @param id |
| * current file or folder id to be moved |
| * @param roomId |
| * room this file need to be moved |
| * @param parentId |
| * new parent folder id |
| * @return - resulting file object |
| * @throws {@link ServiceException} in case of any errors |
| */ |
| @WebMethod |
| @POST |
| @Path("/move/{roomid}/{id}/{parentid}") |
| @Operation( |
| description = "move a file or folder", |
| responses = { |
| @ApiResponse(responseCode = "200", description = "resulting file object", |
| content = @Content(schema = @Schema(implementation = FileItemDTOWrapper.class))), |
| @ApiResponse(responseCode = "500", description = "Error in case of invalid credentials or server error") |
| } |
| ) |
| public FileItemDTO move( |
| @Parameter(required = true, description = "The SID of the User. This SID must be marked as Loggedin") @WebParam(name="sid") @QueryParam("sid") String sid |
| , @Parameter(required = true, description = "current file or folder id to be moved") @WebParam(name="id") @PathParam("id") long id |
| , @Parameter(required = true, description = "room this file need to be moved") @WebParam(name="roomid") @PathParam("roomid") long roomId |
| , @Parameter(required = true, description = "new parent folder id") @WebParam(name="parentid") @PathParam("parentid") long parentId |
| ) throws ServiceException |
| { |
| log.debug("move {}", id); |
| return performCall(sid, User.Right.SOAP, sd -> { |
| FileItem f = fileDao.move(id, parentId, sd.getUserId(), roomId); |
| return f == null ? null : new FileItemDTO(f); |
| }); |
| } |
| } |