feat(office文件预览): 高版本权限问题适配

This commit is contained in:
MAC 2023-01-31 07:11:30 +08:00
parent d74980fb1f
commit 7fff22970f
93 changed files with 5357 additions and 901 deletions

View File

@ -9,7 +9,7 @@ public interface IFileService extends IService<FileBean> {
Long getFilePointCount(String fileId);
void unzipFile(String userFileId, int unzipMode, String filePath);
void updateFileDetail(String userFileId, String identifier, long fileSize, long modifyUserId);
void updateFileDetail(String userFileId, String identifier, long fileSize);
FileDetailVO getFileDetail(String userFileId);

View File

@ -3,7 +3,6 @@ package com.qiwenshare.file.controller;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.qiwenshare.common.exception.NotLoginException;
import com.qiwenshare.common.result.RestResult;
@ -16,21 +15,26 @@ import com.qiwenshare.file.api.IUserService;
import com.qiwenshare.file.component.FileDealComp;
import com.qiwenshare.file.domain.FileBean;
import com.qiwenshare.file.domain.UserFile;
import com.qiwenshare.file.domain.user.UserBean;
import com.qiwenshare.file.dto.file.CreateOfficeFileDTO;
import com.qiwenshare.file.dto.file.EditOfficeFileDTO;
import com.qiwenshare.file.dto.file.PreviewOfficeFileDTO;
import com.qiwenshare.file.helper.ConfigManager;
import com.qiwenshare.file.util.FileModel;
import com.qiwenshare.file.office.documentserver.managers.history.HistoryManager;
import com.qiwenshare.file.office.documentserver.models.enums.Action;
import com.qiwenshare.file.office.documentserver.models.enums.Type;
import com.qiwenshare.file.office.documentserver.models.filemodel.FileModel;
import com.qiwenshare.file.office.entities.User;
import com.qiwenshare.file.office.services.configurers.FileConfigurer;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultFileWrapper;
import com.qiwenshare.ufop.factory.UFOPFactory;
import com.qiwenshare.ufop.operation.copy.Copier;
import com.qiwenshare.ufop.operation.copy.domain.CopyFile;
import com.qiwenshare.ufop.operation.download.domain.DownloadFile;
import com.qiwenshare.ufop.operation.write.Writer;
import com.qiwenshare.ufop.operation.write.domain.WriteFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@ -45,6 +49,7 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import java.util.UUID;
@ -67,11 +72,20 @@ public class OfficeController {
@Value("${ufop.storage-type}")
private Integer storageType;
@Value("${files.docservice.url.site}")
private String docserviceSite;
@Value("${files.docservice.url.api}")
private String docserviceApiUrl;
@Autowired
private FileConfigurer<DefaultFileWrapper> fileConfigurer;
@Resource
IFileService fileService;
@Resource
IUserFileService userFileService;
@Autowired
private HistoryManager historyManager;
@Operation(summary = "创建office文件", description = "创建office文件", tags = {"office"})
@ResponseBody
@ -139,28 +153,38 @@ public class OfficeController {
@Operation(summary = "预览office文件", description = "预览office文件", tags = {"office"})
@RequestMapping(value = "/previewofficefile", method = RequestMethod.POST)
@ResponseBody
public RestResult<Object> previewOfficeFile(HttpServletRequest request, @RequestBody PreviewOfficeFileDTO previewOfficeFileDTO, @RequestHeader("token") String token) {
public RestResult<Object> previewOfficeFile(HttpServletRequest request, @RequestBody PreviewOfficeFileDTO previewOfficeFileDTO) {
RestResult<Object> result = new RestResult<>();
try {
JwtUser loginUser = SessionUtil.getSession();
UserFile userFile = userFileService.getById(previewOfficeFileDTO.getUserFileId());
String baseUrl = request.getScheme()+"://"+ deploymentHost + ":" + port + request.getContextPath();
String query = "?type=show&token="+token;
String callbackUrl = baseUrl + "/office/IndexServlet" + query;
FileModel file = new FileModel(userFile.getUserFileId(),
userFile.getFileName() + "." + userFile.getExtendName(),
previewOfficeFileDTO.getPreviewUrl(),
userFile.getUploadTime(),
String.valueOf(loginUser.getUserId()),
loginUser.getUsername(),
callbackUrl,
"view");
UserBean userBean = userService.getById(loginUser.getUserId());
User user = new User(userBean);
Action action = Action.view;
Type type = Type.desktop;
Locale locale = new Locale("zh");
FileModel fileModel = fileConfigurer.getFileModel(
DefaultFileWrapper
.builder()
.userFileId(userFile.getUserFileId())
.fileName(userFile.getFileName() + "." + userFile.getExtendName())
.type(type)
.lang(locale.toLanguageTag())
.action(action)
.user(user)
.actionData(previewOfficeFileDTO.getPreviewUrl())
.build()
);
JSONObject jsonObject = new JSONObject();
jsonObject.put("file",file);
jsonObject.put("docserviceApiUrl", ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.api"));
jsonObject.put("file",fileModel);
// jsonObject.put("fileHistory", historyManager.getHistory(fileModel.getDocument())); // get file history and add it to the model
jsonObject.put("docserviceApiUrl", docserviceSite + docserviceApiUrl);
jsonObject.put("reportName",userFile.getFileName());
result.setData(jsonObject);
result.setCode(200);
@ -175,32 +199,35 @@ public class OfficeController {
@Operation(summary = "编辑office文件", description = "编辑office文件", tags = {"office"})
@ResponseBody
@RequestMapping(value = "/editofficefile", method = RequestMethod.POST)
public RestResult<Object> editOfficeFile(HttpServletRequest request, @RequestBody EditOfficeFileDTO editOfficeFileDTO, @RequestHeader("token") String token) {
public RestResult<Object> editOfficeFile(HttpServletRequest request, @RequestBody EditOfficeFileDTO editOfficeFileDTO) {
RestResult<Object> result = new RestResult<>();
log.info("editOfficeFile");
try {
JwtUser loginUser = SessionUtil.getSession();
UserFile userFile = userFileService.getById(editOfficeFileDTO.getUserFileId());
String baseUrl = request.getScheme()+"://"+ deploymentHost + ":" + port + request.getContextPath();
log.info("回调地址baseUrl" + baseUrl);
String query = "?type=edit&userFileId="+userFile.getUserFileId()+"&token="+token;
String callbackUrl = baseUrl + "/office/IndexServlet" + query;
FileModel file = new FileModel(userFile.getUserFileId(),
userFile.getFileName() + "." + userFile.getExtendName(),
editOfficeFileDTO.getPreviewUrl(),
userFile.getUploadTime(),
String.valueOf(loginUser.getUserId()),
loginUser.getUsername(),
callbackUrl,
"edit");
UserBean userBean = userService.getById(loginUser.getUserId());
User user = new User(userBean);
Action action = Action.edit;
Type type = Type.desktop;
Locale locale = new Locale("zh");
FileModel fileModel = fileConfigurer.getFileModel(
DefaultFileWrapper
.builder()
.userFileId(userFile.getUserFileId())
.fileName(userFile.getFileName() + "." + userFile.getExtendName())
.type(type)
.lang(locale.toLanguageTag())
.action(action)
.user(user)
.actionData(editOfficeFileDTO.getPreviewUrl())
.build()
);
JSONObject jsonObject = new JSONObject();
jsonObject.put("file",file);
jsonObject.put("docserviceApiUrl",ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.api"));
jsonObject.put("file",fileModel);
jsonObject.put("docserviceApiUrl", docserviceSite + docserviceApiUrl);
jsonObject.put("reportName",userFile.getFileName());
result.setData(jsonObject);
result.setCode(200);
@ -234,7 +261,7 @@ public class OfficeController {
String type = request.getParameter("type");
String downloadUri = (String) jsonObj.get("url");
if("edit".equals(type)){//修改报告
if("edit".equals(type)){ //修改报告
String userFileId = request.getParameter("userFileId");
UserFile userFile = userFileService.getById(userFileId);
FileBean fileBean = fileService.getById(userFile.getFileId());
@ -256,14 +283,14 @@ public class OfficeController {
} finally {
int fileLength = connection.getContentLength();
log.info("当前修改文件大小为:" + Long.valueOf(fileLength));
log.info("当前修改文件大小为:" + (long) fileLength);
DownloadFile downloadFile = new DownloadFile();
downloadFile.setFileUrl(fileBean.getFileUrl());
InputStream inputStream = ufopFactory.getDownloader(fileBean.getStorageType()).getInputStream(downloadFile);
String md5Str = DigestUtils.md5Hex(inputStream);
fileService.updateFileDetail(userFile.getUserFileId(), md5Str, fileLength, userId);
fileService.updateFileDetail(userFile.getUserFileId(), md5Str, fileLength);
connection.disconnect();
}
}
@ -275,6 +302,7 @@ public class OfficeController {
}else {
log.debug("状态为0") ;
writer.write("{\"error\":" + "0" + "}");
}
}

View File

@ -1,60 +0,0 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.helper;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.util.Properties;
@Component
public class ConfigManager
{
private static Properties properties;
static
{
Init();
}
private static void Init()
{
try
{
properties = new Properties();
InputStream stream = ConfigManager.class.getResourceAsStream("/config/settings.properties");
properties.load(stream);
}
catch (Exception ex)
{
properties = null;
}
}
public static String GetProperty(String name)
{
if (properties == null)
{
return "";
}
String property = properties.getProperty(name);
return property == null ? "" : property;
}
}

View File

@ -1,371 +0,0 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.helper;
import com.alibaba.fastjson2.JSONObject;
import com.qiwenshare.file.component.JwtComp;
import com.qiwenshare.file.service.OfficeConverterService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
@Component
public class DocumentManager
{
@Resource
private JwtComp jwtComp;
@Resource
private OfficeConverterService officeConverterService;
private static HttpServletRequest request;
public static void Init(HttpServletRequest req, HttpServletResponse resp)
{
request = req;
}
public static long GetMaxFileSize()
{
long size;
try
{
size = Long.parseLong(ConfigManager.GetProperty("filesize-max"));
}
catch (Exception ex)
{
size = 0;
}
return size > 0 ? size : 5 * 1024 * 1024;
}
public static List<String> GetFileExts()
{
List<String> res = new ArrayList<>();
res.addAll(GetViewedExts());
res.addAll(GetEditedExts());
res.addAll(GetConvertExts());
return res;
}
public static List<String> GetViewedExts()
{
String exts = ConfigManager.GetProperty("files.docservice.viewed-docs");
return Arrays.asList(exts.split("\\|"));
}
public static List<String> GetEditedExts()
{
String exts = ConfigManager.GetProperty("files.docservice.edited-docs");
return Arrays.asList(exts.split("\\|"));
}
public static List<String> GetConvertExts()
{
String exts = ConfigManager.GetProperty("files.docservice.convert-docs");
return Arrays.asList(exts.split("\\|"));
}
public static String CurUserHostAddress(String userAddress)
{
if(userAddress == null)
{
try
{
userAddress = InetAddress.getLocalHost().getHostAddress();
}
catch (Exception ex)
{
userAddress = "";
}
}
return userAddress.replaceAll("[^0-9a-zA-Z.=]", "_");
}
public static String FilesRootPath(String userAddress)
{
String hostAddress = CurUserHostAddress(userAddress);
String serverPath = request.getSession().getServletContext().getRealPath("");
String storagePath = ConfigManager.GetProperty("storage-folder");
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
File file = new File(directory);
if (!file.exists())
{
file.mkdirs();
}
return directory;
}
public static String StoragePath(String fileName, String userAddress)
{
String directory = FilesRootPath(userAddress);
return directory + FileUtility.GetFileName(fileName);
}
public static String ForcesavePath(String fileName, String userAddress, Boolean create)
{
String hostAddress = CurUserHostAddress(userAddress);
String serverPath = request.getSession().getServletContext().getRealPath("");
String storagePath = ConfigManager.GetProperty("storage-folder");
String directory = serverPath + storagePath + File.separator + hostAddress + File.separator;
File file = new File(directory);
if (!file.exists()) return "";
directory = directory + fileName + "-hist" + File.separator;
file = new File(directory);
if (!create && !file.exists()) return "";
file.mkdirs();
directory = directory + fileName;
file = new File(directory);
if (!create && !file.exists()) {
return "";
}
return directory;
}
public static String HistoryDir(String storagePath)
{
return storagePath += "-hist";
}
public static String VersionDir(String histPath, Integer version)
{
return histPath + File.separator + Integer.toString(version);
}
public static String VersionDir(String fileName, String userAddress, Integer version)
{
return VersionDir(HistoryDir(StoragePath(fileName, userAddress)), version);
}
public static Integer GetFileVersion(String historyPath)
{
File dir = new File(historyPath);
if (!dir.exists()) return 0;
File[] dirs = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
return dirs.length + 1;
}
public static int GetFileVersion(String fileName, String userAddress)
{
return GetFileVersion(HistoryDir(StoragePath(fileName, userAddress)));
}
public static String GetCorrectName(String fileName, String userAddress)
{
String baseName = FileUtility.GetFileNameWithoutExtension(fileName);
String ext = FileUtility.GetFileExtension(fileName);
String name = baseName + ext;
File file = new File(StoragePath(name, userAddress));
for (int i = 1; file.exists(); i++)
{
name = baseName + " (" + i + ")" + ext;
file = new File(StoragePath(name, userAddress));
}
return name;
}
public static void CreateMeta(String fileName, String uid, String uname, String userAddress) throws Exception
{
String histDir = HistoryDir(StoragePath(fileName, userAddress));
File dir = new File(histDir);
dir.mkdir();
JSONObject json = new JSONObject();
json.put("created", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
json.put("id", (uid == null || uid.isEmpty()) ? "uid-1" : uid);
if (json.get("id").equals("uid-0")) {
json.put("name", null);
} else {
json.put("name", (uname == null || uname.isEmpty()) ? "John Smith" : uname);
}
File meta = new File(histDir + File.separator + "createdInfo.json");
try (FileWriter writer = new FileWriter(meta)) {
// json.writeJSONString(writer);
}
}
public static File[] GetStoredFiles(String userAddress)
{
String directory = FilesRootPath(userAddress);
File file = new File(directory);
return file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile();
}
});
}
public static String CreateDemo(String fileExt, Boolean sample, String uid, String uname) throws Exception
{
String demoName = (sample ? "sample." : "new.") + fileExt;
String demoPath = "assets" + File.separator + (sample ? "sample" : "new") + File.separator;
String fileName = GetCorrectName(demoName, null);
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(demoPath + demoName);
File file = new File(StoragePath(fileName, null));
try (FileOutputStream out = new FileOutputStream(file))
{
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
}
CreateMeta(fileName, uid, uname, null);
return fileName;
}
public static String GetFileUri(String fileName, Boolean forDocumentServer)
{
try
{
String serverPath = GetServerUrl(forDocumentServer);
String storagePath = ConfigManager.GetProperty("storage-folder");
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()).replace("+", "%20");
return filePath;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
public ArrayList<Map<String, Object>> GetFilesInfo(){
ArrayList<Map<String, Object>> files = new ArrayList<>();
for(File file : GetStoredFiles(null)){
Map<String, Object> map = new LinkedHashMap<>();
map.put("version", GetFileVersion(file.getName(), null));
map.put("id", officeConverterService.GenerateRevisionId(CurUserHostAddress(null) + "/" + file.getName() + "/" + Long.toString(new File(StoragePath(file.getName(), null)).lastModified())));
map.put("contentLength", new BigDecimal(String.valueOf((file.length()/1024.0))).setScale(2, RoundingMode.HALF_UP) + " KB");
map.put("pureContentLength", file.length());
map.put("title", file.getName());
map.put("updated", String.valueOf(new Date(file.lastModified())));
files.add(map);
}
return files;
}
public ArrayList<Map<String, Object>> GetFilesInfo(String fileId){
ArrayList<Map<String, Object>> file = new ArrayList<>();
for (Map<String, Object> map : GetFilesInfo()){
if (map.get("id").equals(fileId)){
file.add(map);
break;
}
}
return file;
}
public static String GetPathUri(String path)
{
String serverPath = GetServerUrl(true);
String storagePath = ConfigManager.GetProperty("storage-folder");
String hostAddress = CurUserHostAddress(null);
String filePath = serverPath + "/" + storagePath + "/" + hostAddress + "/" + path.replace(File.separator, "/").substring(FilesRootPath(null).length()).replace(" ", "%20");
return filePath;
}
public static String GetServerUrl(Boolean forDocumentServer) {
if (forDocumentServer && !ConfigManager.GetProperty("files.docservice.url.example").equals("")) {
return ConfigManager.GetProperty("files.docservice.url.example");
} else {
return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}
}
public static String GetCallback(String fileName)
{
String serverPath = GetServerUrl(true);
String hostAddress = CurUserHostAddress(null);
try
{
String query = "?type=track&fileName=" + URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString()) + "&userAddress=" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
return serverPath + "/IndexServlet" + query;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
public static Boolean TokenEnabled()
{
String secret = GetTokenSecret();
return secret != null && !secret.isEmpty();
}
private static String GetTokenSecret()
{
return ConfigManager.GetProperty("files.docservice.secret");
}
}

View File

@ -1,121 +0,0 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.helper;
import com.qiwenshare.file.constant.FileType;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FileUtility
{
static {}
public static FileType GetFileType(String fileName)
{
String ext = GetFileExtension(fileName).toLowerCase();
if (ExtsDocument.contains(ext))
return FileType.Word;
if (ExtsSpreadsheet.contains(ext))
return FileType.Cell;
if (ExtsPresentation.contains(ext))
return FileType.Slide;
return FileType.Word;
}
public static List<String> ExtsDocument = Arrays.asList
(
".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps"
);
public static List<String> ExtsSpreadsheet = Arrays.asList
(
".xls", ".xlsx", ".xlsm",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv"
);
public static List<String> ExtsPresentation = Arrays.asList
(
".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp"
);
public static String GetFileName(String url)
{
if (url == null) return "";
String fileName = url.substring(url.lastIndexOf('/') + 1, url.length());
fileName = fileName.split("\\?")[0];
return fileName;
}
public static String GetFileNameWithoutExtension(String url)
{
String fileName = GetFileName(url);
if (fileName == null) return null;
String fileNameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));
return fileNameWithoutExt;
}
public static String GetFileExtension(String url)
{
String fileName = GetFileName(url);
if (fileName == null) return null;
String fileExt = fileName.substring(fileName.lastIndexOf("."));
return fileExt.toLowerCase();
}
public static Map<String, String> GetUrlParams(String url)
{
try
{
String query = new URL(url).getQuery();
String[] params = query.split("&");
Map<String, String> map = new HashMap<>();
for (String param : params)
{
String name = param.split("=")[0];
String value = param.split("=")[1];
map.put(name, value);
}
return map;
}
catch (Exception ex)
{
return null;
}
}
}

View File

@ -1,299 +0,0 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.helper;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import com.qiwenshare.file.component.JwtComp;
import com.qiwenshare.file.service.OfficeConverterService;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
@Component
public class TrackManager {
@Resource
private JwtComp jwtComp;
@Resource
private OfficeConverterService officeConverterService;
private static final String DocumentJwtHeader = ConfigManager.GetProperty("files.docservice.header");
public JSONObject readBody(HttpServletRequest request, PrintWriter writer) throws Exception {
String bodyString = "";
try {
Scanner scanner = new Scanner(request.getInputStream());
scanner.useDelimiter("\\A");
bodyString = scanner.hasNext() ? scanner.next() : "";
scanner.close();
}
catch (Exception ex) {
writer.write("get request.getInputStream error:" + ex.getMessage());
throw ex;
}
if (bodyString.isEmpty()) {
writer.write("empty request.getInputStream");
throw new Exception("empty request.getInputStream");
}
JSONObject body;
try {
body = JSONObject.parseObject(bodyString);
} catch (Exception ex) {
writer.write("JSONParser.parse error:" + ex.getMessage());
throw ex;
}
if (DocumentManager.TokenEnabled()) {
String token = (String) body.get("token");
if (token == null) {
String header = (String) request.getHeader(DocumentJwtHeader == null || DocumentJwtHeader.isEmpty() ? "Authorization" : DocumentJwtHeader);
if (header != null && !header.isEmpty()) {
token = header.startsWith("Bearer ") ? header.substring(7) : header;
}
}
if (token == null || token.isEmpty()) {
writer.write("{\"error\":1,\"message\":\"JWT expected\"}");
throw new Exception("{\"error\":1,\"message\":\"JWT expected\"}");
}
Claims claims = jwtComp.parseJWT(token);
try {
body = JSONObject.parseObject(JSON.toJSONString(claims));
} catch (Exception ex) {
writer.write("JSONParser.parse error:" + ex.getMessage());
throw ex;
}
if (body == null) {
writer.write("{\"error\":1,\"message\":\"JWT validation failed\"}");
throw new Exception("{\"error\":1,\"message\":\"JWT validation failed\"}");
}
}
return body;
}
public void processSave(JSONObject body, String fileName, String userAddress) throws Exception {
String downloadUri = (String) body.get("url");
String changesUri = (String) body.get("changesurl");
String key = (String) body.get("key");
String newFileName = fileName;
String curExt = FileUtility.GetFileExtension(fileName);
String downloadExt = FileUtility.GetFileExtension(downloadUri);
if (!curExt.equals(downloadExt)) {
try {
String newFileUri = officeConverterService.GetConvertedUri(downloadUri, downloadExt, curExt, officeConverterService.GenerateRevisionId(downloadUri), null, false);
if (newFileUri.isEmpty()) {
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
}
String storagePath = DocumentManager.StoragePath(newFileName, userAddress);
File histDir = new File(DocumentManager.HistoryDir(storagePath));
if (!histDir.exists()) histDir.mkdirs();
String versionDir = DocumentManager.VersionDir(histDir.getAbsolutePath(), DocumentManager.GetFileVersion(histDir.getAbsolutePath()));
File ver = new File(versionDir);
File lastVersion = new File(DocumentManager.StoragePath(fileName, userAddress));
File toSave = new File(storagePath);
if (!ver.exists()) ver.mkdirs();
lastVersion.renameTo(new File(versionDir + File.separator + "prev" + curExt));
downloadToFile(downloadUri, toSave);
downloadToFile(changesUri, new File(versionDir + File.separator + "diff.zip"));
String history = (String) body.get("changeshistory");
if (history == null && body.containsKey("history")) {
history = ((JSONObject) body.get("history")).toJSONString();
}
if (history != null && !history.isEmpty()) {
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "changes.json"));
fw.write(history);
fw.close();
}
FileWriter fw = new FileWriter(new File(versionDir + File.separator + "key.txt"));
fw.write(key);
fw.close();
String forcesavePath = DocumentManager.ForcesavePath(newFileName, userAddress, false);
if (!forcesavePath.equals("")) {
File forceSaveFile = new File(forcesavePath);
forceSaveFile.delete();
}
}
public void processForceSave(JSONObject body, String fileName, String userAddress) throws Exception {
String downloadUri = (String) body.get("url");
String curExt = FileUtility.GetFileExtension(fileName);
String downloadExt = FileUtility.GetFileExtension(downloadUri);
Boolean newFileName = false;
if (!curExt.equals(downloadExt)) {
try {
String newFileUri = officeConverterService.GetConvertedUri(downloadUri, downloadExt, curExt, officeConverterService.GenerateRevisionId(downloadUri), null, false);
if (newFileUri.isEmpty()) {
newFileName = true;
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = true;
}
}
String forcesavePath = "";
boolean isSubmitForm = body.get("forcesavetype").toString().equals("3");
if (isSubmitForm) {
//new file
if (newFileName){
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + "-form" + downloadExt, userAddress);
} else {
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + "-form" + curExt, userAddress);
}
forcesavePath = DocumentManager.StoragePath(fileName, userAddress);
} else {
if (newFileName){
fileName = DocumentManager.GetCorrectName(FileUtility.GetFileNameWithoutExtension(fileName) + downloadExt, userAddress);
}
forcesavePath = DocumentManager.ForcesavePath(fileName, userAddress, false);
if (forcesavePath == "") {
forcesavePath = DocumentManager.ForcesavePath(fileName, userAddress, true);
}
}
File toSave = new File(forcesavePath);
downloadToFile(downloadUri, toSave);
if (isSubmitForm) {
JSONArray actions = (JSONArray) body.get("actions");
JSONObject action = (JSONObject) actions.get(0);
String user = (String) action.get("userid");
DocumentManager.CreateMeta(fileName, user, "Filling Form", userAddress);
}
}
private static void downloadToFile(String url, File file) throws Exception {
if (url == null || url.isEmpty()) throw new Exception("argument url");
if (file == null) throw new Exception("argument path");
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
InputStream stream = connection.getInputStream();
if (stream == null)
{
throw new Exception("Stream is null");
}
try (FileOutputStream out = new FileOutputStream(file))
{
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
}
connection.disconnect();
}
public void commandRequest(String method, String key) throws Exception {
String DocumentCommandUrl = ConfigManager.GetProperty("files.docservice.url.site") + ConfigManager.GetProperty("files.docservice.url.command");
URL url = new URL(DocumentCommandUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("c", method);
params.put("key", key);
String headerToken = "";
if (DocumentManager.TokenEnabled())
{
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("payload", params);
headerToken = jwtComp.createJWT(payloadMap);
connection.setRequestProperty(DocumentJwtHeader.equals("") ? "Authorization" : DocumentJwtHeader, "Bearer " + headerToken);
String token = jwtComp.createJWT(params);
params.put("token", token);
}
Gson gson = new Gson();
String bodyString = gson.toJson(params);
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setDoOutput(true);
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte);
}
InputStream stream = connection.getInputStream();;
if (stream == null)
throw new Exception("Could not get an answer");
String jsonString = officeConverterService.ConvertStreamToString(stream);
connection.disconnect();
JSONObject response = officeConverterService.ConvertStringToJSON(jsonString);
if (!response.get("error").toString().equals("0")){
throw new Exception(response.toJSONString());
}
}
}

View File

@ -0,0 +1,191 @@
package com.qiwenshare.file.office.controllers;///**
// *
// * (c) Copyright Ascensio System SIA 2021
// *
// * Licensed 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 com.qiwenshare.file.office.controllers;
//
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.onlyoffice.integration.documentserver.managers.history.HistoryManager;
//import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
//import com.onlyoffice.integration.documentserver.models.enums.Action;
//import com.onlyoffice.integration.documentserver.models.enums.Type;
//import com.onlyoffice.integration.documentserver.models.filemodel.FileModel;
//import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
//import com.onlyoffice.integration.dto.Mentions;
//import com.onlyoffice.integration.entities.User;
//import com.onlyoffice.integration.services.UserServices;
//import com.onlyoffice.integration.services.configurers.FileConfigurer;
//import com.onlyoffice.integration.services.configurers.wrappers.DefaultFileWrapper;
//import lombok.SneakyThrows;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Controller;
//import org.springframework.ui.Model;
//import org.springframework.web.bind.annotation.CookieValue;
//import org.springframework.web.bind.annotation.CrossOrigin;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RequestParam;
//
//import java.util.*;
//
//@CrossOrigin("*")
//@Controller
//public class EditorController {
//
// @Value("${files.docservice.url.site}")
// private String docserviceSite;
//
// @Value("${files.docservice.url.api}")
// private String docserviceApiUrl;
//
// @Value("${files.docservice.languages}")
// private String langs;
//
// @Autowired
// private FileStoragePathBuilder storagePathBuilder;
//
// @Autowired
// private JwtManager jwtManager;
//
// @Autowired
// private UserServices userService;
//
// @Autowired
// private HistoryManager historyManager;
//
// @Autowired
// private ObjectMapper objectMapper;
//
// @Autowired
// private FileConfigurer<DefaultFileWrapper> fileConfigurer;
//
// @GetMapping(path = "${url.editor}")
// // process request to open the editor page
// public String index(@RequestParam("fileName") String fileName,
// @RequestParam(value = "action", required = false) String actionParam,
// @RequestParam(value = "type", required = false) String typeParam,
// @RequestParam(value = "actionLink", required = false) String actionLink,
// @CookieValue(value = "uid") String uid,
// @CookieValue(value = "ulang") String lang,
// Model model) throws JsonProcessingException {
// Action action = Action.edit;
// Type type = Type.desktop;
// Locale locale = new Locale("en");
//
// if(actionParam != null) action = Action.valueOf(actionParam);
// if(typeParam != null) type = Type.valueOf(typeParam);
//
// List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
// for (String langAndKey : langsAndKeys) {
// String[] couple = langAndKey.split(":");
// if (couple[0].equals(lang)) {
// String[] langAndCountry = couple[0].split("-");
// locale = new Locale(langAndCountry[0], langAndCountry.length > 1 ? langAndCountry[1] : "");
// }
// }
//
// Optional<User> optionalUser = userService.findUserById(Integer.parseInt(uid));
//
// // if the user is not present, return the ONLYOFFICE start page
// if(!optionalUser.isPresent()) return "index.html";
//
// User user = optionalUser.get();
//
// // get file model with the default file parameters
// FileModel fileModel = fileConfigurer.getFileModel(
// DefaultFileWrapper
// .builder()
// .fileName(fileName)
// .type(type)
// .lang(locale.toLanguageTag())
// .action(action)
// .user(user)
// .actionData(actionLink)
// .build()
// );
//
// // add attributes to the specified model
// model.addAttribute("model", fileModel); // add file model with the default parameters to the original model
// model.addAttribute("fileHistory", historyManager.getHistory(fileModel.getDocument())); // get file history and add it to the model
// model.addAttribute("docserviceApiUrl",docserviceSite + docserviceApiUrl); // create the document service api URL and add it to the model
// model.addAttribute("dataInsertImage", getInsertImage()); // get an image and add it to the model
// model.addAttribute("dataCompareFile", getCompareFile()); // get a document for comparison and add it to the model
// model.addAttribute("dataMailMergeRecipients", getMailMerge()); // get recipients data for mail merging and add it to the model
// model.addAttribute("usersForMentions", getUserMentions(uid)); // get user data for mentions and add it to the model
// return "editor.html";
// }
//
// private List<Mentions> getUserMentions(String uid){ // get user data for mentions
// List<Mentions> usersForMentions=new ArrayList<>();
// if(uid!=null && !uid.equals("4")) {
// List<User> list = userService.findAll();
// for (User u : list) {
// if (u.getId()!=Integer.parseInt(uid) && u.getId()!=4) {
// usersForMentions.add(new Mentions(u.getName(),u.getEmail())); // user data includes user names and emails
// }
// }
// }
//
// return usersForMentions;
// }
//
// @SneakyThrows
// private String getInsertImage() { // get an image that will be inserted into the document
// Map<String, Object> dataInsertImage = new HashMap<>();
// dataInsertImage.put("fileType", "png");
// dataInsertImage.put("url", storagePathBuilder.getServerUrl(true) + "/css/img/logo.png");
// dataInsertImage.put("directUrl", storagePathBuilder.getServerUrl(false) + "/css/img/logo.png");
//
// // check if the document token is enabled
// if(jwtManager.tokenEnabled()){
// dataInsertImage.put("token", jwtManager.createToken(dataInsertImage)); // create token from the dataInsertImage object
// }
//
// return objectMapper.writeValueAsString(dataInsertImage).substring(1, objectMapper.writeValueAsString(dataInsertImage).length()-1);
// }
//
// @SneakyThrows
// private String getCompareFile(){ // get a document that will be compared with the current document
// Map<String, Object> dataCompareFile = new HashMap<>();
// dataCompareFile.put("fileType", "docx");
// dataCompareFile.put("url", storagePathBuilder.getServerUrl(true) + "/assets?name=sample.docx");
// dataCompareFile.put("directUrl", storagePathBuilder.getServerUrl(false) + "/assets?name=sample.docx");
//
// // check if the document token is enabled
// if(jwtManager.tokenEnabled()){
// dataCompareFile.put("token", jwtManager.createToken(dataCompareFile)); // create token from the dataCompareFile object
// }
//
// return objectMapper.writeValueAsString(dataCompareFile);
// }
//
// @SneakyThrows
// private String getMailMerge(){
// Map<String, Object> dataMailMergeRecipients = new HashMap<>(); // get recipients data for mail merging
// dataMailMergeRecipients.put("fileType", "csv");
// dataMailMergeRecipients.put("url", storagePathBuilder.getServerUrl(true) + "/csv");
// dataMailMergeRecipients.put("directUrl", storagePathBuilder.getServerUrl(false) + "/csv");
//
// // check if the document token is enabled
// if(jwtManager.tokenEnabled()){
// dataMailMergeRecipients.put("token", jwtManager.createToken(dataMailMergeRecipients)); // create token from the dataMailMergeRecipients object
// }
//
// return objectMapper.writeValueAsString(dataMailMergeRecipients);
// }
//}

View File

@ -0,0 +1,400 @@
package com.qiwenshare.file.office.controllers;///**
// *
// * (c) Copyright Ascensio System SIA 2021
// *
// * Licensed 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 com.qiwenshare.file.office.controllers;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.onlyoffice.integration.documentserver.callbacks.CallbackHandler;
//import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
//import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
//import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
//import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
//import com.onlyoffice.integration.documentserver.storage.FileStorageMutator;
//import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
//import com.onlyoffice.integration.documentserver.util.file.FileUtility;
//import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
//import com.onlyoffice.integration.dto.Converter;
//import com.onlyoffice.integration.dto.Track;
//import com.onlyoffice.integration.entities.User;
//import com.onlyoffice.integration.services.UserServices;
//import org.json.simple.JSONObject;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.core.io.Resource;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.MediaType;
//import org.springframework.http.ResponseEntity;
//import org.springframework.stereotype.Controller;
//import org.springframework.ui.Model;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.web.multipart.MultipartFile;
//
//import javax.servlet.http.HttpServletRequest;
//import java.io.IOException;
//import java.io.InputStream;
//import java.net.URL;
//import java.net.URLEncoder;
//import java.nio.charset.StandardCharsets;
//import java.nio.file.Path;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.Map;
//import java.util.Optional;
//
//@CrossOrigin("*")
//@Controller
//public class FileController {
//
// @Value("${files.docservice.header}")
// private String documentJwtHeader;
//
// @Value("${filesize-max}")
// private String filesizeMax;
//
// @Value("${files.docservice.url.site}")
// private String docserviceUrlSite;
//
// @Value("${files.docservice.url.command}")
// private String docserviceUrlCommand;
//
// @Autowired
// private FileUtility fileUtility;
// @Autowired
// private DocumentManager documentManager;
// @Autowired
// private JwtManager jwtManager;
// @Autowired
// private FileStorageMutator storageMutator;
// @Autowired
// private FileStoragePathBuilder storagePathBuilder;
// @Autowired
// private UserServices userService;
// @Autowired
// private CallbackHandler callbackHandler;
// @Autowired
// private ObjectMapper objectMapper;
// @Autowired
// private ServiceConverter serviceConverter;
// @Autowired
// private CallbackManager callbackManager;
//
// // create user metadata
// private String createUserMetadata(String uid, String fullFileName) {
// Optional<User> optionalUser = userService.findUserById(Integer.parseInt(uid)); // find a user by their ID
// String documentType = fileUtility.getDocumentType(fullFileName).toString().toLowerCase(); // get document type
// if(optionalUser.isPresent()){
// User user = optionalUser.get();
// storageMutator.createMeta(fullFileName, // create meta information with the user ID and name specified
// String.valueOf(user.getId()), user.getName());
// }
// return "{ \"filename\": \"" + fullFileName + "\", \"documentType\": \"" + documentType + "\" }";
// }
//
// // download data from the specified file
// private ResponseEntity<Resource> downloadFile(String fileName){
// Resource resource = storageMutator.loadFileAsResource(fileName); // load the specified file as a resource
// String contentType = "application/octet-stream";
//
// // create a response with the content type, header and body with the file data
// return ResponseEntity.ok()
// .contentType(MediaType.parseMediaType(contentType))
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
// .body(resource);
// }
//
// // download data from the specified history file
// private ResponseEntity<Resource> downloadFileHistory(String fileName, String version, String file){
// Resource resource = storageMutator.loadFileAsResourceHistory(fileName,version,file); // load the specified file as a resource
// String contentType = "application/octet-stream";
//
// // create a response with the content type, header and body with the file data
// return ResponseEntity.ok()
// .contentType(MediaType.parseMediaType(contentType))
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
// .body(resource);
// }
//
// @PostMapping("/upload")
// @ResponseBody
// public String upload(@RequestParam("file") MultipartFile file, // upload a file
// @CookieValue("uid") String uid){
// try {
// String fullFileName = file.getOriginalFilename(); // get file name
// String fileExtension = fileUtility.getFileExtension(fullFileName); // get file extension
// long fileSize = file.getSize(); // get file size
// byte[] bytes = file.getBytes(); // get file in bytes
//
// // check if the file size exceeds the maximum file size or is less than 0
// if(fileUtility.getMaxFileSize() < fileSize || fileSize <= 0){
// return "{ \"error\": \"File size is incorrect\"}"; // if so, write an error message to the response
// }
//
// // check if file extension is supported by the editor
// if(!fileUtility.getFileExts().contains(fileExtension)){
// return "{ \"error\": \"File type is not supported\"}"; // if not, write an error message to the response
// }
//
// String fileNamePath = storageMutator.updateFile(fullFileName, bytes); // update a file
// if (fileNamePath.isBlank()){
// throw new IOException("Could not update a file"); // if the file cannot be updated, an error occurs
// }
//
// fullFileName = fileUtility.getFileNameWithoutExtension(fileNamePath) + fileExtension; // get full file name
//
// return createUserMetadata(uid, fullFileName); // create user metadata and return it
// } catch (Exception e) {
// e.printStackTrace();
// }
// return "{ \"error\": \"Something went wrong when uploading the file.\"}"; // if the operation of file uploading is unsuccessful, an error occurs
// }
//
// @PostMapping(path = "${url.converter}")
// @ResponseBody
// public String convert(@RequestBody Converter body, // convert a file
// @CookieValue("uid") String uid, @CookieValue("ulang") String lang){
// String fileName = body.getFileName(); // get file name
// String fileUri = documentManager.getDownloadUrl(fileName, true); // get URL for downloading a file with the specified name
// String filePass = body.getFilePass() != null ? body.getFilePass() : null; // get file password if it exists
// String fileExt = fileUtility.getFileExtension(fileName); // get file extension
// DocumentType type = fileUtility.getDocumentType(fileName); // get document type (word, cell or slide)
// String internalFileExt = fileUtility.getInternalExtension(type); // get an editor internal extension (".docx", ".xlsx" or ".pptx")
//
// try{
// if(fileUtility.getConvertExts().contains(fileExt)){ // check if the file with such an extension can be converted
// String key = serviceConverter.generateRevisionId(fileUri); // generate document key
// String newFileUri = serviceConverter // get the URL to the converted file
// .getConvertedUri(fileUri, fileExt, internalFileExt, key, filePass, true, lang);
//
// if(newFileUri.isEmpty()){
// return "{ \"step\" : \"0\", \"filename\" : \"" + fileName + "\"}";
// }
//
// // get a file name of an internal file extension with an index if the file with such a name already exists
// String nameWithInternalExt = fileUtility.getFileNameWithoutExtension(fileName) + internalFileExt;
// String correctedName = documentManager.getCorrectName(nameWithInternalExt);
//
// URL url = new URL(newFileUri);
// java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
// InputStream stream = connection.getInputStream(); // get input stream of the converted file
//
// if (stream == null){
// connection.disconnect();
// throw new RuntimeException("Input stream is null");
// }
//
// // create the converted file with input stream
// storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(correctedName)), stream);
// fileName = correctedName;
// }
//
// // create meta information about the converted file with the user ID and name specified
// return createUserMetadata(uid, fileName);
// }catch (Exception e) {
// e.printStackTrace();
// }
// return "{ \"error\": \"" + "The file can't be converted.\"}"; // if the operation of file converting is unsuccessful, an error occurs
// }
//
// @PostMapping("/delete")
// @ResponseBody
// public String delete(@RequestBody Converter body){ // delete a file
// try
// {
// String fullFileName = fileUtility.getFileName(body.getFileName()); // get full file name
// boolean fileSuccess = storageMutator.deleteFile(fullFileName); // delete a file from the storage and return the status of this operation (true or false)
// boolean historySuccess = storageMutator.deleteFileHistory(fullFileName); // delete file history and return the status of this operation (true or false)
//
// return "{ \"success\": \""+ (fileSuccess && historySuccess) +"\"}";
// }
// catch (Exception e)
// {
// return "{ \"error\": \"" + e.getMessage() + "\"}"; // if the operation of file deleting is unsuccessful, an error occurs
// }
// }
//
// @GetMapping("/downloadhistory")
// public ResponseEntity<Resource> downloadHistory(HttpServletRequest request,// download a file
// @RequestParam("fileName") String fileName,
// @RequestParam("ver") String version,
// @RequestParam("file") String file){ // history file
// try{
// // check if a token is enabled or not
// if(jwtManager.tokenEnabled()){
// String header = request.getHeader(documentJwtHeader == null // get the document JWT header
// || documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
// if(header != null && !header.isEmpty()){
// String token = header.replace("Bearer ", ""); // token is the header without the Bearer prefix
// jwtManager.readToken(token); // read the token
// }else {
// return null;
// }
// }
// return downloadFileHistory(fileName,version,file); // download data from the specified file
// } catch(Exception e){
// return null;
// }
// }
//
// @GetMapping(path = "${url.download}")
// public ResponseEntity<Resource> download(HttpServletRequest request, // download a file
// @RequestParam("fileName") String fileName){
// try{
// // check if a token is enabled or not
// if(jwtManager.tokenEnabled()){
// String header = request.getHeader(documentJwtHeader == null // get the document JWT header
// || documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
// if(header != null && !header.isEmpty()){
// String token = header.replace("Bearer ", ""); // token is the header without the Bearer prefix
// jwtManager.readToken(token); // read the token
// }
// }
// return downloadFile(fileName); // download data from the specified file
// } catch(Exception e){
// return null;
// }
// }
//
// @GetMapping("/create")
// public String create(@RequestParam("fileExt") String fileExt, // create a sample file of the specified extension
// @RequestParam(value = "sample", required = false) Optional<Boolean> isSample,
// @CookieValue(value = "uid", required = false) String uid,
// Model model){
// Boolean sampleData = (isSample.isPresent() && !isSample.isEmpty()) && isSample.get(); // specify if the sample data exists or not
// if(fileExt != null){
// try{
// Optional<User> user = userService.findUserById(Integer.parseInt(uid)); // find a user by their ID
// if (!user.isPresent()) throw new RuntimeException("Could not fine any user with id = "+uid); // if the user with the specified ID doesn't exist, an error occurs
// String fileName = documentManager.createDemo(fileExt, sampleData, uid, user.get().getName()); // create a demo document with the sample data
// if (fileName.isBlank() || fileName == null) {
// throw new RuntimeException("You must have forgotten to add asset files");
// }
// return "redirect:editor?fileName=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8); // redirect the request
// }catch (Exception ex){
// model.addAttribute("error", ex.getMessage());
// return "error.html";
// }
// }
// return "redirect:/";
// }
//
// @GetMapping("/assets")
// public ResponseEntity<Resource> assets(@RequestParam("name") String name) // get sample files from the assests
// {
// String fileName = Path.of("assets", "sample", fileUtility.getFileName(name)).toString();
// return downloadFile(fileName);
// }
//
// @GetMapping("/csv")
// public ResponseEntity<Resource> csv() // download a csv file
// {
// String fileName = Path.of("assets", "sample", "csv.csv").toString();
// return downloadFile(fileName);
// }
//
// @GetMapping("/files")
// @ResponseBody
// public ArrayList<Map<String, Object>> files(@RequestParam(value = "fileId", required = false) String fileId){ // get files information
// return fileId == null ? documentManager.getFilesInfo() : documentManager.getFilesInfo(fileId);
// }
//
// @PostMapping(path = "${url.track}")
// @ResponseBody
// public String track(HttpServletRequest request, // track file changes
// @RequestParam("fileName") String fileName,
// @RequestParam("userAddress") String userAddress,
// @RequestBody Track body){
// try {
// String bodyString = objectMapper.writeValueAsString(body); // write the request body to the object mapper as a string
// String header = request.getHeader(documentJwtHeader == null // get the request header
// || documentJwtHeader.isEmpty() ? "Authorization" : documentJwtHeader);
//
// if (bodyString.isEmpty()) { // if the request body is empty, an error occurs
// throw new RuntimeException("{\"error\":1,\"message\":\"Request payload is empty\"}");
// }
//
// JSONObject bodyCheck = jwtManager.parseBody(bodyString, header); // parse the request body
// body = objectMapper.readValue(bodyCheck.toJSONString(), Track.class); // read the request body
// } catch (Exception e) {
// e.printStackTrace();
// return e.getMessage();
// }
//
// int error = callbackHandler.handle(body, fileName);
//
// return"{\"error\":" + error + "}";
// }
//
// @PostMapping("/saveas")
// @ResponseBody
// public String saveAs(@RequestBody JSONObject body, @CookieValue("uid") String uid) {
// String title = (String) body.get("title");
// String saveAsFileUrl = (String) body.get("url");
//
// try {
// String fileName = documentManager.getCorrectName(title);
// String curExt = fileUtility.getFileExtension(fileName);
//
// if (!fileUtility.getFileExts().contains(curExt)) {
// return "{\"error\":\"File type is not supported\"}";
// }
//
// URL url = new URL(saveAsFileUrl);
// java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
// InputStream stream = connection.getInputStream();
//
// if (Integer.parseInt(filesizeMax) < stream.available() || stream.available() <= 0) {
// return "{\"error\":\"File size is incorrect\"}";
// }
// storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(fileName)), stream);
// createUserMetadata(uid, fileName);
//
// return "{\"file\": \"" + fileName + "\"}";
// } catch (IOException e) {
// e.printStackTrace();
// return "{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}";
// }
// }
//
// @PostMapping("/rename")
// @ResponseBody
// public String rename(@RequestBody JSONObject body) {
// String newfilename = (String) body.get("newfilename");
// String dockey = (String) body.get("dockey");
// String origExt = "." + (String) body.get("ext");
// String curExt = newfilename;
//
// if(newfilename.indexOf(".") != -1) {
// curExt = (String) fileUtility.getFileExtension(newfilename);
// }
//
// if(origExt.compareTo(curExt) != 0) {
// newfilename += origExt;
// }
//
// HashMap<String, String> meta = new HashMap<>();
// meta.put("title", newfilename);
//
// try {
// callbackManager.commandRequest("meta", dockey, meta);
// return "result ok";
// } catch (Exception e) {
// e.printStackTrace();
// return e.getMessage();
// }
// }
//}

View File

@ -0,0 +1,130 @@
package com.qiwenshare.file.office.controllers;///**
// *
// * (c) Copyright Ascensio System SIA 2021
// *
// * Licensed 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 com.qiwenshare.file.office.controllers;
//
//import com.onlyoffice.integration.documentserver.storage.FileStorageMutator;
//import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
//import com.onlyoffice.integration.documentserver.util.Misc;
//import com.onlyoffice.integration.documentserver.util.file.FileUtility;
//import com.onlyoffice.integration.entities.*;
//import com.onlyoffice.integration.services.UserServices;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Controller;
//import org.springframework.ui.Model;
//import org.springframework.web.bind.annotation.CrossOrigin;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.bind.annotation.ResponseBody;
//
//import java.util.*;
//import java.util.stream.Collectors;
//
//@CrossOrigin("*")
//@Controller
//public class IndexController {
//
// @Autowired
// private FileStorageMutator storageMutator;
//
// @Autowired
// private FileStoragePathBuilder storagePathBuilder;
//
// @Autowired
// private FileUtility fileUtility;
//
// @Autowired
// private Misc mistUtility;
//
// @Autowired
// private UserServices userService;
//
// @Value("${files.docservice.url.site}")
// private String docserviceSite;
//
// @Value("${files.docservice.url.preloader}")
// private String docservicePreloader;
//
// @Value("${url.converter}")
// private String urlConverter;
//
// @Value("${url.editor}")
// private String urlEditor;
//
// @Value("${files.docservice.languages}")
// private String langs;
//
// @GetMapping("${url.index}")
// public String index(Model model){
// java.io.File[] files = storageMutator.getStoredFiles(); // get all the stored files from the storage
// List<String> docTypes = new ArrayList<>();
// List<Boolean> filesEditable = new ArrayList<>();
// List<String> versions = new ArrayList<>();
// List<Boolean> isFillFormDoc = new ArrayList<>();
// List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
//
// Map<String, String> languages = new LinkedHashMap<>();
//
// langsAndKeys.forEach((str) -> {
// String[] couple = str.split(":");
// languages.put(couple[0], couple[1]);
// });
//
// List<User> users = userService.findAll(); // get a list of all the users
//
// String tooltip = users.stream() // get the tooltip with the user descriptions
// .map(user -> mistUtility.convertUserDescriptions(user.getName(), user.getDescriptions())) // convert user descriptions to the specified format
// .collect(Collectors.joining());
//
// for(java.io.File file:files){ // run through all the files
// String fileName = file.getName(); // get file name
// docTypes.add(fileUtility.getDocumentType(fileName).toString().toLowerCase()); // add a document type of each file to the list
// filesEditable.add(fileUtility.getEditedExts().contains(fileUtility.getFileExtension(fileName))); // specify if a file is editable or not
// versions.add(" ["+storagePathBuilder.getFileVersion(fileName, true)+"]"); // add a file version to the list
// isFillFormDoc.add(fileUtility.getFillExts().contains(fileUtility.getFileExtension(fileName)));
// }
//
// // add all the parameters to the model
// model.addAttribute("isFillFormDoc", isFillFormDoc);
// model.addAttribute("versions",versions);
// model.addAttribute("files", files);
// model.addAttribute("docTypes", docTypes);
// model.addAttribute("filesEditable", filesEditable);
// model.addAttribute("datadocs", docserviceSite+docservicePreloader);
// model.addAttribute("tooltip", tooltip);
// model.addAttribute("users", users);
// model.addAttribute("languages", languages);
//
// return "index.html";
// }
//
// @PostMapping("/config")
// @ResponseBody
// public HashMap<String, String> configParameters(){ // get configuration parameters
// HashMap<String, String> configuration = new HashMap<>();
//
// configuration.put("FillExtList", String.join(",", fileUtility.getFillExts())); // put a list of the extensions that can be filled to config
// configuration.put("ConverExtList", String.join(",", fileUtility.getConvertExts())); // put a list of the extensions that can be converted to config
// configuration.put("EditedExtList", String.join(",", fileUtility.getEditedExts())); // put a list of the extensions that can be edited to config
// configuration.put("UrlConverter", urlConverter);
// configuration.put("UrlEditor", urlEditor);
//
// return configuration;
// }
//}

View File

@ -0,0 +1,32 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.callbacks;
import com.qiwenshare.file.office.dto.Track;
import org.springframework.beans.factory.annotation.Autowired;
// specify the callback handler functions
public interface Callback {
int handle(Track body, String fileName); // handle the callback
int getStatus(); // get document status
@Autowired
default void selfRegistration(CallbackHandler callbackHandler){ // register a callback handler
callbackHandler.register(getStatus(), this);
}
}

View File

@ -0,0 +1,50 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.callbacks;
import com.qiwenshare.file.office.dto.Track;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class CallbackHandler {
private Logger logger = LoggerFactory.getLogger(CallbackHandler.class);
private Map<Integer, Callback> callbackHandlers = new HashMap<>();
public void register(int code, Callback callback){ // register a callback handler
callbackHandlers.put(code, callback);
}
public int handle(Track body, String fileName){ // handle a callback
Callback callback = callbackHandlers.get(body.getStatus());
if (callback == null){
logger.warn("Callback status "+body.getStatus()+" is not supported yet");
return 0;
}
int result = callback.handle(body, fileName);
return result;
}
}

View File

@ -0,0 +1,35 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.callbacks;
// document status
public enum Status {
EDITING(1), // 1 - document is being edited
SAVE(2), // 2 - document is ready for saving
CORRUPTED(3), // 3 - document saving error has occurred
MUST_FORCE_SAVE(6), // 6 - document is being edited, but the current document state is saved
CORRUPTED_FORCE_SAVE(7); // 7 - error has occurred while force saving the document
private int code;
Status(int code){
this.code = code;
}
public int getCode(){ // get document status
return this.code;
}
}

View File

@ -0,0 +1,56 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.callbacks.implementations;
import com.qiwenshare.file.office.documentserver.callbacks.Callback;
import com.qiwenshare.file.office.documentserver.callbacks.Status;
import com.qiwenshare.file.office.documentserver.managers.callback.CallbackManager;
import com.qiwenshare.file.office.dto.Action;
import com.qiwenshare.file.office.dto.Track;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class EditCallback implements Callback {
@Autowired
private CallbackManager callbackManager;
@Override
public int handle(Track body, String fileName) { // handle the callback when the document is being edited
int result = 0;
Action action = body.getActions().get(0); // get the user ID who is editing the document
if (action.getType().equals(com.qiwenshare.file.office.documentserver.models.enums.Action.edit)) { // if this value is not equal to the user ID
String user = action.getUserid(); // get user ID
if (!body.getUsers().contains(user)) { // if this user is not specified in the body
String key = body.getKey(); // get document key
try {
callbackManager.commandRequest("forcesave", key, null); // create a command request to forcibly save the document being edited without closing it
} catch (Exception e) {
e.printStackTrace();
result = 1;
}
}
}
return result;
}
@Override
public int getStatus() { // get document status
return Status.EDITING.getCode(); // return status 1 - document is being edited
}
}

View File

@ -0,0 +1,48 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.callbacks.implementations;
import com.qiwenshare.file.office.documentserver.callbacks.Callback;
import com.qiwenshare.file.office.documentserver.callbacks.Status;
import com.qiwenshare.file.office.documentserver.managers.callback.CallbackManager;
import com.qiwenshare.file.office.dto.Track;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ForcesaveCallback implements Callback {
@Autowired
private CallbackManager callbackManager;
@Override
public int handle(Track body, String fileName) { // handle the callback when the force saving request is performed
int result = 0;
try {
callbackManager.processForceSave(body, fileName); // file force saving process
} catch (Exception ex) {
ex.printStackTrace();
result = 1;
}
return result;
}
@Override
public int getStatus() { // get document status
return Status.MUST_FORCE_SAVE.getCode(); // return status 6 - document is being edited, but the current document state is saved
}
}

View File

@ -0,0 +1,49 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.callbacks.implementations;
import com.qiwenshare.file.office.documentserver.callbacks.Callback;
import com.qiwenshare.file.office.documentserver.callbacks.Status;
import com.qiwenshare.file.office.documentserver.managers.callback.CallbackManager;
import com.qiwenshare.file.office.dto.Track;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SaveCallback implements Callback {
@Autowired
private CallbackManager callbackManager;
@Override
public int handle(Track body, String fileName) { // handle the callback when the saving request is performed
int result = 0;
try {
callbackManager.processSave(body, fileName); // file saving process
} catch (Exception ex) {
ex.printStackTrace();
result = 1;
}
return result;
}
@Override
public int getStatus() { // get document status
return Status.SAVE.getCode(); // return status 2 - document is ready for saving
}
}

View File

@ -0,0 +1,29 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.callback;
import com.qiwenshare.file.office.dto.Track;
import java.util.HashMap;
public interface CallbackManager { // specify the callback manager functions
void processSave(Track body, String fileName); // file saving process
void commandRequest(String method, String key, HashMap meta); // create a command request
void processForceSave(Track body, String fileName); // file force saving process
}

View File

@ -0,0 +1,280 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.callback;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.qiwenshare.file.office.documentserver.managers.document.DocumentManager;
import com.qiwenshare.file.office.documentserver.managers.jwt.JwtManager;
import com.qiwenshare.file.office.documentserver.storage.FileStorageMutator;
import com.qiwenshare.file.office.documentserver.storage.FileStoragePathBuilder;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import com.qiwenshare.file.office.documentserver.util.service.ServiceConverter;
import com.qiwenshare.file.office.dto.Action;
import com.qiwenshare.file.office.dto.Track;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//TODO: Refactoring
@Component
@Primary
public class DefaultCallbackManager implements CallbackManager {
@Value("${files.docservice.url.site}")
private String docserviceUrlSite;
@Value("${files.docservice.url.command}")
private String docserviceUrlCommand;
@Value("${files.docservice.header}")
private String documentJwtHeader;
@Autowired
private DocumentManager documentManager;
@Autowired
private JwtManager jwtManager;
@Autowired
private FileUtility fileUtility;
@Autowired
private FileStorageMutator storageMutator;
@Autowired
private FileStoragePathBuilder storagePathBuilder;
// @Autowired
// private ObjectMapper objectMapper;
@Autowired
private ServiceConverter serviceConverter;
// save file information from the URL to the file specified
private void downloadToFile(String url, Path path) throws Exception {
if (url == null || url.isEmpty()) throw new RuntimeException("Url argument is not specified"); // URL isn't specified
if (path == null) throw new RuntimeException("Path argument is not specified"); // file isn't specified
URL uri = new URL(url);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
InputStream stream = connection.getInputStream(); // get input stream of the file information from the URL
if (stream == null) {
connection.disconnect();
throw new RuntimeException("Input stream is null");
}
storageMutator.createOrUpdateFile(path, stream); // update a file or create a new one
}
@SneakyThrows
public void processSave(Track body, String fileName) { // file saving process
String downloadUri = body.getUrl();
String changesUri = body.getChangesurl();
String key = body.getKey();
String newFileName = fileName;
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = "." + body.getFiletype(); // get an extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt != "." + null) downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
//TODO: Refactoring
if (!curExt.equals(downloadExt)) { // convert downloaded file to the file with the current extension if these extensions aren't equal
try {
String newFileUri = serviceConverter.getConvertedUri(downloadUri, downloadExt, curExt, serviceConverter.generateRevisionId(downloadUri), null, false, null); // convert a file and get URL to a new file
if (newFileUri.isEmpty()) {
newFileName = documentManager
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + downloadExt); // get the correct file name if it already exists
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = documentManager.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + downloadExt);
}
}
String storagePath = storagePathBuilder.getFileLocation(newFileName); // get the path to a new file
Path lastVersion = Paths.get(storagePathBuilder.getFileLocation(fileName)); // get the path to the last file version
if (lastVersion.toFile().exists()) { // if the last file version exists
Path histDir = Paths.get(storagePathBuilder.getHistoryDir(storagePath)); // get the history directory
storageMutator.createDirectory(histDir); // and create it
String versionDir = documentManager.versionDir(histDir.toAbsolutePath().toString(), // get the file version directory
storagePathBuilder.getFileVersion(histDir.toAbsolutePath().toString(), false), true);
Path ver = Paths.get(versionDir);
Path toSave = Paths.get(storagePath);
storageMutator.createDirectory(ver); // create the file version directory
storageMutator.moveFile(lastVersion, Paths.get(versionDir + File.separator + "prev" + curExt)); // move the last file version to the file version directory with the "prev" postfix
downloadToFile(downloadUri, toSave); // save file to the storage path
downloadToFile(changesUri, new File(versionDir + File.separator + "diff.zip").toPath()); // save file changes to the diff.zip archive
JSONObject jsonChanges = new JSONObject(); // create a json object for document changes
jsonChanges.put("changes", body.getHistory().getChanges()); // put the changes to the json object
jsonChanges.put("serverVersion", body.getHistory().getServerVersion()); // put the server version to the json object
// String history = objectMapper.writeValueAsString(jsonChanges);
String history = JSON.toJSONString(jsonChanges);
if (history == null && body.getHistory() != null) {
history = JSON.toJSONString(body.getHistory());
}
if (history != null && !history.isEmpty()) {
storageMutator.writeToFile(versionDir + File.separator + "changes.json", history); // write the history changes to the changes.json file
}
storageMutator.writeToFile(versionDir + File.separator + "key.txt", key); // write the key value to the key.txt file
storageMutator.deleteFile(storagePathBuilder.getForcesavePath(newFileName, false)); // get the path to the forcesaved file version and remove it
}
}
//TODO: Replace (String method) with (Enum method)
@SneakyThrows
public void commandRequest(String method, String key, HashMap meta) { // create a command request
String DocumentCommandUrl = docserviceUrlSite + docserviceUrlCommand;
URL url = new URL(DocumentCommandUrl);
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("c", method);
params.put("key", key);
if (meta != null) {
params.put("meta", meta);
}
String headerToken;
if (jwtManager.tokenEnabled()) // check if a secret key to generate token exists or not
{
Map<String, Object> payloadMap = new HashMap<>();
payloadMap.put("payload", params);
headerToken = jwtManager.createToken(payloadMap); // encode a payload object into a header token
connection.setRequestProperty(documentJwtHeader.equals("") ? "Authorization" : documentJwtHeader, "Bearer " + headerToken); // add a header Authorization with a header token and Authorization prefix in it
String token = jwtManager.createToken(params); // encode a payload object into a body token
params.put("token", token);
}
String bodyString = JSON.toJSONString(params);
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);
connection.setRequestMethod("POST"); // set the request method
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); // set the Content-Type header
connection.setDoOutput(true); // set the doOutput field to true
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte); // write bytes to the output stream
}
InputStream stream = connection.getInputStream(); // get input stream
if (stream == null) throw new RuntimeException("Could not get an answer");
String jsonString = serviceConverter.convertStreamToString(stream); // convert stream to json string
connection.disconnect();
JSONObject response = JSON.parseObject(jsonString); // convert json string to json object
//TODO: Add errors ENUM
String responseCode = response.get("error").toString();
switch(responseCode) {
case "0":
case "4": {
break;
}
default: {
throw new RuntimeException(response.toJSONString());
}
}
}
@SneakyThrows
public void processForceSave(Track body, String fileName) { // file force saving process
String downloadUri = body.getUrl();
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
String downloadExt = "."+body.getFiletype(); // get an extension of the downloaded file
// Todo [Delete in version 7.0 or higher]
if (downloadExt != "."+null) downloadExt = fileUtility.getFileExtension(downloadUri); // Support for versions below 7.0
Boolean newFileName = false;
// convert downloaded file to the file with the current extension if these extensions aren't equal
//TODO: Extract function
if (!curExt.equals(downloadExt)) {
try {
String newFileUri = serviceConverter.getConvertedUri(downloadUri, downloadExt,
curExt, serviceConverter.generateRevisionId(downloadUri), null, false, null); // convert file and get URL to a new file
if (newFileUri.isEmpty()) {
newFileName = true;
} else {
downloadUri = newFileUri;
}
} catch (Exception e){
newFileName = true;
}
}
String forcesavePath = "";
//TODO: Use ENUMS
//TODO: Pointless toString conversion
boolean isSubmitForm = body.getForcesavetype().toString().equals("3");
//TODO: Extract function
if (isSubmitForm) { // if the form is submitted
if (newFileName){
fileName = documentManager
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "-form" + downloadExt); // get the correct file name if it already exists
} else {
fileName = documentManager.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + "-form" + curExt);
}
forcesavePath = storagePathBuilder.getFileLocation(fileName); // create forcesave path if it doesn't exist
List<Action> actions = body.getActions();
Action action = actions.get(0);
String user = action.getUserid(); // get the user ID
storageMutator.createMeta(fileName, user, "Filling Form"); // create meta data for the forcesaved file
} else {
if (newFileName){
fileName = documentManager.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + downloadExt);
}
forcesavePath = storagePathBuilder.getForcesavePath(fileName, false);
if (forcesavePath.isEmpty()) {
forcesavePath = storagePathBuilder.getForcesavePath(fileName, true);
}
}
downloadToFile(downloadUri, new File(forcesavePath).toPath());
}
}

View File

@ -0,0 +1,234 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.document;
import com.qiwenshare.file.office.documentserver.storage.FileStorageMutator;
import com.qiwenshare.file.office.documentserver.storage.FileStoragePathBuilder;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import com.qiwenshare.file.office.documentserver.util.service.ServiceConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
@Component
@Primary
public class DefaultDocumentManager implements DocumentManager {
@Value("${files.storage.folder}")
private String storageFolder;
@Value("${files.storage}")
private String filesStorage;
@Value("${url.track}")
private String trackUrl;
@Value("${url.download}")
private String downloadUrl;
@Autowired
private FileStorageMutator storageMutator;
@Autowired
private FileStoragePathBuilder storagePathBuilder;
@Autowired
private FileUtility fileUtility;
@Autowired
private ServiceConverter serviceConverter;
@Autowired
private HttpServletRequest request;
// get URL to the created file
public String getCreateUrl(String fileName, Boolean sample){
String fileExt = fileName.substring(fileName.length() - 4);
String url = storagePathBuilder.getServerUrl(true) + "/create?fileExt=" + fileExt + "&sample=" + sample;
return url;
}
// get a file name with an index if the file with such a name already exists
public String getCorrectName(String fileName)
{
String baseName = fileUtility.getFileNameWithoutExtension(fileName); // get file name without extension
String ext = fileUtility.getFileExtension(fileName); // get file extension
String name = baseName + ext; // create a full file name
Path path = Paths.get(storagePathBuilder.getFileLocation(name));
for (int i = 1; Files.exists(path); i++) // run through all the files with such a name in the storage directory
{
name = baseName + " (" + i + ")" + ext; // and add an index to the base name
path = Paths.get(storagePathBuilder.getFileLocation(name));
}
return name;
}
// get file URL
public String getFileUri(String fileName, Boolean forDocumentServer)
{
try
{
String serverPath = storagePathBuilder.getServerUrl(forDocumentServer); // get server URL
String hostAddress = storagePathBuilder.getStorageLocation(); // get the storage directory
String filePathDownload = !fileName.contains(InetAddress.getLocalHost().getHostAddress()) ? fileName
: fileName.substring(fileName.indexOf(InetAddress.getLocalHost().getHostAddress()) + InetAddress.getLocalHost().getHostAddress().length() + 1);
if (!filesStorage.isEmpty() && filePathDownload.contains(filesStorage)) {
filePathDownload = filePathDownload.substring(filesStorage.length() + 1);
}
String filePath = serverPath + "/download?fileName=" + URLEncoder.encode(filePathDownload, java.nio.charset.StandardCharsets.UTF_8.toString())
+ "&userAddress" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
return filePath;
}
catch (UnsupportedEncodingException | UnknownHostException e)
{
return "";
}
}
// get file URL
public String getHistoryFileUrl(String fileName, Integer version, String file, Boolean forDocumentServer)
{
try
{
String serverPath = storagePathBuilder.getServerUrl(forDocumentServer); // get server URL
String hostAddress = storagePathBuilder.getStorageLocation(); // get the storage directory
String filePathDownload = !fileName.contains(InetAddress.getLocalHost().getHostAddress()) ? fileName
: fileName.substring(fileName.indexOf(InetAddress.getLocalHost().getHostAddress()) + InetAddress.getLocalHost().getHostAddress().length() + 1);
String userAddress = forDocumentServer ? "&userAddress" + URLEncoder.encode(hostAddress, java.nio.charset.StandardCharsets.UTF_8.toString()) : "";
String filePath = serverPath + "/downloadhistory?fileName=" + URLEncoder.encode(filePathDownload, java.nio.charset.StandardCharsets.UTF_8.toString())
+ "&ver=" + version + "&file="+file
+ userAddress;
return filePath;
}
catch (UnsupportedEncodingException | UnknownHostException e)
{
return "";
}
}
// get the callback URL
public String getCallback(String userFileId)
{
String serverPath = storagePathBuilder.getServerUrl(true);
String query = "?type=edit&userFileId="+userFileId+"&token="+request.getHeader("token");
return serverPath + "/office/IndexServlet" + query;
}
// get URL to download a file
public String getDownloadUrl(String fileName, Boolean isServer) {
String serverPath = storagePathBuilder.getServerUrl(isServer);
String storageAddress = storagePathBuilder.getStorageLocation();
try
{
String userAddress = isServer ? "&userAddress=" + URLEncoder.encode(storageAddress, java.nio.charset.StandardCharsets.UTF_8.toString()) : "";
String query = downloadUrl+"?fileName="
+ URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString())
+ userAddress;
return serverPath + query;
}
catch (UnsupportedEncodingException e)
{
return "";
}
}
// get file information
public ArrayList<Map<String, Object>> getFilesInfo(){
ArrayList<Map<String, Object>> files = new ArrayList<>();
// run through all the stored files
for(File file : storageMutator.getStoredFiles()){
Map<String, Object> map = new LinkedHashMap<>(); // write all the parameters to the map
map.put("version", storagePathBuilder.getFileVersion(file.getName(), false));
map.put("id", serviceConverter
.generateRevisionId(storagePathBuilder.getStorageLocation() +
"/" + file.getName() + "/"
+ Paths.get(storagePathBuilder.getFileLocation(file.getName()))
.toFile()
.lastModified()));
map.put("contentLength", new BigDecimal(String.valueOf((file.length()/1024.0)))
.setScale(2, RoundingMode.HALF_UP) + " KB");
map.put("pureContentLength", file.length());
map.put("title", file.getName());
map.put("updated", String.valueOf(new Date(file.lastModified())));
files.add(map);
}
return files;
}
// get file information by its ID
public ArrayList<Map<String, Object>> getFilesInfo(String fileId){
ArrayList<Map<String, Object>> file = new ArrayList<>();
for (Map<String, Object> map : getFilesInfo()){
if (map.get("id").equals(fileId)){
file.add(map);
break;
}
}
return file;
}
// get the path to the file version by the history path and file version
public String versionDir(String path, Integer version, boolean historyPath) {
if (!historyPath){
return storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(path)) + version;
}
return path + File.separator + version;
}
// create demo document
// public String createDemo(String fileExt,Boolean sample,String uid,String uname) {
// String demoName = (sample ? "sample." : "new.") + fileExt; // create sample or new template file with the necessary extension
// String demoPath = "assets" + File.separator + (sample ? "sample" : "new") + File.separator + demoName; // get the path to the sample document
// String fileName = getCorrectName(demoName); // get a file name with an index if the file with such a name already exists
//
// InputStream stream = Thread.currentThread()
// .getContextClassLoader()
// .getResourceAsStream(demoPath); // get the input file stream
//
// if (stream == null) return null;
//
// storageMutator.createFile(Path.of(storagePathBuilder.getFileLocation(fileName)), stream); // create a file in the specified directory
// storageMutator.createMeta(fileName, uid, uname); // create meta information of the demo file
//
// return fileName;
// }
}

View File

@ -0,0 +1,36 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.document;
import java.util.ArrayList;
import java.util.Map;
// specify the document manager functions
public interface DocumentManager {
String getCorrectName(String fileName); // get a file name with an index if the file with such a name already exists
String getFileUri(String fileName, Boolean forDocumentServer); // get file URL
String getHistoryFileUrl(String fileName, Integer version, String file, Boolean forDocumentServer); // get file URL
String getCallback(String userFileId); // get the callback URL
String getDownloadUrl(String fileName, Boolean forDocumentServer); // get URL to download a file
ArrayList<Map<String, Object>> getFilesInfo(); // get file information
ArrayList<Map<String, Object>> getFilesInfo(String fileId); // get file information by its ID
String versionDir(String path, Integer version, boolean historyPath); // get the path to the file version by the history path and file version
// String createDemo(String fileExt,Boolean sample,String uid,String uname) throws Exception; // create demo document
String getCreateUrl(String fileName, Boolean sample); // get URL to the created file
}

View File

@ -0,0 +1,157 @@
/**
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.history;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiwenshare.file.office.documentserver.managers.document.DocumentManager;
import com.qiwenshare.file.office.documentserver.managers.jwt.JwtManager;
import com.qiwenshare.file.office.documentserver.models.filemodel.Document;
import com.qiwenshare.file.office.documentserver.storage.FileStoragePathBuilder;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;
//TODO: Rebuild completely
@Component
public class DefaultHistoryManager implements HistoryManager {
@Autowired
private FileStoragePathBuilder storagePathBuilder;
@Autowired
private DocumentManager documentManager;
@Autowired
private JwtManager jwtManager;
@Autowired
private FileUtility fileUtility;
// @Autowired
// private JSONParser parser;
@Autowired
private ObjectMapper objectMapper;
//TODO: Refactoring
@SneakyThrows
public String[] getHistory(Document document) { // get document history
String histDir = storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(document.getTitle())); // get history directory
Integer curVer = storagePathBuilder.getFileVersion(histDir, false); // get current file version
if (curVer > 0) { // check if the current file version is greater than 0
List<Object> hist = new ArrayList<>();
Map<String, Object> histData = new HashMap<>();
for (Integer i = 1; i <= curVer; i++) { // run through all the file versions
Map<String, Object> obj = new HashMap<String, Object>();
Map<String, Object> dataObj = new HashMap<String, Object>();
String verDir = documentManager.versionDir(histDir, i, true); // get the path to the given file version
String key = i == curVer ? document.getKey() : readFileToEnd(new File(verDir + File.separator + "key.txt")); // get document key
obj.put("key", key);
obj.put("version", i);
if (i == 1) { // check if the version number is equal to 1
String createdInfo = readFileToEnd(new File(histDir + File.separator + "createdInfo.json")); // get file with meta data
JSONObject json = JSON.parseObject(createdInfo); // and turn it into json object
// write meta information to the object (user information and creation date)
obj.put("created", json.get("created"));
Map<String, Object> user = new HashMap<String, Object>();
user.put("id", json.get("id"));
user.put("name", json.get("name"));
obj.put("user", user);
}
dataObj.put("fileType", fileUtility.getFileExtension(document.getTitle()).replace(".", ""));
dataObj.put("key", key);
dataObj.put("url", i == curVer ? document.getUrl() :
documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), true));
// dataObj.put("directUrl", i == curVer ? document.getDirectUrl() :
// documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), false));
dataObj.put("version", i);
if (i > 1) { //check if the version number is greater than 1
// if so, get the path to the changes.json file
JSONObject changes = JSON.parseObject(readFileToEnd(new File(documentManager.versionDir(histDir, i - 1, true) + File.separator + "changes.json")));
JSONObject change = (JSONObject) ((JSONArray) changes.get("changes")).get(0);
// write information about changes to the object
obj.put("changes", changes.get("changes"));
obj.put("serverVersion", changes.get("serverVersion"));
obj.put("created", change.get("created"));
obj.put("user", change.get("user"));
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 2)); // get the history data from the previous file version
Map<String, Object> prevInfo = new HashMap<String, Object>();
prevInfo.put("fileType", prev.get("fileType"));
prevInfo.put("key", prev.get("key")); // write key and URL information about previous file version
prevInfo.put("url", prev.get("url"));
prevInfo.put("directUrl", prev.get("directUrl"));
dataObj.put("previous", prevInfo); // write information about previous file version to the data object
// write the path to the diff.zip archive with differences in this file version
Integer verdiff = i - 1;
dataObj.put("changesUrl", documentManager.getHistoryFileUrl(document.getTitle(), verdiff, "diff.zip", true));
}
if (jwtManager.tokenEnabled()) dataObj.put("token", jwtManager.createToken(dataObj));
hist.add(obj);
histData.put(Integer.toString(i - 1), dataObj);
}
// write history information about the current file version to the history object
Map<String, Object> histObj = new HashMap<String, Object>();
histObj.put("currentVersion", curVer);
histObj.put("history", hist);
try {
return new String[]{objectMapper.writeValueAsString(histObj), objectMapper.writeValueAsString(histData)};
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return new String[]{"", ""};
}
// read a file
private String readFileToEnd(File file) {
String output = "";
try {
try (FileInputStream is = new FileInputStream(file)) {
Scanner scanner = new Scanner(is); // read data from the source
scanner.useDelimiter("\\A");
while (scanner.hasNext()) {
output += scanner.next();
}
scanner.close();
}
} catch (Exception e) {
}
return output;
}
}

View File

@ -0,0 +1,26 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.history;
import com.qiwenshare.file.office.documentserver.models.filemodel.Document;
// specify the history manager functions
public interface HistoryManager {
String[] getHistory(Document document); // get document history
}

View File

@ -0,0 +1,120 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.jwt;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.primeframework.jwt.Signer;
import org.primeframework.jwt.Verifier;
import org.primeframework.jwt.domain.JWT;
import org.primeframework.jwt.hmac.HMACSigner;
import org.primeframework.jwt.hmac.HMACVerifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;
@Component
public class DefaultJwtManager implements JwtManager {
@Value("${files.docservice.secret}")
private String tokenSecret;
@Autowired
private ObjectMapper objectMapper;
// @Autowired
// private JSONParser parser;
// create document token
public String createToken(Map<String, Object> payloadClaims) {
try {
// build a HMAC signer using a SHA-256 hash
Signer signer = HMACSigner.newSHA256Signer(tokenSecret);
JWT jwt = new JWT();
for (String key : payloadClaims.keySet()) { // run through all the keys from the payload
jwt.addClaim(key, payloadClaims.get(key)); // and write each claim to the jwt
}
return JWT.getEncoder().encode(jwt, signer); // sign and encode the JWT to a JSON string representation
} catch (Exception e) {
return "";
}
}
// check if the token is enabled
public boolean tokenEnabled() {
return tokenSecret != null && !tokenSecret.isEmpty();
}
// read document token
public JWT readToken(String token) {
try {
// build a HMAC verifier using the token secret
Verifier verifier = HMACVerifier.newVerifier(tokenSecret);
return JWT.getDecoder().decode(token, verifier); // verify and decode the encoded string JWT to a rich object
} catch (Exception exception) {
return null;
}
}
// parse the body
public JSONObject parseBody(String payload, String header) {
JSONObject body;
try {
body = JSON.parseObject(payload); // get body parameters by parsing the payload
} catch (Exception ex) {
throw new RuntimeException("{\"error\":1,\"message\":\"JSON Parsing error\"}");
}
if (tokenEnabled()) { // check if the token is enabled
String token = (String) body.get("token"); // get token from the body
if (token == null) { // if token is empty
if (header != null && !StringUtils.isBlank(header)) { // and the header is defined
token = header.startsWith("Bearer ") ? header.substring(7) : header; // get token from the header (it is placed after the Bearer prefix if it exists)
}
}
if (token == null || StringUtils.isBlank(token)) {
throw new RuntimeException("{\"error\":1,\"message\":\"JWT expected\"}");
}
JWT jwt = readToken(token); // read token
if (jwt == null) {
throw new RuntimeException("{\"error\":1,\"message\":\"JWT validation failed\"}");
}
LinkedHashMap<String, Object> claims = null;
if (jwt.getObject("payload") != null) { // get payload from the token and check if it is not empty
try {
@SuppressWarnings("unchecked") LinkedHashMap<String, Object> jwtPayload =
(LinkedHashMap<String, Object>)jwt.getObject("payload");
claims = jwtPayload;
} catch (Exception ex) {
throw new RuntimeException("{\"error\":1,\"message\":\"Wrong payload\"}");
}
}
try {
body =JSON.parseObject(JSON.toJSONString(claims));
} catch (Exception ex) {
throw new RuntimeException("{\"error\":1,\"message\":\"Parsing error\"}");
}
}
return body;
}
}

View File

@ -0,0 +1,32 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.jwt;
import com.alibaba.fastjson2.JSONObject;
import org.primeframework.jwt.domain.JWT;
import java.util.Map;
// specify the jwt manager functions
public interface JwtManager {
boolean tokenEnabled(); // check if the token is enabled
String createToken(Map<String, Object> payloadClaims); // create document token
JWT readToken(String token); // read document token
JSONObject parseBody(String payload, String header); // parse the body
}

View File

@ -0,0 +1,67 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.template;
import com.qiwenshare.file.office.documentserver.managers.document.DocumentManager;
import com.qiwenshare.file.office.documentserver.models.enums.DocumentType;
import com.qiwenshare.file.office.documentserver.models.filemodel.Template;
import com.qiwenshare.file.office.documentserver.storage.FileStoragePathBuilder;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@Qualifier("sample")
public class SampleTemplateManager implements TemplateManager {
@Autowired
private DocumentManager documentManager;
@Autowired
private FileStoragePathBuilder storagePathBuilder;
@Autowired
private FileUtility fileUtility;
// create a template document with the specified name
public List<Template> createTemplates(String fileName){
List<Template> templates = new ArrayList<>();
templates.add(new Template("", "Blank", documentManager.getCreateUrl(fileName, false)));
templates.add(new Template(getTemplateImageUrl(fileName), "With sample content", documentManager.getCreateUrl(fileName, true)));
return templates;
}
// get the template image URL for the specified file
public String getTemplateImageUrl(String fileName){
DocumentType fileType = fileUtility.getDocumentType(fileName); // get the file type
String path = storagePathBuilder.getServerUrl(true); // get server URL
if(fileType.equals(DocumentType.word)){ // get URL to the template image for the word document type
return path + "/css/img/file_docx.svg";
} else if(fileType.equals(DocumentType.slide)){ // get URL to the template image for the slide document type
return path + "/css/img/file_pptx.svg";
} else if(fileType.equals(DocumentType.cell)){ // get URL to the template image for the cell document type
return path + "/css/img/file_xlsx.svg";
}
return path + "/css/img/file_docx.svg"; // get URL to the template image for the default document type (word)
}
}

View File

@ -0,0 +1,29 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.managers.template;
import com.qiwenshare.file.office.documentserver.models.filemodel.Template;
import java.util.List;
// specify the template manager functions
public interface TemplateManager {
List<Template> createTemplates(String fileName); // create a template document with the specified name
String getTemplateImageUrl(String fileName); // get the template image URL for the specified file
}

View File

@ -0,0 +1,24 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models;
import java.io.Serializable;
public abstract class AbstractModel implements Serializable {
}

View File

@ -0,0 +1,48 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.configurations;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
@Getter
@Setter
public class Customization { // the parameters which allow to customize the editor interface so that it looked like your other products (if there are any) and change the presence or absence of the additional buttons, links, change logos and editor owner details
@Autowired
private Logo logo; // the image file at the top left corner of the Editor header
@Autowired
private Goback goback; // the settings for the Open file location menu button and upper right corner button
private Boolean autosave = true; // if the Autosave menu option is enabled or disabled
private Boolean comments = true; // if the Comments menu button is displayed or hidden
private Boolean compactHeader = false; // if the additional action buttons are displayed in the upper part of the editor window header next to the logo (false) or in the toolbar (true)
private Boolean compactToolbar = false; // if the top toolbar type displayed is full (false) or compact (true)
private Boolean compatibleFeatures = false; // the use of functionality only compatible with the OOXML format
private Boolean forcesave = false; // add the request for the forced file saving to the callback handler when saving the document within the document editing service
private Boolean help = true; // if the Help menu button is displayed or hidden
private Boolean hideRightMenu = false; // if the right menu is displayed or hidden on first loading
private Boolean hideRulers = false; // if the editor rulers are displayed or hidden
private Boolean submitForm = false; // if the Submit form button is displayed or hidden
private Boolean about = true;
private Boolean feedback =true;
}

View File

@ -0,0 +1,36 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.configurations;
import com.qiwenshare.file.office.documentserver.models.enums.ToolbarDocked;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
@Getter
@Setter
public class Embedded { // the parameters which allow to change the settings which define the behavior of the buttons in the embedded mode
private String embedUrl; // the absolute URL to the document serving as a source file for the document embedded into the web page
private String saveUrl; // the absolute URL that will allow the document to be saved onto the user personal computer
private String shareUrl; // the absolute URL that will allow other users to share this document
private ToolbarDocked toolbarDocked; // the place for the embedded viewer toolbar, can be either top or bottom
}

View File

@ -0,0 +1,47 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.configurations;
import com.qiwenshare.file.office.documentserver.storage.FileStoragePathBuilder;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Scope("prototype")
public class Goback { // the settings for the Open file location menu button and upper right corner button
@Autowired
private FileStoragePathBuilder storagePathBuilder;
@Value("${url.index}")
private String indexMapping;
@Getter
private String url; // the absolute URL to the website address which will be opened when clicking the Open file location menu button
@PostConstruct
private void init() {
this.url = storagePathBuilder.getServerUrl(false) + indexMapping;
}
}

View File

@ -0,0 +1,43 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.configurations;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@Component
@Scope("prototype")
@Getter
@Setter
public class Info { // the additional parameters for the document (document owner, folder where the document is stored, uploading date, sharing settings)
private String owner = "Me"; // the name of the document owner/creator
private Boolean favorite = null; // the highlighting state of the Favorite icon
private String uploaded = getDate(); // the document uploading date
private String getDate() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM dd yyyy", Locale.US);
return simpleDateFormat.format(new Date());
}
}

View File

@ -0,0 +1,38 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.configurations;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
@Getter
@Setter
public class Logo { // the image file at the top left corner of the Editor header
@Value("${logo.image}")
private String image; // the path to the image file used to show in common work mode
@Value("${logo.imageEmbedded}")
private String imageEmbedded; // the path to the image file used to show in the embedded mode
@Value("${logo.url}")
private String url; // the absolute URL which will be used when someone clicks the logo image
}

View File

@ -0,0 +1,31 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.enums;
public enum Action {
edit,
review,
view,
embedded,
filter,
comment,
chat,
fillForms,
blockcontent
}

View File

@ -0,0 +1,25 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.enums;
public enum DocumentType {
word,
cell,
slide
}

View File

@ -0,0 +1,24 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.enums;
public enum Mode {
edit,
view
}

View File

@ -0,0 +1,24 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.enums;
public enum ToolbarDocked {
top,
bottom
}

View File

@ -0,0 +1,25 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.enums;
public enum Type {
desktop,
mobile,
embedded
}

View File

@ -0,0 +1,41 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.filemodel;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.qiwenshare.file.office.documentserver.serializers.SerializerFilter;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommentGroup {
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
private List<String> view; // define a list of groups whose comments the user can view
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
private List<String> edit; // define a list of groups whose comments the user can edit
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
private List<String> remove; // define a list of groups whose comments the user can remove
}

View File

@ -0,0 +1,42 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.filemodel;
import com.qiwenshare.file.office.documentserver.models.configurations.Info;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
@Getter
@Setter
public class Document { // the parameters pertaining to the document (title, url, file type, etc.)
@Autowired
private Info info; // additional parameters for the document (document owner, folder where the document is stored, uploading date, sharing settings)
@Autowired
private Permission permissions; // the permission for the document to be edited and downloaded or not
private String fileType; // the file type for the source viewed or edited document
private String key; // the unique document identifier used by the service to recognize the document
private String title; // the desired file name for the viewed or edited document which will also be used as file name when the document is downloaded
private String url; // the absolute URL where the source viewed or edited document is stored
}

View File

@ -0,0 +1,53 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.filemodel;
import com.qiwenshare.file.office.documentserver.models.configurations.Customization;
import com.qiwenshare.file.office.documentserver.models.configurations.Embedded;
import com.qiwenshare.file.office.documentserver.models.enums.Mode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
@Component
@Scope("prototype")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EditorConfig { // the parameters pertaining to the editor interface: opening mode (viewer or editor), interface language, additional buttons, etc.
private HashMap<String, Object> actionLink = null; // the data which contains the information about the action in the document that will be scrolled to
private String callbackUrl; // the absolute URL to the document storage service
private HashMap<String, Object> coEditing = null;
private String createUrl; // the absolute URL of the document where it will be created and available after creation
@Autowired
private Customization customization; // the parameters which allow to customize the editor interface so that it looked like your other products (if there are any) and change the presence or absence of the additional buttons, links, change logos and editor owner details
@Autowired
private Embedded embedded; // the parameters which allow to change the settings which define the behavior of the buttons in the embedded mode
private String lang; // the editor interface language
private Mode mode; // the editor opening mode
@Autowired
private User user; // the user currently viewing or editing the document
private List<Template> templates; // the presence or absence of the templates in the <b>Create New...</b> menu option
}

View File

@ -0,0 +1,41 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.filemodel;
import com.qiwenshare.file.office.documentserver.models.enums.DocumentType;
import com.qiwenshare.file.office.documentserver.models.enums.Type;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
@Getter
@Setter
public class FileModel { // the file base parameters which include the platform type used, document display size (width and height) and type of the document opened
@Autowired
private Document document; // the parameters pertaining to the document (title, url, file type, etc.)
private DocumentType documentType; // the document type to be opened
@Autowired
private EditorConfig editorConfig; // the parameters pertaining to the editor interface: opening mode (viewer or editor), interface language, additional buttons, etc.
private String token; // the encrypted signature added to the Document Server config
private Type type; // the platform type used to access the document
}

View File

@ -0,0 +1,53 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.filemodel;
import com.qiwenshare.file.office.documentserver.models.AbstractModel;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
@Scope("prototype")
@Getter
@Setter
public class Permission extends AbstractModel { // the permission for the document to be edited and downloaded or not
private Boolean comment = true; // if the document can be commented or not
private Boolean copy = true; // if the content can be copied to the clipboard or not
private Boolean download = true; // if the document can be downloaded or only viewed or edited online
private Boolean edit = true; // if the document can be edited or only viewed
private Boolean print = true; // if the document can be printed or not
private Boolean fillForms = true; // if the forms can be filled
private Boolean modifyFilter = true; // if the filter can applied globally (true) affecting all the other users, or locally (false)
private Boolean modifyContentControl = true; // if the content control settings can be changed
private Boolean review = true; // if the document can be reviewed or not
private Boolean chat = true; // if a chat can be used
// private List<String> reviewGroups; // the groups whose changes the user can accept/reject
// private CommentGroup commentGroups = new CommentGroup(); // the groups whose comments the user can edit, remove and/or view
private Map commentGroups = new HashMap();
public Permission(){
commentGroups.put("aaa", "bbb");
}
// private List<String> userInfoGroups;
}

View File

@ -0,0 +1,14 @@
package com.qiwenshare.file.office.documentserver.models.filemodel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
public class Template { // the document template parameters
private String image; // the absolute URL to the image for template
private String title; // the template title that will be displayed in the <b>Create New...</b> menu option
private String url; // the absolute URL to the document where it will be created and available after creation
}

View File

@ -0,0 +1,43 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.models.filemodel;
import com.qiwenshare.file.office.documentserver.models.AbstractModel;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
@Getter
@Setter
public class User extends AbstractModel {
private String id;
private String name;
private String group;
// the user configuration parameters
public void configure(int id, String name, String group){
this.id = "uid-"+id; // the user id
this.name = name; // the user name
this.group = group; // the group the user belongs to
}
}

View File

@ -0,0 +1,23 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.serializers;
public enum FilterState {
NULL
}

View File

@ -0,0 +1,34 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.serializers;
import java.util.List;
public class SerializerFilter {
@Override
public boolean equals(Object obj) {
if (obj instanceof List) {
if(((List<?>) obj).size() == 1 && ((List<?>) obj).get(0) == FilterState.NULL.toString()){
return true;
}
return false;
}
return false;
}
}

View File

@ -0,0 +1,23 @@
package com.qiwenshare.file.office.documentserver.storage;
import org.springframework.core.io.Resource;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Path;
// specify the file storage mutator functions
public interface FileStorageMutator {
void createDirectory(Path path); // create a new directory if it does not exist
boolean createFile(Path path, InputStream stream); // create a new file if it does not exist
boolean deleteFile(String fileName); // delete a file
boolean deleteFileHistory(String fileName); // delete file history
String updateFile(String fileName, byte[] bytes); // update a file
boolean writeToFile(String pathName, String payload); // write the payload to the file
boolean moveFile(Path source, Path destination); // move a file to the specified destination
Resource loadFileAsResource(String fileName); // load file as a resource
Resource loadFileAsResourceHistory(String fileName,String version,String file); // load file as a resource
File[] getStoredFiles(); // get a collection of all the stored files
void createMeta(String fileName, String uid, String uname); // create the file meta information
boolean createOrUpdateFile(Path path, InputStream stream); // create or update a file
}

View File

@ -0,0 +1,12 @@
package com.qiwenshare.file.office.documentserver.storage;
// specify the file storage path builder functions
public interface FileStoragePathBuilder {
void configure(String address); // create a new storage folder
String getStorageLocation(); // get the storage directory
String getFileLocation(String fileName); // get the directory of the specified file
String getServerUrl(Boolean forDocumentServer); // get the server URL
String getHistoryDir(String fileName); // get the history directory
int getFileVersion(String historyPath, Boolean ifIndexPage); // get the file version
String getForcesavePath(String fileName, Boolean create); // get the path where all the forcely saved file versions are saved or create it
}

View File

@ -0,0 +1,360 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.storage;
import com.alibaba.fastjson2.JSONObject;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import lombok.Getter;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Component;
import org.springframework.util.FileSystemUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.stream.Collectors;
import java.util.stream.Stream;
//TODO: Refactoring
@Component
@Primary
public class LocalFileStorage implements FileStorageMutator, FileStoragePathBuilder {
@Getter
private String storageAddress;
@Value("${files.storage.folder}")
private String storageFolder;
@Value("${files.docservice.url.example}")
private String docserviceUrlExample;
@Value("${files.docservice.history.postfix}")
private String historyPostfix;
@Autowired
private FileUtility fileUtility;
@Value("${deployment.host}")
private String deploymentHost;
@Value("${server.port}")
private String port;
@Autowired
private HttpServletRequest request;
/*
This Storage configuration method should be called whenever a new storage folder is required
*/
public void configure(String address) {
this.storageAddress = address;
if(this.storageAddress == null){
try{
this.storageAddress = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e){
this.storageAddress = "unknown_storage";
}
}
this.storageAddress.replaceAll("[^0-9a-zA-Z.=]", "_");
createDirectory(Paths.get(getStorageLocation()));
}
// get the storage directory
public String getStorageLocation(){
String serverPath = System.getProperty("user.dir"); // get the path to the server
String directory; // create the storage directory
if (Paths.get(this.storageAddress).isAbsolute()) {
directory = this.storageAddress + File.separator;
} else {
directory = serverPath
+ File.separator + storageFolder
+ File.separator + this.storageAddress
+ File.separator;
}
if (!Files.exists(Paths.get(directory))) {
createDirectory(Paths.get(directory));
}
return directory;
}
// get the directory of the specified file
public String getFileLocation(String fileName){
if (fileName.contains(File.separator)) {
return getStorageLocation() + fileName;
}
return getStorageLocation() + fileUtility.getFileName(fileName);
}
// create a new directory if it does not exist
public void createDirectory(Path path){
if (Files.exists(path)) return;
try {
Files.createDirectories(path);
} catch (IOException e) {
e.printStackTrace();
}
}
// create a new file if it does not exist
public boolean createFile(Path path, InputStream stream){
if (Files.exists(path)){
return true;
}
try {
File file = Files.createFile(path).toFile(); // create a new file in the specified path
try (FileOutputStream out = new FileOutputStream(file))
{
int read;
final byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1)
{
out.write(bytes, 0, read); // write bytes to the output stream
}
out.flush(); // force write data to the output stream that can be cached in the current thread
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// delete a file
public boolean deleteFile(String fileName){
try {
fileName = URLDecoder.decode(fileName, StandardCharsets.UTF_8.toString()); // decode a x-www-form-urlencoded string
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
if (StringUtils.isBlank(fileName)) return false;
String filenameWithoutExt = fileUtility.getFileNameWithoutExtension(fileName); // get file name without extension
Path filePath = fileName.contains(File.separator) ? Paths.get(fileName) : Paths.get(getFileLocation(fileName)); // get the path to the file
Path filePathWithoutExt = fileName.contains(File.separator) ? Paths.get(filenameWithoutExt) : Paths.get(getStorageLocation() + filenameWithoutExt); // get the path to the file without extension
boolean fileDeleted = FileSystemUtils.deleteRecursively(filePath.toFile()); // delete the specified file; for directories, recursively delete any nested directories or files as well
boolean fileWithoutExtDeleted = FileSystemUtils.deleteRecursively(filePathWithoutExt.toFile()); // delete the specified file without extension; for directories, recursively delete any nested directories or files as well
return fileDeleted && fileWithoutExtDeleted;
}
// delete file history
public boolean deleteFileHistory(String fileName) {
try {
fileName = URLDecoder.decode(fileName, StandardCharsets.UTF_8.toString()); // decode a x-www-form-urlencoded string
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
if (StringUtils.isBlank(fileName)) return false;
Path fileHistoryPath = Paths.get(getStorageLocation() + getHistoryDir(fileName)); // get the path to the history file
Path fileHistoryPathWithoutExt = Paths.get(getStorageLocation() + getHistoryDir(fileUtility.getFileNameWithoutExtension(fileName))); // get the path to the history file without extension
boolean historyDeleted = FileSystemUtils.deleteRecursively(fileHistoryPath.toFile()); // delete the specified history file; for directories, recursively delete any nested directories or files as well
boolean historyWithoutExtDeleted = FileSystemUtils.deleteRecursively(fileHistoryPathWithoutExt.toFile()); // delete the specified history file without extension; for directories, recursively delete any nested directories or files as well
return historyDeleted || historyWithoutExtDeleted;
}
// update a file
public String updateFile(String fileName, byte[] bytes) {
Path path = fileUtility.generateFilepath(getStorageLocation(), fileName); // generate the path to the specified file
try {
Files.write(path, bytes); // write new information in the bytes format to the file
return path.getFileName().toString();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
// move a file to the specified destination
public boolean moveFile(Path source, Path destination){
try {
Files.move(source, destination,
new StandardCopyOption[]{StandardCopyOption.REPLACE_EXISTING});
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// write the payload to the file
public boolean writeToFile(String pathName, String payload){
try (FileWriter fw = new FileWriter(pathName)) {
fw.write(payload);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// get the path where all the forcely saved file versions are saved or create it
public String getForcesavePath(String fileName, Boolean create) {
String directory = getStorageLocation();
Path path = Paths.get(directory); // get the storage directory
if (!Files.exists(path)) return "";
directory = getFileLocation(fileName) + historyPostfix + File.separator;
path = Paths.get(directory); // get the history file directory
if (!create && !Files.exists(path)) return "";
createDirectory(path); // create a new directory where all the forcely saved file versions will be saved
directory = directory + fileName;
path = Paths.get(directory);
if (!create && !Files.exists(path)) {
return "";
}
return directory;
}
// load file as a resource
public Resource loadFileAsResource(String fileName){
String fileLocation = getForcesavePath(fileName, false); // get the path where all the forcely saved file versions are saved
if (StringUtils.isBlank(fileLocation)){ // if file location is empty
fileLocation = getFileLocation(fileName); // get it by the file name
}
try {
Path filePath = Paths.get(fileLocation); // get the path to the file location
Resource resource = new UrlResource(filePath.toUri()); // convert the file path to URL
if(resource.exists()) return resource;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public Resource loadFileAsResourceHistory(String fileName,String version,String file){
String fileLocation = getStorageLocation() + fileName + "-hist" + File.separator + version + File.separator + file; // get it by the file name
try {
Path filePath = Paths.get(fileLocation); // get the path to the file location
Resource resource = new UrlResource(filePath.toUri()); // convert the file path to URL
if(resource.exists()) return resource;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
// get a collection of all the stored files
public File[] getStoredFiles()
{
File file = new File(getStorageLocation());
return file.listFiles(pathname -> pathname.isFile());
}
@SneakyThrows
public void createMeta(String fileName, String uid, String uname) { // create the file meta information
String histDir = getHistoryDir(getFileLocation(fileName)); // get the history directory
Path path = Paths.get(histDir); // get the path to the history directory
createDirectory(path); // create the history directory
// create the json object with the file metadata
JSONObject json = new JSONObject();
json.put("created", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // put the file creation date to the json object
json.put("id", uid); // put the user ID to the json object
json.put("name", uname); // put the user name to the json object
File meta = new File(histDir + File.separator + "createdInfo.json"); // create the createdInfo.json file with the file meta information
try (FileWriter writer = new FileWriter(meta)) {
writer.append(json.toJSONString());
} catch (IOException ex){
ex.printStackTrace();
}
}
// create or update a file
public boolean createOrUpdateFile(Path path, InputStream stream) {
// if (!Files.exists(path)){ // if the specified file does not exist
// return createFile(path, stream); // create it in the specified directory
// } else {
// try {
// Files.write(path, stream.readAllBytes()); // otherwise, write new information in the bytes format to the file
// return true;
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
return false;
}
// get the server URL
public String getServerUrl(Boolean forDocumentServer) {
if (forDocumentServer && !docserviceUrlExample.equals("")) {
return docserviceUrlExample;
} else {
return request.getScheme()+"://"+ deploymentHost + ":" + port + request.getContextPath();
// return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}
}
// get the history directory
public String getHistoryDir(String path)
{
return path + historyPostfix;
}
// get the file version
public int getFileVersion(String historyPath, Boolean ifIndexPage)
{
Path path;
if (ifIndexPage) { // if the start page is opened
path = Paths.get(getStorageLocation() + getHistoryDir(historyPath)); // get the storage directory and add the history directory to it
} else {
path = Paths.get(historyPath); // otherwise, get the path to the history directory
if (!Files.exists(path)) return 1; // if the history directory does not exist, then the file version is 1
}
try (Stream<Path> stream = Files.walk(path, 1)) { // run through all the files in the history directory
return stream
.filter(file -> Files.isDirectory(file)) // take only directories from the history folder
.map(Path::getFileName) // get file names
.map(Path::toString) // and convert them into strings
.collect(Collectors.toSet()).size(); // convert stream into set and get its size which specifies the file version
} catch (IOException e) {
e.printStackTrace();
return 0;
}
}
}

View File

@ -0,0 +1,16 @@
package com.qiwenshare.file.office.documentserver.util;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class Misc {
public String convertUserDescriptions(String username, List<String> description){ // cenvert user descriptions to the specified format
String result = "<div class=\"user-descr\"><b>"+username+"</b><br/><ul>"+description.
stream().map(text -> "<li>"+text+"</li>")
.collect(Collectors.joining()) + "</ul></div>";
return result;
}
}

View File

@ -0,0 +1,53 @@
package com.qiwenshare.file.office.documentserver.util;
import org.springframework.stereotype.Component;
import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
/**
* Disables and enables certificate and host-name checking in
* HttpsURLConnection, the default JVM implementation of the HTTPS/TLS protocol.
* Has no effect on implementations such as Apache Http Client, Ok Http.
*/
@Component
public final class SSLUtils {
private final HostnameVerifier jvmHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
private final HostnameVerifier trivialHostnameVerifier = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession sslSession) {
return true;
}
};
private final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
public void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
HttpsURLConnection.setDefaultHostnameVerifier(trivialHostnameVerifier);
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, UNQUESTIONING_TRUST_MANAGER, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
public void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
HttpsURLConnection.setDefaultHostnameVerifier(jvmHostnameVerifier);
// Return it to the initial state (discovered by reflection, now hardcoded)
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
}

View File

@ -0,0 +1,195 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.util.file;
import com.qiwenshare.file.office.documentserver.models.enums.DocumentType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Component
@Qualifier("default")
public class DefaultFileUtility implements FileUtility {
@Value("${filesize-max}")
private String filesizeMax;
@Value("${files.docservice.viewed-docs}")
private String docserviceViewedDocs;
@Value("${files.docservice.edited-docs}")
private String docserviceEditedDocs;
@Value("${files.docservice.convert-docs}")
private String docserviceConvertDocs;
@Value("${files.docservice.fillforms-docs}")
private String docserviceFillDocs;
// document extensions
private List<String> ExtsDocument = Arrays.asList(
".doc", ".docx", ".docm",
".dot", ".dotx", ".dotm",
".odt", ".fodt", ".ott", ".rtf", ".txt",
".html", ".htm", ".mht", ".xml",
".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oform");
// spreadsheet extensions
private List<String> ExtsSpreadsheet = Arrays.asList(
".xls", ".xlsx", ".xlsm", ".xlsb",
".xlt", ".xltx", ".xltm",
".ods", ".fods", ".ots", ".csv");
// presentation extensions
private List<String> ExtsPresentation = Arrays.asList(
".pps", ".ppsx", ".ppsm",
".ppt", ".pptx", ".pptm",
".pot", ".potx", ".potm",
".odp", ".fodp", ".otp");
// get the document type
public DocumentType getDocumentType(String fileName)
{
String ext = getFileExtension(fileName).toLowerCase(); // get file extension from its name
// word type for document extensions
if (ExtsDocument.contains(ext))
return DocumentType.word;
// cell type for spreadsheet extensions
if (ExtsSpreadsheet.contains(ext))
return DocumentType.cell;
// slide type for presentation extensions
if (ExtsPresentation.contains(ext))
return DocumentType.slide;
// default file type is word
return DocumentType.word;
}
// get file name from its URL
public String getFileName(String url)
{
if (url == null) return "";
// get file name from the last part of URL
String fileName = url.substring(url.lastIndexOf('/') + 1);
fileName = fileName.split("\\?")[0];
return fileName;
}
// get file name without extension
public String getFileNameWithoutExtension(String url)
{
String fileName = getFileName(url);
if (fileName == null) return null;
String fileNameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));
return fileNameWithoutExt;
}
// get file extension from URL
public String getFileExtension(String url)
{
String fileName = getFileName(url);
if (fileName == null) return null;
String fileExt = fileName.substring(fileName.lastIndexOf("."));
return fileExt.toLowerCase();
}
// get an editor internal extension
public String getInternalExtension(DocumentType type)
{
// .docx for word file type
if (type.equals(DocumentType.word))
return ".docx";
// .xlsx for cell file type
if (type.equals(DocumentType.cell))
return ".xlsx";
// .pptx for slide file type
if (type.equals(DocumentType.slide))
return ".pptx";
// the default file type is .docx
return ".docx";
}
public List<String> getFillExts()
{
return Arrays.asList(docserviceFillDocs.split("\\|"));
}
// get file extensions that can be viewed
public List<String> getViewedExts()
{
return Arrays.asList(docserviceViewedDocs.split("\\|"));
}
// get file extensions that can be edited
public List<String> getEditedExts()
{
return Arrays.asList(docserviceEditedDocs.split("\\|"));
}
// get file extensions that can be converted
public List<String> getConvertExts()
{
return Arrays.asList(docserviceConvertDocs.split("\\|"));
}
// get all the supported file extensions
public List<String> getFileExts() {
List<String> res = new ArrayList<>();
res.addAll(getViewedExts());
res.addAll(getEditedExts());
res.addAll(getConvertExts());
res.addAll(getFillExts());
return res;
}
// generate the file path from file directory and name
public Path generateFilepath(String directory, String fullFileName){
String fileName = getFileNameWithoutExtension(fullFileName); // get file name without extension
String fileExtension = getFileExtension(fullFileName); // get file extension
Path path = Paths.get(directory+fullFileName); // get the path to the files with the specified name
for(int i = 1; Files.exists(path); i++){ // run through all the files with the specified name
fileName = getFileNameWithoutExtension(fullFileName) + "("+i+")"; // get a name of each file without extension and add an index to it
path = Paths.get(directory+fileName+fileExtension); // create a new path for this file with the correct name and extension
}
path = Paths.get(directory+fileName+fileExtension);
return path;
}
// get maximum file size
public long getMaxFileSize(){
long size = Long.parseLong(filesizeMax);
return size > 0 ? size : 5 * 1024 * 1024;
}
}

View File

@ -0,0 +1,40 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.util.file;
import com.qiwenshare.file.office.documentserver.models.enums.DocumentType;
import java.nio.file.Path;
import java.util.List;
// specify the file utility functions
public interface FileUtility {
DocumentType getDocumentType(String fileName); // get the document type
String getFileName(String url); // get file name from its URL
String getFileNameWithoutExtension(String url); // get file name without extension
String getFileExtension(String url); // get file extension from URL
String getInternalExtension(DocumentType type); // get an editor internal extension
List<String> getFileExts(); // get all the supported file extensions
List<String> getFillExts(); // get file extensions that can be filled
List<String> getViewedExts(); // get file extensions that can be viewed
List<String> getEditedExts(); // get file extensions that can be edited
List<String> getConvertExts(); // get file extensions that can be converted
Path generateFilepath(String directory, String fullFileName); // generate the file path from file directory and name
long getMaxFileSize(); // get maximum file size
}

View File

@ -0,0 +1,274 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.util.service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiwenshare.file.office.documentserver.managers.jwt.JwtManager;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import com.qiwenshare.file.office.dto.Convert;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
//TODO: Refactoring
@Component
public class DefaultServiceConverter implements ServiceConverter
{
@Value("${files.docservice.header}")
private String documentJwtHeader;
@Value("${files.docservice.url.site}")
private String docServiceUrl;
@Value("${files.docservice.url.converter}")
private String docServiceUrlConverter;
@Value("${files.docservice.timeout}")
private String docserviceTimeout;
private int convertTimeout = 120000;
@Autowired
private JwtManager jwtManager;
@Autowired
private FileUtility fileUtility;
// @Autowired
// private JSONParser parser;
@Autowired
private ObjectMapper objectMapper;
@PostConstruct
public void init(){
int timeout = Integer.parseInt(docserviceTimeout); // parse the dcoument service timeout value
if (timeout > 0) convertTimeout = timeout;
}
@SneakyThrows
private String postToServer(Convert body, String headerToken){ // send the POST request to the server
String bodyString = objectMapper.writeValueAsString(body); // write the body request to the object mapper in the string format
URL url = null;
java.net.HttpURLConnection connection = null;
InputStream response = null;
String jsonString = null;
byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8); // convert body string into bytes
try{
// set the request parameters
url = new URL(docServiceUrl+docServiceUrlConverter);
connection = (java.net.HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setFixedLengthStreamingMode(bodyByte.length);
connection.setRequestProperty("Accept", "application/json");
connection.setConnectTimeout(convertTimeout);
// check if the token is enabled
if (jwtManager.tokenEnabled())
{
// set the JWT header to the request
connection.setRequestProperty(StringUtils.isBlank(documentJwtHeader) ?
"Authorization" : documentJwtHeader, "Bearer " + headerToken);
}
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(bodyByte); // write bytes to the output stream
os.flush(); // force write data to the output stream that can be cached in the current thread
}
response = connection.getInputStream(); // get the input stream
jsonString = convertStreamToString(response); // convert the response stream into a string
} finally {
connection.disconnect();
return jsonString;
}
}
// get the URL to the converted file
public String getConvertedUri(String documentUri, String fromExtension,
String toExtension, String documentRevisionId,
String filePass, Boolean isAsync, String lang)
{
// check if the fromExtension parameter is defined; if not, get it from the document url
fromExtension = fromExtension == null || fromExtension.isEmpty() ?
fileUtility.getFileExtension(documentUri) : fromExtension;
// check if the file name parameter is defined; if not, get random uuid for this file
String title = fileUtility.getFileName(documentUri);
title = title == null || title.isEmpty() ? UUID.randomUUID().toString() : title;
documentRevisionId = documentRevisionId == null || documentRevisionId.isEmpty() ? documentUri : documentRevisionId;
documentRevisionId = generateRevisionId(documentRevisionId); // create document token
// write all the necessary parameters to the body object
Convert body = new Convert();
body.setLang(lang);
body.setUrl(documentUri);
body.setOutputtype(toExtension.replace(".", ""));
body.setFiletype(fromExtension.replace(".", ""));
body.setTitle(title);
body.setKey(documentRevisionId);
body.setFilePass(filePass);
if (isAsync)
body.setAsync(true);
String headerToken = "";
if (jwtManager.tokenEnabled())
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("region", lang);
map.put("url", body.getUrl());
map.put("outputtype", body.getOutputtype());
map.put("filetype", body.getFiletype());
map.put("title", body.getTitle());
map.put("key", body.getKey());
map.put("password", body.getFilePass());
if (isAsync)
map.put("async", body.getAsync());
// add token to the body if it is enabled
String token = jwtManager.createToken(map);
body.setToken(token);
Map<String, Object> payloadMap = new HashMap<String, Object>();
payloadMap.put("payload", map); // create payload object
headerToken = jwtManager.createToken(payloadMap); // create header token
}
String jsonString = postToServer(body, headerToken);
return getResponseUri(jsonString);
}
// generate document key
public String generateRevisionId(String expectedKey)
{
if (expectedKey.length() > 20) // if the expected key length is greater than 20
expectedKey = Integer.toString(expectedKey.hashCode()); // the expected key is hashed and a fixed length value is stored in the string format
String key = expectedKey.replace("[^0-9-.a-zA-Z_=]", "_");
return key.substring(0, Math.min(key.length(), 20)); // the resulting key length is 20 or less
}
//TODO: Replace with a registry (callbacks package for reference)
private void processConvertServiceResponceError(int errorCode) // create an error message for an error code
{
String errorMessage = "";
String errorMessageTemplate = "Error occurred in the ConvertService: ";
// add the error message to the error message template depending on the error code
switch (errorCode)
{
case -8:
errorMessage = errorMessageTemplate + "Error document VKey";
break;
case -7:
errorMessage = errorMessageTemplate + "Error document request";
break;
case -6:
errorMessage = errorMessageTemplate + "Error database";
break;
case -5:
errorMessage = errorMessageTemplate + "Error unexpected guid";
break;
case -4:
errorMessage = errorMessageTemplate + "Error download error";
break;
case -3:
errorMessage = errorMessageTemplate + "Error convertation error";
break;
case -2:
errorMessage = errorMessageTemplate + "Error convertation timeout";
break;
case -1:
errorMessage = errorMessageTemplate + "Error convertation unknown";
break;
case 0: // if the error code is equal to 0, the error message is empty
break;
default:
errorMessage = "ErrorCode = " + errorCode; // default value for the error message
break;
}
throw new RuntimeException(errorMessage);
}
@SneakyThrows
private String getResponseUri(String jsonString) // get the response URL
{
// JSONObject jsonObj = convertStringToJSON(jsonString);
JSONObject jsonObj = JSON.parseObject(jsonString);
Object error = jsonObj.get("error");
if (error != null) // if an error occurs
processConvertServiceResponceError(Math.toIntExact((long)error)); // then get an error message
// check if the conversion is completed and save the result to a variable
Boolean isEndConvert = (Boolean) jsonObj.get("endConvert");
Long resultPercent = 0l;
String responseUri = null;
if (isEndConvert) // if the conversion is completed
{
resultPercent = 100l;
responseUri = (String) jsonObj.get("fileUrl"); // get the file URL
}
else // if the conversion isn't completed
{
resultPercent = (Long) jsonObj.get("percent");
resultPercent = resultPercent >= 100l ? 99l : resultPercent; // get the percentage value of the conversion process
}
return resultPercent >= 100l ? responseUri : "";
}
@SneakyThrows
public String convertStreamToString(InputStream stream) // convert stream to string
{
InputStreamReader inputStreamReader = new InputStreamReader(stream); // create an object to get incoming stream
StringBuilder stringBuilder = new StringBuilder(); // create a string builder object
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // create an object to read incoming streams
String line = bufferedReader.readLine(); // get incoming streams by lines
while (line != null)
{
stringBuilder.append(line); // concatenate strings using the string builder
line = bufferedReader.readLine();
}
String result = stringBuilder.toString();
return result;
}
}

View File

@ -0,0 +1,31 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.documentserver.util.service;
import java.io.InputStream;
// specify the converter service functions
public interface ServiceConverter {
String getConvertedUri(String documentUri, String fromExtension, // get the URL to the converted file
String toExtension, String documentRevisionId,
String filePass, Boolean isAsync, String lang);
String generateRevisionId(String expectedKey); // generate document key
String convertStreamToString(InputStream stream); // convert stream to string
}

View File

@ -0,0 +1,33 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Action {
private String userid;
private com.qiwenshare.file.office.documentserver.models.enums.Action type;
}

View File

@ -0,0 +1,13 @@
package com.qiwenshare.file.office.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChangesHistory {
private String created;
private ChangesUser user;
}

View File

@ -0,0 +1,13 @@
package com.qiwenshare.file.office.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChangesUser {
private String id;
private String name;
}

View File

@ -0,0 +1,40 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Convert {
private String url;
private String outputtype;
private String filetype;
private String title;
private String key;
private String filePass;
private Boolean async;
private String token;
private String lang;
}

View File

@ -0,0 +1,36 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class Converter {
@JsonProperty("filename")
private String fileName;
@JsonProperty("filePass")
private String filePass;
@JsonProperty("lang")
private String lang;
}

View File

@ -0,0 +1,40 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.qiwenshare.file.office.documentserver.models.filemodel.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class History {
@JsonProperty("serverVersion")
private String serverVersion;
private String key;
private Integer version;
private String created;
private User user;
private List<ChangesHistory> changes;
}

View File

@ -0,0 +1,31 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
public class Mentions {
private String name;
private String email;
}

View File

@ -0,0 +1,46 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Track {
private String filetype;
private String url;
private String key;
private String changesurl;
private History history;
private String token;
private Integer forcesavetype;
private Integer status;
private List<String> users;
private List<Action> actions;
private String userdata;
private String lastsave;
private Boolean notmodified;
}

View File

@ -0,0 +1,37 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.entities;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;
@MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
public abstract class AbstractEntity implements Serializable {
String id;
}

View File

@ -0,0 +1,32 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.entities;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class Group extends AbstractEntity {
private String name;
private List<User> users;
}

View File

@ -0,0 +1,51 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.entities;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class Permission extends AbstractEntity {
private Boolean comment = true;
private Boolean copy = true;
private Boolean download = true;
private Boolean edit = true;
private Boolean print = true;
private Boolean fillForms = true;
private Boolean modifyFilter = true;
private Boolean modifyContentControl = true;
private Boolean review = true;
private Boolean chat = true;
private Boolean templates=true;
// @ManyToMany
private List<Group> reviewGroups;
// @ManyToMany
private List<Group> commentsViewGroups;
// @ManyToMany
private List<Group> commentsEditGroups;
// @ManyToMany
private List<Group> commentsRemoveGroups;
// @ManyToMany
private List<Group> userInfoGroups;
}

View File

@ -0,0 +1,50 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.entities;
import com.qiwenshare.file.domain.user.UserBean;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class User extends AbstractEntity {
private String name;
private String email;
private Boolean favorite;
// @ManyToOne
private String group;
// @OneToOne
private Permission permissions;
// @Column(columnDefinition = "CLOB")
// @ElementCollection
// @CollectionTable(name = "user_descriptions")
private List<String> descriptions;
public User(){}
public User(UserBean userBean) {
this.id = userBean.getUserId();
this.name = userBean.getUsername();
this.group = "";
}
}

View File

@ -0,0 +1,58 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.mappers;
import com.qiwenshare.file.office.documentserver.models.AbstractModel;
import com.qiwenshare.file.office.entities.AbstractEntity;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Objects;
public abstract class AbstractMapper<E extends AbstractEntity, M extends AbstractModel> implements Mapper<E, M> {
@Autowired
ModelMapper mapper;
private Class<M> modelClass;
AbstractMapper(Class<M> modelClass) {
this.modelClass = modelClass;
}
@Override
public M toModel(E entity) { // convert the entity to the model
return Objects.isNull(entity) // check if an entity is not empty
? null
: mapper.map(entity, modelClass); // and add it to the model mapper
}
Converter<E, M> modelConverter() { // specify the model converter
return context -> {
E source = context.getSource(); // get the source entity
M destination = context.getDestination(); // get the destination model
handleSpecificFields(source, destination); // map the entity to the model
return context.getDestination();
};
}
void handleSpecificFields(E source, M destination) {
}
}

View File

@ -0,0 +1,27 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.mappers;
import com.qiwenshare.file.office.documentserver.models.AbstractModel;
import com.qiwenshare.file.office.entities.AbstractEntity;
// specify the model mapper functions
public interface Mapper<E extends AbstractEntity, M extends AbstractModel> {
M toModel(E entity); // convert the entity to the model
}

View File

@ -0,0 +1,57 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.mappers;
import com.qiwenshare.file.office.entities.Permission;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Primary
public class PermissionsMapper extends AbstractMapper<Permission, com.qiwenshare.file.office.documentserver.models.filemodel.Permission> {
@Autowired
private ModelMapper mapper;
public PermissionsMapper() {
super(com.qiwenshare.file.office.documentserver.models.filemodel.Permission.class);
}
@PostConstruct
public void configure() { // configure the permission mapper
mapper.createTypeMap(Permission.class, com.qiwenshare.file.office.documentserver.models.filemodel.Permission.class) // create the type map
.setPostConverter(modelConverter()); // and apply the post converter to it
}
@Override
void handleSpecificFields(Permission source, com.qiwenshare.file.office.documentserver.models.filemodel.Permission destination) { // handle specific permission fields
// destination.setReviewGroups(source.getReviewGroups().stream().map(g -> g.getName()).collect(Collectors.toList())); // set the reviewGroups parameter
// destination.setCommentGroups( // set the commentGroups parameter
// new CommentGroup(
// source.getCommentsViewGroups().stream().map(g -> g.getName()).collect(Collectors.toList()),
// source.getCommentsEditGroups().stream().map(g -> g.getName()).collect(Collectors.toList()),
// source.getCommentsRemoveGroups().stream().map(g -> g.getName()).collect(Collectors.toList())
// )
// );
// destination.setUserInfoGroups(source.getUserInfoGroups().stream().map(g -> g.getName()).collect(Collectors.toList()));
}
}

View File

@ -0,0 +1,49 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.mappers;
import com.qiwenshare.file.office.entities.User;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
@Primary
public class UsersMapper extends AbstractMapper<User, com.qiwenshare.file.office.documentserver.models.filemodel.User> {
@Autowired
private ModelMapper mapper;
public UsersMapper(){
super(com.qiwenshare.file.office.documentserver.models.filemodel.User.class);
}
@PostConstruct
public void configure() { // configure the users mapper
mapper.createTypeMap(User.class, com.qiwenshare.file.office.documentserver.models.filemodel.User.class) // create the type map
.setPostConverter(modelConverter()); // and apply the post converter to it
}
@Override
public void handleSpecificFields(User source, com.qiwenshare.file.office.documentserver.models.filemodel.User destination) { // handle specific users fields
// destination.setGroup(source.getGroup() != null ? source.getGroup().getName() : null); // set the Group parameter
}
}

View File

@ -0,0 +1,27 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.repositories;
import com.qiwenshare.file.office.entities.Group;
import java.util.Optional;
public interface GroupRepository {
Optional<Group> findGroupByName(String name);
}

View File

@ -0,0 +1,22 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.repositories;
public interface PermissionRepository {
}

View File

@ -0,0 +1,22 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.repositories;
public interface UserRepository {
}

View File

@ -0,0 +1,54 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services;
import com.qiwenshare.file.office.entities.Group;
import com.qiwenshare.file.office.repositories.GroupRepository;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
//@Service
public class GroupServices {
// @Autowired
private GroupRepository groupRepository;
// create a new group with the specified name
public Group createGroup(String name){
if(name == null) return null; // check if a name is specified
Optional<Group> group = groupRepository.findGroupByName(name); // check if group with such a name already exists
if(group.isPresent()) return group.get(); // if it exists, return it
Group newGroup = new Group();
newGroup.setName(name); // otherwise, create a new group with the specified name
// groupRepository.save(newGroup); // save a new group
return newGroup;
}
// create a list of groups from the reviewGroups permission parameter
public List<Group> createGroups(List<String> reviewGroups){
if(reviewGroups == null) return null; // check if the reviewGroups permission exists
return reviewGroups.stream() // convert this parameter to a list of groups whose changes the user can accept/reject
.map(group -> createGroup(group))
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,60 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services;
import com.qiwenshare.file.office.entities.Group;
import com.qiwenshare.file.office.entities.Permission;
import com.qiwenshare.file.office.repositories.PermissionRepository;
import java.util.List;
//@Service
public class PermissionServices {
// @Autowired
private PermissionRepository permissionRepository;
// create permissions with the specified parameters
public Permission createPermission(List<Group> reviewGroups,
List<Group> commentViewGroups,
List<Group> commentEditGroups,
List<Group> commentRemoveGroups,
List<Group> userInfoGroups,
Boolean chat){
Permission permission = new Permission();
permission.setReviewGroups(reviewGroups); // define the groups whose changes the user can accept/reject
permission.setCommentsViewGroups(commentViewGroups); // defines the groups whose comments the user can view
permission.setCommentsEditGroups(commentEditGroups); // defines the groups whose comments the user can edit
permission.setCommentsRemoveGroups(commentRemoveGroups); // defines the groups whose comments the user can remove
permission.setUserInfoGroups(userInfoGroups);
permission.setChat(chat);
// permissionRepository.save(permission); // save new permissions
return permission;
}
// update permissions
public Permission updatePermission(Permission newPermission){
// permissionRepository.save(newPermission); // save new permissions
return newPermission;
}
}

View File

@ -0,0 +1,82 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services;
import com.qiwenshare.file.office.entities.Group;
import com.qiwenshare.file.office.entities.Permission;
import com.qiwenshare.file.office.entities.User;
import com.qiwenshare.file.office.repositories.UserRepository;
import java.util.List;
import java.util.Optional;
//@Service
public class UserServices {
// @Autowired
private UserRepository userRepository;
// @Autowired
private GroupServices groupServices;
// @Autowired
private PermissionServices permissionService;
// get a list of all users
public List<User> findAll(){
// return userRepository.findAll();
return null;
}
// get a user by their ID
public Optional<User> findUserById(Integer id){
// return userRepository.findById(id);
return null;
}
// create a user with the specified parameters
public User createUser(String name, String email,
List<String> description, String group,
List<String> reviewGroups,
List<String> viewGroups,
List<String> editGroups,
List<String> removeGroups,
List<String> userInfoGroups, Boolean favoriteDoc,
Boolean chat){
User newUser = new User();
newUser.setName(name); // set the user name
newUser.setEmail(email); // set the user email
// newUser.setGroup(groupServices.createGroup(group)); // set the user group
newUser.setDescriptions(description); // set the user description
newUser.setFavorite(favoriteDoc); // specify if the user has the favorite documents or not
List<Group> groupsReview = groupServices.createGroups(reviewGroups); // define the groups whose changes the user can accept/reject
List<Group> commentGroupsView = groupServices.createGroups(viewGroups); // defines the groups whose comments the user can view
List<Group> commentGroupsEdit = groupServices.createGroups(editGroups); // defines the groups whose comments the user can edit
List<Group> commentGroupsRemove = groupServices.createGroups(removeGroups); // defines the groups whose comments the user can remove
List<Group> usInfoGroups = groupServices.createGroups(userInfoGroups);
Permission permission = permissionService
.createPermission(groupsReview, commentGroupsView, commentGroupsEdit, commentGroupsRemove, usInfoGroups, chat); // specify permissions for the current user
newUser.setPermissions(permission);
// userRepository.save(newUser); // save a new user
return newUser;
}
}

View File

@ -0,0 +1,23 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers;
public interface Configurer<O, W> {
void configure(O instance, W wrapper);
}

View File

@ -0,0 +1,25 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers;
import com.qiwenshare.file.office.documentserver.models.configurations.Customization;
public interface CustomizationConfigurer<W> extends Configurer<Customization, W> {
void configure(Customization customization, W wrapper);
}

View File

@ -0,0 +1,25 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers;
import com.qiwenshare.file.office.documentserver.models.filemodel.Document;
public interface DocumentConfigurer<W> extends Configurer<Document, W> {
void configure(Document document, W wrapper);
}

View File

@ -0,0 +1,25 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers;
import com.qiwenshare.file.office.documentserver.models.filemodel.EditorConfig;
public interface EditorConfigConfigurer<W> extends Configurer<EditorConfig, W> {
void configure(EditorConfig editorConfig, W wrapper);
}

View File

@ -0,0 +1,25 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers;
import com.qiwenshare.file.office.documentserver.models.configurations.Embedded;
public interface EmbeddedConfigurer<W> extends Configurer<Embedded, W> {
void configure(Embedded embedded, W wrapper);
}

View File

@ -0,0 +1,26 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers;
import com.qiwenshare.file.office.documentserver.models.filemodel.FileModel;
public interface FileConfigurer<W> extends Configurer<FileModel, W> {
void configure(FileModel model, W wrapper);
FileModel getFileModel(W wrapper);
}

View File

@ -0,0 +1,38 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.implementations;
import com.qiwenshare.file.office.documentserver.models.configurations.Customization;
import com.qiwenshare.file.office.documentserver.models.enums.Action;
import com.qiwenshare.file.office.entities.User;
import com.qiwenshare.file.office.services.configurers.CustomizationConfigurer;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultCustomizationWrapper;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
@Service
@Primary
public class DefaultCustomizationConfigurer implements CustomizationConfigurer<DefaultCustomizationWrapper> {
@Override
public void configure(Customization customization, DefaultCustomizationWrapper wrapper) { // define the customization configurer
Action action = wrapper.getAction(); // get the action parameter from the customization wrapper
User user = wrapper.getUser();
customization.setSubmitForm(action.equals(Action.fillForms) && "1".equals(user.getId()) && false); // set the submitForm parameter to the customization config
}
}

View File

@ -0,0 +1,68 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.implementations;
import com.qiwenshare.file.office.documentserver.managers.document.DocumentManager;
import com.qiwenshare.file.office.documentserver.models.filemodel.Document;
import com.qiwenshare.file.office.documentserver.models.filemodel.Permission;
import com.qiwenshare.file.office.documentserver.storage.FileStoragePathBuilder;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import com.qiwenshare.file.office.documentserver.util.service.ServiceConverter;
import com.qiwenshare.file.office.services.configurers.DocumentConfigurer;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultDocumentWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import java.io.File;
@Service
@Primary
public class DefaultDocumentConfigurer implements DocumentConfigurer<DefaultDocumentWrapper> {
@Autowired
private DocumentManager documentManager;
@Autowired
private FileStoragePathBuilder storagePathBuilder;
@Autowired
private FileUtility fileUtility;
@Autowired
private ServiceConverter serviceConverter;
public void configure(Document document, DefaultDocumentWrapper wrapper){ // define the document configurer
String fileName = wrapper.getFileName(); // get the fileName parameter from the document wrapper
Permission permission = wrapper.getPermission(); // get the permission parameter from the document wrapper
document.setTitle(fileName); // set the title to the document config
document.setUrl(wrapper.getPreviewUrl()); // set the URL to download a file to the document config
document.setFileType(fileUtility.getFileExtension(fileName).replace(".","")); // set the file type to the document config
document.getInfo().setFavorite(wrapper.getFavorite()); // set the favorite parameter to the document config
String key = serviceConverter. // get the document key
generateRevisionId(storagePathBuilder.getStorageLocation()
+ "/" + fileName + "/"
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified());
document.setKey(key); // set the key to the document config
document.setPermissions(permission); // set the permission parameters to the document config
}
}

View File

@ -0,0 +1,99 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.implementations;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiwenshare.file.office.documentserver.managers.document.DocumentManager;
import com.qiwenshare.file.office.documentserver.managers.template.TemplateManager;
import com.qiwenshare.file.office.documentserver.models.enums.Action;
import com.qiwenshare.file.office.documentserver.models.enums.Mode;
import com.qiwenshare.file.office.documentserver.models.filemodel.EditorConfig;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import com.qiwenshare.file.office.entities.User;
import com.qiwenshare.file.office.mappers.Mapper;
import com.qiwenshare.file.office.services.configurers.EditorConfigConfigurer;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultCustomizationWrapper;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultEmbeddedWrapper;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultFileWrapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
@Primary
public class DefaultEditorConfigConfigurer implements EditorConfigConfigurer<DefaultFileWrapper> {
@Autowired
private Mapper<User, com.qiwenshare.file.office.documentserver.models.filemodel.User> mapper;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private DocumentManager documentManager;
@Autowired
@Qualifier("sample")
private TemplateManager templateManager;
@Autowired
private DefaultCustomizationConfigurer defaultCustomizationConfigurer;
@Autowired
private DefaultEmbeddedConfigurer defaultEmbeddedConfigurer;
@Autowired
private FileUtility fileUtility;
@SneakyThrows
public void configure(EditorConfig config, DefaultFileWrapper wrapper){ // define the editorConfig configurer
// if (wrapper.getActionData() != null) { // check if the actionData is not empty in the editorConfig wrapper
// config.setActionLink(objectMapper.readValue(wrapper.getActionData(), (JavaType) new TypeToken<HashMap<String, Object>>() { }.getType())); // set actionLink to the editorConfig
// }
String fileName = wrapper.getFileName(); // set the fileName parameter from the editorConfig wrapper
String fileExt = fileUtility.getFileExtension(fileName);
boolean userIsAnon = wrapper.getUser().getName().equals("Anonymous"); // check if the user from the editorConfig wrapper is anonymous or not
config.setTemplates(userIsAnon ? null : templateManager.createTemplates(fileName)); // set a template to the editorConfig if the user is not anonymous
config.setCallbackUrl(documentManager.getCallback(wrapper.getUserFileId())); // set the callback URL to the editorConfig
config.setCreateUrl(userIsAnon ? null : documentManager.getCreateUrl(fileName, false)); // set the document URL where it will be created to the editorConfig if the user is not anonymous
config.setLang(wrapper.getLang()); // set the language to the editorConfig
Boolean canEdit = wrapper.getCanEdit(); // check if the file of the specified type can be edited or not
Action action = wrapper.getAction(); // get the action parameter from the editorConfig wrapper
config.setCoEditing(action.equals(Action.view) && userIsAnon ? new HashMap<String, Object>() {{
put("mode", "strict");
put("change", false);
}} : null);
defaultCustomizationConfigurer.configure(config.getCustomization(), DefaultCustomizationWrapper.builder() // define the customization configurer
.action(action)
.user(userIsAnon ? null : wrapper.getUser())
.build());
config.setMode(canEdit && !action.equals(Action.view) ? Mode.edit : Mode.view);
config.setUser(mapper.toModel(wrapper.getUser()));
defaultEmbeddedConfigurer.configure(config.getEmbedded(), DefaultEmbeddedWrapper.builder()
.type(wrapper.getType())
.fileName(fileName)
.build());
}
}

View File

@ -0,0 +1,47 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.implementations;
import com.qiwenshare.file.office.documentserver.managers.document.DocumentManager;
import com.qiwenshare.file.office.documentserver.models.configurations.Embedded;
import com.qiwenshare.file.office.documentserver.models.enums.ToolbarDocked;
import com.qiwenshare.file.office.documentserver.models.enums.Type;
import com.qiwenshare.file.office.services.configurers.EmbeddedConfigurer;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultEmbeddedWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
@Service
@Primary
public class DefaultEmbeddedConfigurer implements EmbeddedConfigurer<DefaultEmbeddedWrapper> {
@Autowired
private DocumentManager documentManager;
public void configure(Embedded embedded, DefaultEmbeddedWrapper wrapper){ // define the embedded configurer
if(wrapper.getType().equals(Type.embedded)) { // check if the type from the embedded wrapper is embedded
String url = documentManager.getDownloadUrl(wrapper.getFileName(), false); // get file URL of the specified file
embedded.setEmbedUrl(url); // set the embedURL parameter to the embedded config (the absolute URL to the document serving as a source file for the document embedded into the web page)
embedded.setSaveUrl(url); // set the saveURL parameter to the embedded config (the absolute URL that will allow the document to be saved onto the user personal computer)
embedded.setShareUrl(url); // set the shareURL parameter to the embedded config (the absolute URL that will allow other users to share this document)
embedded.setToolbarDocked(ToolbarDocked.top); // set the top toolbarDocked parameter to the embedded config (the place for the embedded viewer toolbar, can be either top or bottom)
};
}
}

View File

@ -0,0 +1,142 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.implementations;
import com.alibaba.fastjson2.JSON;
import com.qiwenshare.file.office.documentserver.managers.jwt.JwtManager;
import com.qiwenshare.file.office.documentserver.models.enums.Action;
import com.qiwenshare.file.office.documentserver.models.enums.DocumentType;
import com.qiwenshare.file.office.documentserver.models.filemodel.FileModel;
import com.qiwenshare.file.office.documentserver.models.filemodel.Permission;
import com.qiwenshare.file.office.documentserver.util.file.FileUtility;
import com.qiwenshare.file.office.mappers.Mapper;
import com.qiwenshare.file.office.services.configurers.FileConfigurer;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultDocumentWrapper;
import com.qiwenshare.file.office.services.configurers.wrappers.DefaultFileWrapper;
import org.primeframework.jwt.domain.JWT;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
@Primary
public class DefaultFileConfigurer implements FileConfigurer<DefaultFileWrapper> {
@Autowired
private ObjectFactory<FileModel> fileModelObjectFactory;
@Autowired
private FileUtility fileUtility;
@Autowired
private JwtManager jwtManager;
@Autowired
private Mapper<com.qiwenshare.file.office.entities.Permission, Permission> mapper;
@Autowired
private DefaultDocumentConfigurer defaultDocumentConfigurer;
@Autowired
private DefaultEditorConfigConfigurer defaultEditorConfigConfigurer;
public void configure(FileModel fileModel, DefaultFileWrapper wrapper){ // define the file configurer
if (fileModel != null){ // check if the file model is specified
String fileName = wrapper.getFileName(); // get the fileName parameter from the file wrapper
Action action = wrapper.getAction(); // get the action parameter from the file wrapper
DocumentType documentType = fileUtility.getDocumentType(fileName); // get the document type of the specified file
fileModel.setDocumentType(documentType); // set the document type to the file model
fileModel.setType(wrapper.getType()); // set the platform type to the file model
// Permission userPermissions = mapper.toModel(wrapper.getUser().getPermissions()); // convert the permission entity to the model
Permission userPermissions = new Permission(); // TODO
String fileExt = fileUtility.getFileExtension(wrapper.getFileName());
Boolean canEdit = fileUtility.getEditedExts().contains(fileExt);
if ((!canEdit && action.equals(Action.edit) || action.equals(Action.fillForms)) && fileUtility.getFillExts().contains(fileExt)) {
canEdit = true;
wrapper.setAction(Action.fillForms);
}
wrapper.setCanEdit(canEdit);
DefaultDocumentWrapper documentWrapper = DefaultDocumentWrapper // define the document wrapper
.builder()
.fileName(fileName)
.permission(updatePermissions(userPermissions, action, canEdit))
.favorite(wrapper.getUser().getFavorite())
.previewUrl(wrapper.getActionData())
.build();
defaultDocumentConfigurer.configure(fileModel.getDocument(), documentWrapper); // define the document configurer
defaultEditorConfigConfigurer.configure(fileModel.getEditorConfig(), wrapper); // define the editorConfig configurer
Map<String, Object> map = new HashMap<>();
map.put("type", fileModel.getType());
map.put("documentType", documentType);
map.put("document", fileModel.getDocument());
map.put("editorConfig", fileModel.getEditorConfig());
fileModel.setToken(jwtManager.createToken(map)); // create a token and set it to the file model
JWT res = jwtManager.readToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlZGl0b3JDb25maWciOnsiY2FsbGJhY2tVcmwiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAvdHJhY2s_ZmlsZU5hbWU9bmV3LmRvY3gmdXNlckFkZHJlc3M9RSUzQSU1Q2NvZGUlNUMlRTYlOEYlOTIlRTQlQkIlQjYyJTVDSmF2YStTcHJpbmcrRXhhbXBsZSU1Q0phdmErU3ByaW5nK0V4YW1wbGUlNUNkb2N1bWVudHMlNUMxOTIuMTY4LjEuNiU1QyIsImNyZWF0ZVVybCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMC9jcmVhdGU_ZmlsZUV4dD1kb2N4JnNhbXBsZT1mYWxzZSIsImN1c3RvbWl6YXRpb24iOnsibG9nbyI6eyJpbWFnZSI6IiIsImltYWdlRW1iZWRkZWQiOiIiLCJ1cmwiOiJodHRwczovL3d3dy5vbmx5b2ZmaWNlLmNvbSJ9LCJnb2JhY2siOnsidXJsIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwLyJ9LCJhdXRvc2F2ZSI6dHJ1ZSwiY29tbWVudHMiOnRydWUsImNvbXBhY3RIZWFkZXIiOmZhbHNlLCJjb21wYWN0VG9vbGJhciI6ZmFsc2UsImNvbXBhdGlibGVGZWF0dXJlcyI6ZmFsc2UsImZvcmNlc2F2ZSI6ZmFsc2UsImhlbHAiOnRydWUsImhpZGVSaWdodE1lbnUiOmZhbHNlLCJoaWRlUnVsZXJzIjpmYWxzZSwic3VibWl0Rm9ybSI6ZmFsc2UsImFib3V0Ijp0cnVlLCJmZWVkYmFjayI6dHJ1ZX0sImVtYmVkZGVkIjp7fSwibGFuZyI6ImVuIiwibW9kZSI6ImVkaXQiLCJ1c2VyIjp7ImlkIjoiMSIsIm5hbWUiOiJKb2huIFNtaXRoIiwiZ3JvdXAiOiIifSwidGVtcGxhdGVzIjpbeyJpbWFnZSI6IiIsInRpdGxlIjoiQmxhbmsiLCJ1cmwiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAvY3JlYXRlP2ZpbGVFeHQ9ZG9jeCZzYW1wbGU9ZmFsc2UifSx7ImltYWdlIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwL2Nzcy9pbWcvZmlsZV9kb2N4LnN2ZyIsInRpdGxlIjoiV2l0aCBzYW1wbGUgY29udGVudCIsInVybCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMC9jcmVhdGU_ZmlsZUV4dD1kb2N4JnNhbXBsZT10cnVlIn1dfSwiZG9jdW1lbnRUeXBlIjoid29yZCIsImRvY3VtZW50Ijp7ImluZm8iOnsib3duZXIiOiJNZSIsInVwbG9hZGVkIjoiU3VuIE5vdiAyNyAyMDIyIn0sInBlcm1pc3Npb25zIjp7ImNvbW1lbnQiOnRydWUsImNvcHkiOnRydWUsImRvd25sb2FkIjp0cnVlLCJlZGl0Ijp0cnVlLCJwcmludCI6dHJ1ZSwiZmlsbEZvcm1zIjp0cnVlLCJtb2RpZnlGaWx0ZXIiOnRydWUsIm1vZGlmeUNvbnRlbnRDb250cm9sIjp0cnVlLCJyZXZpZXciOnRydWUsImNoYXQiOnRydWUsImNvbW1lbnRHcm91cHMiOnt9fSwiZmlsZVR5cGUiOiJkb2N4Iiwia2V5IjoiLTgxNjAzMzMxMiIsInVybFVzZXIiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAvZG93bmxvYWQ_ZmlsZU5hbWU9bmV3LmRvY3gmdXNlckFkZHJlc3NFJTNBJTVDY29kZSU1QyVFNiU4RiU5MiVFNCVCQiVCNjIlNUNKYXZhK1NwcmluZytFeGFtcGxlJTVDSmF2YStTcHJpbmcrRXhhbXBsZSU1Q2RvY3VtZW50cyU1QzE5Mi4xNjguMS42JTVDIiwidGl0bGUiOiJuZXcuZG9jeCIsInVybCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMC9kb3dubG9hZD9maWxlTmFtZT1uZXcuZG9jeCZ1c2VyQWRkcmVzcz1FJTNBJTVDY29kZSU1QyVFNiU4RiU5MiVFNCVCQiVCNjIlNUNKYXZhK1NwcmluZytFeGFtcGxlJTVDSmF2YStTcHJpbmcrRXhhbXBsZSU1Q2RvY3VtZW50cyU1QzE5Mi4xNjguMS42JTVDIiwiZGlyZWN0VXJsIjoiaHR0cDovL2xvY2FsaG9zdDo0MDAwL2Rvd25sb2FkP2ZpbGVOYW1lPW5ldy5kb2N4In0sInR5cGUiOiJkZXNrdG9wIn0.xZHMRgDUK76I_a_DOZSGJ1Fcxp_ghOCwR1FTqxwbnxE");
System.out.println(JSON.toJSONString(res));
JWT res2 = jwtManager.readToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlZGl0b3JDb25maWciOnsiY2FsbGJhY2tVcmwiOiJodHRwOi8vMTIxLjg5LjIyMi4xMDM6ODc2My9vZmZpY2UvSW5kZXhTZXJ2bGV0P3R5cGU9ZWRpdCZ1c2VyRmlsZUlkPTE1ODUxMzQyOTcyMjQwNDQ1NDQmdG9rZW49QmVhcmVyIGV5SmhiR2NpT2lKSVV6STFOaUo5LmV5SnBjM01pT2lKeGFYZGxiaTFqYlhNaUxDSmxlSEFpT2pFMk5qazNPVFV3T0RJc0luTjFZaUk2SW50Y0luVnpaWEpKWkZ3aU9qSjlJaXdpWVhWa0lqb2ljV2wzWlc1emFHRnlaU0lzSW1saGRDSTZNVFkyT1RFNU1ESTRNbjAuYzJwa1hwejFjMHZRcU9zX3I2V0JySnJDZ1lnbUtNMGc2Q2YxZEhVaG51cyIsImNyZWF0ZVVybCI6Imh0dHA6Ly8xMjEuODkuMjIyLjEwMzo4NzYzL2NyZWF0ZT9maWxlRXh0PXhsc3gmc2FtcGxlPWZhbHNlIiwiY3VzdG9taXphdGlvbiI6eyJsb2dvIjp7ImltYWdlIjoiIiwiaW1hZ2VFbWJlZGRlZCI6IiIsInVybCI6Imh0dHBzOi8vd3d3Lm9ubHlvZmZpY2UuY29tIn0sImdvYmFjayI6eyJ1cmwiOiJodHRwOi8vMTIxLjg5LjIyMi4xMDM6ODc2My8ifSwiYXV0b3NhdmUiOnRydWUsImNvbW1lbnRzIjp0cnVlLCJjb21wYWN0SGVhZGVyIjpmYWxzZSwiY29tcGFjdFRvb2xiYXIiOmZhbHNlLCJjb21wYXRpYmxlRmVhdHVyZXMiOmZhbHNlLCJmb3JjZXNhdmUiOmZhbHNlLCJoZWxwIjp0cnVlLCJoaWRlUmlnaHRNZW51IjpmYWxzZSwiaGlkZVJ1bGVycyI6ZmFsc2UsInN1Ym1pdEZvcm0iOmZhbHNlLCJhYm91dCI6dHJ1ZSwiZmVlZGJhY2siOnRydWV9LCJlbWJlZGRlZCI6e30sImxhbmciOiJ6aCIsIm1vZGUiOiJ2aWV3IiwidXNlciI6eyJpZCI6IjEiLCJuYW1lIjoiSm9obiBTbWl0aCIsImdyb3VwIjoiIn0sInRlbXBsYXRlcyI6W3siaW1hZ2UiOiIiLCJ0aXRsZSI6IkJsYW5rIiwidXJsIjoiaHR0cDovLzEyMS44OS4yMjIuMTAzOjg3NjMvY3JlYXRlP2ZpbGVFeHQ9eGxzeCZzYW1wbGU9ZmFsc2UifSx7ImltYWdlIjoiaHR0cDovLzEyMS44OS4yMjIuMTAzOjg3NjMvY3NzL2ltZy9maWxlX3hsc3guc3ZnIiwidGl0bGUiOiJXaXRoIHNhbXBsZSBjb250ZW50IiwidXJsIjoiaHR0cDovLzEyMS44OS4yMjIuMTAzOjg3NjMvY3JlYXRlP2ZpbGVFeHQ9eGxzeCZzYW1wbGU9dHJ1ZSJ9XX0sImRvY3VtZW50VHlwZSI6ImNlbGwiLCJkb2N1bWVudCI6eyJpbmZvIjp7Im93bmVyIjoiTWUiLCJ1cGxvYWRlZCI6Ik1vbiBOb3YgMjggMjAyMiJ9LCJwZXJtaXNzaW9ucyI6eyJjb21tZW50IjpmYWxzZSwiY29weSI6dHJ1ZSwiZG93bmxvYWQiOnRydWUsImVkaXQiOnRydWUsInByaW50Ijp0cnVlLCJmaWxsRm9ybXMiOmZhbHNlLCJtb2RpZnlGaWx0ZXIiOnRydWUsIm1vZGlmeUNvbnRlbnRDb250cm9sIjp0cnVlLCJyZXZpZXciOmZhbHNlLCJjaGF0Ijp0cnVlLCJjb21tZW50R3JvdXBzIjp7ImFhYSI6ImJiYiJ9fSwiZmlsZVR5cGUiOiJ4bHN4Iiwia2V5IjoiLTExMzc3NjkyMDciLCJ1cmxVc2VyIjoiaHR0cDovLzEyMS44OS4yMjIuMTAzOjg3NjMvZG93bmxvYWQ_ZmlsZU5hbWU9JUU5JTk3JUFFJUU5JUEyJTk4JUU4JUFFJUIwJUU1JUJEJTk1Lnhsc3gmdXNlckFkZHJlc3MlMkZyb290JTJGZ2l0ZWVfZ28lMkZkZXBsb3klMkZxaXdlbi1maWxlJTJGZG9jdW1lbnRzJTJGMTcyLjI2LjIxMS4yMDklMkYiLCJ0aXRsZSI6IumXrumimOiusOW9lS54bHN4IiwidXJsIjoiaHR0cHM6Ly90ZXN0cGFuLnFpd2Vuc2hhcmUuY29tL2FwaS9maWxldHJhbnNmZXIvcHJldmlldz91c2VyRmlsZUlkPTE1ODUxMzQyOTcyMjQwNDQ1NDQmaXNNaW49ZmFsc2Umc2hhcmVCYXRjaE51bT11bmRlZmluZWQmZXh0cmFjdGlvbkNvZGU9dW5kZWZpbmVkJnRva2VuPUJlYXJlciBleUpoYkdjaU9pSklVekkxTmlKOS5leUpwYzNNaU9pSnhhWGRsYmkxamJYTWlMQ0psZUhBaU9qRTJOamszT1RVd09ESXNJbk4xWWlJNkludGNJblZ6WlhKSlpGd2lPako5SWl3aVlYVmtJam9pY1dsM1pXNXphR0Z5WlNJc0ltbGhkQ0k2TVRZMk9URTVNREk0TW4wLmMycGtYcHoxYzB2UXFPc19yNldCckpyQ2dZZ21LTTBnNkNmMWRIVWhudXMiLCJkaXJlY3RVcmwiOiJodHRwOi8vMTIxLjg5LjIyMi4xMDM6ODc2My9kb3dubG9hZD9maWxlTmFtZT0lRTklOTclQUUlRTklQTIlOTglRTglQUUlQjAlRTUlQkQlOTUueGxzeCJ9LCJ0eXBlIjoiZGVza3RvcCJ9.O5eBtPY0eA9CCCkbglO2gt4L42CnBtJsvoOUnL3PujM");
System.out.println(JSON.toJSONString(res2));
}
}
@Override
public FileModel getFileModel(DefaultFileWrapper wrapper) { // get file model
FileModel fileModel = fileModelObjectFactory.getObject();
configure(fileModel, wrapper); // and configure it
return fileModel;
}
private Permission updatePermissions(Permission userPermissions, Action action, Boolean canEdit) {
userPermissions.setComment(
!action.equals(Action.view)
&& !action.equals(Action.fillForms)
&& !action.equals(Action.embedded)
&& !action.equals(Action.blockcontent)
);
userPermissions.setFillForms(
!action.equals(Action.view)
&& !action.equals(Action.comment)
&& !action.equals(Action.embedded)
&& !action.equals(Action.blockcontent)
);
userPermissions.setReview(canEdit &&
(action.equals(Action.review) || action.equals(Action.edit)));
userPermissions.setEdit(canEdit &&
(action.equals(Action.view)
|| action.equals(Action.edit)
|| action.equals(Action.filter)
|| action.equals(Action.blockcontent)));
return userPermissions;
}
}

View File

@ -0,0 +1,31 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.wrappers;
import com.qiwenshare.file.office.documentserver.models.enums.Action;
import com.qiwenshare.file.office.entities.User;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class DefaultCustomizationWrapper {
private Action action;
private User user;
}

View File

@ -0,0 +1,32 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.wrappers;
import com.qiwenshare.file.office.documentserver.models.filemodel.Permission;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class DefaultDocumentWrapper {
private Permission permission;
private String fileName;
private Boolean favorite;
private String previewUrl;
}

View File

@ -0,0 +1,30 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.wrappers;
import com.qiwenshare.file.office.documentserver.models.enums.Type;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class DefaultEmbeddedWrapper {
private Type type;
private String fileName;
}

View File

@ -0,0 +1,40 @@
/**
*
* (c) Copyright Ascensio System SIA 2021
*
* Licensed 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 com.qiwenshare.file.office.services.configurers.wrappers;
import com.qiwenshare.file.office.documentserver.models.enums.Action;
import com.qiwenshare.file.office.documentserver.models.enums.Type;
import com.qiwenshare.file.office.entities.User;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Builder
@Setter
public class DefaultFileWrapper {
private String userFileId;
private String fileName;
private Type type;
private User user;
private String lang;
private Action action;
private String actionData;
private Boolean canEdit;
}

View File

@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiwenshare.common.exception.QiwenException;
import com.qiwenshare.common.operation.FileOperation;
import com.qiwenshare.common.util.DateUtil;
import com.qiwenshare.common.util.security.SessionUtil;
import com.qiwenshare.file.api.IFileService;
import com.qiwenshare.file.component.AsyncTaskComp;
import com.qiwenshare.file.component.FileDealComp;
@ -122,14 +123,14 @@ public class FileService extends ServiceImpl<FileMapper, FileBean> implements IF
}
@Override
public void updateFileDetail(String userFileId, String identifier, long fileSize, long modifyUserId) {
public void updateFileDetail(String userFileId, String identifier, long fileSize) {
UserFile userFile = userFileMapper.selectById(userFileId);
String currentTime = DateUtil.getCurrentTime();
FileBean fileBean = new FileBean();
fileBean.setIdentifier(identifier);
fileBean.setFileSize(fileSize);
fileBean.setModifyTime(currentTime);
fileBean.setModifyUserId(modifyUserId);
fileBean.setModifyUserId(SessionUtil.getSession().getUserId());
fileBean.setFileId(userFile.getFileId());
fileMapper.updateById(fileBean);
userFile.setUploadTime(currentTime);

View File

@ -1,18 +1,26 @@
filesize-max=5242880
storage-folder=app_data
files.docservice.viewed-docs=.pdf|.djvu|.xps
files.docservice.edited-docs=.docx|.xlsx|.csv|.pptx|.txt
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2
files.storage=
files.storage.folder=documents
files.docservice.fillforms-docs=.oform|.docx
files.docservice.viewed-docs=.pdf|.djvu|.xps|.oxps
files.docservice.edited-docs=.docx|.xlsx|.csv|.pptx|.txt|.docxf
files.docservice.convert-docs=.docm|.dotx|.dotm|.dot|.doc|.odt|.fodt|.ott|.xlsm|.xlsb|.xltx|.xltm|.xlt|.xls|.ods|.fods|.ots|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.rtf|.mht|.html|.htm|.xml|.epub|.fb2
files.docservice.timeout=120000
files.docservice.history.postfix=-hist
files.docservice.url.site=http://192.168.1.6:80/
files.docservice.url.site=https://officeview.qiwenshare.com/
files.docservice.url.converter=ConvertService.ashx
files.docservice.url.command=coauthoring/CommandService.ashx
files.docservice.url.api=web-apps/apps/api/documents/api.js
files.docservice.url.preloader=web-apps/apps/api/documents/cache-scripts.html
files.docservice.url.example=
#files.docservice.plugins=../../../../sdkjs-plugins/sdkjs-plugins-auto/textlibrary/config.json,../../../../sdkjs-plugins/sdkjs-plugins-auto/clipart/config.json
files.docservice.secret=
files.docservice.header=Authorization
files.docservice.secret=secret
files.docservice.header=Authorization
files.docservice.verify-peer-off=true
files.docservice.languages=en:English|az:Azerbaijani|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|nb:Norwegian|pl:Polish|pt:Portuguese|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese