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; | ... | ... |