From 043cdd95b37200254a9b9ca2aaadc88979c62599 Mon Sep 17 00:00:00 2001 From: yizhaorong <243653385@qq.com> Date: Sun, 7 Jun 2020 22:27:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=96=87=E4=BB=B6=E5=AD=98?= =?UTF-8?q?=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/yzr/controller/AppController.java | 26 ++-- .../org/yzr/controller/PackageController.java | 115 +++++++---------- .../org/yzr/controller/UserController.java | 4 + src/main/java/org/yzr/dao/PermissionDao.java | 8 +- src/main/java/org/yzr/dao/RoleDao.java | 4 +- src/main/java/org/yzr/model/App.java | 2 +- src/main/java/org/yzr/service/AppService.java | 46 +++++-- .../java/org/yzr/service/PackageService.java | 119 +++++++++++++----- .../java/org/yzr/service/UserService.java | 53 +++++--- .../java/org/yzr/storage/StorageUtil.java | 49 ++------ .../java/org/yzr/utils/file/PathManager.java | 79 ++++-------- .../yzr/utils/webhook/DingDingWebHook.java | 4 +- src/main/java/org/yzr/vo/AppViewModel.java | 27 ++-- .../java/org/yzr/vo/PackageViewModel.java | 19 +-- src/main/resources/application.properties | 4 +- src/main/resources/templates/index.html | 12 +- src/main/resources/templates/install.html | 2 +- src/main/resources/templates/list.html | 4 +- 18 files changed, 311 insertions(+), 266 deletions(-) diff --git a/src/main/java/org/yzr/controller/AppController.java b/src/main/java/org/yzr/controller/AppController.java index a1f7c1a..8870598 100644 --- a/src/main/java/org/yzr/controller/AppController.java +++ b/src/main/java/org/yzr/controller/AppController.java @@ -5,10 +5,7 @@ import org.apache.shiro.authz.annotation.RequiresAuthentication; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import org.yzr.model.User; import org.yzr.service.AppService; import org.yzr.utils.file.PathManager; @@ -36,9 +33,9 @@ public class AppController { try { Subject currentUser = SecurityUtils.getSubject(); User user = (User) currentUser.getPrincipal(); - List apps = this.appService.findByUser(user); + List apps = this.appService.findByUser(user, request); request.setAttribute("apps", apps); - request.setAttribute("baseURL", this.pathManager.getBaseURL(false)); + request.setAttribute("baseURL", PathManager.request(request).getBaseURL()); } catch (Exception e) { e.printStackTrace(); } @@ -49,7 +46,9 @@ public class AppController { @RequiresPermissions("/apps/get") @GetMapping("/apps/{appID}") public String getAppById(@PathVariable("appID") String appID, HttpServletRequest request) { - AppViewModel appViewModel = this.appService.getById(appID); + Subject currentUser = SecurityUtils.getSubject(); + User user = (User) currentUser.getPrincipal(); + AppViewModel appViewModel = this.appService.getById(appID, user, request); request.setAttribute("package", appViewModel); request.setAttribute("apps", appViewModel.getPackageList()); return "list"; @@ -58,8 +57,10 @@ public class AppController { @RequiresPermissions("/packageList/get") @RequestMapping("/packageList/{appID}") @ResponseBody - public Map getAppPackageList(@PathVariable("appID") String appID) { - AppViewModel appViewModel = this.appService.getById(appID); + public Map getAppPackageList(@PathVariable("appID") String appID, HttpServletRequest request) { + Subject currentUser = SecurityUtils.getSubject(); + User user = (User) currentUser.getPrincipal(); + AppViewModel appViewModel = this.appService.getById(appID, user, request); Map map = new HashMap<>(); try { map.put("packages", appViewModel.getPackageList()); @@ -70,23 +71,24 @@ public class AppController { return map; } - @RequiresPermissions("/app/delete") +// @RequiresPermissions("/app/delete") @RequestMapping("/app/delete/{id}") @ResponseBody - public BaseResponse deleteById(@PathVariable("id") String id) { + public BaseResponse deleteById(@PathVariable("id") String id, HttpServletRequest request) { try { Subject currentUser = SecurityUtils.getSubject(); User user = (User) currentUser.getPrincipal(); if (user == null) { return ResponseUtil.unauthz(); } - AppViewModel viewModel = this.appService.getById(id); + AppViewModel viewModel = this.appService.getById(id, user, request); if (viewModel.getUserId().equals(user.getId())) { this.appService.deleteById(id); return ResponseUtil.ok("删除成功"); } return ResponseUtil.unauthz(); } catch (Exception e) { + e.printStackTrace(); return ResponseUtil.fail(); } } diff --git a/src/main/java/org/yzr/controller/PackageController.java b/src/main/java/org/yzr/controller/PackageController.java index fd82c8a..5c5722e 100644 --- a/src/main/java/org/yzr/controller/PackageController.java +++ b/src/main/java/org/yzr/controller/PackageController.java @@ -7,6 +7,9 @@ import org.apache.commons.io.FilenameUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; @@ -50,6 +53,10 @@ public class PackageController { private PathManager pathManager; @Resource private UserService userService; + @Resource + private StorageUtil storageUtil; + @Resource + private StorageService storageService; /** * 预览页 @@ -61,10 +68,10 @@ public class PackageController { @GetMapping("/s/{code}") public String get(@PathVariable("code") String code, HttpServletRequest request) { String id = request.getParameter("id"); - AppViewModel viewModel = this.appService.findByCode(code, id); + AppViewModel viewModel = this.appService.findByCode(code, id, request); request.setAttribute("app", viewModel); - request.setAttribute("ca_path", this.pathManager.getCAPath()); - request.setAttribute("basePath", this.pathManager.getBaseURL(false)); + request.setAttribute("ca_path", PathManager.request(request).getCAPath()); + request.setAttribute("basePath", PathManager.request(request).getBaseURL() + "/"); return "install"; } @@ -77,7 +84,7 @@ public class PackageController { */ @GetMapping("/devices/{id}") public String devices(@PathVariable("id") String id, HttpServletRequest request) { - PackageViewModel viewModel = this.packageService.findById(id); + PackageViewModel viewModel = this.packageService.findById(id, request); request.setAttribute("app", viewModel); return "devices"; } @@ -112,17 +119,16 @@ public class PackageController { Subject currentUser = SecurityUtils.getSubject(); user = (User) currentUser.getPrincipal(); } - // 无用户信息不允许上传 if (user == null) { return ResponseUtil.unauthz(); } - String filePath = StorageUtil.checkAndTransfer(file.getInputStream(), file.getSize(), file.getContentType(), file.getOriginalFilename()); + // 检测文件 + String filePath = storageUtil.checkAndTransfer(file.getInputStream(), file.getContentType(), file.getOriginalFilename()); if (filePath == null) { return ResponseUtil.fail(401, "不支持的文件类型"); } - - Package aPackage = this.packageService.buildPackage(filePath, user); + // 获取扩展参数 Map extra = new HashMap<>(); String jobName = request.getParameter("jobName"); String buildNumber = request.getParameter("buildNumber"); @@ -132,15 +138,13 @@ public class PackageController { if (StringUtils.hasLength(buildNumber)) { extra.put("buildNumber", buildNumber); } - if (!extra.isEmpty()) { - aPackage.setExtra(JSON.toJSONString(extra)); - } - App app = this.appService.savePackage(aPackage, user); - // URL - String codeURL = this.pathManager.getBaseURL(false) + "p/code/" + app.getCurrentPackage().getId(); - // 发送WebHook消息 - WebHookClient.sendMessage(app, pathManager); - return ResponseUtil.ok(codeURL); + Package aPackage = this.packageService.save(filePath, extra, user); +// App app = this.appService.savePackage(aPackage, user); +// // URL +// String codeURL = this.pathManager.getBaseURL(false) + "p/code/" + app.getCurrentPackage().getId(); +// // 发送WebHook消息 +// WebHookClient.sendMessage(app, pathManager); + return ResponseUtil.ok(); } catch (Exception e) { e.printStackTrace(); return ResponseUtil.badArgument(); @@ -154,34 +158,34 @@ public class PackageController { * @param response */ @RequestMapping("/p/{id}") - public void download(@PathVariable("id") String id, HttpServletResponse response) { + public ResponseEntity download(@PathVariable("id") String id, HttpServletResponse response) { try { Package aPackage = this.packageService.get(id); - String path = PathManager.getFullPath(aPackage) + aPackage.getFileName(); - File file = new File(path); - if (file.exists()) { //判断文件父目录是否存在 - response.setContentType("application/force-download"); - // 文件名称转换 - String fileName = aPackage.getName() + "_" + aPackage.getVersion(); - String ext = "." + FilenameUtils.getExtension(aPackage.getFileName()); - String appName = new String(fileName.getBytes("UTF-8"), "iso-8859-1"); - response.setHeader("Content-Disposition", "attachment;fileName=" + appName + ext); - - byte[] buffer = new byte[1024]; - OutputStream os = response.getOutputStream(); - FileInputStream fis = new FileInputStream(file); - BufferedInputStream bis = new BufferedInputStream(fis); - int i = bis.read(buffer); - while (i != -1) { - os.write(buffer); - i = bis.read(buffer); - } - bis.close(); - fis.close(); + String key = aPackage.getSourceFile().getKey(); + Storage storage = storageService.findByKey(key); + if (key == null) { + return ResponseEntity.notFound().build(); } + if (key.contains("../")) { + return ResponseEntity.badRequest().build(); + } + String type = storage.getType(); + MediaType mediaType = MediaType.parseMediaType(type); + + org.springframework.core.io.Resource file = storageUtil.loadAsResource(key); + if (file == null) { + return ResponseEntity.notFound().build(); + } + // 文件名称转换 + String fileName = aPackage.getName() + "_" + aPackage.getVersion(); + String ext = "." + FilenameUtils.getExtension(aPackage.getFileName()); + String appName = new String(fileName.getBytes("UTF-8"), "iso-8859-1"); + return ResponseEntity.ok().contentType(mediaType).header(HttpHeaders.CONTENT_DISPOSITION, + "attachment; filename=\"" + appName + ext + "\"").body(file); } catch (Exception e) { e.printStackTrace(); } + return ResponseEntity.notFound().build(); } /** @@ -191,9 +195,9 @@ public class PackageController { * @param response */ @RequestMapping("/m/{id}") - public void getManifest(@PathVariable("id") String id, HttpServletResponse response) { + public void getManifest(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) { try { - PackageViewModel viewModel = this.packageService.findById(id); + PackageViewModel viewModel = this.packageService.findById(id, request); if (viewModel != null && viewModel.isiOS()) { response.setContentType("application/force-download"); response.setHeader("Content-Disposition", "attachment;fileName=manifest.plist"); @@ -212,9 +216,9 @@ public class PackageController { * @param response */ @RequestMapping("/p/code/{id}") - public void getQrCode(@PathVariable("id") String id, HttpServletResponse response) { + public void getQrCode(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) { try { - PackageViewModel viewModel = this.packageService.findById(id); + PackageViewModel viewModel = this.packageService.findById(id, request); if (viewModel != null) { response.setContentType("image/png"); QRCodeUtil.encode(viewModel.getPreviewURL()).withSize(250, 250).writeTo(response.getOutputStream()); @@ -244,29 +248,4 @@ public class PackageController { return map; } - /** - * 转存文件 - * - * @param srcFile - * @return - */ - private String transfer(MultipartFile srcFile) { - try { - - // 获取文件后缀 - String fileName = srcFile.getOriginalFilename(); - String ext = FilenameUtils.getExtension(fileName); - // 生成文件名 - String newFileName = UUID.randomUUID().toString() + "." + ext; - // 转存到 tmp - String destPath = FileUtils.getTempDirectoryPath() + File.separator + newFileName; - destPath = destPath.replaceAll("//", "/"); - srcFile.transferTo(new File(destPath)); - return destPath; - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - } diff --git a/src/main/java/org/yzr/controller/UserController.java b/src/main/java/org/yzr/controller/UserController.java index 0de2edf..f2b068d 100644 --- a/src/main/java/org/yzr/controller/UserController.java +++ b/src/main/java/org/yzr/controller/UserController.java @@ -72,6 +72,10 @@ public class UserController { if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) { return ResponseUtil.badArgument(); } + User u = this.userService.findByUsername(username); + if (u != null) { + return ResponseUtil.fail(100, username + "已被注册"); + } user = this.userService.createUser(username, password); return login(request, username, password); } diff --git a/src/main/java/org/yzr/dao/PermissionDao.java b/src/main/java/org/yzr/dao/PermissionDao.java index 4e3d381..638a7ac 100644 --- a/src/main/java/org/yzr/dao/PermissionDao.java +++ b/src/main/java/org/yzr/dao/PermissionDao.java @@ -1,9 +1,13 @@ package org.yzr.dao; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; import org.yzr.model.Permission; -import org.yzr.model.User; + +import java.util.List; public interface PermissionDao extends CrudRepository { - + @Query("select p from Permission p where p.permission=:permission and p.role.id=:roleId") + List findByPermission(@Param("permission") String permission, @Param("roleId") String roleId); } diff --git a/src/main/java/org/yzr/dao/RoleDao.java b/src/main/java/org/yzr/dao/RoleDao.java index 296caa5..2709c2b 100644 --- a/src/main/java/org/yzr/dao/RoleDao.java +++ b/src/main/java/org/yzr/dao/RoleDao.java @@ -5,7 +5,9 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.yzr.model.Role; +import java.util.List; + public interface RoleDao extends CrudRepository { @Query("select r from Role r where r.name=:name") - Role findByName(@Param("name") String name); + List findByName(@Param("name") String name); } diff --git a/src/main/java/org/yzr/model/App.java b/src/main/java/org/yzr/model/App.java index 162219f..e688872 100644 --- a/src/main/java/org/yzr/model/App.java +++ b/src/main/java/org/yzr/model/App.java @@ -39,7 +39,7 @@ public class App { // 当前包 @JoinColumn(name = "currentID", referencedColumnName = "id") private Package currentPackage; - @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY) @JoinColumn(name = "userId") private User owner; diff --git a/src/main/java/org/yzr/service/AppService.java b/src/main/java/org/yzr/service/AppService.java index fbf4abf..3e713d8 100644 --- a/src/main/java/org/yzr/service/AppService.java +++ b/src/main/java/org/yzr/service/AppService.java @@ -5,15 +5,19 @@ import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.yzr.dao.AppDao; import org.yzr.dao.PackageDao; +import org.yzr.dao.StorageDao; import org.yzr.dao.UserDao; import org.yzr.model.App; import org.yzr.model.Package; +import org.yzr.model.Storage; import org.yzr.model.User; +import org.yzr.storage.StorageUtil; import org.yzr.utils.CharUtil; import org.yzr.utils.file.PathManager; import org.yzr.vo.AppViewModel; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import javax.transaction.Transactional; import java.util.ArrayList; import java.util.List; @@ -29,6 +33,10 @@ public class AppService { private PackageDao packageDao; @Resource private PathManager pathManager; + @Resource + private StorageDao storageDao; + @Resource + private StorageUtil storageUtil; @Transactional public App save(App app, User user) { @@ -46,24 +54,32 @@ public class AppService { } @Transactional - public List findAll() { + public List findAll(HttpServletRequest request) { Iterable apps = this.appDao.findAll(); List list = new ArrayList<>(); for (App app : apps) { - AppViewModel appViewModel = new AppViewModel(app, this.pathManager, false); + AppViewModel appViewModel = new AppViewModel(app, request, false); list.add(appViewModel); } return list; } @Transactional - public AppViewModel getById(String appID) { + public AppViewModel getById(String appID, User user, HttpServletRequest request) { Optional optionalApp = this.appDao.findById(appID); App app = optionalApp.get(); + if (!app.getOwner().getId().equalsIgnoreCase(user.getId())) { + return null; + } + if (app != null) { app.getPackageList().forEach(aPackage -> { + try{ + aPackage.getSourceFile().getKey(); + aPackage.getIconFile().getKey(); + } catch (Exception e) {} }); - AppViewModel appViewModel = new AppViewModel(app, this.pathManager, true); + AppViewModel appViewModel = new AppViewModel(app, request, true); return appViewModel; } return null; @@ -87,7 +103,8 @@ public class AppService { // 级联查询 app.getPackageList().forEach(aPackage1 -> { }); - app.getWebHookList().forEach(webHook -> {}); + app.getWebHookList().forEach(webHook -> { + }); } app.setName(aPackage.getName()); app.getPackageList().add(aPackage); @@ -100,7 +117,18 @@ public class AppService { public void deleteById(String id) { App app = this.appDao.findById(id).get(); if (app != null) { + app.getPackageList().forEach(aPackage ->{ + Storage iconFile = aPackage.getIconFile(); + this.storageUtil.delete(iconFile.getKey()); + this.storageDao.deleteById(iconFile.getId()); + Storage sourceFile = aPackage.getSourceFile(); + this.storageUtil.delete(sourceFile.getKey()); + this.storageDao.deleteById(sourceFile.getId()); + this.packageDao.deleteById(aPackage.getId()); + }); this.appDao.deleteById(id); + + // 消除整个 APP 目录 String path = PathManager.getAppPath(app); PathManager.deleteDirectory(path); @@ -115,18 +143,18 @@ public class AppService { * @return */ @Transactional - public AppViewModel findByCode(String code, String packageId) { + public AppViewModel findByCode(String code, String packageId, HttpServletRequest request) { App app = this.appDao.findByShortCode(code); - AppViewModel viewModel = new AppViewModel(app, pathManager, packageId); + AppViewModel viewModel = new AppViewModel(app, request, packageId); return viewModel; } @Transactional - public List findByUser(User user) { + public List findByUser(User user, HttpServletRequest request) { Iterable apps = this.appDao.findByUser(user); List list = new ArrayList<>(); for (App app : apps) { - AppViewModel appViewModel = new AppViewModel(app, this.pathManager, false); + AppViewModel appViewModel = new AppViewModel(app, request, false); list.add(appViewModel); } return list; diff --git a/src/main/java/org/yzr/service/PackageService.java b/src/main/java/org/yzr/service/PackageService.java index 1f58731..0ec53c8 100644 --- a/src/main/java/org/yzr/service/PackageService.java +++ b/src/main/java/org/yzr/service/PackageService.java @@ -3,19 +3,31 @@ package org.yzr.service; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; +import org.yzr.dao.AppDao; import org.yzr.dao.PackageDao; +import org.yzr.dao.UserDao; import org.yzr.model.App; import org.yzr.model.Package; +import org.yzr.model.Storage; import org.yzr.model.User; +import org.yzr.storage.StorageUtil; +import org.yzr.utils.CharUtil; +import org.yzr.utils.file.FileType; import org.yzr.utils.file.PathManager; import org.yzr.utils.image.ImageUtils; import org.yzr.utils.parser.ParserClient; import org.yzr.vo.PackageViewModel; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import javax.transaction.Transactional; import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Map; +import java.util.UUID; @Service public class PackageService { @@ -24,38 +36,12 @@ public class PackageService { private PackageDao packageDao; @Resource private PathManager pathManager; - - public Package buildPackage(String filePath, User user) throws ClassNotFoundException { - Package aPackage = ParserClient.parse(filePath); - try { - App app = new App(); - app.setOwner(user); - aPackage.setApp(app); - - String fileName = aPackage.getPlatform() + "." + FilenameUtils.getExtension(filePath); - // 更新文件名 - aPackage.setFileName(fileName); - - String packagePath = PathManager.getFullPath(aPackage); - String tempIconPath = PathManager.getTempIconPath(aPackage); - String iconPath = packagePath + File.separator + "icon.png"; - String sourcePath = packagePath + File.separator + fileName; - - // 拷贝图标 - ImageUtils.resize(tempIconPath, iconPath, 192, 192); - // 源文件 - FileUtils.copyFile(new File(filePath), new File(sourcePath)); - - // 删除临时图标 - FileUtils.forceDelete(new File(tempIconPath)); - // 源文件 - FileUtils.forceDelete(new File(filePath)); - } catch (Exception e) { - e.printStackTrace(); - } - aPackage.setApp(null); - return aPackage; - } + @Resource + private UserDao userDao; + @Resource + private AppDao appDao; + @Resource + private StorageUtil storageUtil; @Transactional public Package save(Package aPackage) { @@ -67,13 +53,14 @@ public class PackageService { Package aPackage = this.packageDao.findById(id).get(); // 级联查询用户 aPackage.getApp().getOwner().getId(); + aPackage.getSourceFile().getKey(); return aPackage; } @Transactional - public PackageViewModel findById(String id) { + public PackageViewModel findById(String id, HttpServletRequest request) { Package aPackage = this.packageDao.findById(id).get(); - PackageViewModel viewModel = new PackageViewModel(aPackage, this.pathManager); + PackageViewModel viewModel = new PackageViewModel(aPackage, request); return viewModel; } @@ -87,4 +74,68 @@ public class PackageService { } } + @Transactional + public Package save(String filePath, Map extra, User user) throws Exception { + Package aPackage = ParserClient.parse(filePath); + String fileName = aPackage.getPlatform() + "." + FilenameUtils.getExtension(filePath); + // 更新文件名 + aPackage.setFileName(fileName); + // 获取用户信息 + user = this.userDao.findById(user.getId()).get(); + // 设置用户信息 + App app = this.appDao.getByBundleIDAndPlatformAndOwner(aPackage.getBundleID(), aPackage.getPlatform(), user); + if (app == null) { + app = new App(); + String shortCode = CharUtil.generate(4); + while (this.appDao.findByShortCode(shortCode) != null) { + shortCode = CharUtil.generate(4); + } + BeanUtils.copyProperties(aPackage, app); + app.setShortCode(shortCode); + app.setOwner(user); + } else { + // 级联查询 + app.getPackageList().forEach(aPackage1 -> { + }); + app.getWebHookList().forEach(webHook -> {}); + } + aPackage.setApp(app); + String packagePath = PathManager.getFullPath(aPackage); + String tempIconPath = PathManager.getTempIconPath(aPackage); + String sourcePath = packagePath + File.separator + fileName; + // 获取文件后缀 + String ext = FilenameUtils.getExtension(fileName); + // 生成文件名 + String newFileName = UUID.randomUUID().toString() + ".png"; + // 转存到 tmp + String iconPath = FileUtils.getTempDirectoryPath() + File.separator + newFileName; + iconPath = iconPath.replaceAll("//", "/"); + + // 拷贝图标 + ImageUtils.resize(tempIconPath, iconPath, 192, 192); + // 源文件 + FileUtils.copyFile(new File(filePath), new File(sourcePath)); + + // 删除临时图标 + FileUtils.forceDelete(new File(tempIconPath)); + // 源文件 + FileUtils.forceDelete(new File(filePath)); + File sourceFile = new File(sourcePath); + File iconFile = new File(iconPath); + Storage storage = storageUtil.store(new FileInputStream(sourceFile), sourceFile.length(), "application/octet-stream", fileName); + Storage iconStorage = storageUtil.store(new FileInputStream(iconFile), iconFile.length(), "application/x-png", iconFile.getName()); + // 删除临时图标 + FileUtils.forceDelete(sourceFile); + // 源文件 + FileUtils.forceDelete(iconFile); + aPackage.setIconFile(iconStorage); + aPackage.setSourceFile(storage); + aPackage = this.packageDao.save(aPackage); + + app.setName(aPackage.getName()); + app.getPackageList().add(aPackage); + app.setCurrentPackage(aPackage); + this.appDao.save(app); + return aPackage; + } } diff --git a/src/main/java/org/yzr/service/UserService.java b/src/main/java/org/yzr/service/UserService.java index 6ceb11e..569cc72 100644 --- a/src/main/java/org/yzr/service/UserService.java +++ b/src/main/java/org/yzr/service/UserService.java @@ -109,12 +109,15 @@ public class UserService { user.setPassword(encoder.encode(password)); user.setCreateTime(System.currentTimeMillis()); - Role role = this.roleDao.findByName("管理员"); - Set roleList = new HashSet<>(); - roleList.add(role); - user.setRoleList(roleList); - updateToken(user); - this.userDao.save(user); + List adminList = this.roleDao.findByName("管理员"); + if (adminList != null && adminList.size() > 0) { + Role role = adminList.get(0); + Set roleList = new HashSet<>(); + roleList.add(role); + user.setRoleList(roleList); + updateToken(user); + this.userDao.save(user); + } return user; } @@ -125,22 +128,38 @@ public class UserService { if (this.userDao.findByUsername(username) == null) { long currentTime = System.currentTimeMillis(); Role role = new Role(); - role.setCreateTime(currentTime); - role.setDescription("管理员"); - role.setName("管理员"); - role.setEnabled(true); - this.roleDao.save(role); - + List adminList = this.roleDao.findByName("管理员"); + if (adminList != null && adminList.size() > 0) { + role = adminList.get(0); + } else { + role.setCreateTime(currentTime); + role.setDescription("管理员"); + role.setName("管理员"); + role.setEnabled(true); + this.roleDao.save(role); + } List permissionList = new ArrayList<>(); String[] perms = new String[]{ "/apps", "/apps/get", -// "/apps/delete", + "/apps/delete", "/packageList/get" }; for (String string : perms) { - Permission permission = new Permission(); - permission.setCreateTime(currentTime); + Permission permission = null; + List permissions = this.permissionDao.findByPermission(string, role.getId()); + if (permissions != null) { + for (int i = 0; i < permissions.size(); i++) { + if (permissions.get(i).getRole().getId().equalsIgnoreCase(role.getId())) { + permission = permissions.get(i); + break; + } + } + } + if (permission == null) { + permission = new Permission(); + permission.setCreateTime(currentTime); + } permission.setPermission(string); permission.setUpdateTime(currentTime); permission.setRole(role); @@ -162,4 +181,8 @@ public class UserService { this.userDao.save(user); } } + + public User findByUsername(String username) { + return this.userDao.findByUsername(username); + } } diff --git a/src/main/java/org/yzr/storage/StorageUtil.java b/src/main/java/org/yzr/storage/StorageUtil.java index 6eb6be7..62edd17 100644 --- a/src/main/java/org/yzr/storage/StorageUtil.java +++ b/src/main/java/org/yzr/storage/StorageUtil.java @@ -4,6 +4,7 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import org.yzr.model.Storage; import org.yzr.utils.CharUtil; @@ -49,27 +50,12 @@ public class StorageUtil { /** * 检测并转存文件 * @param inputStream - * @param contentLength * @param contentType * @param fileName * @return */ - public static String checkAndTransfer(InputStream inputStream, long contentLength, String contentType, String fileName) { - // 判断文件类型 - if (!(contentType != null && contentType.equalsIgnoreCase("application/octet-stream"))) { - return null; - } - int len = 28; - PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream, len); + public String checkAndTransfer(InputStream inputStream, String contentType, String fileName) { try { - byte[] b = new byte[len]; - FileType type = FileUtil.getType(pushbackInputStream); - // ipa和apk文件都是zip文件 - if (type != FileType.ZIP) { - pushbackInputStream.close(); - return null; - } - pushbackInputStream.unread(b); // 获取文件后缀 String ext = FilenameUtils.getExtension(fileName); // 生成文件名 @@ -77,8 +63,14 @@ public class StorageUtil { // 转存到 tmp String destPath = FileUtils.getTempDirectoryPath() + File.separator + newFileName; destPath = destPath.replaceAll("//", "/"); - System.out.println(destPath); - Files.copy(pushbackInputStream, Paths.get(destPath), StandardCopyOption.REPLACE_EXISTING); + Files.copy(inputStream, Paths.get(destPath), StandardCopyOption.REPLACE_EXISTING); + FileType type = FileUtil.getType(destPath); + // ipa和apk文件都是zip文件 + if (type != FileType.ZIP) { + // 删除文件 + FileUtils.forceDelete(new File(destPath)); + return null; + } return destPath; } catch (Exception e) { e.printStackTrace(); @@ -95,27 +87,8 @@ public class StorageUtil { * @param fileName 文件索引名 */ public Storage store(InputStream inputStream, long contentLength, String contentType, String fileName) { - // 判断文件类型 - if (!(contentType != null && contentType.equalsIgnoreCase("application/octet-stream"))) { - return null; - } String key = generateKey(fileName); - int len = 28; - PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream, len); - try { - byte[] b = new byte[len]; - FileType type = FileUtil.getType(pushbackInputStream); - // ipa和apk文件都是zip文件 - if (type != FileType.ZIP) { - pushbackInputStream.close(); - return null; - } - pushbackInputStream.unread(b); - } catch (Exception e) { - e.printStackTrace(); - } - - storage.store(pushbackInputStream, contentLength, contentType, key); + storage.store(inputStream, contentLength, contentType, key); String url = generateUrl(key); Storage storageInfo = new Storage(); diff --git a/src/main/java/org/yzr/utils/file/PathManager.java b/src/main/java/org/yzr/utils/file/PathManager.java index 47c97e4..21261b9 100644 --- a/src/main/java/org/yzr/utils/file/PathManager.java +++ b/src/main/java/org/yzr/utils/file/PathManager.java @@ -8,6 +8,7 @@ import org.yzr.model.App; import org.yzr.model.Package; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import java.io.File; import java.net.InetAddress; @@ -18,6 +19,23 @@ public class PathManager { private Environment environment; private String httpsBaseURL; private String httpBaseURL; + private String host; + private String scheme = "http"; + + public static PathManager request(HttpServletRequest request) { + PathManager pathManager = new PathManager(); + pathManager.host = request.getHeader("host"); + return pathManager; + } + + public PathManager useHttps() { + this.scheme = "https"; + return this; + } + + public String getBaseURL() { + return this.scheme + "://" + this.host; + } /** * 获取图标的临时路径 @@ -110,55 +128,6 @@ public class PathManager { } } - /** - * 获取基础路径 - * - * @param isHttps - * @return - */ - public String getBaseURL(boolean isHttps) { - if (isHttps) { - if (httpsBaseURL != null) { - return httpsBaseURL; - } - } else { - if (httpBaseURL != null) { - return httpBaseURL; - } - } - - try { - // URL - InetAddress address = InetAddress.getLocalHost(); - String domain = environment.getProperty("server.domain"); - if (domain == null) { - domain = address.getHostAddress(); - } - int httpPort = Integer.parseInt(environment.getProperty("server.http.port")); - int httpsPort = Integer.parseInt(environment.getProperty("server.port")); - int port = isHttps ? httpsPort : httpPort; - String protocol = isHttps ? "https" : "http"; - String portString = ":" + port; - if (port == 80 || port == 443) { - portString = ""; - } - - String baseURL = protocol + "://" + domain + portString + "/"; - - //解决重复读配置文件 - if (isHttps) { - httpsBaseURL = baseURL; - } else { - httpBaseURL = baseURL; - } - - return baseURL; - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - /** * 获取包所在路径 * @@ -167,10 +136,12 @@ public class PathManager { * @return */ public String getPackageResourceURL(Package aPackage, boolean isHttps) { - String baseURL = getBaseURL(isHttps); - String resourceURL = baseURL + aPackage.getPlatform() + "/" + aPackage.getBundleID() - + "/" + aPackage.getCreateTime() + "/"; - return resourceURL; +// getBaseURL() + "/fetch/" + aPackage.getSourceFile().getKey(); +// String baseURL = getBaseURL(isHttps); +// String resourceURL = baseURL + aPackage.getPlatform() + "/" + aPackage.getBundleID() +// + "/" + aPackage.getCreateTime() + "/"; +// return resourceURL; + return null; } /** @@ -179,6 +150,6 @@ public class PathManager { * @return */ public String getCAPath() { - return getBaseURL(false) + "crt/ca.crt"; + return getBaseURL() + "/crt/ca.crt"; } } diff --git a/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java b/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java index 11d23a7..ca1791f 100644 --- a/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java +++ b/src/main/java/org/yzr/utils/webhook/DingDingWebHook.java @@ -51,8 +51,8 @@ public class DingDingWebHook implements IWebHook { } Map markdown = new HashMap<>(); markdown.put("title", app.getName()); - String currentPackageURL = pathManager.getBaseURL(false) + "s/" + app.getShortCode() + "?id=" + app.getCurrentPackage().getId(); - String appURL = pathManager.getBaseURL(false) + "apps/" + app.getId(); + String currentPackageURL = "/s/" + app.getShortCode() + "?id=" + app.getCurrentPackage().getId(); + String appURL = "/apps/" + app.getId(); String platform = "iOS"; if (app.getPlatform().equalsIgnoreCase("android")) { platform = "Android"; diff --git a/src/main/java/org/yzr/vo/AppViewModel.java b/src/main/java/org/yzr/vo/AppViewModel.java index eeda4fe..23cd2b3 100644 --- a/src/main/java/org/yzr/vo/AppViewModel.java +++ b/src/main/java/org/yzr/vo/AppViewModel.java @@ -4,6 +4,7 @@ import org.yzr.model.App; import org.yzr.model.Package; import org.yzr.utils.file.PathManager; +import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; @@ -39,43 +40,45 @@ public class AppViewModel { /*** * 初始化是否加载列表 * @param app - * @param pathManager + * @param request * @param loadList */ - public AppViewModel(App app, PathManager pathManager, boolean loadList) { + public AppViewModel(App app, HttpServletRequest request, boolean loadList) { + String httpURL = PathManager.request(request).getBaseURL(); this.id = app.getId(); this.platform = app.getPlatform(); this.bundleID = app.getBundleID(); app.getCurrentPackage().setApp(app); this.userId = app.getOwner().getId(); - this.icon = PathManager.getRelativePath(app.getCurrentPackage()) + "icon.png"; + this.icon = httpURL + "/fetch/" + app.getCurrentPackage().getIconFile().getKey(); Package aPackage = findPackageById(app, null); this.version = aPackage.getVersion(); this.buildVersion = aPackage.getBuildVersion(); this.shortCode = app.getShortCode(); this.name = app.getName(); - this.installPath = pathManager.getBaseURL(false) + "s/" + app.getShortCode(); + this.installPath = httpURL + "/s/" + app.getShortCode(); this.minVersion = aPackage.getMinVersion(); - this.currentPackage = new PackageViewModel(aPackage, pathManager); + this.currentPackage = new PackageViewModel(aPackage, request); if (loadList) { // 排序 - this.packageList = sortPackages(app.getPackageList(), pathManager); + this.packageList = sortPackages(app.getPackageList(), request); } } - public AppViewModel(App app, PathManager pathManager, String packageId) { + public AppViewModel(App app, HttpServletRequest request, String packageId) { + String httpURL = PathManager.request(request).getBaseURL(); this.id = app.getId(); this.platform = app.getPlatform(); this.bundleID = app.getBundleID(); - this.icon = PathManager.getRelativePath(app.getCurrentPackage()) + "icon.png"; + this.icon = httpURL + "/fetch/" + app.getCurrentPackage().getIconFile().getKey(); Package aPackage = findPackageById(app, packageId); this.version = aPackage.getVersion(); this.buildVersion = aPackage.getBuildVersion(); this.shortCode = app.getShortCode(); this.name = app.getName(); - this.installPath = pathManager.getBaseURL(false) + "s/" + app.getShortCode(); + this.installPath = httpURL + "/s/" + app.getShortCode(); this.minVersion = aPackage.getMinVersion(); - this.currentPackage = new PackageViewModel(aPackage, pathManager); + this.currentPackage = new PackageViewModel(aPackage, request); } private static Package findPackageById(App app, String id) { @@ -90,11 +93,11 @@ public class AppViewModel { return app.getCurrentPackage(); } - private static List sortPackages(List packages, PathManager pathManager) { + private static List sortPackages(List packages, HttpServletRequest request) { // 排序 List packageViewModels = new ArrayList<>(); for (Package aPackage : packages) { - PackageViewModel packageViewModel = new PackageViewModel(aPackage, pathManager); + PackageViewModel packageViewModel = new PackageViewModel(aPackage, request); packageViewModels.add(packageViewModel); } packageViewModels.sort((o1, o2) -> { diff --git a/src/main/java/org/yzr/vo/PackageViewModel.java b/src/main/java/org/yzr/vo/PackageViewModel.java index e93941b..51b26b0 100644 --- a/src/main/java/org/yzr/vo/PackageViewModel.java +++ b/src/main/java/org/yzr/vo/PackageViewModel.java @@ -7,6 +7,7 @@ import org.yzr.model.Package; import org.yzr.utils.date.DateUtil; import org.yzr.utils.file.PathManager; +import javax.servlet.http.HttpServletRequest; import java.net.URLEncoder; import java.time.ZoneOffset; import java.util.Arrays; @@ -36,10 +37,11 @@ public class PackageViewModel { private int deviceCount; private String message; - public PackageViewModel(Package aPackage, PathManager pathManager) { - this.downloadURL = pathManager.getBaseURL(false) + "p/" + aPackage.getId(); - this.safeDownloadURL = pathManager.getBaseURL(true) + "p/" + aPackage.getId(); - this.iconURL = pathManager.getPackageResourceURL(aPackage, true) + "icon.png"; + public PackageViewModel(Package aPackage, HttpServletRequest request) { + String httpURL = PathManager.request(request).getBaseURL(); + String httpsURL = PathManager.request(request).useHttps().getBaseURL(); + this.downloadURL = httpURL + "/p/" + aPackage.getId(); + this.safeDownloadURL = httpsURL + "/p/" + aPackage.getId(); this.id = aPackage.getId(); this.version = aPackage.getVersion(); this.bundleID = aPackage.getBundleID(); @@ -52,7 +54,7 @@ public class PackageViewModel { this.displayTime = displayTime; if (aPackage.getPlatform().equals("ios")) { this.iOS = true; - String url = pathManager.getBaseURL(true) + "m/" + aPackage.getId(); + String url = httpsURL + "/m/" + aPackage.getId(); try { this.installURL = "itms-services://?action=download-manifest&url=" + URLEncoder.encode(url, "utf-8"); } catch (Exception e) { @@ -60,9 +62,9 @@ public class PackageViewModel { } } else if (aPackage.getPlatform().equals("android")) { this.iOS = false; - this.installURL = pathManager.getPackageResourceURL(aPackage, false) + aPackage.getFileName(); + this.installURL = httpURL + "/p/" + aPackage.getId(); } - this.previewURL = pathManager.getBaseURL(false) + "s/" + aPackage.getApp().getShortCode() + "?id=" + aPackage.getId(); + this.previewURL = httpURL + "/s/" + aPackage.getApp().getShortCode() + "?id=" + aPackage.getId(); if (this.isiOS()) { if (aPackage.getProvision() == null) { this.type = "内测版"; @@ -96,6 +98,9 @@ public class PackageViewModel { } } this.message = message; + try { + this.iconURL = httpsURL + "/fetch/" + aPackage.getIconFile().getKey(); + } catch (Exception e){} } public String getDownloadURL() { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 13f002f..47bfd73 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -43,7 +43,7 @@ storage.active=local # 本地对象存储配置信息 storage.local.storagePath=storage # 这个地方应该是wx模块的WxStorageController的fetch方法对应的地址 -storage.local.address=http://localhost:8080/app/storage/fetch/ +storage.local.address=http://127.0.0.1/fetch/ # 阿里云对象存储配置信息 storage.aliyun.endpoint=oss-cn-shenzhen.aliyuncs.com storage.aliyun.accessKeyId=111111 @@ -63,7 +63,7 @@ storage.qiniu.bucketName=app_manager # 自定义配置 server.port=443 -server.http.port=80 +server.http.port=8080 config.debug=debug server.domain=127.0.0.1 admin.username=admin diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 349502f..eae818c 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -35,7 +35,7 @@ @@ -73,17 +73,17 @@
- +
-

+

[[${app.name}]]

- + @@ -102,7 +102,7 @@
编辑 - + 预览
短链接:[[${baseURL}]]s/[[${app.shortCode}]][[${baseURL}]]/s/[[${app.shortCode}]]
包名: