package org.linlinjava.litemall.admin.util; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc; public class Permission { private RequiresPermissions requiresPermissions; private RequiresPermissionsDesc requiresPermissionsDesc; private String api; public RequiresPermissions getRequiresPermissions() { return requiresPermissions; } public RequiresPermissionsDesc getRequiresPermissionsDesc() { return requiresPermissionsDesc; } public void setRequiresPermissions(RequiresPermissions requiresPermissions) { this.requiresPermissions = requiresPermissions; } public void setRequiresPermissionsDesc(RequiresPermissionsDesc requiresPermissionsDesc) { this.requiresPermissionsDesc = requiresPermissionsDesc; } public String getApi() { return api; } public void setApi(String api) { this.api = api; } }
package org.linlinjava.litemall.admin.util; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.MethodUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc; import org.linlinjava.litemall.admin.vo.PermVo; import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Controller; import org.springframework.util.ClassUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.lang.reflect.Method; import java.util.*; public class PermissionUtil { public static List<PermVo> listPermVo(List<Permission> permissions) { List<PermVo> root = new ArrayList<>(); for (Permission permission : permissions) { RequiresPermissions requiresPermissions = permission.getRequiresPermissions(); RequiresPermissionsDesc requiresPermissionsDesc = permission.getRequiresPermissionsDesc(); String api = permission.getApi(); String[] menus = requiresPermissionsDesc.menu(); if (menus.length != 2) { throw new RuntimeException("目前只支持两级菜单"); } String menu1 = menus[0]; PermVo perm1 = null; for (PermVo permVo : root) { if (permVo.getLabel().equals(menu1)) { perm1 = permVo; break; } } if (perm1 == null) { perm1 = new PermVo(); perm1.setId(menu1); perm1.setLabel(menu1); perm1.setChildren(new ArrayList<>()); root.add(perm1); } String menu2 = menus[1]; PermVo perm2 = null; for (PermVo permVo : perm1.getChildren()) { if (permVo.getLabel().equals(menu2)) { perm2 = permVo; break; } } if (perm2 == null) { perm2 = new PermVo(); perm2.setId(menu2); perm2.setLabel(menu2); perm2.setChildren(new ArrayList<>()); perm1.getChildren().add(perm2); } String button = requiresPermissionsDesc.button(); PermVo leftPerm = null; for (PermVo permVo : perm2.getChildren()) { if (permVo.getLabel().equals(button)) { leftPerm = permVo; break; } } if (leftPerm == null) { leftPerm = new PermVo(); leftPerm.setId(requiresPermissions.value()[0]); leftPerm.setLabel(requiresPermissionsDesc.button()); leftPerm.setApi (API); . perm2.getChildren () the Add (leftPerm); } the else { // the TODO // current limit Controller inside each method RequiresPermissionsDesc annotations are only // If the same permission, permission may cause internal inconsistency. the throw new new a RuntimeException ( "permission exists, can not add new rights" ); } } return the root; } public static List <the Permission> listPermission (the ApplicationContext context, String basicPackage) { the Map <String, Object> = context.getBeansWithAnnotation Map (the Controller . class ); List<Permission> permissions = new ArrayList<>(); for (Map.Entry<String, Object> entry : map.entrySet()) { Object bean = entry.getValue(); if (!StringUtils.contains(ClassUtils.getPackageName(bean.getClass()), basicPackage)) { continue; } Class<?> clz = bean.getClass(); Class controllerClz = clz.getSuperclass(); RequestMapping clazzRequestMapping = AnnotationUtils.findAnnotation(controllerClz, RequestMapping.class); List<Method> methods = MethodUtils.getMethodsListWithAnnotation(controllerClz, RequiresPermissions.class); for (Method method : methods) { RequiresPermissions requiresPermissions = AnnotationUtils.getAnnotation(method, RequiresPermissions.class); RequiresPermissionsDesc requiresPermissionsDesc = AnnotationUtils.getAnnotation(method, RequiresPermissionsDesc.class); if (requiresPermissions == null || requiresPermissionsDesc == null) { continue; } String api = ""; if (clazzRequestMapping != null) { api = clazzRequestMapping.value()[0]; } PostMapping postMapping = AnnotationUtils.getAnnotation(method, PostMapping.class); if (postMapping != null) { api = "POST " + api + postMapping.value()[0]; Permission permission = new Permission(); permission.setRequiresPermissions(requiresPermissions); permission.setRequiresPermissionsDesc(requiresPermissionsDesc); permission.setApi(api); permissions.add(permission); continue; } GetMapping getMapping = AnnotationUtils.getAnnotation(method, GetMapping.class); if (getMapping != null) { api = "GET " + api + getMapping.value()[0]; Permission permission = new Permission(); permission.setRequiresPermissions (requiresPermissions); permission.setRequiresPermissionsDesc (requiresPermissionsDesc); permission.setApi (API); permissions.add (permission); the Continue ; } // TODO // here only supports GetMapping PostMapping notes or annotations, should provide further flexibility the throw new new RuntimeException ( "current rights management method should be used in front of GetMapping comment or PostMapping notes" ); } } return the permissions; } public static the Set <String> listPermissionString (List <permission> permissions) { Set<String> permissionsString = new HashSet<>(); for (Permission permission : permissions) { permissionsString.add(permission.getRequiresPermissions().value()[0]); } return permissionsString; } }
package org.linlinjava.litemall.admin.vo; import java.util.List; public class PermVo { private String id; private String label; private String api; private List<PermVo> children; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public void setApi(String api) { this.api = api; } public String getApi() { return api; } public List<PermVo> getChildren() { return children; } public void setChildren(List<PermVo> children) { this.children = children; } }
package org.linlinjava.litemall.admin.web; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; import org.linlinjava.litemall.admin.annotation.RequiresPermissionsDesc; import org.linlinjava.litemall.admin.service.LogHelper; import org.linlinjava.litemall.core.util.RegexUtil; import org.linlinjava.litemall.core.util.ResponseUtil; importorg.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder; import org.linlinjava.litemall.core.validator.Order; import org.linlinjava.litemall.core.validator.Sort; import org.linlinjava.litemall.db.domain.LitemallAdmin; import org.linlinjava.litemall.db.service.LitemallAdminService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation. * ; import javax.validation.constraints.NotNull; import java.util.List; import static org.linlinjava.litemall.admin.util.AdminResponseCode.*; @RestController @RequestMapping("/admin/admin") @Validated public class AdminAdminController { private final Log logger = LogFactory.getLog(AdminAdminController.class); @Autowired private LitemallAdminService adminService; @Autowired private LogHelper logHelper; @RequiresPermissions("admin:admin:list") @RequiresPermissionsDesc(menu = {"系统管理", "管理员管理"}, button = "查询") @GetMapping("/list") public Object list(String username, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer limit, @Sort @RequestParam(defaultValue = "add_time") String sort, @Order @RequestParam(defaultValue = "desc") String order) { List<LitemallAdmin> adminList = adminService.querySelective(username, page, limit, sort, order); return ResponseUtil.okList(adminList); } privateThe validate Object (LitemallAdmin ADMIN) { String name = admin.getUsername (); IF (StringUtils.isEmpty (name)) { return ResponseUtil.badArgument (); } IF (! RegexUtil.isUsername (name)) { return ResponseUtil.fail ( ADMIN_INVALID_NAME, "the name of the administrator does not comply" ); } String password = admin.getPassword (); IF (StringUtils.isEmpty (password) || password.length () <. 6 ) { return ResponseUtil.fail (ADMIN_INVALID_PASSWORD, "management members not be less than the length of the password. 6 " ); } return null; } @RequiresPermissions("admin:admin:create") @RequiresPermissionsDesc(menu = {"系统管理", "管理员管理"}, button = "添加") @PostMapping("/create") public Object create(@RequestBody LitemallAdmin admin) { Object error = validate(admin); if (error != null) { return error; } String username = admin.getUsername(); List<LitemallAdmin> adminList = adminService.findAdmin(username); if (adminList.size() > 0) { return ResponseUtil.fail(ADMIN_NAME_EXIST, "管理员已经存在"); } String rawPassword = admin.getPassword(); BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); String encodedPassword = encoder.encode(rawPassword); admin.setPassword(encodedPassword); adminService.add(admin); logHelper.logAuthSucceed("添加管理员", username); return ResponseUtil.ok(admin); } @RequiresPermissions("admin:admin:read") @RequiresPermissionsDesc (MENU = { "management system", "Administrator manage"}, button = "before" ) @GetMapping ( "/ Read" ) public Object Read (@NotNull ID Integer) { LitemallAdmin ADMIN = adminService.findById (ID ); return ResponseUtil.ok (ADMIN); } @RequiresPermissions ( "ADMIN: ADMIN: Update" ) @RequiresPermissionsDesc (MENU = { "management system", "administrator manage"}, button = "edit" ) @PostMapping ( " / update ") public Object update(@RequestBody LitemallAdmin admin) { Object error =the validate (ADMIN); IF (error =! null ) { return error; } Integer anotherAdminId = admin.getId (); IF (anotherAdminId == null ) { return ResponseUtil.badArgument (); } // do not allow editing administrator Interface Change password admin.setPassword ( null ); IF (adminService.updateById (ADMIN) == 0 ) { return ResponseUtil.updatedDataFailed (); } logHelper.logAuthSucceed ( "administrator edit", Admin.getUsername ()); return ResponseUtil.ok (ADMIN); } @RequiresPermissions ( "ADMIN: ADMIN: the Delete" ) @RequiresPermissionsDesc (the MENU = { "System Management", "Administrator Management"}, button = "Delete " ) @PostMapping ( " / Delete " ) public Object Delete (@RequestBody LitemallAdmin ADMIN) { Integer anotherAdminId = admin.getId (); IF (anotherAdminId == null ) { return ResponseUtil.badArgument (); } // administrator can not delete own account Subject currentUser = SecurityUtils.getSubject(); LitemallAdmin currentAdmin = (LitemallAdmin) currentUser.getPrincipal(); if (currentAdmin.getId().equals(anotherAdminId)) { return ResponseUtil.fail(ADMIN_DELETE_NOT_ALLOWED, "管理员不能删除自己账号"); } adminService.deleteById(anotherAdminId); logHelper.logAuthSucceed("删除管理员", admin.getUsername()); return ResponseUtil.ok(); } }
package org.linlinjava.litemall.admin.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface RequiresPermissionsDesc { String[] menu(); String button(); }