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 | 3 | import java.util.Collection; |
| 4 | 4 | |
| 5 | 5 | import javax.ejb.Stateless; |
| 6 | +import javax.enterprise.inject.Alternative; | |
| 6 | 7 | import javax.inject.Inject; |
| 7 | 8 | import javax.persistence.EntityManager; |
| 8 | 9 | import javax.persistence.TypedQuery; |
| ... | ... | @@ -17,6 +18,9 @@ import net.ziemers.swxercise.db.BaseEntity; |
| 17 | 18 | * spazialisierten Data Access Objects geerbt. |
| 18 | 19 | */ |
| 19 | 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 | 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 | 3 | import javax.persistence.Entity; |
| 4 | 4 | import javax.persistence.EnumType; |
| 5 | 5 | import javax.persistence.Enumerated; |
| 6 | +import javax.persistence.ManyToOne; | |
| 6 | 7 | import javax.validation.constraints.NotNull; |
| 7 | 8 | import javax.xml.bind.DatatypeConverter; |
| 8 | 9 | |
| ... | ... | @@ -34,6 +35,8 @@ public class Profile extends BaseEntity { |
| 34 | 35 | |
| 35 | 36 | private String mailaddress; |
| 36 | 37 | |
| 38 | + private Role role; | |
| 39 | + | |
| 37 | 40 | /* |
| 38 | 41 | * ***************************************************************************************************************************** |
| 39 | 42 | * Konstruktoren |
| ... | ... | @@ -188,4 +191,13 @@ public class Profile extends BaseEntity { |
| 188 | 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 | 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 | 32 | public String getName() { |
| 24 | 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 | 8 | |
| 9 | 9 | import net.ziemers.swxercise.db.dao.user.UserDao; |
| 10 | 10 | import net.ziemers.swxercise.lg.model.user.Profile; |
| 11 | +import net.ziemers.swxercise.lg.model.user.Role; | |
| 11 | 12 | import net.ziemers.swxercise.lg.model.user.User; |
| 12 | 13 | import net.ziemers.swxercise.lg.user.dto.UserDto; |
| 13 | 14 | import net.ziemers.swxercise.lg.user.enums.RightState; |
| ... | ... | @@ -83,6 +84,7 @@ public class UserService { |
| 83 | 84 | * @return die Id des neuen Benutzers, wenn die Erstellung erfolgreich war. |
| 84 | 85 | */ |
| 85 | 86 | public Long createUser(final UserDto dto) { |
| 87 | + // der Benutzer darf natürlich noch nicht existieren :) | |
| 86 | 88 | User user = dao.findByUsername(dto.getUsername()); |
| 87 | 89 | if (user == null) { |
| 88 | 90 | final Profile profile = new Profile(dto.getUsername(), dto.getPassword()); |
| ... | ... | @@ -179,11 +181,20 @@ public class UserService { |
| 179 | 181 | if (rightsSet.contains(RightState.Constants.LOGGED_IN)) { |
| 180 | 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 | 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 | 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; | ... | ... |