package org.ohdsi.webapi.service; import org.eclipse.collections.impl.block.factory.Comparators; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.ohdsi.webapi.shiro.Entities.PermissionEntity; import org.ohdsi.webapi.shiro.Entities.RoleEntity; import org.ohdsi.webapi.shiro.Entities.UserEntity; import org.ohdsi.webapi.shiro.PermissionManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * * @author gennadiy.anisimov */ @Path("/") @Component public class UserService { @Autowired private PermissionManager authorizer; private Map<String, String> roleCreatorPermissionsTemplate = new LinkedHashMap<>(); public UserService() { this.roleCreatorPermissionsTemplate.put("role:%s:permissions:*:put", "Add permissions to role with ID = %s"); this.roleCreatorPermissionsTemplate.put("role:%s:permissions:*:delete", "Remove permissions from role with ID = %s"); this.roleCreatorPermissionsTemplate.put("role:%s:post", "Update role with ID = %s"); this.roleCreatorPermissionsTemplate.put("role:%s:delete", "Delete role with ID = %s"); } public static class User implements Comparable<User> { public Long id; public String login; public User() {} public User(UserEntity userEntity) { this.id = userEntity.getId(); this.login = userEntity.getLogin(); } @Override public int compareTo(User o) { Comparator c = Comparators.naturalOrder(); if (this.id == null && o.id == null) return c.compare(this.login, o.login); else return c.compare(this.id, o.id); } } public static class Permission implements Comparable<Permission> { public Long id; public String permission; public String description; public Permission() {} public Permission(PermissionEntity permissionEntity) { this.id = permissionEntity.getId(); this.permission = permissionEntity.getValue(); this.description = permissionEntity.getDescription(); } @Override public int compareTo(Permission o) { Comparator c = Comparators.naturalOrder(); if (this.id == null && o.id == null) return c.compare(this.permission, o.permission); else return c.compare(this.id, o.id); } } public static class Role implements Comparable<Role> { public Long id; public String role; public Role() {} public Role (RoleEntity roleEntity) { this.id = roleEntity.getId(); this.role = roleEntity.getName(); } @Override public int compareTo(Role o) { Comparator c = Comparators.naturalOrder(); if (this.id == null && o.id == null) return c.compare(this.role, o.role); else return c.compare(this.id, o.id); } } @GET @Path("user") @Produces(MediaType.APPLICATION_JSON) public ArrayList<User> getUsers() { Iterable<UserEntity> userEntities = this.authorizer.getUsers(); ArrayList<User> users = convertUsers(userEntities); return users; } @GET @Path("user/{userId}/permissions") @Produces(MediaType.APPLICATION_JSON) public ArrayList<Permission> getUsersPermissions(@PathParam("userId") Long userId) throws Exception { Set<PermissionEntity> permissionEntities = this.authorizer.getUserPermissions(userId); ArrayList<Permission> permissions = convertPermissions(permissionEntities); Collections.sort(permissions); return permissions; } @GET @Path("user/{userId}/roles") @Produces(MediaType.APPLICATION_JSON) public ArrayList<Role> getUserRoles(@PathParam("userId") Long userId) throws Exception { Set<RoleEntity> roleEntities = this.authorizer.getUserRoles(userId); ArrayList<Role> roles = convertRoles(roleEntities); Collections.sort(roles); return roles; } @POST @Path("role") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Role createRole(Role role) throws Exception { RoleEntity roleEntity = this.authorizer.addRole(role.role); RoleEntity personalRole = this.authorizer.getCurrentUserPersonalRole(); this.authorizer.addPermissionsFromTemplate( personalRole, this.roleCreatorPermissionsTemplate, String.valueOf(roleEntity.getId())); Role newRole = new Role(roleEntity); return newRole; } @PUT @Path("role/{roleId}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Role updateRole(@PathParam("roleId") Long id, Role role) throws Exception { RoleEntity roleEntity = this.authorizer.getRole(id); if (roleEntity == null) { throw new Exception("Role doesn't exist"); } roleEntity.setName(role.role); roleEntity = this.authorizer.updateRole(roleEntity); return new Role(roleEntity); } @GET @Path("role") @Produces(MediaType.APPLICATION_JSON) public ArrayList<Role> getRoles( @DefaultValue("false") @QueryParam("include_personal") boolean includePersonalRoles) { Iterable<RoleEntity> roleEntities = this.authorizer.getRoles(includePersonalRoles); ArrayList<Role> roles = convertRoles(roleEntities); return roles; } @GET @Path("role/{roleId}") @Produces(MediaType.APPLICATION_JSON) public Role getRole(@PathParam("roleId") Long id) { RoleEntity roleEntity = this.authorizer.getRole(id); Role role = new Role(roleEntity); return role; } @DELETE @Path("role/{roleId}") public void removeRole(@PathParam("roleId") Long roleId) { this.authorizer.removeRole(roleId); this.authorizer.removePermissionsFromTemplate(this.roleCreatorPermissionsTemplate, String.valueOf(roleId)); } @GET @Path("role/{roleId}/permissions") @Produces(MediaType.APPLICATION_JSON) public ArrayList<Permission> getRolePermissions(@PathParam("roleId") Long roleId) throws Exception { Set<PermissionEntity> permissionEntities = this.authorizer.getRolePermissions(roleId); ArrayList<Permission> permissions = convertPermissions(permissionEntities); Collections.sort(permissions); return permissions; } @PUT @Path("role/{roleId}/permissions/{permissionIdList}") public void addPermissionToRole(@PathParam("roleId") Long roleId, @PathParam("permissionIdList") String permissionIdList) throws Exception { for (String permissionIdString: permissionIdList.split("\\+")) { Long permissionId = Long.parseLong(permissionIdString); this.authorizer.addPermission(roleId, permissionId); } } @DELETE @Path("role/{roleId}/permissions/{permissionIdList}") public void removePermissionFromRole(@PathParam("roleId") Long roleId, @PathParam("permissionIdList") String permissionIdList) { for (String permissionIdString: permissionIdList.split("\\+")) { Long permissionId = Long.parseLong(permissionIdString); this.authorizer.removePermission(permissionId, roleId); } } @GET @Path("role/{roleId}/users") @Produces(MediaType.APPLICATION_JSON) public ArrayList<User> getRoleUsers(@PathParam("roleId") Long roleId) throws Exception { Set<UserEntity> userEntities = this.authorizer.getRoleUsers(roleId); ArrayList<User> users = this.convertUsers(userEntities); Collections.sort(users); return users; } @PUT @Path("role/{roleId}/users/{userIdList}") public void addUserToRole(@PathParam("roleId") Long roleId, @PathParam("userIdList") String userIdList) throws Exception { for (String userIdString: userIdList.split("\\+")) { Long userId = Long.parseLong(userIdString); this.authorizer.addUser(userId, roleId); } } @DELETE @Path("role/{roleId}/users/{userIdList}") public void removeUserFromRole(@PathParam("roleId") Long roleId, @PathParam("userIdList") String userIdList) { for (String userIdString: userIdList.split("\\+")) { Long userId = Long.parseLong(userIdString); this.authorizer.removeUser(userId, roleId); } } @GET @Path("permission") @Produces(MediaType.APPLICATION_JSON) public ArrayList<Permission> getPermissions() { Iterable<PermissionEntity> permissionEntities = this.authorizer.getPermissions(); ArrayList<Permission> permissions = convertPermissions(permissionEntities); return permissions; } private ArrayList<Permission> convertPermissions(final Iterable<PermissionEntity> permissionEntities) { ArrayList<Permission> permissions = new ArrayList<Permission>(); for (PermissionEntity permissionEntity : permissionEntities) { Permission permission = new Permission(permissionEntity); permissions.add(permission); } return permissions; } private ArrayList<Role> convertRoles(final Iterable<RoleEntity> roleEntities) { ArrayList<Role> roles = new ArrayList<Role>(); for (RoleEntity roleEntity : roleEntities) { Role role = new Role(roleEntity); roles.add(role); } return roles; } private ArrayList<User> convertUsers(final Iterable<UserEntity> userEntities) { ArrayList<User> users = new ArrayList<User>(); for (UserEntity userEntity : userEntities) { User user = new User(userEntity); users.add(user); } return users; } }