OnlyOffice Demo
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.serializers.FilterState;
|
||||
import com.onlyoffice.integration.services.UserServices;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class ExampleData {
|
||||
@Autowired
|
||||
private UserServices userService;
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
// the description for user 0
|
||||
List<String> descriptionUserZero = List.of(
|
||||
"The name is requested when the editor is opened",
|
||||
"Doesn’t belong to any group",
|
||||
"Can review all the changes",
|
||||
"Can perform all actions with comments",
|
||||
"The file favorite state is undefined",
|
||||
"Can't mention others in comments",
|
||||
"Can't create new files from the editor",
|
||||
"Can’t see anyone’s information",
|
||||
"Can't rename files from the editor",
|
||||
"Can't view chat",
|
||||
"Can't protect file",
|
||||
"View file without collaboration"
|
||||
);
|
||||
|
||||
// the description for user 1
|
||||
List<String> descriptionUserFirst = List.of(
|
||||
"File author by default",
|
||||
"He doesn’t belong to any of the groups",
|
||||
"He can review all the changes",
|
||||
"He can do everything with the comments",
|
||||
"The file favorite state is undefined",
|
||||
"Can create a file from a template with data from the editor",
|
||||
"Can see the information about all users",
|
||||
"Can view chat"
|
||||
);
|
||||
|
||||
// the description for user 2
|
||||
List<String> descriptionUserSecond = List.of(
|
||||
"He belongs to Group2",
|
||||
"He can review only his own changes or the changes made by the users who don’t belong"
|
||||
+ " to any of the groups",
|
||||
"He can view every comment, edit his comments and the comments left by the users "
|
||||
+ "who don't belong to any of the groups and remove only his comments",
|
||||
"This file is favorite",
|
||||
"Can create a file from an editor",
|
||||
"Can see the information about users from Group2 and users who don’t belong to any group",
|
||||
"Can view chat"
|
||||
);
|
||||
|
||||
// the description for user 3
|
||||
List<String> descriptionUserThird = List.of(
|
||||
"He belongs to Group3",
|
||||
"He can review only the changes made by the users from Group2",
|
||||
"He can view the comments left by the users from Group2 and Group3 and edit the comments left by "
|
||||
+ "the users from Group2",
|
||||
"This file isn’t favorite",
|
||||
"He can’t copy data from the file into the clipboard",
|
||||
"He can’t download the file",
|
||||
"He can’t print the file",
|
||||
"Can create a file from an editor",
|
||||
"Can see the information about Group2 users",
|
||||
"Can view chat"
|
||||
);
|
||||
|
||||
// create user 1 with the specified parameters
|
||||
userService.createUser("John Smith", "smith@example.com", descriptionUserFirst,
|
||||
"", List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
List.of(FilterState.NULL.toString()), null, true, true);
|
||||
|
||||
// create user 2 with the specified parameters
|
||||
userService.createUser("Mark Pottato", "pottato@example.com", descriptionUserSecond,
|
||||
"group-2", List.of("", "group-2"), List.of(FilterState.NULL.toString()),
|
||||
List.of("group-2", ""), List.of("group-2"), List.of("group-2", ""), true, true,
|
||||
true);
|
||||
|
||||
// create user 3 with the specified parameters
|
||||
userService.createUser("Hamish Mitchell", "mitchell@example.com", descriptionUserThird,
|
||||
"group-3", List.of("group-2"), List.of("group-2", "group-3"), List.of("group-2"),
|
||||
new ArrayList<>(), List.of("group-2"), false, true, true);
|
||||
|
||||
// create user 0 with the specified parameters
|
||||
userService.createUser("Anonymous", null, descriptionUserZero, "",
|
||||
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
List.of(FilterState.NULL.toString()), List.of(FilterState.NULL.toString()),
|
||||
new ArrayList<>(), null, false, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class IntegrationApplication {
|
||||
|
||||
// run the SpringApplication from the IntagrationApplication with the specified parameters
|
||||
public static void main(final String[] args) {
|
||||
SpringApplication.run(IntegrationApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.modelmapper.convention.MatchingStrategies;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.util.SSLUtils;
|
||||
|
||||
@Configuration
|
||||
public class IntegrationConfiguration {
|
||||
|
||||
@Value("${files.storage}")
|
||||
private String storageAddress;
|
||||
|
||||
@Value("${files.docservice.verify-peer-off}")
|
||||
private String verifyPerrOff;
|
||||
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@Autowired
|
||||
private SSLUtils ssl;
|
||||
|
||||
@Bean
|
||||
public ModelMapper mapper() { // create the model mapper
|
||||
ModelMapper mapper = new ModelMapper();
|
||||
mapper.getConfiguration() // get the mapper configuration and set new parameters to it
|
||||
.setMatchingStrategy(MatchingStrategies.STRICT) // specify the STRICT matching strategy
|
||||
.setFieldMatchingEnabled(true) // define if the field matching is enabled or not
|
||||
.setSkipNullEnabled(true) // define if null value will be skipped or not
|
||||
.setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE); /* specify
|
||||
the PRIVATE field access level */
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JSONParser jsonParser() { // create JSON parser
|
||||
return new JSONParser();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() { // initialize the storage path builder
|
||||
storagePathBuilder.configure(storageAddress.isBlank() ? null : storageAddress);
|
||||
if (!verifyPerrOff.isEmpty()) {
|
||||
try {
|
||||
if (verifyPerrOff.equals("true")) {
|
||||
ssl.turnOffSslChecking(); //the certificate will be ignored
|
||||
} else {
|
||||
ssl.turnOnSslChecking(); //the certificate will be verified
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ObjectMapper objectMapper() { // create the object mapper
|
||||
return new ObjectMapper();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.dto.Mentions;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.FileModel;
|
||||
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.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.ANONYMOUS_USER_ID;
|
||||
|
||||
@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") final String fileName,
|
||||
@RequestParam(value = "action", required = false) final String actionParam,
|
||||
@RequestParam(value = "type", required = false) final String typeParam,
|
||||
@RequestParam(value = "actionLink", required = false) final String actionLink,
|
||||
@RequestParam(value = "directUrl", required = false,
|
||||
defaultValue = "false") final Boolean directUrl,
|
||||
@CookieValue(value = "uid") final String uid,
|
||||
@CookieValue(value = "ulang") final String lang,
|
||||
final 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)
|
||||
.isEnableDirectUrl(directUrl)
|
||||
.build()
|
||||
);
|
||||
|
||||
// add attributes to the specified model
|
||||
// add file model with the default parameters to the original model
|
||||
model.addAttribute("model", fileModel);
|
||||
|
||||
// get file history and add it to the model
|
||||
model.addAttribute("fileHistory", historyManager.getHistory(fileModel.getDocument()));
|
||||
|
||||
// create the document service api URL and add it to the model
|
||||
model.addAttribute("docserviceApiUrl", docserviceSite + docserviceApiUrl);
|
||||
|
||||
// get an image and add it to the model
|
||||
model.addAttribute("dataInsertImage", getInsertImage(directUrl));
|
||||
|
||||
// get a document for comparison and add it to the model
|
||||
model.addAttribute("dataCompareFile", getCompareFile(directUrl));
|
||||
|
||||
// get recipients data for mail merging and add it to the model
|
||||
model.addAttribute("dataMailMergeRecipients", getMailMerge(directUrl));
|
||||
|
||||
// get user data for mentions and add it to the model
|
||||
model.addAttribute("usersForMentions", getUserMentions(uid));
|
||||
return "editor.html";
|
||||
}
|
||||
|
||||
private List<Mentions> getUserMentions(final 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() != ANONYMOUS_USER_ID) {
|
||||
|
||||
// user data includes user names and emails
|
||||
usersForMentions.add(new Mentions(u.getName(), u.getEmail()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usersForMentions;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String getInsertImage(final Boolean directUrl) { // 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");
|
||||
if (directUrl) {
|
||||
dataInsertImage.put("directUrl", storagePathBuilder
|
||||
.getServerUrl(false) + "/css/img/logo.png");
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
|
||||
// create token from the dataInsertImage object
|
||||
dataInsertImage.put("token", jwtManager.createToken(dataInsertImage));
|
||||
}
|
||||
|
||||
return objectMapper.writeValueAsString(dataInsertImage)
|
||||
.substring(1, objectMapper.writeValueAsString(dataInsertImage).length() - 1);
|
||||
}
|
||||
|
||||
// get a document that will be compared with the current document
|
||||
@SneakyThrows
|
||||
private String getCompareFile(final Boolean directUrl) {
|
||||
Map<String, Object> dataCompareFile = new HashMap<>();
|
||||
dataCompareFile.put("fileType", "docx");
|
||||
dataCompareFile.put("url", storagePathBuilder.getServerUrl(true) + "/assets?name=sample.docx");
|
||||
if (directUrl) {
|
||||
dataCompareFile.put("directUrl", storagePathBuilder
|
||||
.getServerUrl(false) + "/assets?name=sample.docx");
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
|
||||
// create token from the dataCompareFile object
|
||||
dataCompareFile.put("token", jwtManager.createToken(dataCompareFile));
|
||||
}
|
||||
|
||||
return objectMapper.writeValueAsString(dataCompareFile);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String getMailMerge(final Boolean directUrl) {
|
||||
Map<String, Object> dataMailMergeRecipients = new HashMap<>(); // get recipients data for mail merging
|
||||
dataMailMergeRecipients.put("fileType", "csv");
|
||||
dataMailMergeRecipients.put("url", storagePathBuilder.getServerUrl(true) + "/csv");
|
||||
if (directUrl) {
|
||||
dataMailMergeRecipients.put("directUrl", storagePathBuilder.getServerUrl(false) + "/csv");
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
|
||||
// create token from the dataMailMergeRecipients object
|
||||
dataMailMergeRecipients.put("token", jwtManager.createToken(dataMailMergeRecipients));
|
||||
}
|
||||
|
||||
return objectMapper.writeValueAsString(dataMailMergeRecipients);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,624 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.controllers;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.onlyoffice.integration.documentserver.callbacks.CallbackHandler;
|
||||
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStorageMutator;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.dto.Converter;
|
||||
import com.onlyoffice.integration.dto.ConvertedData;
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
|
||||
import com.onlyoffice.integration.services.UserServices;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
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.CookieValue;
|
||||
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.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
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(final String uid, final 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(final 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(final String fileName,
|
||||
final String version,
|
||||
final String file) {
|
||||
|
||||
// load the specified file as a resource
|
||||
Resource resource = storageMutator.loadFileAsResourceHistory(fileName, version, file);
|
||||
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") final MultipartFile file, // upload a file
|
||||
@CookieValue("uid") final 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)) {
|
||||
|
||||
// if not, write an error message to the response
|
||||
return "{ \"error\": \"File type is not supported\"}";
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// if the operation of file uploading is unsuccessful, an error occurs
|
||||
return "{ \"error\": \"Something went wrong when uploading the file.\"}";
|
||||
}
|
||||
|
||||
@PostMapping(path = "${url.converter}")
|
||||
@ResponseBody
|
||||
public String convert(@RequestBody final Converter body, // convert a file
|
||||
@CookieValue("uid") final String uid, @CookieValue("ulang") final String lang) {
|
||||
// get file name
|
||||
String fileName = body.getFileName();
|
||||
|
||||
// get URL for downloading a file with the specified name
|
||||
String fileUri = documentManager.getDownloadUrl(fileName, true);
|
||||
|
||||
// get file password if it exists
|
||||
String filePass = body.getFilePass() != null ? body.getFilePass() : null;
|
||||
|
||||
// get file extension
|
||||
String fileExt = fileUtility.getFileExtension(fileName);
|
||||
|
||||
// get document type (word, cell or slide)
|
||||
DocumentType type = fileUtility.getDocumentType(fileName);
|
||||
|
||||
// convert to .ooxml
|
||||
String internalFileExt = "ooxml";
|
||||
|
||||
try {
|
||||
// check if the file with such an extension can be converted
|
||||
if (fileUtility.getConvertExts().contains(fileExt)) {
|
||||
String key = serviceConverter.generateRevisionId(fileUri); // generate document key
|
||||
ConvertedData response = serviceConverter // get the URL to the converted file
|
||||
.getConvertedData(fileUri, fileExt, internalFileExt, key, filePass, true, lang);
|
||||
|
||||
String newFileUri = response.getUri();
|
||||
String newFileType = "." + response.getFileType();
|
||||
|
||||
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) + newFileType;
|
||||
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");
|
||||
}
|
||||
|
||||
// remove source file
|
||||
storageMutator.deleteFile(fileName);
|
||||
|
||||
// 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();
|
||||
}
|
||||
// if the operation of file converting is unsuccessful, an error occurs
|
||||
return "{ \"error\": \"" + "The file can't be converted.\"}";
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
@ResponseBody
|
||||
public String delete(@RequestBody final Converter body) { // delete a file
|
||||
try {
|
||||
String fullFileName = fileUtility.getFileName(body.getFileName()); // get full file name
|
||||
|
||||
// delete a file from the storage and return the status of this operation (true or false)
|
||||
boolean fileSuccess = storageMutator.deleteFile(fullFileName);
|
||||
|
||||
// delete file history and return the status of this operation (true or false)
|
||||
boolean historySuccess = storageMutator.deleteFileHistory(fullFileName);
|
||||
|
||||
return "{ \"success\": \"" + (fileSuccess && historySuccess) + "\"}";
|
||||
} catch (Exception e) {
|
||||
// if the operation of file deleting is unsuccessful, an error occurs
|
||||
return "{ \"error\": \"" + e.getMessage() + "\"}";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/downloadhistory")
|
||||
public ResponseEntity<Resource> downloadHistory(final HttpServletRequest request, // download a file
|
||||
@RequestParam("fileName") final String fileName,
|
||||
@RequestParam("ver") final String version,
|
||||
@RequestParam("file") final String file) { // history file
|
||||
try {
|
||||
// check if a token is enabled or not
|
||||
if (jwtManager.tokenEnabled() && jwtManager.tokenUseForRequest()) {
|
||||
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(final HttpServletRequest request, // download a file
|
||||
@RequestParam("fileName") final String fileName,
|
||||
@RequestParam(value = "userAddress", required = false)
|
||||
final String userAddress) {
|
||||
try {
|
||||
// check if a token is enabled or not
|
||||
if (jwtManager.tokenEnabled() && userAddress != null && jwtManager.tokenUseForRequest()) {
|
||||
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 downloadFile(fileName); // download data from the specified file
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/create")
|
||||
public String create(@RequestParam("fileExt")
|
||||
final String fileExt, // create a sample file of the specified extension
|
||||
@RequestParam(value = "sample", required = false) final Optional<Boolean> isSample,
|
||||
@CookieValue(value = "uid", required = false) final String uid,
|
||||
final Model model) {
|
||||
// specify if the sample data exists or not
|
||||
Boolean sampleData = (isSample.isPresent() && !isSample.isEmpty()) && isSample.get();
|
||||
if (fileExt != null) {
|
||||
try {
|
||||
Optional<User> user = userService.findUserById(Integer.parseInt(uid)); // find a user by their ID
|
||||
if (!user.isPresent()) {
|
||||
// if the user with the specified ID doesn't exist, an error occurs
|
||||
throw new RuntimeException("Could not fine any user with id = " + uid);
|
||||
}
|
||||
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")
|
||||
final String name) { // get sample files from the assests
|
||||
String fileName = Path.of("assets", "document-templates", "sample", fileUtility.getFileName(name)).toString();
|
||||
return downloadFile(fileName);
|
||||
}
|
||||
|
||||
@GetMapping("/csv")
|
||||
public ResponseEntity<Resource> csv() { // download a csv file
|
||||
String fileName = Path.of("assets", "document-templates", "sample", "csv.csv").toString();
|
||||
return downloadFile(fileName);
|
||||
}
|
||||
|
||||
@GetMapping("/files")
|
||||
@ResponseBody
|
||||
public ArrayList<Map<String, Object>> files(@RequestParam(value = "fileId", required = false)
|
||||
final String fileId) { // get files information
|
||||
return fileId == null ? documentManager.getFilesInfo() : documentManager.getFilesInfo(fileId);
|
||||
}
|
||||
|
||||
@PostMapping(path = "${url.track}")
|
||||
@ResponseBody
|
||||
public String track(final HttpServletRequest request, // track file changes
|
||||
@RequestParam("fileName") final String fileName,
|
||||
@RequestParam("userAddress") final String userAddress,
|
||||
@RequestBody final Track body) {
|
||||
Track track;
|
||||
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
|
||||
track = objectMapper.readValue(bodyCheck.toJSONString(), Track.class); // read the request body
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
|
||||
int error = callbackHandler.handle(track, fileName);
|
||||
|
||||
return "{\"error\":" + error + "}";
|
||||
}
|
||||
|
||||
@PostMapping("/saveas")
|
||||
@ResponseBody
|
||||
public String saveAs(@RequestBody final JSONObject body, @CookieValue("uid") final 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 final 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();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/reference")
|
||||
@ResponseBody
|
||||
public String reference(@RequestBody final JSONObject body) {
|
||||
try {
|
||||
JSONParser parser = new JSONParser();
|
||||
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
||||
|
||||
String userAddress = "";
|
||||
String fileName = "";
|
||||
|
||||
if (body.containsKey("referenceData")) {
|
||||
LinkedHashMap referenceDataObj = (LinkedHashMap) body.get("referenceData");
|
||||
String instanceId = (String) referenceDataObj.get("instanceId");
|
||||
|
||||
if (instanceId.equals(storagePathBuilder.getServerUrl(false))) {
|
||||
JSONObject fileKey = (JSONObject) parser.parse((String) referenceDataObj.get("fileKey"));
|
||||
userAddress = (String) fileKey.get("userAddress");
|
||||
if (userAddress.equals(InetAddress.getLocalHost().getHostAddress())) {
|
||||
fileName = (String) fileKey.get("fileName");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fileName.equals("")) {
|
||||
try {
|
||||
String path = (String) body.get("path");
|
||||
path = fileUtility.getFileName(path);
|
||||
File f = new File(storagePathBuilder.getFileLocation(path));
|
||||
if (f.exists()) {
|
||||
fileName = path;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return "{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}";
|
||||
}
|
||||
}
|
||||
|
||||
if (fileName.equals("")) {
|
||||
return "{ \"error\": \"File not found\"}";
|
||||
}
|
||||
|
||||
boolean directUrl = (boolean) body.get("directUrl");
|
||||
|
||||
HashMap<String, Object> fileKey = new HashMap<>();
|
||||
fileKey.put("fileName", fileName);
|
||||
fileKey.put("userAddress", InetAddress.getLocalHost().getHostAddress());
|
||||
|
||||
HashMap<String, Object> referenceData = new HashMap<>();
|
||||
referenceData.put("instanceId", storagePathBuilder.getServerUrl(true));
|
||||
referenceData.put("fileKey", gson.toJson(fileKey));
|
||||
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("fileType", fileUtility.getFileExtension(fileName).replace(".", ""));
|
||||
data.put("url", documentManager.getDownloadUrl(fileName, true));
|
||||
data.put("directUrl", directUrl ? documentManager.getDownloadUrl(fileName, false) : null);
|
||||
data.put("referenceData", referenceData);
|
||||
data.put("path", fileName);
|
||||
|
||||
if (jwtManager.tokenEnabled()) {
|
||||
String token = jwtManager.createToken(data);
|
||||
data.put("token", token);
|
||||
}
|
||||
return gson.toJson(data);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "{ \"error\" : 1, \"message\" : \"" + e.getMessage() + "\"}";
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/restore")
|
||||
@ResponseBody
|
||||
public String restore(@RequestBody final JSONObject body) {
|
||||
try {
|
||||
String sourceBasename = (String) body.get("fileName");
|
||||
Integer version = (Integer) body.get("version");
|
||||
String userID = (String) body.get("userId");
|
||||
|
||||
String sourceStringFile = storagePathBuilder.getFileLocation(sourceBasename);
|
||||
File sourceFile = new File(sourceStringFile);
|
||||
Path sourcePathFile = sourceFile.toPath();
|
||||
String historyDirectory = storagePathBuilder.getHistoryDir(sourcePathFile.toString());
|
||||
|
||||
Integer bumpedVersion = storagePathBuilder.getFileVersion(historyDirectory, false);
|
||||
String bumpedVersionStringDirectory = documentManager.versionDir(historyDirectory, bumpedVersion, true);
|
||||
File bumpedVersionDirectory = new File(bumpedVersionStringDirectory);
|
||||
if (!bumpedVersionDirectory.exists()) {
|
||||
bumpedVersionDirectory.mkdir();
|
||||
}
|
||||
|
||||
Path bumpedKeyPathFile = Paths.get(bumpedVersionStringDirectory, "key.txt");
|
||||
String bumpedKeyStringFile = bumpedKeyPathFile.toString();
|
||||
File bumpedKeyFile = new File(bumpedKeyStringFile);
|
||||
String bumpedKey = serviceConverter.generateRevisionId(
|
||||
storagePathBuilder.getStorageLocation()
|
||||
+ "/"
|
||||
+ sourceBasename
|
||||
+ "/"
|
||||
+ Long.toString(sourceFile.lastModified())
|
||||
);
|
||||
FileWriter bumpedKeyFileWriter = new FileWriter(bumpedKeyFile);
|
||||
bumpedKeyFileWriter.write(bumpedKey);
|
||||
bumpedKeyFileWriter.close();
|
||||
|
||||
Integer userInnerID = Integer.parseInt(userID.replace("uid-", ""));
|
||||
User user = userService.findUserById(userInnerID).get();
|
||||
|
||||
Path bumpedChangesPathFile = Paths.get(bumpedVersionStringDirectory, "changes.json");
|
||||
String bumpedChangesStringFile = bumpedChangesPathFile.toString();
|
||||
File bumpedChangesFile = new File(bumpedChangesStringFile);
|
||||
JSONObject bumpedChangesUser = new JSONObject();
|
||||
// Don't add the `uid-` prefix.
|
||||
// https://github.com/ONLYOFFICE/document-server-integration/issues/437#issuecomment-1663526562
|
||||
bumpedChangesUser.put("id", user.getId());
|
||||
bumpedChangesUser.put("name", user.getName());
|
||||
JSONObject bumpedChangesChangesItem = new JSONObject();
|
||||
bumpedChangesChangesItem.put("created", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
bumpedChangesChangesItem.put("user", bumpedChangesUser);
|
||||
JSONArray bumpedChangesChanges = new JSONArray();
|
||||
bumpedChangesChanges.add(bumpedChangesChangesItem);
|
||||
JSONObject bumpedChanges = new JSONObject();
|
||||
bumpedChanges.put("serverVersion", null);
|
||||
bumpedChanges.put("changes", bumpedChangesChanges);
|
||||
String bumpedChangesContent = bumpedChanges.toJSONString();
|
||||
FileWriter bumpedChangesFileWriter = new FileWriter(bumpedChangesFile);
|
||||
bumpedChangesFileWriter.write(bumpedChangesContent);
|
||||
bumpedChangesFileWriter.close();
|
||||
|
||||
String sourceExtension = fileUtility.getFileExtension(sourceBasename);
|
||||
String previousBasename = "prev" + sourceExtension;
|
||||
|
||||
Path bumpedFile = Paths.get(bumpedVersionStringDirectory, previousBasename);
|
||||
Files.move(sourcePathFile, bumpedFile);
|
||||
|
||||
String recoveryVersionStringDirectory = documentManager.versionDir(historyDirectory, version, true);
|
||||
Path recoveryPathFile = Paths.get(recoveryVersionStringDirectory, previousBasename);
|
||||
String recoveryStringFile = recoveryPathFile.toString();
|
||||
FileInputStream recoveryStream = new FileInputStream(recoveryStringFile);
|
||||
storageMutator.createFile(sourcePathFile, recoveryStream);
|
||||
recoveryStream.close();
|
||||
|
||||
JSONObject responseBody = new JSONObject();
|
||||
responseBody.put("error", null);
|
||||
responseBody.put("success", true);
|
||||
return responseBody.toJSONString();
|
||||
} catch (Exception error) {
|
||||
error.printStackTrace();
|
||||
JSONObject responseBody = new JSONObject();
|
||||
responseBody.put("error", error.getMessage());
|
||||
responseBody.put("success", false);
|
||||
return responseBody.toJSONString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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.User;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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(@RequestParam(value = "directUrl", required = false) final Boolean directUrl,
|
||||
final 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);
|
||||
model.addAttribute("directUrl", directUrl);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.callbacks;
|
||||
|
||||
import com.onlyoffice.integration.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);
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.callbacks;
|
||||
|
||||
import com.onlyoffice.integration.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(final int code, final Callback callback) { // register a callback handler
|
||||
callbackHandlers.put(code, callback);
|
||||
}
|
||||
|
||||
public int handle(final Track body, final 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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(final int codeParam) {
|
||||
this.code = codeParam;
|
||||
}
|
||||
public int getCode() { // get document status
|
||||
return this.code;
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.callbacks.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Callback;
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Status;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
import com.onlyoffice.integration.dto.Action;
|
||||
import com.onlyoffice.integration.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(final Track body,
|
||||
final 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.onlyoffice.integration.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 {
|
||||
// create a command request to forcibly save the document being edited without closing it
|
||||
callbackManager.commandRequest("forcesave", key, null);
|
||||
} 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
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.callbacks.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Callback;
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Status;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
import com.onlyoffice.integration.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(final Track body,
|
||||
final 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 6 - document is being edited, but the current document state is saved
|
||||
return Status.MUST_FORCE_SAVE.getCode();
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.callbacks.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Callback;
|
||||
import com.onlyoffice.integration.documentserver.callbacks.Status;
|
||||
import com.onlyoffice.integration.documentserver.managers.callback.CallbackManager;
|
||||
import com.onlyoffice.integration.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(final Track body,
|
||||
final 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
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.callback;
|
||||
|
||||
import com.onlyoffice.integration.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
|
||||
}
|
||||
+333
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.callback;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
|
||||
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.dto.Action;
|
||||
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
|
||||
import com.onlyoffice.integration.dto.Track;
|
||||
import lombok.SneakyThrows;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
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;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.FILE_SAVE_TIMEOUT;
|
||||
|
||||
// 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;
|
||||
|
||||
// download file from url
|
||||
@SneakyThrows
|
||||
private byte[] getDownloadFile(final String url) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
throw new RuntimeException("Url argument is not specified"); // URL isn't specified
|
||||
}
|
||||
|
||||
URL uri = new URL(url);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
|
||||
connection.setConnectTimeout(FILE_SAVE_TIMEOUT);
|
||||
InputStream stream = connection.getInputStream(); // get input stream of the file information from the URL
|
||||
|
||||
int statusCode = connection.getResponseCode();
|
||||
if (statusCode != HttpStatus.OK.value()) { // checking status code
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Document editing service returned status: " + statusCode);
|
||||
}
|
||||
|
||||
if (stream == null) {
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Input stream is null");
|
||||
}
|
||||
|
||||
return stream.readAllBytes();
|
||||
}
|
||||
|
||||
// file saving
|
||||
@SneakyThrows
|
||||
private void saveFile(final byte[] byteArray, final Path path) {
|
||||
if (path == null) {
|
||||
throw new RuntimeException("Path argument is not specified"); // file isn't specified
|
||||
}
|
||||
// update a file or create a new one
|
||||
storageMutator.createOrUpdateFile(path, new ByteArrayInputStream(byteArray));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void processSave(final Track body, final 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: Refactoring
|
||||
// convert downloaded file to the file with the current extension if these extensions aren't equal
|
||||
if (!curExt.equals(downloadExt)) {
|
||||
try {
|
||||
String newFileUri = serviceConverter
|
||||
.getConvertedData(downloadUri, downloadExt, curExt,
|
||||
serviceConverter.generateRevisionId(downloadUri), null, false,
|
||||
null).getUri(); // 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);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] byteArrayFile = getDownloadFile(downloadUri); // download document file
|
||||
|
||||
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
|
||||
|
||||
lastVersion.toFile().renameTo(new File(versionDir + File.separator + "prev" + curExt));
|
||||
|
||||
saveFile(byteArrayFile, toSave); // save document file
|
||||
|
||||
byte[] byteArrayChanges = getDownloadFile(changesUri); // download file changes
|
||||
saveFile(byteArrayChanges, Path
|
||||
.of(versionDir + File.separator + "diff.zip")); // 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);
|
||||
|
||||
if (history == null && body.getHistory() != null) {
|
||||
history = objectMapper.writeValueAsString(body.getHistory());
|
||||
}
|
||||
|
||||
if (history != null && !history.isEmpty()) {
|
||||
// write the history changes to the changes.json file
|
||||
storageMutator.writeToFile(versionDir + File.separator + "changes.json", history);
|
||||
}
|
||||
|
||||
// write the key value to the key.txt file
|
||||
storageMutator.writeToFile(versionDir + File.separator + "key.txt", key);
|
||||
|
||||
// get the path to the forcesaved file version and remove it
|
||||
storageMutator.deleteFile(storagePathBuilder.getForcesavePath(newFileName, false));
|
||||
}
|
||||
}
|
||||
|
||||
// todo: Replace (String method) with (Enum method)
|
||||
@SneakyThrows
|
||||
public void commandRequest(final String method,
|
||||
final String key,
|
||||
final 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;
|
||||
// check if a secret key to generate token exists or not
|
||||
if (jwtManager.tokenEnabled() && jwtManager.tokenUseForRequest()) {
|
||||
Map<String, Object> payloadMap = new HashMap<>();
|
||||
payloadMap.put("payload", params);
|
||||
headerToken = jwtManager.createToken(payloadMap); // encode a payload object into a header token
|
||||
|
||||
// add a header Authorization with a header token and Authorization prefix in it
|
||||
connection.setRequestProperty(documentJwtHeader.equals("")
|
||||
? "Authorization" : documentJwtHeader, "Bearer " + headerToken);
|
||||
|
||||
String token = jwtManager.createToken(params); // encode a payload object into a body token
|
||||
params.put("token", token);
|
||||
}
|
||||
|
||||
String bodyString = objectMapper.writeValueAsString(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 = serviceConverter.convertStringToJSON(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(final Track body, final String fileNameParam) { // file force saving process
|
||||
|
||||
String downloadUri = body.getUrl();
|
||||
String fileName = fileNameParam;
|
||||
|
||||
String curExt = fileUtility.getFileExtension(fileName); // get current file extension
|
||||
String downloadExt = "." + body.getFiletype(); // get an extension of the downloaded file
|
||||
|
||||
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 {
|
||||
// convert file and get URL to a new file
|
||||
String newFileUri = serviceConverter
|
||||
.getConvertedData(downloadUri, downloadExt, curExt, serviceConverter
|
||||
.generateRevisionId(downloadUri), null, false, null).getUri();
|
||||
if (newFileUri.isEmpty()) {
|
||||
newFileName = true;
|
||||
} else {
|
||||
downloadUri = newFileUri;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
newFileName = true;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] byteArrayFile = getDownloadFile(downloadUri); // download document file
|
||||
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) {
|
||||
// get the correct file name if it already exists
|
||||
fileName = documentManager
|
||||
.getCorrectName(fileUtility
|
||||
.getFileNameWithoutExtension(fileName) + "-form" + downloadExt);
|
||||
} 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
|
||||
// create meta data for the forcesaved file
|
||||
storageMutator.createMeta(fileName, user, "Filling Form");
|
||||
} else {
|
||||
if (newFileName) {
|
||||
fileName = documentManager
|
||||
.getCorrectName(fileUtility.getFileNameWithoutExtension(fileName) + downloadExt);
|
||||
}
|
||||
|
||||
forcesavePath = storagePathBuilder.getForcesavePath(fileName, false);
|
||||
if (forcesavePath.isEmpty()) {
|
||||
forcesavePath = storagePathBuilder.getForcesavePath(fileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
saveFile(byteArrayFile, Path.of(forcesavePath));
|
||||
}
|
||||
}
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.document;
|
||||
|
||||
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 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.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;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.KILOBYTE_SIZE;
|
||||
|
||||
@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;
|
||||
|
||||
// get URL to the created file
|
||||
public String getCreateUrl(final String fileName, final Boolean sample) {
|
||||
String fileExt = fileUtility.getFileExtension(fileName).replace(".", "");
|
||||
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(final 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));
|
||||
|
||||
// run through all the files with such a name in the storage directory
|
||||
for (int i = 1; Files.exists(path); i++) {
|
||||
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(final String fileName, final 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(final String fileName, final Integer version, final String file,
|
||||
final 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(final String fileName) {
|
||||
String serverPath = storagePathBuilder.getServerUrl(true);
|
||||
String storageAddress = storagePathBuilder.getStorageLocation();
|
||||
try {
|
||||
String query = trackUrl + "?fileName="
|
||||
+ URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8.toString())
|
||||
+ "&userAddress=" + URLEncoder
|
||||
.encode(storageAddress, java.nio.charset.StandardCharsets.UTF_8.toString());
|
||||
return serverPath + query;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// get URL to download a file
|
||||
public String getDownloadUrl(final String fileName, final 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() / Double.valueOf(KILOBYTE_SIZE))))
|
||||
.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(final 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(final String path, final Integer version, final boolean historyPath) {
|
||||
if (!historyPath) {
|
||||
return storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(path)) + version;
|
||||
}
|
||||
return path + File.separator + version;
|
||||
}
|
||||
|
||||
// create demo document
|
||||
public String createDemo(final String fileExt, final Boolean sample, final String uid, final String uname) {
|
||||
String demoName = (sample ? "sample." : "new.")
|
||||
+ fileExt; // create sample or new template file with the necessary extension
|
||||
String demoPath =
|
||||
"assets"
|
||||
+ File.separator
|
||||
+ "document-templates"
|
||||
+ File.separator
|
||||
+ (sample ? "sample" : "new")
|
||||
+ File.separator
|
||||
+ demoName;
|
||||
|
||||
// get a file name with an index if the file with such a name already exists
|
||||
String fileName = getCorrectName(demoName);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
// specify the document manager functions
|
||||
public interface DocumentManager {
|
||||
|
||||
// get a file name with an index if the file with such a name already exists
|
||||
String getCorrectName(String fileName);
|
||||
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 fileName); // 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
|
||||
|
||||
// get the path to the file version by the history path and file version
|
||||
String versionDir(String path, Integer version, boolean historyPath);
|
||||
|
||||
// create demo document
|
||||
String createDemo(String fileExt, Boolean sample, String uid, String uname) throws Exception;
|
||||
String getCreateUrl(String fileName, Boolean sample); // get URL to the created file
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.history;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Document;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import lombok.SneakyThrows;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
// 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(final Document document) { // get document history
|
||||
|
||||
// get history directory
|
||||
String histDir = storagePathBuilder.getHistoryDir(storagePathBuilder.getFileLocation(document.getTitle()));
|
||||
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 = (JSONObject) parser.parse(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));
|
||||
if (!document.getDirectUrl().equals("")) {
|
||||
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 = (JSONObject) parser.parse(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"));
|
||||
|
||||
// get the history data from the previous file version
|
||||
Map<String, Object> prev = (Map<String, Object>) histData.get(Integer.toString(i - 2));
|
||||
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"));
|
||||
if (!document.getDirectUrl().equals("")) {
|
||||
prevInfo.put("directUrl", prev.get("directUrl"));
|
||||
}
|
||||
|
||||
// write information about previous file version to the data object
|
||||
dataObj.put("previous", prevInfo);
|
||||
// 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(final 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;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.history;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Document;
|
||||
|
||||
// specify the history manager functions
|
||||
public interface HistoryManager {
|
||||
String[] getHistory(Document document); // get document history
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.jwt;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
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;
|
||||
@Value("${files.docservice.token-use-for-request}")
|
||||
private String tokenUseForRequest;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
private JSONParser parser;
|
||||
|
||||
// create document token
|
||||
@Override
|
||||
public String createToken(final 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
|
||||
@Override
|
||||
public boolean tokenEnabled() {
|
||||
return tokenSecret != null && !tokenSecret.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tokenUseForRequest() {
|
||||
return Boolean.parseBoolean(tokenUseForRequest) && !tokenUseForRequest.isEmpty();
|
||||
}
|
||||
|
||||
// read document token
|
||||
@Override
|
||||
public JWT readToken(final String token) {
|
||||
try {
|
||||
// build a HMAC verifier using the token secret
|
||||
Verifier verifier = HMACVerifier.newVerifier(tokenSecret);
|
||||
|
||||
// verify and decode the encoded string JWT to a rich object
|
||||
return JWT.getDecoder().decode(token, verifier);
|
||||
} catch (Exception exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// parse the body
|
||||
@Override
|
||||
public JSONObject parseBody(final String payload, final String header) {
|
||||
JSONObject body;
|
||||
try {
|
||||
Object obj = parser.parse(payload); // get body parameters by parsing the payload
|
||||
body = (JSONObject) obj;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"JSON Parsing error\"}");
|
||||
}
|
||||
if (tokenEnabled() && tokenUseForRequest()) { // 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 && header.trim()!="") { // and the header is defined
|
||||
|
||||
// get token from the header (it is placed after the Bearer prefix if it exists)
|
||||
token = header.startsWith("Bearer ") ? header.substring("Bearer ".length()) : header;
|
||||
}
|
||||
}
|
||||
if (token == null || token.trim()=="") {
|
||||
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\"}");
|
||||
}
|
||||
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");
|
||||
|
||||
jwt.claims = jwtPayload;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"Wrong payload\"}");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Object obj = parser.parse(objectMapper.writeValueAsString(jwt.claims));
|
||||
body = (JSONObject) obj;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("{\"error\":1,\"message\":\"Parsing error\"}");
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.jwt;
|
||||
|
||||
import org.json.simple.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
|
||||
boolean tokenUseForRequest(); // 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
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.template;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Template;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.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.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(final String fileName) {
|
||||
List<Template> templates = List.of(
|
||||
new Template("", "Blank", documentManager
|
||||
.getCreateUrl(fileName, false)), // create a blank template
|
||||
new Template(getTemplateImageUrl(fileName), "With sample content", documentManager
|
||||
.getCreateUrl(fileName,
|
||||
true)) // create a template with sample content using the template image
|
||||
);
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
// get the template image URL for the specified file
|
||||
public String getTemplateImageUrl(final 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)
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.managers.template;
|
||||
|
||||
import com.onlyoffice.integration.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
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public abstract class AbstractModel implements Serializable {
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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
|
||||
/* 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. */
|
||||
public class Customization {
|
||||
@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;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.configurations;
|
||||
|
||||
import com.onlyoffice.integration.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
|
||||
/* The parameters which allow to change the settings
|
||||
which define the behavior of the buttons in the embedded mode */
|
||||
public class Embedded {
|
||||
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
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.configurations;
|
||||
|
||||
import com.onlyoffice.integration.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;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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
|
||||
/* The additional parameters for the document (document owner, folder where the document is stored,
|
||||
uploading date, sharing settings) */
|
||||
public class Info {
|
||||
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());
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum Action {
|
||||
edit,
|
||||
review,
|
||||
view,
|
||||
embedded,
|
||||
filter,
|
||||
comment,
|
||||
chat,
|
||||
fillForms,
|
||||
blockcontent,
|
||||
protect
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum ConvertErrorType {
|
||||
EMPTY_ERROR(0, ""),
|
||||
CONVERTATION_UNKNOWN(-1, "Error convertation unknown"),
|
||||
CONVERTATION_TIMEOUT(-2, "Error convertation timeout"),
|
||||
CONVERTATION_ERROR(-3, "Error convertation error"),
|
||||
DOWNLOAD_ERROR(-4, "Error download error"),
|
||||
UNEXPECTED_GUID_ERROR(-5, "Error unexpected guid"),
|
||||
DATABASE_ERROR(-6, "Error database"),
|
||||
DOCUMENT_REQUEST_ERROR(-7, "Error document request"),
|
||||
DOCUMENT_VKEY_ERROR(-8, "Error document VKey");
|
||||
|
||||
private final int code;
|
||||
private final String label;
|
||||
|
||||
ConvertErrorType(final int codeParam, final String labelParam) {
|
||||
this.code = codeParam;
|
||||
this.label = labelParam;
|
||||
}
|
||||
|
||||
public static String labelOfCode(final int code) {
|
||||
for (ConvertErrorType convertErrorType : values()) {
|
||||
if (convertErrorType.code == code) {
|
||||
return convertErrorType.label;
|
||||
}
|
||||
}
|
||||
return "ErrorCode = " + code;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum DocumentType {
|
||||
word,
|
||||
cell,
|
||||
slide
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum Mode {
|
||||
edit,
|
||||
view
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum ToolbarDocked {
|
||||
top,
|
||||
bottom
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum Type {
|
||||
desktop,
|
||||
mobile,
|
||||
embedded
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.onlyoffice.integration.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
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.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;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@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 urlUser; /* the absolute URL that will allow the document to be saved
|
||||
onto the user personal computer */
|
||||
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
|
||||
private String directUrl;
|
||||
private HashMap<String, Object> referenceData;
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Customization;
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Embedded;
|
||||
import com.onlyoffice.integration.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 */
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
|
||||
import com.onlyoffice.integration.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
|
||||
/* the file base parameters which include the platform type used,
|
||||
document display size (width and height) and type of the document opened */
|
||||
public class FileModel {
|
||||
@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
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.onlyoffice.integration.documentserver.models.AbstractModel;
|
||||
import com.onlyoffice.integration.documentserver.serializers.SerializerFilter;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@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
|
||||
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
|
||||
private List<String> reviewGroups; // the groups whose changes the user can accept/reject
|
||||
@Autowired
|
||||
private CommentGroup commentGroups; // the groups whose comments the user can edit, remove and/or view
|
||||
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = SerializerFilter.class)
|
||||
private List<String> userInfoGroups;
|
||||
private Boolean protect = true;
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class ReferenceData {
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
private final String instanceId;
|
||||
private final Map<String, String> fileKey;
|
||||
public ReferenceData(final String fileName, final String curUserHostAddress, final User user) {
|
||||
instanceId = storagePathBuilder.getServerUrl(true);
|
||||
Map<String, String> fileKeyList = new HashMap<>();
|
||||
if (!user.getId().equals("uid-0")) {
|
||||
fileKeyList.put("fileName", fileName);
|
||||
fileKeyList.put("userAddress", curUserHostAddress);
|
||||
} else {
|
||||
fileKeyList = null;
|
||||
}
|
||||
fileKey = fileKeyList;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.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(final int idParam, final String nameParam, final String groupParam) {
|
||||
this.id = "uid-" + idParam; // the user id
|
||||
this.name = nameParam; // the user name
|
||||
this.group = groupParam; // the group the user belongs to
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.serializers;
|
||||
|
||||
public enum FilterState {
|
||||
NULL
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.serializers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SerializerFilter {
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj instanceof List) {
|
||||
if (((List<?>) obj).size() == 1 && ((List<?>) obj).get(0) == FilterState.NULL.toString()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.storage;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
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, ByteArrayInputStream stream); // create or update a file
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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 */
|
||||
}
|
||||
+392
@@ -0,0 +1,392 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.storage;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.json.simple.JSONObject;
|
||||
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.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
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;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.KILOBYTE_SIZE;
|
||||
|
||||
// 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;
|
||||
|
||||
@Autowired
|
||||
private HttpServletRequest request;
|
||||
|
||||
/*
|
||||
This Storage configuration method should be called whenever a new storage folder is required
|
||||
*/
|
||||
public void configure(final 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(final 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(final 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(final Path path, final 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[KILOBYTE_SIZE];
|
||||
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(final String fileNameParam) {
|
||||
String fileName = URLDecoder
|
||||
.decode(fileNameParam, StandardCharsets.UTF_8); // decode a x-www-form-urlencoded string
|
||||
if (fileName.isBlank()) {
|
||||
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
|
||||
|
||||
// delete the specified file; for directories, recursively delete any nested directories or files as well
|
||||
boolean fileDeleted = FileSystemUtils.deleteRecursively(filePath.toFile());
|
||||
/* delete the specified file without extension; for directories,
|
||||
recursively delete any nested directories or files as well */
|
||||
boolean fileWithoutExtDeleted = FileSystemUtils.deleteRecursively(filePathWithoutExt.toFile());
|
||||
|
||||
return fileDeleted && fileWithoutExtDeleted;
|
||||
}
|
||||
|
||||
// delete file history
|
||||
public boolean deleteFileHistory(final String fileNameParam) {
|
||||
String fileName = URLDecoder
|
||||
.decode(fileNameParam, StandardCharsets.UTF_8); // decode a x-www-form-urlencoded string
|
||||
if (fileName.isBlank()) {
|
||||
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
|
||||
|
||||
/* delete the specified history file; for directories,
|
||||
recursively delete any nested directories or files as well */
|
||||
boolean historyDeleted = FileSystemUtils.deleteRecursively(fileHistoryPath.toFile());
|
||||
|
||||
/* delete the specified history file without extension; for directories,
|
||||
recursively delete any nested directories or files as well */
|
||||
boolean historyWithoutExtDeleted = FileSystemUtils.deleteRecursively(fileHistoryPathWithoutExt.toFile());
|
||||
|
||||
return historyDeleted || historyWithoutExtDeleted;
|
||||
}
|
||||
|
||||
// update a file
|
||||
public String updateFile(final String fileName, final 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(final Path source, final 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(final String pathName, final 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(final String fileName, final 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(final String fileName) {
|
||||
String fileLocation = getForcesavePath(fileName,
|
||||
false); // get the path where all the forcely saved file versions are saved
|
||||
if (fileLocation.isBlank()) { // 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(final String fileName, final String version, final 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(final String fileName,
|
||||
final String uid,
|
||||
final 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)) {
|
||||
json.writeJSONString(writer);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// create or update a file
|
||||
public boolean createOrUpdateFile(final Path path, final ByteArrayInputStream 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(final Boolean forDocumentServer) {
|
||||
if (forDocumentServer && !docserviceUrlExample.equals("")) {
|
||||
return docserviceUrlExample;
|
||||
} else {
|
||||
return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
|
||||
+ request.getContextPath();
|
||||
}
|
||||
}
|
||||
|
||||
// get the history directory
|
||||
public String getHistoryDir(final String path) {
|
||||
return path + historyPostfix;
|
||||
}
|
||||
|
||||
// get the file version
|
||||
public int getFileVersion(final String historyPath, final 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
|
||||
}
|
||||
}
|
||||
|
||||
// run through all the files in the history directory
|
||||
try (Stream<Path> stream = Files.walk(path, 1)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.util;
|
||||
|
||||
public final class Constants {
|
||||
public static final Integer MAX_FILE_SIZE = 5 * 1024 * 1024;
|
||||
public static final Integer CONVERT_TIMEOUT_MS = 120000;
|
||||
public static final String CONVERTATION_ERROR_MESSAGE_TEMPLATE = "Error occurred in the ConvertService: ";
|
||||
public static final Long FULL_LOADING_IN_PERCENT = 100L;
|
||||
public static final Integer FILE_SAVE_TIMEOUT = 5000;
|
||||
public static final Integer MAX_KEY_LENGTH = 20;
|
||||
public static final Integer ANONYMOUS_USER_ID = 4;
|
||||
public static final Integer KILOBYTE_SIZE = 1024;
|
||||
|
||||
private Constants() { }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class Misc {
|
||||
|
||||
// convert user descriptions to the specified format
|
||||
public String convertUserDescriptions(final String username, final List<String> description) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.util;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
/**
|
||||
* 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(final String hostname, final SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private final TrustManager[] unquestioningTrustManager = new TrustManager[] {
|
||||
new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(final X509Certificate[] certs, final String authType) {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(final X509Certificate[] certs, final 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, unquestioningTrustManager, 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());
|
||||
}
|
||||
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.util.file;
|
||||
|
||||
import com.onlyoffice.integration.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;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.MAX_FILE_SIZE;
|
||||
|
||||
@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(final 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(final 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(final 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(final 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(final 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(final String directory, final 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
|
||||
// get a name of each file without extension and add an index to it
|
||||
fileName = getFileNameWithoutExtension(fullFileName) + "(" + i + ")";
|
||||
|
||||
// create a new path for this file with the correct name and extension
|
||||
path = Paths.get(directory + fileName + fileExtension);
|
||||
}
|
||||
|
||||
path = Paths.get(directory + fileName + fileExtension);
|
||||
return path;
|
||||
}
|
||||
|
||||
// get maximum file size
|
||||
public long getMaxFileSize() {
|
||||
long size = Long.parseLong(filesizeMax);
|
||||
return size > 0 ? size : MAX_FILE_SIZE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.util.file;
|
||||
|
||||
import com.onlyoffice.integration.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
|
||||
}
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.util.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.ConvertErrorType;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.dto.Convert;
|
||||
import com.onlyoffice.integration.dto.ConvertedData;
|
||||
import lombok.SneakyThrows;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
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;
|
||||
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.CONVERTATION_ERROR_MESSAGE_TEMPLATE;
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.CONVERT_TIMEOUT_MS;
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.FULL_LOADING_IN_PERCENT;
|
||||
import static com.onlyoffice.integration.documentserver.util.Constants.MAX_KEY_LENGTH;
|
||||
|
||||
// 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;
|
||||
|
||||
@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
|
||||
convertTimeout = timeout > 0 ? timeout : CONVERT_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String postToServer(final Convert body, final 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(documentJwtHeader.isBlank()
|
||||
? "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
|
||||
}
|
||||
|
||||
int statusCode = connection.getResponseCode();
|
||||
if (statusCode != HttpStatus.OK.value()) { // checking status code
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Convertation service returned status: " + statusCode);
|
||||
}
|
||||
|
||||
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 ConvertedData getConvertedData(final String documentUri, final String fromExtension,
|
||||
final String toExtension, final String documentRevisionId,
|
||||
final String filePass, final Boolean isAsync, final String lang) {
|
||||
// check if the fromExtension parameter is defined; if not, get it from the document url
|
||||
String fromExt = 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;
|
||||
|
||||
String documentRevId = documentRevisionId == null || documentRevisionId.isEmpty()
|
||||
? documentUri : documentRevisionId;
|
||||
|
||||
documentRevId = generateRevisionId(documentRevId); // 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(fromExt.replace(".", ""));
|
||||
body.setTitle(title);
|
||||
body.setKey(documentRevId);
|
||||
body.setFilePass(filePass);
|
||||
if (isAsync) {
|
||||
body.setAsync(true);
|
||||
}
|
||||
|
||||
String headerToken = "";
|
||||
if (jwtManager.tokenEnabled() && jwtManager.tokenUseForRequest()) {
|
||||
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 getResponseData(jsonString);
|
||||
}
|
||||
|
||||
// generate document key
|
||||
public String generateRevisionId(final String expectedKey) {
|
||||
/* if the expected key length is greater than 20
|
||||
then he expected key is hashed and a fixed length value is stored in the string format */
|
||||
String formatKey = expectedKey.length() > MAX_KEY_LENGTH
|
||||
? Integer.toString(expectedKey.hashCode()) : expectedKey;
|
||||
String key = formatKey.replace("[^0-9-.a-zA-Z_=]", "_");
|
||||
|
||||
return key.substring(0, Math.min(key.length(), MAX_KEY_LENGTH)); // the resulting key length is 20 or less
|
||||
}
|
||||
|
||||
// todo: Replace with a registry (callbacks package for reference)
|
||||
// create an error message for an error code
|
||||
private void processConvertServiceResponceError(final int errorCode) {
|
||||
String errorMessage = CONVERTATION_ERROR_MESSAGE_TEMPLATE + ConvertErrorType.labelOfCode(errorCode);
|
||||
|
||||
throw new RuntimeException(errorMessage);
|
||||
}
|
||||
|
||||
// get the response URL
|
||||
@SneakyThrows
|
||||
private ConvertedData getResponseData(final String jsonString) {
|
||||
JSONObject jsonObj = convertStringToJSON(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;
|
||||
String responseFileType = null;
|
||||
ConvertedData convertedData = new ConvertedData("", "");
|
||||
|
||||
if (isEndConvert) { // if the conversion is completed
|
||||
resultPercent = FULL_LOADING_IN_PERCENT;
|
||||
responseUri = (String) jsonObj.get("fileUrl"); // get the file URL
|
||||
responseFileType = (String) jsonObj.get("fileType"); // get the file type
|
||||
convertedData.setUri(responseUri);
|
||||
convertedData.setFileType(responseFileType);
|
||||
} else { // if the conversion isn't completed
|
||||
resultPercent = (Long) jsonObj.get("percent");
|
||||
|
||||
// get the percentage value of the conversion process
|
||||
resultPercent = resultPercent >= FULL_LOADING_IN_PERCENT ? FULL_LOADING_IN_PERCENT - 1 : resultPercent;
|
||||
}
|
||||
|
||||
return convertedData;
|
||||
}
|
||||
|
||||
// convert stream to string
|
||||
@SneakyThrows
|
||||
public String convertStreamToString(final InputStream stream) {
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(stream); // create an object to get incoming stream
|
||||
StringBuilder stringBuilder = new StringBuilder(); // create a string builder object
|
||||
|
||||
// create an object to read incoming streams
|
||||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
|
||||
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;
|
||||
}
|
||||
|
||||
// convert string to json
|
||||
@SneakyThrows
|
||||
public JSONObject convertStringToJSON(final String jsonString) {
|
||||
Object obj = parser.parse(jsonString); // parse json string
|
||||
JSONObject jsonObj = (JSONObject) obj; // and turn it into a json object
|
||||
|
||||
return jsonObj;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.documentserver.util.service;
|
||||
|
||||
import com.onlyoffice.integration.dto.ConvertedData;
|
||||
import org.json.simple.JSONObject;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
// specify the converter service functions
|
||||
public interface ServiceConverter {
|
||||
ConvertedData getConvertedData(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
|
||||
JSONObject convertStringToJSON(String jsonString); // convert string to json
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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.onlyoffice.integration.documentserver.models.enums.Action type;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChangesHistory {
|
||||
private String created;
|
||||
private ChangesUser user;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChangesUser {
|
||||
private String id;
|
||||
private String name;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ConvertedData {
|
||||
private String uri;
|
||||
private String fileType;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.onlyoffice.integration.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;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public class Mentions {
|
||||
private String name;
|
||||
private String email;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.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;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.entities;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import java.io.Serializable;
|
||||
|
||||
@MappedSuperclass
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Setter
|
||||
@Getter
|
||||
public abstract class AbstractEntity implements Serializable {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private int id;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.entities;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "`group`")
|
||||
@Getter
|
||||
@Setter
|
||||
public class Group extends AbstractEntity {
|
||||
@Column(unique = true)
|
||||
private String name;
|
||||
@OneToMany(mappedBy = "group")
|
||||
private List<User> users;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.entities;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "`permission`")
|
||||
@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;
|
||||
private Boolean protect = true;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.entities;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "`user`")
|
||||
@Getter
|
||||
@Setter
|
||||
public class User extends AbstractEntity {
|
||||
private String name;
|
||||
private String email;
|
||||
private Boolean favorite;
|
||||
@ManyToOne
|
||||
private Group group;
|
||||
@OneToOne
|
||||
private Permission permissions;
|
||||
// @Column(columnDefinition = "CLOB")
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "user_descriptions")
|
||||
private List<String> descriptions;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.mappers;
|
||||
|
||||
import com.onlyoffice.integration.entities.AbstractEntity;
|
||||
import com.onlyoffice.integration.documentserver.models.AbstractModel;
|
||||
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
|
||||
private ModelMapper mapper;
|
||||
|
||||
private Class<M> modelClass;
|
||||
|
||||
AbstractMapper(final Class<M> modelClassParam) {
|
||||
this.modelClass = modelClassParam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public M toModel(final 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(final E source, final M destination) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.mappers;
|
||||
|
||||
import com.onlyoffice.integration.entities.AbstractEntity;
|
||||
import com.onlyoffice.integration.documentserver.models.AbstractModel;
|
||||
|
||||
// specify the model mapper functions
|
||||
public interface Mapper<E extends AbstractEntity, M extends AbstractModel> {
|
||||
M toModel(E entity); // convert the entity to the model
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.mappers;
|
||||
|
||||
import com.onlyoffice.integration.entities.Permission;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.CommentGroup;
|
||||
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;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Primary
|
||||
public class PermissionsMapper extends AbstractMapper<Permission,
|
||||
com.onlyoffice.integration.documentserver.models.filemodel.Permission> {
|
||||
@Autowired
|
||||
private ModelMapper mapper;
|
||||
|
||||
public PermissionsMapper() {
|
||||
super(com.onlyoffice.integration.documentserver.models.filemodel.Permission.class);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void configure() { // configure the permission mapper
|
||||
mapper.createTypeMap(Permission.class, com.onlyoffice.integration.documentserver.models.filemodel
|
||||
.Permission.class) // create the type map
|
||||
.setPostConverter(modelConverter()); // and apply the post converter to it
|
||||
}
|
||||
|
||||
@Override
|
||||
void handleSpecificFields(final Permission source,
|
||||
final com.onlyoffice.integration.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
|
||||
|
||||
// set the commentGroups parameter
|
||||
destination.setCommentGroups(
|
||||
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()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.mappers;
|
||||
|
||||
import com.onlyoffice.integration.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.onlyoffice.integration.documentserver.models.filemodel.User> {
|
||||
@Autowired
|
||||
private ModelMapper mapper;
|
||||
|
||||
public UsersMapper() {
|
||||
super(com.onlyoffice.integration.documentserver.models.filemodel.User.class);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void configure() { // configure the users mapper
|
||||
mapper.createTypeMap(User.class, com.onlyoffice.integration.documentserver.models.filemodel
|
||||
.User.class) // create the type map
|
||||
.setPostConverter(modelConverter()); // and apply the post converter to it
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSpecificFields(final User source,
|
||||
final com.onlyoffice.integration.documentserver.models.filemodel
|
||||
.User destination) { // handle specific users fields
|
||||
destination.setGroup(source.getGroup() != null
|
||||
? source.getGroup().getName() : null); // set the Group parameter
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.repositories;
|
||||
|
||||
import com.onlyoffice.integration.entities.Group;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface GroupRepository extends JpaRepository<Group, Integer> {
|
||||
Optional<Group> findGroupByName(String name);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.repositories;
|
||||
|
||||
import com.onlyoffice.integration.entities.Permission;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface PermissionRepository extends JpaRepository<Permission, Integer> {
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.repositories;
|
||||
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Integer> {
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services;
|
||||
|
||||
import com.onlyoffice.integration.entities.Group;
|
||||
import com.onlyoffice.integration.repositories.GroupRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
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(final 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(final List<String> reviewGroups) {
|
||||
if (reviewGroups == null) {
|
||||
return null; // check if the reviewGroups permission exists
|
||||
}
|
||||
// convert this parameter to a list of groups whose changes the user can accept/reject
|
||||
return reviewGroups.stream()
|
||||
.map(group -> createGroup(group))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services;
|
||||
|
||||
import com.onlyoffice.integration.entities.Group;
|
||||
import com.onlyoffice.integration.entities.Permission;
|
||||
import com.onlyoffice.integration.repositories.PermissionRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class PermissionServices {
|
||||
|
||||
@Autowired
|
||||
private PermissionRepository permissionRepository;
|
||||
|
||||
// create permissions with the specified parameters
|
||||
public Permission createPermission(final List<Group> reviewGroups,
|
||||
final List<Group> commentViewGroups,
|
||||
final List<Group> commentEditGroups,
|
||||
final List<Group> commentRemoveGroups,
|
||||
final List<Group> userInfoGroups,
|
||||
final Boolean chat,
|
||||
final Boolean protect) {
|
||||
|
||||
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);
|
||||
permission.setProtect(protect);
|
||||
|
||||
permissionRepository.save(permission); // save new permissions
|
||||
|
||||
return permission;
|
||||
}
|
||||
|
||||
// update permissions
|
||||
public Permission updatePermission(final Permission newPermission) {
|
||||
permissionRepository.save(newPermission); // save new permissions
|
||||
|
||||
return newPermission;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services;
|
||||
|
||||
import com.onlyoffice.integration.entities.Group;
|
||||
import com.onlyoffice.integration.entities.Permission;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.repositories.UserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// get a user by their ID
|
||||
public Optional<User> findUserById(final Integer id) {
|
||||
return userRepository.findById(id);
|
||||
}
|
||||
|
||||
// create a user with the specified parameters
|
||||
public User createUser(final String name, final String email,
|
||||
final List<String> description, final String group,
|
||||
final List<String> reviewGroups,
|
||||
final List<String> viewGroups,
|
||||
final List<String> editGroups,
|
||||
final List<String> removeGroups,
|
||||
final List<String> userInfoGroups, final Boolean favoriteDoc,
|
||||
final Boolean chat,
|
||||
final Boolean protect) {
|
||||
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,
|
||||
protect); // specify permissions for the current user
|
||||
newUser.setPermissions(permission);
|
||||
|
||||
userRepository.save(newUser); // save a new user
|
||||
|
||||
return newUser;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers;
|
||||
|
||||
public interface Configurer<O, W> {
|
||||
void configure(O instance, W wrapper);
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Customization;
|
||||
|
||||
public interface CustomizationConfigurer<W> extends Configurer<Customization, W> {
|
||||
void configure(Customization customization, W wrapper);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Document;
|
||||
|
||||
public interface DocumentConfigurer<W> extends Configurer<Document, W> {
|
||||
void configure(Document document, W wrapper);
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.EditorConfig;
|
||||
|
||||
public interface EditorConfigConfigurer<W> extends Configurer<EditorConfig, W> {
|
||||
void configure(EditorConfig editorConfig, W wrapper);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Embedded;
|
||||
|
||||
public interface EmbeddedConfigurer<W> extends Configurer<Embedded, W> {
|
||||
void configure(Embedded embedded, W wrapper);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.FileModel;
|
||||
|
||||
public interface FileConfigurer<W> extends Configurer<FileModel, W> {
|
||||
void configure(FileModel model, W wrapper);
|
||||
FileModel getFileModel(W wrapper);
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Customization;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.services.configurers.CustomizationConfigurer;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultCustomizationWrapper;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Primary
|
||||
public class DefaultCustomizationConfigurer implements CustomizationConfigurer<DefaultCustomizationWrapper> {
|
||||
@Override
|
||||
// define the customization configurer
|
||||
public void configure(final Customization customization, final DefaultCustomizationWrapper wrapper) {
|
||||
Action action = wrapper.getAction(); // get the action parameter from the customization wrapper
|
||||
User user = wrapper.getUser();
|
||||
customization.setSubmitForm(false); // set the submitForm parameter to the customization config
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.implementations;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Document;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Permission;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.services.configurers.DocumentConfigurer;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultDocumentWrapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.documentserver.util.service.ServiceConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetAddress;
|
||||
import java.util.HashMap;
|
||||
|
||||
@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(final Document document,
|
||||
final 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
|
||||
|
||||
// set the URL to download a file to the document config
|
||||
document.setUrl(documentManager.getDownloadUrl(fileName, true));
|
||||
document.setUrlUser(documentManager
|
||||
.getFileUri(fileName, false)); // set the file URL to the document config
|
||||
document.setDirectUrl(wrapper.getIsEnableDirectUrl() ? documentManager
|
||||
.getDownloadUrl(fileName, false) : "");
|
||||
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
|
||||
|
||||
// get the document key
|
||||
String key = serviceConverter
|
||||
.generateRevisionId(storagePathBuilder.getStorageLocation()
|
||||
+ "/" + fileName + "/"
|
||||
+ new File(storagePathBuilder.getFileLocation(fileName)).lastModified());
|
||||
|
||||
Gson gson = new Gson();
|
||||
HashMap<String, String> fileKey = new HashMap<>();
|
||||
fileKey.put("fileName", fileName);
|
||||
try {
|
||||
fileKey.put("userAddress", InetAddress.getLocalHost().getHostAddress());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
HashMap<String, Object> referenceData = new HashMap<>();
|
||||
referenceData.put("instanceId", storagePathBuilder.getServerUrl(true));
|
||||
referenceData.put("fileKey", gson.toJson(fileKey));
|
||||
|
||||
document.setKey(key); // set the key to the document config
|
||||
document.setPermissions(permission); // set the permission parameters to the document config
|
||||
document.setReferenceData(referenceData);
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.implementations;
|
||||
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.documentserver.managers.template.TemplateManager;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.mappers.Mapper;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Mode;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.EditorConfig;
|
||||
import com.onlyoffice.integration.services.configurers.EditorConfigConfigurer;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultCustomizationWrapper;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultEmbeddedWrapper;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultFileWrapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
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.onlyoffice.integration.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(final EditorConfig config,
|
||||
final DefaultFileWrapper wrapper) { // define the editorConfig configurer
|
||||
if (wrapper.getActionData() != null) { // check if the actionData is not empty in the editorConfig wrapper
|
||||
|
||||
// set actionLink to the editorConfig
|
||||
config.setActionLink(objectMapper.readValue(wrapper.getActionData(),
|
||||
(JavaType) new TypeToken<HashMap<String, Object>>() { }.getType()));
|
||||
}
|
||||
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
|
||||
|
||||
// set a template to the editorConfig if the user is not anonymous
|
||||
config.setTemplates(userIsAnon ? null : templateManager.createTemplates(fileName));
|
||||
config.setCallbackUrl(documentManager.getCallback(fileName)); // set the callback URL to the editorConfig
|
||||
|
||||
// set the document URL where it will be created to the editorConfig if the user is not anonymous
|
||||
config.setCreateUrl(userIsAnon ? null : documentManager.getCreateUrl(fileName, false));
|
||||
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());
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Embedded;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.ToolbarDocked;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import com.onlyoffice.integration.services.configurers.EmbeddedConfigurer;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultEmbeddedWrapper;
|
||||
import com.onlyoffice.integration.documentserver.managers.document.DocumentManager;
|
||||
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(final Embedded embedded,
|
||||
final 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
|
||||
|
||||
/* 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.setEmbedUrl(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.setSaveUrl(url);
|
||||
|
||||
/* set the shareURL parameter to the embedded config (the absolute URL
|
||||
that will allow other users to share this document) */
|
||||
embedded.setShareUrl(url);
|
||||
|
||||
/* set the top toolbarDocked parameter to the embedded config (the place for the
|
||||
embedded viewer toolbar, can be either top or bottom) */
|
||||
embedded.setToolbarDocked(ToolbarDocked.top);
|
||||
}
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.implementations;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.managers.jwt.JwtManager;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.DocumentType;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.FileModel;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Permission;
|
||||
import com.onlyoffice.integration.documentserver.util.file.FileUtility;
|
||||
import com.onlyoffice.integration.mappers.Mapper;
|
||||
import com.onlyoffice.integration.services.configurers.FileConfigurer;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultDocumentWrapper;
|
||||
import com.onlyoffice.integration.services.configurers.wrappers.DefaultFileWrapper;
|
||||
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.onlyoffice.integration.entities.Permission, Permission> mapper;
|
||||
|
||||
@Autowired
|
||||
private DefaultDocumentConfigurer defaultDocumentConfigurer;
|
||||
|
||||
@Autowired
|
||||
private DefaultEditorConfigConfigurer defaultEditorConfigConfigurer;
|
||||
|
||||
public void configure(final FileModel fileModel, final 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
|
||||
|
||||
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())
|
||||
.isEnableDirectUrl(wrapper.getIsEnableDirectUrl())
|
||||
.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
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileModel getFileModel(final DefaultFileWrapper wrapper) { // get file model
|
||||
FileModel fileModel = fileModelObjectFactory.getObject();
|
||||
configure(fileModel, wrapper); // and configure it
|
||||
return fileModel;
|
||||
}
|
||||
|
||||
private Permission updatePermissions(final Permission userPermissions, final Action action, final 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;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.wrappers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class DefaultCustomizationWrapper {
|
||||
private Action action;
|
||||
private User user;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.wrappers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.Permission;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.ReferenceData;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class DefaultDocumentWrapper {
|
||||
private Permission permission;
|
||||
private String fileName;
|
||||
private Boolean favorite;
|
||||
private Boolean isEnableDirectUrl;
|
||||
private ReferenceData referenceData;
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.wrappers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class DefaultEmbeddedWrapper {
|
||||
private Type type;
|
||||
private String fileName;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2023
|
||||
*
|
||||
* 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.onlyoffice.integration.services.configurers.wrappers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
@Setter
|
||||
public class DefaultFileWrapper {
|
||||
private String fileName;
|
||||
private Type type;
|
||||
private User user;
|
||||
private String lang;
|
||||
private Action action;
|
||||
private String actionData;
|
||||
private Boolean canEdit;
|
||||
private Boolean isEnableDirectUrl;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
server.version=1.7.0
|
||||
|
||||
server.address=172.16.0.152
|
||||
server.port=8080
|
||||
|
||||
filesize-max=5242880
|
||||
|
||||
files.storage=5242880
|
||||
files.storage.folder=documents
|
||||
|
||||
files.docservice.fillforms-docs=.docx|.oform
|
||||
files.docservice.viewed-docs=.djvu|.oxps|.pdf|.xps
|
||||
files.docservice.edited-docs=.csv|.docm|.docx|.docxf|.dotm|.dotx|.epub|.fb2|.html|.odp|.ods|.odt|.otp|.ots|.ott|.potm|.potx|.ppsm|.ppsx|.pptm|.pptx|.rtf|.txt|.xlsm|.xlsx|.xltm|.xltx
|
||||
files.docservice.convert-docs=.doc|.dot|.dps|.dpt|.epub|.et|.ett|.fb2|.fodp|.fods|.fodt|.htm|.html|.mht|.mhtml|.odp|.ods|.odt|.otp|.ots|.ott|.pot|.pps|.ppt|.rtf|.stw|.sxc|.sxi|.sxw|.wps|.wpt|.xls|.xlsb|.xlt|.xml
|
||||
files.docservice.timeout=120000
|
||||
files.docservice.history.postfix=-hist
|
||||
|
||||
files.docservice.url.site=http://121.40.189.20:8009
|
||||
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.secret=
|
||||
files.docservice.header=Authorization
|
||||
files.docservice.token-use-for-request=true
|
||||
|
||||
files.docservice.verify-peer-off=true
|
||||
|
||||
files.docservice.languages=en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (Simplified)|zh-TW:Chinese (Traditional)|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|lo:Lao|lv:Latvian|ms:Malay (Malaysia)|no:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|si:Sinhala (Sri Lanka)|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language
|
||||
|
||||
spring.datasource.url=jdbc:h2:mem:usersdb
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=password
|
||||
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||
hibernate.ddl-auto
|
||||
spring.h2.console.enabled=true
|
||||
spring.h2.console.path=/h2
|
||||
spring.servlet.multipart.max-file-size=5MB
|
||||
spring.servlet.multipart.max-request-size=5MB
|
||||
|
||||
url.index=/
|
||||
url.converter=/converter
|
||||
url.editor=/editor
|
||||
url.track=/track
|
||||
url.download=/download
|
||||
|
||||
logo.image=
|
||||
logo.imageEmbedded=
|
||||
logo.url=https://www.onlyoffice.com
|
||||
@@ -0,0 +1,4 @@
|
||||
# Authors
|
||||
|
||||
* Ascensio System SIA: <integration@onlyoffice.com>
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,8 @@
|
||||
## Overview
|
||||
|
||||
Template files used to create new documents and documents with sample content in:
|
||||
|
||||
* [Document Server integration example](https://github.com/ONLYOFFICE/document-server-integration)
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user