/projects/de.skuzzle.polly.core/src/de/skuzzle/polly/core/internal/roles/RoleManagerImpl.java

https://github.com/skuzzle/polly · Java · 442 lines · 333 code · 107 blank · 2 comment · 47 complexity · 1e7dff94052f9bb525c7863391caed2a MD5 · raw file

  1. package de.skuzzle.polly.core.internal.roles;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.HashSet;
  5. import java.util.List;
  6. import java.util.Set;
  7. import org.apache.log4j.Logger;
  8. import de.skuzzle.polly.core.internal.users.UserImpl;
  9. import de.skuzzle.polly.sdk.PersistenceManagerV2;
  10. import de.skuzzle.polly.sdk.PersistenceManagerV2.Atomic;
  11. import de.skuzzle.polly.sdk.PersistenceManagerV2.Param;
  12. import de.skuzzle.polly.sdk.PersistenceManagerV2.Read;
  13. import de.skuzzle.polly.sdk.PersistenceManagerV2.Write;
  14. import de.skuzzle.polly.sdk.User;
  15. import de.skuzzle.polly.sdk.exceptions.DatabaseException;
  16. import de.skuzzle.polly.sdk.exceptions.InsufficientRightsException;
  17. import de.skuzzle.polly.sdk.exceptions.RoleException;
  18. import de.skuzzle.polly.sdk.roles.RoleManager;
  19. import de.skuzzle.polly.sdk.roles.SecurityContainer;
  20. import de.skuzzle.polly.sdk.roles.SecurityObject;
  21. public class RoleManagerImpl implements RoleManager {
  22. private final static Logger logger = Logger.getLogger(RoleManagerImpl.class
  23. .getName());
  24. private final static Object SYNC = new Object();
  25. private PersistenceManagerV2 persistence;
  26. private boolean rolesStale;
  27. private Set<String> allRoles;
  28. public RoleManagerImpl(PersistenceManagerV2 persistence) {
  29. this.persistence = persistence;
  30. }
  31. @Override
  32. public boolean roleExists(String roleName) {
  33. synchronized (SYNC) {
  34. return this.getRoles().contains(roleName);
  35. }
  36. }
  37. @Override
  38. public boolean permissionExists(String permissionName) {
  39. return this.persistence.atomic().findSingle(Permission.class,
  40. Permission.PERMISSION_BY_NAME, new Param(permissionName)) != null;
  41. }
  42. @Override
  43. public Set<String> getRoles() {
  44. synchronized(SYNC) {
  45. if (this.rolesStale || this.allRoles == null) {
  46. List<Role> roles = this.persistence.atomic().findList(
  47. Role.class, Role.ALL_ROLES);
  48. this.allRoles = new HashSet<String>(roles.size());
  49. for (Role role : roles) {
  50. this.allRoles.add(role.getName());
  51. }
  52. this.rolesStale = false;
  53. }
  54. }
  55. return Collections.unmodifiableSet(this.allRoles);
  56. }
  57. @Override
  58. public Set<String> getRoles(User user) {
  59. Set<String> result = new HashSet<String>();
  60. for (Role role : ((de.skuzzle.polly.core.internal.users.UserImpl)user).getRoles()) {
  61. result.add(role.getName());
  62. }
  63. return Collections.unmodifiableSet(result);
  64. }
  65. @Override
  66. public boolean hasRole(User user, String role) {
  67. return this.getRoles(user).contains(role);
  68. }
  69. @Override
  70. public Set<String> getPermissions(String roleName) {
  71. try (final Read r = this.persistence.read()) {
  72. Role role = r.findSingle(
  73. Role.class, Role.ROLE_BY_NAME, new Param(roleName));
  74. if (role == null) {
  75. return Collections.emptySet();
  76. }
  77. return role.getPermissionNames();
  78. }
  79. }
  80. @Override
  81. public void createRole(final String newRoleName)
  82. throws DatabaseException {
  83. synchronized(SYNC) {
  84. this.persistence.writeAtomic(new Atomic() {
  85. @Override
  86. public void perform(Write write) throws DatabaseException {
  87. final Role role = write.read().findSingle(Role.class,
  88. Role.ROLE_BY_NAME, new Param(newRoleName));
  89. if (role != null) {
  90. return;
  91. }
  92. logger.info("Creating new Role: '" + newRoleName + "'");
  93. write.single(new Role(newRoleName));
  94. }
  95. });
  96. this.rolesStale = true;
  97. }
  98. }
  99. @Override
  100. public void createRole(final String baseRoleName, final String newRoleName)
  101. throws RoleException, DatabaseException {
  102. synchronized (SYNC) {
  103. try (final Write write = this.persistence.write()) {
  104. final Role role = write.read().findSingle(Role.class,
  105. Role.ROLE_BY_NAME, new Param(newRoleName));
  106. if (role != null) {
  107. return;
  108. }
  109. final Role baseRole = write.read().findSingle(Role.class,
  110. Role.ROLE_BY_NAME, new Param(baseRoleName));
  111. if (baseRole == null) {
  112. throw new RoleException("Unknown base role: '" + baseRoleName + "'");
  113. }
  114. logger.info("Creating new Role: '" + newRoleName + "' from base role '" +
  115. baseRoleName + "'");
  116. write.single(new Role(newRoleName,
  117. new HashSet<>(baseRole.getPermissions())));
  118. }
  119. this.rolesStale = true;
  120. }
  121. }
  122. @Override
  123. public void deleteRole(final String roleName)
  124. throws RoleException, DatabaseException {
  125. if (roleName.equals(ADMIN_ROLE) || roleName.equals(DEFAULT_ROLE)) {
  126. throw new RoleException("Default roles cant be deleted");
  127. }
  128. this.persistence.writeAtomic(new Atomic() {
  129. @Override
  130. public void perform(Write write) throws DatabaseException {
  131. final Role role = write.read().findSingle(Role.class, Role.ROLE_BY_NAME,
  132. new Param(roleName));
  133. if (role == null) {
  134. return;
  135. }
  136. final List<User> allUsers = write.read().findList(User.class,
  137. UserImpl.ALL_USERS);
  138. logger.debug("Deleting role: '" + roleName + "'");
  139. write.remove(role);
  140. for (User user : allUsers) {
  141. UserImpl puser = (UserImpl) user;
  142. puser.getRoles().remove(role);
  143. }
  144. }
  145. });
  146. }
  147. @Override
  148. public void registerPermission(final String permission) throws DatabaseException {
  149. synchronized(SYNC) {
  150. if (!permissionExists(permission)) {
  151. logger.debug("Registering permission: '" + permission + "'");
  152. this.persistence.writeAtomic(new Atomic() {
  153. @Override
  154. public void perform(Write write) throws DatabaseException {
  155. write.single(new Permission(permission));
  156. }
  157. });
  158. }
  159. }
  160. }
  161. @Override
  162. public void registerPermissions(final Set<String> permissions)
  163. throws DatabaseException {
  164. synchronized(SYNC) {
  165. this.persistence.writeAtomic(new Atomic() {
  166. @Override
  167. public void perform(Write write) {
  168. for (String perm : permissions) {
  169. if (!permissionExists(perm)) {
  170. logger.debug("Registering permission: '" + perm + "'");
  171. write.single(new Permission(perm));
  172. }
  173. }
  174. }
  175. });
  176. }
  177. }
  178. @Override
  179. public void registerPermissions(SecurityContainer container)
  180. throws DatabaseException {
  181. this.registerPermissions(container.getContainedPermissions());
  182. }
  183. @Override
  184. public void assignPermission(final String roleName, final String permission)
  185. throws DatabaseException, RoleException {
  186. synchronized(SYNC) {
  187. try (final Write write = this.persistence.write()) {
  188. final Role role =
  189. write.read().findSingle(Role.class, Role.ROLE_BY_NAME,
  190. new Param(roleName));
  191. if (role == null) {
  192. throw new RoleException("Unknown role: " + roleName);
  193. }
  194. final Permission perm = write.read().findSingle(Permission.class,
  195. Permission.PERMISSION_BY_NAME, new Param(permission));
  196. if (perm == null) {
  197. throw new RoleException("Unknown permission: " + permission);
  198. }
  199. // TODO: add permission to admin role
  200. logger.debug("Assigning permission '" +
  201. permission + "' to role '" + roleName + "'");
  202. role.getPermissions().add(perm);
  203. role.setStale(true); // this updates the permission name string set
  204. }
  205. }
  206. }
  207. @Override
  208. public void assignPermissions(String roleName, final Set<String> permissions)
  209. throws RoleException, DatabaseException {
  210. synchronized(SYNC) {
  211. try (final Write write = this.persistence.write()) {
  212. final Role role = write.read().findSingle(Role.class,
  213. Role.ROLE_BY_NAME, new Param(roleName));
  214. if (role == null) {
  215. throw new RoleException("Unknown role: " + roleName);
  216. }
  217. final List<Permission> perms = new ArrayList<Permission>(permissions.size());
  218. for (String permission : permissions) {
  219. final Permission perm = write.read().findSingle(Permission.class,
  220. Permission.PERMISSION_BY_NAME, new Param(permission));
  221. if (perm == null) {
  222. throw new RoleException(
  223. "Unknown permission: '" + permission + "'");
  224. }
  225. perms.add(perm);
  226. }
  227. // TODO: add permission to admin role
  228. logger.debug("Assigning permission '" +
  229. permissions + "' to role '" + roleName + "'");
  230. role.getPermissions().addAll(perms);
  231. role.setStale(true); // this updates the permission name string set
  232. }
  233. }
  234. }
  235. @Override
  236. public void assignPermissions(String roleName, SecurityContainer container)
  237. throws RoleException, DatabaseException {
  238. this.assignPermissions(roleName, container.getContainedPermissions());
  239. }
  240. @Override
  241. public synchronized void removePermission(final String roleName,
  242. final String permission) throws RoleException, DatabaseException {
  243. synchronized(SYNC) {
  244. try (final Write write = this.persistence.write()) {
  245. final Role role = write.read().findSingle(Role.class, Role.ROLE_BY_NAME,
  246. new Param(roleName));
  247. if (role == null) {
  248. throw new RoleException("Unknown role: " + roleName);
  249. }
  250. final Permission perm = write.read().findSingle(Permission.class,
  251. Permission.PERMISSION_BY_NAME, new Param(permission));
  252. if (perm == null) {
  253. return;
  254. }
  255. logger.debug("Removing permission '" +
  256. permission + "' from role '" + roleName + "'");
  257. role.getPermissions().remove(perm);
  258. role.setStale(true);
  259. }
  260. }
  261. }
  262. @Override
  263. public synchronized void assignRole(final User user, final String roleName)
  264. throws RoleException, DatabaseException {
  265. synchronized (SYNC) {
  266. try (final Write w = this.persistence.write()) {
  267. final Role role = w.read().findSingle(Role.class, Role.ROLE_BY_NAME,
  268. new Param(roleName));
  269. if (role == null) {
  270. throw new RoleException("Unknown role: " + roleName);
  271. }
  272. logger.debug("Assigning role '" +
  273. roleName + "' to user '" + user + "'");
  274. ((UserImpl) user).getRoles().add(role);
  275. }
  276. }
  277. }
  278. @Override
  279. public synchronized void removeRole(final User user, final String roleName)
  280. throws RoleException, DatabaseException {
  281. synchronized (SYNC) {
  282. logger.debug("Removing role '" +
  283. roleName + "' from user '" + user + "'");
  284. this.persistence.writeAtomic(new Atomic() {
  285. @Override
  286. public void perform(Write write) {
  287. ((UserImpl) user).getRoles().remove(new Role(roleName));
  288. }
  289. });
  290. }
  291. }
  292. @Override
  293. public boolean hasPermission(User user, String permission) {
  294. if (permission.equals(RoleManager.NONE_PERMISSION)) {
  295. return true;
  296. } else if (user == null) {
  297. return false;
  298. }
  299. de.skuzzle.polly.core.internal.users.UserImpl puser = (de.skuzzle.polly.core.internal.users.UserImpl) user;
  300. synchronized (SYNC) {
  301. for (Role role : puser.getRoles()) {
  302. if (role.getName().equals(RoleManager.ADMIN_ROLE) ||
  303. role.getPermissionNames().contains(permission)) {
  304. return true;
  305. }
  306. }
  307. }
  308. return false;
  309. }
  310. @Override
  311. public boolean hasPermission(User user, Set<String> permissions) {
  312. for (String perm : permissions) {
  313. if (!this.hasPermission(user, perm)) {
  314. return false;
  315. }
  316. }
  317. return true;
  318. }
  319. @Override
  320. public boolean canAccess(User user, SecurityObject securityObject) {
  321. return this.hasPermission(user, securityObject.getRequiredPermission());
  322. }
  323. @Override
  324. public void checkAccess(User user, SecurityObject securityObject)
  325. throws InsufficientRightsException {
  326. if (!this.canAccess(user, securityObject)) {
  327. this.denyAccess(securityObject);
  328. }
  329. }
  330. @Override
  331. public void denyAccess(SecurityObject securityObject)
  332. throws InsufficientRightsException {
  333. throw new InsufficientRightsException(securityObject);
  334. }
  335. }