Commit b9d5c2030a80e0fffccc7a563929fba63715e807
1 parent
56e7ca33
feature: Funktionierender Zwischenstand der Standard-Rechteverwaltung
Showing
9 changed files
with
242 additions
and
6 deletions
src/main/java/net/ziemers/swxercise/db/dao/GenericDao.java
| @@ -3,6 +3,7 @@ package net.ziemers.swxercise.db.dao; | @@ -3,6 +3,7 @@ package net.ziemers.swxercise.db.dao; | ||
| 3 | import java.util.Collection; | 3 | import java.util.Collection; |
| 4 | 4 | ||
| 5 | import javax.ejb.Stateless; | 5 | import javax.ejb.Stateless; |
| 6 | +import javax.enterprise.inject.Alternative; | ||
| 6 | import javax.inject.Inject; | 7 | import javax.inject.Inject; |
| 7 | import javax.persistence.EntityManager; | 8 | import javax.persistence.EntityManager; |
| 8 | import javax.persistence.TypedQuery; | 9 | import javax.persistence.TypedQuery; |
| @@ -17,6 +18,9 @@ import net.ziemers.swxercise.db.BaseEntity; | @@ -17,6 +18,9 @@ import net.ziemers.swxercise.db.BaseEntity; | ||
| 17 | * spazialisierten Data Access Objects geerbt. | 18 | * spazialisierten Data Access Objects geerbt. |
| 18 | */ | 19 | */ |
| 19 | @Stateless | 20 | @Stateless |
| 21 | +// diese Bean ist nur die Alternative zur Ermittlung des Entity Managers | ||
| 22 | +// Quelle: https://stackoverflow.com/questions/10185976/cdi-ambiguous-dependencies | ||
| 23 | +@Alternative | ||
| 20 | public class GenericDao { | 24 | public class GenericDao { |
| 21 | 25 | ||
| 22 | /* | 26 | /* |
src/main/java/net/ziemers/swxercise/lg/model/user/Profile.java
| @@ -3,6 +3,7 @@ package net.ziemers.swxercise.lg.model.user; | @@ -3,6 +3,7 @@ package net.ziemers.swxercise.lg.model.user; | ||
| 3 | import javax.persistence.Entity; | 3 | import javax.persistence.Entity; |
| 4 | import javax.persistence.EnumType; | 4 | import javax.persistence.EnumType; |
| 5 | import javax.persistence.Enumerated; | 5 | import javax.persistence.Enumerated; |
| 6 | +import javax.persistence.ManyToOne; | ||
| 6 | import javax.validation.constraints.NotNull; | 7 | import javax.validation.constraints.NotNull; |
| 7 | import javax.xml.bind.DatatypeConverter; | 8 | import javax.xml.bind.DatatypeConverter; |
| 8 | 9 | ||
| @@ -34,6 +35,8 @@ public class Profile extends BaseEntity { | @@ -34,6 +35,8 @@ public class Profile extends BaseEntity { | ||
| 34 | 35 | ||
| 35 | private String mailaddress; | 36 | private String mailaddress; |
| 36 | 37 | ||
| 38 | + private Role role; | ||
| 39 | + | ||
| 37 | /* | 40 | /* |
| 38 | * ***************************************************************************************************************************** | 41 | * ***************************************************************************************************************************** |
| 39 | * Konstruktoren | 42 | * Konstruktoren |
| @@ -188,4 +191,13 @@ public class Profile extends BaseEntity { | @@ -188,4 +191,13 @@ public class Profile extends BaseEntity { | ||
| 188 | return this; | 191 | return this; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| 194 | + @ManyToOne | ||
| 195 | + public Role getRole() { | ||
| 196 | + return role; | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + public void setRole(Role role) { | ||
| 200 | + this.role = role; | ||
| 201 | + } | ||
| 202 | + | ||
| 191 | } | 203 | } |
src/main/java/net/ziemers/swxercise/lg/model/user/Role.java
0 → 100644
| 1 | +package net.ziemers.swxercise.lg.model.user; | ||
| 2 | + | ||
| 3 | +import net.ziemers.swxercise.db.BaseEntity; | ||
| 4 | +import net.ziemers.swxercise.lg.user.enums.RightState; | ||
| 5 | + | ||
| 6 | +import javax.persistence.*; | ||
| 7 | +import javax.validation.constraints.NotNull; | ||
| 8 | +import java.util.Collection; | ||
| 9 | +import java.util.HashSet; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * Rollen sind Container für Benutzerrechte (siehe {@link net.ziemers.swxercise.lg.user.enums.RightState}. | ||
| 13 | + * Eine Rolle kann von einer Vaterrolle erben. Somit umfasst diese Rolle auch alle Rechte der Vaterrolle. | ||
| 14 | + */ | ||
| 15 | +@Entity | ||
| 16 | +public class Role extends BaseEntity { | ||
| 17 | + | ||
| 18 | + @NotNull | ||
| 19 | + private String name; | ||
| 20 | + | ||
| 21 | + private Collection<RightState> rights = new HashSet<>(); | ||
| 22 | + | ||
| 23 | + private Role parent = null; | ||
| 24 | + | ||
| 25 | + public Role() {} | ||
| 26 | + | ||
| 27 | + public Role(final String name) { | ||
| 28 | + setName(name); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public Role(final String name, final RightState right) { | ||
| 32 | + this(name); | ||
| 33 | + rights.add(right); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public Role(final String name, final String right) { | ||
| 37 | + this(name, RightState.getByName(right)); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public boolean hasRight(RightState right) { | ||
| 41 | + return rights.contains(right); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public String getName() { | ||
| 45 | + return name; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public void setName(String name) { | ||
| 49 | + this.name = name; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public Role withName(final String name) { | ||
| 53 | + setName(name); | ||
| 54 | + return this; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @ElementCollection(targetClass = RightState.class, fetch = FetchType.EAGER) | ||
| 58 | + //@JoinTable(name = "Role_rights", joinColumns = @JoinColumn(name = "Role_id")) | ||
| 59 | + //@Column(name = "rights") | ||
| 60 | + @Enumerated(EnumType.STRING) | ||
| 61 | + public Collection<RightState> getRights() { | ||
| 62 | + return rights; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + public void setRights(Collection<RightState> rights) { | ||
| 66 | + this.rights = rights; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + @ManyToOne | ||
| 70 | + public Role getParent() { | ||
| 71 | + return parent; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + public void setParent(Role parent) { | ||
| 75 | + this.parent = parent; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | +} |
src/main/java/net/ziemers/swxercise/lg/user/dto/RoleDto.java
0 → 100644
| 1 | +package net.ziemers.swxercise.lg.user.dto; | ||
| 2 | + | ||
| 3 | +import javax.validation.constraints.NotNull; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Das Data Transfer Object im Kontext der Rollen- und Rechteverwaltung. Es wird unter anderem auch aus einem | ||
| 7 | + * JSON-Objekt des {@link net.ziemers.swxercise.ui.RoleViewController}s gefüllt. | ||
| 8 | + */ | ||
| 9 | +public class RoleDto { | ||
| 10 | + | ||
| 11 | + @NotNull | ||
| 12 | + private String name; | ||
| 13 | + | ||
| 14 | + @NotNull | ||
| 15 | + private String right; | ||
| 16 | + | ||
| 17 | + public String getName() { return name; } | ||
| 18 | + | ||
| 19 | + public RoleDto withName(final String name) { | ||
| 20 | + this.name = name; | ||
| 21 | + return this; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public String getRight() { return right; } | ||
| 25 | + | ||
| 26 | + public RoleDto withRight(final String right) { | ||
| 27 | + this.right = right; | ||
| 28 | + return this; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | +} |
src/main/java/net/ziemers/swxercise/lg/user/enums/RightState.java
| @@ -20,6 +20,15 @@ public enum RightState { | @@ -20,6 +20,15 @@ public enum RightState { | ||
| 20 | this.name = name; | 20 | this.name = name; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | + public static RightState getByName(final String name) { | ||
| 24 | + for (RightState value : values()) { | ||
| 25 | + if (value.name().equals(name)) { | ||
| 26 | + return value; | ||
| 27 | + } | ||
| 28 | + } | ||
| 29 | + return null; | ||
| 30 | + } | ||
| 31 | + | ||
| 23 | public String getName() { | 32 | public String getName() { |
| 24 | return name; | 33 | return name; |
| 25 | } | 34 | } |
src/main/java/net/ziemers/swxercise/lg/user/service/RoleService.java
0 → 100644
| 1 | +package net.ziemers.swxercise.lg.user.service; | ||
| 2 | + | ||
| 3 | +import net.ziemers.swxercise.db.dao.GenericDao; | ||
| 4 | +import net.ziemers.swxercise.lg.model.user.Role; | ||
| 5 | +import net.ziemers.swxercise.lg.user.dto.RoleDto; | ||
| 6 | + | ||
| 7 | +import javax.ejb.Stateless; | ||
| 8 | +import javax.inject.Inject; | ||
| 9 | +import java.util.Collection; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * Diese Klasse stellt alle Dienste im Kontext einer Rollen- und Rechteverwaltung zur Verfügung. | ||
| 13 | + */ | ||
| 14 | +@Stateless | ||
| 15 | +public class RoleService { | ||
| 16 | + | ||
| 17 | + @Inject | ||
| 18 | + private GenericDao dao; | ||
| 19 | + | ||
| 20 | + public Collection<Role> findAllRoles() { | ||
| 21 | + // TODO noch zu implementieren | ||
| 22 | + return null; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public Long createRole(final RoleDto dto) { | ||
| 26 | + final Role role = new Role(dto.getName(), dto.getRight()); | ||
| 27 | + return dao.save(role); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | +} |
src/main/java/net/ziemers/swxercise/lg/user/service/UserService.java
| @@ -8,6 +8,7 @@ import javax.inject.Inject; | @@ -8,6 +8,7 @@ import javax.inject.Inject; | ||
| 8 | 8 | ||
| 9 | import net.ziemers.swxercise.db.dao.user.UserDao; | 9 | import net.ziemers.swxercise.db.dao.user.UserDao; |
| 10 | import net.ziemers.swxercise.lg.model.user.Profile; | 10 | import net.ziemers.swxercise.lg.model.user.Profile; |
| 11 | +import net.ziemers.swxercise.lg.model.user.Role; | ||
| 11 | import net.ziemers.swxercise.lg.model.user.User; | 12 | import net.ziemers.swxercise.lg.model.user.User; |
| 12 | import net.ziemers.swxercise.lg.user.dto.UserDto; | 13 | import net.ziemers.swxercise.lg.user.dto.UserDto; |
| 13 | import net.ziemers.swxercise.lg.user.enums.RightState; | 14 | import net.ziemers.swxercise.lg.user.enums.RightState; |
| @@ -83,6 +84,7 @@ public class UserService { | @@ -83,6 +84,7 @@ public class UserService { | ||
| 83 | * @return die Id des neuen Benutzers, wenn die Erstellung erfolgreich war. | 84 | * @return die Id des neuen Benutzers, wenn die Erstellung erfolgreich war. |
| 84 | */ | 85 | */ |
| 85 | public Long createUser(final UserDto dto) { | 86 | public Long createUser(final UserDto dto) { |
| 87 | + // der Benutzer darf natürlich noch nicht existieren :) | ||
| 86 | User user = dao.findByUsername(dto.getUsername()); | 88 | User user = dao.findByUsername(dto.getUsername()); |
| 87 | if (user == null) { | 89 | if (user == null) { |
| 88 | final Profile profile = new Profile(dto.getUsername(), dto.getPassword()); | 90 | final Profile profile = new Profile(dto.getUsername(), dto.getPassword()); |
| @@ -179,11 +181,20 @@ public class UserService { | @@ -179,11 +181,20 @@ public class UserService { | ||
| 179 | if (rightsSet.contains(RightState.Constants.LOGGED_IN)) { | 181 | if (rightsSet.contains(RightState.Constants.LOGGED_IN)) { |
| 180 | return true; | 182 | return true; |
| 181 | } | 183 | } |
| 182 | - if (rightsSet.contains(RightState.Constants.ADMIN)) { | ||
| 183 | - // TODO muss noch implementiert werden | ||
| 184 | - return true; | 184 | + // besitzt dieser Benutzer eine zugewiesene Rolle? |
| 185 | + final Role role = user.getProfile().getRole(); | ||
| 186 | + if (role != null) { | ||
| 187 | + // sämtliche Rechte iterieren, die den Benutzer berechtigen würden, um zu ermitteln, | ||
| 188 | + // ob der Benutzer eines dieser Rechte besitzt | ||
| 189 | + for (String right : rightsSet) { | ||
| 190 | + // besitzt der Benutzer das betrachtete Recht? | ||
| 191 | + if (role.hasRight(RightState.getByName(right))) { | ||
| 192 | + return true; | ||
| 193 | + } | ||
| 194 | + } | ||
| 185 | } | 195 | } |
| 186 | } | 196 | } |
| 187 | return false; | 197 | return false; |
| 188 | } | 198 | } |
| 199 | + | ||
| 189 | } | 200 | } |
src/main/java/net/ziemers/swxercise/ui/RoleViewController.java
0 → 100644
| 1 | +package net.ziemers.swxercise.ui; | ||
| 2 | + | ||
| 3 | +import net.ziemers.swxercise.lg.model.user.Role; | ||
| 4 | +import net.ziemers.swxercise.lg.user.dto.RoleDto; | ||
| 5 | +import net.ziemers.swxercise.lg.user.enums.RightState; | ||
| 6 | +import net.ziemers.swxercise.lg.user.service.RoleService; | ||
| 7 | + | ||
| 8 | +import javax.annotation.security.RolesAllowed; | ||
| 9 | +import javax.enterprise.context.ApplicationScoped; | ||
| 10 | +import javax.inject.Inject; | ||
| 11 | +import javax.ws.rs.*; | ||
| 12 | +import javax.ws.rs.core.MediaType; | ||
| 13 | +import java.util.Collection; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * REST-Methoden für die Rollen- und Rechteverwaltung. | ||
| 17 | + */ | ||
| 18 | +@ApplicationScoped | ||
| 19 | +@Path(RoleViewController.webContextPath) | ||
| 20 | +public class RoleViewController { | ||
| 21 | + | ||
| 22 | + static final String webContextPath = "/"; | ||
| 23 | + | ||
| 24 | + @Inject | ||
| 25 | + private RoleService roleService; | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * Liefert alle Rollen-Objekte zurück. | ||
| 29 | + * <p> | ||
| 30 | + * Aufruf: | ||
| 31 | + * GET http://localhost:8080/swxercise/rest/v1/roles | ||
| 32 | + * | ||
| 33 | + * @return die Rollen-Objekte, oder ein leeres JSON-Array, falls keine existieren. | ||
| 34 | + */ | ||
| 35 | + @GET | ||
| 36 | + @Path("v1/roles") | ||
| 37 | + @Produces(MediaType.APPLICATION_JSON) | ||
| 38 | + @RolesAllowed(RightState.Constants.ADMIN) | ||
| 39 | + public Collection<Role> getAllRoles() { | ||
| 40 | + return roleService.findAllRoles(); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * Erstellt eine neue Rolle. | ||
| 45 | + * | ||
| 46 | + * @param dto | ||
| 47 | + * @return | ||
| 48 | + */ | ||
| 49 | + @POST | ||
| 50 | + @Path("v1/role") | ||
| 51 | + @Consumes(MediaType.APPLICATION_JSON) | ||
| 52 | + @Produces(MediaType.APPLICATION_JSON) | ||
| 53 | + @RolesAllowed(RightState.Constants.ADMIN) | ||
| 54 | + public RestResponse createRole(RoleDto dto) { | ||
| 55 | + Long id = roleService.createRole(dto); | ||
| 56 | + return new RestResponse(); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | +} |
src/main/resources/bootstrap_data.sql
| 1 | -INSERT INTO Profile (id, username, hashAlgorithm, passwordHash, salt) VALUES (2, "admin", "SHA512", "JeuPx1++vnOSp/rdDwjnPwNIldN49UhtJEwUcKr3ksTvu/3s6nmnWbh+mkjfsw41w1LE8VJJAukn+LpfnUybzg==", "wwUVuetAfN1dtaXk0zWOMmb1nIw="); | ||
| 2 | -INSERT INTO User (id, firstname, lastname, profile_id) VALUES (1, "Chuck", "Norris", 2); | ||
| 3 | -UPDATE hibernate_sequence SET next_val = 3; | ||
| 4 | \ No newline at end of file | 1 | \ No newline at end of file |
| 2 | +INSERT INTO Role (id, name) VALUES(1, "Adminrolle"); | ||
| 3 | +INSERT INTO Role_rights (Role_id, rights) VALUES(1, "ADMIN"); | ||
| 4 | +INSERT INTO Profile (id, role_id, username, hashAlgorithm, passwordHash, salt) VALUES (2, 1, "admin", "SHA512", "JeuPx1++vnOSp/rdDwjnPwNIldN49UhtJEwUcKr3ksTvu/3s6nmnWbh+mkjfsw41w1LE8VJJAukn+LpfnUybzg==", "wwUVuetAfN1dtaXk0zWOMmb1nIw="); | ||
| 5 | +INSERT INTO User (id, profile_id, firstname, lastname) VALUES (3, 2, "Chuck", "Norris"); | ||
| 6 | +UPDATE hibernate_sequence SET next_val = 4; |